Skip to content

Commit

Permalink
hardened normalizeAdvert()
Browse files Browse the repository at this point in the history
  • Loading branch information
jlarsson committed Mar 5, 2024
1 parent 86d466a commit d4c4e23
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
39 changes: 23 additions & 16 deletions src/adverts/mappers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ import { getAdvertMeta } from './advert-meta'
const isObject = (o: any) => o === Object(o)
const isArray = (a: any) => Array.isArray(a)

const omitNullProperties = <T>(o?: Partial<T>): Partial<T> | undefined =>
(o
? Object.fromEntries(
Object.entries(o).filter(
([_, v]) => v !== null && typeof v !== 'undefined'
)
)
: o) as Partial<T>

export const normalizeAdvert = (
{
id,
Expand Down Expand Up @@ -90,8 +99,10 @@ export const normalizeAdvert = (
export const normalizeAdvertImage = ({ url }: AdvertImage): AdvertImage => ({
url,
})

export const normalizeAdvertTags = (tags: string[] = []): string[] =>
tags.map(s => s?.trim()).filter(s => s)

export const normalizeAdvertLocation = (
{
name,
Expand Down Expand Up @@ -149,7 +160,7 @@ export const createEmptyAdvert = (defaults?: Partial<Advert>): Advert => ({

location: createEmptyAdvertLocation(),
contact: createEmptyAdvertContact(),
...defaults,
...omitNullProperties(defaults),
})

export const createEmptyAdvertLocation = (
Expand All @@ -160,7 +171,7 @@ export const createEmptyAdvertLocation = (
zipCode: '',
city: '',
country: '',
...defaults,
...omitNullProperties(defaults),
})

export const createEmptyAdvertContact = (
Expand All @@ -169,7 +180,7 @@ export const createEmptyAdvertContact = (
email: '',
phone: '',
organization: '',
...defaults,
...omitNullProperties(defaults),
})

export const createEmptyAdvertInput = (): AdvertInput => ({
Expand Down Expand Up @@ -202,20 +213,21 @@ export const mapCreateAdvertInputToAdvert = (
user: HaffaUser,
when: string = new Date().toISOString()
): Advert => ({
...createEmptyAdvert(),
id: uuid.v4().toString(),
createdBy: user.id,
createdAt: when,
modifiedAt: when,
...input,
...createEmptyAdvert({
id: uuid.v4().toString(),
createdBy: user.id,
createdAt: when,
modifiedAt: when,
...omitNullProperties(input),
}),
})

export const patchAdvertWithAdvertInput = (
advert: Advert,
input: AdvertInput
): Advert => ({
...advert,
...input,
...omitNullProperties(input),
modifiedAt: new Date().toISOString(),
})

Expand All @@ -225,12 +237,7 @@ export const mapAdvertToAdvertWithMeta = (
): AdvertWithMeta | null =>
advert
? {
...createEmptyAdvert(),
...advert,
location: {
...createEmptyAdvertLocation(),
...advert.location,
},
...normalizeAdvert(advert),
...{
get meta() {
return getAdvertMeta(advert, user)
Expand Down
37 changes: 37 additions & 0 deletions src/adverts/repository/validation/validate-advert.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { validateAdvert } from '.'
import { createEmptyAdvert, createEmptyAdvertContact } from '../../mappers'

describe('validate-advert', () => {
it('throws on validation error', () => {
const badAdverts: any[] = [
null,
{},
{ id: 'x', title: ['title should be a string'] },
]

badAdverts.forEach(bad =>
expect(() => validateAdvert(bad)).toThrow('Validation error')
)
})

it('normalizes away unknown properties', () => {
const ad = createEmptyAdvert({
title: 'a title',
description: 'a description',
contact: createEmptyAdvertContact({
email: 'test@user.com',
}),
})
const adWithExtra = {
...ad,
extra: [1, 2, 3],
contact: { ...ad.contact, extra: ['extra', 'stuff'] },
}

const n = validateAdvert(adWithExtra) as any

expect(n).toMatchObject(ad)
expect(n.extra).toBeUndefined()
expect(n.contact.extra).toBeUndefined()
})
})
1 change: 1 addition & 0 deletions src/snapshot/snapshot-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const snapshotModule =
if (!handler) {
return ctx.throw(HttpStatusCodes.BAD_REQUEST)
}

await handler(user, services, data[collection])
ctx.body = { success: true }
return undefined
Expand Down

0 comments on commit d4c4e23

Please sign in to comment.