diff --git a/src/tasks/demo-url-processor/handler.js b/src/tasks/demo-url-processor/handler.js index 0633cf8..f55e8dd 100644 --- a/src/tasks/demo-url-processor/handler.js +++ b/src/tasks/demo-url-processor/handler.js @@ -17,6 +17,7 @@ const TASK_TYPE = 'demo-url-processor'; /** * Gets the IMS tenant ID from the organization + * @param {object} imsOrgId - The IMS organization ID * @param {object} organization - The organization object * @param {object} context - The context object * @param {object} log - The log object @@ -44,15 +45,15 @@ function getImsTenantId(imsOrgId, organization, context, log) { } /** - * Runs the audit status processor - * @param {object} demoUrlMessage - The demoUrlMessage object + * Runs the demo URL processor + * @param {object} message - The message object * @param {object} context - The context object */ export async function runDemoUrlProcessor(message, context) { const { log, env, dataAccess } = context; const { Organization } = dataAccess; const { - siteId, imsOrgId, organizationId, taskContext, + siteId, siteUrl, imsOrgId, organizationId, taskContext, } = message; const { experienceUrl, slackContext, @@ -61,22 +62,35 @@ export async function runDemoUrlProcessor(message, context) { log.info('Processing demo url for site:', { taskType: TASK_TYPE, siteId, + siteUrl, + imsOrgId, experienceUrl, organizationId, }); - const organization = await Organization.findById(organizationId); - if (!organization) { - log.error(`Organization not found for organizationId: ${organizationId}`); - await say(env, log, slackContext, `:x: Organization not found for organizationId: ${organizationId}`); - return ok({ message: 'Organization not found' }); + let imsTenantId = context.env.DEFAULT_TENANT_ID; + try { + const organization = await Organization.findById(organizationId); + if (!organization) { + log.error(`Organization not found for organizationId: ${organizationId}`); + if (slackContext) { + await say(env, log, slackContext, `:x: Organization not found for organizationId: ${organizationId}`); + } + return ok({ message: 'Organization not found' }); + } + imsTenantId = getImsTenantId(imsOrgId, organization, context, log); + } catch (error) { + log.error(`Error finding organization for organizationId: ${organizationId}`, error); } - const imsTenantId = getImsTenantId(imsOrgId, organization, context, log); const demoUrl = `${experienceUrl}?organizationId=${organizationId}#/@${imsTenantId}/sites-optimizer/sites/${siteId}/home`; - const slackMessage = `:white_check_mark: Setup complete! Access your demo environment here: ${demoUrl}`; - await say(env, log, slackContext, slackMessage); - log.info(`Setup complete! Access your demo environment here: ${demoUrl}`); + const slackMessage = `:white_check_mark: Setup complete for site ${siteUrl}! Access your environment here: ${demoUrl}`; + + if (slackContext) { + await say(env, log, slackContext, slackMessage); + } + + log.info(`Setup complete for site ${siteUrl}! Access your environment here: ${demoUrl}`); return ok({ message: 'Demo URL processor completed' }); } diff --git a/src/tasks/disable-import-audit-processor/handler.js b/src/tasks/disable-import-audit-processor/handler.js index fe8415e..5ff8382 100644 --- a/src/tasks/disable-import-audit-processor/handler.js +++ b/src/tasks/disable-import-audit-processor/handler.js @@ -54,8 +54,10 @@ export async function runDisableImportAuditProcessor(message, context) { await site.save(); await configuration.save(); - log.info('Disabled imports and audits'); - const slackMessage = `:broom: *Disabled imports*: ${importTypes.join(', ')} *and audits*: ${auditTypes.join(', ')}`; + log.info(`For site: ${siteUrl}: Disabled imports and audits`); + let slackMessage = `:broom: *For site: ${siteUrl}: Disabled imports*: ${importTypes.join(', ')} *and audits*: ${auditTypes.join(', ')}`; + await say(env, log, slackContext, slackMessage); + slackMessage = ':information_source: The list of enabled imports and audits may differ from the disabled ones because items that are already enabled are not automatically disabled.'; await say(env, log, slackContext, slackMessage); } catch (error) { log.error('Error in disable import and audit processor:', error); diff --git a/src/tasks/opportunity-status-processor/handler.js b/src/tasks/opportunity-status-processor/handler.js index 03e07f6..52e3c81 100644 --- a/src/tasks/opportunity-status-processor/handler.js +++ b/src/tasks/opportunity-status-processor/handler.js @@ -50,7 +50,9 @@ function getOpportunityTitle(opportunityType) { export async function runOpportunityStatusProcessor(message, context) { const { log, env, dataAccess } = context; const { Site } = dataAccess; - const { siteId, organizationId, taskContext } = message; + const { + siteId, siteUrl, organizationId, taskContext, + } = message; const { auditTypes = [], slackContext, } = taskContext; @@ -98,7 +100,9 @@ export async function runOpportunityStatusProcessor(message, context) { // send status messages to slack if (statusMessages.length > 0) { + const slackMessage = `:white_check_mark: *Opportunities status for site ${siteUrl}*:`; const combinedMessage = statusMessages.join('\n'); + await say(env, log, slackContext, slackMessage); await say(env, log, slackContext, combinedMessage); } } catch (error) { diff --git a/test/tasks/demo-url-processor/demo-url-processor.test.js b/test/tasks/demo-url-processor/demo-url-processor.test.js index c908c3f..1e62230 100644 --- a/test/tasks/demo-url-processor/demo-url-processor.test.js +++ b/test/tasks/demo-url-processor/demo-url-processor.test.js @@ -50,6 +50,7 @@ describe('Demo URL Processor', () => { // Mock message message = { siteId: 'test-site-id', + siteUrl: 'example.com', imsOrgId: '8C6043F15F43B6390A49401A@AdobeOrg', organizationId: 'test-org-id', taskContext: { @@ -74,36 +75,13 @@ describe('Demo URL Processor', () => { expect(context.log.info.calledWith('Processing demo url for site:', { taskType: 'demo-url-processor', siteId: 'test-site-id', + siteUrl: 'example.com', + imsOrgId: '8C6043F15F43B6390A49401A@AdobeOrg', experienceUrl: 'https://example.com', organizationId: 'test-org-id', })).to.be.true; const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@aem-sites-engineering/sites-optimizer/sites/test-site-id/home'; - expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true; - }); - - it('should handle missing slackContext in taskContext', async () => { - // Set up the IMS_ORG_TENANT_ID_MAPPINGS secret in context - context.env.IMS_ORG_TENANT_ID_MAPPINGS = JSON.stringify({ - '8C6043F15F43B6390A49401A@AdobeOrg': 'aem-sites-engineering', - }); - - delete message.taskContext.slackContext; - await runDemoUrlProcessor(message, context); - const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@aem-sites-engineering/sites-optimizer/sites/test-site-id/home'; - expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true; - }); - - it('should use IMS_ORG_TENANT_ID_MAPPINGS mapping when available', async () => { - // Set up the IMS_ORG_TENANT_ID_MAPPINGS secret in context - context.env.IMS_ORG_TENANT_ID_MAPPINGS = JSON.stringify({ - '8C6043F15F43B6390A49401A@AdobeOrg': 'aem-sites-engineering', - }); - - await runDemoUrlProcessor(message, context); - - // Should use the mapped tenant name instead of the fallback - const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@aem-sites-engineering/sites-optimizer/sites/test-site-id/home'; - expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true; + expect(context.log.info.calledWith(`Setup complete for site example.com! Access your environment here: ${expectedDemoUrl}`)).to.be.true; }); it('should fallback to name-based tenant when IMS_ORG_TENANT_ID_MAPPINGS mapping is not available', async () => { @@ -114,7 +92,7 @@ describe('Demo URL Processor', () => { // Should use the fallback name-based tenant (lowercase, no spaces) const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@adobesitesengineering/sites-optimizer/sites/test-site-id/home'; - expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true; + expect(context.log.info.calledWith(`Setup complete for site example.com! Access your environment here: ${expectedDemoUrl}`)).to.be.true; }); it('should fallback to name-based tenant when IMS_ORG_TENANT_ID_MAPPINGS mapping is invalid JSON', async () => { @@ -125,20 +103,7 @@ describe('Demo URL Processor', () => { // Should use the fallback name-based tenant const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@adobesitesengineering/sites-optimizer/sites/test-site-id/home'; - expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true; - }); - - it('should fallback to name-based tenant when IMS_ORG_TENANT_ID_MAPPINGS mapping does not contain the imsOrgId', async () => { - // Set IMS_ORG_TENANT_ID_MAPPINGS secret with different mapping - context.env.IMS_ORG_TENANT_ID_MAPPINGS = JSON.stringify({ - 'DIFFERENT_ORG_ID@AdobeOrg': 'different-team', - }); - - await runDemoUrlProcessor(message, context); - - // Should use the fallback name-based tenant since the imsOrgId is not in the mapping - const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@adobesitesengineering/sites-optimizer/sites/test-site-id/home'; - expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true; + expect(context.log.info.calledWith(`Setup complete for site example.com! Access your environment here: ${expectedDemoUrl}`)).to.be.true; }); it('should handle organization not found error', async () => { @@ -150,7 +115,7 @@ describe('Demo URL Processor', () => { // Should log error and return early expect(context.log.error.calledWith('Organization not found for organizationId: test-org-id')).to.be.true; // Should not log the success message - expect(context.log.info.calledWithMatch(sinon.match('Setup complete!'))).to.be.false; + expect(context.log.info.calledWithMatch(sinon.match('Setup complete for site example.com!'))).to.be.false; }); it('should handle organization with missing name property', async () => { @@ -168,7 +133,53 @@ describe('Demo URL Processor', () => { // Should log error about missing name and use fallback expect(context.log.error.calledWith('Organization name is missing, using default tenant ID')).to.be.true; const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@default-tenant/sites-optimizer/sites/test-site-id/home'; - expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true; + expect(context.log.info.calledWith(`Setup complete for site example.com! Access your environment here: ${expectedDemoUrl}`)).to.be.true; + }); + + it('should return success message when processing completes', async () => { + // Set up the IMS_ORG_TENANT_ID_MAPPINGS secret in context + context.env.IMS_ORG_TENANT_ID_MAPPINGS = JSON.stringify({ + '8C6043F15F43B6390A49401A@AdobeOrg': 'aem-sites-engineering', + }); + + // The function should complete without throwing an error + await runDemoUrlProcessor(message, context); + + // Verify that the success message was logged + expect(context.log.info.calledWithMatch(sinon.match('Setup complete for site example.com!'))).to.be.true; + }); + + it('should handle error when Organization.findById throws an exception', async () => { + // Set up the IMS_ORG_TENANT_ID_MAPPINGS secret in context + context.env.IMS_ORG_TENANT_ID_MAPPINGS = JSON.stringify({ + '8C6043F15F43B6390A49401A@AdobeOrg': 'aem-sites-engineering', + }); + + // Mock Organization.findById to throw an error + context.dataAccess.Organization.findById.rejects(new Error('Database connection failed')); + + // The function should handle the error gracefully without throwing + await runDemoUrlProcessor(message, context); + + // Verify that the error was logged + expect(context.log.error.calledWith('Error finding organization for organizationId: test-org-id', sinon.match.any)).to.be.true; + + // Note: The current implementation continues execution even after errors, + // so the success message will still be logged. This test verifies that + // the error handling works and the function completes successfully. + + // Verify that the success message was still logged (since the function continues) + expect(context.log.info.calledWithMatch(sinon.match('Setup complete for site example.com!'))).to.be.true; + + // Verify that the processing log was recorded + expect(context.log.info.calledWith('Processing demo url for site:', { + taskType: 'demo-url-processor', + siteId: 'test-site-id', + siteUrl: 'example.com', + imsOrgId: '8C6043F15F43B6390A49401A@AdobeOrg', + experienceUrl: 'https://example.com', + organizationId: 'test-org-id', + })).to.be.true; }); }); }); diff --git a/test/tasks/disable-import-audit-processor/disable-import-audit-processor.test.js b/test/tasks/disable-import-audit-processor/disable-import-audit-processor.test.js index ba3423f..4fea184 100644 --- a/test/tasks/disable-import-audit-processor/disable-import-audit-processor.test.js +++ b/test/tasks/disable-import-audit-processor/disable-import-audit-processor.test.js @@ -105,7 +105,7 @@ describe('Disable Import Audit Processor', () => { // Check saves were called expect(mockSite.save.called).to.be.true; expect(mockConfiguration.save.called).to.be.true; - expect(context.log.info.calledWith('Disabled imports and audits')).to.be.true; + expect(context.log.info.calledWith('For site: https://example.com: Disabled imports and audits')).to.be.true; }); it('should handle site not found error', async () => { @@ -132,7 +132,7 @@ describe('Disable Import Audit Processor', () => { await runDisableImportAuditProcessor(message, context); // Should complete without error - expect(context.log.info.calledWith('Disabled imports and audits')).to.be.true; + expect(context.log.info.calledWith('For site: https://example.com: Disabled imports and audits')).to.be.true; }); }); });