Initial commit: Brachnha Insight project setup
- Next.js 14+ with App Router and TypeScript - Tailwind CSS and ShadCN UI styling - Zustand state management - Dexie.js for IndexedDB (local-first data) - Auth.js v5 for authentication - BMAD framework integration Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
79
tests/integration/offline-action-queueing.test.ts
Normal file
79
tests/integration/offline-action-queueing.test.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
import { expect } from '@playwright/test';
|
||||
import { test } from '../support/fixtures/offline.fixture';
|
||||
|
||||
test.describe('Offline Action Queueing', () => {
|
||||
test('should enqueue SAVE_DRAFT action when offline', async ({ offlineControl, page }) => {
|
||||
// GIVEN: App is loaded
|
||||
await page.goto('/');
|
||||
await page.waitForFunction(() => (window as any).db !== undefined && (window as any).DraftService !== undefined, { timeout: 10000 });
|
||||
|
||||
// GIVEN: App goes offline
|
||||
await offlineControl.goOffline(page.context());
|
||||
|
||||
// WHEN: DraftService.saveDraft is called (Service Integration)
|
||||
await page.evaluate(async () => {
|
||||
// @ts-ignore
|
||||
await window.DraftService.saveDraft({
|
||||
title: 'Offline Draft',
|
||||
content: 'Content written offline',
|
||||
tags: [],
|
||||
createdAt: Date.now(),
|
||||
status: 'draft',
|
||||
sessionId: 'test-session'
|
||||
});
|
||||
});
|
||||
|
||||
// THEN: 'syncQueue' table has 1 item
|
||||
const queueCount = await page.evaluate(async () => {
|
||||
// @ts-ignore
|
||||
return await window.db.syncQueue.count();
|
||||
});
|
||||
|
||||
expect(queueCount).toBe(1);
|
||||
|
||||
const firstItem = await page.evaluate(async () => {
|
||||
// @ts-ignore
|
||||
return await window.db.syncQueue.orderBy('createdAt').first();
|
||||
});
|
||||
expect(firstItem.action).toBe('saveDraft');
|
||||
expect(firstItem.payload.draftData.title).toBe('Offline Draft');
|
||||
});
|
||||
|
||||
test('should enqueue DELETE_ENTRY action when offline', async ({ offlineControl, page }) => {
|
||||
// GIVEN: App is loaded and has an entry
|
||||
await page.goto('/');
|
||||
await page.waitForFunction(() => (window as any).db !== undefined && (window as any).DraftService !== undefined, { timeout: 10000 });
|
||||
|
||||
// Setup entry
|
||||
const draftId = await page.evaluate(async () => {
|
||||
// @ts-ignore
|
||||
const id = await window.db.drafts.add({
|
||||
title: 'To Delete',
|
||||
content: 'Delete me',
|
||||
tags: [],
|
||||
createdAt: Date.now(),
|
||||
status: 'draft',
|
||||
sessionId: 'test-session'
|
||||
});
|
||||
return id;
|
||||
});
|
||||
|
||||
await offlineControl.goOffline(page.context());
|
||||
|
||||
// WHEN: DraftService.deleteDraft is called
|
||||
await page.evaluate(async (id) => {
|
||||
// @ts-ignore
|
||||
await window.DraftService.deleteDraft(id);
|
||||
}, draftId);
|
||||
|
||||
// THEN: SyncQueue has delete action
|
||||
const lastItem = await page.evaluate(async () => {
|
||||
// @ts-ignore
|
||||
return await window.db.syncQueue.orderBy('createdAt').last();
|
||||
});
|
||||
|
||||
expect(lastItem.action).toBe('deleteDraft');
|
||||
expect(lastItem.payload.draftId).toBe(draftId);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user