@adobe/spacecat-shared-tier-client 1.3.12 → 1.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/tier-client.js +70 -31
- package/test/tier-client.test.js +122 -64
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [@adobe/spacecat-shared-tier-client-v1.3.13](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tier-client-v1.3.12...@adobe/spacecat-shared-tier-client-v1.3.13) (2026-03-01)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* **tier-client:** avoid 414 URI Too Large on orgs with many enrollments ([#1390](https://github.com/adobe/spacecat-shared/issues/1390)) ([2e9de5e](https://github.com/adobe/spacecat-shared/commit/2e9de5e685c2a25801d4d50ad7317773ee706ef0))
|
|
6
|
+
|
|
1
7
|
## [@adobe/spacecat-shared-tier-client-v1.3.12](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tier-client-v1.3.11...@adobe/spacecat-shared-tier-client-v1.3.12) (2026-02-17)
|
|
2
8
|
|
|
3
9
|
### Bug Fixes
|
package/package.json
CHANGED
package/src/tier-client.js
CHANGED
|
@@ -239,10 +239,40 @@ class TierClient {
|
|
|
239
239
|
return { entitlement, enrollments: [] };
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
//
|
|
242
|
+
// When a specific site is provided, skip batch fetch entirely.
|
|
243
|
+
// Just filter enrollments by site ID and verify org ownership with a single lookup.
|
|
244
|
+
if (this.site) {
|
|
245
|
+
const targetSiteId = this.site.getId();
|
|
246
|
+
const matchingEnrollments = allEnrollments.filter(
|
|
247
|
+
(se) => se.getSiteId() === targetSiteId,
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
if (matchingEnrollments.length === 0) {
|
|
251
|
+
return { entitlement, enrollments: [] };
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const site = await this.Site.findById(targetSiteId);
|
|
255
|
+
if (!site || site.getOrganizationId() !== orgId) {
|
|
256
|
+
return { entitlement, enrollments: [] };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return { entitlement, enrollments: matchingEnrollments };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Org-only path: fetch sites in chunks to avoid 414 URI Too Large.
|
|
263
|
+
// PostgREST uses GET with ?id=in.(...) which has URL length limits.
|
|
264
|
+
const CHUNK_SIZE = 50;
|
|
243
265
|
const siteKeys = allEnrollments.map((enrollment) => ({ siteId: enrollment.getSiteId() }));
|
|
244
|
-
const
|
|
245
|
-
|
|
266
|
+
const sitesMap = new Map();
|
|
267
|
+
|
|
268
|
+
for (let i = 0; i < siteKeys.length; i += CHUNK_SIZE) {
|
|
269
|
+
const chunk = siteKeys.slice(i, i + CHUNK_SIZE);
|
|
270
|
+
// eslint-disable-next-line no-await-in-loop
|
|
271
|
+
const sitesResult = await this.Site.batchGetByKeys(chunk);
|
|
272
|
+
for (const site of sitesResult.data) {
|
|
273
|
+
sitesMap.set(site.getId(), site);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
246
276
|
|
|
247
277
|
// Filter enrollments where site's orgId matches the entitlement's orgId
|
|
248
278
|
const validEnrollments = [];
|
|
@@ -250,27 +280,13 @@ class TierClient {
|
|
|
250
280
|
for (const enrollment of allEnrollments) {
|
|
251
281
|
const site = sitesMap.get(enrollment.getSiteId());
|
|
252
282
|
if (!site) {
|
|
253
|
-
// Site not found, log warning and skip
|
|
254
283
|
this.log.warn(`Site not found for enrollment ${enrollment.getId()} with siteId ${enrollment.getSiteId()}`);
|
|
255
|
-
} else {
|
|
256
|
-
|
|
257
|
-
if (siteOrgId === orgId) {
|
|
258
|
-
validEnrollments.push(enrollment);
|
|
259
|
-
}
|
|
284
|
+
} else if (site.getOrganizationId() === orgId) {
|
|
285
|
+
validEnrollments.push(enrollment);
|
|
260
286
|
}
|
|
261
287
|
}
|
|
262
288
|
|
|
263
|
-
|
|
264
|
-
// Return site enrollments matching the entitlement and site
|
|
265
|
-
const siteId = this.site.getId();
|
|
266
|
-
const matchingEnrollments = validEnrollments.filter(
|
|
267
|
-
(se) => se.getSiteId() === siteId,
|
|
268
|
-
);
|
|
269
|
-
return { entitlement, enrollments: matchingEnrollments };
|
|
270
|
-
} else {
|
|
271
|
-
// Return all valid enrollments for the entitlement
|
|
272
|
-
return { entitlement, enrollments: validEnrollments };
|
|
273
|
-
}
|
|
289
|
+
return { entitlement, enrollments: validEnrollments };
|
|
274
290
|
} catch (error) {
|
|
275
291
|
this.log.error(`Error getting all enrollments: ${error.message}`);
|
|
276
292
|
throw error;
|
|
@@ -279,28 +295,51 @@ class TierClient {
|
|
|
279
295
|
|
|
280
296
|
/**
|
|
281
297
|
* Gets the first enrollment and its site, filtered by productCode.
|
|
282
|
-
* - If site is provided:
|
|
283
|
-
* - If org-only:
|
|
298
|
+
* - If site is provided: finds matching enrollment and returns this.site directly
|
|
299
|
+
* - If org-only: iterates enrollments, fetches sites one at a time, returns first org match
|
|
284
300
|
* @returns {Promise<object>} Object with entitlement, enrollment, and site.
|
|
285
301
|
*/
|
|
286
302
|
async getFirstEnrollment() {
|
|
287
303
|
try {
|
|
288
|
-
const
|
|
304
|
+
const orgId = this.organization.getId();
|
|
305
|
+
const entitlement = await this.Entitlement
|
|
306
|
+
.findByOrganizationIdAndProductCode(orgId, this.productCode);
|
|
307
|
+
|
|
308
|
+
if (!entitlement) {
|
|
309
|
+
return { entitlement: null, enrollment: null, site: null };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const allEnrollments = await this.SiteEnrollment.allByEntitlementId(entitlement.getId());
|
|
289
313
|
|
|
290
|
-
if (!
|
|
314
|
+
if (!allEnrollments || allEnrollments.length === 0) {
|
|
291
315
|
return { entitlement: null, enrollment: null, site: null };
|
|
292
316
|
}
|
|
293
317
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
318
|
+
// When a specific site is set, find its enrollment in memory — no fetch needed.
|
|
319
|
+
if (this.site) {
|
|
320
|
+
const targetSiteId = this.site.getId();
|
|
321
|
+
const matchingEnrollment = allEnrollments.find(
|
|
322
|
+
(se) => se.getSiteId() === targetSiteId,
|
|
323
|
+
);
|
|
324
|
+
if (matchingEnrollment) {
|
|
325
|
+
return { entitlement, enrollment: matchingEnrollment, site: this.site };
|
|
326
|
+
}
|
|
327
|
+
return { entitlement: null, enrollment: null, site: null };
|
|
328
|
+
}
|
|
297
329
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
330
|
+
// Org-only: iterate enrollments, fetch site one at a time, return first org match.
|
|
331
|
+
// This avoids batch-fetching all sites (which causes 414 on large sets).
|
|
332
|
+
for (const enrollment of allEnrollments) {
|
|
333
|
+
// eslint-disable-next-line no-await-in-loop
|
|
334
|
+
const site = await this.Site.findById(enrollment.getSiteId());
|
|
335
|
+
if (!site) {
|
|
336
|
+
this.log.warn(`Site not found for enrollment ${enrollment.getId()} with siteId ${enrollment.getSiteId()}`);
|
|
337
|
+
} else if (site.getOrganizationId() === orgId) {
|
|
338
|
+
return { entitlement, enrollment, site };
|
|
339
|
+
}
|
|
301
340
|
}
|
|
302
341
|
|
|
303
|
-
return { entitlement, enrollment:
|
|
342
|
+
return { entitlement: null, enrollment: null, site: null };
|
|
304
343
|
} catch (error) {
|
|
305
344
|
this.log.error(`Error getting first enrollment: ${error.message}`);
|
|
306
345
|
throw error;
|
package/test/tier-client.test.js
CHANGED
|
@@ -764,20 +764,12 @@ describe('TierClient', () => {
|
|
|
764
764
|
getOrganizationId: () => orgId,
|
|
765
765
|
};
|
|
766
766
|
|
|
767
|
-
const mockSiteForEnrollment2 = {
|
|
768
|
-
getId: () => 'other-site-id',
|
|
769
|
-
getOrganizationId: () => orgId,
|
|
770
|
-
};
|
|
771
|
-
|
|
772
767
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
773
768
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([
|
|
774
769
|
mockSiteEnrollment,
|
|
775
770
|
mockEnrollment2,
|
|
776
771
|
]);
|
|
777
|
-
mockDataAccess.Site.
|
|
778
|
-
data: [mockSiteForEnrollment1, mockSiteForEnrollment2],
|
|
779
|
-
unprocessed: [],
|
|
780
|
-
});
|
|
772
|
+
mockDataAccess.Site.findById.resolves(mockSiteForEnrollment1);
|
|
781
773
|
|
|
782
774
|
const result = await tierClient.getAllEnrollment();
|
|
783
775
|
|
|
@@ -785,8 +777,8 @@ describe('TierClient', () => {
|
|
|
785
777
|
entitlement: mockEntitlement,
|
|
786
778
|
enrollments: [mockSiteEnrollment],
|
|
787
779
|
});
|
|
788
|
-
expect(mockDataAccess.
|
|
789
|
-
|
|
780
|
+
expect(mockDataAccess.Site.batchGetByKeys).to.not.have.been.called;
|
|
781
|
+
expect(mockDataAccess.Site.findById).to.have.been.calledWith(siteId);
|
|
790
782
|
});
|
|
791
783
|
|
|
792
784
|
it('should return null entitlement and empty enrollments when no entitlement exists', async () => {
|
|
@@ -820,6 +812,38 @@ describe('TierClient', () => {
|
|
|
820
812
|
expect(mockContext.log.error).to.have.been.calledWith('Error getting all enrollments: Database error');
|
|
821
813
|
});
|
|
822
814
|
|
|
815
|
+
it('should return empty enrollments when site has no matching enrollments', async () => {
|
|
816
|
+
const nonMatchingEnrollment = {
|
|
817
|
+
getId: () => 'enrollment-999',
|
|
818
|
+
getSiteId: () => 'other-site-id',
|
|
819
|
+
getEntitlementId: () => 'entitlement-123',
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
823
|
+
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([nonMatchingEnrollment]);
|
|
824
|
+
|
|
825
|
+
const result = await tierClient.getAllEnrollment();
|
|
826
|
+
|
|
827
|
+
expect(result).to.deep.equal({ entitlement: mockEntitlement, enrollments: [] });
|
|
828
|
+
expect(mockDataAccess.Site.findById).to.not.have.been.called;
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
it('should return empty enrollments when site org does not match', async () => {
|
|
832
|
+
const wrongOrgSite = {
|
|
833
|
+
getId: () => siteId,
|
|
834
|
+
getOrganizationId: () => 'wrong-org-id',
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
838
|
+
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
839
|
+
mockDataAccess.Site.findById.resolves(wrongOrgSite);
|
|
840
|
+
|
|
841
|
+
const result = await tierClient.getAllEnrollment();
|
|
842
|
+
|
|
843
|
+
expect(result).to.deep.equal({ entitlement: mockEntitlement, enrollments: [] });
|
|
844
|
+
expect(mockDataAccess.Site.findById).to.have.been.calledWith(siteId);
|
|
845
|
+
});
|
|
846
|
+
|
|
823
847
|
it('should filter out enrollments not matching site ID', async () => {
|
|
824
848
|
const mockEnrollment2 = {
|
|
825
849
|
getId: () => 'enrollment-456',
|
|
@@ -838,26 +862,20 @@ describe('TierClient', () => {
|
|
|
838
862
|
getOrganizationId: () => orgId,
|
|
839
863
|
};
|
|
840
864
|
|
|
841
|
-
const mockSiteForEnrollment2 = {
|
|
842
|
-
getId: () => 'different-site-id',
|
|
843
|
-
getOrganizationId: () => orgId,
|
|
844
|
-
};
|
|
845
|
-
|
|
846
865
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
847
866
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([
|
|
848
867
|
mockSiteEnrollment,
|
|
849
868
|
mockEnrollment2,
|
|
850
869
|
mockEnrollment3,
|
|
851
870
|
]);
|
|
852
|
-
mockDataAccess.Site.
|
|
853
|
-
data: [mockSiteForEnrollment1, mockSiteForEnrollment2, mockSiteForEnrollment1],
|
|
854
|
-
unprocessed: [],
|
|
855
|
-
});
|
|
871
|
+
mockDataAccess.Site.findById.resolves(mockSiteForEnrollment1);
|
|
856
872
|
|
|
857
873
|
const result = await tierClient.getAllEnrollment();
|
|
858
874
|
|
|
859
875
|
expect(result.enrollments).to.have.lengthOf(2);
|
|
860
876
|
expect(result.enrollments).to.deep.equal([mockSiteEnrollment, mockEnrollment3]);
|
|
877
|
+
expect(mockDataAccess.Site.batchGetByKeys).to.not.have.been.called;
|
|
878
|
+
expect(mockDataAccess.Site.findById).to.have.been.calledWith(siteId);
|
|
861
879
|
});
|
|
862
880
|
|
|
863
881
|
it('should filter out enrollments with mismatching orgId', async () => {
|
|
@@ -939,10 +957,6 @@ describe('TierClient', () => {
|
|
|
939
957
|
|
|
940
958
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
941
959
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
942
|
-
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
943
|
-
data: [mockSiteObject],
|
|
944
|
-
unprocessed: [],
|
|
945
|
-
});
|
|
946
960
|
mockDataAccess.Site.findById.resolves(mockSiteObject);
|
|
947
961
|
|
|
948
962
|
const tierClientWithoutSite = new TierClient(
|
|
@@ -960,6 +974,7 @@ describe('TierClient', () => {
|
|
|
960
974
|
site: mockSiteObject,
|
|
961
975
|
});
|
|
962
976
|
expect(mockDataAccess.Site.findById).to.have.been.calledWith(siteId);
|
|
977
|
+
expect(mockDataAccess.Site.batchGetByKeys).to.not.have.been.called;
|
|
963
978
|
});
|
|
964
979
|
|
|
965
980
|
it('should return first enrollment when multiple exist', async () => {
|
|
@@ -969,12 +984,6 @@ describe('TierClient', () => {
|
|
|
969
984
|
getOrganizationId: () => orgId,
|
|
970
985
|
};
|
|
971
986
|
|
|
972
|
-
const mockSiteObject2 = {
|
|
973
|
-
getId: () => 'other-site-id',
|
|
974
|
-
getName: () => 'Other Site',
|
|
975
|
-
getOrganizationId: () => orgId,
|
|
976
|
-
};
|
|
977
|
-
|
|
978
987
|
const mockEnrollment2 = {
|
|
979
988
|
getId: () => 'enrollment-456',
|
|
980
989
|
getSiteId: () => 'other-site-id',
|
|
@@ -986,10 +995,6 @@ describe('TierClient', () => {
|
|
|
986
995
|
mockSiteEnrollment,
|
|
987
996
|
mockEnrollment2,
|
|
988
997
|
]);
|
|
989
|
-
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
990
|
-
data: [mockSiteObject, mockSiteObject2],
|
|
991
|
-
unprocessed: [],
|
|
992
|
-
});
|
|
993
998
|
mockDataAccess.Site.findById.resolves(mockSiteObject);
|
|
994
999
|
|
|
995
1000
|
const tierClientWithoutSite = new TierClient(
|
|
@@ -1002,7 +1007,9 @@ describe('TierClient', () => {
|
|
|
1002
1007
|
const result = await tierClientWithoutSite.getFirstEnrollment();
|
|
1003
1008
|
|
|
1004
1009
|
expect(result.enrollment).to.equal(mockSiteEnrollment);
|
|
1005
|
-
expect(
|
|
1010
|
+
expect(result.site).to.equal(mockSiteObject);
|
|
1011
|
+
expect(mockDataAccess.Site.findById).to.have.been.calledOnceWith(siteId);
|
|
1012
|
+
expect(mockDataAccess.Site.batchGetByKeys).to.not.have.been.called;
|
|
1006
1013
|
});
|
|
1007
1014
|
|
|
1008
1015
|
it('should return nulls when no entitlement exists', async () => {
|
|
@@ -1032,19 +1039,9 @@ describe('TierClient', () => {
|
|
|
1032
1039
|
expect(mockDataAccess.Site.findById).to.not.have.been.called;
|
|
1033
1040
|
});
|
|
1034
1041
|
|
|
1035
|
-
it('should
|
|
1036
|
-
const mockSiteObject = {
|
|
1037
|
-
getId: () => siteId,
|
|
1038
|
-
getName: () => 'Test Site',
|
|
1039
|
-
getOrganizationId: () => orgId,
|
|
1040
|
-
};
|
|
1041
|
-
|
|
1042
|
+
it('should skip enrollment when site not found and return nulls', async () => {
|
|
1042
1043
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
1043
1044
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
1044
|
-
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
1045
|
-
data: [mockSiteObject],
|
|
1046
|
-
unprocessed: [],
|
|
1047
|
-
});
|
|
1048
1045
|
mockDataAccess.Site.findById.resolves(null);
|
|
1049
1046
|
|
|
1050
1047
|
const tierClientWithoutSite = new TierClient(
|
|
@@ -1057,12 +1054,12 @@ describe('TierClient', () => {
|
|
|
1057
1054
|
const result = await tierClientWithoutSite.getFirstEnrollment();
|
|
1058
1055
|
|
|
1059
1056
|
expect(result).to.deep.equal({
|
|
1060
|
-
entitlement:
|
|
1061
|
-
enrollment:
|
|
1057
|
+
entitlement: null,
|
|
1058
|
+
enrollment: null,
|
|
1062
1059
|
site: null,
|
|
1063
1060
|
});
|
|
1064
1061
|
expect(mockContext.log.warn).to.have.been.calledWith(
|
|
1065
|
-
`Site not found for enrollment ${mockSiteEnrollment.getId()} with
|
|
1062
|
+
`Site not found for enrollment ${mockSiteEnrollment.getId()} with siteId ${siteId}`,
|
|
1066
1063
|
);
|
|
1067
1064
|
});
|
|
1068
1065
|
|
|
@@ -1074,35 +1071,96 @@ describe('TierClient', () => {
|
|
|
1074
1071
|
});
|
|
1075
1072
|
|
|
1076
1073
|
it('should work with site-specific client', async () => {
|
|
1077
|
-
const mockSiteObject = {
|
|
1078
|
-
getId: () => siteId,
|
|
1079
|
-
getName: () => 'Test Site',
|
|
1080
|
-
getOrganizationId: () => orgId,
|
|
1081
|
-
};
|
|
1082
|
-
|
|
1083
1074
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
1084
1075
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
1085
|
-
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
1086
|
-
data: [mockSiteObject],
|
|
1087
|
-
unprocessed: [],
|
|
1088
|
-
});
|
|
1089
|
-
mockDataAccess.Site.findById.resolves(mockSiteObject);
|
|
1090
1076
|
|
|
1091
1077
|
const result = await tierClient.getFirstEnrollment();
|
|
1092
1078
|
|
|
1093
1079
|
expect(result).to.deep.equal({
|
|
1094
1080
|
entitlement: mockEntitlement,
|
|
1095
1081
|
enrollment: mockSiteEnrollment,
|
|
1096
|
-
site:
|
|
1082
|
+
site: siteInstance,
|
|
1097
1083
|
});
|
|
1084
|
+
expect(mockDataAccess.Site.findById).to.not.have.been.called;
|
|
1085
|
+
expect(mockDataAccess.Site.batchGetByKeys).to.not.have.been.called;
|
|
1098
1086
|
});
|
|
1099
1087
|
|
|
1100
|
-
it('should handle error when fetching site via
|
|
1088
|
+
it('should handle error when fetching site via findById', async () => {
|
|
1101
1089
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
1102
1090
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
1103
|
-
mockDataAccess.Site.
|
|
1091
|
+
mockDataAccess.Site.findById.rejects(new Error('Site fetch error'));
|
|
1092
|
+
|
|
1093
|
+
const tierClientWithoutSite = new TierClient(
|
|
1094
|
+
mockContext,
|
|
1095
|
+
organizationInstance,
|
|
1096
|
+
null,
|
|
1097
|
+
productCode,
|
|
1098
|
+
);
|
|
1099
|
+
|
|
1100
|
+
await expect(tierClientWithoutSite.getFirstEnrollment()).to.be.rejectedWith('Site fetch error');
|
|
1101
|
+
expect(mockDataAccess.Site.batchGetByKeys).to.not.have.been.called;
|
|
1102
|
+
});
|
|
1103
|
+
|
|
1104
|
+
it('should return nulls when site-specific client has no matching enrollment', async () => {
|
|
1105
|
+
const nonMatchingEnrollment = {
|
|
1106
|
+
getId: () => 'enrollment-999',
|
|
1107
|
+
getSiteId: () => 'other-site-id',
|
|
1108
|
+
getEntitlementId: () => 'entitlement-123',
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
1112
|
+
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([nonMatchingEnrollment]);
|
|
1113
|
+
|
|
1114
|
+
const result = await tierClient.getFirstEnrollment();
|
|
1115
|
+
|
|
1116
|
+
expect(result).to.deep.equal({
|
|
1117
|
+
entitlement: null,
|
|
1118
|
+
enrollment: null,
|
|
1119
|
+
site: null,
|
|
1120
|
+
});
|
|
1121
|
+
expect(mockDataAccess.Site.findById).to.not.have.been.called;
|
|
1122
|
+
});
|
|
1123
|
+
|
|
1124
|
+
it('should skip enrollments with mismatching orgId and return first match', async () => {
|
|
1125
|
+
const wrongOrgSite = {
|
|
1126
|
+
getId: () => siteId,
|
|
1127
|
+
getOrganizationId: () => 'wrong-org-id',
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
const correctSite = {
|
|
1131
|
+
getId: () => 'correct-site-id',
|
|
1132
|
+
getOrganizationId: () => orgId,
|
|
1133
|
+
};
|
|
1134
|
+
|
|
1135
|
+
const enrollment2 = {
|
|
1136
|
+
getId: () => 'enrollment-456',
|
|
1137
|
+
getSiteId: () => 'correct-site-id',
|
|
1138
|
+
getEntitlementId: () => 'entitlement-123',
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
1142
|
+
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([
|
|
1143
|
+
mockSiteEnrollment,
|
|
1144
|
+
enrollment2,
|
|
1145
|
+
]);
|
|
1146
|
+
mockDataAccess.Site.findById.onFirstCall().resolves(wrongOrgSite);
|
|
1147
|
+
mockDataAccess.Site.findById.onSecondCall().resolves(correctSite);
|
|
1148
|
+
|
|
1149
|
+
const tierClientWithoutSite = new TierClient(
|
|
1150
|
+
mockContext,
|
|
1151
|
+
organizationInstance,
|
|
1152
|
+
null,
|
|
1153
|
+
productCode,
|
|
1154
|
+
);
|
|
1155
|
+
|
|
1156
|
+
const result = await tierClientWithoutSite.getFirstEnrollment();
|
|
1104
1157
|
|
|
1105
|
-
|
|
1158
|
+
expect(result).to.deep.equal({
|
|
1159
|
+
entitlement: mockEntitlement,
|
|
1160
|
+
enrollment: enrollment2,
|
|
1161
|
+
site: correctSite,
|
|
1162
|
+
});
|
|
1163
|
+
expect(mockDataAccess.Site.findById).to.have.been.calledTwice;
|
|
1106
1164
|
});
|
|
1107
1165
|
});
|
|
1108
1166
|
});
|