Skip to content

Commit 125c8ea

Browse files
committed
fix: loadcodeassist eligible tiers getting ignored for unlicensed users (regression)
1 parent b07953f commit 125c8ea

File tree

2 files changed

+112
-2
lines changed

2 files changed

+112
-2
lines changed

packages/core/src/code_assist/setup.test.ts

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,10 @@ describe('setupUser validation', () => {
332332
vi.unstubAllEnvs();
333333
});
334334

335-
it('should throw error if LoadCodeAssist returns ineligible tiers and no current tier', async () => {
335+
it('should throw error if LoadCodeAssist returns ineligible tiers, no current tier, and no allowed tiers', async () => {
336336
mockLoad.mockResolvedValue({
337337
currentTier: null,
338+
allowedTiers: [],
338339
ineligibleTiers: [
339340
{
340341
reasonMessage: 'User is not eligible',
@@ -350,6 +351,110 @@ describe('setupUser validation', () => {
350351
);
351352
});
352353

354+
it('should continue if LoadCodeAssist returns ineligible tiers but has allowed tiers', async () => {
355+
const mockOnboardUser = vi.fn().mockResolvedValue({
356+
done: true,
357+
response: {
358+
cloudaicompanionProject: {
359+
id: 'server-project',
360+
},
361+
},
362+
});
363+
vi.mocked(CodeAssistServer).mockImplementation(
364+
() =>
365+
({
366+
loadCodeAssist: mockLoad,
367+
onboardUser: mockOnboardUser,
368+
}) as unknown as CodeAssistServer,
369+
);
370+
371+
mockLoad.mockResolvedValue({
372+
currentTier: null,
373+
allowedTiers: [mockPaidTier],
374+
ineligibleTiers: [
375+
{
376+
reasonMessage: 'Not eligible for free tier',
377+
reasonCode: 'INELIGIBLE_ACCOUNT',
378+
tierId: 'free-tier',
379+
tierName: 'free',
380+
},
381+
],
382+
});
383+
384+
// Should not throw - should proceed to onboarding with the allowed tier
385+
const result = await setupUser({} as OAuth2Client);
386+
expect(result).toEqual({
387+
projectId: 'server-project',
388+
userTier: 'standard-tier',
389+
userTierName: 'paid',
390+
});
391+
expect(mockOnboardUser).toHaveBeenCalled();
392+
});
393+
394+
it('should throw error when only ineligible tiers exist and allowedTiers is undefined', async () => {
395+
mockLoad.mockResolvedValue({
396+
currentTier: null,
397+
allowedTiers: undefined,
398+
ineligibleTiers: [
399+
{
400+
reasonMessage: 'User is not eligible',
401+
reasonCode: 'INELIGIBLE_ACCOUNT',
402+
tierId: 'standard-tier',
403+
tierName: 'standard',
404+
},
405+
],
406+
});
407+
408+
await expect(setupUser({} as OAuth2Client)).rejects.toThrow(
409+
'User is not eligible',
410+
);
411+
});
412+
413+
it('should throw ValidationRequiredError even if allowed tiers exist', async () => {
414+
mockLoad.mockResolvedValue({
415+
currentTier: null,
416+
allowedTiers: [mockPaidTier],
417+
ineligibleTiers: [
418+
{
419+
reasonMessage: 'Please verify your account',
420+
reasonCode: 'VALIDATION_REQUIRED',
421+
tierId: 'free-tier',
422+
tierName: 'free',
423+
validationUrl: 'https://example.com/verify',
424+
},
425+
],
426+
});
427+
428+
await expect(setupUser({} as OAuth2Client)).rejects.toThrow(
429+
ValidationRequiredError,
430+
);
431+
});
432+
433+
it('should combine multiple ineligible tier messages when no allowed tiers', async () => {
434+
mockLoad.mockResolvedValue({
435+
currentTier: null,
436+
allowedTiers: [],
437+
ineligibleTiers: [
438+
{
439+
reasonMessage: 'Not eligible for standard',
440+
reasonCode: 'INELIGIBLE_ACCOUNT',
441+
tierId: 'standard-tier',
442+
tierName: 'standard',
443+
},
444+
{
445+
reasonMessage: 'Not eligible for free',
446+
reasonCode: 'INELIGIBLE_ACCOUNT',
447+
tierId: 'free-tier',
448+
tierName: 'free',
449+
},
450+
],
451+
});
452+
453+
await expect(setupUser({} as OAuth2Client)).rejects.toThrow(
454+
'Not eligible for standard, Not eligible for free',
455+
);
456+
});
457+
353458
it('should retry if validation handler returns verify', async () => {
354459
// First call fails
355460
mockLoad.mockResolvedValueOnce({

packages/core/src/code_assist/setup.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,12 @@ function validateLoadCodeAssistResponse(res: LoadCodeAssistResponse): void {
204204
);
205205
}
206206

207-
// For other ineligibility reasons, throw a generic error
207+
// If there are eligible tiers, continue despite ineligible ones
208+
if (res.allowedTiers && res.allowedTiers.length > 0) {
209+
return;
210+
}
211+
212+
// No eligible tiers - throw error with ineligibility reasons
208213
const reasons = res.ineligibleTiers.map((t) => t.reasonMessage).join(', ');
209214
throw new Error(reasons);
210215
}

0 commit comments

Comments
 (0)