Skip to content

chore(notifications): migrates from jest to vitest#2745

Merged
ygrishajev merged 1 commit intomainfrom
feature/notification-tests
Feb 16, 2026
Merged

chore(notifications): migrates from jest to vitest#2745
ygrishajev merged 1 commit intomainfrom
feature/notification-tests

Conversation

@ygrishajev
Copy link
Contributor

@ygrishajev ygrishajev commented Feb 16, 2026

Summary by CodeRabbit

  • Chores

    • Replaced Jest with Vitest for the notifications project, removed old Jest config, added a new Vitest configuration, and updated test scripts and dev tooling.
  • Tests

    • Migrated all test suites and mocks to Vitest (unit and functional), updated timing/mocking APIs and test setups; no runtime behavior or public APIs changed.

@ygrishajev ygrishajev requested a review from a team as a code owner February 16, 2026 10:56
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 16, 2026

📝 Walkthrough

Walkthrough

Migrate the notifications app test tooling from Jest to Vitest: remove the Jest config, add a Vitest config, update package.json scripts and devDependencies, and convert test files and mocks to Vitest APIs and vitest-mock-extended. Test logic remains unchanged.

Changes

Cohort / File(s) Summary
Test framework config & deps
apps/notifications/jest.config.ts, apps/notifications/vitest.config.ts, apps/notifications/package.json
Removed Jest config, added vitest.config.ts (SWC plugin, aliases, v8 coverage, unit/functional projects), replaced test scripts and devDependencies to Vitest ecosystem.
Global functional tests & mocks
apps/notifications/test/..., apps/notifications/test/mocks/provider.mock.ts, apps/notifications/test/setup-functional-tests.ts
Switched functional tests, shared mocks, and setup files to Vitest: added Vitest imports and replaced jest-mock-extended with vitest-mock-extended.
Infrastructure & broker tests
apps/notifications/src/infrastructure/.../db.provider.spec.ts, .../pg-boss.provider.spec.ts, .../broker-healthz.service.spec.ts, .../broker.service.spec.ts, .../pg-boss-handler.service.spec.ts
Migrated mocking and timer APIs from Jest → Vitest: jest.fn()vi.fn(), jest.useFakeTimers()vi.useFakeTimers(), adjusted mock implementations/assertions to Vitest style.
Database health & common services tests
apps/notifications/src/common/.../healthz-helper.service.spec.ts, .../shutdown.service.spec.ts, src/infrastructure/db/.../db-healthz.service.spec.ts
Replaced Jest mocking/timer usages with Vitest equivalents and switched mock type imports to vitest-mock-extended.
Alert & notification services tests
apps/notifications/src/modules/alert/..., apps/notifications/src/modules/notifications/...
Converted many service specs to Vitest: mock types moved to vitest-mock-extended, jest.fn()/jest.spyOnvi.fn()/vi.spyOn; some test helper types updated to Vitest Mock.
Chain & block services tests
apps/notifications/src/modules/chain/...
Updated MockProxy/type imports to vitest-mock-extended and replaced jest.fn() with vi.fn() where present; no functional changes.
REST controllers & handlers tests
apps/notifications/src/interfaces/.../*.spec.ts
Primarily typing/import changes: jest-mock-extendedvitest-mock-extended; added Vitest imports (describe/expect/it); occasional jest.fn()vi.fn().
Utilities & lib tests
apps/notifications/src/lib/..., apps/notifications/src/infrastructure/broker/services/state/...
Replaced Jest mocks with Vitest mocks and adjusted type imports; tests unchanged functionally.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • baktun14

Poem

🐰 I hopped from Jest to Vitest tonight,
Vi.fn() sparkling in the moonlight,
Configs refreshed, mocks all aligned,
Tests still dance — the hops combined. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: migrating the notifications module from Jest to Vitest testing framework.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/notification-tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Feb 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.40%. Comparing base (a8f6054) to head (c99d213).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2745   +/-   ##
=======================================
  Coverage   52.39%   52.40%           
=======================================
  Files        1045     1045           
  Lines       27825    27825           
  Branches     6343     6325   -18     
=======================================
+ Hits        14579    14581    +2     
+ Misses      12800    12789   -11     
- Partials      446      455    +9     
Flag Coverage Δ *Carryforward flag
api 76.65% <ø> (+0.02%) ⬆️
deploy-web 37.20% <ø> (ø)
log-collector 75.35% <ø> (ø)
notifications 87.81% <ø> (ø) Carriedforward from a8f6054
provider-console 81.48% <ø> (ø)
provider-proxy 84.35% <ø> (ø)
tx-signer 79.25% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.
see 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ygrishajev ygrishajev force-pushed the feature/notification-tests branch 2 times, most recently from 6c57ab4 to 7fdf2e1 Compare February 16, 2026 10:59
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
apps/notifications/src/modules/chain/services/tx-events-service/tx-events.service.spec.ts (1)

187-195: ⚠️ Potential issue | 🟡 Minor

Align setup signature with the required test helper pattern.

Add a single inline-typed options parameter to setup to match the test setup guideline.

♻️ Suggested update
-  async function setup() {
+  async function setup({}: {} = {}) {

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."

apps/notifications/src/interfaces/alert-events/handlers/chain-events/chain-events.handler.spec.ts (1)

50-68: ⚠️ Potential issue | 🟡 Minor

Align setup signature with the required test helper pattern.

Add a single inline-typed options parameter to setup to match the test setup guideline.

♻️ Suggested update
-  async function setup() {
+  async function setup({}: {} = {}) {

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."

apps/notifications/src/modules/chain/services/block-message/block-message.service.spec.ts (1)

101-117: ⚠️ Potential issue | 🟡 Minor

Make setup follow the single-parameter/no-return-type convention.

Remove the explicit return type and add a single inline-typed options parameter.

♻️ Suggested update
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BlockMessageService;
-    blockchainClientService: MockProxy<BlockchainClientService>;
-    blockMessageParserService: MockProxy<BlockMessageParserService>;
-  }> {
+  async function setup({}: {} = {}) {

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."

apps/notifications/src/infrastructure/broker/services/state/state.service.spec.ts (1)

52-75: ⚠️ Potential issue | 🟡 Minor

Make setup follow the single-parameter/no-return-type convention.

Remove the explicit return type and add a single inline-typed options parameter.

♻️ Suggested update
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: StateService;
-    pgBossHandlerService: MockProxy<PgBossHandlerService>;
-    boss: MockProxy<PgBoss>;
-    pg: MockProxy<Pool>;
-  }> {
+  async function setup({}: {} = {}) {

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."

apps/notifications/test/functional/balance-alert.spec.ts (1)

144-163: ⚠️ Potential issue | 🟡 Minor

Align setup signature with the required test helper pattern.

Add a single inline-typed options parameter to setup to match the test setup guideline.

♻️ Suggested update
-  async function setup() {
+  async function setup({}: {} = {}) {

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."

apps/notifications/src/modules/chain/services/blockchain-client/blockchain-client.service.spec.ts (1)

52-65: ⚠️ Potential issue | 🟡 Minor

Make setup follow the single-parameter/no-return-type convention.

Remove the explicit return type and add a single inline-typed options parameter.

♻️ Suggested update
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BlockchainClientService;
-    stargateClient: MockProxy<StargateClient>;
-  }> {
+  async function setup({}: {} = {}) {

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."

🤖 Fix all issues with AI agents
In
`@apps/notifications/src/infrastructure/broker/providers/pg-boss/pg-boss.provider.spec.ts`:
- Around line 20-22: Replace the three usages of `any` with concrete types:
change the MockPgBoss factory (symbol: MockPgBoss) to an arrow function with no
parameters instead of `(..._args: any[])`, redefine the `ExecuteSqlFn` type to
use proper typed parameters for `values` and `rows` (e.g., unknown[] or specific
value/row shapes instead of `any[]`), and update the second mock created with
`vi.fn` (the function taking `options?: any`) to use a properly typed optional
parameter (e.g., `options?: PgBossOptions` or `options?: Record<string,
unknown>`). Ensure the new types are imported or declared in the test file so
the mocks and type alias compile without using `any`.
🧹 Nitpick comments (5)
apps/notifications/src/modules/alert/services/deployment/deployment.service.spec.ts (1)

17-17: Consider updating test descriptions to remove "should" prefix.

The test descriptions currently use "should" prefix which doesn't align with the coding guidelines. While these lines weren't changed in this PR, since this is a test file migration, it might be a good opportunity to update them.

-    it("should return the deployment calculated escrow balance", async () => {
+    it("returns the deployment calculated escrow balance", async () => {
-    it("should return null if deployment is closed", async () => {
+    it("returns null if deployment is closed", async () => {

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'"

Also applies to: 55-55

apps/notifications/src/modules/notifications/services/analytics/analytics.service.spec.ts (3)

11-12: Use AnalyticsService.name and remove "should" prefix from test descriptions.

Per coding guidelines:

  • Root describe should use AnalyticsService.name instead of hardcoded string to enable automated refactoring tools.
  • Test descriptions should use present simple, 3rd person singular without "should" prefix.
♻️ Proposed fix
-describe("AnalyticsService", () => {
-  it("should track events when user is sampled", async () => {
+describe(AnalyticsService.name, () => {
+  it("tracks events when user is sampled", async () => {

As per coding guidelines: "Use <Subject>.name in the root describe suite description" and "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


25-39: Refactor to use setup function with configurable sample rate.

This test duplicates mock creation instead of using the setup function. The setup function should accept a parameter to configure the sample rate, allowing all tests to use it consistently.

Also, the test description should not start with "should".

♻️ Proposed fix
-  it("should not track events when user is not sampled", async () => {
-    const amplitude = mock<Amplitude>();
-    const hasher = mock<Hasher>();
-    const configService = mock<ConfigService<Namespaced<"notifications", NotificationEnvConfig>>>();
-    const loggerService = mock<LoggerService>();
-
-    configService.getOrThrow.mockReturnValue("0.0");
-    hasher.hash.mockReturnValue(50); // Hash value that would normally be sampled
-
-    const service = new AnalyticsService(amplitude, hasher, configService, loggerService);
-
-    service.track("user123", "email_sent", { recipient_count: 1 });
-
-    expect(amplitude.track).not.toHaveBeenCalled();
-  });
+  it("does not track events when user is not sampled", async () => {
+    const { service, amplitude } = await setup({ sampleRate: "0.0" });
+
+    service.track("user123", "email_sent", { recipient_count: 1 });
+
+    expect(amplitude.track).not.toHaveBeenCalled();
+  });

And update setup function to accept a parameter:

-  async function setup() {
+  async function setup({ sampleRate = "1.0" }: { sampleRate?: string } = {}) {
     const amplitude = mock<Amplitude>();
     const hasher = mock<Hasher>();
     const configService = mock<ConfigService<Namespaced<"notifications", NotificationEnvConfig>>>();
     const loggerService = mock<LoggerService>();

-    configService.getOrThrow.mockReturnValue("1.0");
+    configService.getOrThrow.mockReturnValue(sampleRate);
     hasher.hash.mockReturnValue(50); // Mock hash value that will be sampled

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must... accept a single parameter with inline type definition".


41-41: Remove "should" prefix from test description.

♻️ Proposed fix
-  it("should track email_failed events with error details", async () => {
+  it("tracks email_failed events with error details", async () => {
apps/notifications/src/modules/chain/services/chain-events-poller/chain-events-poller.service.spec.ts (1)

141-141: Avoid casting to any.

The StargateClient as any cast violates the coding guideline that prohibits using type any. Consider creating a proper mock type or using a type assertion to a more specific mock interface.

♻️ Suggested fix
-        MockProvider(StargateClient as any),
+        MockProvider(StargateClient as unknown as new () => StargateClient),

Alternatively, you could define a proper mock type for StargateClient that satisfies the provider requirements.

As per coding guidelines: "Never use type any or cast to type any. Always define the proper TypeScript types."

Comment on lines +20 to +22
const MockPgBoss = vi.fn(function (..._args: any[]) {
return mockInstance;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd apps/notifications/src/infrastructure/broker/providers/pg-boss && head -80 pg-boss.provider.spec.ts | cat -n

Repository: akash-network/console

Length of output: 3131


🏁 Script executed:

rg -n '\bany\b' apps/notifications/src/infrastructure/broker/providers/pg-boss/pg-boss.provider.spec.ts

Repository: akash-network/console

Length of output: 314


Remove any from Vitest mock signatures and type definitions.

The test file uses any in three locations, which violates the guideline to always define proper TypeScript types:

  • Line 20: vi.fn(function (..._args: any[])) — arguments are unused; simplify to arrow function
  • Line 53: type ExecuteSqlFn type uses any[] for both values and rows—define proper types
  • Line 59: vi.fn(function (options?: any)) — parameter should be typed
✅ Suggested fix
+  type ExecuteSqlFn = (text: string, values: unknown[]) => Promise<{ rows: unknown[] }>;
+
   it("should use pool.query for executeSql", async () => {
     const config = generateBrokerConfig();
     const pool = mock<Pool>();
 
     const mockQueryResult: QueryResult = {
       command: "SELECT",
       rowCount: 0,
       oid: 0,
       rows: [],
       fields: []
     };
 
     pool.query.mockImplementation(() => Promise.resolve(mockQueryResult));
 
-    type ExecuteSqlFn = (text: string, values: any[]) => Promise<{ rows: any[] }>;
     let capturedExecuteSql: ExecuteSqlFn | undefined;
 
     const mockInstance = mock<PgBoss>();
     mockInstance.start.mockResolvedValue(mockInstance);
 
-    const MockPgBoss = vi.fn(function (options?: any) {
+    const MockPgBoss = vi.fn(function (options?: { db?: { executeSql?: ExecuteSqlFn } }) {
       if (options?.db?.executeSql) {
         capturedExecuteSql = options.db.executeSql;
       }
       return mockInstance;
     });
-    const MockPgBoss = vi.fn(function (..._args: any[]) {
-      return mockInstance;
-    });
+    const MockPgBoss = vi.fn(() => mockInstance);
📝 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.

Suggested change
const MockPgBoss = vi.fn(function (..._args: any[]) {
return mockInstance;
});
const MockPgBoss = vi.fn(() => mockInstance);
🤖 Prompt for AI Agents
In
`@apps/notifications/src/infrastructure/broker/providers/pg-boss/pg-boss.provider.spec.ts`
around lines 20 - 22, Replace the three usages of `any` with concrete types:
change the MockPgBoss factory (symbol: MockPgBoss) to an arrow function with no
parameters instead of `(..._args: any[])`, redefine the `ExecuteSqlFn` type to
use proper typed parameters for `values` and `rows` (e.g., unknown[] or specific
value/row shapes instead of `any[]`), and update the second mock created with
`vi.fn` (the function taking `options?: any`) to use a properly typed optional
parameter (e.g., `options?: PgBossOptions` or `options?: Record<string,
unknown>`). Ensure the new types are imported or declared in the test file so
the mocks and type alias compile without using `any`.

@ygrishajev ygrishajev force-pushed the feature/notification-tests branch from 7fdf2e1 to f26a393 Compare February 16, 2026 11:15
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (7)
apps/notifications/src/modules/chain/services/blockchain-client/blockchain-client.service.spec.ts (2)

15-49: ⚠️ Potential issue | 🟡 Minor

Use present-tense test descriptions without “should”.

Rename the test titles to present simple, 3rd person singular (e.g., “is defined”, “fetches a block by height”, “fetches the latest block when height is 'latest'”).
As per coding guidelines: Use present simple, 3rd person singular for test descriptions without prepending 'should'.

♻️ Suggested rename
-  it("should be defined", async () => {
+  it("is defined", async () => {
...
-    it("should fetch a block by height", async () => {
+    it("fetches a block by height", async () => {
...
-    it('should fetch the latest block when height is "latest"', async () => {
+    it('fetches the latest block when height is "latest"', async () => {

52-56: ⚠️ Potential issue | 🟡 Minor

Align setup signature with test guidelines.

setup should accept a single parameter with an inline type definition and omit the explicit return type.
As per coding guidelines: Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

♻️ Proposed adjustment
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BlockchainClientService;
-    stargateClient: MockProxy<StargateClient>;
-  }> {
+  async function setup({
+    stargateClient = mock<StargateClient>()
+  }: {
+    stargateClient?: MockProxy<StargateClient>;
+  } = {}) {
     const module = await Test.createTestingModule({
-      providers: [BlockchainClientService, MockProvider(LoggerService), { provide: StargateClient, useValue: mock<StargateClient>() }]
+      providers: [BlockchainClientService, MockProvider(LoggerService), { provide: StargateClient, useValue: stargateClient }]
     }).compile();

     return {
       module,
       service: module.get<BlockchainClientService>(BlockchainClientService),
-      stargateClient: module.get<MockProxy<StargateClient>>(StargateClient)
+      stargateClient: module.get<MockProxy<StargateClient>>(StargateClient)
     };
   }

Also applies to: 57-65

apps/notifications/src/interfaces/alert-events/handlers/chain-events/chain-events.handler.spec.ts (2)

20-21: ⚠️ Potential issue | 🟡 Minor

Rename test titles to present simple without “should”.

Suggested update
-    it("should log the received event and process alerts", async () => {
+    it("logs the received event and processes alerts", async () => {
@@
-    it("should log the received block and process balance alerts", async () => {
+    it("logs the received block and processes balance alerts", async () => {

As per coding guidelines, "Use present simple, 3rd person singular for test descriptions without prepending 'should'".

Also applies to: 35-36


50-50: ⚠️ Potential issue | 🟡 Minor

Make setup() accept a single inline-typed parameter.

Suggested update
-  async function setup() {
+  async function setup({}: { } = {}) {

As per coding guidelines, "The setup function must ... accept a single parameter with inline type definition".

apps/notifications/src/modules/alert/services/wallet-balance-alerts/wallet-balance-alerts.service.spec.ts (3)

125-152: ⚠️ Potential issue | 🟡 Minor

Update test descriptions to present-simple without “should”.

These test titles should follow the present-simple convention.

Proposed fix
-    it("should not proceed with an already triggered alert", async () => {
+    it("does not proceed with an already triggered alert", async () => {

-    it("should log error if alert repository call fails and reject", async () => {
+    it("logs error if alert repository call fails and rejects", async () => {

-    it("should log a single alert error", async () => {
+    it("logs a single alert error", async () => {

As per coding guidelines: “Use present simple, 3rd person singular for test descriptions without prepending 'should'.”

Also applies to: 194-201, 213-224


138-152: ⚠️ Potential issue | 🟡 Minor

Remove the as any cast when passing alerts.

Please keep the type safe here and in the other occurrences in this file.

Proposed fix
-      const alerts: WalletBalanceAlertOutput[] = [alert];
-      alertRepository.paginateAll.mockImplementation(async options => {
-        await options.callback(alerts as any);
-      });
+      const alerts: AlertOutput[] = [alert];
+      alertRepository.paginateAll.mockImplementation(async options => {
+        await options.callback(alerts);
+      });

As per coding guidelines: “Never use type any or cast to type any.”


236-256: ⚠️ Potential issue | 🟡 Minor

Align setup helper signature and type onMessage explicitly.

The setup function currently violates coding guidelines in three ways: it has an explicit return type (should be inferred), accepts no parameters (should accept one with inline type), and onMessage lacks explicit typing (defaults to implicit any-like Mock). Update as follows:

Proposed fix
-  async function setup(): Promise<{
-    service: WalletBalanceAlertsService;
-    loggerService: MockProxy<LoggerService>;
-    alertRepository: MockProxy<AlertRepository>;
-    conditionsMatcherService: ConditionsMatcherService;
-    alertMessageService: MockProxy<AlertMessageService>;
-    balanceHttpService: MockProxy<BalanceHttpService>;
-    onMessage: Mock;
-  }> {
+  async function setup({}: {} = {}) {
     const module: TestingModule = await Test.createTestingModule({
       providers: [
         WalletBalanceAlertsService,
         ConditionsMatcherService,
         TemplateService,
         MockProvider(AlertRepository),
         MockProvider(AlertMessageService),
         MockProvider(BalanceHttpService),
         MockProvider(LoggerService)
       ]
     }).compile();
-    const onMessage = vi.fn();
+    const onMessage: Mock<(message: ReturnType<typeof generateAlertMessage>) => void> = vi.fn();
🤖 Fix all issues with AI agents
In
`@apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts`:
- Around line 8-10: The handler created with vi.fn() is untyped and yields
implicit any; replace its creation by typing the mock function (e.g., use
vi.fn<[job: ExpectedJobType]>(() => {}) or the actual PgBoss handler signature)
so the handler variable has an explicit parameter/return type; also fix the mock
for pool.connect so its mock matches the overloaded connect signature (adjust
the MockProxy or typing used for the pool mock) to remove the need for the
`@ts-expect-error` suppressions around pool.connect in the test (reference the
handler variable and pool.connect mock setup in broker.service.spec.ts).
- Line 48: The test's handler mock is untyped (const handler = vi.fn()) which
yields Mock<any, any>; change it to a properly typed mock matching the broker
subscribe handler signature by importing the SubscribeHandler (or the concrete
handler type used by BrokerService.subscribe) and typing the mock accordingly
(e.g., create handler as a vi.fn typed to that SubscribeHandler / mocked
function type) so the mock's parameters and return type are type-checked in the
spec.
🧹 Nitpick comments (3)
apps/notifications/src/infrastructure/broker/services/broker-healthz/broker-healthz.service.spec.ts (2)

67-73: Consider moving timer setup into the setup function.

Per coding guidelines, setup function should be used instead of beforeEach. The fake timer initialization could be integrated into setup by accepting an options parameter and returning a cleanup callback.

♻️ Suggested refactor
   describe("getLivenessStatus", () => {
-    beforeEach(() => {
-      vi.useFakeTimers();
-    });
-
-    afterEach(() => {
-      vi.useRealTimers();
-    });
-
     it("returns ok if db is alive", async () => {
-      const { service, db } = await setup();
+      const { service, db, cleanup } = await setup({ useFakeTimers: true });
       db.query.mockResolvedValueOnce({} as never);

       const result = await service.getLivenessStatus();

       expect(result.status).toBe("ok");
       expect(result.data.postgres).toBe(true);
+      cleanup();
     });

And update setup:

-  async function setup(): Promise<{...}> {
+  async function setup({ useFakeTimers = false }: { useFakeTimers?: boolean } = {}) {
+    if (useFakeTimers) {
+      vi.useFakeTimers();
+    }
     const module = await Test.createTestingModule({
       ...
     }).compile();

     return {
       ...
+      cleanup: () => {
+        if (useFakeTimers) {
+          vi.useRealTimers();
+        }
+      }
     };
   }

As per coding guidelines: "Use setup function instead of beforeEach in unit and service level tests".


120-125: Remove explicit return type from setup function.

Per coding guidelines, the setup function should not have a specified return type—it should be inferred by TypeScript.

♻️ Suggested refactor
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BrokerHealthzService;
-    db: MockProxy<Pool>;
-    stateService: MockProxy<StateService>;
-    logger: MockProxy<LoggerService>;
-  }> {
+  async function setup() {

As per coding guidelines: "The setup function... not have a specified return type".

apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts (1)

63-65: Prefer overload narrowing over @ts-expect-error (apply in both tests).

The suppression hides real typing drift if pg changes. A typed overload keeps the intent explicit without suppressions.

♻️ Suggested overload narrowing
-import { vi } from "vitest";
+import { vi, type MockedFunction } from "vitest";
-      // `@ts-expect-error` Pool.connect has overloaded signatures; TS resolves to the callback variant returning void
-      pool.connect.mockResolvedValue(poolClient);
+      const connectMock = pool.connect as MockedFunction<() => Promise<PoolClient>>;
+      connectMock.mockResolvedValue(poolClient);
As per coding guidelines, "Don't add unnecessary comments to the code."

Also applies to: 91-93

Comment on lines 8 to 10
import { vi } from "vitest";
import type { MockProxy } from "vitest-mock-extended";
import { mock } from "vitest-mock-extended";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check vitest/vitest-mock-extended versions in package manifests and lockfiles
rg '"vitest' -g 'package*.json' -g '*lock*.yaml' -g '*lock*.json' | head -30

Repository: akash-network/console

Length of output: 1898


🏁 Script executed:

# Inspect the spec file to see all the changes mentioned in the scratchpad
cd apps/notifications/src/infrastructure/broker/services/broker 2>/dev/null && cat -n broker.service.spec.ts || rg -n 'broker.service.spec.ts' -A 100

Repository: akash-network/console

Length of output: 5965


Type the vi.fn() handler to avoid implicit any type.

Line 48 creates a handler with vi.fn() which defaults to Mock<any, any>. Instead, type it explicitly:

const handler = vi.fn<[job: any]>(() => {});

or with the expected signature from PgBoss. This aligns with the guideline forbidding any types in .{ts,tsx,js} files.

Additionally, the @ts-expect-error suppressions on lines 63-65 and 91-93 suggest the mock setup for pool.connect doesn't properly match the overloaded signature. Consider typing the mock to resolve the overload correctly, which would eliminate the need for the suppressions.

🤖 Prompt for AI Agents
In
`@apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts`
around lines 8 - 10, The handler created with vi.fn() is untyped and yields
implicit any; replace its creation by typing the mock function (e.g., use
vi.fn<[job: ExpectedJobType]>(() => {}) or the actual PgBoss handler signature)
so the handler variable has an explicit parameter/return type; also fix the mock
for pool.connect so its mock matches the overloaded connect signature (adjust
the MockProxy or typing used for the pool mock) to remove the need for the
`@ts-expect-error` suppressions around pool.connect in the test (reference the
handler variable and pool.connect mock setup in broker.service.spec.ts).

const queueName = `${configService.getOrThrow("broker.APP_NAME")}.${eventName}`;
const options = { prefetchCount: faker.number.int({ min: 1, max: 5 }) };
const handler = jest.fn();
const handler = vi.fn();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat -n apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts | sed -n '40,60p'

Repository: akash-network/console

Length of output: 1119


🏁 Script executed:

# Find the BrokerService definition to understand the subscribe signature
fd -e ts -e tsx | xargs grep -l "class BrokerService"

Repository: akash-network/console

Length of output: 145


🏁 Script executed:

cat -n apps/notifications/src/infrastructure/broker/services/broker/broker.service.ts | head -100

Repository: akash-network/console

Length of output: 3288


🏁 Script executed:

# Find the subscribe method signature
rg "subscribe\(" apps/notifications/src/infrastructure/broker/services/broker/broker.service.ts -A 10 -B 2

Repository: akash-network/console

Length of output: 504


🏁 Script executed:

head -40 apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts

Repository: akash-network/console

Length of output: 1535


🏁 Script executed:

# Check if SingleMsgWorkHandler is imported or available in test
rg "SingleMsgWorkHandler|import.*BrokerService" apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts -B 2 -A 2

Repository: akash-network/console

Length of output: 307


🏁 Script executed:

# Check if SingleMsgWorkHandler is exported and can be imported
rg "export.*SingleMsgWorkHandler" apps/notifications/src/infrastructure/broker/services/broker/broker.service.ts

Repository: akash-network/console

Length of output: 152


🏁 Script executed:

# Get the full test file to see the setup function and understand better
wc -l apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts

Repository: akash-network/console

Length of output: 152


🏁 Script executed:

# Get the full context around the subscribe test including setup function
cat -n apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts | sed -n '40,131p'

Repository: akash-network/console

Length of output: 4222


🏁 Script executed:

# Verify if PgBoss.Job is properly typed and available in test
rg "import.*PgBoss" apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts

Repository: akash-network/console

Length of output: 94


🏁 Script executed:

# Check if SingleMsgWorkHandler is exported from broker.service and verify the typing approach
cd apps/notifications/src/infrastructure/broker/services/broker && \
rg "export.*SingleMsgWorkHandler|export.*type SingleMsgWorkHandler" .

Repository: akash-network/console

Length of output: 172


🏁 Script executed:

# Let's verify the exact typing approach by checking if it would work correctly
# Check how vi.fn is used elsewhere in the test file with typing
rg "vi\.fn<" apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts

Repository: akash-network/console

Length of output: 47


🏁 Script executed:

# Check test coding guidelines for similar patterns in other test files
fd "\.spec\.ts$" -x grep -l "vi\.fn<" {} \; | head -5

Repository: akash-network/console

Length of output: 47


🏁 Script executed:

# Look for other handlers/callbacks in the test file to see if there's a pattern
grep -n "vi\.fn" apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts

Repository: akash-network/console

Length of output: 98


🏁 Script executed:

# Check the pg-boss types to understand Job better
rg "interface Job|type Job" --type ts | grep -i "pgboss\|pg-boss" | head -5

Repository: akash-network/console

Length of output: 168


🏁 Script executed:

# Let's see if there are other test files that properly type vi.fn with handler/callback parameters
fd "\.spec\.ts$" apps/notifications -x grep -l "Handler" {} \; | head -3

Repository: akash-network/console

Length of output: 282


🏁 Script executed:

# Check if we can use SingleMsgWorkHandler directly - see full import in test
head -20 apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts

Repository: akash-network/console

Length of output: 977


🏁 Script executed:

# Let's verify what happens when we use the suggested typing approach
# Check if SingleMsgWorkHandler needs to be imported
rg "import.*from.*broker\.service" apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts

Repository: akash-network/console

Length of output: 114


🏁 Script executed:

# Check if there are simpler typing approaches for vi.fn in other test files
rg "vi\.fn.*PgBoss" apps/notifications --type ts -A 2 -B 2 | head -20

Repository: akash-network/console

Length of output: 47


🏁 Script executed:

# Verify the exact structure of how SingleMsgWorkHandler should be used
cat apps/notifications/src/infrastructure/broker/services/broker/broker.service.ts | sed -n '10,20p'

Repository: akash-network/console

Length of output: 303


Type the handler mock to avoid implicit any.

vi.fn() defaults to Mock<any, any>. Please bind it to the subscribe handler signature to keep the test type-safe.

♻️ Suggested typing
-      const handler = vi.fn();
+      type SubscribeHandler = Parameters<BrokerService["subscribe"]>[2];
+      type HandlerArgs = Parameters<SubscribeHandler>;
+      type HandlerReturn = ReturnType<SubscribeHandler>;
+      const handler = vi.fn<HandlerArgs, HandlerReturn>();

Per coding guidelines, "Never use type any or cast to type any. Always define the proper TypeScript types."

🤖 Prompt for AI Agents
In
`@apps/notifications/src/infrastructure/broker/services/broker/broker.service.spec.ts`
at line 48, The test's handler mock is untyped (const handler = vi.fn()) which
yields Mock<any, any>; change it to a properly typed mock matching the broker
subscribe handler signature by importing the SubscribeHandler (or the concrete
handler type used by BrokerService.subscribe) and typing the mock accordingly
(e.g., create handler as a vi.fn typed to that SubscribeHandler / mocked
function type) so the mock's parameters and return type are type-checked in the
spec.

@ygrishajev ygrishajev force-pushed the feature/notification-tests branch from f26a393 to ea78dee Compare February 16, 2026 11:18
@@ -7273,29 +7273,28 @@
"@swc/cli": "^0.6.0",
Copy link
Contributor

@github-actions github-actions bot Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔄 Carefully review the package-lock.json diff

Resolve the comment if everything is ok

- node_modules/@nestjs/schematics/node_modules/readdirp                                    4.1.2   

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (10)
apps/notifications/src/modules/chain/services/tx-events-service/tx-events.service.spec.ts (2)

15-15: ⚠️ Potential issue | 🟡 Minor

Update the test description to present simple (no “should”).

Line 15 uses “should…”, which conflicts with the test-description convention. Consider:

✅ Suggested fix
-    it("should extract certain events from tx logs", async () => {
+    it("extracts certain events from tx logs", async () => {
As per coding guidelines, “Use present simple, 3rd person singular for test descriptions without prepending 'should'”.

188-191: ⚠️ Potential issue | 🟡 Minor

Make setup accept a single inline-typed parameter.

The setup helper currently takes no parameters; guidelines require a single parameter with an inline type definition. You can also use it to allow dependency overrides:

✅ Suggested fix
-  async function setup() {
+  async function setup({ cometClient = mock<Comet38Client>() }: { cometClient?: MockProxy<Comet38Client> } = {}) {
     const module = await Test.createTestingModule({
-      providers: [TxEventsService, { provide: Comet38Client, useValue: mock<Comet38Client>() }, MockProvider(LoggerService)]
+      providers: [TxEventsService, { provide: Comet38Client, useValue: cometClient }, MockProvider(LoggerService)]
     }).compile();
As per coding guidelines, “Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.”
apps/notifications/src/modules/chain/services/blockchain-client/blockchain-client.service.spec.ts (2)

16-50: ⚠️ Potential issue | 🟡 Minor

Use present-simple test descriptions (no “should”).

This violates the test description guideline. Rename to present simple, 3rd person singular.
As per coding guidelines: Use present simple, 3rd person singular for test descriptions without prepending 'should'.

Proposed update
-  it("should be defined", async () => {
+  it("is defined", async () => {
@@
-    it("should fetch a block by height", async () => {
+    it("fetches a block by height", async () => {
@@
-    it('should fetch the latest block when height is "latest"', async () => {
+    it('fetches the latest block when height is "latest"', async () => {

53-67: ⚠️ Potential issue | 🟡 Minor

Adjust setup signature to meet test helper rules.

setup must accept a single parameter with an inline type definition and must not specify a return type.
As per coding guidelines: Use setup function instead of beforeEach... The setup function must ... accept a single parameter with inline type definition ... and not have a specified return type.

Proposed update
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BlockchainClientService;
-    stargateClient: MockProxy<StargateClient>;
-  }> {
+  async function setup({
+    stargateClient = mock<StargateClient>()
+  }: { stargateClient?: MockProxy<StargateClient> }) {
     const module = await Test.createTestingModule({
-      providers: [BlockchainClientService, MockProvider(LoggerService), { provide: StargateClient, useValue: mock<StargateClient>() }]
+      providers: [BlockchainClientService, MockProvider(LoggerService), { provide: StargateClient, useValue: stargateClient }]
     }).compile();
apps/notifications/src/modules/alert/services/alert-message/alert-message.service.spec.ts (2)

12-12: ⚠️ Potential issue | 🟡 Minor

Update test descriptions to present simple (no “should”).
Use 3rd‑person present simple for test names to satisfy the test description style rule.

✅ Suggested rename
-    it("should return an alert payload with prefix", async () => {
+    it("returns an alert payload with prefix", async () => {
...
-    it("should an alert payload  without prefix", async () => {
+    it("returns an alert payload without prefix", async () => {

As per coding guidelines: “Use present simple, 3rd person singular for test descriptions without prepending 'should'.”

Also applies to: 27-27


43-45: ⚠️ Potential issue | 🟡 Minor

Adjust setup signature to match the required pattern.
The helper should accept a single parameter with an inline type definition and should not declare an explicit return type.

✅ Suggested fix
-  async function setup(): Promise<{
-    service: AlertMessageService;
-  }> {
+  async function setup({}: { }): Promise<{
+    service: AlertMessageService;
+  }> {
-  async function setup(): Promise<{
+  async function setup({}: { }) {

As per coding guidelines: “Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.”

apps/notifications/src/modules/notifications/services/notification-router/notification-router.service.spec.ts (2)

17-17: ⚠️ Potential issue | 🟡 Minor

Use present-simple test description.

Replace “should send an email” with present simple, 3rd person singular.

Proposed change
-    it("should send an email", async () => {
+    it("sends an email", async () => {

As per coding guidelines: “Use present simple, 3rd person singular for test descriptions without prepending 'should'.”


36-40: ⚠️ Potential issue | 🟡 Minor

Make setup conform to the required signature.

Remove the explicit return type and accept a single inline-typed parameter.

Proposed change
-  async function setup(): Promise<{
-    service: NotificationRouterService;
-    emailSenderService: MockProxy<EmailSenderService>;
-    notificationChannelRepository: MockProxy<NotificationChannelRepository>;
-  }> {
+  async function setup(_: {} = {}) {

As per coding guidelines: “Use setup function instead of beforeEach… The setup function must … accept a single parameter with inline type definition … and not have a specified return type.”

apps/notifications/src/infrastructure/broker/services/state/state.service.spec.ts (2)

13-42: ⚠️ Potential issue | 🟡 Minor

Update test descriptions to present simple (no “should”)

These it descriptions don’t match the project’s required grammar. Suggested rewrites below.

✍️ Proposed renames
-  it("should be defined", async () => {
+  it("is defined", async () => {
@@
-  it("should initialize with state 'stopped'", async () => {
+  it("initializes with state 'stopped'", async () => {
@@
-  it("should set state to 'active' after bootstrap", async () => {
+  it("sets state to 'active' after bootstrap", async () => {
@@
-  it("should stop pgBoss and pg pool and set state to 'stopped' on shutdown", async () => {
+  it("stops pgBoss and pg pool and sets state to 'stopped' on shutdown", async () => {
@@
-  it("should update state to 'stopped' when PgBoss emits 'stopped'", async () => {
+  it("updates state to 'stopped' when PgBoss emits 'stopped'", async () => {

As per coding guidelines, Use present simple, 3rd person singular for test descriptions without prepending 'should'.


53-59: ⚠️ Potential issue | 🟡 Minor

Align setup signature with test setup guidelines

setup should accept a single parameter with an inline type definition and should not specify a return type.

✅ Suggested adjustment
-  async function setup(): Promise<{
+  async function setup({}: {
     module: TestingModule;
     service: StateService;
     pgBossHandlerService: MockProxy<PgBossHandlerService>;
     boss: MockProxy<PgBoss>;
     pg: MockProxy<Pool>;
-  }> {
+  } = {}) {

As per coding guidelines, Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type.

🤖 Fix all issues with AI agents
In
`@apps/notifications/src/infrastructure/broker/services/state/state.service.spec.ts`:
- Around line 4-5: The test currently casts boss.on to jest.Mock which is
invalid for Vitest; update the test to use Vitest's mock utilities by treating
boss as a MockProxy<PgBoss> and use vi.mocked(boss).on (or
vi.mocked(boss).on.mock.calls / .mockImplementation as needed) to inspect or
manipulate calls to boss.on; replace any "jest.Mock" casts with vi.mocked(...)
usages and adjust assertions to read from the vi.mocked(boss).on mock call
history.
🧹 Nitpick comments (10)
apps/notifications/src/infrastructure/broker/providers/db/db.provider.spec.ts (1)

10-11: Describe suite and test description don't follow naming conventions.

Per coding guidelines:

  1. The root describe should use createPgPoolFactory.name instead of the hardcoded string "createPgPool".
  2. Test descriptions should use present simple without "should" prefix.
♻️ Proposed fix
-describe("createPgPool", () => {
-  it("should create a pool with the correct connection string", async () => {
+describe(createPgPoolFactory.name, () => {
+  it("creates a pool with the correct connection string", async () => {

As per coding guidelines: "Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings" and "Use present simple, 3rd person singular for test descriptions without prepending 'should'".

apps/notifications/test/setup-functional-tests.ts (1)

10-10: Consider whether console.error is acceptable here.

The guideline recommends LoggerService over console.error. However, since this is test infrastructure bootstrap code that executes before the application context exists, using console.error may be the only viable option. If this is intentional, no change is needed.

apps/notifications/test/functional/chain-message-alert.spec.ts (1)

20-20: Consider updating test description to remove "should".

As per coding guidelines, test descriptions should use present simple, 3rd person singular without prepending "should".

📝 Suggested change
-  it("should send an alert based on conditions", async () => {
+  it("sends an alert based on conditions", async () => {
apps/notifications/test/functional/http-tools.spec.ts (2)

21-21: Consider updating test descriptions to remove "should".

As per coding guidelines, test descriptions should use present simple, 3rd person singular without prepending "should".

📝 Suggested changes
-    it("should succeed with valid request and response", async () => {
+    it("succeeds with valid request and response", async () => {
-    it("should fail with invalid body", async () => {
+    it("fails with invalid body", async () => {
-    it("should fail with invalid query", async () => {
+    it("fails with invalid query", async () => {
-    it("should return 500 on invalid response schema", async () => {
+    it("returns 500 on invalid response schema", async () => {

Also applies to: 32-32, 41-41, 50-50


63-65: Remove explicit return type from setup function.

As per coding guidelines, the setup function should not have a specified return type.

♻️ Suggested change
-  async function setup(): Promise<{
-    app: INestApplication;
-    logger: MockProxy<LoggerService>;
-  }> {
+  async function setup() {
apps/notifications/src/lib/rich-error/rich-error.spec.ts (1)

5-5: Consider using RichError.name instead of hardcoded string.

This enables automated refactoring tools to find all references when renaming the class. As per coding guidelines: "Use <Subject>.name in the root describe suite description."

This is a pre-existing issue, so feel free to address it in a separate PR if out of scope for this migration.

♻️ Suggested change
-describe("RichError", () => {
+describe(RichError.name, () => {
apps/notifications/src/infrastructure/db/services/db-healthz/db-healthz.service.spec.ts (2)

48-54: Pre-existing: Consider consolidating timer setup into the setup function.

The beforeEach/afterEach pattern for timers predates this PR, but per coding guidelines, test setup should use a setup function. This could be refactored by returning timer control from setup and calling vi.useRealTimers() in individual tests or via a cleanup callback.

This is a low-priority improvement that can be addressed in a future PR. As per coding guidelines: "Use setup function instead of beforeEach in test files."


99-115: Pre-existing: Replace any with a proper schema type.

The NodePgDatabase<any> usage on lines 102, 106, and 112 violates the guideline against using any. Consider defining a minimal schema type or using unknown if the schema isn't needed for these tests.

This is a pre-existing issue not introduced by this migration. As per coding guidelines: "Never use type any or cast to type any. Always define the proper TypeScript types."

apps/notifications/src/modules/chain/services/block-message/block-message.service.spec.ts (2)

15-15: Test description should use present simple tense.

Per coding guidelines, test descriptions should use present simple, 3rd person singular without prepending "should".

♻️ Suggested fix
-  it("should be defined", async () => {
+  it("is defined", async () => {

102-118: Setup function has explicit return type.

Per coding guidelines, the setup function should not have a specified return type to allow TypeScript inference.

♻️ Suggested fix
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BlockMessageService;
-    blockchainClientService: MockProxy<BlockchainClientService>;
-    blockMessageParserService: MockProxy<BlockMessageParserService>;
-  }> {
+  async function setup() {

Comment on lines +4 to +5
import { describe, expect, it } from "vitest";
import type { MockProxy } from "vitest-mock-extended";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n apps/notifications/src/infrastructure/broker/services/state/state.service.spec.ts

Repository: akash-network/console

Length of output: 3132


🏁 Script executed:

rg "vitest-mock-extended" apps/notifications/ --type ts --type tsx -A 2 | head -50

Repository: akash-network/console

Length of output: 92


🏁 Script executed:

rg "vitest-mock-extended" apps/notifications --type ts -A 2 | head -50

Repository: akash-network/console

Length of output: 5127


Replace jest.Mock cast with Vitest mock API

Line 45 casts boss.on to jest.Mock, which doesn't exist in Vitest. This will cause a compile/runtime error. Since boss is a MockProxy<PgBoss>, use vi.mocked() to access the mock's call history:

Fix
-import { describe, expect, it } from "vitest";
+import { describe, expect, it, vi } from "vitest";
-    const stoppedListener = (boss.on as jest.Mock).mock.calls.find(([event]: [string]) => event === "stopped")?.[1] as (() => void) | undefined;
+    const stoppedListener = vi.mocked(boss.on).mock.calls.find(([event]: [string]) => event === "stopped")?.[1] as (() => void) | undefined;
🤖 Prompt for AI Agents
In
`@apps/notifications/src/infrastructure/broker/services/state/state.service.spec.ts`
around lines 4 - 5, The test currently casts boss.on to jest.Mock which is
invalid for Vitest; update the test to use Vitest's mock utilities by treating
boss as a MockProxy<PgBoss> and use vi.mocked(boss).on (or
vi.mocked(boss).on.mock.calls / .mockImplementation as needed) to inspect or
manipulate calls to boss.on; replace any "jest.Mock" casts with vi.mocked(...)
usages and adjust assertions to read from the vi.mocked(boss).on mock call
history.

@ygrishajev ygrishajev force-pushed the feature/notification-tests branch from ea78dee to c99d213 Compare February 16, 2026 12:56
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (16)
apps/notifications/src/modules/chain/services/block-message/block-message.service.spec.ts (2)

15-99: ⚠️ Potential issue | 🟡 Minor

Use present‑simple test titles (remove “should”).

The test descriptions should be present simple, third‑person singular, without “should”.
As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'."

✏️ Suggested renames
-  it("should be defined", async () => {
+  it("is defined", async () => {
...
-    it("should fetch a block and parse its messages", async () => {
+    it("fetches a block and parses its messages", async () => {
...
-    it('should fetch the latest block when height is "latest"', async () => {
+    it('fetches the latest block when height is "latest"', async () => {
...
-    it("should filter messages by type when messageTypes is provided", async () => {
+    it("filters messages by type when messageTypes is provided", async () => {
...
-    it("should return empty messages array when block has no transactions", async () => {
+    it("returns empty messages array when block has no transactions", async () => {

102-108: ⚠️ Potential issue | 🟡 Minor

Adjust setup signature to match the test setup guideline.

The helper should accept a single parameter with an inline type and must not specify a return type.
As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."

🛠️ Suggested adjustment
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BlockMessageService;
-    blockchainClientService: MockProxy<BlockchainClientService>;
-    blockMessageParserService: MockProxy<BlockMessageParserService>;
-  }> {
+  async function setup({}: {} = {}) {
apps/notifications/src/modules/chain/services/message-decoder/message-decoder.service.spec.ts (2)

14-20: ⚠️ Potential issue | 🟡 Minor

Use present-simple test names (no “should”).
Rename descriptions like “should be defined” → “is defined” to match the test naming convention.

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


95-106: ⚠️ Potential issue | 🟡 Minor

Align setup signature with test conventions.
The helper should accept a single inline-typed parameter and avoid an explicit return type.

♻️ Proposed fix
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: MessageDecoderService;
-  }> {
+  async function setup({}: {} = {}) {
As per coding guidelines: "Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."
apps/notifications/src/modules/alert/services/deployment-alert/deployment-alert.service.spec.ts (2)

23-27: ⚠️ Potential issue | 🟡 Minor

Use present-simple test names (no “should”).
E.g., “creates a new alert when it does not exist.”

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


209-225: ⚠️ Potential issue | 🟡 Minor

Add a single inline-typed parameter to setup.
The helper should accept one parameter (with inline type) to match the test setup convention.

♻️ Proposed fix
-  async function setup() {
+  async function setup({}: {} = {}) {
As per coding guidelines: "Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."
apps/notifications/src/infrastructure/broker/services/state/state.service.spec.ts (2)

13-20: ⚠️ Potential issue | 🟡 Minor

Use present-simple test names (no “should”).
E.g., “is defined”, “initializes with state ‘stopped’”, “sets state to ‘active’ after bootstrap”.

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


53-75: ⚠️ Potential issue | 🟡 Minor

Align setup signature with test conventions.
Add a single inline-typed parameter and remove the explicit return type.

♻️ Proposed fix
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: StateService;
-    pgBossHandlerService: MockProxy<PgBossHandlerService>;
-    boss: MockProxy<PgBoss>;
-    pg: MockProxy<Pool>;
-  }> {
+  async function setup({}: {} = {}) {
As per coding guidelines: "Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."
apps/notifications/src/modules/notifications/services/notification-router/notification-router.service.spec.ts (2)

17-18: ⚠️ Potential issue | 🟡 Minor

Use present-simple test names (no “should”).
E.g., “sends an email”.

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


36-49: ⚠️ Potential issue | 🟡 Minor

Align setup signature with test conventions.
Remove the explicit return type and add a single inline-typed parameter.

♻️ Proposed fix
-  async function setup(): Promise<{
-    service: NotificationRouterService;
-    emailSenderService: MockProxy<EmailSenderService>;
-    notificationChannelRepository: MockProxy<NotificationChannelRepository>;
-  }> {
+  async function setup({}: {} = {}) {
As per coding guidelines: "Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."
apps/notifications/test/functional/balance-alert.spec.ts (2)

24-26: ⚠️ Potential issue | 🟡 Minor

Use <Subject>.name and present-simple test names.
Consider describe(ChainEventsHandler.name, ...) and rename to “sends an alert based on conditions.”

As per coding guidelines: "Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references."
As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


144-162: ⚠️ Potential issue | 🟡 Minor

Add a single inline-typed parameter to setup.
This keeps the functional tests aligned with the shared setup convention.

♻️ Proposed fix
-  async function setup() {
+  async function setup({}: {} = {}) {
As per coding guidelines: "Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."
apps/notifications/src/interfaces/notifications-events/handlers/notification/notification.handler.spec.ts (2)

15-22: ⚠️ Potential issue | 🟡 Minor

Use present-simple test names (no “should”).
E.g., “is defined”, “sends a notification”.

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


31-44: ⚠️ Potential issue | 🟡 Minor

Align setup signature with test conventions.
Remove the explicit return type and add a single inline-typed parameter.

♻️ Proposed fix
-  async function setup(): Promise<{
-    controller: NotificationHandler;
-    notificationRouter: MockProxy<NotificationRouterService>;
-    loggerService: MockProxy<LoggerService>;
-  }> {
+  async function setup({}: {} = {}) {
As per coding guidelines: "Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."
apps/notifications/test/functional/notification-channel-crud.spec.ts (2)

16-18: ⚠️ Potential issue | 🟡 Minor

Use <Subject>.name and present-simple test names.
Replace the hardcoded suite name (e.g., describe(NotificationChannelController.name, ...)) and rename the test to “performs all CRUD operations against contact points.”

As per coding guidelines: "Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references."
As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


100-118: ⚠️ Potential issue | 🟡 Minor

Align setup signature with test conventions.
Remove the explicit return type and add a single inline-typed parameter.

♻️ Proposed fix
-  async function setup(): Promise<{
-    app: INestApplication;
-  }> {
+  async function setup({}: {} = {}) {
As per coding guidelines: "Use `setup` function instead of `beforeEach` in test files. The `setup` function must be at the bottom of the root `describe` block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."
🤖 Fix all issues with AI agents
In `@apps/notifications/src/lib/value-backoff/value-backoff.spec.ts`:
- Around line 6-7: Rename the test descriptions to present simple, 3rd person
singular without the leading "should": replace "should return value immediately
when available on first attempt" with "returns value immediately when available
on first attempt" and similarly update the other test titles referenced (lines
with the strings at ~16-17, 30-31, 45-46, 60-61, 73-74, 86-88, 96-98) to use the
same pattern (e.g., "returns ...", "retries ...", "throws ..." as appropriate)
so every it(...) description is present simple, 3rd person singular and does not
start with "should".
- Line 5: Replace the hardcoded test suite title with the function's .name to
make renames safe: update the root describe that currently uses "valueBackoff"
to use valueBackoff.name instead so the suite references the actual exported
function symbol (valueBackoff) rather than a string literal.
🧹 Nitpick comments (5)
apps/notifications/src/lib/rich-error/rich-error.spec.ts (2)

5-5: Consider using RichError.name instead of hardcoded string.

This enables automated refactoring tools to find all references when renaming the class.

♻️ Suggested change
-describe("RichError", () => {
+describe(RichError.name, () => {

As per coding guidelines: "Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings."


7-7: Consider removing "should" prefix from test descriptions.

The coding guidelines require using present simple, 3rd person singular without prepending "should". This applies to all test descriptions in this file (lines 7, 12, 17, 22, 30, 35, 41, 49, 63, 71, 80, 88).

♻️ Example changes
-    it("should return the same message if input is a string", () => {
+    it("returns the same message if input is a string", () => {
-    it("should extract message from Error object", () => {
+    it("extracts message from Error object", () => {

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'."

apps/notifications/src/infrastructure/broker/services/broker-healthz/broker-healthz.service.spec.ts (2)

15-15: Optional: Align test description with coding guidelines.

The test description uses "should be defined" but the coding guidelines specify using present simple, 3rd person singular without prepending "should".

✨ Suggested change
-  it("should be defined", async () => {
+  it("is defined", async () => {

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".


120-126: Optional: Remove explicit return type from setup function.

The coding guidelines specify that the setup function should "not have a specified return type" to let TypeScript infer it.

✨ Suggested change
-  async function setup(): Promise<{
-    module: TestingModule;
-    service: BrokerHealthzService;
-    db: MockProxy<Pool>;
-    stateService: MockProxy<StateService>;
-    logger: MockProxy<LoggerService>;
-  }> {
+  async function setup() {

As per coding guidelines: "The setup function must [...] not have a specified return type."

apps/notifications/src/infrastructure/db/services/db-healthz/db-healthz.service.spec.ts (1)

48-54: Remove beforeEach/afterEach and handle timers per test.

Guidelines require using a setup function instead of beforeEach. Consider moving fake-timer setup into each test (or into setup via an options param) and restore in a finally block.

Proposed change (pattern for each liveness test)
-    beforeEach(() => {
-      vi.useFakeTimers();
-    });
-
-    afterEach(() => {
-      vi.useRealTimers();
-    });
-
     it("returns ok if db is alive", async () => {
-      const { service, db } = await setup();
-      db.execute.mockResolvedValueOnce(mockQueryResult());
-
-      const result = await service.getLivenessStatus();
-
-      expect(result.status).toBe("ok");
-      expect(result.data.postgres).toBe(true);
+      vi.useFakeTimers();
+      try {
+        const { service, db } = await setup();
+        db.execute.mockResolvedValueOnce(mockQueryResult());
+
+        const result = await service.getLivenessStatus();
+
+        expect(result.status).toBe("ok");
+        expect(result.data.postgres).toBe(true);
+      } finally {
+        vi.useRealTimers();
+      }
     });

As per coding guidelines: "Use setup function instead of beforeEach in test files. The setup function must be at the bottom of the root describe block, should create an object under test and return it, accept a single parameter with inline type definition, avoid shared state, and not have a specified return type."


import { MESSAGE, valueBackoff } from "./value-backoff";

describe("valueBackoff", () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use <Subject>.name in the root describe.

This suite should use the function’s .name to keep refactors safe.

🔧 Suggested update
-describe("valueBackoff", () => {
+describe(valueBackoff.name, () => {

As per coding guidelines: "Use <Subject>.name in the root describe suite description instead of hardcoded class/service name strings to enable automated refactoring tools to find all references".

📝 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.

Suggested change
describe("valueBackoff", () => {
describe(valueBackoff.name, () => {
🤖 Prompt for AI Agents
In `@apps/notifications/src/lib/value-backoff/value-backoff.spec.ts` at line 5,
Replace the hardcoded test suite title with the function's .name to make renames
safe: update the root describe that currently uses "valueBackoff" to use
valueBackoff.name instead so the suite references the actual exported function
symbol (valueBackoff) rather than a string literal.

Comment on lines 6 to +7
it("should return value immediately when available on first attempt", async () => {
const mockRequest = jest.fn().mockResolvedValue("success");
const mockRequest = vi.fn().mockResolvedValue("success");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Rename test descriptions to present simple (no “should”).

Each it description should be present simple, 3rd person singular without “should”.

✍️ Example renames
-it("should return value immediately when available on first attempt", async () => {
+it("returns value immediately when available on first attempt", async () => {
-it("should retry until value is available", async () => {
+it("retries until value is available", async () => {

As per coding guidelines: "Use present simple, 3rd person singular for test descriptions without prepending 'should'".

Also applies to: 16-17, 30-31, 45-46, 60-61, 73-74, 86-88, 96-98

🤖 Prompt for AI Agents
In `@apps/notifications/src/lib/value-backoff/value-backoff.spec.ts` around lines
6 - 7, Rename the test descriptions to present simple, 3rd person singular
without the leading "should": replace "should return value immediately when
available on first attempt" with "returns value immediately when available on
first attempt" and similarly update the other test titles referenced (lines with
the strings at ~16-17, 30-31, 45-46, 60-61, 73-74, 86-88, 96-98) to use the same
pattern (e.g., "returns ...", "retries ...", "throws ..." as appropriate) so
every it(...) description is present simple, 3rd person singular and does not
start with "should".

@ygrishajev ygrishajev merged commit 0eea42d into main Feb 16, 2026
53 of 56 checks passed
@ygrishajev ygrishajev deleted the feature/notification-tests branch February 16, 2026 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments