Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions packages/mcp-server/test/server.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type * as http from 'http';
import type * as net from 'net';

import jsonwebtoken from 'jsonwebtoken';
import request from 'supertest';

import createMockForestServerClient from './helpers/forest-server-client';
import getAvailablePort from './test-utils/get-available-port';
import MockServer from './test-utils/mock-server';
import ForestMCPServer from '../src/server';
import { clearSchemaCache } from '../src/utils/schema-fetcher';
Expand Down Expand Up @@ -125,7 +127,7 @@ describe('ForestMCPServer Instance', () => {
});

it('should start server on specified port', async () => {
const testPort = 39310; // Use a different port for testing
const testPort = await getAvailablePort();
process.env.MCP_SERVER_PORT = testPort.toString();

server = new ForestMCPServer({
Expand All @@ -142,9 +144,11 @@ describe('ForestMCPServer Instance', () => {
setTimeout(resolve, 500);
});

// Verify the server is running by making a request
// Verify the server is running on the specified port
const { httpServer } = server;
expect(httpServer).toBeDefined();
const address = (httpServer as http.Server).address() as net.AddressInfo;
expect(address.port).toBe(testPort);

// Make a request to verify server is responding
const response = await request(httpServer as http.Server)
Expand All @@ -155,7 +159,7 @@ describe('ForestMCPServer Instance', () => {
});

it('should create transport instance', async () => {
const testPort = 39311;
const testPort = await getAvailablePort();
process.env.MCP_SERVER_PORT = testPort.toString();

server = new ForestMCPServer({
Expand All @@ -175,13 +179,14 @@ describe('ForestMCPServer Instance', () => {

describe('HTTP endpoint', () => {
let httpServer: http.Server;
let httpEndpointPort: number;

beforeAll(async () => {
process.env.FOREST_ENV_SECRET = 'test-env-secret';
process.env.FOREST_AUTH_SECRET = 'test-auth-secret';
process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com';
const testPort = 39312;
process.env.MCP_SERVER_PORT = testPort.toString();
httpEndpointPort = await getAvailablePort();
process.env.MCP_SERVER_PORT = httpEndpointPort.toString();

server = new ForestMCPServer({
envSecret: 'test-env-secret',
Expand Down Expand Up @@ -240,12 +245,16 @@ describe('ForestMCPServer Instance', () => {

expect(response.status).toBe(200);
expect(response.headers['content-type']).toMatch(/application\/json/);
expect(response.body.issuer).toBe('http://localhost:39312/');
expect(response.body.issuer).toBe(`http://localhost:${httpEndpointPort}/`);
expect(response.body.registration_endpoint).toBe(
'https://test.forestadmin.com/oauth/register',
);
expect(response.body.authorization_endpoint).toBe(`http://localhost:39312/oauth/authorize`);
expect(response.body.token_endpoint).toBe(`http://localhost:39312/oauth/token`);
expect(response.body.authorization_endpoint).toBe(
`http://localhost:${httpEndpointPort}/oauth/authorize`,
);
expect(response.body.token_endpoint).toBe(
`http://localhost:${httpEndpointPort}/oauth/token`,
);
expect(response.body.revocation_endpoint).toBeUndefined();
expect(response.body.scopes_supported).toEqual([
'mcp:read',
Expand All @@ -266,7 +275,7 @@ describe('ForestMCPServer Instance', () => {
// Clean up previous server
await shutDownHttpServer(server?.httpServer as http.Server);

process.env.MCP_SERVER_PORT = '39314';
process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString();

server = new ForestMCPServer({
authSecret: 'AUTH_SECRET',
Expand Down Expand Up @@ -424,7 +433,7 @@ describe('ForestMCPServer Instance', () => {
process.env.FOREST_ENV_SECRET = 'test-env-secret';
process.env.FOREST_AUTH_SECRET = 'test-auth-secret';
process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com';
process.env.MCP_SERVER_PORT = '39320';
process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString();

// Setup mock for Forest Admin server API responses
mcpMockServer = new MockServer();
Expand Down Expand Up @@ -904,7 +913,7 @@ describe('ForestMCPServer Instance', () => {
process.env.FOREST_AUTH_SECRET = 'test-auth-secret';
process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com';
process.env.AGENT_HOSTNAME = 'http://localhost:3310';
process.env.MCP_SERVER_PORT = '39330';
process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString();

listMockServer = new MockServer();
listMockServer
Expand Down Expand Up @@ -1975,7 +1984,7 @@ describe('ForestMCPServer Instance', () => {
process.env.FOREST_AUTH_SECRET = 'test-auth-secret';
process.env.FOREST_SERVER_URL = 'https://test.forestadmin.com';
process.env.AGENT_HOSTNAME = 'http://localhost:3310';
process.env.MCP_SERVER_PORT = '39331';
process.env.MCP_SERVER_PORT = (await getAvailablePort()).toString();

loggingMockServer = new MockServer();
loggingMockServer
Expand Down
12 changes: 12 additions & 0 deletions packages/mcp-server/test/test-utils/get-available-port.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as net from 'net';

export default function getAvailablePort(): Promise<number> {
return new Promise((resolve, reject) => {
const srv = net.createServer();
srv.listen(0, () => {
const { port } = srv.address() as net.AddressInfo;
srv.close(() => resolve(port));
});
srv.on('error', reject);
});
}
Loading