Skip to content

Commit 7adf842

Browse files
committed
Fixed tests
1 parent 87c7f1b commit 7adf842

17 files changed

+630
-306
lines changed

bot.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { createBot } from "./src/core/app.ts";
2+
import { initializeDb } from "./src/core/database.ts"; // Import the initializer
3+
4+
// Initialize the production database before creating the bot
5+
await initializeDb("./sessions/kv.db");
26

37
export const bot = await createBot();
48

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
# Bug Analysis Report: Missing 'clearDb' Export in Test Helpers
2+
3+
## 1. Executive Summary
4+
5+
- **Brief description of the analyzed bug:** The `deno task test` command fails
6+
during the type-checking phase with `TS2305` errors, indicating that the
7+
`clearDb` function cannot be found in the module `test/helpers.ts`.
8+
- **Most likely root cause(s):** The root cause is an incomplete refactoring. As
9+
part of a larger effort to isolate the test database (detailed in
10+
`plan_google_tests2_2_phase1_architect.md`), the `clearDb` function was
11+
intentionally removed from `test/helpers.ts` and replaced with a more robust
12+
`setupTestDb` pattern. While several integration test files were updated to
13+
use this new pattern, two files,
14+
`src/modules/reminders/reminders.handlers.test.ts` and
15+
`src/modules/tasks/tasks.handlers.test.ts`, were missed and still attempt to
16+
import and use the now-non-existent `clearDb` function.
17+
- **Key code areas/modules involved in the problem:**
18+
- `src/modules/reminders/reminders.handlers.test.ts` (Incorrect usage)
19+
- `src/modules/tasks/tasks.handlers.test.ts` (Incorrect usage)
20+
- `test/helpers.ts` (Source of the removed function)
21+
- `plans/plan_google_tests2_2_phase1_architect.md` (Documentation of the
22+
intended change)
23+
24+
## 2. Bug Description and Context (from `User Task`)
25+
26+
- **Observed Behavior:** When running `deno task test`, the process fails with
27+
TypeScript errors.
28+
- **Expected Behavior:** The test suite should pass the type-checking phase and
29+
execute all tests successfully.
30+
- **Steps to Reproduce (STR):**
31+
1. Run the command `deno task test`.
32+
- **Environment (if provided):** Deno
33+
- **Error Messages (if any):**
34+
```
35+
TS2305 [ERROR]: Module '"file:///.../test/helpers.ts"' has no exported member 'clearDb'.
36+
import { clearDb, createMockContext } from "../../../test/helpers.ts";
37+
~~~~~~~
38+
at file:///.../src/modules/reminders/reminders.handlers.test.ts:7:10
39+
40+
TS2305 [ERROR]: Module '"file:///.../test/helpers.ts"' has no exported member 'clearDb'.
41+
import { clearDb, createMockContext } from "../../../test/helpers.ts";
42+
~~~~~~~
43+
at file:///.../src/modules/tasks/tasks.handlers.test.ts:6:10
44+
```
45+
46+
## 3. Code Execution Path Analysis
47+
48+
The reported errors are not runtime errors but type-checking errors that occur
49+
before any test code is executed. The analysis path is that of the TypeScript
50+
compiler.
51+
52+
### 3.1. Entry Point(s) and Initial State
53+
54+
The process begins when the user executes the `deno task test` command. This
55+
invokes the Deno test runner, which initiates a type-checking pass on all
56+
relevant project files.
57+
58+
### 3.2. Key Functions/Modules/Components in the Execution Path
59+
60+
- **Deno Test Runner:** The orchestrator that starts the type-checking process.
61+
- **TypeScript Compiler:** The tool that statically analyzes the code.
62+
- **`reminders.handlers.test.ts` / `tasks.handlers.test.ts`:** The test files
63+
containing the invalid import statements.
64+
- **`test/helpers.ts`:** The module from which the import is attempted.
65+
66+
### 3.3. Execution Flow Tracing
67+
68+
The compiler's analysis flow is as follows for each of the failing files:
69+
70+
```mermaid
71+
sequenceDiagram
72+
participant DenoCLI
73+
participant TypeScriptCompiler as TSC
74+
participant HandlerTestFile as `reminders.handlers.test.ts`
75+
participant HelpersModule as `test/helpers.ts`
76+
77+
DenoCLI->>TSC: Start type-checking project
78+
TSC->>HandlerTestFile: Analyze `reminders.handlers.test.ts`
79+
HandlerTestFile-->>TSC: Reads `import { clearDb, ... } from '../../../test/helpers.ts';`
80+
TSC->>HelpersModule: Resolve module and look for exported member 'clearDb'
81+
HelpersModule-->>TSC: Module resolved, but no export named 'clearDb' found. Exports include 'setupTestDb'.
82+
TSC->>TSC: Import resolution failed.
83+
TSC-->>DenoCLI: Report TS2503 Error: "Module has no exported member 'clearDb'."
84+
DenoCLI-->>User: Print error and halt.
85+
```
86+
87+
- **Step 1:** The TypeScript compiler parses
88+
`src/modules/reminders/reminders.handlers.test.ts`.
89+
- **Step 2:** It encounters the import statement:
90+
`import { clearDb, createMockContext } from "../../../test/helpers.ts";`.
91+
- **Step 3:** The compiler resolves the module path to `test/helpers.ts` and
92+
inspects its exported members.
93+
- **Step 4:** It finds exports for `createMockContext`,
94+
`createMockConversation`, and `setupTestDb`, but it does not find an export
95+
for `clearDb`. This is because the function was removed as part of a planned
96+
refactoring.
97+
- **Step 5:** The compiler flags this as a `TS2305` error because the import
98+
cannot be satisfied.
99+
- **Step 6:** The same process repeats for
100+
`src/modules/tasks/tasks.handlers.test.ts`, resulting in the second error. The
101+
test run is aborted.
102+
103+
### 3.4. Data State and Flow Analysis
104+
105+
This is a static analysis error. There is no data flow or state change involved.
106+
The issue is a structural mismatch between what the test files expect to import
107+
and what the helper module actually exports.
108+
109+
## 4. Potential Root Causes and Hypotheses
110+
111+
### 4.1. Hypothesis 1: Incomplete Refactoring of Test Database Management
112+
113+
- **Rationale/Evidence:** This is the definitive root cause. The planning
114+
document `plan_google_tests2_2_phase1_architect.md` explicitly mandates the
115+
removal of `clearDb` and its replacement with a new `setupTestDb` helper to
116+
prevent tests from wiping the production database. The error messages are a
117+
direct symptom of this change. The code in `test/helpers.ts` confirms
118+
`clearDb` is gone, while the code in the failing test files confirms they were
119+
not updated to reflect this change. In contrast, other integration tests like
120+
`reminders.repository.test.ts` and `tasks.repository.test.ts` _were_ correctly
121+
refactored, demonstrating the intended pattern and highlighting the
122+
inconsistency.
123+
- **How it leads to the bug:** The test files `reminders.handlers.test.ts` and
124+
`tasks.handlers.test.ts` have become desynchronized from their dependency,
125+
`test/helpers.ts`. They attempt to import a function that no longer exists,
126+
leading to a fatal type-checking error.
127+
128+
### 4.2. Most Likely Cause(s)
129+
130+
Hypothesis 1 is confirmed as the sole cause of the issue. It's a classic case of
131+
an incomplete refactoring effort where some dependent files were overlooked.
132+
133+
## 5. Supporting Evidence from Code
134+
135+
- **The explicit instruction to remove the function** from
136+
`plans/plan_google_tests2_2_phase1_architect.md`:
137+
```typescript
138+
// test/helpers.ts
139+
// ...
140+
// The old clearDb function should be REMOVED to avoid confusion.
141+
// export async function clearDb() { ... } // <- DELETE THIS
142+
```
143+
144+
- **The invalid import** in `src/modules/reminders/reminders.handlers.test.ts`:
145+
```typescript
146+
import { clearDb, createMockContext } from "../../../test/helpers.ts";
147+
// ...
148+
Deno.test("ReminderHandlers - remindersHandler", async (t) => {
149+
await clearDb(); // Calling the non-existent function
150+
// ...
151+
});
152+
```
153+
154+
- **The correct, updated pattern** in
155+
`src/modules/reminders/reminders.repository.test.ts` (for comparison):
156+
```typescript
157+
import { setupTestDb } from "../../../test/helpers.ts"; // Import new helper
158+
159+
Deno.test(
160+
"ReminderRepository",
161+
{ sanitizeResources: false, sanitizeOps: false },
162+
async (t) => {
163+
const { clear, teardown } = await setupTestDb(); // Correctly using the new helper
164+
try {
165+
// ... test steps using `await clear()`
166+
} finally {
167+
teardown(); // Correctly tearing down
168+
}
169+
},
170+
);
171+
```
172+
173+
## 6. Recommended Steps for Debugging and Verification
174+
175+
The cause is definitively identified. The following steps are for fixing the
176+
issue by completing the refactoring. The pattern from
177+
`reminders.repository.test.ts` should be applied to the failing handler test
178+
files.
179+
180+
**1. Refactor `src/modules/reminders/reminders.handlers.test.ts`:**
181+
182+
Update the file to use the `setupTestDb` helper for tests that require database
183+
interaction.
184+
185+
```typescript
186+
// src/modules/reminders/reminders.handlers.test.ts
187+
188+
import * as chrono from "npm:chrono-node/ru";
189+
import {
190+
assertSpyCall,
191+
Spy,
192+
} from "https://deno.land/[email protected]/testing/mock.ts";
193+
// Change the import: remove 'clearDb', add 'setupTestDb'
194+
import { createMockContext, setupTestDb } from "../../../test/helpers.ts";
195+
import { createReminderHandlers } from "./reminders.handlers.ts";
196+
import { ReminderService } from "./reminders.service.ts";
197+
import { ReminderRepository } from "./reminders.repository.ts";
198+
199+
// ... (tests that don't need the DB are unchanged)
200+
201+
Deno.test("ReminderHandlers - remindersHandler", async (t) => {
202+
// Use the new setupTestDb pattern
203+
const { clear, teardown } = await setupTestDb();
204+
try {
205+
const reminderRepository = new ReminderRepository();
206+
const reminderService = new ReminderService(reminderRepository);
207+
const handlers = createReminderHandlers(reminderService);
208+
const ctx = createMockContext();
209+
210+
await t.step(
211+
"should reply with 'No reminders in the list' if no reminders exist",
212+
async () => {
213+
await clear(); // Clear DB state for this step
214+
await handlers.remindersHandler(ctx);
215+
assertSpyCall(ctx.reply as Spy<any>, 0, {
216+
args: ["No reminders in the list"],
217+
});
218+
},
219+
);
220+
221+
await t.step(
222+
"should reply with a list of reminders if reminders exist",
223+
async () => {
224+
await clear(); // Clear DB state for this step
225+
// ... (rest of the test logic is the same, but now correctly isolated)
226+
await reminderService.addReminder(
227+
ctx.from!.id,
228+
"Test Reminder 1 завтра",
229+
);
230+
// ...
231+
await handlers.remindersHandler(ctx);
232+
// ... (assertions)
233+
},
234+
);
235+
} finally {
236+
teardown(); // Ensure the test DB is cleaned up
237+
}
238+
});
239+
```
240+
241+
**2. Refactor `src/modules/tasks/tasks.handlers.test.ts`:**
242+
243+
Apply the exact same `setupTestDb` pattern to this file for its integration
244+
tests.
245+
246+
## 7. Bug Impact Assessment
247+
248+
**High.** This is a build-time failure that completely blocks the entire test
249+
suite from running. It prevents the CI pipeline from validating code changes,
250+
which significantly increases the risk of introducing regressions. Developer
251+
productivity is hampered as they cannot get feedback on their changes.
252+
253+
## 8. Assumptions Made During Analysis
254+
255+
- The refactoring described in `plan_google_tests2_2_phase1_architect.md` was
256+
intentional and should be applied consistently across all integration tests.
257+
- The handler tests that interact with the `TaskService` and `ReminderService`
258+
are considered integration tests because they rely on a real (though
259+
temporary) database instance.
260+
261+
## 9. Open Questions / Areas for Further Investigation
262+
263+
There are no open questions. The cause is clear, and the path to resolution is a
264+
straightforward completion of the previously planned refactoring.

src/core/database.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
import { DenoKVAdapter } from "https://deno.land/x/grammy_storages/denokv/src/mod.ts";
2-
// import { freeStorage } from "https://deno.land/x/[email protected]/free/src/mod.ts";
3-
// import { FileAdapter } from "https://deno.land/x/grammy_storages/file/src/mod.ts";
42

5-
// Deno.kv storage
6-
export let kv = await Deno.openKv("./sessions/kv.db");
7-
export const storage = new DenoKVAdapter(kv);
3+
export let kv: Deno.Kv;
4+
export let storage: DenoKVAdapter<Deno.Kv>;
5+
6+
export async function initializeDb(path: string): Promise<void> {
7+
kv = await Deno.openKv(path);
8+
storage = new DenoKVAdapter(kv);
9+
}
810

9-
// Export a setter for testing purposes
1011
export function __setKv(newKv: Deno.Kv) {
1112
kv = newKv;
13+
storage = new DenoKVAdapter(kv);
1214
}
13-
14-
// File storage
15-
// export const storage = new FileAdapter<SessionData>({
16-
// dirName: "sessions",
17-
// });
18-
19-
// Free storage
20-
// export const storage = new freeStorage<SessionData>(bot.token);

0 commit comments

Comments
 (0)