Skip to content

Commit 7441d16

Browse files
committed
slas client create should merge custom scopes with default
1 parent be0106c commit 7441d16

2 files changed

Lines changed: 52 additions & 2 deletions

File tree

packages/b2c-cli/src/commands/slas/client/create.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export default class SlasClientCreate extends SlasClientCommand<typeof SlasClien
7979
delimiter: ',',
8080
}),
8181
'default-scopes': Flags.boolean({
82-
description: 'Use default shopper scopes (alternative to --scopes)',
82+
description: 'Use default shopper scopes (can be combined with --scopes for additional scopes)',
8383
default: false,
8484
}),
8585
'redirect-uri': Flags.string({
@@ -140,7 +140,7 @@ export default class SlasClientCreate extends SlasClientCommand<typeof SlasClien
140140

141141
// oclif handles comma-separation via delimiter option
142142
const parsedChannels = channels;
143-
const parsedScopes = useDefaultScopes ? DEFAULT_SCOPES : scopes!;
143+
const parsedScopes = useDefaultScopes ? [...new Set([...(scopes ?? []), ...DEFAULT_SCOPES])] : scopes!;
144144
const parsedRedirectUri = redirectUri;
145145
const parsedCallbackUri = callbackUri;
146146

packages/b2c-cli/test/commands/slas/client/create.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,56 @@ describe('slas client create', () => {
157157
expect(result.isPrivateClient).to.equal(false);
158158
});
159159

160+
it('merges custom scopes with default scopes when both --default-scopes and --scopes are provided', async () => {
161+
const command: any = await createCommand(
162+
{
163+
'tenant-id': 'abcd_123',
164+
name: 'My Client',
165+
channels: ['RefArch'],
166+
scopes: ['sfcc.shopper-products', 'my.custom.scope'],
167+
'default-scopes': true,
168+
'redirect-uri': ['http://localhost/callback'],
169+
public: true,
170+
'create-tenant': false,
171+
},
172+
{clientId: 'my-client'},
173+
);
174+
175+
sinon.stub(command, 'requireOAuthCredentials').returns(void 0);
176+
177+
const putStub = sinon.stub().resolves({
178+
data: {
179+
clientId: 'my-client',
180+
name: 'My Client',
181+
isPrivateClient: false,
182+
},
183+
error: undefined,
184+
response: {status: 201},
185+
});
186+
187+
sinon.stub(command, 'getSlasClient').returns({
188+
PUT: putStub,
189+
} as any);
190+
191+
sinon.stub(command, 'ensureTenantExists').resolves(void 0);
192+
sinon.stub(command, 'jsonEnabled').returns(true);
193+
194+
await command.run();
195+
196+
const [, options] = putStub.firstCall.args as [string, any];
197+
const sentScopes = options.body.scopes as string[];
198+
199+
// Should contain the custom scope
200+
expect(sentScopes).to.include('my.custom.scope');
201+
// Should contain default scopes (spot-check a few)
202+
expect(sentScopes).to.include('sfcc.shopper-products');
203+
expect(sentScopes).to.include('sfcc.shopper-baskets-orders.rw');
204+
expect(sentScopes).to.include('sfcc.shopper-customers.login');
205+
// sfcc.shopper-products appears in both --scopes and defaults; should not be duplicated
206+
const productScopeCount = sentScopes.filter((s: string) => s === 'sfcc.shopper-products').length;
207+
expect(productScopeCount).to.equal(1);
208+
});
209+
160210
it('calls ensureTenantExists when --create-tenant is true', async () => {
161211
const command: any = await createCommand(
162212
{

0 commit comments

Comments
 (0)