Skip to content

Commit 39f7b02

Browse files
committed
Test formGet
1 parent 82eec3d commit 39f7b02

File tree

5 files changed

+72
-5
lines changed

5 files changed

+72
-5
lines changed

src/authentication/login/get-user-from-session.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const SessionCodec = t.strict({
1313
});
1414

1515
export const getUserFromSession =
16-
(deps: Dependencies) =>
16+
(deps: Pick<Dependencies, 'logger'>) =>
1717
(session: unknown): O.Option<User> =>
1818
pipe(
1919
session,

src/http/form-get.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {pipe} from 'fp-ts/lib/function';
55
import {getUserFromSession} from '../authentication';
66
import {Dependencies} from '../dependencies';
77
import {oopsPage, pageTemplate} from '../templates';
8-
import {Form} from '../types/form';
8+
import {Form, FormDependencies} from '../types/form';
99
import {CompleteHtmlDocument, sanitizeString} from '../types/html';
1010
import {logInPath} from '../authentication/login/routes';
1111

@@ -14,7 +14,7 @@ import {logInPath} from '../authentication/login/routes';
1414
// get a view of the current state of a resource. This should be completely pure because its read-only and
1515
// is where conflict resolution etc. is handled as described in form-post.
1616
export const formGet =
17-
<T>(deps: Dependencies, form: Form<T>) =>
17+
<T>(deps: FormDependencies, form: Form<T>) =>
1818
async (req: Request, res: Response<CompleteHtmlDocument>) => {
1919
const user = getUserFromSession(deps)(req.session);
2020
if (O.isNone(user)) {

src/types/form.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {SharedReadModel} from '../read-models/shared-state';
66
import {Member} from './tagged-union';
77
import { Dependencies } from '../dependencies';
88

9-
export type FormDependencies = Pick<Dependencies, 'getEventById'>;
9+
export type FormDependencies = Pick<Dependencies, 'getEventById' | 'sharedReadModel' | 'logger'>;
1010

1111
export type Form<T> = {
1212
renderForm: (viewModel: T) => Member<HttpResponse, 'LoggedInContent'>;

tests/http/form-get.test.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {Request, Response} from 'express';
2+
import {faker} from '@faker-js/faker';
3+
import * as TE from 'fp-ts/TaskEither';
4+
import {Dependencies} from '../../src/dependencies';
5+
import {formGet} from '../../src/http/form-get';
6+
import {
7+
html,
8+
CompleteHtmlDocument,
9+
safe,
10+
sanitizeString,
11+
toLoggedInContent,
12+
} from '../../src/types/html';
13+
import {Form} from '../../src/types/form';
14+
import {initTestFramework, TestFramework} from '../read-models/test-framework';
15+
import { arbitraryUser } from '../types/user.helper';
16+
17+
describe('formGet', () => {
18+
const user = arbitraryUser();
19+
let framework: TestFramework;
20+
21+
beforeEach(async () => {
22+
framework = await initTestFramework();
23+
await framework.commands.memberNumbers.linkNumberToEmail({
24+
email: user.emailAddress,
25+
memberNumber: user.memberNumber,
26+
name: undefined,
27+
formOfAddress: undefined,
28+
});
29+
});
30+
31+
afterEach(() => {
32+
framework.close();
33+
});
34+
35+
it('responds with a rendered page when the form loads successfully', async () => {
36+
const form: Form<{message: string}> = {
37+
constructForm: input => _context => TE.right({message: (input as any).id}),
38+
renderForm: ({message}) => toLoggedInContent(html`Test form`)(html`<p>${sanitizeString(message)}</p>`),
39+
};
40+
const req = {
41+
session: {passport: {user}},
42+
query: {},
43+
params: {id: 'hello'},
44+
} as unknown as Request;
45+
const res = {
46+
status: jest.fn(),
47+
send: jest.fn(),
48+
redirect: jest.fn(),
49+
};
50+
res.status.mockReturnValue(res);
51+
res.send.mockReturnValue(res);
52+
53+
await formGet(framework, form)(
54+
req,
55+
res as unknown as Response<CompleteHtmlDocument>
56+
);
57+
58+
expect(res.redirect).not.toHaveBeenCalled();
59+
expect(res.status).toHaveBeenCalledWith(200);
60+
expect(res.send).toHaveBeenCalledWith(expect.stringContaining('hello'));
61+
});
62+
});

tests/read-models/test-framework.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import createLogger from 'pino';
1+
import createLogger, { Logger } from 'pino';
22
import * as T from 'fp-ts/Task';
33
import * as O from 'fp-ts/Option';
44
import * as TE from 'fp-ts/TaskEither';
55
import {
66
getAllEvents,
77
getAllEventsByType,
8+
getEventById,
89
} from '../../src/init-dependencies/event-store/get-all-events';
910
import {ensureEventTableExists} from '../../src/init-dependencies/event-store/ensure-events-table-exists';
1011
import {Actor, DomainEvent, StoredDomainEvent, StoredEventOfType} from '../../src/types';
@@ -47,6 +48,8 @@ type ToFrameworkCommands<T> = {
4748
};
4849

4950
export type TestFramework = {
51+
logger: Logger;
52+
getEventById: Dependencies['getEventById'];
5053
getAllEvents: () => Promise<ReadonlyArray<StoredDomainEvent>>;
5154
getAllEventsByType: <T extends EventName>(
5255
eventType: T
@@ -107,6 +110,8 @@ export const initTestFramework = async (): Promise<TestFramework> => {
107110
};
108111

109112
return {
113+
logger,
114+
getEventById: getEventById(eventDB),
110115
getAllEvents: frameworkGetAllEvents,
111116
getAllEventsByType: frameworkGetAllEventsByType,
112117
getTroubleTicketData: getTroubleTicketData(

0 commit comments

Comments
 (0)