Skip to content

Commit

Permalink
categories snapshot support
Browse files Browse the repository at this point in the history
  • Loading branch information
jlarsson committed May 31, 2024
1 parent 81f4ade commit 996ee84
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { PassThrough } from 'stream'
import type { Advert } from '../adverts/types'
import type { FilesService } from '../files/types'
import { convertObjectStream, jsonStream } from '../lib/streams'
import type { ImportSnapshotFunction, SnapshotFunction } from './types'
import { createAdvertMutations } from '../adverts/advert-mutations'
import { waitForAll } from '../lib'
import { validateAdvert } from '../adverts/repository/validation'
import type { Advert } from '../../adverts/types'
import type { FilesService } from '../../files/types'
import { convertObjectStream, jsonStream } from '../../lib/streams'
import type { ImportSnapshotFunction, SnapshotFunction } from '../types'
import { createAdvertMutations } from '../../adverts/advert-mutations'
import { waitForAll } from '../../lib'
import { validateAdvert } from '../../adverts/repository/validation'

const createConvertAdvertToAdvertWithInlinedImages =
(files: FilesService) => (advert: Advert) =>
Expand Down
33 changes: 33 additions & 0 deletions src/snapshot/categories/categories-snapshot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { PassThrough } from 'stream'
import type { ImportSnapshotFunction, SnapshotFunction } from '../types'
import { jsonStream, objectStream } from '../../lib/streams'
import type { Category } from '../../categories/types'
import { patchCategories } from './patch-categories'

export const categoriesSnapshot: SnapshotFunction = (ctx, { categories }) => {
const stream = new PassThrough()
ctx.type = 'application/json'
ctx.body = stream

objectStream<Category, Category>(
() => categories.getCategories(),
async c => c
)
.pipe(
jsonStream({
prefix: '{"snapshot": "categories", "categories": [',
separator: ',',
terminator: ']}',
})
)
.pipe(stream)
}

export const importCategoriesSnapshot: ImportSnapshotFunction = async (
user,
{ categories },
data
) => {
const patched = patchCategories(await categories.getCategories(), data)
return categories.updateCategories(patched)
}
40 changes: 40 additions & 0 deletions src/snapshot/categories/patch-categories.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { Category } from '../../categories/types'
import { patchCategories } from './patch-categories'

const cat = (c: Partial<Category>): Category => ({
id: '',
parentId: '',
label: '',
co2kg: 0,
valueByUnit: 0,
...c,
})
describe('patchCategories', () => {
it('does not update existing', () => {
const initial = [cat({ id: 'c1', label: 'C1' })]
const patch = [cat({ id: 'c1', label: 'modified C1' })]

expect(patchCategories(initial, patch)).toMatchObject(initial)
})

it('ignores unlabelled', () => {
const initial = [cat({ id: 'c1', label: 'C1' })]
const patch = [cat({ id: 'c1', label: '' }), cat({ id: 'c2' })]

expect(patchCategories(initial, patch)).toMatchObject(initial)
})

it('fixes bad parents', () => {
const initial = [cat({ id: 'c1', label: 'C1' })]
const patch = [
cat({ id: 'c2', label: 'C2', parentId: 'missing' }),
cat({ id: 'c3', parentId: 'c2', label: 'C3' }),
]

expect(patchCategories(initial, patch)).toMatchObject([
cat({ id: 'c1', label: 'C1' }),
cat({ id: 'c2', label: 'C2', parentId: '' }),
cat({ id: 'c3', parentId: 'c2', label: 'C3' }),
])
})
})
21 changes: 21 additions & 0 deletions src/snapshot/categories/patch-categories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { normalizeCategories } from '../../categories/category-adapter'
import type { Category } from '../../categories/types'
import { uniqueBy } from '../../lib'

export const patchCategories = (
existing: Category[],
patch: Category[]
): Category[] =>
fixParentLinks(
[...normalizeCategories(existing), ...normalizeCategories(patch)]
.filter(uniqueBy(({ id }) => id))
.filter(({ label }) => label)
)

const fixParentLinks = (cats: Category[]): Category[] => {
const ids = new Set<String>(cats.map(({ id }) => id))
return cats.map(c => ({
...c,
parentId: ids.has(c.parentId) ? c.parentId : '',
}))
}
11 changes: 10 additions & 1 deletion src/snapshot/snapshot-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@ import { type ApplicationModule } from '@helsingborg-stad/gdi-api-node'
import type { Services } from '../types'
import { normalizeRoles } from '../login'
import type { ImportSnapshotFunction, SnapshotFunction } from './types'
import { advertsSnapshot, importAdvertsSnapshot } from './adverts-snapshot'
import {
advertsSnapshot,
importAdvertsSnapshot,
} from './adverts/adverts-snapshot'
import { requireHaffaUser } from '../login/require-haffa-user'
import {
categoriesSnapshot,
importCategoriesSnapshot,
} from './categories/categories-snapshot'

const snapshotHandlers: Record<string, SnapshotFunction> = {
adverts: advertsSnapshot,
categories: categoriesSnapshot,
}

const importSnapshotHandlers: Record<string, ImportSnapshotFunction> = {
adverts: importAdvertsSnapshot,
categories: importCategoriesSnapshot,
}

export const snapshotModule =
Expand Down

0 comments on commit 996ee84

Please sign in to comment.