Skip to content

Conversation

@Breimerct
Copy link
Owner

This pull request introduces significant changes to enhance testing capabilities, improve code organization, and add new features to the HttpClient. The key updates include the integration of vitest for testing, the addition of comprehensive test cases, the adoption of path aliases, and the introduction of a new method in the HttpClient class.

Testing Enhancements:

  • Added vitest as the testing framework, configured in vitest.config.ts with support for code coverage, test inclusion/exclusion patterns, and global test utilities.
  • Created a new tsconfig.test.json file to support path aliases (@/* for src and @tests/* for tests) and include test-related files.
  • Added comprehensive test cases for the HttpClient, helpers, and type definitions, covering various scenarios such as HTTP methods, interceptors, and error handling. [1] [2] [3] [4]

Code Organization:

  • Replaced relative imports with path aliases (@/) in files like src/app/app.ts, src/client/http-client.ts, and src/helpers/utils.ts for better maintainability and readability. [1] [2] [3] [4]

New Features:

  • Introduced a getConfig method in the HttpClient class to retrieve the current configuration, enhancing its usability.

Build and Test Integration:

  • Updated the package.json to include new vitest commands (test, test:watch, test:ui, test:coverage, test:ci) and added @vitest dependencies. [1] [2]
  • Modified the GitHub Actions workflow (publish.yml) to execute tests before building the project.

@Breimerct Breimerct requested a review from Copilot June 15, 2025 10:51
Copy link

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

This PR sets up Vitest for testing, adds comprehensive tests, refactors imports to use path aliases, and introduces a new getConfig method in HttpClient.

  • Configure Vitest and TypeScript for tests (vitest.config.ts, tsconfig.test.json)
  • Add tests for types, helpers, HttpClient, and app-level functions
  • Refactor imports to @/ aliases and expose getConfig in HttpClient
  • Update package scripts and CI workflow to run tests

Reviewed Changes

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

Show a summary per file
File Description
vitest.config.ts Configure Vitest (environment, coverage, globals)
tsconfig.test.json Add test-specific TS config and path aliases
tests/types/types.test.ts Validate type definitions
tests/helpers/helpers.test.ts Test helper utilities
tests/client/http-client.test.ts Exercise HttpClient methods over network
tests/app/app.test.ts Test app-level HTTP shortcuts
src/helpers/utils.ts Update imports to use path aliases
src/client/http-client.ts Update imports and add getConfig
src/app/app.ts Update imports to use path aliases
package.json Add Vitest scripts and dev dependencies
.github/workflows/publish.yml Run tests before build in CI
Comments suppressed due to low confidence (1)

.github/workflows/publish.yml:100

  • Silently skipping failing or missing tests may mask regressions; it’s better to let the step fail so that CI surfaces test failures.
run: npm run test || echo "No tests found, skipping..."

Comment on lines +42 to +52
const signal = createTimeoutSignal(1000);
expect(signal).toBeInstanceOf(AbortSignal);
expect(signal.aborted).toBe(false);

// Wait for the timeout to complete
return new Promise((resolve) => {
setTimeout(() => {
expect(signal.aborted).toBe(true);
resolve(true);
}, 1000);
});
Copy link

Copilot AI Jun 15, 2025

Choose a reason for hiding this comment

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

This test waits a real 1s timeout, which can slow down the suite; consider using Vitest's fake timers or mocking setTimeout to simulate the timeout instantly.

Suggested change
const signal = createTimeoutSignal(1000);
expect(signal).toBeInstanceOf(AbortSignal);
expect(signal.aborted).toBe(false);
// Wait for the timeout to complete
return new Promise((resolve) => {
setTimeout(() => {
expect(signal.aborted).toBe(true);
resolve(true);
}, 1000);
});
vi.useFakeTimers();
const signal = createTimeoutSignal(1000);
expect(signal).toBeInstanceOf(AbortSignal);
expect(signal.aborted).toBe(false);
// Simulate the timeout
vi.advanceTimersByTime(1000);
expect(signal.aborted).toBe(true);
vi.restoreAllMocks();

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +22
const client = new HttpClient({ baseURL });
const response = await client.request({ method: 'GET', url: '/users' });

expect(response.status).toBe(200);
expect(response.content).not.toBeNull();
});

it('should handle GET request', async () => {
const client = new HttpClient({ baseURL });
Copy link

Copilot AI Jun 15, 2025

Choose a reason for hiding this comment

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

[nitpick] These tests perform real HTTP requests against an external API, which can be slow or flaky; consider mocking fetch or using a local mock server to improve reliability and speed.

Suggested change
const client = new HttpClient({ baseURL });
const response = await client.request({ method: 'GET', url: '/users' });
expect(response.status).toBe(200);
expect(response.content).not.toBeNull();
});
it('should handle GET request', async () => {
const client = new HttpClient({ baseURL });
const client = new HttpClient({ baseURL });
// Mock the response for the GET request
vi.spyOn(client, 'request').mockResolvedValue({
status: 200,
content: [{ id: 1, name: 'John Doe' }],
});
const response = await client.request({ method: 'GET', url: '/users' });
expect(response.status).toBe(200);
expect(response.content).not.toBeNull();
expect(response.content[0].id).toBe(1);
});
it('should handle GET request', async () => {
const client = new HttpClient({ baseURL });
// Mock the response for the GET request
vi.spyOn(client, 'get').mockResolvedValue({
status: 200,
content: { id: 1, name: 'John Doe' },
});

Copilot uses AI. Check for mistakes.
it('should create a Brex client with default config', async () => {
const client = createBrexClient({ baseURL });

const response = await client.request({
Copy link

Copilot AI Jun 15, 2025

Choose a reason for hiding this comment

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

[nitpick] The app-level tests hit the real API as well; mocking responses will make tests more deterministic and faster.

Copilot uses AI. Check for mistakes.
}

getConfig(): HttpClientConfig {
return this.config;
Copy link

Copilot AI Jun 15, 2025

Choose a reason for hiding this comment

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

Returning the internal config object exposes mutable state to callers; consider returning a shallow copy to prevent accidental external mutations.

Suggested change
return this.config;
return { ...this.config };

Copilot uses AI. Check for mistakes.
@Breimerct Breimerct merged commit 57c8db7 into main Jun 15, 2025
1 check passed
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.

2 participants