|
1 | 1 | import { describe, expect, test } from 'vitest'; |
2 | 2 | import { RequestError } from '@octokit/request-error'; |
3 | 3 | import { GitbeakerRequestError } from '@gitbeaker/requester-utils'; |
4 | | -import { isForbidden, isUnauthorized } from './errors'; |
| 4 | +import { isForbidden, isGone, isUnauthorized } from './errors'; |
5 | 5 | import { throwOnHttpError } from './bitbucket'; |
6 | 6 |
|
7 | 7 | // Helper: invoke the openapi-fetch middleware against a synthetic Response and |
@@ -148,6 +148,56 @@ describe('isForbidden', () => { |
148 | 148 | }); |
149 | 149 | }); |
150 | 150 |
|
| 151 | +describe('isGone', () => { |
| 152 | + test('Octokit RequestError with status 410', () => { |
| 153 | + const err = new RequestError('Gone', 410, { |
| 154 | + request: { method: 'GET', url: 'https://api.github.com/user/repos', headers: {} }, |
| 155 | + }); |
| 156 | + expect(isGone(err)).toBe(true); |
| 157 | + }); |
| 158 | + |
| 159 | + test('Octokit RequestError with status 401 is NOT gone', () => { |
| 160 | + const err = new RequestError('Unauthorized', 401, { |
| 161 | + request: { method: 'GET', url: 'https://api.github.com/user/repos', headers: {} }, |
| 162 | + }); |
| 163 | + expect(isGone(err)).toBe(false); |
| 164 | + }); |
| 165 | + |
| 166 | + test('Bitbucket middleware throws an isGone error on 410 Response', async () => { |
| 167 | + // Real-world case: Bitbucket Cloud's CHANGE-2770 removed |
| 168 | + // /2.0/user/permissions/repositories and now returns 410 Gone. |
| 169 | + const err = await invokeMiddleware(new Response('CHANGE-2770 - Functionality has been deprecated', { status: 410 })); |
| 170 | + expect(err).toBeInstanceOf(Error); |
| 171 | + expect(isGone(err)).toBe(true); |
| 172 | + }); |
| 173 | + |
| 174 | + test('real GitbeakerRequestError with response status 410', () => { |
| 175 | + const err = new GitbeakerRequestError('Gone', { |
| 176 | + cause: { |
| 177 | + description: 'Gone', |
| 178 | + request: new Request('https://gitlab.com/api/v4/projects'), |
| 179 | + response: new Response(null, { status: 410 }), |
| 180 | + }, |
| 181 | + }); |
| 182 | + expect(isGone(err)).toBe(true); |
| 183 | + }); |
| 184 | + |
| 185 | + test('plain Error without status is NOT gone', () => { |
| 186 | + expect(isGone(new Error('Missing required scope'))).toBe(false); |
| 187 | + }); |
| 188 | + |
| 189 | + test('null is NOT gone', () => { |
| 190 | + expect(isGone(null)).toBe(false); |
| 191 | + }); |
| 192 | + |
| 193 | + test('Octokit RequestError with status 500 is NOT gone', () => { |
| 194 | + const err = new RequestError('Internal Server Error', 500, { |
| 195 | + request: { method: 'GET', url: 'https://api.github.com/user/repos', headers: {} }, |
| 196 | + }); |
| 197 | + expect(isGone(err)).toBe(false); |
| 198 | + }); |
| 199 | +}); |
| 200 | + |
151 | 201 | describe('throwOnHttpError middleware contract', () => { |
152 | 202 | test('does not throw on 2xx Response', async () => { |
153 | 203 | const err = await invokeMiddleware(new Response('ok', { status: 200 })); |
|
0 commit comments