feat: add CI test workflow and timezone audit for chart utils#10
feat: add CI test workflow and timezone audit for chart utils#10
Conversation
- Add test.yml workflow to run Jest tests on PRs and pushes to main - Remove preview.yml (replaced by test workflow) - Add timezone handling consistency tests for chart aggregation - Use isSameDay for single-day detection per CodeRabbit feedback - Document timezone conversion flow in test file comments
📝 WalkthroughWalkthroughUpdates CI workflow and test step; tightens calendar-day logic in chart aggregation and adds timezone-consistency tests; broad test refactors and mocks across POS and database packages; refactors populate internals; removes RxDB validation plugins (z-schema & AJV); adjusts Jest mappings and removes react-hooks test dependency. Changes
Sequence Diagram(s)(Skipped — changes are primarily tests, refactors, and removals without a new multi-component runtime control flow that requires visualization.) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Add Record<string, any> type to data objects for dynamic property access - Add missing jsonSchema.properties to mock collection schemas - Add test for meta_data population behavior
- Fix populate.test.ts TypeScript type errors with proper type assertions - Fix populate.ts TypeScript error in populateResource function - Replace ESM-only imports (faker, uuid, randomCouchString) with rxdb's randomToken - Simplify nested-collection helper to match working query tests pattern - Update products-collection helper with same fixes
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/database/src/tests/helpers/nested-collection.ts`:
- Around line 33-34: The test helper in nested-collection.ts uses
randomToken(36) for the uuid field; change it to use the UUID v4 helper to match
other test helpers (like product-schemas.ts). Import the v4 function from the
'uuid' package (use the same import style used in product-schemas.ts, e.g. v4 as
uuidv4) and replace the default uuid value (uuid: string = randomToken(36)) with
uuid: string = uuidv4(); also remove the randomToken import if it becomes
unused.
🧹 Nitpick comments (5)
packages/database/src/plugins/populate.ts (1)
196-202: Consider adding a typed interface for the extended document.The
as anycast is functional but violates the coding guideline to avoidany. While RxDB plugin patterns often require dynamic property access, you could improve type safety with an interface.♻️ Suggested type-safe approach
+// At the top of the file or in a types file +interface PopulatedRxDocument extends RxDocument { + [key: `${string}Resource`]: ObservableResource<RxDocument[]>; + populate$: (key: string) => Observable<RxDocument[]>; +} + /** */ proto.populateResource = function (this: RxDocument, key: string) { - const self = this as any; + const self = this as PopulatedRxDocument; if (!self[key + 'Resource']) { - self[key + 'Resource'] = new ObservableResource(self.populate$(key)); + (self as any)[key + 'Resource'] = new ObservableResource(self.populate$(key)); } return self[key + 'Resource']; };Note: The assignment still requires
as anydue to TypeScript's limitations with template literal index signatures during assignment, but reading is type-safe.packages/database/src/tests/helpers/nested-collection.ts (2)
42-47: Inconsistent database naming strategy withproducts-collection.ts.This file uses
Date.now()for unique names whileproducts-collection.tsusesrandomToken(10). For consistency and to avoid potential collisions in parallel test runs on the same millisecond, consider using the same approach.♻️ Align with products-collection.ts approach
-/** - * Generate a unique database name - */ -function generateUniqueDbName(baseName: string): string { - return `${baseName}_${Date.now()}`; -} - export async function create( size: number = 20, collectionName: string = 'nested', storage: RxStorage<any, object, object> = getRxStorageMemory() ): Promise<RxCollection<any, object, object>> { const db = await createRxDatabase({ - name: generateUniqueDbName('nesteddb'), + name: randomToken(10), storage, allowSlowCount: true, });Also applies to: 55-55
53-53: Return type usesany, losing type safety.The return type
RxCollection<any, object, object>is less strict thanproducts-collection.tswhich usesRxCollection<typeof productDefaultSchema, object, object>. Per coding guidelines, avoidanytypes.♻️ Use schema type for better type safety
export async function create( size: number = 20, collectionName: string = 'nested', storage: RxStorage<any, any> = getRxStorageMemory() -): Promise<RxCollection<any, object, object>> { +): Promise<RxCollection<typeof nestedDefaultSchema, object, object>> {packages/database/src/plugins/populate.test.ts (2)
7-18: Type definitions useanyand are incomplete.The
NestedDocinterface is missing properties from the schema (uuid,name) and usesanyin multiple places, which violates coding guidelines. A more complete interface would reduce the need foras unknown ascasts throughout the tests.♻️ Improve type definitions
// Type for collection with plugin methods type NestedCollection = Awaited<ReturnType<typeof create>> & { - upsertRefs: (data: any) => Promise<void>; - removeRefs: (data: any) => Promise<void>; + upsertRefs: (data: NestedData) => Promise<void>; + removeRefs: (data: NestedData) => Promise<void>; }; +// Base nested data shape +interface NestedData { + uuid: string; + name: string; + child?: (NestedData | string)[]; +} + // Type for document with plugin methods -interface NestedDoc { - child: string[]; - populate: (key: string) => Promise<NestedDoc[]>; - toPopulatedJSON: () => Promise<any>; -} +interface NestedDoc extends NestedData { + child: string[]; + populate: (key: string) => Promise<NestedDoc[]>; + toPopulatedJSON: () => Promise<NestedData>; +}
40-40: Multipleas unknown ascasts indicate type definition gaps.The repeated use of
as unknown as NestedDocis a code smell suggesting the types don't align well with RxDB's actual return types. Consider extending RxDB's document type properly or creating a utility type.♻️ Create a typed query helper
// Helper to reduce casting boilerplate async function findNestedDoc( collection: NestedCollection, id?: string ): Promise<NestedDoc | null> { const query = id ? collection.findOne(id) : collection.findOne(); return query.exec() as Promise<NestedDoc | null>; }Also applies to: 51-51, 66-66, 81-81
| uuid: string = randomToken(36), | ||
| name: string = `nested-${randomToken(6)}` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# 1. Read the file to understand context
echo "=== File content around lines 33-34 ==="
head -40 packages/database/src/tests/helpers/nested-collection.ts | tail -20
echo -e "\n=== Find randomToken function ==="
rg -n "function randomToken|const randomToken|export.*randomToken" -A 3 --type ts
echo -e "\n=== Find uuid schema definition ==="
rg -n "uuid.*maxLength|uuid.*max_length" --type ts -A 2 -B 2 | head -50
echo -e "\n=== Search for UUID validation patterns ==="
rg -n "uuid.*validate|validateUUID|isUUID|UUID.*regex|uuid.*pattern" --type ts | head -30Repository: wcpos/monorepo
Length of output: 507
🏁 Script executed:
#!/bin/bash
# Read entire file to see imports and schema
echo "=== Full file content ==="
cat -n packages/database/src/tests/helpers/nested-collection.ts
echo -e "\n=== Find randomToken import ==="
rg -n "import.*randomToken|from.*randomToken" --type ts
echo -e "\n=== Find randomToken definition anywhere ==="
rg -n "function randomToken|const randomToken = " --type ts -A 5Repository: wcpos/monorepo
Length of output: 2422
🏁 Script executed:
#!/bin/bash
# Check if there's any UUID format validation in the codebase
echo "=== Search for UUID format/pattern validation ==="
rg -n "uuid.*regex|uuid.*format|Pattern.*uuid|validate.*uuid" --type ts | head -20
echo -e "\n=== Check if schema validation enforces format ==="
rg -n "format.*uuid|pattern.*uuid" --type ts | head -20
echo -e "\n=== Look for actual UUID generation (standard format with hyphens) ==="
rg -n "uuid|UUID" --type ts -g '!*.test.ts' | grep -i "v4\|v1\|generate" | head -20
echo -e "\n=== Check RxDB schema validation in actual collections ==="
rg -n "primaryKey.*uuid|type.*string.*uuid" --type ts -A 3 | head -40Repository: wcpos/monorepo
Length of output: 4769
🏁 Script executed:
#!/bin/bash
# Check how product-schemas handles UUID generation for comparison
echo "=== product-schemas.ts UUID handling ==="
cat -n packages/database/src/tests/helpers/product-schemas.ts | head -50
echo -e "\n=== Check order-schema.ts UUID handling ==="
cat -n packages/database/src/tests/helpers/order-schema.ts | head -50Repository: wcpos/monorepo
Length of output: 1616
🏁 Script executed:
#!/bin/bash
# Check if order-schema has a generate function
echo "=== Check order-schema.ts for generate function ==="
cat -n packages/database/src/tests/helpers/order-schema.ts | tail -20Repository: wcpos/monorepo
Length of output: 525
Use uuidv4() instead of randomToken(36) for consistency with other test helpers.
Similar test helpers in the same directory (product-schemas.ts) use uuidv4() from the 'uuid' library for UUID generation. Update nested-collection.ts to follow the same pattern for consistency:
- import { randomToken } from 'rxdb/plugins/utils';
+ import { v4 as uuidv4 } from 'uuid';export const generateNested = (
- uuid: string = randomToken(36),
+ uuid: string = uuidv4(),
name: string = `nested-${randomToken(6)}`
) => {🤖 Prompt for AI Agents
In `@packages/database/src/tests/helpers/nested-collection.ts` around lines 33 -
34, The test helper in nested-collection.ts uses randomToken(36) for the uuid
field; change it to use the UUID v4 helper to match other test helpers (like
product-schemas.ts). Import the v4 function from the 'uuid' package (use the
same import style used in product-schemas.ts, e.g. v4 as uuidv4) and replace the
default uuid value (uuid: string = randomToken(36)) with uuid: string =
uuidv4(); also remove the randomToken import if it becomes unused.
- Fix mock paths to match actual module locations - Add uuid, @wcpos/utils/logger mocks for ESM module compatibility - Add moduleNameMapper for @wcpos/utils and @wcpos/database - Fix TypeScript scoping error in parsePosData (posData not in catch scope) - Simplify price update test assertions to check metadata updates
- Add logger mock to avoid __DEV__ not defined error - Add type assertion for mock customer object - Update shipping test expectation to include postcode field
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@packages/core/jest.config.js`:
- Around line 27-28: The Jest moduleNameMapper entry for '^@wcpos/database$'
only matches the exact package name and misses subpath imports; add a subpath
pattern similar to '^@wcpos/utils/(.*)$' to map '^@wcpos/database/(.*)$' to the
database src folder (use the same '<rootDir>/../database/src/$1' style) so
imports like '@wcpos/database/src' resolve correctly while keeping the existing
exact '^@wcpos/database$' mapping.
In `@packages/core/src/screens/main/pos/hooks/use-update-line-item.test.ts`:
- Around line 97-108: The test mock for useLineItemData is looking for the wrong
metadata key (_pos_data) which doesn't match production; update the
getLineItemData mock inside useLineItemData (the jest.mock block) to search for
'_woocommerce_pos_data' instead of '_pos_data' so the test mirrors real code
behavior and returns parsed JSON from that meta entry; keep the rest of the mock
behavior (default return object and function name getLineItemData) unchanged.
- Around line 49-55: The test mock in use-update-line-item.test.ts uses the
metadata key '_pos_data' but the assertion and production utils expect
'_woocommerce_pos_data'; update the mock metadata key from '_pos_data' to
'_woocommerce_pos_data' (and any other occurrences in that test file) so the
mocked meta_data array matches the assertion and the keys used by utils.ts.
🧹 Nitpick comments (1)
packages/core/src/screens/main/pos/hooks/use-update-line-item.test.ts (1)
76-95: Consider documenting the mock tax calculation.The mock uses a hardcoded 10% tax rate. A brief comment explaining this is intentional for predictable test assertions would help future maintainers.
Optional: Add clarifying comment
// Mock useCalculateLineItemTaxAndTotals jest.mock('./use-calculate-line-item-tax-and-totals', () => ({ useCalculateLineItemTaxAndTotals: () => ({ + // Mock uses fixed 10% tax rate for predictable test assertions calculateLineItemTaxesAndTotals: jest.fn().mockImplementation((lineItem) => { const quantity = lineItem.quantity ?? 1; const price = lineItem.price ?? 10;
| '^@wcpos/utils/(.*)$': '<rootDir>/../utils/src/$1', | ||
| '^@wcpos/database$': '<rootDir>/../database/src', |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether subpath imports exist for `@wcpos/database`
rg -n "@wcpos/database/" --type=ts --type=tsx --type=js --type=jsxRepository: wcpos/monorepo
Length of output: 85
🏁 Script executed:
#!/bin/bash
# Verify whether subpath imports exist for `@wcpos/database`
rg -n "@wcpos/database/" --type=ts --type=jsRepository: wcpos/monorepo
Length of output: 863
🏁 Script executed:
#!/bin/bash
# Search for all `@wcpos/database` imports to see the full pattern
rg -n "@wcpos/database" --type=ts --type=js | head -30
# Also check if there are other subpath patterns
rg -n "@wcpos/database/[^s]" --type=ts --type=jsRepository: wcpos/monorepo
Length of output: 3535
🏁 Script executed:
#!/bin/bash
# Read the jest.config.js file to verify current state
cat -n packages/core/jest.config.js | head -50Repository: wcpos/monorepo
Length of output: 1109
Add a subpath mapper for @wcpos/database to resolve subpath imports.
The mapper for @wcpos/database is exact-only and will fail to resolve subpath imports like @wcpos/database/src (found in packages/query). Add a subpath pattern to match the @wcpos/utils mapper style:
Required mapper extension
moduleNameMapper: {
'^expo-localization$': '<rootDir>/jest/__mocks__/expo-localization.js',
'^@wcpos/utils/(.*)$': '<rootDir>/../utils/src/$1',
'^@wcpos/database$': '<rootDir>/../database/src',
+ '^@wcpos/database/(.*)$': '<rootDir>/../database/src/$1',
},🤖 Prompt for AI Agents
In `@packages/core/jest.config.js` around lines 27 - 28, The Jest moduleNameMapper
entry for '^@wcpos/database$' only matches the exact package name and misses
subpath imports; add a subpath pattern similar to '^@wcpos/utils/(.*)$' to map
'^@wcpos/database/(.*)$' to the database src folder (use the same
'<rootDir>/../database/src/$1' style) so imports like '@wcpos/database/src'
resolve correctly while keeping the existing exact '^@wcpos/database$' mapping.
- Add type assertions for mock data - Change tax IDs from strings to numbers - Update expected values to match implementation output format (no trailing zeros, and correct cart_tax/total calculations)
- Replace import from '@testing-library/react-hooks' with '@testing-library/react' - Add @jest-environment jsdom directive for DOM-dependent tests
- Pass explicit undefined/null arguments instead of no args - Expect null return value for empty inputs (matches implementation)
Address CodeRabbit feedback to use production metadata key name
Summary
test.ymlworkflow to run Jest tests on PRs and pushes to mainpreview.yml(functionality replaced by test workflow)isSameDayfor single-day detection per CodeRabbit feedbackChanges
CI Workflow (
test.yml)pnpm jest --ci --passWithNoTestssetup-monorepoaction for consistent environmentChart Utils Timezone Audit
should find orders when date range and orders use same conversionshould bucket multi-day orders by their dateshould use isSameDay for single-day detectiondifferenceInDays <= 1toisSameDay()for clarityTest Plan
Summary by CodeRabbit
Bug Fixes
Tests
Chores
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.