Skip to content

Commit

Permalink
Add AttachmentQueue tests
Browse files Browse the repository at this point in the history
  • Loading branch information
HeinrichvonStein committed Dec 3, 2024
1 parent 5cd0ae0 commit 32f4ddb
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 31 deletions.
17 changes: 16 additions & 1 deletion packages/attachments/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,24 @@
"build": "tsc -b",
"build:prod": "tsc -b --sourceMap false",
"clean": "rm -rf lib tsconfig.tsbuildinfo",
"watch": "tsc -b -w"
"watch": "tsc -b -w",
"test": "pnpm build && vitest"
},
"peerDependencies": {
"@powersync/common": "workspace:^1.18.1"
},
"devDependencies": {
"@powersync/web": "workspace:*",
"@journeyapps/wa-sqlite": "^1.0.0",
"@types/node": "^20.17.6",
"@vitest/browser": "^2.1.4",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
"typescript": "^5.6.3",
"vite": "^5.4.10",
"vite-plugin-top-level-await": "^1.4.4",
"vite-plugin-wasm": "^3.3.0",
"vitest": "^2.1.4",
"webdriverio": "^9.2.8"
}
}
5 changes: 4 additions & 1 deletion packages/attachments/src/AbstractAttachmentQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,9 @@ export abstract class AbstractAttachmentQueue<T extends AttachmentQueueOptions =
}

async downloadRecord(record: AttachmentRecord) {
if (!this.options.downloadAttachments) {
return false;
}
if (!record.local_uri) {
record.local_uri = this.getLocalFilePathSuffix(record.filename);
}
Expand Down Expand Up @@ -442,7 +445,7 @@ export abstract class AbstractAttachmentQueue<T extends AttachmentQueueOptions =
}

private async downloadRecords() {
if (this.options.downloadAttachments) {
if (!this.options.downloadAttachments) {
return;
}
if (this.downloading) {
Expand Down
95 changes: 95 additions & 0 deletions packages/attachments/tests/attachments/AttachmentQueue.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as commonSdk from '@powersync/common';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { AbstractAttachmentQueue } from '../../src/AbstractAttachmentQueue';
import { AttachmentRecord, AttachmentState } from '../../src/Schema';
import { AbstractPowerSyncDatabase } from '@powersync/common';
import { StorageAdapter } from '../../src/StorageAdapter';

const record = {
id: 'test-1',
filename: 'test.jpg',
state: AttachmentState.QUEUED_DOWNLOAD
}

const mockPowerSync = {
currentStatus: { status: 'initial' },
registerListener: vi.fn(() => {}),
resolveTables: vi.fn(() => ['table1', 'table2']),
onChangeWithCallback: vi.fn(),
getAll: vi.fn(() => Promise.resolve([{id: 'test-1'}, {id: 'test-2'}])),
execute: vi.fn(() => Promise.resolve()),
getOptional: vi.fn((_query, params) => Promise.resolve(record)),
watch: vi.fn((query, params, callbacks) => {
callbacks?.onResult?.({ rows: { _array: [{id: 'test-1'}, {id: 'test-2'}] } });
}),
writeTransaction: vi.fn(async (callback) => {
await callback({
execute: vi.fn(() => Promise.resolve())
});
})
};

const mockStorage: StorageAdapter = {
downloadFile: vi.fn(),
uploadFile: vi.fn(),
deleteFile: vi.fn(),
writeFile: vi.fn(),
readFile: vi.fn(),
fileExists: vi.fn(),
makeDir: vi.fn(),
copyFile: vi.fn(),
getUserStorageDirectory: vi.fn()
};

class TestAttachmentQueue extends AbstractAttachmentQueue {
onAttachmentIdsChange(onUpdate: (ids: string[]) => void): void {
throw new Error('Method not implemented.');
}
newAttachmentRecord(record?: Partial<AttachmentRecord>): Promise<AttachmentRecord> {
throw new Error('Method not implemented.');
}
}

describe('attachments', () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('should not download attachments when downloadRecord is called with downloadAttachments false', async () => {
const queue = new TestAttachmentQueue({
powersync: mockPowerSync as any,
storage: mockStorage,
downloadAttachments: false
});

await queue.downloadRecord(record);

expect(mockStorage.downloadFile).not.toHaveBeenCalled();
});

it('should download attachments when downloadRecord is called with downloadAttachments true', async () => {
const queue = new TestAttachmentQueue({
powersync: mockPowerSync as any,
storage: mockStorage,
downloadAttachments: true
});

await queue.downloadRecord(record);

expect(mockStorage.downloadFile).toHaveBeenCalled();
});

// Testing the inverse of this test, i.e. when downloadAttachments is false, is not required as you can't wait for something that does not happen
it('should not download attachments with watchDownloads is called with downloadAttachments false', async () => {
const queue = new TestAttachmentQueue({
powersync: mockPowerSync as any,
storage: mockStorage,
downloadAttachments: true
});

queue.watchDownloads();
await vi.waitFor(() => {
expect(mockStorage.downloadFile).toBeCalledTimes(2);
});
});
});
29 changes: 29 additions & 0 deletions packages/attachments/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import wasm from 'vite-plugin-wasm';
import topLevelAwait from 'vite-plugin-top-level-await';
import { defineConfig, UserConfigExport } from 'vitest/config';

const config: UserConfigExport = {
worker: {
format: 'es',
plugins: () => [wasm(), topLevelAwait()]
},
optimizeDeps: {
// Don't optimise these packages as they contain web workers and WASM files.
// https://github.com/vitejs/vite/issues/11672#issuecomment-1415820673
exclude: ['@journeyapps/wa-sqlite', '@powersync/web']
},
plugins: [wasm(), topLevelAwait()],
test: {
isolate: false,
globals: true,
include: ['tests/**/*.test.ts'],
browser: {
enabled: true,
headless: true,
provider: 'webdriverio',
name: 'chrome' // browser name is required
}
}
};

export default defineConfig(config);
Loading

0 comments on commit 32f4ddb

Please sign in to comment.