From 964fa2aa5be92c7f5e42a587ba1288bbbd467109 Mon Sep 17 00:00:00 2001 From: Jesse MacFadyen Date: Tue, 20 Apr 2021 22:55:51 -0700 Subject: [PATCH 1/2] added app info command, with tests --- src/commands/app/info.js | 76 ++++++++++++++++++++++++ test/commands/app/info.test.js | 105 +++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 src/commands/app/info.js create mode 100644 test/commands/app/info.test.js diff --git a/src/commands/app/info.js b/src/commands/app/info.js new file mode 100644 index 00000000..befedec0 --- /dev/null +++ b/src/commands/app/info.js @@ -0,0 +1,76 @@ +/* +Copyright 2021 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +const BaseCommand = require('../../BaseCommand') +const { flags } = require('@oclif/command') +const yaml = require('js-yaml') + +class Info extends BaseCommand { + async run () { + // cli input + const { flags } = this.parse(Info) + const appConfig = this.getAppConfig() + delete appConfig.cli + if (!appConfig.s3.tvmUrl) { + delete appConfig.s3.tvmUrl + } + // todo: mask these + if (!appConfig.s3.creds) { + delete appConfig.s3.creds + } + + if (flags.mask) { + appConfig.ow.auth = appConfig.ow.auth ? '' : 'undefined' + } + + if (flags.json) { + this.log(JSON.stringify(appConfig)) + } else if (flags.yml) { + this.log(yaml.safeDump(appConfig)) + } else { // flags.hson + this.log(appConfig) + } + } +} + +Info.description = `Display settings/configuration in use by an Adobe I/O App + +` + +Info.flags = { + ...BaseCommand.flags, + json: flags.boolean({ + description: 'Output json', + char: 'j', + exclusive: ['hson', 'yml'] + }), + hson: flags.boolean({ + default: true, + description: 'Output human readable json', + char: 'h', + exclusive: ['json', 'yml'] + }), + yml: flags.boolean({ + description: 'Output yml', + char: 'y', + exclusive: ['hson', 'json'] + }), + mask: flags.boolean({ + description: 'Hide known private info', + default: true, + allowNo: true + }) +} + +Info.args = [] + +module.exports = Info diff --git a/test/commands/app/info.test.js b/test/commands/app/info.test.js new file mode 100644 index 00000000..1880391c --- /dev/null +++ b/test/commands/app/info.test.js @@ -0,0 +1,105 @@ +/* +Copyright 2021 Adobe Inc. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +const TheCommand = require('../../../src/commands/app/info.js') +const BaseCommand = require('../../../src/BaseCommand.js') +const HHelp = require('@oclif/plugin-help').default +const owlocal = require('../../../src/lib/owlocal.js') + +test('exports', async () => { + expect(typeof TheCommand).toEqual('function') + expect(TheCommand.prototype instanceof BaseCommand).toBeTruthy() +}) + +test('description', async () => { + expect(TheCommand.description).toBeDefined() +}) + +test('flags', async () => { + expect(TheCommand.flags).toMatchObject({ + json: expect.any(Object), + hson: expect.any(Object), + yml: expect.any(Object), + mask: expect.any(Object) + }) +}) + +test('args', async () => { + expect(TheCommand.args).toBeDefined() + expect(TheCommand.args).toBeInstanceOf(Array) +}) + +describe('instance methods', () => { + let command + + beforeEach(() => { + command = new TheCommand([]) + }) + + describe('run', () => { + test('exists', async () => { + expect(command.run).toBeInstanceOf(Function) + }) + }) +}) + +describe('missing props', () => { + test('appConfig.s3.tvmUrl', async () => { + const command = new TheCommand([]) + command.error = jest.fn() + command.log = jest.fn() + command.appConfig = { s3: { tvmUrl: 'some url', creds: 'definitely defined' }, ow: { auth: 'super secret' } } + command.run() + expect(command.error).toHaveBeenCalledTimes(0) + expect(command.log).not.toHaveBeenCalledWith(expect.stringContaining('super secret')) + }) +}) + +describe('masking secrets', () => { + test('masks by default', async () => { + const command = new TheCommand([]) + command.error = jest.fn() + command.log = jest.fn() + command.appConfig = { s3: {}, ow: { auth: 'super secret' } } + command.run() + expect(command.error).toHaveBeenCalledTimes(0) + expect(command.log).not.toHaveBeenCalledWith(expect.stringContaining('super secret')) + }) + // this is really just to get coverage on L32 + test('masks without appConfig.ow.auth', async () => { + const command = new TheCommand([]) + command.error = jest.fn() + command.log = jest.fn() + command.appConfig = { s3: {}, ow: { auth: '' } } + command.run() + expect(command.error).toHaveBeenCalledTimes(0) + expect(command.log).not.toHaveBeenCalledWith(expect.stringContaining('super secret')) + }) + test('no-masking', async () => { + const command = new TheCommand(['--no-mask', '-j']) + command.error = jest.fn() + command.log = jest.fn() + command.appConfig = { s3: {}, ow: { auth: 'super secret' } } + command.run() + expect(command.error).toHaveBeenCalledTimes(0) + expect(command.log).toHaveBeenCalledWith(expect.stringContaining('super secret')) + }) + test('no-masking --yaml', async () => { + const command = new TheCommand(['--no-mask', '-y']) + command.error = jest.fn() + command.log = jest.fn() + command.appConfig = { s3: {}, ow: { auth: 'super secret' } } + command.run() + expect(command.error).toHaveBeenCalledTimes(0) + expect(command.log).toHaveBeenCalledWith(expect.stringContaining('super secret')) + }) +}) From 5fbe47c236869024d42234ede43b04a477101fa7 Mon Sep 17 00:00:00 2001 From: Jesse MacFadyen Date: Wed, 21 Apr 2021 10:03:42 -0700 Subject: [PATCH 2/2] cleanup unused requires breaking the tests --- test/commands/app/info.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/commands/app/info.test.js b/test/commands/app/info.test.js index 1880391c..b25fd6f0 100644 --- a/test/commands/app/info.test.js +++ b/test/commands/app/info.test.js @@ -12,8 +12,6 @@ governing permissions and limitations under the License. const TheCommand = require('../../../src/commands/app/info.js') const BaseCommand = require('../../../src/BaseCommand.js') -const HHelp = require('@oclif/plugin-help').default -const owlocal = require('../../../src/lib/owlocal.js') test('exports', async () => { expect(typeof TheCommand).toEqual('function')