Skip to content

Commit 6c0cd4c

Browse files
authored
fix: throw more useful error if OAuthClientCredentialsApiClient fails to authenticate (#58)
Fixes #52
1 parent 47992d4 commit 6c0cd4c

File tree

10 files changed

+8371
-126
lines changed

10 files changed

+8371
-126
lines changed

package-lock.json

Lines changed: 8312 additions & 101 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spec/fakes/common/response.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
export function createFakeResponseBody(
22
status: number,
33
json: any = {},
4+
ok = true,
45
headers: any = []
56
) {
67
return {
7-
status: status,
8+
status,
9+
ok,
810
json: async() => (json),
9-
ok: true,
1011
headers: { get: () => headers }
1112
};
1213
}

src/common/client/bugsplat-api-client/bugsplat-api-client.e2e.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ describe('BugSplatApiClient', () => {
1818
expect(json.user).toEqual(email);
1919
});
2020

21-
it('should throw error for incorrect email and password', async () => {
22-
try {
23-
await client.login(email, 'password');
24-
fail('login was supposed to throw!');
25-
} catch (error: any) {
26-
expect(error.message).toMatch(/Invalid email or password/);
27-
}
21+
describe('error', () => {
22+
it('should throw error for incorrect email and password', async () => {
23+
await expectAsync(client.login(email, 'password')).toBeRejectedWithError(
24+
Error,
25+
/Could not authenticate, check credentials and try again/
26+
);
27+
});
2828
});
2929
});
3030
});

src/common/client/bugsplat-api-client/bugsplat-api-client.spec.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe('BugSplatApiClient', () => {
2121
expectedStatus = 'success';
2222
expectedJson = { success: 'true' };
2323
fakeFormData = { append: appendSpy, toString: () => 'BugSplat rocks!' };
24-
fakeSuccessReponseBody = createFakeResponseBody(expectedStatus, expectedJson, cookie);
24+
fakeSuccessReponseBody = createFakeResponseBody(expectedStatus, expectedJson, true, cookie);
2525
client = createFakeBugSplatApiClient(
2626
Environment.Node,
2727
fakeSuccessReponseBody,
@@ -122,13 +122,12 @@ describe('BugSplatApiClient', () => {
122122

123123
describe('error', () => {
124124
it('should throw if response status is 401', async () => {
125-
try {
126-
(<any>client)._fetch.and.returnValue({ status: 401 });
127-
await client.login(email, password);
128-
fail('login was supposed to throw!');
129-
} catch (error) {
130-
expect(error).toMatch(/Invalid email or password/);
131-
}
125+
(<any>client)._fetch.and.returnValue({ status: 401 });
126+
127+
await expectAsync(client.login(email, password)).toBeRejectedWithError(
128+
Error,
129+
/Could not authenticate, check credentials and try again/
130+
);
132131
});
133132
});
134133
});

src/common/client/bugsplat-api-client/bugsplat-api-client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class BugSplatApiClient implements ApiClient {
6767
});
6868

6969
if (response.status === 401) {
70-
throw new Error('Invalid email or password');
70+
throw new Error('Could not authenticate, check credentials and try again');
7171
}
7272

7373
if (this._environment === Environment.Node) {

src/common/client/oauth-client-credentials-api-client/oauth-client-credentials-api-client.e2e.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ describe('OAuthClientCredentialsClient', () => {
2525
expect(json.access_token).toBeDefined();
2626
expect(json.token_type).toBeDefined();
2727
});
28+
29+
describe('error', () => {
30+
it('should throw error for incorrect email and password', async () => {
31+
const client = new OAuthClientCredentialsClient('BugSplat', 'rocks');
32+
33+
await expectAsync(client.login()).toBeRejectedWithError(
34+
Error,
35+
/Could not authenticate, check credentials and try again/
36+
);
37+
});
38+
});
2839
});
2940

3041
describe('fetch', () => {

src/common/client/oauth-client-credentials-api-client/oauth-client-credentials-api-client.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,24 @@ describe('OAuthClientCredentialsClient', () => {
6868
expect(result.status).toEqual(fakeAuthorizeResponseBody.status);
6969
expect(json).toEqual(fakeAuthorizeResult);
7070
});
71+
72+
describe('error', () => {
73+
it('should return useful error message when authenication fails', async () => {
74+
const failureResponseBody = createFakeResponseBody(200, { error: 'invalid_client' });
75+
sut = createFakeOAuthClientCredentialsClient(
76+
'blah',
77+
'blah',
78+
host,
79+
failureResponseBody,
80+
fakeFormData
81+
);
82+
83+
await expectAsync(sut.login()).toBeRejectedWithError(
84+
Error,
85+
/Could not authenticate, check credentials and try again/
86+
);
87+
});
88+
});
7189
});
7290

7391
describe('fetch', () => {

src/common/client/oauth-client-credentials-api-client/oauth-client-credentials-api-client.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,15 @@ export class OAuthClientCredentialsClient implements ApiClient {
4444

4545
const response = await this.fetch(url, <RequestInit><unknown>request);
4646
const responseJson = await response.json();
47+
const status = response.status;
48+
49+
if (responseJson.error === 'invalid_client') {
50+
throw new Error('Could not authenticate, check credentials and try again');
51+
}
52+
4753
this._accessToken = responseJson.access_token;
4854
this._tokenType = responseJson.token_type;
49-
50-
const status = response.status;
55+
5156
const json = async () => responseJson;
5257
return {
5358
status,

src/crash/crash-api-client/crash-api-client.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe('CrashApiClient', () => {
2121

2222
beforeEach(async () => {
2323
fakeCrashApiResponse = createFakeCrashApiResponse();
24-
const fakeResponse = createFakeResponseBody(200, fakeCrashApiResponse, []);
24+
const fakeResponse = createFakeResponseBody(200, fakeCrashApiResponse);
2525
fakeBugSplatApiClient = createFakeBugSplatApiClient(fakeFormData, fakeResponse);
2626
client = new CrashApiClient(fakeBugSplatApiClient);
2727

@@ -58,7 +58,7 @@ describe('CrashApiClient', () => {
5858

5959
try {
6060
const fakeReprocessErrorBody = { message };
61-
const fakeResponse = createFakeResponseBody(400, fakeReprocessErrorBody, []);
61+
const fakeResponse = createFakeResponseBody(400, fakeReprocessErrorBody, false);
6262
const fakeBugSplatApiClient = createFakeBugSplatApiClient(fakeFormData, fakeResponse);
6363
const client = new CrashApiClient(fakeBugSplatApiClient);
6464

@@ -96,7 +96,7 @@ describe('CrashApiClient', () => {
9696

9797
beforeEach(async () => {
9898
fakeReprocessApiResponse = { success: true };
99-
const fakeResponse = createFakeResponseBody(202, fakeReprocessApiResponse, []);
99+
const fakeResponse = createFakeResponseBody(202, fakeReprocessApiResponse);
100100
fakeBugSplatApiClient = createFakeBugSplatApiClient(fakeFormData, fakeResponse);
101101
client = new CrashApiClient(fakeBugSplatApiClient);
102102

@@ -132,7 +132,7 @@ describe('CrashApiClient', () => {
132132

133133
try {
134134
const fakeReprocessErrorBody = { message };
135-
const fakeResponse = createFakeResponseBody(422, fakeReprocessErrorBody, []);
135+
const fakeResponse = createFakeResponseBody(422, fakeReprocessErrorBody, false);
136136
const fakeBugSplatApiClient = createFakeBugSplatApiClient(fakeFormData, fakeResponse);
137137
const client = new CrashApiClient(fakeBugSplatApiClient);
138138

src/events/events-api-client/events-api-client.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe('CrashApiClient', () => {
1515
let result;
1616

1717
beforeEach(() => {
18-
const fakeResponse = createFakeResponseBody(200, fakeEventsApiResponse, []);
18+
const fakeResponse = createFakeResponseBody(200, fakeEventsApiResponse);
1919
fakeEvents = createFakeEvents();
2020
fakeFormData = createFakeFormData();
2121
fakeBugSplatApiClient = createFakeBugSplatApiClient(fakeFormData, fakeResponse);

0 commit comments

Comments
 (0)