Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dependencies": {
"@crypto-wallet/cache": "workspace:*",
"@crypto-wallet/config": "workspace:*",
"@crypto-wallet/ledger-core": "workspace:*",
"@crypto-wallet/shared-types": "workspace:*",
"@crypto-wallet/storage": "workspace:*",
"@opentelemetry/api": "^1.9.1",
Expand Down
137 changes: 137 additions & 0 deletions apps/api/src/__tests__/exchange-account-repository.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { randomUUID } from "node:crypto";

import { describe, expect, it } from "vitest";

import { PostgresStorage } from "@crypto-wallet/storage";

import { ExchangeAccountRepository } from "../exchange/exchange-account-repository.js";

const databaseUrl = process.env.DATABASE_URL;

if (!databaseUrl) {
throw new Error("DATABASE_URL is required for exchange account repository tests");
}

describe("ExchangeAccountRepository", () => {
it("creates and finds a customer exchange account", async () => {
const storage = new PostgresStorage(databaseUrl);
const repository = new ExchangeAccountRepository(storage);

const ownerId = randomUUID();

try {
await storage.connect();

const created = await repository.create({
ownerType: "customer",
ownerId,
kind: "customer",
});

expect(created).toMatchObject({
ownerType: "customer",
ownerId,
kind: "customer",
status: "active",
});

expect(created.id).toBeTruthy();
expect(created.createdAt).toBeInstanceOf(Date);

const found = await repository.findById(created.id);

expect(found).toEqual(created);
} finally {
await storage.query(
`
DELETE FROM exchange_accounts
WHERE owner_id = $1
`,
[ownerId],
);

await storage.disconnect();
}
});

it("finds an account by owner and kind", async () => {
const storage = new PostgresStorage(databaseUrl);
const repository = new ExchangeAccountRepository(storage);

const ownerId = randomUUID();

try {
await storage.connect();

const created = await repository.create({
ownerType: "platform",
ownerId,
kind: "treasury",
});

const found = await repository.findByOwnerAndKind("platform", ownerId, "treasury");

expect(found).toEqual(created);
} finally {
await storage.query(
`
DELETE FROM exchange_accounts
WHERE owner_id = $1
`,
[ownerId],
);

await storage.disconnect();
}
});

it("returns null for an unknown account", async () => {
const storage = new PostgresStorage(databaseUrl);
const repository = new ExchangeAccountRepository(storage);

try {
await storage.connect();

const found = await repository.findById(randomUUID());

expect(found).toBeNull();
} finally {
await storage.disconnect();
}
});

it("enforces the database uniqueness boundary", async () => {
const storage = new PostgresStorage(databaseUrl);
const repository = new ExchangeAccountRepository(storage);

const ownerId = randomUUID();

try {
await storage.connect();

await repository.create({
ownerType: "customer",
ownerId,
kind: "customer",
});

await expect(
repository.create({
ownerType: "customer",
ownerId,
kind: "customer",
}),
).rejects.toThrow();
} finally {
await storage.query(
`
DELETE FROM exchange_accounts
WHERE owner_id = $1
`,
[ownerId],
);

await storage.disconnect();
}
});
});
Loading
Loading