From 57d4404630f544e1f962cd5eb13cdc855cc40576 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah <36107+shazron@users.noreply.github.com> Date: Thu, 20 Oct 2022 22:18:24 +0800 Subject: [PATCH] fix: ACNA-1808 - move action generators to their own repos (#206) * fix: remove extensions --- generators/add-action/analytics/index.js | 70 ------- .../templates/getCollections.test.js | 84 -------- .../add-action/audience-manager-cd/index.js | 65 ------- .../templates/getProfile.test.js | 84 -------- .../add-action/campaign-standard/index.js | 70 ------- .../templates/getAllProfiles.test.js | 84 -------- .../add-action/customer-profile/index.js | 72 ------- .../templates/getProfile.test.js | 83 -------- generators/add-action/index.js | 25 +-- generators/add-action/target/index.js | 70 ------- .../target/templates/getActivities.test.js | 85 --------- generators/index.js | 9 +- package.json | 5 + test/generators/add-action/analytics.test.js | 172 ----------------- .../add-action/audience-manager-cd.test.js | 149 --------------- .../add-action/campaign-standard.test.js | 172 ----------------- .../add-action/customer-profile.test.js | 179 ------------------ test/generators/add-action/index.test.js | 16 +- test/generators/add-action/target.test.js | 173 ----------------- test/generators/index.test.js | 1 - test/jest.setup.js | 2 + 21 files changed, 33 insertions(+), 1637 deletions(-) delete mode 100644 generators/add-action/analytics/index.js delete mode 100644 generators/add-action/analytics/templates/getCollections.test.js delete mode 100644 generators/add-action/audience-manager-cd/index.js delete mode 100644 generators/add-action/audience-manager-cd/templates/getProfile.test.js delete mode 100644 generators/add-action/campaign-standard/index.js delete mode 100644 generators/add-action/campaign-standard/templates/getAllProfiles.test.js delete mode 100644 generators/add-action/customer-profile/index.js delete mode 100644 generators/add-action/customer-profile/templates/getProfile.test.js delete mode 100644 generators/add-action/target/index.js delete mode 100644 generators/add-action/target/templates/getActivities.test.js delete mode 100644 test/generators/add-action/analytics.test.js delete mode 100644 test/generators/add-action/audience-manager-cd.test.js delete mode 100644 test/generators/add-action/campaign-standard.test.js delete mode 100644 test/generators/add-action/customer-profile.test.js delete mode 100644 test/generators/add-action/target.test.js diff --git a/generators/add-action/analytics/index.js b/generators/add-action/analytics/index.js deleted file mode 100644 index f4239d98..00000000 --- a/generators/add-action/analytics/index.js +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2019 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 path = require('path') -const { ActionGenerator, constants, commonTemplates } = require('@adobe/generator-app-common-lib') -const { commonDependencyVersions } = constants - -class AnalyticsGenerator extends ActionGenerator { - constructor (args, opts) { - super(args, opts) - this.props = { - description: 'This is a sample action showcasing how to access the Adobe Analytics API', - // eslint-disable-next-line quotes - requiredParams: `['apiKey', 'companyId']`, - // eslint-disable-next-line quotes - requiredHeaders: `['Authorization']`, - // eslint-disable-next-line quotes - importCode: `const { Core, Analytics } = require('@adobe/aio-sdk')`, - responseCode: `// initialize the sdk - const analyticsClient = await Analytics.init(params.companyId, params.apiKey, token) - - // get collections from analytics API - const collections = await analyticsClient.getCollections({ limit: 5, page: 0 }) - const response = { - statusCode: 200, - body: collections - }` - } - } - - async prompting () { - this.props.actionName = await this.promptForActionName('interacts with the Adobe Analytics API', 'analytics') - } - - writing () { - // this.registerTransformStream(beautify({ indent_size: 2 })) - this.sourceRoot(path.join(__dirname, '.')) - - this.addAction(this.props.actionName, commonTemplates['stub-action'], { - testFile: './templates/getCollections.test.js', - sharedLibFile: commonTemplates.utils, - sharedLibTestFile: commonTemplates['utils.test'], - e2eTestFile: commonTemplates['stub-action.e2e'], - tplContext: this.props, - dependencies: { - '@adobe/aio-sdk': commonDependencyVersions['@adobe/aio-sdk'] - }, - dotenvStub: { - label: 'please provide your Adobe I/O Analytics company id', - vars: [ - 'ANALYTICS_COMPANY_ID' - ] - }, - actionManifestConfig: { - inputs: { LOG_LEVEL: 'debug', companyId: '$ANALYTICS_COMPANY_ID', apiKey: '$SERVICE_API_KEY' }, - annotations: { final: true } - } - }) - } -} - -module.exports = AnalyticsGenerator diff --git a/generators/add-action/analytics/templates/getCollections.test.js b/generators/add-action/analytics/templates/getCollections.test.js deleted file mode 100644 index faf36e44..00000000 --- a/generators/add-action/analytics/templates/getCollections.test.js +++ /dev/null @@ -1,84 +0,0 @@ -/*<% if (false) { %> -Copyright 2019 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. -<% } %> -* -*/ - -jest.mock('@adobe/aio-sdk', () => ({ - Analytics: { - init: jest.fn() - }, - Core: { - Logger: jest.fn() - } -})) - -const { Core, Analytics } = require('@adobe/aio-sdk') -const mockAnalyticsInstance = { getCollections: jest.fn() } -const mockLoggerInstance = { info: jest.fn(), debug: jest.fn(), error: jest.fn() } -Core.Logger.mockReturnValue(mockLoggerInstance) -Analytics.init.mockResolvedValue(mockAnalyticsInstance) - -const action = require('./<%= actionRelPath %>') - -beforeEach(() => { - Analytics.init.mockClear() // only clears calls stats - mockAnalyticsInstance.getCollections.mockReset() // clears calls + mock implementation - - Core.Logger.mockClear() - mockLoggerInstance.info.mockReset() - mockLoggerInstance.debug.mockReset() - mockLoggerInstance.error.mockReset() -}) - -const fakeRequestParams = { companyId: 'fakeId', apiKey: 'fakeKey', __ow_headers: { authorization: 'Bearer fakeToken' } } -describe('<%= actionName %>', () => { - test('main should be defined', () => { - expect(action.main).toBeInstanceOf(Function) - }) - test('should set logger to use LOG_LEVEL param', async () => { - await action.main({ ...fakeRequestParams, LOG_LEVEL: 'fakeLevel' }) - expect(Core.Logger).toHaveBeenCalledWith(expect.any(String), { level: 'fakeLevel' }) - }) - test('analytics sdk should be initialized with input credentials', async () => { - await action.main({ ...fakeRequestParams, otherParam: 'fake4' }) - expect(Analytics.init).toHaveBeenCalledWith('fakeId', 'fakeKey', 'fakeToken' ) - }) - test('should return an http response with analytics collections', async () => { - const fakeResponse = { collections: 'fake' } - mockAnalyticsInstance.getCollections.mockResolvedValue(fakeResponse) - const response = await action.main(fakeRequestParams) - expect(response).toEqual(expect.objectContaining({ - statusCode: 200, - body: fakeResponse - })) - }) - test('if there is an error should return a 500 and log the error', async () => { - const fakeError = new Error('fake') - mockAnalyticsInstance.getCollections.mockRejectedValue(fakeError) - const response = await action.main(fakeRequestParams) - expect(response).toEqual(expect.objectContaining({ - error: { - statusCode: 500, - body: { error: 'server error' } - } - })) - expect(mockLoggerInstance.error).toHaveBeenCalledWith(fakeError) - }) - test('missing input request parameters, should return 400', async () => { - const response = await action.main({}) - expect(response).toEqual({ - error: { - statusCode: 400, - body: { error: 'missing header(s) \'authorization\' and missing parameter(s) \'apiKey,companyId\'' } - } - }) - }) -}) diff --git a/generators/add-action/audience-manager-cd/index.js b/generators/add-action/audience-manager-cd/index.js deleted file mode 100644 index 884e3943..00000000 --- a/generators/add-action/audience-manager-cd/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2020 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 path = require('path') -const { ActionGenerator, constants, commonTemplates } = require('@adobe/generator-app-common-lib') -const { commonDependencyVersions } = constants - -class AudienceManagerCDGenerator extends ActionGenerator { - constructor (args, opts) { - super(args, opts) - this.props = { - description: 'This is a sample action showcasing how to access the Adobe Audience Manager Customer Data API', - // eslint-disable-next-line quotes - requiredParams: `['apiKey', 'id', 'dataSourceId']`, - // eslint-disable-next-line quotes - requiredHeaders: `['Authorization', 'x-gw-ims-org-id']`, - // eslint-disable-next-line quotes - importCode: `const { Core, AudienceManagerCD } = require('@adobe/aio-sdk')`, - responseCode: `// initialize the sdk - const orgId = params.__ow_headers['x-gw-ims-org-id'] - const audienceManagerClient = await AudienceManagerCD.init(orgId, params.apiKey, token) - - // get Customer Profile from Audience Manager Customer Data API - const profiles = await audienceManagerClient.getProfile(params.id, params.dataSourceId) - const response = { - statusCode: 200, - body: profiles - }` - } - } - - async prompting () { - this.props.actionName = await this.promptForActionName('interacts with the Adobe Audience Manager Customer Data API', 'audience-manager-cd') - } - - writing () { - // this.registerTransformStream(beautify({ indent_size: 2 })) - this.sourceRoot(path.join(__dirname, '.')) - - this.addAction(this.props.actionName, commonTemplates['stub-action'], { - testFile: './templates/getProfile.test.js', - sharedLibFile: commonTemplates.utils, - sharedLibTestFile: commonTemplates['utils.test'], - e2eTestFile: commonTemplates['stub-action.e2e'], - tplContext: this.props, - dependencies: { - '@adobe/aio-sdk': commonDependencyVersions['@adobe/aio-sdk'] - }, - actionManifestConfig: { - inputs: { LOG_LEVEL: 'debug', apiKey: '$SERVICE_API_KEY' }, - annotations: { final: true } - } - }) - } -} - -module.exports = AudienceManagerCDGenerator diff --git a/generators/add-action/audience-manager-cd/templates/getProfile.test.js b/generators/add-action/audience-manager-cd/templates/getProfile.test.js deleted file mode 100644 index 312c6909..00000000 --- a/generators/add-action/audience-manager-cd/templates/getProfile.test.js +++ /dev/null @@ -1,84 +0,0 @@ -/*<% if (false) { %> -Copyright 2020 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. -<% } %> -* -*/ - -jest.mock('@adobe/aio-sdk', () => ({ - AudienceManagerCD: { - init: jest.fn() - }, - Core: { - Logger: jest.fn() - } -})) - -const { Core, AudienceManagerCD } = require('@adobe/aio-sdk') -const mockAudienceManagerCDInstance = { getProfile: jest.fn() } -const mockLoggerInstance = { info: jest.fn(), debug: jest.fn(), error: jest.fn() } -Core.Logger.mockReturnValue(mockLoggerInstance) -AudienceManagerCD.init.mockResolvedValue(mockAudienceManagerCDInstance) - -const action = require('./<%= actionRelPath %>') - -beforeEach(() => { - AudienceManagerCD.init.mockClear() // only clears calls stats - mockAudienceManagerCDInstance.getProfile.mockReset() // clears calls + mock implementation - - Core.Logger.mockClear() - mockLoggerInstance.info.mockReset() - mockLoggerInstance.debug.mockReset() - mockLoggerInstance.error.mockReset() -}) - -const fakeRequestParams = { apiKey: 'fakeKey', id: 'fakeId', dataSourceId: 'fakeDataSourceId', __ow_headers: { authorization: 'Bearer fakeToken', 'x-gw-ims-org-id': 'fakeOrgId' } } -describe('<%= actionName %>', () => { - test('main should be defined', () => { - expect(action.main).toBeInstanceOf(Function) - }) - test('should set logger to use LOG_LEVEL param', async () => { - await action.main({ ...fakeRequestParams, LOG_LEVEL: 'fakeLevel' }) - expect(Core.Logger).toHaveBeenCalledWith(expect.any(String), { level: 'fakeLevel' }) - }) - test('AudienceManagerCD sdk should be initialized with input credentials', async () => { - await action.main({ ...fakeRequestParams, otherParam: 'fake4' }) - expect(AudienceManagerCD.init).toHaveBeenCalledWith('fakeOrgId', 'fakeKey', 'fakeToken') - }) - test('should return an http response with AudienceManagerCD profiles', async () => { - const fakeResponse = { profiles: 'fake' } - mockAudienceManagerCDInstance.getProfile.mockResolvedValue(fakeResponse) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - statusCode: 200, - body: fakeResponse - }) - }) - test('if there is an error should return a 500 and log the error', async () => { - const fakeError = new Error('fake') - mockAudienceManagerCDInstance.getProfile.mockRejectedValue(fakeError) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - error: { - statusCode: 500, - body: { error: 'server error' } - } - }) - expect(mockLoggerInstance.error).toHaveBeenCalledWith(fakeError) - }) - test('missing input request parameters, should return 400', async () => { - const response = await action.main({}) - expect(response).toEqual({ - error: { - statusCode: 400, - body: { error: 'missing header(s) \'authorization,x-gw-ims-org-id\' and missing parameter(s) \'apiKey,id,dataSourceId\'' } - } - }) - }) -}) diff --git a/generators/add-action/campaign-standard/index.js b/generators/add-action/campaign-standard/index.js deleted file mode 100644 index df9ea122..00000000 --- a/generators/add-action/campaign-standard/index.js +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2019 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 path = require('path') -const { ActionGenerator, constants, commonTemplates } = require('@adobe/generator-app-common-lib') -const { commonDependencyVersions } = constants - -class CampaignStandardGenerator extends ActionGenerator { - constructor (args, opts) { - super(args, opts) - this.props = { - description: 'This is a sample action showcasing how to access the Adobe Campaign Standard API', - // eslint-disable-next-line quotes - requiredParams: `['apiKey', 'tenant']`, - // eslint-disable-next-line quotes - requiredHeaders: `['Authorization']`, - // eslint-disable-next-line quotes - importCode: `const { Core, CampaignStandard } = require('@adobe/aio-sdk')`, - responseCode: `// initialize the sdk - const campaignClient = await CampaignStandard.init(params.tenant, params.apiKey, token) - - // get profiles from Campaign Standard - const profiles = await campaignClient.getAllProfiles() - const response = { - statusCode: 200, - body: profiles - }` - } - } - - async prompting () { - this.props.actionName = await this.promptForActionName('interacts with the Adobe Campaign Standard API', 'campaign-standard') - } - - writing () { - // this.registerTransformStream(beautify({ indent_size: 2 })) - this.sourceRoot(path.join(__dirname, '.')) - - this.addAction(this.props.actionName, commonTemplates['stub-action'], { - testFile: './templates/getAllProfiles.test.js', - sharedLibFile: commonTemplates.utils, - sharedLibTestFile: commonTemplates['utils.test'], - e2eTestFile: commonTemplates['stub-action.e2e'], - tplContext: this.props, - dotenvStub: { - label: 'please provide your Adobe I/O Campaign Standard tenant', - vars: [ - 'CAMPAIGN_STANDARD_TENANT' - ] - }, - dependencies: { - '@adobe/aio-sdk': commonDependencyVersions['@adobe/aio-sdk'] - }, - actionManifestConfig: { - inputs: { LOG_LEVEL: 'debug', tenant: '$CAMPAIGN_STANDARD_TENANT', apiKey: '$SERVICE_API_KEY' }, - annotations: { final: true } - } - }) - } -} - -module.exports = CampaignStandardGenerator diff --git a/generators/add-action/campaign-standard/templates/getAllProfiles.test.js b/generators/add-action/campaign-standard/templates/getAllProfiles.test.js deleted file mode 100644 index 1e474834..00000000 --- a/generators/add-action/campaign-standard/templates/getAllProfiles.test.js +++ /dev/null @@ -1,84 +0,0 @@ -/*<% if (false) { %> -Copyright 2019 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. -<% } %> -* -*/ - -jest.mock('@adobe/aio-sdk', () => ({ - CampaignStandard: { - init: jest.fn() - }, - Core: { - Logger: jest.fn() - } -})) - -const { Core, CampaignStandard } = require('@adobe/aio-sdk') -const mockCampaignStandardInstance = { getAllProfiles: jest.fn() } -const mockLoggerInstance = { info: jest.fn(), debug: jest.fn(), error: jest.fn() } -Core.Logger.mockReturnValue(mockLoggerInstance) -CampaignStandard.init.mockResolvedValue(mockCampaignStandardInstance) - -const action = require('./<%= actionRelPath %>') - -beforeEach(() => { - CampaignStandard.init.mockClear() // only clears calls stats - mockCampaignStandardInstance.getAllProfiles.mockReset() // clears calls + mock implementation - - Core.Logger.mockClear() - mockLoggerInstance.info.mockReset() - mockLoggerInstance.debug.mockReset() - mockLoggerInstance.error.mockReset() -}) - -const fakeRequestParams = { tenant: 'fakeId', apiKey: 'fakeKey', __ow_headers: { authorization: 'Bearer fakeToken' } } -describe('<%= actionName %>', () => { - test('main should be defined', () => { - expect(action.main).toBeInstanceOf(Function) - }) - test('should set logger to use LOG_LEVEL param', async () => { - await action.main({ ...fakeRequestParams, LOG_LEVEL: 'fakeLevel' }) - expect(Core.Logger).toHaveBeenCalledWith(expect.any(String), { level: 'fakeLevel' }) - }) - test('CampaignStandard sdk should be initialized with input credentials', async () => { - await action.main({ ...fakeRequestParams, otherParam: 'fake4' }) - expect(CampaignStandard.init).toHaveBeenCalledWith('fakeId', 'fakeKey', 'fakeToken') - }) - test('should return an http response with CampaignStandard profiles', async () => { - const fakeResponse = { profiles: 'fake' } - mockCampaignStandardInstance.getAllProfiles.mockResolvedValue(fakeResponse) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - statusCode: 200, - body: fakeResponse - }) - }) - test('if there is an error should return a 500 and log the error', async () => { - const fakeError = new Error('fake') - mockCampaignStandardInstance.getAllProfiles.mockRejectedValue(fakeError) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - error: { - statusCode: 500, - body: { error: 'server error' } - } - }) - expect(mockLoggerInstance.error).toHaveBeenCalledWith(fakeError) - }) - test('missing input request parameters, should return 400', async () => { - const response = await action.main({}) - expect(response).toEqual({ - error: { - statusCode: 400, - body: { error: 'missing header(s) \'authorization\' and missing parameter(s) \'apiKey,tenant\'' } - } - }) - }) -}) diff --git a/generators/add-action/customer-profile/index.js b/generators/add-action/customer-profile/index.js deleted file mode 100644 index dab05b62..00000000 --- a/generators/add-action/customer-profile/index.js +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2019 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 path = require('path') -const { ActionGenerator, constants, commonTemplates } = require('@adobe/generator-app-common-lib') -const { commonDependencyVersions } = constants - -class CustomerProfileGenerator extends ActionGenerator { - constructor (args, opts) { - super(args, opts) - this.props = { - description: 'This is a sample action showcasing how to access an external Adobe Experience Platform: Realtime Customer Profile API', - // eslint-disable-next-line quotes - requiredParams: `['tenant', 'apiKey', 'entityId', 'entityIdNS']`, - // eslint-disable-next-line quotes - requiredHeaders: `['Authorization', 'x-gw-ims-org-id']`, - // eslint-disable-next-line quotes - importCode: `const { Core, CustomerProfile } = require('@adobe/aio-sdk')`, - responseCode: `// initialize sdk - const orgId = params.__ow_headers['x-gw-ims-org-id'] - const client = await CustomerProfile.init(params.tenant, orgId, params.apiKey, token) - // call methods, eg getProfile - const profile = await client.getProfile({ - entityId: params.entityId, - entityIdNS: params.entityIdNS - }); - const response = { - statusCode: 200, - body: profile - }` - } - } - - async prompting () { - this.props.actionName = await this.promptForActionName('interacts with the Adobe Experience Platform: Realtime Customer Profile', 'customer-profile') - } - - writing () { - this.sourceRoot(path.join(__dirname, '.')) - - this.addAction(this.props.actionName, commonTemplates['stub-action'], { - testFile: './templates/getProfile.test.js', - sharedLibFile: commonTemplates.utils, - sharedLibTestFile: commonTemplates['utils.test'], - e2eTestFile: commonTemplates['stub-action.e2e'], - tplContext: this.props, - dotenvStub: { - label: 'please provide your Adobe Experience Platform Realtime Customer Profile tenant', - vars: [ - 'CUSTOMER_PROFILE_TENANT' - ] - }, - dependencies: { - '@adobe/aio-sdk': commonDependencyVersions['@adobe/aio-sdk'] - }, - actionManifestConfig: { - inputs: { LOG_LEVEL: 'debug', tenant: '$CUSTOMER_PROFILE_TENANT', apiKey: '$SERVICE_API_KEY' }, - annotations: { final: true } // makes sure loglevel cannot be overwritten by request param - } - }) - } -} - -module.exports = CustomerProfileGenerator diff --git a/generators/add-action/customer-profile/templates/getProfile.test.js b/generators/add-action/customer-profile/templates/getProfile.test.js deleted file mode 100644 index e61fc705..00000000 --- a/generators/add-action/customer-profile/templates/getProfile.test.js +++ /dev/null @@ -1,83 +0,0 @@ -/*<% if (false) { %> -Copyright 2019 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. -<% } %> -* -*/ - -jest.mock('@adobe/aio-sdk', () => ({ - Core: { - Logger: jest.fn() - }, - CustomerProfile: { - init: jest.fn() - } -})) - -const { Core, CustomerProfile } = require('@adobe/aio-sdk') -const mockCustomerProfileInstance = { getProfile: jest.fn() } -const mockLoggerInstance = { info: jest.fn(), debug: jest.fn(), error: jest.fn() } -Core.Logger.mockReturnValue(mockLoggerInstance) -CustomerProfile.init.mockResolvedValue(mockCustomerProfileInstance) - -const action = require('./<%= actionRelPath %>') - -beforeEach(() => { - CustomerProfile.init.mockClear() // only clears calls stats - mockCustomerProfileInstance.getProfile.mockReset() // clears calls + mock implementation - - Core.Logger.mockClear() - mockLoggerInstance.info.mockReset() - mockLoggerInstance.debug.mockReset() - mockLoggerInstance.error.mockReset() -}) -const fakeRequestParams = { tenant: 'fakeId', apiKey: 'fakeKey', entityId: 'fakeEntityId', entityIdNS: 'fakeEntityIdNS', __ow_headers: { authorization: 'Bearer fakeToken', 'x-gw-ims-org-id': 'fakeOrgId' } } -describe('<%= actionName %>', () => { - test('main should be defined', () => { - expect(action.main).toBeInstanceOf(Function) - }) - test('should set logger to use LOG_LEVEL param', async () => { - await action.main({ ...fakeRequestParams, LOG_LEVEL: 'fakeLevel' }) - expect(Core.Logger).toHaveBeenCalledWith(expect.any(String), { level: 'fakeLevel' }) - }) - test('CustomerProfileSDK should be initialized with input credentials', async () => { - await action.main({ ...fakeRequestParams, otherParam: 'fake4' }) - expect(CustomerProfile.init).toHaveBeenCalledWith('fakeId', 'fakeOrgId', 'fakeKey', 'fakeToken') - }) - test('should return an http response with CustomerProfile API profile', async () => { - const fakeResponse = { fakeHash: {} } - mockCustomerProfileInstance.getProfile.mockResolvedValue(fakeResponse) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - statusCode: 200, - body: fakeResponse - }) - }) - test('if there is an error should return a 500 and log the error', async () => { - const fakeError = new Error('fake') - mockCustomerProfileInstance.getProfile.mockRejectedValue(fakeError) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - error: { - statusCode: 500, - body: { error: 'server error' } - } - }) - expect(mockLoggerInstance.error).toHaveBeenCalledWith(fakeError) - }) - test('missing input request parameters, should return 400', async () => { - const response = await action.main({}) - expect(response).toEqual({ - error: { - statusCode: 400, - body: { error: 'missing header(s) \'authorization,x-gw-ims-org-id\' and missing parameter(s) \'tenant,apiKey,entityId,entityIdNS\'' } - } - }) - }) -}) diff --git a/generators/add-action/index.js b/generators/add-action/index.js index 05890432..ce29b6d7 100644 --- a/generators/add-action/index.js +++ b/generators/add-action/index.js @@ -17,17 +17,22 @@ const { sdkCodes, isLoopingPrompts } = constants const generic = require('@adobe/generator-add-action-generic') const assetCompute = require('@adobe/generator-add-action-asset-compute') +const target = require('@adobe/generator-add-action-target') +const analytics = require('@adobe/generator-add-action-analytics') +const campaign = require('@adobe/generator-add-action-campaign-standard') +const customerProfile = require('@adobe/generator-add-action-customer-profile') +const audienceManagerCD = require('@adobe/generator-add-action-audience-manager-cd') const inquirer = require('inquirer') // we have one actions generator per service, an action generator could generate different types of actions const sdkCodeToActionGenerator = { - [sdkCodes.target]: require('./target'), - [sdkCodes.analytics]: require('./analytics'), - [sdkCodes.campaign]: require('./campaign-standard'), + [sdkCodes.target]: target, + [sdkCodes.analytics]: analytics, + [sdkCodes.campaign]: campaign, [sdkCodes.assetCompute]: assetCompute, - [sdkCodes.customerProfile]: require('./customer-profile'), - [sdkCodes.audienceManagerCD]: require('./audience-manager-cd') + [sdkCodes.customerProfile]: customerProfile, + [sdkCodes.audienceManagerCD]: audienceManagerCD } const sdkCodeToTitle = { @@ -39,8 +44,6 @@ const sdkCodeToTitle = { [sdkCodes.audienceManagerCD]: 'Adobe Audience Manager: Customer Data' } -const genericActionGenerator = generic - /* 'initializing', 'prompting', @@ -71,7 +74,7 @@ class AddActions extends Generator { async prompting () { // default if skip-prompt = true - let actionGenerators = [genericActionGenerator] + let actionGenerators = [generic] if (!this.options['skip-prompt']) { // get list of choices @@ -137,7 +140,7 @@ function getPromptChoices (adobeServicesOption, supportedAdobeServicesOption) { const addedServicesChoices = toChoices(addedSet, true) const choices = [ new inquirer.Separator('-- supported templates for services added to this Adobe Developer Console Workspace --'), - { name: 'Generic', value: genericActionGenerator, checked: addedServicesChoices.length <= 0 }, + { name: 'Generic', value: generic, checked: addedServicesChoices.length <= 0 }, ...addedServicesChoices ] if (supportedNotAddedSet.size > 0) { @@ -162,7 +165,7 @@ function getPromptChoices (adobeServicesOption, supportedAdobeServicesOption) { const addedServicesChoices = toChoices(addedSet, true) const choices = [ new inquirer.Separator('-- supported templates for services added to this Adobe Developer Console Workspace --'), - { name: 'Generic', value: genericActionGenerator, checked: addedServicesChoices.length <= 0 }, + { name: 'Generic', value: generic, checked: addedServicesChoices.length <= 0 }, ...addedServicesChoices ] if (remainingSet.size > 0) { @@ -177,7 +180,7 @@ function getPromptChoices (adobeServicesOption, supportedAdobeServicesOption) { /// case c. no supported-adobe-services nor adobe-services /// e.g. `aio app init --import` with no services in workspace or `aio app init --no-login` return [ - { name: 'Generic', value: genericActionGenerator, checked: true }, + { name: 'Generic', value: generic, checked: true }, new inquirer.Separator('-- Adobe service specific templates, corresponding services may have to be added to this Workspace in https://console.adobe.io/ --'), ...toChoices(remainingSet) ] diff --git a/generators/add-action/target/index.js b/generators/add-action/target/index.js deleted file mode 100644 index bb362a24..00000000 --- a/generators/add-action/target/index.js +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2019 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 path = require('path') - -const { ActionGenerator, constants, commonTemplates } = require('@adobe/generator-app-common-lib') -const { commonDependencyVersions } = constants - -class TargetGenerator extends ActionGenerator { - constructor (args, opts) { - super(args, opts) - this.props = { - description: 'This is a sample action showcasing how to access the Adobe Target API', - // eslint-disable-next-line quotes - requiredParams: `['apiKey', 'tenant']`, - // eslint-disable-next-line quotes - requiredHeaders: `['Authorization']`, - // eslint-disable-next-line quotes - importCode: `const { Core, Target } = require('@adobe/aio-sdk')`, - responseCode: `// initialize the sdk - const targetClient = await Target.init(params.tenant, params.apiKey, token) - - // get activities from Target api - const activities = await targetClient.getActivities({ limit: 5, offset: 0 }) - const response = { - statusCode: 200, - body: activities - }` - } - } - - async prompting () { - this.props.actionName = await this.promptForActionName('interacts with the Adobe Target API', 'target') - } - - writing () { - this.sourceRoot(path.join(__dirname, '.')) - - this.addAction(this.props.actionName, commonTemplates['stub-action'], { - testFile: './templates/getActivities.test.js', - sharedLibFile: commonTemplates.utils, - sharedLibTestFile: commonTemplates['utils.test'], - e2eTestFile: commonTemplates['stub-action.e2e'], - tplContext: this.props, - dotenvStub: { - label: 'please provide your Adobe I/O Target tenant', - vars: [ - 'TARGET_TENANT' - ] - }, - dependencies: { - '@adobe/aio-sdk': commonDependencyVersions['@adobe/aio-sdk'] - }, - actionManifestConfig: { - inputs: { LOG_LEVEL: 'debug', tenant: '$TARGET_TENANT', apiKey: '$SERVICE_API_KEY' }, - annotations: { final: true } - } - }) - } -} - -module.exports = TargetGenerator diff --git a/generators/add-action/target/templates/getActivities.test.js b/generators/add-action/target/templates/getActivities.test.js deleted file mode 100644 index 3cf4b3b1..00000000 --- a/generators/add-action/target/templates/getActivities.test.js +++ /dev/null @@ -1,85 +0,0 @@ -/*<% if (false) { %> -Copyright 2019 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. -<% } %> -* -*/ - - -jest.mock('@adobe/aio-sdk', () => ({ - Target: { - init: jest.fn() - }, - Core: { - Logger: jest.fn() - } -})) - -const { Core, Target } = require('@adobe/aio-sdk') -const mockTargetInstance = { getActivities: jest.fn() } -const mockLoggerInstance = { info: jest.fn(), debug: jest.fn(), error: jest.fn() } -Core.Logger.mockReturnValue(mockLoggerInstance) -Target.init.mockResolvedValue(mockTargetInstance) - -const action = require('./<%= actionRelPath %>') - -beforeEach(() => { - Target.init.mockClear() // only clears calls stats - mockTargetInstance.getActivities.mockReset() // clears calls + mock implementation - - Core.Logger.mockClear() - mockLoggerInstance.info.mockReset() - mockLoggerInstance.debug.mockReset() - mockLoggerInstance.error.mockReset() -}) - -const fakeRequestParams = { tenant: 'fakeId', apiKey: 'fakeKey', __ow_headers: { authorization: 'Bearer fakeToken' } } -describe('<%= actionName %>', () => { - test('main should be defined', () => { - expect(action.main).toBeInstanceOf(Function) - }) - test('should set logger to use LOG_LEVEL param', async () => { - await action.main({ ...fakeRequestParams, LOG_LEVEL: 'fakeLevel' }) - expect(Core.Logger).toHaveBeenCalledWith(expect.any(String), { level: 'fakeLevel' }) - }) - test('Target sdk should be initialized with input credentials', async () => { - await action.main({ ...fakeRequestParams, otherParam: 'fake4' }) - expect(Target.init).toHaveBeenCalledWith('fakeId', 'fakeKey', 'fakeToken') - }) - test('should return an http response with Target activities', async () => { - const fakeResponse = { activities: 'fake' } - mockTargetInstance.getActivities.mockResolvedValue(fakeResponse) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - statusCode: 200, - body: fakeResponse - }) - }) - test('if there is an error should return a 500 and log the error', async () => { - const fakeError = new Error('fake') - mockTargetInstance.getActivities.mockRejectedValue(fakeError) - const response = await action.main(fakeRequestParams) - expect(response).toEqual({ - error: { - statusCode: 500, - body: { error: 'server error' } - } - }) - expect(mockLoggerInstance.error).toHaveBeenCalledWith(fakeError) - }) - test('missing input request parameters, should return 400', async () => { - const response = await action.main({}) - expect(response).toEqual({ - error: { - statusCode: 400, - body: { error: 'missing header(s) \'authorization\' and missing parameter(s) \'apiKey,tenant\'' } - } - }) - }) -}) diff --git a/generators/index.js b/generators/index.js index 83f79f28..8f553c49 100644 --- a/generators/index.js +++ b/generators/index.js @@ -9,9 +9,6 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const excshell = require('@adobe/generator-app-excshell') -const assetComputeWorker = require('@adobe/generator-app-asset-compute') - module.exports = { 'add-action': require('./add-action'), 'add-ci': require('./add-ci'), @@ -19,9 +16,5 @@ module.exports = { 'add-vscode-config': require('./add-vscode-config'), 'add-web-assets': require('./add-web-assets'), application: require('./application'), - 'base-app': require('./base-app'), - extensions: { - 'dx/excshell/1': excshell, - 'dx/asset-compute/worker/1': assetComputeWorker - } + 'base-app': require('./base-app') } diff --git a/package.json b/package.json index 52bcdbdb..dc210ee6 100644 --- a/package.json +++ b/package.json @@ -45,8 +45,13 @@ }, "dependencies": { "@adobe/aio-lib-env": "^2.0.0", + "@adobe/generator-add-action-analytics": "^0.1.1", "@adobe/generator-add-action-asset-compute": "^0.2.1", + "@adobe/generator-add-action-audience-manager-cd": "^0.1.1", + "@adobe/generator-add-action-campaign-standard": "^0.1.1", + "@adobe/generator-add-action-customer-profile": "^0.1.1", "@adobe/generator-add-action-generic": "^0.2.2", + "@adobe/generator-add-action-target": "^0.1.1", "@adobe/generator-add-web-assets-exc-raw-html": "^0.2.1", "@adobe/generator-add-web-assets-exc-react": "^0.2.1", "@adobe/generator-app-asset-compute": "^0.2.0", diff --git a/test/generators/add-action/analytics.test.js b/test/generators/add-action/analytics.test.js deleted file mode 100644 index e345f7fe..00000000 --- a/test/generators/add-action/analytics.test.js +++ /dev/null @@ -1,172 +0,0 @@ -/* eslint-disable jest/expect-expect */ -/* -Copyright 2019 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 helpers = require('yeoman-test') -const assert = require('yeoman-assert') -const fs = require('fs') -const yaml = require('js-yaml') -const path = require('path') -const { EOL } = require('os') -const cloneDeep = require('lodash.clonedeep') - -const theGeneratorPath = require.resolve('../../../generators/add-action/analytics') -const Generator = require('yeoman-generator') - -const { constants } = require('@adobe/generator-app-common-lib') - -describe('prototype', () => { - test('exports a yeoman generator', () => { - expect(require(theGeneratorPath).prototype).toBeInstanceOf(Generator) - }) -}) - -function assertGeneratedFiles (actionName) { - assert.file(`${constants.actionsDirname}/${actionName}/index.js`) - - assert.file(`test/${actionName}.test.js`) - assert.file(`e2e/${actionName}.e2e.test.js`) - - assert.file(`${constants.actionsDirname}/utils.js`) - assert.file('test//utils.test.js') - - assert.file('ext.config.yaml') - assert.file('.env') -} - -// pkgName is optional -function assertManifestContent (actionName, pkgName) { - const json = yaml.load(fs.readFileSync('ext.config.yaml').toString()) - expect(json.runtimeManifest.packages).toBeDefined() - - // default packageName is path.basename(path.dirname('ext.config.yaml')) - pkgName = pkgName || path.basename(process.cwd()) - - expect(json.runtimeManifest.packages[pkgName].actions[actionName]).toEqual({ - function: `${constants.actionsDirname}/${actionName}/index.js`, - web: 'yes', - runtime: constants.defaultRuntimeKind, - inputs: { - LOG_LEVEL: 'debug', - apiKey: '$SERVICE_API_KEY', - companyId: '$ANALYTICS_COMPANY_ID' - }, - annotations: { - final: true, - 'require-adobe-auth': true - } - }) -} - -function assertEnvContent (prevContent) { - assert.fileContent('.env', `## please provide your Adobe I/O Analytics company id${EOL}#ANALYTICS_COMPANY_ID=`) - assert.fileContent('.env', prevContent) -} - -function assertActionCodeContent (actionName) { - const theFile = `${constants.actionsDirname}/${actionName}/index.js` - // a few checks to make sure the action calls the analytics sdk - assert.fileContent( - theFile, - 'const { Core, Analytics } = require(\'@adobe/aio-sdk\')' - ) - assert.fileContent( - theFile, - 'const requiredParams = [\'apiKey\', \'companyId\']' - ) - assert.fileContent( - theFile, - 'const requiredHeaders = [\'Authorization\']' - ) - assert.fileContent( - theFile, - 'const analyticsClient = await Analytics.init(params.companyId, params.apiKey, token)' - ) - assert.fileContent( - theFile, - 'const collections = await analyticsClient.getCollections({ limit: 5, page: 0 })' - ) -} - -describe('run', () => { - test('--skip-prompt', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'analytics' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('--skip-prompt, and action with default name already exists', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync('ext.config.yaml', yaml.dump({ - runtimeManifest: { - packages: { - somepackage: { - actions: { - analytics: { function: 'fake.js' } - } - } - } - } - })) - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'analytics-1' - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName, 'somepackage') - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('user input actionName=fakeAction', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = false - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .withPrompts({ actionName: 'fakeAction' }) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - const actionName = 'fakeAction' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) -}) diff --git a/test/generators/add-action/audience-manager-cd.test.js b/test/generators/add-action/audience-manager-cd.test.js deleted file mode 100644 index 637fa173..00000000 --- a/test/generators/add-action/audience-manager-cd.test.js +++ /dev/null @@ -1,149 +0,0 @@ -/* eslint-disable jest/expect-expect */ -/* -Copyright 2019 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 helpers = require('yeoman-test') -const assert = require('yeoman-assert') -const fs = require('fs') -const yaml = require('js-yaml') -const cloneDeep = require('lodash.clonedeep') -const path = require('path') -const theGeneratorPath = require.resolve('../../../generators/add-action/audience-manager-cd') -const Generator = require('yeoman-generator') - -const { constants } = require('@adobe/generator-app-common-lib') - -describe('prototype', () => { - test('exports a yeoman generator', () => { - expect(require(theGeneratorPath).prototype).toBeInstanceOf(Generator) - }) -}) - -function assertGeneratedFiles (actionName) { - assert.file(`${constants.actionsDirname}/${actionName}/index.js`) - - assert.file(`test/${actionName}.test.js`) - assert.file(`e2e/${actionName}.e2e.test.js`) - - assert.file(`${constants.actionsDirname}/utils.js`) - assert.file('test/utils.test.js') - - assert.file('ext.config.yaml') -} - -// pkgName is optional -function assertManifestContent (actionName, pkgName) { - const json = yaml.load(fs.readFileSync('ext.config.yaml').toString()) - expect(json.runtimeManifest.packages).toBeDefined() - - // default packageName is path.basename(path.dirname('ext.config.yaml')) - pkgName = pkgName || path.basename(process.cwd()) - - expect(json.runtimeManifest.packages[pkgName].actions[actionName]).toEqual({ - function: `${constants.actionsDirname}/${actionName}/index.js`, - web: 'yes', - runtime: constants.defaultRuntimeKind, - inputs: { - LOG_LEVEL: 'debug', - apiKey: '$SERVICE_API_KEY' - }, - annotations: { - final: true, - 'require-adobe-auth': true - } - }) -} - -function assertActionCodeContent (actionName) { - const theFile = `${constants.actionsDirname}/${actionName}/index.js` - // a few checks to make sure the action calls the audienceManagerCD sdk - assert.fileContent( - theFile, - 'const { Core, AudienceManagerCD } = require(\'@adobe/aio-sdk\')' - ) - assert.fileContent( - theFile, - 'const requiredParams = [\'apiKey\', \'id\', \'dataSourceId\']' - ) - assert.fileContent( - theFile, - 'const requiredHeaders = [\'Authorization\', \'x-gw-ims-org-id\']' - ) - assert.fileContent( - theFile, - 'const audienceManagerClient = await AudienceManagerCD.init(orgId, params.apiKey, token)' - ) - assert.fileContent( - theFile, - 'const profiles = await audienceManagerClient.getProfile(params.id, params.dataSourceId)' - ) -} - -describe('run', () => { - test('--skip-prompt', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - await helpers.run(theGeneratorPath) - .withOptions(options) - - // default - const actionName = 'audience-manager-cd' - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('--skip-prompt, and action with default name already exists', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync('ext.config.yaml', yaml.dump({ - runtimeManifest: { - packages: { - somepackage: { - actions: { - 'audience-manager-cd': { function: 'fake.js' } - } - } - } - } - })) - }) - - // default - const actionName = 'audience-manager-cd-1' - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName, 'somepackage') - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('user input actionName=fakeAction', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = false - await helpers.run(theGeneratorPath) - .withOptions(options) - .withPrompts({ actionName: 'fakeAction' }) - - const actionName = 'fakeAction' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) -}) diff --git a/test/generators/add-action/campaign-standard.test.js b/test/generators/add-action/campaign-standard.test.js deleted file mode 100644 index 4d5f01b8..00000000 --- a/test/generators/add-action/campaign-standard.test.js +++ /dev/null @@ -1,172 +0,0 @@ -/* eslint-disable jest/expect-expect */ -/* -Copyright 2019 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 helpers = require('yeoman-test') -const assert = require('yeoman-assert') -const fs = require('fs') -const yaml = require('js-yaml') -const path = require('path') -const { EOL } = require('os') -const cloneDeep = require('lodash.clonedeep') - -const theGeneratorPath = require.resolve('../../../generators/add-action/campaign-standard') -const Generator = require('yeoman-generator') - -const { constants } = require('@adobe/generator-app-common-lib') - -describe('prototype', () => { - test('exports a yeoman generator', () => { - expect(require(theGeneratorPath).prototype).toBeInstanceOf(Generator) - }) -}) - -function assertGeneratedFiles (actionName) { - assert.file(`${constants.actionsDirname}/${actionName}/index.js`) - - assert.file(`test/${actionName}.test.js`) - assert.file(`e2e/${actionName}.e2e.test.js`) - - assert.file(`${constants.actionsDirname}/utils.js`) - assert.file('test/utils.test.js') - - assert.file('ext.config.yaml') - assert.file('.env') -} - -// pkgName is optional -function assertManifestContent (actionName, pkgName) { - const json = yaml.load(fs.readFileSync('ext.config.yaml').toString()) - expect(json.runtimeManifest.packages).toBeDefined() - - // default packageName is path.basename(path.dirname('ext.config.yaml')) - pkgName = pkgName || path.basename(process.cwd()) - - expect(json.runtimeManifest.packages[pkgName].actions[actionName]).toEqual({ - function: `${constants.actionsDirname}/${actionName}/index.js`, - web: 'yes', - runtime: constants.defaultRuntimeKind, - inputs: { - LOG_LEVEL: 'debug', - apiKey: '$SERVICE_API_KEY', - tenant: '$CAMPAIGN_STANDARD_TENANT' - }, - annotations: { - final: true, - 'require-adobe-auth': true - } - }) -} - -function assertEnvContent (prevContent) { - assert.fileContent('.env', `## please provide your Adobe I/O Campaign Standard tenant${EOL}#CAMPAIGN_STANDARD_TENANT=`) - assert.fileContent('.env', prevContent) -} - -function assertActionCodeContent (actionName) { - const theFile = `${constants.actionsDirname}/${actionName}/index.js` - // a few checks to make sure the action calls the sdk - assert.fileContent( - theFile, - 'const { Core, CampaignStandard } = require(\'@adobe/aio-sdk\')' - ) - assert.fileContent( - theFile, - 'const requiredParams = [\'apiKey\', \'tenant\']' - ) - assert.fileContent( - theFile, - 'const requiredHeaders = [\'Authorization\']' - ) - assert.fileContent( - theFile, - 'const campaignClient = await CampaignStandard.init(params.tenant, params.apiKey, token)' - ) - assert.fileContent( - theFile, - 'const profiles = await campaignClient.getAllProfiles()' - ) -} - -describe('run', () => { - test('--skip-prompt', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'campaign-standard' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('--skip-prompt, and action with default name already exists', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync('ext.config.yaml', yaml.dump({ - runtimeManifest: { - packages: { - somepackage: { - actions: { - 'campaign-standard': { function: 'fake.js' } - } - } - } - } - })) - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'campaign-standard-1' - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName, 'somepackage') - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('user input actionName=fakeAction', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = false - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .withPrompts({ actionName: 'fakeAction' }) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - const actionName = 'fakeAction' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) -}) diff --git a/test/generators/add-action/customer-profile.test.js b/test/generators/add-action/customer-profile.test.js deleted file mode 100644 index 58f0a668..00000000 --- a/test/generators/add-action/customer-profile.test.js +++ /dev/null @@ -1,179 +0,0 @@ -/* eslint-disable jest/expect-expect */ -/* -Copyright 2019 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 helpers = require('yeoman-test') -const assert = require('yeoman-assert') -const fs = require('fs') -const yaml = require('js-yaml') -const path = require('path') -const { EOL } = require('os') -const cloneDeep = require('lodash.clonedeep') - -const theGeneratorPath = require.resolve('../../../generators/add-action/customer-profile') -const Generator = require('yeoman-generator') - -const { constants } = require('@adobe/generator-app-common-lib') - -describe('prototype', () => { - test('exports a yeoman generator', () => { - expect(require(theGeneratorPath).prototype).toBeInstanceOf(Generator) - }) -}) - -function assertGeneratedFiles (actionName) { - assert.file(`${constants.actionsDirname}/${actionName}/index.js`) - - assert.file(`test/${actionName}.test.js`) - assert.file(`e2e/${actionName}.e2e.test.js`) - - assert.file(`${constants.actionsDirname}/utils.js`) - assert.file('test/utils.test.js') - - assert.file('ext.config.yaml') - assert.file('.env') -} - -// pkgName is optional -function assertManifestContent (actionName, pkgName) { - const json = yaml.load(fs.readFileSync('ext.config.yaml').toString()) - expect(json.runtimeManifest.packages).toBeDefined() - - // default packageName is path.basename(path.dirname('ext.config.yaml')) - pkgName = pkgName || path.basename(process.cwd()) - - expect(json.runtimeManifest.packages[pkgName].actions[actionName]).toEqual({ - function: `${constants.actionsDirname}/${actionName}/index.js`, - web: 'yes', - runtime: constants.defaultRuntimeKind, - inputs: { - LOG_LEVEL: 'debug', - tenant: '$CUSTOMER_PROFILE_TENANT', - apiKey: '$SERVICE_API_KEY' - }, - annotations: { - final: true, - 'require-adobe-auth': true - } - }) -} - -function assertEnvContent (prevContent) { - assert.fileContent('.env', `## please provide your Adobe Experience Platform Realtime Customer Profile tenant${EOL}#CUSTOMER_PROFILE_TENANT=`) - assert.fileContent('.env', prevContent) -} - -function assertActionCodeContent (actionName) { - const theFile = `${constants.actionsDirname}/${actionName}/index.js` - // a few checks to make sure the action calls the sdk - assert.fileContent( - theFile, - 'const { Core, CustomerProfile } = require(\'@adobe/aio-sdk\')' - ) - assert.fileContent( - theFile, - 'const requiredParams = [\'tenant\', \'apiKey\', \'entityId\', \'entityIdNS\']' - ) - assert.fileContent( - theFile, - 'const requiredHeaders = [\'Authorization\', \'x-gw-ims-org-id\']' - ) - assert.fileContent( - theFile, - 'const client = await CustomerProfile.init(params.tenant, orgId, params.apiKey, token)' - ) - assert.fileContent( - theFile, - `const profile = await client.getProfile({ - entityId: params.entityId, - entityIdNS: params.entityIdNS - }); - const response = { - statusCode: 200, - body: profile - }` - ) -} - -describe('run', () => { - test('--skip-prompt', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'customer-profile' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('--skip-prompt, and action with default name already exists', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync('ext.config.yaml', yaml.dump({ - runtimeManifest: { - packages: { - somepackage: { - actions: { - 'customer-profile': { function: 'fake.js' } - } - } - } - } - })) - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'customer-profile-1' - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName, 'somepackage') - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('user input actionName=fakeAction', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = false - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .withPrompts({ actionName: 'fakeAction' }) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - const actionName = 'fakeAction' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) -}) diff --git a/test/generators/add-action/index.test.js b/test/generators/add-action/index.test.js index 7f1a575a..8032cbf8 100644 --- a/test/generators/add-action/index.test.js +++ b/test/generators/add-action/index.test.js @@ -16,8 +16,14 @@ const Generator = require('yeoman-generator') const { constants } = require('@adobe/generator-app-common-lib') const { sdkCodes } = constants const cloneDeep = require('lodash.clonedeep') + const generic = require('@adobe/generator-add-action-generic') const assetCompute = require('@adobe/generator-add-action-asset-compute') +const target = require('@adobe/generator-add-action-target') +const analytics = require('@adobe/generator-add-action-analytics') +const campaign = require('@adobe/generator-add-action-campaign-standard') +const customerProfile = require('@adobe/generator-add-action-customer-profile') +const audienceManagerCD = require('@adobe/generator-add-action-audience-manager-cd') const expectedSeparator = expect.objectContaining({ type: 'separator', @@ -30,15 +36,15 @@ const expectedChoices = { }, [sdkCodes.analytics]: { name: 'Adobe Analytics', - value: require('../../../generators/add-action/analytics') + value: analytics }, [sdkCodes.target]: { name: 'Adobe Target', - value: require('../../../generators/add-action/target') + value: target }, [sdkCodes.campaign]: { name: 'Adobe Campaign Standard', - value: require('../../../generators/add-action/campaign-standard') + value: campaign }, [sdkCodes.assetCompute]: { name: 'Adobe Asset Compute Worker', @@ -46,11 +52,11 @@ const expectedChoices = { }, [sdkCodes.customerProfile]: { name: 'Adobe Experience Platform: Realtime Customer Profile', - value: require('../../../generators/add-action/customer-profile') + value: customerProfile }, [sdkCodes.audienceManagerCD]: { name: 'Adobe Audience Manager: Customer Data', - value: require('../../../generators/add-action/audience-manager-cd') + value: audienceManagerCD } } diff --git a/test/generators/add-action/target.test.js b/test/generators/add-action/target.test.js deleted file mode 100644 index 04a1d869..00000000 --- a/test/generators/add-action/target.test.js +++ /dev/null @@ -1,173 +0,0 @@ -/* eslint-disable jest/expect-expect */ -/* -Copyright 2019 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 helpers = require('yeoman-test') -const assert = require('yeoman-assert') -const fs = require('fs') -const yaml = require('js-yaml') -const path = require('path') -const { EOL } = require('os') -const cloneDeep = require('lodash.clonedeep') - -const theGeneratorPath = require.resolve('../../../generators/add-action/target') -const Generator = require('yeoman-generator') - -const { constants } = require('@adobe/generator-app-common-lib') - -describe('prototype', () => { - test('exports a yeoman generator', () => { - expect(require(theGeneratorPath).prototype).toBeInstanceOf(Generator) - }) -}) - -function assertGeneratedFiles (actionName) { - assert.file(`${constants.actionsDirname}/${actionName}/index.js`) - - assert.file(`test/${actionName}.test.js`) - assert.file(`e2e/${actionName}.e2e.test.js`) - - assert.file(`${constants.actionsDirname}/utils.js`) - assert.file('test/utils.test.js') - - assert.file('ext.config.yaml') - assert.file('.env') -} - -// pkgName is optional -function assertManifestContent (actionName, pkgName) { - const json = yaml.load(fs.readFileSync('ext.config.yaml').toString()) - expect(json.runtimeManifest.packages).toBeDefined() - - // default packageName is path.basename(path.dirname('ext.config.yaml')) - pkgName = pkgName || path.basename(process.cwd()) - - expect(json.runtimeManifest.packages[pkgName].actions[actionName]).toEqual({ - function: `${constants.actionsDirname}/${actionName}/index.js`, - web: 'yes', - runtime: constants.defaultRuntimeKind, - inputs: { - LOG_LEVEL: 'debug', - apiKey: '$SERVICE_API_KEY', - tenant: '$TARGET_TENANT' - }, - annotations: { - final: true, - 'require-adobe-auth': true - } - }) -} - -function assertEnvContent (prevContent) { - assert.fileContent('.env', `## please provide your Adobe I/O Target tenant${EOL}#TARGET_TENANT=`) - assert.fileContent('.env', prevContent) -} - -function assertActionCodeContent (actionName) { - const theFile = `${constants.actionsDirname}/${actionName}/index.js` - // a few checks to make sure the action calls the sdk - assert.fileContent( - theFile, - 'const { Core, Target } = require(\'@adobe/aio-sdk\')' - ) - assert.fileContent( - theFile, - 'const requiredParams = [\'apiKey\', \'tenant\']' - ) - assert.fileContent( - theFile, - 'const requiredHeaders = [\'Authorization\']' - ) - assert.fileContent( - theFile, - 'const targetClient = await Target.init(params.tenant, params.apiKey, token)' - ) - assert.fileContent( - theFile, - 'const activities = await targetClient.getActivities({ limit: 5, offset: 0 })' - ) -} - -describe('run', () => { - test('--skip-prompt', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'target' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('--skip-prompt, and action with default name already exists', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = true - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .inTmpDir(dir => { - fs.writeFileSync('ext.config.yaml', yaml.dump({ - runtimeManifest: { - packages: { - somepackage: { - actions: { - target: { function: 'fake.js' } - } - } - } - } - })) - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - // default - const actionName = 'target-1' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName, 'somepackage') - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) - - test('user input actionName=fakeAction', async () => { - const options = cloneDeep(global.basicGeneratorOptions) - options['skip-prompt'] = false - const prevDotEnvContent = `PREVIOUSCONTENT${EOL}` - await helpers.run(theGeneratorPath) - .withOptions(options) - .withPrompts({ actionName: 'fakeAction' }) - .inTmpDir(dir => { - fs.writeFileSync(path.join(dir, '.env'), prevDotEnvContent) - }) - - const actionName = 'fakeAction' - - assertGeneratedFiles(actionName) - assertActionCodeContent(actionName) - assertManifestContent(actionName) - assertEnvContent(prevDotEnvContent) - assertDependencies(fs, { '@adobe/aio-sdk': expect.any(String) }, { '@openwhisk/wskdebug': expect.any(String) }) - assertNodeEngines(fs, constants.nodeEngines) - }) -}) diff --git a/test/generators/index.test.js b/test/generators/index.test.js index 078e32b0..7eeb4720 100644 --- a/test/generators/index.test.js +++ b/test/generators/index.test.js @@ -19,5 +19,4 @@ test('all exports', () => { expect(generators['add-web-assets']).toBeDefined() expect(generators.application).toBeDefined() expect(generators['base-app']).toBeDefined() - expect(generators.extensions).toBeDefined() }) diff --git a/test/jest.setup.js b/test/jest.setup.js index 7b9f5d64..ea9a8fc4 100644 --- a/test/jest.setup.js +++ b/test/jest.setup.js @@ -12,6 +12,8 @@ governing permissions and limitations under the License. const path = require('path') const { stdout, stderr } = require('stdout-stderr') +jest.setTimeout(30000) + process.on('unhandledRejection', error => { throw error })