Skip to content
Open
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
4 changes: 4 additions & 0 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,7 @@ jobs:
env:
DATABASE_URL: "file:./test.db"
run: npm test

- name: Cleanup test artifacts
if: always()
run: rm -rf coverage logs test.db* migration-status.md
4 changes: 4 additions & 0 deletions .github/workflows/dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,7 @@ jobs:

- name: Run browser smoke test
run: npm run test:browser -w dashboard -- --project=${{ matrix.browser }}

- name: Cleanup test artifacts
if: always()
run: rm -rf dashboard/test-results
4 changes: 4 additions & 0 deletions .github/workflows/migration-integrity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ jobs:
core.warning(`Unable to comment migration report on PR: ${error.message}`);
}

- name: Cleanup test artifacts
if: always()
run: rm -f backend/migrate-status.txt backend/migration-report.md

staging-migration-test:
name: Test Migration on Staging Clone
runs-on: ubuntu-latest
Expand Down
3 changes: 0 additions & 3 deletions backend/src/api/controllers/sep12.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ type UploadedFiles = { [fieldname: string]: Array<{ path: string }> };
const ALLOWED_CONTENT_TYPES = (process.env.UPLOAD_ALLOWED_CONTENT_TYPES ?? 'image/jpeg,image/png,application/pdf').split(',');
const UPLOAD_URL_EXPIRY_SECONDS = parseInt(process.env.UPLOAD_URL_EXPIRY_SECONDS ?? '900', 10);
const KEY_PREFIX = process.env.STORAGE_KEY_PREFIX ?? 'kyc';

type UploadedFiles = { [fieldname: string]: Array<{ path: string }> };

const pack = (enc?: { encryptedData: string; iv: string } | null) =>
enc ? `${enc.iv}|${enc.encryptedData}` : null;

Expand Down
3 changes: 2 additions & 1 deletion backend/src/api/routes/queue-dashboard.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const queues = Object.values(QUEUE_NAMES).map(
(name) => new BullMQAdapter(new Queue(name, { connection: queueConnection }))
);

createBullBoard({ queues, serverAdapter });
// eslint-disable-next-line @typescript-eslint/no-explicit-any
createBullBoard({ queues: queues as any, serverAdapter });

const router = Router();
router.use('/', serverAdapter.getRouter());
Expand Down
1 change: 1 addition & 0 deletions backend/src/lib/redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const redis = isTest
set: createNoop<(key: string, value: string) => Promise<'OK'>>(Promise.resolve('OK')),
del: createNoop<(key: string) => Promise<number>>(Promise.resolve(1)),
publish: createNoop<(channel: string, message: string) => Promise<number>>(Promise.resolve(1)),
ping: createNoop<() => Promise<string>>(Promise.resolve('PONG')),
} as any)


Expand Down
33 changes: 33 additions & 0 deletions backend/src/services/storage-provider.service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MockStorageProvider, storageProvider } from './storage-provider.service';

describe('storage-provider.service', () => {
describe('MockStorageProvider', () => {
let mockProvider: MockStorageProvider;

beforeEach(() => {
mockProvider = new MockStorageProvider('test-mock-bucket');
});

it('should generate mock presigned URL', async () => {
const url = await mockProvider.generatePresignedPutUrl('test-key', 'image/png', 3600);
expect(url).toBe('https://test-mock-bucket.mock.storage/test-key?X-Mock-Signed=1');
});

it('should correctly check if object exists', async () => {
expect(await mockProvider.objectExists('test-key')).toBe(false);
mockProvider._markUploaded('test-key');
expect(await mockProvider.objectExists('test-key')).toBe(true);
});

it('should use default mock bucket name if not specified', () => {
const defaultProvider = new MockStorageProvider();
expect(defaultProvider).toBeDefined();
});
});

describe('default storageProvider instance', () => {
it('should be defined', () => {
expect(storageProvider).toBeDefined();
});
});
});
58 changes: 58 additions & 0 deletions backend/src/services/upload-store.service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { uploadStore } from './upload-store.service';

describe('uploadStore', () => {
beforeEach(() => {
// Clear in-memory maps or stale records if any
const recordsMap = (uploadStore as any).records;
if (recordsMap) {
recordsMap.clear();
}
});

it('should create and retrieve an upload record', () => {
const expiresAt = new Date(Date.now() + 60000);
const record = uploadStore.create(
'GD3...123',
'id_front',
'kyc/GD3...123/id_front/1',
'image/png',
expiresAt
);

expect(record.uploadId).toBeDefined();
expect(record.status).toBe('PENDING');
expect(record.account).toBe('GD3...123');

const fetched = uploadStore.get(record.uploadId);
expect(fetched).toEqual(record);
});

it('should set the status of a record', () => {
const expiresAt = new Date(Date.now() + 60000);
const record = uploadStore.create(
'GD3...123',
'id_front',
'kyc/GD3...123/id_front/1',
'image/png',
expiresAt
);

uploadStore.setStatus(record.uploadId, 'COMPLETED');
expect(uploadStore.get(record.uploadId)?.status).toBe('COMPLETED');
});

it('should expire stale records', () => {
const pastDate = new Date(Date.now() - 10000);
const record = uploadStore.create(
'GD3...123',
'id_front',
'kyc/GD3...123/id_front/1',
'image/png',
pastDate
);

const expiredCount = uploadStore.expireStale();
expect(expiredCount).toBe(1);
expect(uploadStore.get(record.uploadId)?.status).toBe('EXPIRED');
});
});
1 change: 0 additions & 1 deletion dashboard/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ const SEP24Flow = lazy(() => import('./components/SEP24Flow'));
const KycStatusView = lazy(() => import('./components/KycStatusView'));
const NotificationCenter = lazy(() => import('./components/NotificationCenter'));
const NotificationPreferences = lazy(() => import('./components/NotificationPreferences'));
const AdminControls = lazy(() => import('./components/AdminControls'));
const Sep38QuotePanel = lazy(() => import('./components/Sep38QuotePanel'));
const ServiceStatusPanel = lazy(() => import('./components/ServiceStatusPanel'));
const SettingsView = lazy(() => import('./components/SettingsView'));
Expand Down
2 changes: 1 addition & 1 deletion dashboard/tests/browser/cross-browser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test.describe('dashboard cross-browser smoke coverage', () => {
await expect(page.getByTestId('active-view')).toContainText('Preview State');
await expect(page.getByTestId('active-view')).toContainText('Verification Failed');

await page.getByRole('button', { name: 'Overview' }).click();
await page.getByRole('button', { name: 'Overview' }).click({ force: true });
await expect(page.getByTestId('active-view')).toContainText('Total Volume');
});
});
Loading