Skip to content

Commit 6de3cdb

Browse files
get tenant id from imsClient if organization does not have tenantId
1 parent 34ab6ae commit 6de3cdb

5 files changed

Lines changed: 138 additions & 12 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"@adobe/spacecat-shared-http-utils": "1.15.2",
7070
"@adobe/spacecat-shared-slack-client": "^1.3.12",
7171
"@adobe/spacecat-shared-utils": "1.44.1",
72+
"@adobe/spacecat-shared-ims-client": "1.8.6",
7273
"@aws-sdk/client-lambda": "3.851.0",
7374
"@aws-sdk/client-sqs": "3.854.0",
7475
"@aws-sdk/credential-provider-node": "3.848.0",

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import secrets from '@adobe/helix-shared-secrets';
1515
import dataAccess from '@adobe/spacecat-shared-data-access';
1616
import { sqsEventAdapter } from '@adobe/spacecat-shared-utils';
1717
import { internalServerError, notFound, ok } from '@adobe/spacecat-shared-http-utils';
18+
import { imsClientWrapper } from '@adobe/spacecat-shared-ims-client';
1819

1920
import { runOpportunityStatusProcessor as opportunityStatusProcessor } from './tasks/opportunity-status-processor/handler.js';
2021
import { runDisableImportAuditProcessor as disableImportAuditProcessor } from './tasks/disable-import-audit-processor/handler.js';
@@ -76,5 +77,6 @@ async function run(message, context) {
7677
export const main = wrap(run)
7778
.with(dataAccess)
7879
.with(sqsEventAdapter)
80+
.with(imsClientWrapper)
7981
.with(secrets, { name: getSecretName })
8082
.with(helixStatus);

src/tasks/demo-url-processor/handler.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,26 @@ const TASK_TYPE = 'demo-url-processor';
2626
* @returns {string} The IMS tenant ID
2727
*/
2828
async function getImsTenantId(imsOrgId, organization, context, log, env, slackContext) {
29+
// Get tenantId from organization
2930
const { name, tenantId } = organization;
30-
31-
// If tenantId is there, return it
3231
if (tenantId) {
3332
return tenantId;
33+
} else {
34+
// Get tenantId from IMS org details if tenantId is not there in organization
35+
let imsOrgDetails;
36+
try {
37+
imsOrgDetails = await context.imsClient.getImsOrganizationDetails(imsOrgId);
38+
return imsOrgDetails.tenantId;
39+
} catch (error) {
40+
log.error(`Error retrieving IMS Org details: ${error.message}`);
41+
}
3442
}
35-
36-
// If tenantId isn't there, use name to generate (backward compatible for existing orgs)
43+
// As a fallback option, use name to generate tenant id (backward compatible for existing orgs)
3744
if (name) {
3845
return name.toLowerCase().replace(/\s+/g, '');
3946
}
40-
41-
// If name is also not there, log an error and return DEFAULT_TENANT_ID
42-
log.error('Organization name and tenantId are missing, using default tenant ID');
43-
await say(env, log, slackContext, ':x: Organization name and tenantId are missing, using default tenant ID');
47+
log.error('Using default tenant ID');
48+
await say(env, log, slackContext, ':x: Using default tenant ID');
4449
return context.env.DEFAULT_TENANT_ID;
4550
}
4651

test/index.test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,20 @@ describe('Index Tests', () => {
4545
warn: sandbox.stub(),
4646
debug: sandbox.stub(),
4747
},
48+
env: {
49+
imsHost: 'https://ims-na1.adobelogin.com',
50+
clientId: 'test-client-id',
51+
clientCode: 'test-client-code',
52+
clientSecret: 'test-client-secret',
53+
DEFAULT_TENANT_ID: 'default-tenant',
54+
},
55+
imsHost: 'https://ims-na1.adobelogin.com',
56+
clientId: 'test-client-id',
57+
clientCode: 'test-client-code',
58+
clientSecret: 'test-client-secret',
59+
imsClient: {
60+
getImsOrganizationDetails: sandbox.stub(),
61+
},
4862
runtime: {
4963
region: 'us-east-1',
5064
},

test/tasks/demo-url-processor/demo-url-processor.test.js

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ describe('Demo URL Processor', () => {
122122

123123
await runDemoUrlProcessor(message, context);
124124

125-
// Should log error about missing name and tenantId and use fallback
126-
expect(context.log.error.calledWith('Organization name and tenantId are missing, using default tenant ID')).to.be.true;
125+
// Should log error about using default tenant ID
126+
expect(context.log.error.calledWith('Using default tenant ID')).to.be.true;
127127
const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@default-tenant/sites-optimizer/sites/test-site-id/home';
128128
expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true;
129129
});
@@ -194,12 +194,116 @@ describe('Demo URL Processor', () => {
194194
organizationId: 'test-org-id',
195195
})).to.be.true;
196196

197-
// Should log error about missing name and tenantId
198-
expect(context.log.error.calledWith('Organization name and tenantId are missing, using default tenant ID')).to.be.true;
197+
// Should log error about using default tenant ID
198+
expect(context.log.error.calledWith('Using default tenant ID')).to.be.true;
199199

200200
// Should log the completion message with default tenant
201201
const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@default-tenant/sites-optimizer/sites/test-site-id/home';
202202
expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true;
203203
});
204+
205+
it('should get tenantId from imsClient when not available in organization', async () => {
206+
// Mock Organization.findById to return organization without tenantId
207+
context.dataAccess.Organization.findById.resolves({
208+
name: 'Adobe Sites Engineering',
209+
imsOrgId: '8C6043F15F43B6390A49401A@AdobeOrg',
210+
// tenantId property is missing
211+
});
212+
213+
// Mock imsClient to return tenantId
214+
context.imsClient = {
215+
getImsOrganizationDetails: sinon.stub().resolves({
216+
tenantId: 'ims-tenant-id-from-client',
217+
}),
218+
};
219+
220+
await runDemoUrlProcessor(message, context);
221+
222+
// Should call imsClient.getImsOrganizationDetails
223+
expect(context.imsClient.getImsOrganizationDetails.calledWith('8C6043F15F43B6390A49401A@AdobeOrg')).to.be.true;
224+
225+
// Should use the tenantId from imsClient
226+
const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@ims-tenant-id-from-client/sites-optimizer/sites/test-site-id/home';
227+
expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true;
228+
});
229+
230+
it('should fallback to name when imsClient fails and tenantId is missing', async () => {
231+
// Mock Organization.findById to return organization without tenantId
232+
context.dataAccess.Organization.findById.resolves({
233+
name: 'Adobe Sites Engineering',
234+
imsOrgId: '8C6043F15F43B6390A49401A@AdobeOrg',
235+
// tenantId property is missing
236+
});
237+
238+
// Mock imsClient to throw an error
239+
context.imsClient = {
240+
getImsOrganizationDetails: sinon.stub().rejects(new Error('IMS API error')),
241+
};
242+
243+
await runDemoUrlProcessor(message, context);
244+
245+
// Should call imsClient.getImsOrganizationDetails
246+
expect(context.imsClient.getImsOrganizationDetails.calledWith('8C6043F15F43B6390A49401A@AdobeOrg')).to.be.true;
247+
248+
// Should log error about IMS API failure
249+
expect(context.log.error.calledWith('Error retrieving IMS Org details: IMS API error')).to.be.true;
250+
251+
// Should fallback to name-based tenant
252+
const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@adobesitesengineering/sites-optimizer/sites/test-site-id/home';
253+
expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true;
254+
});
255+
256+
it('should fallback to DEFAULT_TENANT_ID when imsClient fails and name is missing', async () => {
257+
// Mock Organization.findById to return organization without tenantId and name
258+
context.dataAccess.Organization.findById.resolves({
259+
imsOrgId: '8C6043F15F43B6390A49401A@AdobeOrg',
260+
// tenantId and name properties are missing
261+
});
262+
263+
// Mock imsClient to throw an error
264+
context.imsClient = {
265+
getImsOrganizationDetails: sinon.stub().rejects(new Error('IMS API error')),
266+
};
267+
268+
// Set default tenant ID
269+
context.env.DEFAULT_TENANT_ID = 'default-tenant';
270+
271+
await runDemoUrlProcessor(message, context);
272+
273+
// Should call imsClient.getImsOrganizationDetails
274+
expect(context.imsClient.getImsOrganizationDetails.calledWith('8C6043F15F43B6390A49401A@AdobeOrg')).to.be.true;
275+
276+
// Should log error about IMS API failure
277+
expect(context.log.error.calledWith('Error retrieving IMS Org details: IMS API error')).to.be.true;
278+
279+
// Should log error about using default tenant ID
280+
expect(context.log.error.calledWith('Using default tenant ID')).to.be.true;
281+
282+
// Should use DEFAULT_TENANT_ID as final fallback
283+
const expectedDemoUrl = 'https://example.com?organizationId=test-org-id#/@default-tenant/sites-optimizer/sites/test-site-id/home';
284+
expect(context.log.info.calledWith(`Setup complete! Access your demo environment here: ${expectedDemoUrl}`)).to.be.true;
285+
});
286+
287+
it('should send Slack message when using default tenant ID', async () => {
288+
// Mock Organization.findById to return organization without tenantId and name
289+
context.dataAccess.Organization.findById.resolves({
290+
imsOrgId: '8C6043F15F43B6390A49401A@AdobeOrg',
291+
// tenantId and name properties are missing
292+
});
293+
294+
// Mock imsClient to throw an error
295+
context.imsClient = {
296+
getImsOrganizationDetails: sinon.stub().rejects(new Error('IMS API error')),
297+
};
298+
299+
// Set default tenant ID
300+
context.env.DEFAULT_TENANT_ID = 'default-tenant';
301+
302+
await runDemoUrlProcessor(message, context);
303+
304+
// Should send Slack message about using default tenant ID
305+
// Note: We can't directly test the say function call, but we can verify the log message
306+
expect(context.log.error.calledWith('Using default tenant ID')).to.be.true;
307+
});
204308
});
205309
});

0 commit comments

Comments
 (0)