Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions src/tasks/demo-url-processor/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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' });
}
Expand Down
6 changes: 4 additions & 2 deletions src/tasks/disable-import-audit-processor/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 5 additions & 1 deletion src/tasks/opportunity-status-processor/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
97 changes: 54 additions & 43 deletions test/tasks/demo-url-processor/demo-url-processor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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 () => {
Expand All @@ -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 () => {
Expand All @@ -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 () => {
Expand All @@ -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 () => {
Expand All @@ -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;
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand All @@ -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;
});
});
});