mirror of
https://github.com/samanhappy/mcphub.git
synced 2025-12-24 02:39:19 -05:00
Fix BASE_PATH configuration breaking login in development mode
- Normalize BASE_PATH by removing trailing slashes in backend config - Update Vite dev server proxy to dynamically support BASE_PATH from env - Add integration tests for BASE_PATH functionality - All tests pass, build successful Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
This commit is contained in:
131
tests/integration/base-path-routes.test.ts
Normal file
131
tests/integration/base-path-routes.test.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import { beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
import request from 'supertest';
|
||||
|
||||
// Mock dependencies
|
||||
jest.mock('../../src/utils/i18n.js', () => ({
|
||||
__esModule: true,
|
||||
initI18n: jest.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
jest.mock('../../src/models/User.js', () => ({
|
||||
__esModule: true,
|
||||
initializeDefaultUser: jest.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
jest.mock('../../src/services/oauthService.js', () => ({
|
||||
__esModule: true,
|
||||
initOAuthProvider: jest.fn(),
|
||||
getOAuthRouter: jest.fn(() => null),
|
||||
}));
|
||||
|
||||
jest.mock('../../src/services/mcpService.js', () => ({
|
||||
__esModule: true,
|
||||
initUpstreamServers: jest.fn().mockResolvedValue(undefined),
|
||||
connected: jest.fn().mockReturnValue(true),
|
||||
}));
|
||||
|
||||
jest.mock('../../src/middlewares/userContext.js', () => ({
|
||||
__esModule: true,
|
||||
userContextMiddleware: jest.fn((_req, _res, next) => next()),
|
||||
sseUserContextMiddleware: jest.fn((_req, _res, next) => next()),
|
||||
}));
|
||||
|
||||
describe('AppServer with BASE_PATH configuration', () => {
|
||||
// Save original BASE_PATH
|
||||
const originalBasePath = process.env.BASE_PATH;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
// Clear module cache to allow fresh imports with different config
|
||||
jest.resetModules();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Restore original BASE_PATH or remove it
|
||||
if (originalBasePath !== undefined) {
|
||||
process.env.BASE_PATH = originalBasePath;
|
||||
} else {
|
||||
delete process.env.BASE_PATH;
|
||||
}
|
||||
});
|
||||
|
||||
const flushPromises = async () => {
|
||||
await new Promise((resolve) => setImmediate(resolve));
|
||||
};
|
||||
|
||||
it('should serve auth routes with BASE_PATH=/mcphub/', async () => {
|
||||
// Set environment variable for BASE_PATH (with trailing slash)
|
||||
process.env.BASE_PATH = '/mcphub/';
|
||||
|
||||
// Dynamically import after setting env var
|
||||
const { AppServer } = await import('../../src/server.js');
|
||||
const config = await import('../../src/config/index.js');
|
||||
|
||||
// Verify config loaded the BASE_PATH and normalized it (removed trailing slash)
|
||||
expect(config.default.basePath).toBe('/mcphub');
|
||||
|
||||
const appServer = new AppServer();
|
||||
await appServer.initialize();
|
||||
await flushPromises();
|
||||
|
||||
const app = appServer.getApp();
|
||||
|
||||
// Test that /mcphub/config endpoint exists
|
||||
const configResponse = await request(app).get('/mcphub/config');
|
||||
expect(configResponse.status).not.toBe(404);
|
||||
|
||||
// Test that /mcphub/public-config endpoint exists
|
||||
const publicConfigResponse = await request(app).get('/mcphub/public-config');
|
||||
expect(publicConfigResponse.status).not.toBe(404);
|
||||
|
||||
// Clean up
|
||||
delete process.env.BASE_PATH;
|
||||
});
|
||||
|
||||
it('should serve auth routes without BASE_PATH (default)', async () => {
|
||||
// Ensure BASE_PATH is not set
|
||||
delete process.env.BASE_PATH;
|
||||
|
||||
// Dynamically import after clearing env var
|
||||
jest.resetModules();
|
||||
const { AppServer } = await import('../../src/server.js');
|
||||
const config = await import('../../src/config/index.js');
|
||||
|
||||
// Verify config has empty BASE_PATH
|
||||
expect(config.default.basePath).toBe('');
|
||||
|
||||
const appServer = new AppServer();
|
||||
await appServer.initialize();
|
||||
await flushPromises();
|
||||
|
||||
const app = appServer.getApp();
|
||||
|
||||
// Test that /config endpoint exists (without base path)
|
||||
const configResponse = await request(app).get('/config');
|
||||
expect(configResponse.status).not.toBe(404);
|
||||
|
||||
// Test that /public-config endpoint exists
|
||||
const publicConfigResponse = await request(app).get('/public-config');
|
||||
expect(publicConfigResponse.status).not.toBe(404);
|
||||
});
|
||||
|
||||
it('should correctly mount API routes with BASE_PATH', async () => {
|
||||
process.env.BASE_PATH = '/test-base/';
|
||||
|
||||
jest.resetModules();
|
||||
const { AppServer } = await import('../../src/server.js');
|
||||
|
||||
const appServer = new AppServer();
|
||||
await appServer.initialize();
|
||||
await flushPromises();
|
||||
|
||||
const app = appServer.getApp();
|
||||
|
||||
// Test that API routes are accessible with base path
|
||||
const apiHealthResponse = await request(app).get('/health');
|
||||
expect(apiHealthResponse.status).not.toBe(404);
|
||||
|
||||
// Clean up
|
||||
delete process.env.BASE_PATH;
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user