Skip to content

Commit d30c6c2

Browse files
committed
Fix remaining tests
1 parent 3fc1c3a commit d30c6c2

4 files changed

Lines changed: 31 additions & 12 deletions

File tree

packages/fxa-auth-server/lib/oauth/grant.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const JWT_ACCESS_TOKENS_ENABLED = config.get(
3131
const JWT_ACCESS_TOKENS_CLIENT_IDS = new Set(
3232
config.get('oauthServer.jwtAccessTokens.enabledClientIds')
3333
);
34+
const SUBSCRIPTIONS_ENABLED = !!config.get('subscriptions.enabled');
3435

3536
const UNTRUSTED_CLIENT_ALLOWED_SCOPES = ScopeSet.fromArray([
3637
'openid',
@@ -264,7 +265,14 @@ exports.generateAccessToken = async function generateAccessToken(grant) {
264265
return accessToken;
265266
}
266267

267-
if (grant.scope.contains('profile:subscriptions')) {
268+
// Skip when subscriptions are disabled. Mirrors the gate
269+
// `lib/routes/account.ts` already applies before calling
270+
// `capabilityService.subscriptionCapabilities` / `hasFreeAccess` —
271+
// without it, this path drives a chain that ends in
272+
// `planIdsToClientCapabilities` throwing (errno 998) because no
273+
// `CapabilityManager` is registered in Container when subscriptions
274+
// are off.
275+
if (SUBSCRIPTIONS_ENABLED && grant.scope.contains('profile:subscriptions')) {
268276
const capabilities =
269277
await capabilityService.determineClientVisibleSubscriptionCapabilities(
270278
clientId,

packages/fxa-auth-server/lib/oauth/grant.spec.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
// `grant.js` captures `JWT_ACCESS_TOKENS_ENABLED` and the allow-list at
6-
// module load, so the config is fixed once here. validateRequestedGrant
7-
// tests don't depend on those values; generateTokens tests do.
5+
// `grant.js` captures `JWT_ACCESS_TOKENS_ENABLED`, the allow-list, and
6+
// `SUBSCRIPTIONS_ENABLED` at module load, so the config is fixed once
7+
// here. validateRequestedGrant tests don't depend on those values;
8+
// generateTokens tests do.
89
jest.mock('../../config', () => {
910
const realConfig = jest.requireActual('../../config').config;
1011
return {
@@ -15,6 +16,8 @@ jest.mock('../../config', () => {
1516
return true;
1617
case 'oauthServer.jwtAccessTokens.enabledClientIds':
1718
return ['9876543210'];
19+
case 'subscriptions.enabled':
20+
return true;
1821
default:
1922
return realConfig.get(key);
2023
}

packages/fxa-auth-server/lib/payments/capability.spec.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -905,14 +905,14 @@ describe('CapabilityService', () => {
905905

906906
describe('subscriptionCapabilities — email-list merge', () => {
907907
beforeEach(() => {
908-
// No subscriptions so we isolate the email-list contribution.
909-
mockStripeHelper.fetchCustomer = jest.fn(async () => ({
910-
subscriptions: { data: [] },
911-
}));
912-
mockStripeHelper.iapPurchasesToPriceIds = jest.fn().mockReturnValue([]);
913-
mockPlayBilling.userManager.queryCurrentSubscriptions = jest
914-
.fn()
915-
.mockResolvedValue([]);
908+
// Stub the price-ID lookup so it returns a single placeholder price.
909+
// The merge tests rely on the `priceIdsToClientCapabilities` mock
910+
// returning subscription caps; `planIdsToClientCapabilities`
911+
// short-circuits on an empty input, so we need a non-empty array
912+
// here for the CapabilityManager path to be exercised at all.
913+
jest
914+
.spyOn(CapabilityService.prototype, 'subscribedPriceIds')
915+
.mockResolvedValue(['price_test']);
916916
mockCapabilityManager.priceIdsToClientCapabilities = jest
917917
.fn()
918918
.mockResolvedValue({});

packages/fxa-auth-server/lib/payments/capability.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,14 @@ export class CapabilityService {
799799
async planIdsToClientCapabilities(
800800
subscribedPrices: string[]
801801
): Promise<ClientIdCapabilityMap> {
802+
// No prices to resolve → no capabilities. Short-circuit before the
803+
// CapabilityManager guard so callers that pass through with an empty
804+
// list (e.g. `/v1/oauth/token` for an account with no Stripe subs)
805+
// don't hit a 500 just because CMS isn't wired in this environment.
806+
if (subscribedPrices.length === 0) {
807+
return {};
808+
}
809+
802810
if (!this.capabilityManager) {
803811
throw error.internalValidationError(
804812
'planIdsToClientCapabilities',

0 commit comments

Comments
 (0)