Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions src/controllers/llmo/llmo-onboarding.js
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,10 @@ export async function createOrFindSite(baseURL, organizationId, context, deliver
const site = await Site.findByBaseURL(baseURL);
if (site) {
if (site.getOrganizationId() !== organizationId) {
const enrollments = await site.getSiteEnrollments();
if (enrollments?.length > 0) {
Comment thread
Kanishkavijay39 marked this conversation as resolved.
Outdated
throw new Error(`Site ${baseURL} is already associated with another org that has active products and cannot be moved.`);
}
site.setOrganizationId(organizationId);
// Persist the re-parent immediately. resolveLlmoOnboardingMode (called
// right after this in performLlmoOnboarding) reads sites by org_id, so
Expand Down
33 changes: 33 additions & 0 deletions test/controllers/llmo/llmo-onboarding.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,7 @@ describe('LLMO Onboarding Functions', () => {
const mockSite = {
getOrganizationId: sinon.stub().returns('old-org-123'),
setOrganizationId: sinon.stub(),
getSiteEnrollments: sinon.stub().resolves([]),
save: sinon.stub().resolves(),
};

Expand All @@ -1256,6 +1257,38 @@ describe('LLMO Onboarding Functions', () => {
// queries Site.allByOrganizationId, otherwise a legacy site moved into a
// brand-new org would be misclassified as v2.
expect(mockSite.save).to.have.been.calledOnce;
}).timeout(5000);

it('should throw when existing site has different org and active enrollments', async () => {
const { createOrFindSite } = await esmock('../../../src/controllers/llmo/llmo-onboarding.js', {
'@adobe/spacecat-shared-data-access/src/models/entitlement/index.js': {
Entitlement: {
PRODUCT_CODES: { LLMO: 'LLMO' },
TIERS: { FREE_TRIAL: 'FREE_TRIAL' },
},
},
'@adobe/spacecat-shared-tier-client': {
default: sinon.stub(),
},
});

const mockSite = {
getOrganizationId: sinon.stub().returns('other-org-789'),
setOrganizationId: sinon.stub(),
getSiteEnrollments: sinon.stub().resolves([{ getId: () => 'enroll-1' }]),
save: sinon.stub().resolves(),
};

mockDataAccess.Site.findByBaseURL.resolves(mockSite);

const context = { dataAccess: mockDataAccess };

await expect(
createOrFindSite('https://example.com', 'new-org-456', context),
).to.be.rejectedWith('already associated with another org that has active products');

expect(mockSite.setOrganizationId).to.not.have.been.called;
expect(mockSite.save).to.not.have.been.called;
});

it('should not update organization ID when existing site has same organization', async () => {
Expand Down
1 change: 1 addition & 0 deletions test/support/slack/actions/onboard-llmo-modal.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe('onboard-llmo-modal', () => {
getImports: sinonSandbox.stub().returns([]),
}),
setConfig: sinonSandbox.stub(),
getSiteEnrollments: sinonSandbox.stub().resolves([]),
save: sinonSandbox.stub().resolves(),
};
};
Expand Down
Loading