Files
DevRunbook-Public/packages/db/src/playbooks/playbook-favorite-store.test.ts
T
DevRunbook release export cfd2804e27
Managed validation / full (push) Successful in 3m18s
Publish DevRunbook source
2026-09-03 04:09:17 +02:00

91 lines
2.7 KiB
TypeScript

import { drizzle } from 'drizzle-orm/postgres-js'
import { describe, expect, it } from 'vitest'
import * as schema from '../schema'
import {
buildAccessibleFavoriteTargetQuery,
DrizzlePlaybookFavoriteStore,
type PlaybookFavoriteTransaction,
type PlaybookFavoriteTransactionRunner,
} from './playbook-favorite-store'
const workspaceId = '00000000-0000-4000-8000-000000000001'
const userId = '00000000-0000-4000-8000-000000000002'
const playbookId = '00000000-0000-4000-8000-000000000003'
class MemoryRunner implements PlaybookFavoriteTransactionRunner {
accessible = true
favorite = false
additions = 0
removals = 0
async run<T>(
work: (transaction: PlaybookFavoriteTransaction) => Promise<T>,
): Promise<T> {
return work({
targetIsAccessible: async () => this.accessible,
add: async () => {
if (!this.favorite) this.additions += 1
this.favorite = true
},
remove: async () => {
if (this.favorite) this.removals += 1
this.favorite = false
},
})
}
}
describe('favorite target query', () => {
it('accepts only the requested built-in or same-workspace playbook', () => {
const database = drizzle.mock({ schema })
const query = buildAccessibleFavoriteTargetQuery(database, {
workspaceId,
playbookId,
}).toSQL()
expect(query.sql).toContain('from "playbooks"')
expect(query.sql).toContain('"playbooks"."source_type" = $')
expect(query.sql).toContain('"playbooks"."workspace_id" = $')
expect(query.params).toEqual(
expect.arrayContaining([playbookId, 'built_in', workspaceId]),
)
})
})
describe('DrizzlePlaybookFavoriteStore', () => {
it('adds and removes idempotently', async () => {
const runner = new MemoryRunner()
const store = new DrizzlePlaybookFavoriteStore(runner)
const input = { workspaceId, userId, playbookId }
await expect(
store.mutateFavorite({ ...input, mutation: 'add' }),
).resolves.toBe(true)
await store.mutateFavorite({ ...input, mutation: 'add' })
await expect(
store.mutateFavorite({ ...input, mutation: 'remove' }),
).resolves.toBe(true)
await store.mutateFavorite({ ...input, mutation: 'remove' })
expect(runner.additions).toBe(1)
expect(runner.removals).toBe(1)
})
it('does not mutate a missing or inaccessible target', async () => {
const runner = new MemoryRunner()
runner.accessible = false
const store = new DrizzlePlaybookFavoriteStore(runner)
await expect(
store.mutateFavorite({
workspaceId,
userId,
playbookId,
mutation: 'add',
}),
).resolves.toBe(false)
expect(runner.favorite).toBe(false)
})
})