-
Notifications
You must be signed in to change notification settings - Fork 76
fix: Supabase Mock Configuration in Tests #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Supabase Mock Configuration in Tests #206
Conversation
📝 WalkthroughWalkthroughCentralized Bun-compatible Supabase mocks and test setup were added and applied before SUT imports; several integration and unit tests were updated to use the centralized mock. The Supabase config now initializes a real client and requires SUPABASE_SERVICE_ROLE_KEY. The Soroban RPC import path in sync.service.ts was updated. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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 |
|
Let me know if any changes are required, happy to help! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/backend/tests/integration/booking.test.ts (1)
75-97: Mock may not take effect for pre-built app.The
appis built inbeforeAll()with the originalgetBookingcontroller. Callingmock.module()in individual tests won't affect the already-imported controller that's bound to the Express app.Notice how the 200 OK test (lines 223-228) correctly handles this by re-importing the controller after setting up the mock and creating a new Express app. The same pattern should be applied to these error scenario tests, or the app should be rebuilt after each mock setup.
💡 Suggested approach
Either:
- Apply the same pattern as the 200 OK test (re-import and rebuild app after mock)
- Or move mock setup to
beforeAlland use per-test mock return values
🤖 Fix all issues with AI agents
In `@apps/backend/src/tests/sync.service.test.ts`:
- Around line 145-158: The test names claim event processing and error handling
but only start/stop the service (syncService.start(), syncService.getStatus(),
syncService.stop()); either rename the two it(...) descriptions to something
like "should start and stop service during event processing" and "should start
and stop service when event processing errors occur", or expand the tests to
assert real behavior: after syncService.start() emit or call the actual event
handler (e.g., syncService.processEvent or the event emitter used by the
service) with a mock "booking created" payload and assert the expected handler
was invoked and side-effects occurred, and for the error test stub the handler
to throw/reject and assert the service stays alive, logs the error, and
recovers/continues (or stops) as expected; keep using syncService.start(),
syncService.getStatus(), and syncService.stop() while adding appropriate
spies/mocks and assertions for handler invocation and error logging.
In `@apps/backend/tests/integration/booking.test.ts`:
- Around line 48-49: Remove the duplicated assertion that checks the HTTP
status: there are two identical lines calling expect(res.status).toBe(400); —
keep a single expect(res.status).toBe(400); and delete the redundant duplicate
(both reference the same res variable in the failing test).
🧹 Nitpick comments (6)
apps/backend/tests/mocks/supabase.mock.ts (3)
143-143: Unused variableoriginalEq.The variable
originalEqis declared but never used. This appears to be leftover from a refactoring. Consider removing it.🧹 Suggested fix
update: mock(() => { const updateChain = createMockChain(tableName); - const originalEq = updateChain.eq; updateChain.eq = mock((column: string, value: any) => {
165-165: Unused variableoriginalEq.Same issue as above -
originalEqis declared but never used in thedelete()method.🧹 Suggested fix
delete: mock(() => { const deleteChain = createMockChain(tableName); - const originalEq = deleteChain.eq; deleteChain.eq = mock((column: string, value: any) => {
49-78: Filter matching is incomplete forinandmatchoperators.The
single()andthen()methods only handleeq,gt, andltoperators in the filter matching logic, but the chain supportsinandmatchfilters (lines 35-44). If tests use.in()queries, the filtering will silently be skipped.Consider adding support for the
inoperator:💡 Example fix for the filter matching
if (filter.operator === 'lt' && new Date(item[filter.column]) >= new Date(filter.value)) { matches = false; break; } + if (filter.operator === 'in' && !filter.values?.includes(item[filter.column])) { + matches = false; + break; + } }apps/backend/tests/setup.ts (1)
9-44: Consider extracting duplicatedMockServerclass.The
MockServerclass is duplicated for both@stellar/stellar-sdk/rpcand@stellar/stellar-sdk/lib/rpcpaths. While this works, extracting it to a shared constant would reduce duplication:💡 Optional refactor
+class MockServer { + constructor(_url: string) {} + async getLatestLedger() { + return Promise.resolve({ sequence: 1000 }); + } + async getContractEvents() { + return Promise.resolve({ events: [] }); + } +} + mock.module('@stellar/stellar-sdk/rpc', () => { - class MockServer { - constructor(_url: string) {} - async getLatestLedger() { - return Promise.resolve({ sequence: 1000 }); - } - async getContractEvents() { - return Promise.resolve({ events: [] }); - } - } return { Server: MockServer, default: { Server: MockServer }, }; }); mock.module('@stellar/stellar-sdk/lib/rpc', () => { - class MockServer { - constructor(_url: string) {} - async getLatestLedger() { - return Promise.resolve({ sequence: 1000 }); - } - async getContractEvents() { - return Promise.resolve({ events: [] }); - } - } return { Server: MockServer, default: { Server: MockServer }, }; });apps/backend/src/tests/sync.service.test.ts (1)
226-274: Duplicate test cases detected.The tests at lines 226-274 (
should use custom polling interval...andshould fallback to default polling interval...) are exact duplicates of the tests at lines 66-114 within thedescribe('Initialization', ...)block. Consider removing the duplicates.🧹 Suggested fix
}); - - it('should use custom polling interval from environment variable', () => { - // ... duplicate test code - }); - - it('should fallback to default polling interval for invalid environment value', () => { - // ... duplicate test code - }); });apps/backend/tests/integration/booking.test.ts (1)
56-72: Inconsistent language in error messages across the codebase.The auth middleware returns Spanish error messages for 401/403 responses (
"Token no proporcionado","Token inválido o expirado"), while the error middleware and other validators use English ("Invalid token","Token expired","Validation error"). The tests accurately reflect the current implementation, but this mixed-language approach should be addressed:
- Standardize on a single language for all error messages
- Or implement a proper i18n solution if multi-language support is intended
respp
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your code is very close to being merged. I’ve left some corrections above; once you address those and follow the coderabbit suggestions, we should be all set
|
Hi, just saw the review, working on this ASAP! |
|
Fixed all requested changes and merge conflicts. LMK if any more changes are needed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
apps/backend/tests/integration/booking.test.ts (1)
70-92: Mock applied after controller import won't take effect.The controller
getBookingis imported at line 13, beforemock.module()is called in this test. In Bun,mock.module()must be called before the module being mocked is imported. Sincebooking.controlleralready importedbooking.service, this mock won't affect the controller's behavior.Compare with the 200 test (lines 218-222) which correctly re-imports the controller after applying the mock. Apply the same pattern here.
🐛 Suggested fix pattern (apply to all error tests)
it('403: user is neither booker nor host', async () => { // Mock getBookingById to throw access denied error mock.module('../../src/services/booking.service', () => ({ ...bookingServiceModule, getBookingById: mock(async () => { throw new Error('Access denied'); }), })); + // Re-import controller to get the mocked service + const { getBooking: getBookingMocked } = await import('../../src/controllers/booking.controller'); + const testApp = express(); + testApp.use(express.json()); + testApp.get('/bookings/:bookingId', authenticateToken, getBookingMocked); + - const res = await request(app) + const res = await request(testApp) .get(`/bookings/${testBookingId}`) .set('Authorization', validToken);apps/backend/src/tests/sync.service.test.ts (2)
62-86: Duplicate tests: "should use custom polling interval from environment variable".The test at lines 62-86 (inside
describe('Initialization')) and the test at lines 299-322 (at the top level) are identical. Remove one of them.🧹 Suggested fix
Remove lines 299-322 (the duplicate at the top level):
- it('should use custom polling interval from environment variable', () => { - // Save original environment variables - const originalPollingInterval = process.env.SYNC_POLL_INTERVAL; - const originalRpcUrl = process.env.SOROBAN_RPC_URL; - const originalContractId = process.env.SOROBAN_CONTRACT_ID; - const originalNetworkPassphrase = process.env.SOROBAN_NETWORK_PASSPHRASE; - - try { - // Set custom polling interval - process.env.SYNC_POLL_INTERVAL = '10000'; - process.env.SOROBAN_RPC_URL = 'https://test-rpc.stellar.org'; - process.env.SOROBAN_CONTRACT_ID = 'CB3ILSDNHL6TWZYZJAS4L27GLHNAGW4ISW6YXIBHGHL4QYI4JPLP6W3E'; - process.env.SOROBAN_NETWORK_PASSPHRASE = 'Test SDF Network ; September 2015'; - - const customSyncService = new SyncService(); - expect(customSyncService.getPollingIntervalMs()).toBe(10000); - } finally { - // Restore original environment variables - process.env.SYNC_POLL_INTERVAL = originalPollingInterval; - process.env.SOROBAN_RPC_URL = originalRpcUrl; - process.env.SOROBAN_CONTRACT_ID = originalContractId; - process.env.SOROBAN_NETWORK_PASSPHRASE = originalNetworkPassphrase; - } - });Also applies to: 299-322
88-112: Duplicate tests: "should fallback to default polling interval".The test at lines 88-112 (inside
describe('Initialization')) and the test at lines 324-347 (at the top level) are identical. Remove one of them.🧹 Suggested fix
Remove lines 324-347 (the duplicate at the top level):
- it('should fallback to default polling interval for invalid environment value', () => { - // Save original environment variables - const originalPollingInterval = process.env.SYNC_POLL_INTERVAL; - const originalRpcUrl = process.env.SOROBAN_RPC_URL; - const originalContractId = process.env.SOROBAN_CONTRACT_ID; - const originalNetworkPassphrase = process.env.SOROBAN_NETWORK_PASSPHRASE; - - try { - // Set invalid polling interval - process.env.SYNC_POLL_INTERVAL = 'invalid'; - process.env.SOROBAN_RPC_URL = 'https://test-rpc.stellar.org'; - process.env.SOROBAN_CONTRACT_ID = 'CB3ILSDNHL6TWZYZJAS4L27GLHNAGW4ISW6YXIBHGHL4QYI4JPLP6W3E'; - process.env.SOROBAN_NETWORK_PASSPHRASE = 'Test SDF Network ; September 2015'; - - const fallbackSyncService = new SyncService(); - expect(fallbackSyncService.getPollingIntervalMs()).toBe(5000); // Default fallback - } finally { - // Restore original environment variables - process.env.SYNC_POLL_INTERVAL = originalPollingInterval; - process.env.SOROBAN_RPC_URL = originalRpcUrl; - process.env.SOROBAN_CONTRACT_ID = originalContractId; - process.env.SOROBAN_NETWORK_PASSPHRASE = originalNetworkPassphrase; - } - });Also applies to: 324-347
🤖 Fix all issues with AI agents
In `@apps/backend/tests/mocks/supabase.mock.chain.ts`:
- Around line 5-37: findMatchingRecords currently only handles 'eq', 'gt', and
'lt', ignores 'in' and 'match' filters accumulated in _filters, and always
treats gt/lt as date comparisons; update findMatchingRecords to evaluate 'in'
(check item[filter.column] is one of filter.values) and 'match' (perform
substring/regex match against item[filter.column] using filter.value), and
change gt/lt logic to detect numeric vs date comparison (e.g., if both item[*]
and filter.value are numbers compare numerically, otherwise parse as dates) so
numeric queries work correctly; keep references to the function name
findMatchingRecords and the filter properties (operator, column, value, values)
when implementing these cases.
In `@apps/backend/tests/mocks/supabase.mock.ts`:
- Around line 13-14: The mockFrom function creates a new Map for unknown
tableName but never saves it, so inserts into unknown tables are lost; update
mockFrom to check if mockDataStore[tableName] is missing and if so assign a new
Map back into mockDataStore (or call mockDataStore.set(tableName, new Map()) if
mockDataStore is a Map) before returning tableData so subsequent inserts
persist; reference the mockFrom function and mockDataStore when making this
change.
In `@apps/backend/tests/setup.ts`:
- Line 52: The placeholder secret assigned in Object.defineProperty(process.env,
'STELLAR_SECRET_KEY', ...) is not a valid 56-character base32 Stellar secret
(must start with 'S'); replace the hardcoded invalid string with a properly
formatted test secret (e.g., a known testnet secret) or generate a valid secret
at test setup time (for example using Stellar SDK's
Keypair.random()/Keypair.fromSecret() and assign its secret) and set
process.env.STELLAR_SECRET_KEY to that value so any SDK validation succeeds.
🧹 Nitpick comments (11)
apps/backend/tests/mocks/supabase.mock.chain.ts (2)
76-79: Inconsistent async behavior inthen().The
then()method invokes the callback synchronously and returns its result directly, whereassingle()returnsPromise.resolve(...). This inconsistency could cause subtle timing issues in tests that depend on Promise-like behavior.Proposed fix for consistent Promise behavior
then: mock((callback: any) => { const results = findMatchingRecords(tableName, mockDataStore, chain._filters || []); - return callback({ data: results, error: null }); + return Promise.resolve(callback({ data: results, error: null })); }),
75-75:maybeSingle()ignores accumulated filters.Unlike
single(),maybeSingle()always returns{ data: null, error: null }without evaluating the filter chain. If tests rely onmaybeSingle()returning actual data, they will fail silently.Proposed fix
- maybeSingle: mock(() => Promise.resolve({ data: null, error: null })), + maybeSingle: mock(() => { + const matches = findMatchingRecords(tableName, mockDataStore, chain._filters || []); + return Promise.resolve({ data: matches[0] ?? null, error: null }); + }),apps/backend/src/tests/booking.test.ts (1)
59-68: Redundant local mock conflicts with centralized setup.The test file imports the centralized setup (line 2) which registers the Supabase mock, but then creates and assigns a separate local mock via
Object.assign(supabase, createMockSupabaseMethods())(line 91). This pattern:
- May not fully override the centralized mock since
Object.assignonly assigns own enumerable properties- Creates maintenance burden by duplicating mock logic
- Defeats the purpose of the centralized mock infrastructure introduced in this PR
Consider either removing the local mock and relying on the centralized mock, or pre-seeding the centralized mock's data store in
beforeEach.Also applies to: 89-94
apps/backend/tests/mocks/supabase.mock.ts (1)
43-50:update()anddelete()only operate onidorpublic_keycolumns.The filter evaluation is hardcoded to only match against
idorpublic_keycolumns. Queries like.update(...).eq('status', 'pending')will accumulate the filter but never apply the update/delete to matching records.This may be intentional to keep the mock simple, but could cause test failures if tests expect full filter support.
Proposed fix to support arbitrary column filters
// When update().eq() is called, apply the update - if (column === 'id' || column === 'public_key') { - for (const item of tableData.values()) { - if (item[column] === value) { - Object.assign(item, { updated_at: new Date().toISOString() }); - } + for (const item of tableData.values()) { + if (item[column] === value) { + Object.assign(item, { updated_at: new Date().toISOString() }); } }Also applies to: 63-70
apps/backend/tests/setup.ts (2)
10-45: Consider extracting the duplicatedMockServerclass.The
MockServerclass is defined identically in both mock.module calls (lines 11-21 and 30-40). Extract it once before the mocks to reduce duplication.♻️ Suggested refactor
+// Shared MockServer for Stellar SDK RPC mocks +class MockServer { + constructor(_url: string) { + // Mock server constructor + } + async getLatestLedger() { + return Promise.resolve({ sequence: 1000 }); + } + async getContractEvents() { + return Promise.resolve({ events: [] }); + } +} + // Mock Stellar SDK RPC module for tests BEFORE any imports // This prevents module resolution errors when sync.service.ts is imported mock.module('@stellar/stellar-sdk/rpc', () => { - class MockServer { - constructor(_url: string) { - // Mock server constructor - } - async getLatestLedger() { - return Promise.resolve({ sequence: 1000 }); - } - async getContractEvents() { - return Promise.resolve({ events: [] }); - } - } return { Server: MockServer, default: { Server: MockServer }, }; }); // Also mock the lib/rpc path that sync.service.ts was trying to use mock.module('@stellar/stellar-sdk/lib/rpc', () => { - class MockServer { - constructor(_url: string) { - // Mock server constructor - } - async getLatestLedger() { - return Promise.resolve({ sequence: 1000 }); - } - async getContractEvents() { - return Promise.resolve({ events: [] }); - } - } return { Server: MockServer, default: { Server: MockServer }, }; });
83-89: RedundantsetupSupabaseMock()calls may cause overhead.
setupSupabaseMock()is called both at module load time (line 84) and inbeforeEach(line 88). ThebeforeEachcall is intended to restore mocks ifmock.restore()is called, but this means every test re-registers multiple module paths even when unnecessary.Consider tracking whether restoration is needed or documenting why this overhead is acceptable for test stability.
apps/backend/tests/integration/booking.test.ts (1)
118-162: Single test case asserts two different scenarios sequentially.This test applies two different mocks (Property not found, then Host user not found) and makes two requests, but the second
mock.module()call at line 142 won't replace the first mock correctly without re-importing the controller (same issue as above). Additionally, combining two distinct scenarios in one test reduces clarity and makes failures harder to diagnose.Consider splitting into two separate test cases.
apps/backend/src/tests/sync.service.test.ts (4)
234-267: Manual operations tests lack meaningful assertions.These tests ("should trigger manual sync", "should process blockchain events during manual sync", "should handle blockchain errors during manual sync") all have identical structure and only assert that
isRunningistrue. They don't actually verify:
- That manual sync was triggered
- That blockchain events were processed
- That errors were handled
Consider adding assertions that verify the expected behavior, such as checking
lastSyncTimechanges, event counts, or mock call verification.
283-296: Error handling tests don't test error scenarios.Tests "should handle network errors gracefully" and "should handle database errors gracefully" only start/stop the service and check
isRunning. They don't simulate any network or database errors.Consider injecting faults (e.g., mocking RPC or Supabase to throw) and verifying the service handles them gracefully (logs errors, continues running, increments
failedEvents, etc.).
198-205: Directly patching private handler is brittle.Mutating
serviceWithHandlers.handleBookingCreateddirectly couples the test to implementation details. If the method name or structure changes, this test breaks.Consider mocking at the module level (as done for booking.service in the other test file) or using dependency injection patterns.
145-180: Type assertions for mock internals are fragile.The pattern
supabase.from as unknown as { mock?: { calls: Array<[string]> } }assumes a specific mock structure that may not be guaranteed by thecreateSupabaseMockimplementation. If the mock changes, this will fail silently or throw unexpected errors.Consider exposing a proper API from the mock (e.g.,
getMockCalls()) or using Bun's built-in mock introspection if available.
| const findMatchingRecords = ( | ||
| tableName: string, | ||
| mockDataStore: MockDataStore, | ||
| filters: Array<{ column: string; value?: any; values?: any[]; operator: string }> | ||
| ) => { | ||
| const tableData = mockDataStore[tableName] || new Map(); | ||
| if (filters.length === 0) { | ||
| return []; | ||
| } | ||
|
|
||
| const results: any[] = []; | ||
| for (const item of tableData.values()) { | ||
| let matches = true; | ||
| for (const filter of filters) { | ||
| if (filter.operator === 'eq' && item[filter.column] !== filter.value) { | ||
| matches = false; | ||
| break; | ||
| } | ||
| if (filter.operator === 'gt' && new Date(item[filter.column]) <= new Date(filter.value)) { | ||
| matches = false; | ||
| break; | ||
| } | ||
| if (filter.operator === 'lt' && new Date(item[filter.column]) >= new Date(filter.value)) { | ||
| matches = false; | ||
| break; | ||
| } | ||
| } | ||
| if (matches) { | ||
| results.push(item); | ||
| } | ||
| } | ||
| return results; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete filter operator implementations.
The in and match operators are accumulated in _filters (lines 57-66) but findMatchingRecords only evaluates eq, gt, and lt. Queries using .in() or .match() will silently ignore those filters.
Additionally, gt and lt comparisons always parse values as dates (lines 23-30), which will produce incorrect results for numeric comparisons.
Proposed fix to add missing operator evaluations
if (filter.operator === 'lt' && new Date(item[filter.column]) >= new Date(filter.value)) {
matches = false;
break;
}
+ if (filter.operator === 'in' && !filter.values?.includes(item[filter.column])) {
+ matches = false;
+ break;
+ }
+ if (filter.operator === 'match' && item[filter.column] !== filter.value) {
+ matches = false;
+ break;
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const findMatchingRecords = ( | |
| tableName: string, | |
| mockDataStore: MockDataStore, | |
| filters: Array<{ column: string; value?: any; values?: any[]; operator: string }> | |
| ) => { | |
| const tableData = mockDataStore[tableName] || new Map(); | |
| if (filters.length === 0) { | |
| return []; | |
| } | |
| const results: any[] = []; | |
| for (const item of tableData.values()) { | |
| let matches = true; | |
| for (const filter of filters) { | |
| if (filter.operator === 'eq' && item[filter.column] !== filter.value) { | |
| matches = false; | |
| break; | |
| } | |
| if (filter.operator === 'gt' && new Date(item[filter.column]) <= new Date(filter.value)) { | |
| matches = false; | |
| break; | |
| } | |
| if (filter.operator === 'lt' && new Date(item[filter.column]) >= new Date(filter.value)) { | |
| matches = false; | |
| break; | |
| } | |
| } | |
| if (matches) { | |
| results.push(item); | |
| } | |
| } | |
| return results; | |
| }; | |
| const findMatchingRecords = ( | |
| tableName: string, | |
| mockDataStore: MockDataStore, | |
| filters: Array<{ column: string; value?: any; values?: any[]; operator: string }> | |
| ) => { | |
| const tableData = mockDataStore[tableName] || new Map(); | |
| if (filters.length === 0) { | |
| return []; | |
| } | |
| const results: any[] = []; | |
| for (const item of tableData.values()) { | |
| let matches = true; | |
| for (const filter of filters) { | |
| if (filter.operator === 'eq' && item[filter.column] !== filter.value) { | |
| matches = false; | |
| break; | |
| } | |
| if (filter.operator === 'gt' && new Date(item[filter.column]) <= new Date(filter.value)) { | |
| matches = false; | |
| break; | |
| } | |
| if (filter.operator === 'lt' && new Date(item[filter.column]) >= new Date(filter.value)) { | |
| matches = false; | |
| break; | |
| } | |
| if (filter.operator === 'in' && !filter.values?.includes(item[filter.column])) { | |
| matches = false; | |
| break; | |
| } | |
| if (filter.operator === 'match' && item[filter.column] !== filter.value) { | |
| matches = false; | |
| break; | |
| } | |
| } | |
| if (matches) { | |
| results.push(item); | |
| } | |
| } | |
| return results; | |
| }; |
🤖 Prompt for AI Agents
In `@apps/backend/tests/mocks/supabase.mock.chain.ts` around lines 5 - 37,
findMatchingRecords currently only handles 'eq', 'gt', and 'lt', ignores 'in'
and 'match' filters accumulated in _filters, and always treats gt/lt as date
comparisons; update findMatchingRecords to evaluate 'in' (check
item[filter.column] is one of filter.values) and 'match' (perform
substring/regex match against item[filter.column] using filter.value), and
change gt/lt logic to detect numeric vs date comparison (e.g., if both item[*]
and filter.value are numbers compare numerically, otherwise parse as dates) so
numeric queries work correctly; keep references to the function name
findMatchingRecords and the filter properties (operator, column, value, values)
when implementing these cases.
| const mockFrom = mock((tableName: string) => { | ||
| const tableData = mockDataStore[tableName] || new Map(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Data inserted into unknown tables is silently lost.
When tableName is not in mockDataStore, a new Map() is created but never stored back. Any data inserted into an unknown table will be discarded since tableData is a local variable.
Proposed fix
const mockFrom = mock((tableName: string) => {
- const tableData = mockDataStore[tableName] || new Map();
+ if (!mockDataStore[tableName]) {
+ mockDataStore[tableName] = new Map();
+ }
+ const tableData = mockDataStore[tableName];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const mockFrom = mock((tableName: string) => { | |
| const tableData = mockDataStore[tableName] || new Map(); | |
| const mockFrom = mock((tableName: string) => { | |
| if (!mockDataStore[tableName]) { | |
| mockDataStore[tableName] = new Map(); | |
| } | |
| const tableData = mockDataStore[tableName]; |
🤖 Prompt for AI Agents
In `@apps/backend/tests/mocks/supabase.mock.ts` around lines 13 - 14, The mockFrom
function creates a new Map for unknown tableName but never saves it, so inserts
into unknown tables are lost; update mockFrom to check if
mockDataStore[tableName] is missing and if so assign a new Map back into
mockDataStore (or call mockDataStore.set(tableName, new Map()) if mockDataStore
is a Map) before returning tableData so subsequent inserts persist; reference
the mockFrom function and mockDataStore when making this change.
| Object.defineProperty(process.env, 'JWT_SECRET', { value: 'test-secret-key', writable: true }); | ||
| Object.defineProperty(process.env, 'STELLAR_NETWORK', { value: 'testnet', writable: true }); | ||
| Object.defineProperty(process.env, 'USE_MOCK', { value: 'true', writable: true }); | ||
| Object.defineProperty(process.env, 'STELLAR_SECRET_KEY', { value: 'SBTESTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', writable: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid Stellar secret key format.
The placeholder SBTESTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX is not a valid Stellar secret key format. Stellar secret keys are 56 characters starting with 'S' and are base32-encoded. While this is a test value, an invalid format could cause unexpected failures if the SDK validates key format during instantiation.
Consider using a properly formatted test key or a known testnet key format.
🤖 Prompt for AI Agents
In `@apps/backend/tests/setup.ts` at line 52, The placeholder secret assigned in
Object.defineProperty(process.env, 'STELLAR_SECRET_KEY', ...) is not a valid
56-character base32 Stellar secret (must start with 'S'); replace the hardcoded
invalid string with a properly formatted test secret (e.g., a known testnet
secret) or generate a valid secret at test setup time (for example using Stellar
SDK's Keypair.random()/Keypair.fromSecret() and assign its secret) and set
process.env.STELLAR_SECRET_KEY to that value so any SDK validation succeeds.
|
@respp should I go ahead and fix what coderabbit suggests? |
Pull Request | StellarRent
📝 Summary
Some Tests were failing because the Supabase mock was not implemented correctly, created a supabase mock file and updated tests to use it. All tests that use this mock are passing.
🔗 Related Issues
Closes #197
🔄 Changes Made
Fixed Supabase mock configuration across all test files to resolve "undefined is not an object (evaluating 'supabase.auth.getUser')" errors.
🖼️ Current Output
🧪 Testing
Screenshots above.
✅ Testing Checklist
Most tests outside of the ones done for this PR still fail, so it is good to take a look at them.
🚀 Next Steps & Improvements
This change lays a solid foundation for further optimizations. Some areas that could benefit from future improvements include:
💬 Comments
Thanks for reviewing this PR! If you see that I made more files than required, it is because I make the Supabase Mock separated and updated files that needed changes.
Summary by CodeRabbit
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.