Skip to content

MB-0501: Bootstrap test framework and fixtures#74

Open
FarisZR wants to merge 1 commit intomainfrom
automation/mb-0501
Open

MB-0501: Bootstrap test framework and fixtures#74
FarisZR wants to merge 1 commit intomainfrom
automation/mb-0501

Conversation

@FarisZR
Copy link
Copy Markdown
Member

@FarisZR FarisZR commented Feb 21, 2026

Summary

  • add Vitest test framework with coverage support and npm test scripts
  • add reusable fixture and mock utilities under test/ for future suites
  • add mandatory smoke tests for one discourse module and one platform module
  • add GitHub Actions test workflow to run baseline tests on pull requests
  • document local test and coverage commands in README

Validation

  • npm test
  • npm run test:coverage

Closes #59

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 21, 2026

Walkthrough

This pull request establishes foundational testing infrastructure for the project. It adds Vitest as the test runner with npm scripts for testing and coverage reporting, configured via vitest.config.mjs. GitHub Actions workflow is added to execute tests on pushes and pull requests to the main branch. Test utilities are created for fixture loading and mock creation. Smoke tests are added for the Discourse getCategories module and Telegram start command, along with corresponding test fixtures. Development dependencies (vitest and @vitest/coverage-v8) are added to package.json. Documentation and configuration files are updated accordingly.

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'MB-0501: Bootstrap test framework and fixtures' directly and clearly summarizes the main purpose of the changeset: establishing test infrastructure.
Description check ✅ Passed The description comprehensively relates to the changeset, outlining framework setup, utilities, smoke tests, CI workflow, and documentation—all present in the changes.
Linked Issues check ✅ Passed The PR successfully implements all key requirements: test runner with coverage (vitest.config.mjs, package.json), npm scripts (package.json), fixtures and mocks (test/utils/), smoke tests for discourse and telegram modules, and CI workflow (.github/workflows/tests.yml).
Out of Scope Changes check ✅ Passed All changes are directly aligned with the PR objectives: test framework setup, fixtures, utilities, smoke tests, CI configuration, and README documentation—no out-of-scope modifications detected.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch automation/mb-0501

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

import { createFetchJsonResponse } from '../utils/mocks.js';
import { readFixture } from '../utils/fixtures.js';

const mocks = vi.hoisted(() => ({

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
mocks.readJsonSyncMock.mockReturnValue({ url: 'https://forum.example' });
mocks.fetchMock.mockResolvedValue(createFetchJsonResponse(readFixture('discourse', 'categories.json')));

const { default: getCategories } = await import('../../discourse/getCategories.js');

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'destructuring binding' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
mocks.readJsonSyncMock.mockReturnValue({ url: 'https://forum.example' });
mocks.fetchMock.mockResolvedValue(createFetchJsonResponse(readFixture('discourse', 'categories.json')));

const { default: getCategories } = await import('../../discourse/getCategories.js');

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
mocks.fetchMock.mockResolvedValue(createFetchJsonResponse(readFixture('discourse', 'categories.json')));

const { default: getCategories } = await import('../../discourse/getCategories.js');
const categories = await getCategories();

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
import { createTelegramContext } from '../utils/mocks.js';
import { readFixture } from '../utils/fixtures.js';

const mocks = vi.hoisted(() => ({

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
reply: vi.fn()
});

const { default: start } = await import('../../telegram/command/start.js');

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
reply: vi.fn()
});

const { default: start } = await import('../../telegram/command/start.js');

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'destructuring binding' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
Comment thread test/utils/fixtures.js
import path from 'path';
import { fileURLToPath } from 'url';

const utilsDir = path.dirname(fileURLToPath(import.meta.url));

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
Comment thread test/utils/fixtures.js
import { fileURLToPath } from 'url';

const utilsDir = path.dirname(fileURLToPath(import.meta.url));
const fixturesDir = path.join(utilsDir, '..', 'fixtures');

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
Comment thread test/utils/fixtures.js
const fixturesDir = path.join(utilsDir, '..', 'fixtures');

export function readFixture(...segments) {
const fixturePath = path.join(fixturesDir, ...segments);

Check notice

Code scanning / Jshint (reported by Codacy)

Prohibits the use of __iterator__ property due to compatibility issues Note test

'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz).
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/utils/fixtures.js`:
- Around line 1-3: Imports are inconsistent: `fs` is imported with the node:
prefix while `path` and `fileURLToPath` are not; update the `import path from
'path'` and `import { fileURLToPath } from 'url'` statements to use the same
`node:` prefix (i.e., `node:path` and `node:url`) so all built-in modules in
this file use the `node:` scheme and remain consistent; locate these imports by
the symbols `path` and `fileURLToPath` in the top of the file and change their
module specifiers accordingly.

In `@test/utils/mocks.js`:
- Around line 7-25: The createTelegramContext helper uses a shallow spread of
overrides which will replace entire nested objects (e.g., passing { from: { id:
999 } } drops username/first_name); change it to perform a deep merge between
the default context object and overrides so partial nested overrides preserve
other properties (either by using a proven utility like lodash.merge/mergeWith
or a small recursive deepMerge helper) and update the createTelegramContext
signature to call that deep merge on the default object and overrides (keep
function name createTelegramContext and the overrides parameter), or
alternatively add a short comment/docstring above createTelegramContext
explaining the current shallow-merge behavior if you prefer not to change
implementation.

Comment thread test/utils/fixtures.js
Comment on lines +1 to +3
import fs from 'node:fs';
import path from 'path';
import { fileURLToPath } from 'url';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Inconsistent Node.js built-in module import prefixes.

Line 1 uses node:fs, but lines 2-3 use path and url without the node: prefix. Consider using consistent prefixes for clarity.

Suggested consistency fix
 import fs from 'node:fs';
-import path from 'path';
-import { fileURLToPath } from 'url';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/utils/fixtures.js` around lines 1 - 3, Imports are inconsistent: `fs` is
imported with the node: prefix while `path` and `fileURLToPath` are not; update
the `import path from 'path'` and `import { fileURLToPath } from 'url'`
statements to use the same `node:` prefix (i.e., `node:path` and `node:url`) so
all built-in modules in this file use the `node:` scheme and remain consistent;
locate these imports by the symbols `path` and `fileURLToPath` in the top of the
file and change their module specifiers accordingly.

Comment thread test/utils/mocks.js
Comment on lines +7 to +25
export function createTelegramContext(overrides = {}) {
return {
from: {
id: 1001,
username: 'smoke_user',
first_name: 'Smoke'
},
chat: {
id: 1001,
username: 'smoke_user',
first_name: 'Smoke',
type: 'private'
},
message: {
message_id: 42
},
...overrides
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Shallow merge may cause unexpected behavior when overriding nested properties.

The spread operator ...overrides only performs a shallow merge. If a test passes { from: { id: 999 } }, it will replace the entire from object, losing username and first_name. This may be intentional, but consider documenting this behavior or implementing deep merge if partial nested overrides are needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/utils/mocks.js` around lines 7 - 25, The createTelegramContext helper
uses a shallow spread of overrides which will replace entire nested objects
(e.g., passing { from: { id: 999 } } drops username/first_name); change it to
perform a deep merge between the default context object and overrides so partial
nested overrides preserve other properties (either by using a proven utility
like lodash.merge/mergeWith or a small recursive deepMerge helper) and update
the createTelegramContext signature to call that deep merge on the default
object and overrides (keep function name createTelegramContext and the overrides
parameter), or alternatively add a short comment/docstring above
createTelegramContext explaining the current shallow-merge behavior if you
prefer not to change implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MB-0501][P0] Bootstrap test framework and fixtures

2 participants