mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
add server test suite
This commit is contained in:
@@ -85,7 +85,7 @@ export default defineConfig(({command}) => {
|
|||||||
environment: 'jsdom',
|
environment: 'jsdom',
|
||||||
registerNodeLoader: false,
|
registerNodeLoader: false,
|
||||||
setupFiles: ['./src/test/setup.ts'],
|
setupFiles: ['./src/test/setup.ts'],
|
||||||
exclude: [...configDefaults.exclude, 'workers/**', 'dist/**'],
|
exclude: [...configDefaults.exclude, 'dist/**'],
|
||||||
coverage: {
|
coverage: {
|
||||||
provider: 'v8',
|
provider: 'v8',
|
||||||
reporter: ['text', 'json', 'html'],
|
reporter: ['text', 'json', 'html'],
|
||||||
|
189
workers/site/__tests__/AssetService.test.ts
Normal file
189
workers/site/__tests__/AssetService.test.ts
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
|
import { getSnapshot, Instance } from 'mobx-state-tree';
|
||||||
|
import AssetService from '../services/AssetService';
|
||||||
|
|
||||||
|
// Define types for testing
|
||||||
|
type AssetServiceInstance = Instance<typeof AssetService>;
|
||||||
|
|
||||||
|
// Mock the vike/server module
|
||||||
|
vi.mock('vike/server', () => ({
|
||||||
|
renderPage: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Import the mocked renderPage function for assertions
|
||||||
|
import { renderPage } from 'vike/server';
|
||||||
|
|
||||||
|
// Mock global types
|
||||||
|
vi.stubGlobal('ReadableStream', class MockReadableStream {});
|
||||||
|
vi.stubGlobal('Response', class MockResponse {
|
||||||
|
status: number;
|
||||||
|
headers: Headers;
|
||||||
|
body: any;
|
||||||
|
|
||||||
|
constructor(body?: any, init?: ResponseInit) {
|
||||||
|
this.body = body;
|
||||||
|
this.status = init?.status || 200;
|
||||||
|
this.headers = new Headers(init?.headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
clone() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
async text() {
|
||||||
|
return this.body?.toString() || '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('AssetService', () => {
|
||||||
|
let assetService: AssetServiceInstance;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Create a new instance of the service before each test
|
||||||
|
assetService = AssetService.create();
|
||||||
|
|
||||||
|
// Reset mocks
|
||||||
|
vi.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Initial state', () => {
|
||||||
|
it('should have empty env and ctx objects initially', () => {
|
||||||
|
expect(assetService.env).toEqual({});
|
||||||
|
expect(assetService.ctx).toEqual({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setEnv', () => {
|
||||||
|
it('should set the environment', () => {
|
||||||
|
const mockEnv = { ASSETS: { fetch: vi.fn() } };
|
||||||
|
assetService.setEnv(mockEnv);
|
||||||
|
expect(assetService.env).toEqual(mockEnv);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setCtx', () => {
|
||||||
|
it('should set the execution context', () => {
|
||||||
|
const mockCtx = { waitUntil: vi.fn() };
|
||||||
|
assetService.setCtx(mockCtx);
|
||||||
|
expect(assetService.ctx).toEqual(mockCtx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleSsr', () => {
|
||||||
|
it('should return null when httpResponse is not available', async () => {
|
||||||
|
// Setup mock to return a pageContext without httpResponse
|
||||||
|
vi.mocked(renderPage).mockResolvedValue({});
|
||||||
|
|
||||||
|
const url = 'https://example.com';
|
||||||
|
const headers = new Headers();
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
const result = await assetService.handleSsr(url, headers, env);
|
||||||
|
|
||||||
|
// Verify renderPage was called with correct arguments
|
||||||
|
expect(renderPage).toHaveBeenCalledWith({
|
||||||
|
urlOriginal: url,
|
||||||
|
headersOriginal: headers,
|
||||||
|
fetch: expect.any(Function),
|
||||||
|
env,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verify result is null
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a Response when httpResponse is available', async () => {
|
||||||
|
// Create mock stream
|
||||||
|
const mockStream = new ReadableStream();
|
||||||
|
|
||||||
|
// Setup mock to return a pageContext with httpResponse
|
||||||
|
vi.mocked(renderPage).mockResolvedValue({
|
||||||
|
httpResponse: {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: new Headers({ 'Content-Type': 'text/html' }),
|
||||||
|
getReadableWebStream: () => mockStream,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = 'https://example.com';
|
||||||
|
const headers = new Headers();
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
const result = await assetService.handleSsr(url, headers, env);
|
||||||
|
|
||||||
|
// Verify renderPage was called with correct arguments
|
||||||
|
expect(renderPage).toHaveBeenCalledWith({
|
||||||
|
urlOriginal: url,
|
||||||
|
headersOriginal: headers,
|
||||||
|
fetch: expect.any(Function),
|
||||||
|
env,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verify result is a Response with correct properties
|
||||||
|
expect(result).toBeInstanceOf(Response);
|
||||||
|
expect(result.status).toBe(200);
|
||||||
|
expect(result.headers.get('Content-Type')).toBe('text/html');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleStaticAssets', () => {
|
||||||
|
it('should fetch assets from the environment', async () => {
|
||||||
|
// Create mock request
|
||||||
|
const request = new Request('https://example.com/static/image.png');
|
||||||
|
|
||||||
|
// Create mock response
|
||||||
|
const mockResponse = new Response('Mock asset content', {
|
||||||
|
status: 200,
|
||||||
|
headers: { 'Content-Type': 'image/png' },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create mock environment with ASSETS.fetch
|
||||||
|
const mockEnv = {
|
||||||
|
ASSETS: {
|
||||||
|
fetch: vi.fn().mockResolvedValue(mockResponse),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the environment
|
||||||
|
assetService.setEnv(mockEnv);
|
||||||
|
|
||||||
|
// Call the method
|
||||||
|
const result = await assetService.handleStaticAssets(request, mockEnv);
|
||||||
|
|
||||||
|
// Verify ASSETS.fetch was called with the request
|
||||||
|
expect(mockEnv.ASSETS.fetch).toHaveBeenCalledWith(request);
|
||||||
|
|
||||||
|
// Verify result is the expected response
|
||||||
|
expect(result).toBe(mockResponse);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a 404 response when an error occurs', async () => {
|
||||||
|
// Create mock request
|
||||||
|
const request = new Request('https://example.com/static/not-found.png');
|
||||||
|
|
||||||
|
// Create mock environment with ASSETS.fetch that throws an error
|
||||||
|
const mockEnv = {
|
||||||
|
ASSETS: {
|
||||||
|
fetch: vi.fn().mockRejectedValue(new Error('Asset not found')),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the environment
|
||||||
|
assetService.setEnv(mockEnv);
|
||||||
|
|
||||||
|
// Call the method
|
||||||
|
const result = await assetService.handleStaticAssets(request, mockEnv);
|
||||||
|
|
||||||
|
// Verify ASSETS.fetch was called with the request
|
||||||
|
expect(mockEnv.ASSETS.fetch).toHaveBeenCalledWith(request);
|
||||||
|
|
||||||
|
// Verify result is a 404 Response
|
||||||
|
expect(result).toBeInstanceOf(Response);
|
||||||
|
expect(result.status).toBe(404);
|
||||||
|
|
||||||
|
// Verify response body
|
||||||
|
const text = await result.clone().text();
|
||||||
|
expect(text).toBe('Asset not found');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
16
workers/site/__tests__/api-router.test.ts
Normal file
16
workers/site/__tests__/api-router.test.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
|
import { createRouter } from '../api-router';
|
||||||
|
|
||||||
|
// Mock the vike/server module
|
||||||
|
vi.mock('vike/server', () => ({
|
||||||
|
renderPage: vi.fn()
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('api-router', () => {
|
||||||
|
// Test that the router is created successfully
|
||||||
|
it('creates a router', () => {
|
||||||
|
const router = createRouter();
|
||||||
|
expect(router).toBeDefined();
|
||||||
|
expect(typeof router.handle).toBe('function');
|
||||||
|
});
|
||||||
|
});
|
@@ -40,7 +40,7 @@ export default types
|
|||||||
async handleStaticAssets(request: Request, env) {
|
async handleStaticAssets(request: Request, env) {
|
||||||
console.log("handleStaticAssets");
|
console.log("handleStaticAssets");
|
||||||
try {
|
try {
|
||||||
return env.ASSETS.fetch(request);
|
return await env.ASSETS.fetch(request);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error serving static asset:", error);
|
console.error("Error serving static asset:", error);
|
||||||
return new Response("Asset not found", { status: 404 });
|
return new Response("Asset not found", { status: 404 });
|
||||||
|
164
workers/site/services/__tests__/AssetService.test.ts
Normal file
164
workers/site/services/__tests__/AssetService.test.ts
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
|
import { getSnapshot } from 'mobx-state-tree';
|
||||||
|
import AssetService from '../AssetService';
|
||||||
|
|
||||||
|
// Mock the vike/server module
|
||||||
|
vi.mock('vike/server', () => ({
|
||||||
|
renderPage: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Import the mocked renderPage function for assertions
|
||||||
|
import { renderPage } from 'vike/server';
|
||||||
|
|
||||||
|
describe('AssetService', () => {
|
||||||
|
let assetService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Create a new instance of the service before each test
|
||||||
|
assetService = AssetService.create();
|
||||||
|
|
||||||
|
// Reset mocks
|
||||||
|
vi.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Initial state', () => {
|
||||||
|
it('should have empty env and ctx objects initially', () => {
|
||||||
|
expect(assetService.env).toEqual({});
|
||||||
|
expect(assetService.ctx).toEqual({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setEnv', () => {
|
||||||
|
it('should set the environment', () => {
|
||||||
|
const mockEnv = { ASSETS: { fetch: vi.fn() } };
|
||||||
|
assetService.setEnv(mockEnv);
|
||||||
|
expect(assetService.env).toEqual(mockEnv);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setCtx', () => {
|
||||||
|
it('should set the execution context', () => {
|
||||||
|
const mockCtx = { waitUntil: vi.fn() };
|
||||||
|
assetService.setCtx(mockCtx);
|
||||||
|
expect(assetService.ctx).toEqual(mockCtx);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleSsr', () => {
|
||||||
|
it('should return null when httpResponse is not available', async () => {
|
||||||
|
// Setup mock to return a pageContext without httpResponse
|
||||||
|
vi.mocked(renderPage).mockResolvedValue({});
|
||||||
|
|
||||||
|
const url = 'https://example.com';
|
||||||
|
const headers = new Headers();
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
const result = await assetService.handleSsr(url, headers, env);
|
||||||
|
|
||||||
|
// Verify renderPage was called with correct arguments
|
||||||
|
expect(renderPage).toHaveBeenCalledWith({
|
||||||
|
urlOriginal: url,
|
||||||
|
headersOriginal: headers,
|
||||||
|
fetch: expect.any(Function),
|
||||||
|
env,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verify result is null
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a Response when httpResponse is available', async () => {
|
||||||
|
// Create mock stream
|
||||||
|
const mockStream = new ReadableStream();
|
||||||
|
|
||||||
|
// Setup mock to return a pageContext with httpResponse
|
||||||
|
vi.mocked(renderPage).mockResolvedValue({
|
||||||
|
httpResponse: {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: new Headers({ 'Content-Type': 'text/html' }),
|
||||||
|
getReadableWebStream: () => mockStream,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = 'https://example.com';
|
||||||
|
const headers = new Headers();
|
||||||
|
const env = {};
|
||||||
|
|
||||||
|
const result = await assetService.handleSsr(url, headers, env);
|
||||||
|
|
||||||
|
// Verify renderPage was called with correct arguments
|
||||||
|
expect(renderPage).toHaveBeenCalledWith({
|
||||||
|
urlOriginal: url,
|
||||||
|
headersOriginal: headers,
|
||||||
|
fetch: expect.any(Function),
|
||||||
|
env,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verify result is a Response with correct properties
|
||||||
|
expect(result).toBeInstanceOf(Response);
|
||||||
|
expect(result.status).toBe(200);
|
||||||
|
expect(result.headers.get('Content-Type')).toBe('text/html');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleStaticAssets', () => {
|
||||||
|
it('should fetch assets from the environment', async () => {
|
||||||
|
// Create mock request
|
||||||
|
const request = new Request('https://example.com/static/image.png');
|
||||||
|
|
||||||
|
// Create mock response
|
||||||
|
const mockResponse = new Response('Mock asset content', {
|
||||||
|
status: 200,
|
||||||
|
headers: { 'Content-Type': 'image/png' },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create mock environment with ASSETS.fetch
|
||||||
|
const mockEnv = {
|
||||||
|
ASSETS: {
|
||||||
|
fetch: vi.fn().mockResolvedValue(mockResponse),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the environment
|
||||||
|
assetService.setEnv(mockEnv);
|
||||||
|
|
||||||
|
// Call the method
|
||||||
|
const result = await assetService.handleStaticAssets(request, mockEnv);
|
||||||
|
|
||||||
|
// Verify ASSETS.fetch was called with the request
|
||||||
|
expect(mockEnv.ASSETS.fetch).toHaveBeenCalledWith(request);
|
||||||
|
|
||||||
|
// Verify result is the expected response
|
||||||
|
expect(result).toBe(mockResponse);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a 404 response when an error occurs', async () => {
|
||||||
|
// Create mock request
|
||||||
|
const request = new Request('https://example.com/static/not-found.png');
|
||||||
|
|
||||||
|
// Create mock environment with ASSETS.fetch that throws an error
|
||||||
|
const mockEnv = {
|
||||||
|
ASSETS: {
|
||||||
|
fetch: vi.fn().mockRejectedValue(new Error('Asset not found')),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the environment
|
||||||
|
assetService.setEnv(mockEnv);
|
||||||
|
|
||||||
|
// Call the method
|
||||||
|
const result = await assetService.handleStaticAssets(request, mockEnv);
|
||||||
|
|
||||||
|
// Verify ASSETS.fetch was called with the request
|
||||||
|
expect(mockEnv.ASSETS.fetch).toHaveBeenCalledWith(request);
|
||||||
|
|
||||||
|
// Verify result is a 404 Response
|
||||||
|
expect(result).toBeInstanceOf(Response);
|
||||||
|
expect(result.status).toBe(404);
|
||||||
|
|
||||||
|
// Verify response body
|
||||||
|
const text = await result.clone().text();
|
||||||
|
expect(text).toBe('Asset not found');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Reference in New Issue
Block a user