Skip to content

Commit 39ad06b

Browse files
authored
test(hono): Add E2E tests for middleware spans (#20465)
Patches `app.route` to also support middleware defined in Hono route groups. The Node instrumentation still produces too many spans, this will be fixed in another PR - one test is skipped for now. Closes #20449
1 parent ec2c3d7 commit 39ad06b

15 files changed

Lines changed: 600 additions & 220 deletions

File tree

dev-packages/e2e-tests/test-applications/hono-4/playwright.config.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import { getPlaywrightConfig } from '@sentry-internal/test-utils';
2-
3-
type Runtime = 'cloudflare' | 'node' | 'bun';
4-
5-
const RUNTIME = (process.env.RUNTIME || 'cloudflare') as Runtime;
2+
import { RUNTIME, type Runtime } from './tests/constants';
63

74
const testEnv = process.env.TEST_ENV;
85

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
import { Hono } from 'hono';
2+
import { failingMiddleware, middlewareA, middlewareB } from '../middleware';
23

3-
const testMiddleware = new Hono();
4+
const middlewareRoutes = new Hono();
45

5-
testMiddleware.get('/named', c => c.json({ middleware: 'named' }));
6-
testMiddleware.get('/anonymous', c => c.json({ middleware: 'anonymous' }));
7-
testMiddleware.get('/multi', c => c.json({ middleware: 'multi' }));
8-
testMiddleware.get('/error', c => c.text('should not reach'));
6+
middlewareRoutes.get('/named', c => c.json({ middleware: 'named' }));
7+
middlewareRoutes.get('/anonymous', c => c.json({ middleware: 'anonymous' }));
8+
middlewareRoutes.get('/multi', c => c.json({ middleware: 'multi' }));
9+
middlewareRoutes.get('/error', c => c.text('should not reach'));
910

10-
export { testMiddleware };
11+
// Self-contained sub-app registering its own middleware
12+
const subAppWithMiddleware = new Hono();
13+
14+
subAppWithMiddleware.use('/named/*', middlewareA);
15+
subAppWithMiddleware.use('/anonymous/*', async (c, next) => {
16+
c.header('X-Custom', 'anonymous');
17+
await next();
18+
});
19+
subAppWithMiddleware.use('/multi/*', middlewareA, middlewareB);
20+
subAppWithMiddleware.use('/error/*', failingMiddleware);
21+
22+
// .all() produces the same method:'ALL' as .use() in Hono's route record.
23+
// Wrapping it is harmless (onlyIfParent:true) — this route exists to prove that.
24+
subAppWithMiddleware.all('/all-handler', async function allCatchAll(c) {
25+
return c.json({ handler: 'all' });
26+
});
27+
28+
subAppWithMiddleware.route('/', middlewareRoutes);
29+
30+
export { middlewareRoutes, subAppWithMiddleware };

dev-packages/e2e-tests/test-applications/hono-4/src/routes.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Hono } from 'hono';
22
import { HTTPException } from 'hono/http-exception';
3-
import { testMiddleware } from './route-groups/test-middleware';
4-
import { middlewareA, middlewareB, failingMiddleware } from './middleware';
3+
import { failingMiddleware, middlewareA, middlewareB } from './middleware';
4+
import { middlewareRoutes, subAppWithMiddleware } from './route-groups/test-middleware';
55

66
export function addRoutes(app: Hono<{ Bindings?: { E2E_TEST_DSN: string } }>): void {
77
app.get('/', c => {
@@ -24,16 +24,16 @@ export function addRoutes(app: Hono<{ Bindings?: { E2E_TEST_DSN: string } }>): v
2424
throw new HTTPException(code, { message: `HTTPException ${code}` });
2525
});
2626

27-
// === Middleware ===
28-
// Middleware is registered on the main app (the patched instance) via `app.use()`
29-
// TODO: In the future, we may want to support middleware registration on sub-apps (route groups)
27+
// Root-app middleware: registered on the patched main app instance
3028
app.use('/test-middleware/named/*', middlewareA);
3129
app.use('/test-middleware/anonymous/*', async (c, next) => {
3230
c.header('X-Custom', 'anonymous');
3331
await next();
3432
});
3533
app.use('/test-middleware/multi/*', middlewareA, middlewareB);
3634
app.use('/test-middleware/error/*', failingMiddleware);
35+
app.route('/test-middleware', middlewareRoutes);
3736

38-
app.route('/test-middleware', testMiddleware);
37+
// Sub-app middleware: registered on the sub-app, wrapped at mount time by route() patching
38+
app.route('/test-subapp-middleware', subAppWithMiddleware);
3939
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export type Runtime = 'cloudflare' | 'node' | 'bun';
2+
3+
export const RUNTIME = (process.env.RUNTIME || 'cloudflare') as Runtime;
4+
export const isNode = RUNTIME === 'node';
5+
6+
export const APP_NAME = 'hono-4';

dev-packages/e2e-tests/test-applications/hono-4/tests/errors.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { expect, test } from '@playwright/test';
22
import { waitForError } from '@sentry-internal/test-utils';
3-
4-
const APP_NAME = 'hono-4';
3+
import { APP_NAME } from './constants';
54

65
test('captures error thrown in route handler', async ({ baseURL }) => {
76
const errorWaiter = waitForError(APP_NAME, event => {

0 commit comments

Comments
 (0)