-
Notifications
You must be signed in to change notification settings - Fork 19
Fix(#297) : Enhance project creation with recovery tests and error handling #298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
haddybhaiya
wants to merge
14
commits into
InsForge:main
Choose a base branch
from
haddybhaiya:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 7 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
46a9da4
test(create): add recovery tests for project creation handling
haddybhaiya ec80472
feat(create): enhance project creation with recovery handling and tra…
haddybhaiya 859aea8
test(create): update recovery tests to report ambiguous results after…
haddybhaiya ebd697d
refactor(create): improve project creation error handling and rename …
haddybhaiya 9266f56
refactor(create): enhance project recovery handling by preserving las…
haddybhaiya 80a02c1
refactor(create): update error handling for project activation timeou…
haddybhaiya e9c768c
Merge pull request #6 from haddybhaiya/create-err
haddybhaiya 6a97bad
refactor(create): enhance project recovery handling with improved tim…
haddybhaiya 0918991
refactor(auth): implement abort handling for OAuth login and token ex…
haddybhaiya 6fc8d3a
refactor(platform): add abort signal support for token refresh and pl…
haddybhaiya 1e6947d
refactor(auth): improve OAuth login handling with abort support and t…
haddybhaiya bdf00ac
refactor(create): update error messages to clarify API URL usage in p…
haddybhaiya c3f5522
refactor(auth): add cleanup for global mocks after tests and ensure s…
haddybhaiya 320bad5
Merge pull request #7 from haddybhaiya/create-err
haddybhaiya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest'; | ||
| import { CLIError, isTransientApiError } from '../lib/errors.js'; | ||
|
|
||
| vi.mock('../lib/api/platform.js', () => ({ | ||
| listOrganizations: vi.fn(), | ||
| createProject: vi.fn(), | ||
| getProject: vi.fn(), | ||
| getProjectApiKey: vi.fn(), | ||
| NETWORK_ERROR_CODE: 'NETWORK_ERROR', | ||
| })); | ||
|
|
||
| import { | ||
| createProjectOrReportAmbiguousResult, | ||
| isAmbiguousProjectCreateFailure, | ||
| waitForProjectActive, | ||
| } from './create.js'; | ||
|
|
||
| const createdProject = { | ||
| id: 'project-id', | ||
| organization_id: 'org-id', | ||
| name: 'demo', | ||
| appkey: 'demo-appkey', | ||
| region: 'eu-central', | ||
| status: 'creating', | ||
| instance_type: 'shared', | ||
| service_version: null, | ||
| customized_domain: null, | ||
| created_at: new Date().toISOString(), | ||
| updated_at: new Date().toISOString(), | ||
| }; | ||
|
|
||
| describe('create project recovery', () => { | ||
| beforeEach(async () => { | ||
| vi.clearAllMocks(); | ||
| const platform = await import('../lib/api/platform.js'); | ||
| (platform.createProject as Mock).mockResolvedValue(createdProject); | ||
| (platform.getProject as Mock).mockResolvedValue({ ...createdProject, status: 'active' }); | ||
| }); | ||
|
|
||
| it('reports an unknown result after a gateway failure without adopting a project', async () => { | ||
| const platform = await import('../lib/api/platform.js'); | ||
| (platform.createProject as Mock).mockRejectedValueOnce( | ||
| new CLIError('Request failed: 502', 1, undefined, 502), | ||
| ); | ||
|
|
||
| await expect(createProjectOrReportAmbiguousResult('org-id', 'demo', 'eu-central', undefined)) | ||
| .rejects.toMatchObject({ | ||
| code: 'PROJECT_CREATE_RESULT_UNKNOWN', | ||
| statusCode: 502, | ||
| message: expect.stringContaining('insforge list --json'), | ||
| }); | ||
| }); | ||
|
|
||
| it('never reconciles an ordinary API 500', async () => { | ||
| const platform = await import('../lib/api/platform.js'); | ||
| const failure = new CLIError('Internal server error', 1, undefined, 500); | ||
| (platform.createProject as Mock).mockRejectedValueOnce(failure); | ||
|
|
||
| await expect(createProjectOrReportAmbiguousResult('org-id', 'demo', 'eu-central', undefined)) | ||
| .rejects.toBe(failure); | ||
| }); | ||
|
|
||
| it('recognizes only gateway and transport failures as ambiguous', () => { | ||
| expect(isAmbiguousProjectCreateFailure(new CLIError('network', 1, 'NETWORK_ERROR'))).toBe(true); | ||
| expect(isAmbiguousProjectCreateFailure(new CLIError('gateway', 1, undefined, 503))).toBe(true); | ||
| expect(isAmbiguousProjectCreateFailure(new CLIError('invalid request', 1, undefined, 400))).toBe(false); | ||
| expect(isAmbiguousProjectCreateFailure(new CLIError('server error', 1, undefined, 500))).toBe(false); | ||
| }); | ||
|
|
||
| it('continues polling through three transient activation-read failures when the project recovers', async () => { | ||
| const platform = await import('../lib/api/platform.js'); | ||
| (platform.getProject as Mock) | ||
| .mockRejectedValueOnce(new CLIError('Request failed: 502', 1, undefined, 502)) | ||
| .mockRejectedValueOnce(new CLIError('Request failed: 502', 1, undefined, 502)) | ||
| .mockRejectedValueOnce(new CLIError('Request failed: 502', 1, undefined, 502)) | ||
| .mockResolvedValueOnce({ ...createdProject, status: 'active' }); | ||
| vi.useFakeTimers(); | ||
| try { | ||
| const pending = waitForProjectActive('project-id'); | ||
| await vi.runAllTimersAsync(); | ||
| await expect(pending).resolves.toBeUndefined(); | ||
| } finally { | ||
| vi.useRealTimers(); | ||
| } | ||
| expect(platform.getProject).toHaveBeenCalledTimes(4); | ||
| }); | ||
|
|
||
| it('preserves the last actionable error when the activation deadline expires', async () => { | ||
| const platform = await import('../lib/api/platform.js'); | ||
| (platform.getProject as Mock).mockRejectedValue( | ||
| new CLIError('Request failed: 502', 1, undefined, 502), | ||
| ); | ||
| vi.useFakeTimers(); | ||
| try { | ||
| const pending = waitForProjectActive('project-id', undefined, 10_000) | ||
| .catch(err => err as CLIError); | ||
| await vi.runAllTimersAsync(); | ||
| const timeout = await pending; | ||
| expect(timeout).toMatchObject({ | ||
| code: 'PROJECT_ACTIVATION_TIMEOUT', | ||
| message: expect.stringContaining('Last control-plane error: Request failed: 502'), | ||
| }); | ||
| expect(timeout.statusCode).toBeUndefined(); | ||
| expect(isTransientApiError(timeout)).toBe(false); | ||
| } finally { | ||
| vi.useRealTimers(); | ||
| } | ||
| expect(platform.getProject).toHaveBeenCalledTimes(4); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.