From 9e80bdd89ba88be549a080acff4553e9f6b3fef3 Mon Sep 17 00:00:00 2001 From: Julian Sedding Date: Fri, 23 Aug 2024 13:12:56 +0200 Subject: [PATCH] Issue #67 - access_token is stored in global conf not local .aio - fix test cases --- src/ctx/ConfigCliContext.js | 4 +- test/ctx/ConfigCliContext.test.js | 61 +++++++++++++++++++++++++---- test/ctx/Context.test.js | 12 +++--- test/ctx/StateActionContext.test.js | 12 +++--- 4 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/ctx/ConfigCliContext.js b/src/ctx/ConfigCliContext.js index 71a5b82..52e4c03 100644 --- a/src/ctx/ConfigCliContext.js +++ b/src/ctx/ConfigCliContext.js @@ -33,7 +33,7 @@ class ConfigCliContext extends Context { */ async getCli () { aioLogger.debug('get cli') - return this.getContextValue(this.keyNames.CLI) + return (await this.getContextValue(this.keyNames.CLI))?.data } /** @@ -54,7 +54,7 @@ class ConfigCliContext extends Context { // make sure to not merge any global config into local and vice versa const getCli = source => this.getContextValueFromOptionalSource(this.keyNames.CLI, source) const existingData = merge ? (local ? getCli('local') : getCli('global')) : {} - this.setContextValue(`${this.keyNames.CLI}`, { ...existingData, ...contextData }, local) + this.setContextValue(`${this.keyNames.CLI}`, { ...existingData.data, ...contextData }, local) } /** diff --git a/test/ctx/ConfigCliContext.test.js b/test/ctx/ConfigCliContext.test.js index 0f53e3c..546c40a 100644 --- a/test/ctx/ConfigCliContext.test.js +++ b/test/ctx/ConfigCliContext.test.js @@ -11,10 +11,47 @@ governing permissions and limitations under the License. */ const TheContext = require('../../src/ctx/ConfigCliContext') - +const { merge, getValue, setValue } = require('@adobe/aio-lib-core-config/src/util') const aioConfig = require('@adobe/aio-lib-core-config') jest.mock('@adobe/aio-lib-core-config') +/** + * Utility to merge values into an object. Intended for us within + * `mockConfig`'s `configCallback`. + * @param obj the object to modify + * @param key the dot-separated deep key of the value + * @param value the value to assign to the key + * @return void + * @private + */ +function addValue (obj, key, value) { + Object.assign(obj, setValue(key, value, obj)) +} + +/** + * Utility for mocking configs with 'local' and 'global' parts + * + * @param configCallback callback that receives a "global" and a "local" + * config object, both of which can be modified + * @return returns a function compatible with mockImplementation calls on aioConfig.get() + * @private + */ +function mockConfig (configCallback) { + const config = { + global: {}, + local: {} + } + configCallback(config.global, config.local) + + return (key, source) => { + if (!source) { + const result = merge(config.global, config.local) + return getValue(result, key) + } + return getValue(config[source], key) + } +} + const keyNames = { IMS: 'a', CONFIG: 'b', @@ -40,9 +77,12 @@ describe('constructor', () => { describe('getCli', () => { test('()', async () => { - aioConfig.get.mockReturnValue('value') + aioConfig.get.mockImplementation(mockConfig((global, _) => { + addValue(global, `${keyNames.IMS}.${keyNames.CONTEXTS}.${keyNames.CLI}`, 'value') + })) await expect(context.getCli()).resolves.toEqual('value') - expect(aioConfig.get).toHaveBeenCalledWith(`${keyNames.IMS}.${keyNames.CONTEXTS}.${keyNames.CLI}`) + expect(aioConfig.get).toHaveBeenNthCalledWith(1, `${keyNames.IMS}.${keyNames.CONTEXTS}.${keyNames.CLI}`, undefined) + expect(aioConfig.get).toHaveBeenNthCalledWith(2, `${keyNames.IMS}.${keyNames.CONTEXTS}.${keyNames.CLI}`, 'local') }) }) @@ -55,7 +95,9 @@ describe('setCli', () => { }) test('{ the: value }, prev={ another: fakevalue }', async () => { - aioConfig.get.mockReturnValue({ another: 'fakevalue' }) + aioConfig.get.mockImplementation(mockConfig((global, _) => { + addValue(global, `${keyNames.IMS}.${keyNames.CONTEXTS}.${keyNames.CLI}`, { another: 'fakevalue' }) + })) await expect(context.setCli({ the: 'value' })).resolves.toEqual(undefined) expect(aioConfig.get).toHaveBeenCalledWith(`${keyNames.IMS}.${keyNames.CONTEXTS}.${keyNames.CLI}`, 'global') expect(aioConfig.set).toHaveBeenCalledWith(`${keyNames.IMS}.${keyNames.CONTEXTS}.${keyNames.CLI}`, { the: 'value', another: 'fakevalue' }, false) @@ -88,9 +130,14 @@ describe('setCli', () => { describe('getContextValue', () => { test('(fake)', async () => { - aioConfig.get.mockReturnValue('value') - await expect(context.getContextValue('fake')).resolves.toEqual('value') - expect(aioConfig.get).toHaveBeenCalledWith(`${keyNames.IMS}.${keyNames.CONTEXTS}.fake`) + aioConfig.get.mockImplementation(mockConfig((global, _) => { + addValue(global, `${keyNames.IMS}.${keyNames.CONTEXTS}.fake`, 'value') + })) + await expect(context.getContextValue('fake')).resolves.toEqual({ data: 'value', local: false }) + expect(aioConfig.get) + .toHaveBeenNthCalledWith(1, `${keyNames.IMS}.${keyNames.CONTEXTS}.fake`, undefined) + expect(aioConfig.get) + .toHaveBeenNthCalledWith(2, `${keyNames.IMS}.${keyNames.CONTEXTS}.fake`, 'local') }) }) diff --git a/test/ctx/Context.test.js b/test/ctx/Context.test.js index 315241b..058304b 100644 --- a/test/ctx/Context.test.js +++ b/test/ctx/Context.test.js @@ -70,25 +70,25 @@ describe('setCurrent', () => { describe('get', () => { test('(), current=fake', async () => { context.getConfigValue = jest.fn().mockResolvedValue('fake') - context.getContextValue = jest.fn().mockResolvedValue({ fake: 'data' }) + context.getContextValue = jest.fn().mockResolvedValue({ data: { fake: 'data' }, local: true }) const ret = await context.get() - expect(ret).toEqual({ data: { fake: 'data' }, name: 'fake' }) + expect(ret).toEqual({ data: { fake: 'data' }, name: 'fake', local: true }) expect(context.getContextValue).toHaveBeenCalledWith('fake') expect(context.getConfigValue).toHaveBeenCalledWith(keyNames.CURRENT) }) test('(), current=undefined', async () => { context.getConfigValue = jest.fn().mockResolvedValue(undefined) - context.getContextValue = jest.fn().mockResolvedValue({ fake: 'data' }) + context.getContextValue = jest.fn().mockResolvedValue({ data: { fake: 'data' }, local: true }) const ret = await context.get() - expect(ret).toEqual({ data: undefined, name: undefined }) + expect(ret).toEqual({ data: undefined, name: undefined, local: false }) expect(context.getContextValue).toHaveBeenCalledTimes(0) expect(context.getConfigValue).toHaveBeenCalledWith(keyNames.CURRENT) }) test('(fake)', async () => { context.getConfigValue = jest.fn().mockResolvedValue(undefined) - context.getContextValue = jest.fn().mockResolvedValue({ fake: 'data' }) + context.getContextValue = jest.fn().mockResolvedValue({ data: { fake: 'data' }, local: false }) const ret = await context.get('fake') - expect(ret).toEqual({ data: { fake: 'data' }, name: 'fake' }) + expect(ret).toEqual({ data: { fake: 'data' }, name: 'fake', local: false }) expect(context.getContextValue).toHaveBeenCalledWith('fake') expect(context.getConfigValue).toHaveBeenCalledTimes(0) }) diff --git a/test/ctx/StateActionContext.test.js b/test/ctx/StateActionContext.test.js index d8a6ba7..0ab984e 100644 --- a/test/ctx/StateActionContext.test.js +++ b/test/ctx/StateActionContext.test.js @@ -107,21 +107,21 @@ describe('setConfigValue', () => { describe('getContextValue', () => { test('key=fake, context data = {}, no state tokens', async () => { - await expect(context.getContextValue('fake')).resolves.toEqual(undefined) + expect((await context.getContextValue('fake')).data).toEqual(undefined) // does interact with state expect(context.state).toBe(mockStateInstance) expect(mockState.init).toHaveBeenCalledTimes(1) }) test('2 calls: key=fake, context data = {}, no state tokens', async () => { - await expect(context.getContextValue('fake')).resolves.toEqual(undefined) - await expect(context.getContextValue('fake')).resolves.toEqual(undefined) + expect((await context.getContextValue('fake')).data).toEqual(undefined) + expect((await context.getContextValue('fake')).data).toEqual(undefined) // does interact with state, make sure we init once only expect(context.state).toBe(mockStateInstance) expect(mockState.init).toHaveBeenCalledTimes(1) }) test('key=fake, context data = { fake: value }, no state tokens', async () => { context.data[keyNames.CONTEXTS].fake = 'value' - await expect(context.getContextValue('fake')).resolves.toEqual('value') + expect((await context.getContextValue('fake')).data).toEqual('value') expect(cloneDeep).toHaveBeenCalledWith('value') // does interact with state expect(context.state).toBe(mockStateInstance) @@ -131,7 +131,7 @@ describe('getContextValue', () => { test('key=fake, context data = { fake: value, fake2: value2 }, no state tokens', async () => { context.data[keyNames.CONTEXTS].fake = 'value' context.data[keyNames.CONTEXTS].fake2 = 'value2' - await expect(context.getContextValue('fake')).resolves.toEqual('value') + expect((await context.getContextValue('fake')).data).toEqual('value') expect(cloneDeep).toHaveBeenCalledWith('value') // does interact with state twice expect(context.state).toBe(mockStateInstance) @@ -150,7 +150,7 @@ describe('getContextValue', () => { if (k.endsWith('fake2')) return { value: { access_token: 789, other: 'dontcare' } } if (k.endsWith('fake3')) return { value: { refresh_token: 120, other: 'dontcare' } } }) - await expect(context.getContextValue('fake')).resolves.toEqual({ the: 'value', access_token: 123, refresh_token: 456 }) + expect((await context.getContextValue('fake')).data).toEqual({ the: 'value', access_token: 123, refresh_token: 456 }) expect(cloneDeep).toHaveBeenCalledWith({ the: 'value', access_token: 123, refresh_token: 456 }) // does interact with state twice expect(context.state).toBe(mockStateInstance)