import { jest } from '@jest/globals' import { Kysely, Transaction } from 'kysely' import type { DbConfig } from '../../../../src/Database/index.js' import { KyselyDatabase } from '../../../../src/Database/integrations/kysely/KyselyDatabase.js' import { KyselyTransactionImpl } from '../../../../src/Database/integrations/kysely/KyselyTransaction.js' const testResources = async (config: Partial>) => { type DB = { view: { id: number } secondView: { title: string } } const database = { config: { autoCommit: true, ...config, } as DbConfig<'kysely'>, } as any as KyselyDatabase const transaction = jest.fn().mockImplementation(() => { return { execute: jest.fn(async (cb: any) => { try { await cb(transaction) } catch (e) { /* empty */ } }), executeQuery: jest.fn(), } })() as any as Transaction const writer = jest.fn().mockImplementation(() => { return { transaction: jest.fn(() => transaction), } })() as any as Kysely return { transaction, writer, underTest: await KyselyTransactionImpl.newTransaction(writer, database), } } describe('KyselyTransaction', () => { test('Transaction starts opened', async () => { const { transaction, underTest } = await testResources({}) expect(underTest.isOpen()).toBe(true) expect(transaction['execute']).toHaveBeenCalledTimes(1) await expect(underTest.begin).rejects.toThrowError( 'Cannot begin, transaction is already opened!' ) }) test('Can only commit once', async () => { const { underTest } = await testResources({}) await underTest.commit() expect(underTest.isOpen()).toBe(false) await expect(underTest.commit).rejects.toThrowError( 'Cannot commit, transaction is already closed!' ) }) test('Can only rollback once', async () => { const { underTest } = await testResources({}) await underTest.rollback() expect(underTest.isOpen()).toBe(false) await expect(underTest.rollback).rejects.toThrowError( 'Cannot rollback, transaction is already closed!' ) }) test("Can't open transaction twice", async () => { const { underTest } = await testResources({}) expect(underTest.isOpen()).toBe(true) await expect(underTest.begin).rejects.toThrowError( 'Cannot begin, transaction is already opened!' ) }) test('Can commit, begin and commit again ', async () => { const { underTest } = await testResources({}) await underTest.commit() expect(underTest.isOpen()).toBe(false) await underTest.begin() expect(underTest.isOpen()).toBe(true) await underTest.commit() expect(underTest.isOpen()).toBe(false) }) test('Can commit, begin and rollback ', async () => { const { underTest } = await testResources({}) await underTest.commit() expect(underTest.isOpen()).toBe(false) await underTest.begin() expect(underTest.isOpen()).toBe(true) await underTest.rollback() expect(underTest.isOpen()).toBe(false) }) test('Can rollback, begin and commit ', async () => { const { underTest } = await testResources({}) await underTest.rollback() expect(underTest.isOpen()).toBe(false) await underTest.begin() expect(underTest.isOpen()).toBe(true) await underTest.commit() expect(underTest.isOpen()).toBe(false) }) })