Skip to content

Commit 8b34596

Browse files
authored
Merge branch 'main' into feat/task-filtering
2 parents 28f61b4 + 6ae051a commit 8b34596

5 files changed

Lines changed: 66 additions & 59 deletions

File tree

src/components/VoteButton/__tests__/VoteButton.test.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ jest.mock('@/services/contractClient', () => ({
1111
jest.mock('@/context/RoleContext', () => ({
1212
useRole: jest.fn(),
1313
}));
14-
jest.mock('@/context/NetworkContext', () => ({
15-
useNetwork: jest.fn(),
16-
}));
1714
jest.mock('@/components/Toast');
1815
jest.mock('@/utils/logger', () => ({
1916
appendAuditEvent: jest.fn(() => Promise.resolve()),
@@ -39,6 +36,7 @@ import { useNetwork } from '@/context/NetworkContext';
3936
const mockCastVote = castVote as jest.MockedFunction<typeof castVote>;
4037
const mockUseRole = useRole as jest.MockedFunction<typeof useRole>;
4138
const mockUseToast = useToast as jest.MockedFunction<typeof useToast>;
39+
const mockUseNetwork = useNetwork as jest.MockedFunction<typeof useNetwork>;
4240
const mockShowToast = jest.fn();
4341
const mockRefreshRole = jest.fn();
4442

src/services/__tests__/txBuilder.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,10 @@ describe('BatchTransactionBuilder (Soroban)', () => {
275275
async (_tx: StellarSdk.Transaction | StellarSdk.FeeBumpTransaction) => ({
276276
id: '1',
277277
latestLedger: 100,
278-
transactionData: new StellarSdk.SorobanDataBuilder(),
278+
transactionData: new StellarSdk.SorobanDataBuilder().build(),
279279
minResourceFee: '100',
280280
cost: { cpuInsns: '0', memBytes: '0' },
281+
results: [{ auth: [], xdr: 'AAAAAQ==' }],
281282
} as unknown as StellarSdk.SorobanRpc.Api.SimulateTransactionResponse),
282283
),
283284
sendTransaction: jest.fn(

src/tests/wallet-multiprovider.test.tsx

Lines changed: 45 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,30 @@ import React from 'react';
22
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
33
import { WalletProvider, useWallet } from '@/context/WalletContext';
44

5+
jest.mock('@/auth/session', () => {
6+
const store: Record<string, string> = {};
7+
return {
8+
setSessionItem: jest.fn(async (key: string, value: string) => {
9+
store[key] = value;
10+
try { localStorage.setItem(key, value); } catch {}
11+
}),
12+
getSessionItem: jest.fn(async (key: string) => store[key] ?? null),
13+
sessionManager: {
14+
subscribe: jest.fn(() => jest.fn()),
15+
startMonitoring: jest.fn(),
16+
stopMonitoring: jest.fn(),
17+
},
18+
};
19+
});
20+
521
jest.mock('@stellar/freighter-api', () => ({
622
isConnected: jest.fn().mockResolvedValue({ isConnected: false }),
723
getAddress: jest.fn(),
824
requestAccess: jest.fn(),
9-
WatchWalletChanges: jest.fn(),
25+
WatchWalletChanges: jest.fn(() => ({ watch: jest.fn(() => ({})), stop: jest.fn() })),
1026
getPublicKey: jest.fn(),
1127
}));
28+
1229
jest.mock('@/lib/stellar-interact', () => ({
1330
getReputation: jest.fn(async () => 0),
1431
}));
@@ -26,76 +43,51 @@ const STORAGE_KEY = 'vero_wallet_publicKey';
2643
const PROVIDER_STORAGE_KEY = 'vero_wallet_provider';
2744

2845
type TestWindow = {
29-
freighter?: unknown;
3046
rabet?: { connect: jest.Mock };
3147
};
32-
const testWindow = window as unknown as TestWindow;
33-
34-
function Consumer() {
35-
const { publicKey, activeProvider, availableProviders, error, isLoading, connect } = useWallet();
36-
return (
37-
<div>
38-
<div data-testid="pk">{publicKey || 'none'}</div>
39-
<div data-testid="provider">{activeProvider || 'none'}</div>
40-
<div data-testid="available">
41-
{availableProviders.map((provider) => `${provider.id}:${provider.isAvailable}`).join(',')}
42-
</div>
43-
<div data-testid="error">{error || 'none'}</div>
44-
<div data-testid="loading">{isLoading ? 'loading' : 'ready'}</div>
45-
<button data-testid="connect-rabet" onClick={() => connect('rabet')}>
46-
rabet
47-
</button>
48-
</div>
49-
);
50-
}
51-
52-
function renderConsumer() {
53-
return render(
54-
<WalletProvider>
55-
<Consumer />
56-
</WalletProvider>
57-
);
58-
}
5948

6049
describe('WalletContext multi-provider support', () => {
50+
const testWindow = window as unknown as TestWindow;
51+
6152
beforeEach(() => {
6253
localStorage.clear();
63-
testWindow.freighter = undefined;
64-
testWindow.rabet = undefined;
6554
});
6655

67-
it('lists detected providers and their availability', async () => {
68-
testWindow.rabet = { connect: jest.fn() };
69-
renderConsumer();
70-
71-
await waitFor(() => expect(screen.getByTestId('loading')).toHaveTextContent('ready'));
72-
expect(screen.getByTestId('available')).toHaveTextContent('freighter:false,rabet:true');
56+
afterEach(() => {
57+
delete testWindow.rabet;
7358
});
7459

60+
function TestComponent() {
61+
const { publicKey, isConnected, activeProvider, connect, isLoading } = useWallet();
62+
return (
63+
<div>
64+
<div data-testid="pk">{publicKey}</div>
65+
<div data-testid="connected">{isConnected ? 'Connected' : 'Disconnected'}</div>
66+
<div data-testid="provider">{activeProvider ?? 'none'}</div>
67+
<div data-testid="loading">{isLoading ? 'loading' : 'ready'}</div>
68+
<button data-testid="connect-btn" onClick={() => connect('rabet')}>
69+
Connect Rabet
70+
</button>
71+
</div>
72+
);
73+
}
74+
7575
it('connects through Rabet and persists the active provider', async () => {
7676
testWindow.rabet = { connect: jest.fn().mockResolvedValue({ publicKey: RABET_KEY }) };
77-
renderConsumer();
77+
78+
render(
79+
<WalletProvider>
80+
<TestComponent />
81+
</WalletProvider>
82+
);
7883

7984
await waitFor(() => expect(screen.getByTestId('loading')).toHaveTextContent('ready'));
80-
fireEvent.click(screen.getByTestId('connect-rabet'));
85+
86+
fireEvent.click(screen.getByTestId('connect-btn'));
8187

8288
await waitFor(() => expect(screen.getByTestId('pk')).toHaveTextContent(RABET_KEY));
8389
expect(screen.getByTestId('provider')).toHaveTextContent('rabet');
8490
expect(localStorage.getItem(STORAGE_KEY)).toBe(RABET_KEY);
8591
expect(localStorage.getItem(PROVIDER_STORAGE_KEY)).toBe('rabet');
8692
});
87-
88-
it('surfaces an error when the selected wallet is not installed', async () => {
89-
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
90-
renderConsumer();
91-
92-
await waitFor(() => expect(screen.getByTestId('loading')).toHaveTextContent('ready'));
93-
fireEvent.click(screen.getByTestId('connect-rabet'));
94-
95-
await waitFor(() =>
96-
expect(screen.getByTestId('error')).toHaveTextContent('Rabet wallet is not installed')
97-
);
98-
expect(screen.getByTestId('provider')).toHaveTextContent('none');
99-
consoleSpy.mockRestore();
100-
});
10193
});

src/tests/wallet.test.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ import React from 'react';
22
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
33
import { WalletProvider, useWallet } from '@/context/WalletContext';
44

5+
jest.mock('@/auth/session', () => {
6+
const store: Record<string, string> = {};
7+
return {
8+
setSessionItem: jest.fn(async (key: string, value: string) => {
9+
store[key] = value;
10+
try { localStorage.setItem(key, value); } catch {}
11+
}),
12+
getSessionItem: jest.fn(async (key: string) => store[key] ?? null),
13+
sessionManager: {
14+
subscribe: jest.fn(() => jest.fn()),
15+
startMonitoring: jest.fn(),
16+
stopMonitoring: jest.fn(),
17+
},
18+
};
19+
});
20+
521
jest.mock('@stellar/freighter-api', () => ({
622
isConnected: jest.fn(),
723
getAddress: jest.fn(),

src/utils/logger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,8 @@ async function decryptRecord(
456456
key: CryptoKey,
457457
record: EncryptedAuditLogRecord,
458458
): Promise<AuditLogEvent> {
459-
const iv = bytesToArrayBuffer(base64ToBytes(record.iv));
460-
const ciphertext = bytesToArrayBuffer(base64ToBytes(record.ciphertext));
459+
const iv = base64ToBytes(record.iv);
460+
const ciphertext = base64ToBytes(record.ciphertext);
461461
const decrypted = await cryptoProvider.subtle.decrypt(
462462
{ name: 'AES-GCM', iv },
463463
key,

0 commit comments

Comments
 (0)