@adobe/spacecat-shared-tier-client 1.3.10 → 1.3.11
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 +7 -0
- package/package.json +1 -1
- package/src/tier-client.js +29 -3
- package/test/tier-client.test.js +144 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-tier-client-v1.3.11](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tier-client-v1.3.10...@adobe/spacecat-shared-tier-client-v1.3.11) (2026-02-06)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* adds additional check for dangling enrollments ([#1296](https://github.com/adobe/spacecat-shared/issues/1296)) ([e5a0de3](https://github.com/adobe/spacecat-shared/commit/e5a0de32112dbf81e3da37d7b90a747d993497da))
|
|
7
|
+
|
|
1
8
|
# [@adobe/spacecat-shared-tier-client-v1.3.10](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tier-client-v1.3.9...@adobe/spacecat-shared-tier-client-v1.3.10) (2025-12-05)
|
|
2
9
|
|
|
3
10
|
|
package/package.json
CHANGED
package/src/tier-client.js
CHANGED
|
@@ -220,6 +220,7 @@ class TierClient {
|
|
|
220
220
|
* Gets all enrollments based on context, filtered by productCode.
|
|
221
221
|
* - If site is provided: returns site enrollment for the entitlement matching productCode
|
|
222
222
|
* - If org-only: returns all site enrollments for the entitlement matching productCode
|
|
223
|
+
* - Filters out enrollments where the site's orgId doesn't match the entitlement's orgId
|
|
223
224
|
* @returns {Promise<object>} Object with entitlement and enrollments array.
|
|
224
225
|
*/
|
|
225
226
|
async getAllEnrollment() {
|
|
@@ -234,16 +235,41 @@ class TierClient {
|
|
|
234
235
|
|
|
235
236
|
const allEnrollments = await this.SiteEnrollment.allByEntitlementId(entitlement.getId());
|
|
236
237
|
|
|
238
|
+
if (allEnrollments.length === 0) {
|
|
239
|
+
return { entitlement, enrollments: [] };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Fetch all sites using batchGetByKeys
|
|
243
|
+
const siteKeys = allEnrollments.map((enrollment) => ({ siteId: enrollment.getSiteId() }));
|
|
244
|
+
const sitesResult = await this.Site.batchGetByKeys(siteKeys);
|
|
245
|
+
const sitesMap = new Map(sitesResult.data.map((site) => [site.getId(), site]));
|
|
246
|
+
|
|
247
|
+
// Filter enrollments where site's orgId matches the entitlement's orgId
|
|
248
|
+
const validEnrollments = [];
|
|
249
|
+
|
|
250
|
+
for (const enrollment of allEnrollments) {
|
|
251
|
+
const site = sitesMap.get(enrollment.getSiteId());
|
|
252
|
+
if (!site) {
|
|
253
|
+
// Site not found, log warning and skip
|
|
254
|
+
this.log.warn(`Site not found for enrollment ${enrollment.getId()} with siteId ${enrollment.getSiteId()}`);
|
|
255
|
+
} else {
|
|
256
|
+
const siteOrgId = site.getOrganizationId();
|
|
257
|
+
if (siteOrgId === orgId) {
|
|
258
|
+
validEnrollments.push(enrollment);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
237
263
|
if (this.site) {
|
|
238
264
|
// Return site enrollments matching the entitlement and site
|
|
239
265
|
const siteId = this.site.getId();
|
|
240
|
-
const matchingEnrollments =
|
|
266
|
+
const matchingEnrollments = validEnrollments.filter(
|
|
241
267
|
(se) => se.getSiteId() === siteId,
|
|
242
268
|
);
|
|
243
269
|
return { entitlement, enrollments: matchingEnrollments };
|
|
244
270
|
} else {
|
|
245
|
-
// Return all enrollments for the entitlement
|
|
246
|
-
return { entitlement, enrollments:
|
|
271
|
+
// Return all valid enrollments for the entitlement
|
|
272
|
+
return { entitlement, enrollments: validEnrollments };
|
|
247
273
|
}
|
|
248
274
|
} catch (error) {
|
|
249
275
|
this.log.error(`Error getting all enrollments: ${error.message}`);
|
package/test/tier-client.test.js
CHANGED
|
@@ -80,6 +80,7 @@ describe('TierClient', () => {
|
|
|
80
80
|
},
|
|
81
81
|
Site: {
|
|
82
82
|
findById: sandbox.stub(),
|
|
83
|
+
batchGetByKeys: sandbox.stub(),
|
|
83
84
|
},
|
|
84
85
|
};
|
|
85
86
|
|
|
@@ -726,11 +727,25 @@ describe('TierClient', () => {
|
|
|
726
727
|
getEntitlementId: () => 'entitlement-123',
|
|
727
728
|
};
|
|
728
729
|
|
|
730
|
+
const mockSiteForEnrollment1 = {
|
|
731
|
+
getId: () => siteId,
|
|
732
|
+
getOrganizationId: () => orgId,
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
const mockSiteForEnrollment2 = {
|
|
736
|
+
getId: () => '789-site-id',
|
|
737
|
+
getOrganizationId: () => orgId,
|
|
738
|
+
};
|
|
739
|
+
|
|
729
740
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
730
741
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([
|
|
731
742
|
mockSiteEnrollment,
|
|
732
743
|
mockEnrollment2,
|
|
733
744
|
]);
|
|
745
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
746
|
+
data: [mockSiteForEnrollment1, mockSiteForEnrollment2],
|
|
747
|
+
unprocessed: [],
|
|
748
|
+
});
|
|
734
749
|
|
|
735
750
|
const result = await tierClientWithoutSite.getAllEnrollment();
|
|
736
751
|
|
|
@@ -742,6 +757,10 @@ describe('TierClient', () => {
|
|
|
742
757
|
.to.have.been.calledWith(orgId, productCode);
|
|
743
758
|
expect(mockDataAccess.SiteEnrollment.allByEntitlementId)
|
|
744
759
|
.to.have.been.calledWith('entitlement-123');
|
|
760
|
+
expect(mockDataAccess.Site.batchGetByKeys).to.have.been.calledWith([
|
|
761
|
+
{ siteId },
|
|
762
|
+
{ siteId: '789-site-id' },
|
|
763
|
+
]);
|
|
745
764
|
});
|
|
746
765
|
|
|
747
766
|
it('should return filtered enrollments when site is provided', async () => {
|
|
@@ -751,11 +770,25 @@ describe('TierClient', () => {
|
|
|
751
770
|
getEntitlementId: () => 'entitlement-123',
|
|
752
771
|
};
|
|
753
772
|
|
|
773
|
+
const mockSiteForEnrollment1 = {
|
|
774
|
+
getId: () => siteId,
|
|
775
|
+
getOrganizationId: () => orgId,
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
const mockSiteForEnrollment2 = {
|
|
779
|
+
getId: () => 'other-site-id',
|
|
780
|
+
getOrganizationId: () => orgId,
|
|
781
|
+
};
|
|
782
|
+
|
|
754
783
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
755
784
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([
|
|
756
785
|
mockSiteEnrollment,
|
|
757
786
|
mockEnrollment2,
|
|
758
787
|
]);
|
|
788
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
789
|
+
data: [mockSiteForEnrollment1, mockSiteForEnrollment2],
|
|
790
|
+
unprocessed: [],
|
|
791
|
+
});
|
|
759
792
|
|
|
760
793
|
const result = await tierClient.getAllEnrollment();
|
|
761
794
|
|
|
@@ -811,18 +844,96 @@ describe('TierClient', () => {
|
|
|
811
844
|
getEntitlementId: () => 'entitlement-123',
|
|
812
845
|
};
|
|
813
846
|
|
|
847
|
+
const mockSiteForEnrollment1 = {
|
|
848
|
+
getId: () => siteId,
|
|
849
|
+
getOrganizationId: () => orgId,
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
const mockSiteForEnrollment2 = {
|
|
853
|
+
getId: () => 'different-site-id',
|
|
854
|
+
getOrganizationId: () => orgId,
|
|
855
|
+
};
|
|
856
|
+
|
|
814
857
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
815
858
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([
|
|
816
859
|
mockSiteEnrollment,
|
|
817
860
|
mockEnrollment2,
|
|
818
861
|
mockEnrollment3,
|
|
819
862
|
]);
|
|
863
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
864
|
+
data: [mockSiteForEnrollment1, mockSiteForEnrollment2, mockSiteForEnrollment1],
|
|
865
|
+
unprocessed: [],
|
|
866
|
+
});
|
|
820
867
|
|
|
821
868
|
const result = await tierClient.getAllEnrollment();
|
|
822
869
|
|
|
823
870
|
expect(result.enrollments).to.have.lengthOf(2);
|
|
824
871
|
expect(result.enrollments).to.deep.equal([mockSiteEnrollment, mockEnrollment3]);
|
|
825
872
|
});
|
|
873
|
+
|
|
874
|
+
it('should filter out enrollments with mismatching orgId', async () => {
|
|
875
|
+
const tierClientWithoutSite = new TierClient(
|
|
876
|
+
mockContext,
|
|
877
|
+
organizationInstance,
|
|
878
|
+
null,
|
|
879
|
+
productCode,
|
|
880
|
+
);
|
|
881
|
+
|
|
882
|
+
const mismatchingOrgId = 'different-org-id';
|
|
883
|
+
const mockEnrollment2 = {
|
|
884
|
+
getId: () => 'enrollment-456',
|
|
885
|
+
getSiteId: () => 'site-with-wrong-org',
|
|
886
|
+
getEntitlementId: () => 'entitlement-123',
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
const mockSiteForEnrollment1 = {
|
|
890
|
+
getId: () => siteId,
|
|
891
|
+
getOrganizationId: () => orgId,
|
|
892
|
+
};
|
|
893
|
+
|
|
894
|
+
const mockSiteForEnrollment2 = {
|
|
895
|
+
getId: () => 'site-with-wrong-org',
|
|
896
|
+
getOrganizationId: () => mismatchingOrgId,
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
900
|
+
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([
|
|
901
|
+
mockSiteEnrollment,
|
|
902
|
+
mockEnrollment2,
|
|
903
|
+
]);
|
|
904
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
905
|
+
data: [mockSiteForEnrollment1, mockSiteForEnrollment2],
|
|
906
|
+
unprocessed: [],
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
const result = await tierClientWithoutSite.getAllEnrollment();
|
|
910
|
+
|
|
911
|
+
expect(result.enrollments).to.have.lengthOf(1);
|
|
912
|
+
expect(result.enrollments[0].getId()).to.equal('enrollment-123');
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
it('should log warning when site not found for enrollment', async () => {
|
|
916
|
+
const tierClientWithoutSite = new TierClient(
|
|
917
|
+
mockContext,
|
|
918
|
+
organizationInstance,
|
|
919
|
+
null,
|
|
920
|
+
productCode,
|
|
921
|
+
);
|
|
922
|
+
|
|
923
|
+
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
924
|
+
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
925
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
926
|
+
data: [],
|
|
927
|
+
unprocessed: [],
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
const result = await tierClientWithoutSite.getAllEnrollment();
|
|
931
|
+
|
|
932
|
+
expect(result.enrollments).to.have.lengthOf(0);
|
|
933
|
+
expect(mockContext.log.warn).to.have.been.calledWith(
|
|
934
|
+
`Site not found for enrollment ${mockSiteEnrollment.getId()} with siteId ${siteId}`,
|
|
935
|
+
);
|
|
936
|
+
});
|
|
826
937
|
});
|
|
827
938
|
|
|
828
939
|
describe('getFirstEnrollment', () => {
|
|
@@ -834,10 +945,15 @@ describe('TierClient', () => {
|
|
|
834
945
|
const mockSiteObject = {
|
|
835
946
|
getId: () => siteId,
|
|
836
947
|
getName: () => 'Test Site',
|
|
948
|
+
getOrganizationId: () => orgId,
|
|
837
949
|
};
|
|
838
950
|
|
|
839
951
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
840
952
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
953
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
954
|
+
data: [mockSiteObject],
|
|
955
|
+
unprocessed: [],
|
|
956
|
+
});
|
|
841
957
|
mockDataAccess.Site.findById.resolves(mockSiteObject);
|
|
842
958
|
|
|
843
959
|
const tierClientWithoutSite = new TierClient(
|
|
@@ -861,6 +977,13 @@ describe('TierClient', () => {
|
|
|
861
977
|
const mockSiteObject = {
|
|
862
978
|
getId: () => siteId,
|
|
863
979
|
getName: () => 'Test Site',
|
|
980
|
+
getOrganizationId: () => orgId,
|
|
981
|
+
};
|
|
982
|
+
|
|
983
|
+
const mockSiteObject2 = {
|
|
984
|
+
getId: () => 'other-site-id',
|
|
985
|
+
getName: () => 'Other Site',
|
|
986
|
+
getOrganizationId: () => orgId,
|
|
864
987
|
};
|
|
865
988
|
|
|
866
989
|
const mockEnrollment2 = {
|
|
@@ -874,6 +997,10 @@ describe('TierClient', () => {
|
|
|
874
997
|
mockSiteEnrollment,
|
|
875
998
|
mockEnrollment2,
|
|
876
999
|
]);
|
|
1000
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
1001
|
+
data: [mockSiteObject, mockSiteObject2],
|
|
1002
|
+
unprocessed: [],
|
|
1003
|
+
});
|
|
877
1004
|
mockDataAccess.Site.findById.resolves(mockSiteObject);
|
|
878
1005
|
|
|
879
1006
|
const tierClientWithoutSite = new TierClient(
|
|
@@ -917,8 +1044,18 @@ describe('TierClient', () => {
|
|
|
917
1044
|
});
|
|
918
1045
|
|
|
919
1046
|
it('should return null site when site not found in database', async () => {
|
|
1047
|
+
const mockSiteObject = {
|
|
1048
|
+
getId: () => siteId,
|
|
1049
|
+
getName: () => 'Test Site',
|
|
1050
|
+
getOrganizationId: () => orgId,
|
|
1051
|
+
};
|
|
1052
|
+
|
|
920
1053
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
921
1054
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
1055
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
1056
|
+
data: [mockSiteObject],
|
|
1057
|
+
unprocessed: [],
|
|
1058
|
+
});
|
|
922
1059
|
mockDataAccess.Site.findById.resolves(null);
|
|
923
1060
|
|
|
924
1061
|
const tierClientWithoutSite = new TierClient(
|
|
@@ -951,10 +1088,15 @@ describe('TierClient', () => {
|
|
|
951
1088
|
const mockSiteObject = {
|
|
952
1089
|
getId: () => siteId,
|
|
953
1090
|
getName: () => 'Test Site',
|
|
1091
|
+
getOrganizationId: () => orgId,
|
|
954
1092
|
};
|
|
955
1093
|
|
|
956
1094
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
957
1095
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
1096
|
+
mockDataAccess.Site.batchGetByKeys.resolves({
|
|
1097
|
+
data: [mockSiteObject],
|
|
1098
|
+
unprocessed: [],
|
|
1099
|
+
});
|
|
958
1100
|
mockDataAccess.Site.findById.resolves(mockSiteObject);
|
|
959
1101
|
|
|
960
1102
|
const result = await tierClient.getFirstEnrollment();
|
|
@@ -966,10 +1108,10 @@ describe('TierClient', () => {
|
|
|
966
1108
|
});
|
|
967
1109
|
});
|
|
968
1110
|
|
|
969
|
-
it('should handle error when fetching site', async () => {
|
|
1111
|
+
it('should handle error when fetching site via batchGetByKeys', async () => {
|
|
970
1112
|
mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
|
|
971
1113
|
mockDataAccess.SiteEnrollment.allByEntitlementId.resolves([mockSiteEnrollment]);
|
|
972
|
-
mockDataAccess.Site.
|
|
1114
|
+
mockDataAccess.Site.batchGetByKeys.rejects(new Error('Site fetch error'));
|
|
973
1115
|
|
|
974
1116
|
await expect(tierClient.getFirstEnrollment()).to.be.rejectedWith('Site fetch error');
|
|
975
1117
|
});
|