UNPKG

@furystack/rest-service

Version:

Repository implementation for FuryStack

203 lines 10.1 kB
import { Injector } from '@furystack/inject'; import { sleepAsync, usingAsync } from '@furystack/utils'; import { ServerManager } from './server-manager.js'; import { StaticServerManager } from './static-server-manager.js'; import { describe, it, expect, vi } from 'vitest'; import { getPort } from '@furystack/core/port-generator'; describe('StaticServerManager', () => { describe('Top level routing', () => { it('Should return a 404 without fallback', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/', path: '.', port, }); const result = await fetch(`http://127.0.0.1:${port}/not-found.html`); expect(result.ok).toBe(false); expect(result.status).toBe(404); expect(result?.headers.get('content-type')).toBe('text/plain'); const body = await result.text(); expect(body).toBe('Not found'); }); }); it('Should return a fallback', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/', path: '.', fallback: 'package.json', port, headers: { 'custom-header': 'custom-value', }, }); const result = await fetch(`http://localhost:${port}/not-found.html`); expect(result.headers.get('content-type')).toBe('application/json'); expect(result.headers.get('custom-header')).toBe('custom-value'); }); }); it('Should return a fallback for root files', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/', path: '.', fallback: 'package.json', port, headers: { 'custom-header': 'custom-value', }, }); const result = await fetch(`http://localhost:${port}`); expect(result.headers.get('content-type')).toBe('application/json'); expect(result.headers.get('custom-header')).toBe('custom-value'); }); }); it('Should return a defined file from a root directory', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/', path: '.', port, headers: { 'custom-header': 'custom-value', }, }); const result = await fetch(`http://localhost:${port}/README.md`); expect(result.headers.get('content-type')).toBe('text/markdown'); expect(result.headers.get('custom-header')).toBe('custom-value'); }); }); it('Should return a defined file from a subdirectory', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/', path: '.', port, }); const result = await fetch(`http://localhost:${port}/packages/utils/README.md`); expect(result.headers.get('content-type')).toBe('text/markdown'); }); }); }); describe('Non-top level routing', () => { it('Should not handle a request when the path is not matching', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/bundle', path: '.', port, }); const server = [...injector.getInstance(ServerManager).servers.values()][0]; server.apis[0].onRequest = vi.fn(); fetch(`http://localhost:${port}/bundleToAnotherFolder/not-found.html`).catch(() => { /** should fall, ignore */ }); await sleepAsync(100); expect(server.apis[0].onRequest).not.toHaveBeenCalled(); }); }); it('Should return a 404 without fallback', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/bundle', path: '.', port, }); const result = await fetch(`http://localhost:${port}/bundle/not-found.html`); expect(result.ok).toBe(false); expect(result.status).toBe(404); expect(result.headers.get('content-type')).toBe('text/plain'); const body = await result.text(); expect(body).toBe('Not found'); }); }); it('Should return a fallback', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/bundle', path: '.', fallback: 'package.json', port, }); const result = await fetch(`http://localhost:${port}/bundle/not-found.html`); expect(result.headers.get('content-type')).toBe('application/json'); }); }); it('Should return a defined file from a root directory', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/', path: '.', port, }); const result = await fetch(`http://localhost:${port}/README.md`); expect(result.headers.get('content-type')).toBe('text/markdown'); }); }); it('Should return a defined file from a subdirectory', async () => { await usingAsync(new Injector(), async (injector) => { const staticServerManager = injector.getInstance(StaticServerManager); const port = getPort(); await staticServerManager.addStaticSite({ baseUrl: '/', path: '.', port, }); const result = await fetch(`http://localhost:${port}/packages/utils/README.md`); expect(result.headers.get('content-type')).toBe('text/markdown'); }); }); }); describe('shouldExec', () => { it('Should NOT match for requests with not defined method', () => { const staticServerManager = new StaticServerManager(); expect(staticServerManager.shouldExec('/')({ req: { url: '/' } })).toBe(false); }); it('Should NOT match for non-GET requests', () => { const staticServerManager = new StaticServerManager(); expect(staticServerManager.shouldExec('/')({ req: { method: 'POST', url: '/' } })).toBe(false); }); [ ['/', '/'], ['/', '/index.html'], ['/', '/subdir'], ['/', '/subdir/'], ['/', '/subdir/file.js'], ['/subdir', '/subdir'], ['/subdir', '/subdir/'], ['/subdir', '/subdir/file.js'], ['/subdir', '/subdir/s2/file.js'], ].forEach(([root, url]) => it(`Should match for '${root}' root and '${url}' url`, () => { const staticServerManager = new StaticServerManager(); const shouldExec = staticServerManager.shouldExec(root)({ req: { method: 'GET', url } }); expect(shouldExec).toBe(true); })); it('Should not exec different paths for non-top level root directory', () => { const staticServerManager = new StaticServerManager(); expect(staticServerManager.shouldExec('/subdir')({ req: { method: 'GET', url: '/' } })).toBe(false); expect(staticServerManager.shouldExec('/subdir')({ req: { method: 'GET', url: '/other/index.html' } })).toBe(false); expect(staticServerManager.shouldExec('/subdir')({ req: { method: 'GET', url: '/subdir2' } })).toBe(false); expect(staticServerManager.shouldExec('/subdir')({ req: { method: 'GET', url: '/subdir2/index.html' } })).toBe(false); }); }); }); //# sourceMappingURL=static-server-manager.spec.js.map