@adobe/spacecat-shared-tier-client 1.1.1 → 1.2.0

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 CHANGED
@@ -1,3 +1,17 @@
1
+ # [@adobe/spacecat-shared-tier-client-v1.2.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tier-client-v1.1.2...@adobe/spacecat-shared-tier-client-v1.2.0) (2025-10-08)
2
+
3
+
4
+ ### Features
5
+
6
+ * revoke enrollment API ([#1009](https://github.com/adobe/spacecat-shared/issues/1009)) ([7617368](https://github.com/adobe/spacecat-shared/commit/7617368082375e37ee1f23a097e7f4cf6b29edd7))
7
+
8
+ # [@adobe/spacecat-shared-tier-client-v1.1.2](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tier-client-v1.1.1...@adobe/spacecat-shared-tier-client-v1.1.2) (2025-09-24)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * move logs to debug ([#982](https://github.com/adobe/spacecat-shared/issues/982)) ([7a78c6e](https://github.com/adobe/spacecat-shared/commit/7a78c6ee011bbc8adf162644153170d3ebf29c83))
14
+
1
15
  # [@adobe/spacecat-shared-tier-client-v1.1.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-tier-client-v1.1.0...@adobe/spacecat-shared-tier-client-v1.1.1) (2025-09-22)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-tier-client",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Shared modules of the Spacecat Services - Tier Client",
5
5
  "type": "module",
6
6
  "engines": {
@@ -16,7 +16,6 @@ import {
16
16
  Entitlement as EntitlementModel,
17
17
  Organization,
18
18
  } from '@adobe/spacecat-shared-data-access';
19
-
20
19
  /**
21
20
  * TierClient provides methods to manage entitlements and site enrollments.
22
21
  */
@@ -104,41 +103,28 @@ class TierClient {
104
103
  async checkValidEntitlement() {
105
104
  try {
106
105
  const orgId = this.organization.getId();
107
- this.log.info(`Checking for valid entitlement for org ${orgId} and product ${this.productCode}`);
108
-
109
106
  const entitlement = await this.Entitlement
110
107
  .findByOrganizationIdAndProductCode(orgId, this.productCode);
111
108
 
112
109
  if (!entitlement) {
113
- this.log.info(`No valid entitlement found for org ${orgId} and product ${this.productCode}`);
114
110
  return {};
115
111
  }
116
-
117
- this.log.info(`Found valid entitlement: ${entitlement.getId()}`);
118
-
119
112
  // Only check for site enrollment if site is provided
120
113
  if (this.site) {
121
114
  const siteId = this.site.getId();
122
- this.log.info(`Checking for valid site enrollment for site ${siteId} and entitlement ${entitlement.getId()}`);
123
-
124
115
  const siteEnrollments = await this.SiteEnrollment.allBySiteId(siteId);
125
116
  const validSiteEnrollment = siteEnrollments.find(
126
117
  (se) => se.getEntitlementId() === entitlement.getId(),
127
118
  );
128
119
 
129
120
  if (!validSiteEnrollment) {
130
- this.log.info(`No valid site enrollment found for site ${siteId} and entitlement ${entitlement.getId()}`);
131
121
  return { entitlement };
132
122
  }
133
-
134
- this.log.info(`Found valid site enrollment: ${validSiteEnrollment.getId()}`);
135
-
136
123
  return {
137
124
  entitlement,
138
125
  siteEnrollment: validSiteEnrollment,
139
126
  };
140
127
  } else {
141
- this.log.info(`No site provided, returning entitlement only for org ${orgId}`);
142
128
  return { entitlement };
143
129
  }
144
130
  } catch (error) {
@@ -159,10 +145,7 @@ class TierClient {
159
145
  if (!Object.values(EntitlementModel.TIERS).includes(tier)) {
160
146
  throw new Error(`Invalid tier: ${tier}. Valid tiers: ${Object.values(EntitlementModel.TIERS).join(', ')}`);
161
147
  }
162
-
163
148
  const orgId = this.organization.getId();
164
- this.log.info(`Creating/updating entitlement for org ${orgId}, product ${this.productCode}, tier ${tier}`);
165
-
166
149
  // Check what already exists
167
150
  const existing = await this.checkValidEntitlement();
168
151
 
@@ -172,7 +155,6 @@ class TierClient {
172
155
 
173
156
  // If tier doesn't match, update it
174
157
  if (currentTier !== tier) {
175
- this.log.info(`Updating entitlement tier from ${currentTier} to ${tier} for org ${orgId}`);
176
158
  existing.entitlement.setTier(tier);
177
159
  await existing.entitlement.save();
178
160
  }
@@ -184,7 +166,6 @@ class TierClient {
184
166
  siteId,
185
167
  entitlementId: existing.entitlement.getId(),
186
168
  });
187
- this.log.info(`Created site enrollment: ${siteEnrollment.getId()}`);
188
169
  return {
189
170
  entitlement: existing.entitlement,
190
171
  siteEnrollment,
@@ -205,8 +186,6 @@ class TierClient {
205
186
  },
206
187
  });
207
188
 
208
- this.log.info(`Created new entitlement: ${entitlement.getId()}`);
209
-
210
189
  // If no site provided, return entitlement only
211
190
  if (!this.site) {
212
191
  return { entitlement };
@@ -219,8 +198,6 @@ class TierClient {
219
198
  entitlementId: entitlement.getId(),
220
199
  });
221
200
 
222
- this.log.info(`Created site enrollment: ${siteEnrollment.getId()}`);
223
-
224
201
  return {
225
202
  entitlement,
226
203
  siteEnrollment,
@@ -230,6 +207,19 @@ class TierClient {
230
207
  throw error;
231
208
  }
232
209
  }
210
+
211
+ /**
212
+ * Revokes site enrollment for the current site.
213
+ * @returns {Promise<object>} HTTP response object.
214
+ */
215
+ async revokeSiteEnrollment() {
216
+ const existing = await this.checkValidEntitlement();
217
+ if (existing.siteEnrollment) {
218
+ await existing.siteEnrollment.remove();
219
+ } else {
220
+ throw new Error('Site enrollment not found');
221
+ }
222
+ }
233
223
  }
234
224
 
235
225
  export default TierClient;
@@ -85,6 +85,7 @@ describe('TierClient', () => {
85
85
  log: {
86
86
  info: sandbox.stub(),
87
87
  error: sandbox.stub(),
88
+ debug: sandbox.stub(),
88
89
  },
89
90
  attributes: {
90
91
  authInfo: {
@@ -482,4 +483,64 @@ describe('TierClient', () => {
482
483
  expect(result).to.deep.equal({ entitlement: mockEntitlement });
483
484
  });
484
485
  });
486
+
487
+ describe('revokeSiteEnrollment', () => {
488
+ it('should successfully revoke site enrollment when it exists', async () => {
489
+ const mockSiteEnrollmentWithRemove = {
490
+ ...mockSiteEnrollment,
491
+ remove: sandbox.stub().resolves(),
492
+ };
493
+
494
+ mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
495
+ mockDataAccess.SiteEnrollment.allBySiteId.resolves([mockSiteEnrollmentWithRemove]);
496
+
497
+ await tierClient.revokeSiteEnrollment();
498
+
499
+ expect(mockSiteEnrollmentWithRemove.remove.calledOnce).to.be.true;
500
+ });
501
+
502
+ it('should throw error when site enrollment does not exist', async () => {
503
+ mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
504
+ mockDataAccess.SiteEnrollment.allBySiteId.resolves([]);
505
+
506
+ await expect(tierClient.revokeSiteEnrollment()).to.be.rejectedWith('Site enrollment not found');
507
+ });
508
+
509
+ it('should throw error when entitlement does not exist', async () => {
510
+ mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(null);
511
+
512
+ await expect(tierClient.revokeSiteEnrollment()).to.be.rejectedWith('Site enrollment not found');
513
+ });
514
+
515
+ it('should handle database errors during revocation', async () => {
516
+ const mockSiteEnrollmentWithRemove = {
517
+ ...mockSiteEnrollment,
518
+ remove: sandbox.stub().rejects(new Error('Database error')),
519
+ };
520
+
521
+ mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
522
+ mockDataAccess.SiteEnrollment.allBySiteId.resolves([mockSiteEnrollmentWithRemove]);
523
+
524
+ await expect(tierClient.revokeSiteEnrollment()).to.be.rejectedWith('Database error');
525
+ });
526
+
527
+ it('should handle errors when checking valid entitlement', async () => {
528
+ mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.rejects(new Error('Database error'));
529
+
530
+ await expect(tierClient.revokeSiteEnrollment()).to.be.rejectedWith('Database error');
531
+ });
532
+
533
+ it('should throw error with organization-only client (no site)', async () => {
534
+ const orgOnlyClient = new TierClient(
535
+ mockContext,
536
+ organizationInstance,
537
+ null,
538
+ productCode,
539
+ );
540
+
541
+ mockDataAccess.Entitlement.findByOrganizationIdAndProductCode.resolves(mockEntitlement);
542
+
543
+ await expect(orgOnlyClient.revokeSiteEnrollment()).to.be.rejectedWith('Site enrollment not found');
544
+ });
545
+ });
485
546
  });