Skip to content

feat: add tests, coverage, and Codecov CI setup#1

Merged
printAlexis merged 1 commit into
masterfrom
feat/coverage-codecov
Apr 23, 2026
Merged

feat: add tests, coverage, and Codecov CI setup#1
printAlexis merged 1 commit into
masterfrom
feat/coverage-codecov

Conversation

@printAlexis
Copy link
Copy Markdown
Owner

No description provided.

Copilot AI review requested due to automatic review settings April 23, 2026 13:08
@printAlexis printAlexis merged commit cf27cbd into master Apr 23, 2026
1 check passed
@codecov-commenter
Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a modular User API (entities/services/controllers) and introduces Jest + Supertest tests with coverage reporting and Codecov upload via GitHub Actions.

Changes:

  • Implement User entity, service, and controller, and wire routes in index.js.
  • Add unit + web/integration tests and Jest coverage thresholds/config.
  • Update CI workflow to run tests, generate coverage, and upload to Codecov; refine Docker build.

Reviewed changes

Copilot reviewed 12 out of 14 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/web/api.test.js Adds Supertest-based integration tests for API endpoints
tests/unit/UserService.test.js Adds unit tests for UserService behavior
tests/unit/User.test.js Adds unit tests for User entity serialization/validation
src/services/UserService.js Implements in-memory user CRUD + health reporting
src/entities/User.js Adds User entity with validation and toJSON()
src/controllers/UserController.js Adds controller methods mapping HTTP to service operations
package.json Adds Jest/Supertest + test scripts and coverage
jest.config.js Configures coverage collection and global thresholds
index.js Wires routes/controllers and exports app for testing
README.md Documents architecture, scripts, API, and CI/Codecov
Dockerfile Switches to npm ci, narrows COPY set, adds HEALTHCHECK
.github/workflows/action.yml Runs tests, builds Docker image, uploads coverage to Codecov
.dockerignore Excludes tests/docs/git metadata from Docker build context

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/web/api.test.js
Comment on lines +2 to +4
const app = require('../../index');

describe('User API Endpoints', () => {
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

The integration tests import a singleton app instance, which (given index.js creates a single in-memory UserService) couples tests through shared state within the file. To keep tests isolated and easier to extend, consider exporting an app factory (e.g., createApp() that instantiates fresh services/controllers) or resetting the module between tests (e.g., jest.resetModules() + re-require) so each test/describe can start from a known clean state.

Suggested change
const app = require('../../index');
describe('User API Endpoints', () => {
let app;
describe('User API Endpoints', () => {
beforeEach(() => {
jest.resetModules();
app = require('../../index');
});

Copilot uses AI. Check for mistakes.
Comment thread tests/web/api.test.js
const res = await request(app)
.get('/users')
.expect(200);
expect(Array.isArray(res.body)).toBe(true);
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

This test name claims the users array is empty, but the assertion only checks that the response is an array. Either assert res.body is empty (e.g., length 0) or rename the test to match what it verifies.

Suggested change
expect(Array.isArray(res.body)).toBe(true);
expect(res.body).toEqual([]);

Copilot uses AI. Check for mistakes.
}

/**
* GET / - Health check
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

The doc comment says GET / - Health check, but the route wired in index.js is /health. Update the comment to prevent confusion for future maintainers.

Suggested change
* GET / - Health check
* GET /health - Health check

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +43
const { id } = req.params;
const user = this.userService.getUserById(parseInt(id));
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.status(200).json(user.toJSON());
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

Use parseInt(id, 10) (or Number(id)) instead of parseInt(id) to avoid radix ambiguity and keep numeric parsing explicit. The same applies to the parseInt(id) calls in updateUser and deleteUser.

Copilot uses AI. Check for mistakes.
Comment thread package.json
"test": "echo \"Tests passed\""
"test": "jest --coverage",
"test:unit": "jest tests/unit --no-coverage",
"test:web": "jest tests/web --forceExit --no-coverage",
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

--forceExit can hide resource leaks (open handles) and make test cleanup issues harder to detect. Prefer removing it and using --detectOpenHandles while fixing the underlying leak, or ensure the app/resources are properly torn down in tests.

Suggested change
"test:web": "jest tests/web --forceExit --no-coverage",
"test:web": "jest tests/web --detectOpenHandles --no-coverage",

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +39
- name: Run Unit Tests
run: npm run test:unit

- name: Run Web/Integration Tests
run: npm run test:web

Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

CI runs the test suite multiple times (unit, web, then all again for coverage), which increases duration and compute cost. Consider running only npm test (coverage) and, if you still want separate visibility, use Jest projects/groups or split by testMatch while generating coverage once.

Suggested change
- name: Run Unit Tests
run: npm run test:unit
- name: Run Web/Integration Tests
run: npm run test:web

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +114 to +122
| Méthode | Route | Description |
|---------|-------|-------------|
| GET | `/` | Message de bienvenue |
| GET | `/health` | Vérification de santé du service |
| GET | `/users` | Récupérer tous les utilisateurs |
| GET | `/users/:id` | Récupérer un utilisateur |
| POST | `/users` | Créer un utilisateur |
| PUT | `/users/:id` | Mettre à jour un utilisateur |
| DELETE | `/users/:id` | Supprimer un utilisateur |
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

This Markdown table has an extra leading | on each line (|| ...), which can break rendering on GitHub. Use standard table syntax with a single leading pipe per row.

Copilot uses AI. Check for mistakes.
Comment thread Dockerfile
ENTRYPOINT ["node", "index.js"] No newline at end of file

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD node -e "require('http').get('http://localhost:8080/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

The HEALTHCHECK script doesn't consume the response body or explicitly handle connection errors/timeouts, which can lead to hanging checks or noisy/unreliable health reporting. Consider draining the response (r.resume()), adding an error handler, and ensuring the process exits deterministically on failure (or use a lightweight tool like wget if available).

Suggested change
CMD node -e "require('http').get('http://localhost:8080/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})"
CMD node -e "const http = require('http'); const req = http.get('http://localhost:8080/health', (r) => { r.resume(); process.exit(r.statusCode === 200 ? 0 : 1); }); req.on('error', () => process.exit(1)); req.setTimeout(2500, () => { req.destroy(); process.exit(1); });"

Copilot uses AI. Check for mistakes.
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.

3 participants