test: Add comprehensive unit tests and CI workflow - #65
Conversation
- Set up Jest testing framework with TypeScript support - Add fake-indexeddb for database testing - Add test polyfills for TextEncoder, crypto.subtle, and structuredClone - Create comprehensive test suites: - utils/index.test.ts: 20 tests for hashing and URL utilities - database/index.test.ts: 26 tests for IndexedDB operations - export/zipExport.test.ts: 13 tests for ZIP export functionality - Add GitHub Actions workflow to run tests on CI - All 59 tests passing with coverage Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: minorcell <120795714+minorcell@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - name: Setup pnpm | ||
| uses: pnpm/action-setup@v2 | ||
| with: | ||
| version: 8 | ||
|
|
||
| - name: Get pnpm store directory | ||
| id: pnpm-cache | ||
| shell: bash | ||
| run: | | ||
| echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Setup pnpm cache | ||
| uses: actions/cache@v3 | ||
| with: | ||
| path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} | ||
| key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-pnpm-store- | ||
|
|
||
| - name: Install dependencies | ||
| run: pnpm install --frozen-lockfile | ||
|
|
There was a problem hiding this comment.
Keep pnpm lockfile in sync with new workflow step
The new CI job installs dependencies using pnpm install --frozen-lockfile (lines 26‑47), but this same commit also added new Jest dependencies and scripts to package.json without updating pnpm-lock.yaml. When pnpm runs with --frozen-lockfile and the lockfile is out of sync with package.json, it aborts with “Cannot install with frozen lockfile because pnpm-lock.yaml is not up to date,” so this workflow never reaches the test steps. Please update the pnpm lockfile (or drop the frozen flag) so the CI job introduced here can actually execute.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Summary
- Updated
pnpm-lock.yamlto capture the new testing-related dependencies (@testing-library/*,@types/jest,fake-indexeddb,jest,jest-environment-jsdom,ts-jest, etc.), ensuring the CI workflow can runpnpm install --frozen-lockfilewithout aborting. pnpm-lock.yamlL41-L80
Testing
⚠️ Not run (not requested)
|
|
||
| // Polyfill structuredClone for Node < 17 | ||
| if (typeof global.structuredClone === 'undefined') { | ||
| global.structuredClone = (obj: any) => JSON.parse(JSON.stringify(obj)) |
There was a problem hiding this comment.
Security Issue: Unsafe structuredClone polyfill
This polyfill has several critical issues:
- Cannot handle circular references (will throw)
- Loses functions, Symbols, and other non-JSON-serializable values
- Doesn't match the real
structuredClonebehavior
This could mask production bugs that only appear in Node 17+. Consider using a proper polyfill library like core-js-pure or at minimum add validation:
if (typeof global.structuredClone === 'undefined') {
global.structuredClone = (value: any) => {
try {
return JSON.parse(JSON.stringify(value))
} catch (e) {
throw new Error(`structuredClone polyfill failed: ${e.message}`)
}
}
}| run: pnpm install --frozen-lockfile | ||
|
|
||
| - name: Run tests | ||
| run: pnpm test |
There was a problem hiding this comment.
Performance Issue: Redundant test execution
This workflow runs tests twice:
- Line 49:
pnpm test - Line 52:
pnpm test:coverage
The second run repeats all tests with coverage instrumentation. Consider running tests only once:
- name: Run tests with coverage
run: pnpm test:coverage
if: matrix.node-version == '20.x'
- name: Run tests (no coverage)
run: pnpm test
if: matrix.node-version == '18.x'This would reduce CI time by ~50% for the Node 20.x job.
| } from './index' | ||
|
|
||
| // Helper to create a test item | ||
| const createTestItem = (overrides: Partial<Item> = {}): Item => ({ |
There was a problem hiding this comment.
Code Quality: Duplicate helper function
The createTestItem helper is duplicated in both database/index.test.ts and export/zipExport.test.ts with identical implementations. Consider extracting to a shared file:
// src/test/helpers.ts
export const createTestItem = (overrides: Partial<Item> = {}): Item => ({
id: `item-${Date.now()}-${Math.random()}`,
type: 'text',
content: 'Test content',
source: {
title: 'Test Page',
url: 'https://example.com/test',
site: 'example.com'
},
createdAt: Date.now(),
...overrides
})This improves maintainability if the Item type changes.
| describe('searchItems', () => { | ||
| beforeEach(async () => { | ||
| // Set up test data | ||
| await addItem(createTestItem({ |
There was a problem hiding this comment.
Performance Issue: Inefficient test setup
This beforeEach hook runs for all 8 tests in the searchItems suite, performing 24 database operations total (8 tests × 3 items).
Consider using beforeAll instead since these tests only read data:
beforeAll(async () => {
await addItem(createTestItem({ /* ... */ }))
await addItem(createTestItem({ /* ... */ }))
await addItem(createTestItem({ /* ... */ }))
})This reduces database operations by 87% (from 24 to 3).
| await addItem(createTestItem({ | ||
| id: 'image1', | ||
| type: 'image', | ||
| content: 'data:image/png;base64,xyz', |
There was a problem hiding this comment.
Security Issue: Invalid base64 test data
The value 'xyz' is not valid base64. While this test doesn't exercise the export path, having invalid data could mask bugs. If this ever reaches dataUrlToBlob() in zipExport.ts, it would silently produce corrupted data.
Use a valid base64 image:
const validBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=='
content: `data:image/png;base64,${validBase64}`,| describe('database', () => { | ||
| beforeEach(() => { | ||
| // Clear IndexedDB before each test | ||
| indexedDB = new IDBFactory() |
There was a problem hiding this comment.
Performance Issue: Full database reinitialization
Resetting the entire IDBFactory for every test is expensive. With 26 database tests, this creates significant overhead.
Consider clearing only the data instead:
beforeEach(async () => {
// Clear data without recreating the entire database
const db = await openDb()
const tx = db.transaction(['items', 'categories'], 'readwrite')
tx.objectStore('items').clear()
tx.objectStore('categories').clear()
db.close()
})This preserves the database schema and indexes, reducing setup time.
Code Review SummaryExcellent work on adding comprehensive test coverage! The test suite is well-organized with clear naming and good coverage of edge cases. The CI workflow follows best practices with matrix testing and caching. Key Issues to Address:
Strengths:
All issues have inline comments with specific solutions. Great foundation for the project's testing infrastructure! |
|
@codercellone 修复这个问题: P1 Badge Keep pnpm lockfile in sync with new workflow step The new CI job installs dependencies using pnpm install --frozen-lockfile (lines 26‑47), but this same commit also added new Jest dependencies and scripts to package.json without updating pnpm-lock.yaml. When pnpm runs with --frozen-lockfile and the lockfile is out of sync with package.json, it aborts with “Cannot install with frozen lockfile because pnpm-lock.yaml is not up to date,” so this workflow never reaches the test steps. Please update the pnpm lockfile (or drop the frozen flag) so the CI job introduced here can actually execute. |
Requested by @minorcell
Resolves #64
Summary
Added comprehensive unit test coverage for the Pick Quote extension and integrated automated testing into the CI pipeline.
Test Coverage
Utils Module (20 tests)
Database Module (26 tests)
Export Module (13 tests)
Infrastructure
Test Results
Test plan
Generated with codeagent
Co-authored-by: minorcell 120795714+minorcell@users.noreply.github.com