From 380732d28a23f56f5f25028aac6b641916e24cd9 Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Sun, 20 Jan 2019 22:12:51 +0100 Subject: [PATCH] Add test for login failure --- packages/client/src/http/IResponse.ts | 1 + .../{index.test.tsx => LoginForm.test.tsx} | 18 ++++++-- .../src/test-utils/HTTPClientMock.test.ts | 12 ++++++ .../client/src/test-utils/HTTPClientMock.ts | 42 ++++++++++++------- 4 files changed, 56 insertions(+), 17 deletions(-) rename packages/client/src/login/{index.test.tsx => LoginForm.test.tsx} (74%) diff --git a/packages/client/src/http/IResponse.ts b/packages/client/src/http/IResponse.ts index 41964ab..f45b6dd 100644 --- a/packages/client/src/http/IResponse.ts +++ b/packages/client/src/http/IResponse.ts @@ -1,3 +1,4 @@ export interface IResponse { data: any + status: number } diff --git a/packages/client/src/login/index.test.tsx b/packages/client/src/login/LoginForm.test.tsx similarity index 74% rename from packages/client/src/login/index.test.tsx rename to packages/client/src/login/LoginForm.test.tsx index 0e4d12c..0512578 100644 --- a/packages/client/src/login/index.test.tsx +++ b/packages/client/src/login/LoginForm.test.tsx @@ -1,11 +1,11 @@ import * as Feature from './' -import {HTTPClientMock, TestUtils} from '../test-utils' +import {HTTPClientMock, TestUtils, getError} from '../test-utils' import {IAPIDef} from '@rondo/common' import T from 'react-dom/test-utils' const test = new TestUtils() -describe('Login', () => { +describe('LoginForm', () => { const http = new HTTPClientMock() const loginActions = new Feature.LoginActions(http) @@ -31,7 +31,7 @@ describe('Login', () => { method: 'post', url: '/auth/login', data, - }, { id: 123 }) + }, {id: 123}) node = t.render({onSuccess}).node T.Simulate.change( @@ -55,6 +55,18 @@ describe('Login', () => { expect(onSuccess.mock.calls.length).toBe(1) }) + it('sets the error message on failure', async () => { + http.mockAdd({ + method: 'post', + url: '/auth/login', + data, + }, {error: 'test'}, 500) + T.Simulate.submit(node) + await getError(http.wait()) + expect(node.querySelector('.error')!.textContent) + .toMatch(/HTTP Status: 500/i) + }) + }) }) diff --git a/packages/client/src/test-utils/HTTPClientMock.test.ts b/packages/client/src/test-utils/HTTPClientMock.test.ts index d901d8f..033d956 100644 --- a/packages/client/src/test-utils/HTTPClientMock.test.ts +++ b/packages/client/src/test-utils/HTTPClientMock.test.ts @@ -24,6 +24,18 @@ describe('HTTPClientMock', () => { const error = await getError(http.get('/test')) expect(error.message).toMatch(/mock/i) }) + + it('can add a mock for custom status code', async () => { + http.mockClear().mockAdd( + {method: 'get', url: '/test'}, + {error: 'Internal'}, 500) + + const waitPromise = http.wait() + const error = await getError(http.get('/test')) + const error2 = await getError(waitPromise) + expect(error.message).toEqual('HTTP Status: 500') + expect(error2).toBe(error) + }) }) describe('await wait', () => { diff --git a/packages/client/src/test-utils/HTTPClientMock.ts b/packages/client/src/test-utils/HTTPClientMock.ts index f114375..4ed1276 100644 --- a/packages/client/src/test-utils/HTTPClientMock.ts +++ b/packages/client/src/test-utils/HTTPClientMock.ts @@ -8,10 +8,22 @@ interface IReqRes { res: IResponse } +export class HTTPClientError extends Error { + constructor(readonly request: IRequest, readonly response: IResponse) { + super('HTTP Status: ' + response.status) + Error.captureStackTrace(this) + } +} + export class HTTPClientMock extends HTTPClient { - mocks: {[key: string]: any} = {} + mocks: {[key: string]: IResponse} = {} requests: IRequest[] = [] + protected waitPromise?: { + resolve: (r: IReqRes) => void + reject: (err: Error) => void + } + constructor() { super() } @@ -30,33 +42,35 @@ export class HTTPClientMock extends HTTPClient { }) return } - const data = this.mocks[key] - const res: IResponse = {data} + const res = this.mocks[key] setImmediate(() => { - resolve(res) - this.notify({req, res}) + if (res.status >= 200 && res.status < 400) { + resolve(res) + this.notify({req, res}) + return + } + const error = new HTTPClientError(req, res) + reject(error) + this.notify(error) }) }) }, } } - serialize(req: IRequest) { + protected serialize(req: IRequest) { return JSON.stringify(req, null, ' ') } - mockAdd(req: IRequest, res: any) { - this.mocks[this.serialize(req)] = res + mockAdd(req: IRequest, data: any, status = 200): this { + this.mocks[this.serialize(req)] = {data, status} + return this } - mockClear() { + mockClear(): this { this.requests = [] this.mocks = {} - } - - protected waitPromise?: { - resolve: (r: IReqRes) => void - reject: (err: Error) => void + return this } protected notify(r: IReqRes | Error) {