Skip to content
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

Catch delete token error if namespace is not provisioned #1046

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion packages/common/src/helpers/__tests__/errors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import axios, { AxiosError, AxiosResponse } from 'axios';
import { HttpError } from '@kubernetes/client-node';
import AxiosMockAdapter from 'axios-mock-adapter';
import * as http from 'http';
import { getMessage, isAxiosError, isError } from '../errors';
import {
getMessage,
isAxiosError,
isError,
isTokenNotFoundError,
} from '../errors';

const mockAxios = new AxiosMockAdapter(axios);

Expand All @@ -41,6 +46,30 @@ describe('Errors helper', () => {
error.isAxiosError = true;
expect(isAxiosError(error)).toEqual(true);
});

it('should check if token not found error', () => {
const expectedError = {
name: '',
config: {},
request: {},
response: {
data: {
message:
'OAuth token for user xxxxx-xxxxx-xxxxx-xxxxx was not found',
},
status: 401,
statusText: '',
headers: {},
config: {},
request: {},
},
message: '',
};

const unexpectedError = new Error('Unsupported OAuth provider xxxxx');
expect(isTokenNotFoundError(expectedError)).toEqual(true);
expect(isTokenNotFoundError(unexpectedError)).toEqual(false);
});
});

it('should return default message', () => {
Expand Down
10 changes: 10 additions & 0 deletions packages/common/src/helpers/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,13 @@ export function isKubeClientError(error: unknown): error is HttpError {
'body' in (error as HttpError)
);
}
export function isTokenNotFoundError(
error: unknown,
): error is ObjectWithAxiosResponse {
return (
includesAxiosResponse(error) &&
/^OAuth token for user .* was not found$/.test(
(error as ObjectWithAxiosResponse).response.data.message,
)
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,30 @@ const mockGetOAuthToken = jest.fn().mockImplementation(provider => {
}
return new Promise((_resolve, reject) => reject(new Error('Token not found')));
});
const mockDeleteOAuthToken = jest.fn().mockImplementation(provider => {
if (provider === 'github') {
return new Promise((_resolve, reject) => {
const expectedError = {
name: '',
config: {},
request: {},
response: {
data: {
message: 'OAuth token for user xxxxx-xxxxx-xxxxx-xxxxx was not found',
},
status: 401,
statusText: '',
headers: {},
config: {},
request: {},
},
message: '',
};
reject(expectedError);
});
}
return new Promise(resolve => resolve(undefined));
});
const mockFetchTokens = jest.fn().mockResolvedValue([
{
tokenName: 'github-personal-access-token',
Expand All @@ -68,6 +92,7 @@ jest.mock('@/services/backend-client/oAuthApi', () => {
return {
getOAuthProviders: (...args: unknown[]) => mockGetOAuthProviders(...args),
getOAuthToken: (...args: unknown[]) => mockGetOAuthToken(...args),
deleteOAuthToken: (...args: unknown[]) => mockDeleteOAuthToken(...args),
getDevWorkspacePreferences: (...args: unknown[]) => mockGetDevWorkspacePreferences(...args),
};
});
Expand Down Expand Up @@ -113,4 +138,30 @@ describe('GitOauthConfig store, actions', () => {

expect(actions).toContainEqual(expectedAction);
});

it('should request DeleteGitOauthToken', async () => {
await store.dispatch(TestStore.actionCreators.revokeOauth('gitlab'));

const actions = store.getActions();

const expectedAction: TestStore.KnownAction = {
provider: 'gitlab',
type: TestStore.Type.DELETE_GIT_OAUTH_TOKEN,
};

expect(actions).toContainEqual(expectedAction);
});

it('should request DeleteGitOauthToken in the case with token not found error', async () => {
await store.dispatch(TestStore.actionCreators.revokeOauth('github')); // this oauthProvider throws the token not found error

const actions = store.getActions();

const expectedAction: TestStore.KnownAction = {
provider: 'github',
type: TestStore.Type.DELETE_GIT_OAUTH_TOKEN,
};

expect(actions).toContainEqual(expectedAction);
});
});
22 changes: 12 additions & 10 deletions packages/dashboard-frontend/src/store/GitOauthConfig/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,18 +219,20 @@ export const actionCreators: ActionCreators = {

try {
await deleteOAuthToken(oauthProvider);
dispatch({
type: Type.DELETE_GIT_OAUTH_TOKEN,
provider: oauthProvider,
});
} catch (e) {
const errorMessage = common.helpers.errors.getMessage(e);
dispatch({
type: Type.RECEIVE_GIT_OAUTH_ERROR,
error: errorMessage,
});
throw e;
if (!common.helpers.errors.isTokenNotFoundError(e)) {
const errorMessage = common.helpers.errors.getMessage(e);
dispatch({
type: Type.RECEIVE_GIT_OAUTH_ERROR,
error: errorMessage,
});
throw e;
}
}
dispatch({
type: Type.DELETE_GIT_OAUTH_TOKEN,
provider: oauthProvider,
});
},

deleteSkipOauth:
Expand Down
Loading