@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.
949 lines • 44.1 kB
JavaScript
import { TimeSpan } from "../../../time-span/implementations/_module-exports.js";
/**
* The `databaseSharedLockAdapterTestSuite` function simplifies the process of testing your custom implementation of {@link IDatabaseSharedLockAdapter | `IDatabaseSharedLockAdapter`} with `vitest`.
*
* IMPORT_PATH: `"@daiso-tech/core/shared-lock/test-utilities"`
* @group Utilities
* @example
* ```ts
* import { afterEach, beforeEach, describe, expect, test } from "vitest";
* import { databaseSharedLockAdapterTestSuite } from "@daiso-tech/core/shared-lock/test-utilities";
* import { KyselySharedLockAdapter, type KyselySharedLockTables } from "@daiso-tech/core/shared-lock/kysely-shared-lock-adapter";
* import { Kysely, SqliteDialect } from "kysely";
* import Sqlite, { type Database } from "better-sqlite3";
*
* describe("class: KyselySharedLockAdapter", () => {
* let database: Database;
* let kysely: Kysely<KyselySharedLockTables>;
*
* beforeEach(() => {
* database = new Sqlite(":memory:");
* kysely = new Kysely({
* dialect: new SqliteDialect({
* database,
* }),
* });
* });
* afterEach(() => {
* database.close();
* });
* databaseSharedLockAdapterTestSuite({
* createAdapter: async () => {
* const sharedLockAdapter = new KyselySharedLockAdapter({
* kysely,
* shouldRemoveExpiredKeys: false,
* });
* await sharedLockAdapter.init();
* return sharedLockAdapter;
* },
* test,
* beforeEach,
* expect,
* describe,
* });
* });
* ```
*/
export function databaseSharedLockAdapterTestSuite(settings) {
const { expect, test, createAdapter, describe, beforeEach } = settings;
describe("Reusable tests:", () => {
let adapter;
beforeEach(async () => {
adapter = await createAdapter();
});
describe("method: transaction writer.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.writer.upsert(key, owner, expiration);
});
const noneExistingKey = "b";
const result = await adapter.transaction(async (trx) => {
return await trx.writer.find(noneExistingKey);
});
expect(result).toBeNull();
});
test("Should return IWriterLockData when key exists", async () => {
const key = "a";
const owner = "1";
const expiration = TimeSpan.fromMinutes(2).toEndDate();
await adapter.transaction(async (trx) => {
await trx.writer.upsert(key, owner, expiration);
});
const result = await adapter.transaction(async (trx) => {
return await trx.writer.find(key);
});
expect(result).toEqual({
owner,
expiration,
});
});
});
describe("method: transaction writer.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.writer.upsert(key, owner, expiration);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner1, expiration1);
});
const owner2 = "2";
const expiration2 = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
await trx.writer.upsert(key, owner2, expiration2);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.find(key);
});
expect(lockData).toEqual({
expiration: expiration2,
owner: owner2,
});
});
});
describe("method: transaction writer.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.writer.upsert(key, owner, expiration);
});
const noneExistingKey = "c";
const lockExpirationData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const lockExpirationData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const lockExpirationData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
await adapter.transaction(async (trx) => {
return await trx.writer.remove(key);
});
const lockExpirationData = await adapter.transaction(async (trx) => {
return await trx.writer.find(key);
});
expect(lockExpirationData).toBeNull();
});
});
describe("method: transaction writer.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.writer.upsert(key, owner, expiration);
});
const noneExistingKey = "c";
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const noneExistingOwner = "c";
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
await adapter.transaction(async (trx) => {
await trx.writer.removeIfOwner(key, owner);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const noneExsitingOwner = "c";
await adapter.transaction(async (trx) => {
await trx.writer.removeIfOwner(key, noneExsitingOwner);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.find(key);
});
expect(lockData).toEqual({
expiration,
owner,
});
});
});
describe("method: transaction writer.updateExpiration", () => {
test("Should return 0 when semaphore key doesnt exists", async () => {
const key = "a";
const owner = "1";
const expiration = TimeSpan.fromMilliseconds(50).toEndDate();
await adapter.transaction(async (trx) => {
await trx.writer.upsert(key, owner, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const noneExistingKey = "b";
const result1 = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const noneExistingOwner = "b";
const result1 = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const result1 = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const result1 = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration.toEndDate());
});
const newExpiration = TimeSpan.fromMilliseconds(100);
const result1 = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
await trx.writer.updateExpiration(key, owner, newExpiration);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
await trx.writer.updateExpiration(key, owner, newExpiration);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.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.writer.upsert(key, owner, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
await trx.writer.updateExpiration(key, owner, newExpiration);
});
const lockData = await adapter.transaction(async (trx) => {
return await trx.writer.find(key);
});
expect(lockData).toEqual({
owner,
expiration: newExpiration,
});
});
});
describe("method: transaction writer.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.writer.upsert(key, owner, expiration);
});
const noneExistingKey = "b";
const result = await adapter.transaction(async (trx) => {
return await trx.writer.find(noneExistingKey);
});
expect(result).toBeNull();
});
test("Should return IWriterLockData when key exists", async () => {
const key = "a";
const owner = "1";
const expiration = TimeSpan.fromMinutes(2).toEndDate();
await adapter.transaction(async (trx) => {
await trx.writer.upsert(key, owner, expiration);
});
const result = await adapter.transaction(async (trx) => {
return await trx.writer.find(key);
});
expect(result).toEqual({
owner,
expiration,
});
});
});
describe("method: transaction reader.findSemaphore", () => {
test("Should return null when key doesnt exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const noneExistingKey = "b";
const result = await adapter.transaction(async (trx) => {
return await trx.reader.findSemaphore(noneExistingKey);
});
expect(result).toBeNull();
});
test("Should return ISemaphoreData when key exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const result = await adapter.transaction(async (trx) => {
return await trx.reader.findSemaphore(key);
});
expect(result).toEqual({
limit,
});
});
});
describe("method: transaction reader.findSlots", () => {
test("Should return empty array when key doesnt exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const noneExistingKey = "b";
const result = await adapter.transaction(async (trx) => {
return await trx.reader.findSlots(noneExistingKey);
});
expect(result).toEqual([]);
});
test("Should return empty array when key exists and has no slots", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const result = await adapter.transaction(async (trx) => {
return await trx.reader.findSlots(key);
});
expect(result).toEqual([]);
});
test("Should not return empty array when key exists and has no slots", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration1 = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration1);
});
const slotId2 = "2";
const expiration2 = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId2, expiration2);
});
const result = await adapter.transaction(async (trx) => {
return await trx.reader.findSlots(key);
});
expect(result).toEqual([
{
id: slotId1,
expiration: expiration1,
},
{
id: slotId2,
expiration: expiration2,
},
]);
});
});
describe("method: transaction reader.upsertSemaphore", () => {
test("Should insert when key doesnt exists exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const result = await adapter.transaction(async (trx) => {
return await trx.reader.findSemaphore(key);
});
expect(result).toEqual({
limit,
});
});
test("Should update when key exists exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const newLimit = 4;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, newLimit);
});
const result = await adapter.transaction(async (trx) => {
return await trx.reader.findSemaphore(key);
});
expect(result).toEqual({
limit: newLimit,
});
});
});
describe("method: transaction reader.upsertSlot", () => {
test("Should insert when key doesnt exists exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId = "a";
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
const slot = await adapter.transaction(async (trx) => {
const slots = await trx.reader.findSlots(key);
return slots.find((slot) => slot.id === slotId);
});
expect(slot).toEqual({
expiration,
id: slotId,
});
});
test("Should update when key exists exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration1 = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration1);
});
const slotId2 = "2";
const expiration2 = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId2, expiration2);
});
const slot = await adapter.transaction(async (trx) => {
const slots = await trx.reader.findSlots(key);
return slots.find((slot) => slot.id === slotId2);
});
expect(slot).toEqual({
expiration: expiration2,
id: slotId2,
});
});
});
describe("method: removeSlot", () => {
test("Should return null when key doesnt exists", async () => {
const key = "a";
const slotId = "b";
const limit = 2;
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
const noneExistingKey = "c";
const result = await adapter.transaction(async (trx) => {
return await trx.reader.removeSlot(noneExistingKey, slotId);
});
expect(result).toBeNull();
});
test("Should return null when slotId doesnt exists", async () => {
const key = "a";
const slotId = "b";
const limit = 2;
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
const noneExistingSlotId = "c";
const result = await adapter.transaction(async (trx) => {
return await trx.reader.removeSlot(key, noneExistingSlotId);
});
expect(result).toBeNull();
});
test("Should return expiration as null when key and slotId exists", async () => {
const key = "a";
const slotId = "b";
const limit = 2;
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
const result = await adapter.transaction(async (trx) => {
return await trx.reader.removeSlot(key, slotId);
});
expect(result).toEqual({
expiration,
});
});
test("Should return expiration as date when key and slotId exists", async () => {
const key = "a";
const slotId = "b";
const limit = 2;
const expiration = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
const result = await adapter.transaction(async (trx) => {
return await trx.reader.removeSlot(key, slotId);
});
expect(result).toEqual({
expiration,
});
});
test("Should remove slot when key and slotId exists", async () => {
const key = "a";
const slotId = "b";
const limit = 2;
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
await adapter.transaction(async (trx) => {
return await trx.reader.removeSlot(key, slotId);
});
const slot = await adapter.transaction(async (trx) => {
const slots = await trx.reader.findSlots(key);
return slots.find((slot) => slot.id === slotId);
});
expect(slot).toBeUndefined();
});
test("Should not remove slot when key exists and slotId does not exists", async () => {
const key = "a";
const slotId = "b";
const limit = 2;
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
const noneExistingSlotId = "c";
await adapter.transaction(async (trx) => {
return await trx.reader.removeSlot(key, noneExistingSlotId);
});
const slot = await adapter.transaction(async (trx) => {
const slots = await trx.reader.findSlots(key);
return slots.find((slot) => slot.id === slotId);
});
expect(slot).toEqual({
id: slotId,
expiration,
});
});
});
describe("method: removeAllSlots", () => {
test("Should return empty array when key doesnt exists", async () => {
const key = "a";
const slotId = "b";
const limit = 2;
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId, expiration);
});
const noneExistingKey = "c";
const result = await adapter.transaction(async (trx) => {
return trx.reader.removeAllSlots(noneExistingKey);
});
expect(result).toEqual([]);
});
test("Should return empty array when key exists and has no slots", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const result = await adapter.transaction(async (trx) => {
return trx.reader.removeAllSlots(key);
});
expect(result).toEqual([]);
});
test("Should return array with 2 items when key exists and has slots", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "b";
const expiration1 = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration1);
});
const slotId2 = "c";
const expiration2 = TimeSpan.fromMilliseconds(10).toEndDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId2, expiration2);
});
const result = await adapter.transaction(async (trx) => {
return trx.reader.removeAllSlots(key);
});
expect(result).toEqual([
{
expiration: expiration1,
},
{
expiration: expiration2,
},
]);
});
test("Should remove all items when key exists and has slots", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "b";
const expiration1 = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration1);
});
const slotId2 = "c";
const expiration2 = TimeSpan.fromMilliseconds(10).toEndDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId2, expiration2);
});
await adapter.transaction(async (trx) => {
return trx.reader.removeAllSlots(key);
});
const slots = await adapter.transaction(async (trx) => {
return await trx.reader.findSlots(key);
});
expect(slots).toEqual([]);
});
});
describe("method: updateExpiration", () => {
test("Should return 0 when semaphore key doesnt exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = TimeSpan.fromMilliseconds(50).toEndDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const noneExistingKey = "b";
const result1 = await adapter.transaction(async (trx) => {
return trx.reader.updateExpiration(noneExistingKey, slotId1, newExpiration);
});
expect(result1).toBe(0);
});
test("Should return 0 when slot doesnt exists", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = TimeSpan.fromMilliseconds(50).toEndDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const noneExistingSlotId = "b";
const result1 = await adapter.transaction(async (trx) => {
return trx.reader.updateExpiration(key, noneExistingSlotId, newExpiration);
});
expect(result1).toBe(0);
});
test("Should return 0 when slot is expired", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = TimeSpan.fromMilliseconds(50).toStartDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const result1 = await adapter.transaction(async (trx) => {
return trx.reader.updateExpiration(key, slotId1, newExpiration);
});
expect(result1).toBe(0);
});
test("Should return 0 when slot is unexpireable", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
const result1 = await adapter.transaction(async (trx) => {
return trx.reader.updateExpiration(key, slotId1, newExpiration);
});
expect(result1).toBe(0);
});
test("Should return number greater than 0 when slot is unexpired", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = TimeSpan.fromMilliseconds(50);
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration.toEndDate());
});
const newExpiration = TimeSpan.fromMilliseconds(100);
const result1 = await adapter.transaction(async (trx) => {
return trx.reader.updateExpiration(key, slotId1, newExpiration.toEndDate());
});
expect(result1).toBeGreaterThan(0);
});
test("Should not update expiration when slot is expired", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = TimeSpan.fromMilliseconds(50).toStartDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
return await trx.reader.updateExpiration(key, slotId1, newExpiration);
});
const slot = await adapter.transaction(async (trx) => {
const slots = await trx.reader.findSlots(key);
return slots.find((slot) => slot.id === slotId1);
});
expect(slot).toEqual({
id: slotId1,
expiration,
});
});
test("Should not update expiration when slot is unexpireable", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = null;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
return await trx.reader.updateExpiration(key, slotId1, newExpiration);
});
const slot = await adapter.transaction(async (trx) => {
const slots = await trx.reader.findSlots(key);
return slots.find((slot) => slot.id === slotId1);
});
expect(slot).toEqual({
id: slotId1,
expiration,
});
});
test("Should update expiration when slot is unexpired", async () => {
const key = "a";
const limit = 2;
await adapter.transaction(async (trx) => {
await trx.reader.upsertSemaphore(key, limit);
});
const slotId1 = "1";
const expiration = TimeSpan.fromMilliseconds(50).toEndDate();
await adapter.transaction(async (trx) => {
await trx.reader.upsertSlot(key, slotId1, expiration);
});
const newExpiration = TimeSpan.fromMilliseconds(100).toEndDate();
await adapter.transaction(async (trx) => {
return await trx.reader.updateExpiration(key, slotId1, newExpiration);
});
const slot = await adapter.transaction(async (trx) => {
const slots = await trx.reader.findSlots(key);
return slots.find((slot) => slot.id === slotId1);
});
expect(slot).toEqual({
id: slotId1,
expiration: newExpiration,
});
});
});
});
}
//# sourceMappingURL=database-shared-lock-adapter.test-suite.js.map