From ce894580ae715c91bdbf682e0fc40233b9ee4545 Mon Sep 17 00:00:00 2001 From: Benni-Math Date: Tue, 3 Sep 2024 23:04:34 -0400 Subject: [PATCH] repos and images tests --- index.js | 3 +- lib/aws.js | 1 + test/integration/cli.test.js | 145 +++++++++++++++++++++++++++++++++-- 3 files changed, 141 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 1d77070..6ccbd52 100755 --- a/index.js +++ b/index.js @@ -560,7 +560,7 @@ async function setupCLI(innerConf) { }); if (data.length) { - const tableOutput = table([['Respository Name'], ...data]); + const tableOutput = table([['Repository Name'], ...data]); exitWithSuccess(tableOutput); } exitWithError('No ECR repositories found'); @@ -590,6 +590,7 @@ async function setupCLI(innerConf) { * If `--all` flag is provided this will return true for all tags. * Otherwise only tags that look like e.g. "1.1.1" or master/stage * will be included. + * TODO: discuss this, as opposed to lib/aws.js:291 (getRepoImageList) */ const includeThisTag = (t) => { return cmd.all || looksLikeSemver(t) || ['master', 'stage'].includes(t); diff --git a/lib/aws.js b/lib/aws.js index 1bdb151..436c783 100644 --- a/lib/aws.js +++ b/lib/aws.js @@ -287,6 +287,7 @@ const aws = { // find the latest semver tagged image return images.filter((i) => { return i.imageTags.some((t) => { + // TODO: discuss this, as opposed to index.js:595 (includeThisTag) return looksLikeSemver(t) || ['main', 'master', 'stage'].includes(t); }); }); diff --git a/test/integration/cli.test.js b/test/integration/cli.test.js index 5c2aae6..9abd9b9 100644 --- a/test/integration/cli.test.js +++ b/test/integration/cli.test.js @@ -1,10 +1,32 @@ +// Import AWS mock const AWS = require('aws-sdk-mock'); + +// Import table +const moment = require('moment'); const { table } = require('table'); +// Import CLI and conf const { setupCLI } = require('../../index'); const { conf, setConfigDefaults } = require('../../lib/conf'); +// Helpers +const runCLI = async (...args) => { + const cli = await setupCLI(conf); + + let res; + try { + res = await cli.parseAsync(['node', 'caccl-deploy', ...args]); + } catch (err) { + return err.message; + } + + return res; +}; + +// Tests +// TODO: test failure scenarios? describe('caccl-deploy CLI', () => { + // Setup beforeAll(() => { // eslint-disable-next-line @typescript-eslint/no-empty-function jest.spyOn(console, 'log').mockImplementation(() => {}); @@ -15,8 +37,17 @@ describe('caccl-deploy CLI', () => { `Process exited: ${errorCode === 1 ? 'error' : 'success'}`, ); }); + + // Set conf + setConfigDefaults(); + }); + + afterEach(() => { + AWS.restore(); }); + // apps + // TODO: test other flags for apps it('lists apps with the app command', async () => { // Arrange AWS.mock('SSM', 'describeParameters', { @@ -32,18 +63,118 @@ describe('caccl-deploy CLI', () => { }, ], }); - setConfigDefaults(); - const cli = await setupCLI(conf); // Act - try { - await cli.parseAsync(['node', 'caccl-deploy', 'apps']); - } catch (err) { - expect(err.message).toBe('Process exited: success'); - } + const res = await runCLI('apps'); + + // Assert + expect(res).toBe('Process exited: success'); expect(console.log).toHaveBeenLastCalledWith( table([['App'], ['test-app-1'], ['test-app-3']]), ); }); + + // TODO: connect + + // TODO: delete + + // TODO: exec + + // images + // TODO: more scenarios + it('lists images with the images command', async () => { + // Arrange + AWS.mock('ECR', 'describeImages', { + imageDetails: [ + { + imagePushedAt: 1725416968, + imageTags: ['main'], + registryId: 'test-registry-id', + }, + { + imagePushedAt: 1725416068, + imageTags: ['1.0'], + registryId: 'test-registry-id', + }, + { + imagePushedAt: 1725410968, + imageTags: ['feature/test'], + registryId: 'test-registry-id', + }, + ], + }); + + // Act + const res = await runCLI('images', '-r', 'test'); + + // TODO: discuss this + // const res = await runCLI('images', '-r', 'test', '--all'); + + // Assert + expect(res).toBe('Process exited: success'); + + expect(console.log).toHaveBeenLastCalledWith( + table([ + ['Pushed On', 'Tags', 'ARNs'], + [moment(1725416968).format(), '', ''], + ]), + ); + }); + + // TODO: new + + // TODO: release + + // repos + // TODO: more scenarios + it('lists repos with the repos command', async () => { + // Arrange + AWS.mock('ECR', 'describeRepositories', { + repositories: [ + { + repositoryName: 'test-1', + repositoryArn: '', + }, + { + repositoryName: 'test-2', + repositoryArn: '', + }, + { + repositoryName: 'test-3', + repositoryArn: '', + }, + ], + }); + + // TODO: could test non-edtech-apps via (params, callback) => callback(null, { tags: ... }); + AWS.mock('ECR', 'listTagsForResource', { + tags: [ + { + Key: 'product', + Value: 'edtech-apps', + }, + ], + }); + + // Act + const res = await runCLI('repos'); + + // Assert + expect(res).toBe('Process exited: success'); + + expect(console.log).toHaveBeenLastCalledWith( + table([['Repository Name'], ['test-1'], ['test-2'], ['test-3']]), + ); + }); + + // TODO: restart + + // TODO: schedule + + // TODO: show + + // TODO: stack - need to catch the CDK call + + // TODO: update });