generated from ministryofjustice/hmpps-template-typescript
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Haar 1904 view base client page (#27)
* add tests for list base clients page * add view base client page * Fix errors in template
- Loading branch information
1 parent
5e5d216
commit 6d13bd5
Showing
14 changed files
with
830 additions
and
4 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import type { DeepMocked } from '@golevelup/ts-jest' | ||
import { createMock } from '@golevelup/ts-jest' | ||
import type { NextFunction, Request, Response } from 'express' | ||
|
||
import BaseClientController from './baseClientController' | ||
import { BaseClientService } from '../services' | ||
import { baseClientFactory, clientFactory } from '../testutils/factories' | ||
import listBaseClientsPresenter from '../views/presenters/listBaseClientsPresenter' | ||
import createUserToken from '../testutils/createUserToken' | ||
import viewBaseClientPresenter from '../views/presenters/viewBaseClientPresenter' | ||
import nunjucksUtils from '../views/helpers/nunjucksUtils' | ||
|
||
describe('BaseClientController', () => { | ||
const token = createUserToken(['ADMIN']) | ||
let request: DeepMocked<Request> | ||
let response: DeepMocked<Response> | ||
const next: DeepMocked<NextFunction> = createMock<NextFunction>({}) | ||
const baseClientService = createMock<BaseClientService>({}) | ||
let baseClientController: BaseClientController | ||
|
||
beforeEach(() => { | ||
request = createMock<Request>() | ||
response = createMock<Response>({ | ||
locals: { | ||
clientToken: 'CLIENT_TOKEN', | ||
user: { | ||
token, | ||
authSource: 'auth', | ||
}, | ||
}, | ||
render: jest.fn(), | ||
redirect: jest.fn(), | ||
}) | ||
|
||
baseClientController = new BaseClientController(baseClientService) | ||
}) | ||
|
||
describe('displayBaseClients', () => { | ||
it('renders the list index template with a list of base clients', async () => { | ||
// GIVEN a list of base clients | ||
const baseClients = baseClientFactory.buildList(3) | ||
baseClientService.listBaseClients.mockResolvedValue(baseClients) | ||
|
||
// WHEN the index page is requested | ||
await baseClientController.displayBaseClients()(request, response, next) | ||
|
||
// THEN the list of base clients is rendered | ||
const presenter = listBaseClientsPresenter(baseClients) | ||
expect(response.render).toHaveBeenCalledWith('pages/base-clients.njk', { | ||
presenter, | ||
}) | ||
|
||
// AND the list of base clients is retrieved from the base client service | ||
expect(baseClientService.listBaseClients).toHaveBeenCalledWith(token) | ||
}) | ||
}) | ||
|
||
describe('view base client', () => { | ||
it('renders the main view of a base clients', async () => { | ||
// GIVEN a list of base clients | ||
const baseClient = baseClientFactory.build() | ||
const clients = clientFactory.buildList(3) | ||
baseClientService.getBaseClient.mockResolvedValue(baseClient) | ||
baseClientService.listClientInstances.mockResolvedValue(clients) | ||
|
||
// WHEN the index page is requested | ||
request = createMock<Request>({ params: { baseClientId: baseClient.baseClientId } }) | ||
await baseClientController.displayBaseClient()(request, response, next) | ||
|
||
// THEN the view base client page is rendered | ||
const presenter = viewBaseClientPresenter(baseClient, clients) | ||
expect(response.render).toHaveBeenCalledWith('pages/base-client.njk', { | ||
baseClient, | ||
presenter, | ||
...nunjucksUtils, | ||
}) | ||
|
||
// AND the base client is retrieved from the base client service | ||
expect(baseClientService.getBaseClient).toHaveBeenCalledWith(token, baseClient.baseClientId) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import jwt from 'jsonwebtoken' | ||
|
||
export default function createUserToken(authorities: string[]) { | ||
const payload = { | ||
user_name: 'user1', | ||
scope: ['read', 'write'], | ||
auth_source: 'nomis', | ||
authorities, | ||
jti: 'a610a10-cca6-41db-985f-e87efb303aaf', | ||
client_id: 'clientid', | ||
} | ||
|
||
return jwt.sign(payload, 'secret', { expiresIn: '1h' }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import nunjucksUtils from './nunjucksUtils' | ||
|
||
describe('nunjucksUtils', () => { | ||
describe('capitalCase', () => { | ||
it.each([ | ||
[null, null, ''], | ||
['an empty string', '', ''], | ||
['lower case', 'robert', 'Robert'], | ||
['upper case', 'ROBERT', 'Robert'], | ||
['mixed case', 'RoBErT', 'Robert'], | ||
['multiple words', 'RobeRT SMiTH', 'Robert Smith'], | ||
['leading spaces', ' RobeRT', ' Robert'], | ||
['trailing spaces', 'RobeRT ', 'Robert '], | ||
])('handles %s: %s -> %s', (_inputType: string | null, input: string | null, expectedOutput: string) => { | ||
expect(nunjucksUtils.capitalCase(input)).toEqual(expectedOutput) | ||
}) | ||
}) | ||
|
||
describe('sentenceCase', () => { | ||
it.each([ | ||
['an empty string', '', ''], | ||
['a single lower case letter', 'a', 'A'], | ||
['a single upper case letter', 'A', 'A'], | ||
['a lower case word', 'rosa', 'Rosa'], | ||
['an upper case word', 'ROSA', 'Rosa'], | ||
['a proper case word', 'Rosa', 'Rosa'], | ||
['a mixed case word', 'RoSa', 'Rosa'], | ||
['multiple words', 'the fish swam', 'The fish swam'], | ||
])('handles %s: %s -> %s', (_inputType: string, input: string, expectedOutput: string) => { | ||
expect(nunjucksUtils.sentenceCase(input)).toEqual(expectedOutput) | ||
}) | ||
}) | ||
|
||
describe('capitalize', () => { | ||
it.each([ | ||
['an empty string', '', ''], | ||
['a single lower case letter', 'a', 'A'], | ||
['a single upper case letter', 'A', 'A'], | ||
['a lower case word', 'rosa', 'Rosa'], | ||
['an upper case word', 'ROSA', 'Rosa'], | ||
['a proper case word', 'Rosa', 'Rosa'], | ||
['a mixed case word', 'RoSa', 'Rosa'], | ||
])('handles %s: %s -> %s', (_inputType: string, input: string, expectedOutput: string) => { | ||
expect(nunjucksUtils.capitalize(input)).toEqual(expectedOutput) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const isBlank = (str: string): boolean => { | ||
return !str || /^\s*$/.test(str) | ||
} | ||
|
||
const capitalCase = (sentence: string | null): string => { | ||
return sentence === null || isBlank(sentence) ? '' : sentence.split(' ').map(capitalize).join(' ') | ||
} | ||
|
||
const sentenceCase = (sentence: string | null): string => { | ||
if (sentence === null || isBlank(sentence)) { | ||
return '' | ||
} | ||
|
||
const words = sentence.split(' ') | ||
if (words.length === 1) { | ||
return capitalize(words[0]) | ||
} | ||
return `${capitalize(words[0])} ${words.slice(1).join(' ')}` | ||
} | ||
|
||
const capitalize = (word: string): string => { | ||
return word.length >= 1 ? word[0].toUpperCase() + word.toLowerCase().slice(1) : word | ||
} | ||
|
||
const toLinesHtml = (str?: string[]): string | null => { | ||
return str.join('<br>') | ||
} | ||
|
||
const toLines = (str?: string[]): string | null => { | ||
return str.join('/n') | ||
} | ||
|
||
export default { | ||
toLinesHtml, | ||
toLines, | ||
sentenceCase, | ||
capitalize, | ||
capitalCase, | ||
} |
Oops, something went wrong.