Skip to content

Commit 66bef62

Browse files
Shawclaude
andcommitted
fix(cloud-tests): biome format direct-wallet-payments.integration.test
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 5ac952d commit 66bef62

1 file changed

Lines changed: 155 additions & 156 deletions

File tree

packages/cloud-shared/src/lib/services/__tests__/direct-wallet-payments.integration.test.ts

Lines changed: 155 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,7 @@
1414
* - mock `bnb-price-oracle` so we don't hit the network for BNB quotes.
1515
*/
1616

17-
import {
18-
afterAll,
19-
beforeAll,
20-
beforeEach,
21-
describe,
22-
expect,
23-
test,
24-
vi,
25-
} from "vitest";
17+
import { afterAll, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
2618

2719
// This integration test relies on Vitest-only module-mock plumbing
2820
// (`vi.mock(id, async () => ({ ...await vi.importActual<T>(id), ...overrides }))`)
@@ -39,8 +31,7 @@ import {
3931
// state-machine paths are exercised by other integration suites that use
4032
// real test fixtures rather than vi.mock.
4133
const SUPPORTS_VITEST_MOCK_API =
42-
typeof (vi as unknown as { importActual?: unknown }).importActual ===
43-
"function";
34+
typeof (vi as unknown as { importActual?: unknown }).importActual === "function";
4435
const d = SUPPORTS_VITEST_MOCK_API ? describe : describe.skip;
4536

4637
// --- Required env BEFORE any imports of cloud-shared/db ---------------------
@@ -83,90 +74,92 @@ interface FakeTx {
8374

8475
const chainTxs = new Map<string, FakeTx>();
8576

86-
if (SUPPORTS_VITEST_MOCK_API) vi.mock("viem", async () => {
87-
const actual = (await vi.importActual("viem")) as typeof import("viem");
88-
return {
89-
...actual,
90-
createPublicClient: () => ({
91-
async getTransactionReceipt({ hash }: { hash: string }) {
92-
const tx = chainTxs.get(hash);
93-
if (!tx) {
94-
const err = new Error("Transaction receipt not found");
95-
err.name = "TransactionReceiptNotFoundError";
96-
throw err;
97-
}
98-
if (tx.throwNotFound) {
99-
const err = new Error("could not be found");
100-
err.name = "TransactionReceiptNotFoundError";
101-
throw err;
102-
}
103-
if (tx.throwTerminal) {
104-
throw new Error(tx.throwTerminal);
105-
}
106-
return {
107-
status: tx.status,
108-
blockNumber: 12345n,
109-
logs: tx.erc20
110-
? [
111-
{
112-
address: tx.erc20.tokenAddress,
113-
topics: [],
114-
data: "0x",
115-
// parseEventLogs uses these — we shortcut via stubbed parseEventLogs below
77+
if (SUPPORTS_VITEST_MOCK_API)
78+
vi.mock("viem", async () => {
79+
const actual = (await vi.importActual("viem")) as typeof import("viem");
80+
return {
81+
...actual,
82+
createPublicClient: () => ({
83+
async getTransactionReceipt({ hash }: { hash: string }) {
84+
const tx = chainTxs.get(hash);
85+
if (!tx) {
86+
const err = new Error("Transaction receipt not found");
87+
err.name = "TransactionReceiptNotFoundError";
88+
throw err;
89+
}
90+
if (tx.throwNotFound) {
91+
const err = new Error("could not be found");
92+
err.name = "TransactionReceiptNotFoundError";
93+
throw err;
94+
}
95+
if (tx.throwTerminal) {
96+
throw new Error(tx.throwTerminal);
97+
}
98+
return {
99+
status: tx.status,
100+
blockNumber: 12345n,
101+
logs: tx.erc20
102+
? [
103+
{
104+
address: tx.erc20.tokenAddress,
105+
topics: [],
106+
data: "0x",
107+
// parseEventLogs uses these — we shortcut via stubbed parseEventLogs below
108+
},
109+
]
110+
: [],
111+
};
112+
},
113+
async getTransaction({ hash }: { hash: string }) {
114+
const tx = chainTxs.get(hash);
115+
if (!tx) throw new Error("not found");
116+
return { from: tx.from, to: tx.to, value: tx.value };
117+
},
118+
async readContract() {
119+
return 18n;
120+
},
121+
}),
122+
parseEventLogs: ({ logs }: { logs: Array<{ address: string }> }) => {
123+
// Map the stub-receipt log back to a parsed Transfer event using the
124+
// chainTxs entry whose tokenAddress matches.
125+
const out: Array<{
126+
address: string;
127+
args: { from: string; to: string; value: bigint };
128+
}> = [];
129+
for (const log of logs) {
130+
for (const tx of chainTxs.values()) {
131+
if (tx.erc20 && tx.erc20.tokenAddress.toLowerCase() === log.address.toLowerCase()) {
132+
out.push({
133+
address: tx.erc20.tokenAddress,
134+
args: {
135+
from: tx.erc20.from,
136+
to: tx.erc20.to,
137+
value: tx.erc20.value,
116138
},
117-
]
118-
: [],
119-
};
120-
},
121-
async getTransaction({ hash }: { hash: string }) {
122-
const tx = chainTxs.get(hash);
123-
if (!tx) throw new Error("not found");
124-
return { from: tx.from, to: tx.to, value: tx.value };
125-
},
126-
async readContract() {
127-
return 18n;
128-
},
129-
}),
130-
parseEventLogs: ({ logs }: { logs: Array<{ address: string }> }) => {
131-
// Map the stub-receipt log back to a parsed Transfer event using the
132-
// chainTxs entry whose tokenAddress matches.
133-
const out: Array<{
134-
address: string;
135-
args: { from: string; to: string; value: bigint };
136-
}> = [];
137-
for (const log of logs) {
138-
for (const tx of chainTxs.values()) {
139-
if (tx.erc20 && tx.erc20.tokenAddress.toLowerCase() === log.address.toLowerCase()) {
140-
out.push({
141-
address: tx.erc20.tokenAddress,
142-
args: {
143-
from: tx.erc20.from,
144-
to: tx.erc20.to,
145-
value: tx.erc20.value,
146-
},
147-
});
148-
break;
139+
});
140+
break;
141+
}
149142
}
150143
}
151-
}
152-
return out;
153-
},
154-
};
155-
});
144+
return out;
145+
},
146+
};
147+
});
156148

157149
// BNB price oracle — fixed quote so the math is predictable.
158-
if (SUPPORTS_VITEST_MOCK_API) vi.mock("../bnb-price-oracle", async () => {
159-
const Decimal = (await import("decimal.js")).default;
160-
return {
161-
getBnbUsdQuote: vi.fn(async () => ({
162-
priceUsd: new Decimal(600),
163-
source: "chainlink",
164-
feedAddress: "0xfeed",
165-
updatedAt: "2026-01-01T00:00:00Z",
166-
fetchedAt: "2026-01-01T00:00:01Z",
167-
})),
168-
};
169-
});
150+
if (SUPPORTS_VITEST_MOCK_API)
151+
vi.mock("../bnb-price-oracle", async () => {
152+
const Decimal = (await import("decimal.js")).default;
153+
return {
154+
getBnbUsdQuote: vi.fn(async () => ({
155+
priceUsd: new Decimal(600),
156+
source: "chainlink",
157+
feedAddress: "0xfeed",
158+
updatedAt: "2026-01-01T00:00:00Z",
159+
fetchedAt: "2026-01-01T00:00:01Z",
160+
})),
161+
};
162+
});
170163

171164
// Solana — we don't test the Solana confirm path through verify (would need a
172165
// huge mock of getParsedTransaction + ATA owner check). The Solana createPayment
@@ -179,39 +172,43 @@ const solanaTestState = vi.hoisted(() => ({
179172
parsedTxOverride: null as unknown,
180173
}));
181174

182-
if (SUPPORTS_VITEST_MOCK_API) vi.mock("@solana/spl-token", async () => {
183-
const actual = (await vi.importActual("@solana/spl-token")) as typeof import("@solana/spl-token");
184-
return {
185-
...actual,
186-
getAccount: vi.fn(async (_connection: unknown, ata: { toBase58(): string }) => {
187-
if (solanaTestState.ataOwnerOverride) {
188-
const { PublicKey } = await import("@solana/web3.js");
189-
return {
190-
address: ata,
191-
owner: new PublicKey(solanaTestState.ataOwnerOverride),
192-
mint: ata,
193-
amount: 0n,
194-
} as unknown as Awaited<ReturnType<typeof actual.getAccount>>;
195-
}
196-
return actual.getAccount(_connection as never, ata as never);
197-
}),
198-
};
199-
});
200-
201-
if (SUPPORTS_VITEST_MOCK_API) vi.mock("@solana/web3.js", async () => {
202-
const actual = (await vi.importActual("@solana/web3.js")) as typeof import("@solana/web3.js");
203-
return {
204-
...actual,
205-
Connection: class FakeConnection {
206-
async getParsedTransaction() {
207-
return solanaTestState.parsedTxOverride;
208-
}
209-
async getAccountInfo() {
210-
return null;
211-
}
212-
},
213-
};
214-
});
175+
if (SUPPORTS_VITEST_MOCK_API)
176+
vi.mock("@solana/spl-token", async () => {
177+
const actual = (await vi.importActual(
178+
"@solana/spl-token",
179+
)) as typeof import("@solana/spl-token");
180+
return {
181+
...actual,
182+
getAccount: vi.fn(async (_connection: unknown, ata: { toBase58(): string }) => {
183+
if (solanaTestState.ataOwnerOverride) {
184+
const { PublicKey } = await import("@solana/web3.js");
185+
return {
186+
address: ata,
187+
owner: new PublicKey(solanaTestState.ataOwnerOverride),
188+
mint: ata,
189+
amount: 0n,
190+
} as unknown as Awaited<ReturnType<typeof actual.getAccount>>;
191+
}
192+
return actual.getAccount(_connection as never, ata as never);
193+
}),
194+
};
195+
});
196+
197+
if (SUPPORTS_VITEST_MOCK_API)
198+
vi.mock("@solana/web3.js", async () => {
199+
const actual = (await vi.importActual("@solana/web3.js")) as typeof import("@solana/web3.js");
200+
return {
201+
...actual,
202+
Connection: class FakeConnection {
203+
async getParsedTransaction() {
204+
return solanaTestState.parsedTxOverride;
205+
}
206+
async getAccountInfo() {
207+
return null;
208+
}
209+
},
210+
};
211+
});
215212

216213
// creditsService stand-in: respects stripePaymentIntentId idempotency, which
217214
// is the contract that prevents double-credit on retry.
@@ -221,43 +218,45 @@ const creditsLedger: Array<{
221218
stripePaymentIntentId: string | undefined;
222219
}> = [];
223220

224-
if (SUPPORTS_VITEST_MOCK_API) vi.mock("../credits", () => ({
225-
creditsService: {
226-
async addCredits(params: {
227-
organizationId: string;
228-
amount: number;
229-
description: string;
230-
stripePaymentIntentId?: string;
231-
metadata?: Record<string, unknown>;
232-
}) {
233-
if (params.stripePaymentIntentId) {
234-
const existing = creditsLedger.find(
235-
(l) => l.stripePaymentIntentId === params.stripePaymentIntentId,
236-
);
237-
if (existing) {
238-
return { transaction: { id: "existing" }, newBalance: 0 };
221+
if (SUPPORTS_VITEST_MOCK_API)
222+
vi.mock("../credits", () => ({
223+
creditsService: {
224+
async addCredits(params: {
225+
organizationId: string;
226+
amount: number;
227+
description: string;
228+
stripePaymentIntentId?: string;
229+
metadata?: Record<string, unknown>;
230+
}) {
231+
if (params.stripePaymentIntentId) {
232+
const existing = creditsLedger.find(
233+
(l) => l.stripePaymentIntentId === params.stripePaymentIntentId,
234+
);
235+
if (existing) {
236+
return { transaction: { id: "existing" }, newBalance: 0 };
237+
}
239238
}
240-
}
241-
creditsLedger.push({
242-
organizationId: params.organizationId,
243-
amount: params.amount,
244-
stripePaymentIntentId: params.stripePaymentIntentId,
245-
});
246-
return { transaction: { id: "new" }, newBalance: params.amount };
239+
creditsLedger.push({
240+
organizationId: params.organizationId,
241+
amount: params.amount,
242+
stripePaymentIntentId: params.stripePaymentIntentId,
243+
});
244+
return { transaction: { id: "new" }, newBalance: params.amount };
245+
},
247246
},
248-
},
249-
}));
247+
}));
250248

251-
if (SUPPORTS_VITEST_MOCK_API) vi.mock("../invoices", () => ({
252-
invoicesService: {
253-
async getByStripeInvoiceId() {
254-
return undefined;
255-
},
256-
async create() {
257-
return { id: "invoice-stub" };
249+
if (SUPPORTS_VITEST_MOCK_API)
250+
vi.mock("../invoices", () => ({
251+
invoicesService: {
252+
async getByStripeInvoiceId() {
253+
return undefined;
254+
},
255+
async create() {
256+
return { id: "invoice-stub" };
257+
},
258258
},
259-
},
260-
}));
259+
}));
261260

262261
// ---------------------------------------------------------------------------
263262
// Test harness

0 commit comments

Comments
 (0)