97 lines
3.0 KiB
TypeScript
97 lines
3.0 KiB
TypeScript
import { mkdtemp, rm } from 'node:fs/promises'
|
|
import { join } from 'node:path'
|
|
import { tmpdir } from 'node:os'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { openDatabase, type AppDatabase } from '../src/server/database.js'
|
|
import {
|
|
FeedbackRepository,
|
|
ProductNotFoundError
|
|
} from '../src/server/feedback-repository.js'
|
|
|
|
const directories: string[] = []
|
|
const databases: AppDatabase[] = []
|
|
|
|
afterEach(async () => {
|
|
while (databases.length > 0) {
|
|
databases.pop()?.close()
|
|
}
|
|
await Promise.all(
|
|
directories.splice(0).map((directory) =>
|
|
rm(directory, { recursive: true, force: true })
|
|
)
|
|
)
|
|
})
|
|
|
|
async function repository(): Promise<FeedbackRepository> {
|
|
const directory = await mkdtemp(join(tmpdir(), 'product-issue-repository-'))
|
|
directories.push(directory)
|
|
const database = openDatabase(join(directory, 'database.sqlite'))
|
|
databases.push(database)
|
|
return new FeedbackRepository(database)
|
|
}
|
|
|
|
describe('FeedbackRepository', () => {
|
|
it('seeds GoodBuddy and stores searchable feedback with stable references', async () => {
|
|
const store = await repository()
|
|
expect(store.listProducts()).toMatchObject([
|
|
{ key: 'goodbuddy', name: 'GoodBuddy', enabled: true }
|
|
])
|
|
|
|
const result = store.createFeedback({
|
|
id: '00000000-0000-4000-8000-000000000010',
|
|
payload: {
|
|
schemaVersion: 1,
|
|
productKey: 'goodbuddy',
|
|
category: 'feature',
|
|
title: '增加应用内反馈',
|
|
description: '希望可以在关于页面直接提交产品建议和截图。',
|
|
installationId: '00000000-0000-4000-8000-000000000011',
|
|
clientRequestId: '00000000-0000-4000-8000-000000000012'
|
|
},
|
|
installationHash: 'installation',
|
|
sourceIpHash: 'ip'
|
|
})
|
|
|
|
expect(result.reference).toBe('GOODBUDDY-000001')
|
|
expect(
|
|
store.getDuplicate(
|
|
'goodbuddy',
|
|
'00000000-0000-4000-8000-000000000012'
|
|
)
|
|
).toMatchObject({ reference: result.reference })
|
|
expect(
|
|
store.listFeedback({
|
|
search: '应用内',
|
|
page: 1,
|
|
limit: 30
|
|
})
|
|
).toMatchObject({
|
|
total: 1,
|
|
items: [{ reference: result.reference, category: 'feature' }]
|
|
})
|
|
})
|
|
|
|
it('fails closed for unknown or disabled products', async () => {
|
|
const store = await repository()
|
|
const product = store.createProduct('another-product', 'Another Product')
|
|
store.updateProduct(product.id, { enabled: false })
|
|
|
|
expect(() =>
|
|
store.createFeedback({
|
|
id: '00000000-0000-4000-8000-000000000020',
|
|
payload: {
|
|
schemaVersion: 1,
|
|
productKey: 'another-product',
|
|
category: 'other',
|
|
title: 'A valid feedback title',
|
|
description: 'A sufficiently descriptive feedback body.',
|
|
installationId: '00000000-0000-4000-8000-000000000021',
|
|
clientRequestId: '00000000-0000-4000-8000-000000000022'
|
|
},
|
|
installationHash: 'installation',
|
|
sourceIpHash: 'ip'
|
|
})
|
|
).toThrow(ProductNotFoundError)
|
|
})
|
|
})
|