UNPKG

@daiso-tech/core

Version:

The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.

379 lines 16.9 kB
/** * @module Lock */ import {} from "vitest"; import {} from "../../../lock/contracts/_module.js"; import { TimeSpan } from "../../../time-span/implementations/_module.js"; import {} from "../../../utilities/_module.js"; /** * The `databaseLockAdapterTestSuite` function simplifies the process of testing your custom implementation of {@link IDatabaseLockAdapter | `IDatabaseLockAdapter`} with `vitest`. * * IMPORT_PATH: `"@daiso-tech/core/lock/test-utilities"` * @group Utilities * @example * ```ts * import { afterEach, beforeEach, describe, expect, test } from "vitest"; * import { databaseLockAdapterTestSuite } from "@daiso-tech/core/lock/test-utilities"; * import { kyselyLockAdapter, type KyselyLockTables } from "@daiso-tech/core/lock/kysely-lock-adapter"; * import { Kysely, SqliteDialect } from "kysely"; * import Sqlite, { type Database } from "better-sqlite3"; * * describe("class: kyselyLockAdapter", () => { * let database: Database; * let kysely: Kysely<KyselyLockTables>; * * beforeEach(() => { * database = new Sqlite(":memory:"); * kysely = new Kysely({ * dialect: new SqliteDialect({ * database, * }), * }); * }); * afterEach(() => { * database.close(); * }); * databaseLockAdapterTestSuite({ * createAdapter: async () => { * const lockAdapter = new kyselyLockAdapter({ * kysely, * shouldRemoveExpiredKeys: false, * }); * await lockAdapter.init(); * return lockAdapter; * }, * test, * beforeEach, * expect, * describe, * }); * }); * ``` */ export function databaseLockAdapterTestSuite(settings) { const { expect, test, createAdapter, describe, beforeEach } = settings; describe("Reusable tests:", () => { let adapter; beforeEach(async () => { adapter = await createAdapter(); }); describe("method: transaction find", () => { test("Should return null when key doesnt exists", async () => { const key = "a"; const owner = "1"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const noneExistingKey = "b"; const result = await adapter.transaction(async (trx) => { return await trx.find(noneExistingKey); }); expect(result).toBeNull(); }); test("Should return ILockData when key exists", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMinutes(2).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const result = await adapter.transaction(async (trx) => { return await trx.find(key); }); expect(result).toEqual({ owner, expiration, }); }); }); describe("method: transaction upsert", () => { test("Should insert when key doesnt exists exists", async () => { const key = "a"; const owner = "b"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const lockData = await adapter.find(key); expect(lockData).toEqual({ expiration, owner, }); }); test("Should update when key exists exists", async () => { const key = "a"; const owner1 = "1"; const expiration1 = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner1, expiration1); }); const owner2 = "2"; const expiration2 = TimeSpan.fromMilliseconds(100).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner2, expiration2); }); const lockData = await adapter.find(key); expect(lockData).toEqual({ expiration: expiration2, owner: owner2, }); }); }); describe("method: remove", () => { test("Should return null when key doesnt exists", async () => { const key = "a"; const owner = "b"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const noneExistingKey = "c"; const lockExpirationData = await adapter.remove(noneExistingKey); expect(lockExpirationData).toBeNull(); }); test("Should return expiration as null when key exists", async () => { const key = "a"; const owner = "b"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const lockExpirationData = await adapter.remove(key); expect(lockExpirationData).toEqual({ expiration, }); }); test("Should return expiration as date when key exists", async () => { const key = "a"; const owner = "b"; const expiration = TimeSpan.fromMinutes(5).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const lockExpirationData = await adapter.remove(key); expect(lockExpirationData).toEqual({ expiration, }); }); test("Should remove lock when key exists", async () => { const key = "a"; const owner = "b"; const expiration = TimeSpan.fromMinutes(5).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); await adapter.remove(key); const lockExpirationData = await adapter.find(key); expect(lockExpirationData).toBeNull(); }); }); describe("method: removeIfOwner", () => { test("Should return null when key doesnt exists", async () => { const key = "a"; const owner = "b"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const noneExistingKey = "c"; const lockData = await adapter.removeIfOwner(noneExistingKey, owner); expect(lockData).toBeNull(); }); test("Should return null when owner doesnt exists", async () => { const key = "a"; const owner = "b"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const noneExistingOwner = "c"; const lockData = await adapter.removeIfOwner(key, noneExistingOwner); expect(lockData).toBeNull(); }); test("Should return expiration as null when key and owner exists and is unexpireable", async () => { const key = "a"; const owner = "b"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const lockData = await adapter.removeIfOwner(key, owner); expect(lockData).toEqual({ expiration, owner, }); }); test("Should return expiration as date when key and owner exists and is unexpireable", async () => { const key = "a"; const owner = "b"; const expiration = TimeSpan.fromMinutes(10).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const lockData = await adapter.removeIfOwner(key, owner); expect(lockData).toEqual({ expiration, owner, }); }); test("Should remove lock when key and owner exists", async () => { const key = "a"; const owner = "b"; const expiration = TimeSpan.fromMinutes(10).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); await adapter.removeIfOwner(key, owner); const lockData = await adapter.find(key); expect(lockData).toBeNull(); }); test("Should not remove lock when key exists and owner does not exists", async () => { const key = "a"; const owner = "b"; const expiration = TimeSpan.fromMinutes(10).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const noneExsitingOwner = "c"; await adapter.removeIfOwner(key, noneExsitingOwner); const lockData = await adapter.find(key); expect(lockData).toEqual({ expiration, owner, }); }); }); describe("method: updateExpiration", () => { test("Should return 0 when lock key doesnt exists", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMilliseconds(50).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate(); const noneExistingKey = "b"; const result1 = await adapter.updateExpiration(noneExistingKey, owner, newExpiration); expect(result1).toBe(0); }); test("Should return 0 when owner doesnt exists", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMilliseconds(50).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate(); const noneExistingOwner = "b"; const result1 = await adapter.updateExpiration(key, noneExistingOwner, newExpiration); expect(result1).toBe(0); }); test("Should return 0 when lock is expired", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMilliseconds(50).toStartDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate(); const result1 = await adapter.updateExpiration(key, owner, newExpiration); expect(result1).toBe(0); }); test("Should return 0 when lock is unexpireable", async () => { const key = "a"; const owner = "1"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate(); const result1 = await adapter.updateExpiration(key, owner, newExpiration); expect(result1).toBe(0); }); test("Should return number greater than 0 when lock is unexpired", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMilliseconds(50); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration.toEndDate()); }); const newExpiration = TimeSpan.fromMilliseconds(100); const result1 = await adapter.updateExpiration(key, owner, newExpiration.toEndDate()); expect(result1).toBeGreaterThan(0); }); test("Should not update expiration when lock is expired", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMilliseconds(50).toStartDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate(); await adapter.updateExpiration(key, owner, newExpiration); const lockData = await adapter.find(key); expect(lockData).toEqual({ owner, expiration, }); }); test("Should not update expiration when lock is unexpireable", async () => { const key = "a"; const owner = "1"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate(); await adapter.updateExpiration(key, owner, newExpiration); const lockData = await adapter.find(key); expect(lockData).toEqual({ owner, expiration, }); }); test("Should update expiration when lock is unexpired", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMilliseconds(50).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate(); await adapter.updateExpiration(key, owner, newExpiration); const lockData = await adapter.find(key); expect(lockData).toEqual({ owner, expiration: newExpiration, }); }); }); describe("method: find", () => { test("Should return null when key doesnt exists", async () => { const key = "a"; const owner = "1"; const expiration = null; await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const noneExistingKey = "b"; const result = await adapter.find(noneExistingKey); expect(result).toBeNull(); }); test("Should return ILockData when key exists", async () => { const key = "a"; const owner = "1"; const expiration = TimeSpan.fromMinutes(2).toEndDate(); await adapter.transaction(async (trx) => { await trx.upsert(key, owner, expiration); }); const result = await adapter.find(key); expect(result).toEqual({ owner, expiration, }); }); }); }); } //# sourceMappingURL=database-lock-adapter.test-suite.js.map