Skip to content

Commit

Permalink
Implemet serialization, repo & service, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
khoidt committed Dec 17, 2024
1 parent 5c46641 commit 6fb7ab1
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/dossiers/application/DossiersService.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { testDelegation, TestData } from 'test-support/utils'
import DossiersRepository from 'dossiers/infrastructure/DossiersRepository'
import DossierRecord from 'dossiers/domain/DossierRecord'
import DossiersService from 'dossiers/application/DossiersService'
import { stringify } from 'query-string'
import { ReferenceType } from 'bibliography/domain/Reference'
import { Provenances } from 'corpus/domain/provenance'
import { PeriodModifiers, Periods } from 'common/period'

jest.mock('dossiers/infrastructure/DossiersRepository')
const dossiersRepository = new (DossiersRepository as jest.Mock)()

const dossiersService = new DossiersService(dossiersRepository)

const resultStub = {
id: 'test',
description: 'some desciption',
isApproximateDate: true,
yearRangeFrom: -500,
yearRangeTo: -470,
relatedKings: [10.2, 11],
provenance: Provenances.Assyria,
script: {
period: Periods['Neo-Assyrian'],
periodModifier: PeriodModifiers.None,
uncertain: false,
},
references: ['EDITION' as ReferenceType, 'DISCUSSION' as ReferenceType],
}

const query = { ids: ['test'] }
const entry = new DossierRecord(resultStub)

const testData: TestData<DossiersService>[] = [
new TestData(
'searchByIds',
[stringify(query)],
dossiersRepository.searchByIds,
[entry],
[stringify(query)],
Promise.resolve([entry])
),
]

describe('DossiersService', () => {
testDelegation(dossiersService, testData)
})
18 changes: 18 additions & 0 deletions src/dossiers/application/DossiersService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import DossiersRepository from 'dossiers/infrastructure/DossiersRepository'
import DossierRecord from 'dossiers/domain/DossierRecord'

export interface DossiersSearch {
searchByIds(query: string): Promise<readonly DossierRecord[]>
}

export default class DossiersService implements DossiersSearch {
private readonly dossiersRepository: DossiersRepository

constructor(afoRegisterRepository: DossiersRepository) {
this.dossiersRepository = afoRegisterRepository
}

searchByIds(query: string): Promise<readonly DossierRecord[]> {
return this.dossiersRepository.searchByIds(query)
}
}
41 changes: 41 additions & 0 deletions src/dossiers/domain/DossierRecord.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import DossierRecord from 'dossiers/domain/DossierRecord'
import { ReferenceType } from 'bibliography/domain/Reference'
import { PeriodModifiers, Periods } from 'common/period'
import { Provenances } from 'corpus/domain/provenance'

describe('DossierRecord', () => {
const mockRecord = {
id: 'test',
description: 'some desciption',
isApproximateDate: true,
yearRangeFrom: -500,
yearRangeTo: -470,
relatedKings: [10.2, 11],
provenance: Provenances.Assyria,
script: {
period: Periods['Neo-Assyrian'],
periodModifier: PeriodModifiers.None,
uncertain: false,
},
references: ['EDITION' as ReferenceType, 'DISCUSSION' as ReferenceType],
}

describe('constructor', () => {
it('should initialize properties correctly', () => {
const record = new DossierRecord(mockRecord)
expect(record.id).toEqual('test')
expect(record.description).toEqual('some desciption')
expect(record.isApproximateDate).toEqual(true)
expect(record.yearRangeFrom).toEqual(-500)
expect(record.yearRangeTo).toEqual(-470)
expect(record.relatedKings).toEqual([10.2, 11])
expect(record.provenance).toEqual(Provenances.Assyria)
expect(record.script).toEqual({
period: Periods['Neo-Assyrian'],
periodModifier: PeriodModifiers.None,
uncertain: false,
})
expect(record.references).toEqual(['EDITION', 'DISCUSSION'])
})
})
})
52 changes: 52 additions & 0 deletions src/dossiers/domain/DossierRecord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { immerable } from 'immer'
import { ReferenceType } from 'bibliography/domain/Reference'
import { Provenance } from 'corpus/domain/provenance'
import { Script } from 'fragmentarium/domain/fragment'

interface DossierRecordData {
readonly id: string
readonly description?: string
readonly isApproximateDate?: boolean
readonly yearRangeFrom?: number
readonly yearRangeTo?: number
readonly relatedKings?: number[]
readonly provenance?: Provenance
readonly script?: Script
readonly references?: ReferenceType[]
}

export default class DossierRecord {
[immerable] = true

readonly id: string
readonly description?: string
readonly isApproximateDate: boolean
readonly yearRangeFrom?: number
readonly yearRangeTo?: number
readonly relatedKings: number[]
readonly provenance?: Provenance
readonly script?: Script
readonly references: ReferenceType[]

constructor({
id,
description,
isApproximateDate = false,
yearRangeFrom,
yearRangeTo,
relatedKings = [],
provenance,
script,
references = [],
}: DossierRecordData) {
this.id = id
this.description = description
this.isApproximateDate = isApproximateDate
this.yearRangeFrom = yearRangeFrom
this.yearRangeTo = yearRangeTo
this.relatedKings = relatedKings
this.provenance = provenance
this.script = script
this.references = references
}
}
84 changes: 84 additions & 0 deletions src/dossiers/infrastructure/DossiersRepository.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { testDelegation, TestData } from 'test-support/utils'
import DossiersRepository from 'dossiers/infrastructure/DossiersRepository'
import DossierRecord from 'dossiers/domain/DossierRecord'
import { stringify } from 'query-string'
import ApiClient from 'http/ApiClient'
import { PeriodModifiers, Periods } from 'common/period'
import { ReferenceType } from 'bibliography/domain/Reference'
import { Provenances } from 'corpus/domain/provenance'

jest.mock('http/ApiClient')
jest.mock('dossiers/application/DossiersService')

const apiClient = new (ApiClient as jest.Mock<jest.Mocked<ApiClient>>)()
const dossiersRepository = new DossiersRepository(apiClient)

const resultStub = {
id: 'test',
description: 'some description',
isApproximateDate: true,
yearRangeFrom: -500,
yearRangeTo: -470,
relatedKings: [10.2, 11],
provenance: Provenances.Assyria,
script: {
period: Periods['Neo-Assyrian'],
periodModifier: PeriodModifiers.None,
uncertain: false,
},
references: ['EDITION' as ReferenceType, 'DISCUSSION' as ReferenceType],
}

const query = { ids: ['test'] }
const record = new DossierRecord(resultStub)

const testData: TestData<DossiersRepository>[] = [
new TestData(
'searchByIds',
[stringify(query)],
apiClient.fetchJson,
[record],
[`/dossiers?${stringify(query)}`, false],
Promise.resolve([resultStub])
),
]

describe('dossiersService', () => testDelegation(dossiersRepository, testData))

describe('DossiersRepository - search by ids', () => {
it('handles search without errors', async () => {
apiClient.fetchJson.mockResolvedValueOnce([resultStub])
const response = await dossiersRepository.searchByIds(stringify(query))
expect(response).toEqual([record])
expect(apiClient.fetchJson).toHaveBeenCalledWith(
`/dossiers?${stringify(query)}`,
false
)
})

it('handles different query strings', async () => {
const query2 = { id: 'test2' }
const resultStub2 = {
...resultStub,
id: 'test2',
description: 'another description',
}
const record2 = new DossierRecord(resultStub2)
apiClient.fetchJson.mockResolvedValueOnce([resultStub, resultStub2])
const response = await dossiersRepository.searchByIds(stringify(query2))
expect(response).toEqual([record, record2])
})

it('handles empty response', async () => {
apiClient.fetchJson.mockResolvedValueOnce([])
const response = await dossiersRepository.searchByIds(stringify(query))
expect(response).toEqual([])
})

it('handles API errors', async () => {
apiClient.fetchJson.mockRejectedValueOnce(new Error('API Error'))
await expect(
dossiersRepository.searchByIds(stringify(query))
).rejects.toThrow('API Error')
})
})
17 changes: 17 additions & 0 deletions src/dossiers/infrastructure/DossiersRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import DossierRecord from 'dossiers/domain/DossierRecord'
import Promise from 'bluebird'
import ApiClient from 'http/ApiClient'

export default class DossiersRepository {
private readonly apiClient: ApiClient

constructor(apiClient: ApiClient) {
this.apiClient = apiClient
}

searchByIds(query: string): Promise<DossierRecord[]> {
return this.apiClient
.fetchJson(`/dossiers?${query}`, false)
.then((result) => result.map((data) => new DossierRecord(data)))
}
}
Empty file.
Empty file.

0 comments on commit 6fb7ab1

Please sign in to comment.