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.
PI-1504 Store search parameters in user session
- Loading branch information
1 parent
e1e16b0
commit 3aec169
Showing
24 changed files
with
453 additions
and
146 deletions.
There are no files selected for viewing
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
50 changes: 50 additions & 0 deletions
50
packages/probation-search-frontend/data/searchParameters.test.ts
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,50 @@ | ||
import { Request } from 'express' | ||
import SearchParameters, { ProbationSearchSession } from './searchParameters' | ||
|
||
describe('SearchParameters', () => { | ||
let req: Request | ||
let session: ProbationSearchSession | ||
|
||
beforeEach(() => { | ||
session = {} | ||
req = { | ||
protocol: 'https', | ||
get: () => 'localhost', | ||
originalUrl: '/path', | ||
session, | ||
} as unknown as Request | ||
}) | ||
|
||
it('should load parameters from the session', () => { | ||
session.probationSearch = { | ||
q: 'value1', | ||
providers: ['value2', 'value3'], | ||
} | ||
const params = SearchParameters.loadFromSession(req) | ||
expect(params).toBe('https://localhost/path?q=value1&providers=value2&providers=value3') | ||
}) | ||
|
||
it('should save parameters to the session', () => { | ||
req.query = { | ||
q: 'value1', | ||
providers: ['value2', 'value3'], | ||
} | ||
SearchParameters.saveToSession(req) | ||
expect(session.probationSearch).toEqual({ | ||
q: 'value1', | ||
providers: ['value2', 'value3'], | ||
}) | ||
}) | ||
|
||
it('should check if parameters are in the session', () => { | ||
expect(SearchParameters.inSession(req)).toBe(false) | ||
|
||
req.query = { | ||
param1: 'value1', | ||
param2: ['value2', 'value3'], | ||
} | ||
SearchParameters.saveToSession(req) | ||
|
||
expect(SearchParameters.inSession(req)).toBe(true) | ||
}) | ||
}) |
36 changes: 36 additions & 0 deletions
36
packages/probation-search-frontend/data/searchParameters.ts
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,36 @@ | ||
import { Request } from 'express' | ||
import { addParameters } from '../utils/url' | ||
|
||
export default class SearchParameters { | ||
private static getSession(req: Request): ProbationSearchSession { | ||
return req.session as unknown | ||
} | ||
|
||
static loadFromSession(req: Request): string { | ||
return addParameters(req, SearchParameters.getSession(req).probationSearch) | ||
} | ||
|
||
static saveToSession(req: Request) { | ||
SearchParameters.getSession(req).probationSearch = { | ||
q: req.query.q as string, | ||
matchAllTerms: req.query.matchAllTerms as string, | ||
providers: req.query.providers as string[], | ||
page: req.query.page as string, | ||
} | ||
} | ||
|
||
static inSession(req: Request): boolean { | ||
return 'probationSearch' in req.session | ||
} | ||
} | ||
|
||
export interface ProbationSearchSession { | ||
probationSearch?: ProbationSearchParameters | ||
} | ||
|
||
export interface ProbationSearchParameters extends Record<string, string | string[]> { | ||
q?: string | ||
page?: string | ||
matchAllTerms?: string | ||
providers?: string[] | ||
} |
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 |
---|---|---|
@@ -1,13 +1,43 @@ | ||
import addParameters from './url' | ||
import { Request } from 'express' | ||
import { addParameters, getAbsoluteUrl, removeParameters } from './url' | ||
|
||
describe('getAbsoluteUrl', () => { | ||
test.each([ | ||
['http', 'example.com', '/path', 'http://example.com/path'], | ||
['https', 'example.com', '/path', 'https://example.com/path'], | ||
['http', 'localhost:3000', '/path?param=value', 'http://localhost:3000/path?param=value'], | ||
])('returns the correct absolute URL for %s://%s%s', (protocol, host, originalUrl, expected) => { | ||
const req = { protocol, originalUrl, get: () => host } as unknown as Request | ||
expect(getAbsoluteUrl(req)).toBe(expected) | ||
}) | ||
}) | ||
|
||
describe('addParameters', () => { | ||
it.each([ | ||
['https://example.com', { p1: 'value1' }, 'https://example.com/?p1=value1'], | ||
['https://example.com/path', { p1: 'value1' }, 'https://example.com/path?p1=value1'], | ||
['https://example.com?p1=value1', { p1: 'newValue', p2: 'value2' }, 'https://example.com/?p1=newValue&p2=value2'], | ||
['/path?p1=value1', { p1: 'newValue', p2: 'value2' }, '/path?p1=newValue&p2=value2'], | ||
['https://example.com?p1=value1', { p1: ['1', '2', '3'] }, 'https://example.com/?p1=1&p1=2&p1=3'], | ||
['https://example.com/path?p1=value1', undefined, 'https://example.com/path?p1=value1'], | ||
])('should add parameters to the URL', (url, params, expected) => { | ||
const result = addParameters(url, params) | ||
expect(result).toBe(expected) | ||
}) | ||
}) | ||
|
||
describe('removeParameters', () => { | ||
it.each([ | ||
[ | ||
'https://example.com/?param1=value1¶m2=value2¶m3=value3', | ||
['param1', 'param3'], | ||
'https://example.com/?param2=value2', | ||
], | ||
['https://example.com/?param1=value1', [], 'https://example.com/?param1=value1'], | ||
['https://example.com/?param1=value1', ['param2'], 'https://example.com/?param1=value1'], | ||
['https://example.com/path', ['param1'], 'https://example.com/path'], | ||
['https://example.com/path?param1=value', [undefined], 'https://example.com/path?param1=value'], | ||
])('should remove specified parameters from the URL (%s)', (url, paramsToRemove: string[], expected) => { | ||
const result = removeParameters(url, ...paramsToRemove) | ||
expect(result).toBe(expected) | ||
}) | ||
}) |
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 |
---|---|---|
@@ -1,9 +1,25 @@ | ||
import { parse, format } from 'url' | ||
import { Request } from 'express' | ||
|
||
export default function addParameters(url: string, params: { [key: string]: string }): string { | ||
const parsedUrl = parse(url) | ||
const urlSearchParams = new URLSearchParams(parsedUrl.search) | ||
Object.entries(params).forEach(([key, value]) => urlSearchParams.set(key, value)) | ||
parsedUrl.search = urlSearchParams.toString() | ||
return format(parsedUrl) | ||
export function getAbsoluteUrl(req: Request): string { | ||
return `${req.protocol}://${req.get('host')}${req.originalUrl}` | ||
} | ||
|
||
export function addParameters(url: string | Request, params?: Record<string, string | string[]>): string { | ||
const newUrl = new URL(typeof url === 'string' ? url : getAbsoluteUrl(url)) | ||
if (params) | ||
Object.entries(params).forEach(([key, value]) => { | ||
newUrl.searchParams.delete(key) | ||
if (Array.isArray(value)) { | ||
value.forEach(v => newUrl.searchParams.append(key, v.toString())) | ||
} else { | ||
newUrl.searchParams.set(key, value.toString()) | ||
} | ||
}) | ||
return newUrl.toString() | ||
} | ||
|
||
export function removeParameters(url: string | Request, ...params: string[]): string { | ||
const newUrl = new URL(typeof url === 'string' ? url : getAbsoluteUrl(url)) | ||
params.forEach(key => newUrl.searchParams.delete(key)) | ||
return newUrl.toString() | ||
} |
Oops, something went wrong.