@geekmidas/constructs 3.0.9 → 3.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,7 @@ import {
8
8
  import type { Service } from '@geekmidas/services';
9
9
  import { ServiceDiscovery } from '@geekmidas/services';
10
10
  import { Hono } from 'hono';
11
+ import { Client } from 'pg';
11
12
  import { afterAll, beforeAll, describe, expect, it } from 'vitest';
12
13
  import { z } from 'zod';
13
14
  import { e } from '../EndpointFactory';
@@ -18,18 +19,33 @@ type OrderEvent =
18
19
  | PublishableMessage<'notification.sent', { orderId: string; type: string }>;
19
20
 
20
21
  const POSTGRES_URL = 'postgres://geekmidas:geekmidas@localhost:5432/geekmidas';
22
+ const TEST_SCHEMA = 'pgboss_hono_publisher_test';
21
23
 
22
24
  const uniqueQueue = () =>
23
25
  `test-${Date.now()}-${Math.random().toString(36).substring(7)}`;
24
26
 
27
+ // Drop the test schema before pg-boss runs. Without this, a stale schema left
28
+ // behind by an older pg-boss version trips v12's migrator because it sees the
29
+ // `version` table but not the new `job_common` table.
30
+ async function dropTestSchema() {
31
+ const client = new Client({ connectionString: POSTGRES_URL });
32
+ await client.connect();
33
+ try {
34
+ await client.query(`DROP SCHEMA IF EXISTS "${TEST_SCHEMA}" CASCADE`);
35
+ } finally {
36
+ await client.end();
37
+ }
38
+ }
39
+
25
40
  describe('HonoEndpoint with PgBoss Publisher', () => {
26
41
  let connection: PgBossConnection;
27
42
  let envParser: EnvironmentParser<{}>;
28
43
 
29
44
  beforeAll(async () => {
45
+ await dropTestSchema();
30
46
  connection = new PgBossConnection({
31
47
  connectionString: POSTGRES_URL,
32
- schema: 'pgboss_hono_publisher_test',
48
+ schema: TEST_SCHEMA,
33
49
  });
34
50
  await connection.connect();
35
51
  envParser = new EnvironmentParser({});
@@ -801,7 +801,7 @@ describe('HonoEndpointAdaptor', () => {
801
801
  expect(await response.json()).toEqual({ success: true });
802
802
  });
803
803
 
804
- it('should return 401 when authorize returns false', async () => {
804
+ it('should return 403 when authorize returns false', async () => {
805
805
  const endpoint = new Endpoint({
806
806
  route: '/protected',
807
807
  method: 'GET',
@@ -827,11 +827,9 @@ describe('HonoEndpointAdaptor', () => {
827
827
  adaptor.addRoute(serviceDiscovery, app);
828
828
 
829
829
  const response = await app.request('/protected');
830
- expect(response.status).toBe(401);
831
- expect(await response.json()).toEqual({ error: 'Unauthorized' });
832
- expect(mockLogger.warn).toHaveBeenCalledWith(
833
- 'Unauthorized access attempt',
834
- );
830
+ expect(response.status).toBe(403);
831
+ expect(await response.json()).toEqual({ error: 'Forbidden' });
832
+ expect(mockLogger.warn).toHaveBeenCalledWith('Forbidden access attempt');
835
833
  });
836
834
 
837
835
  it('should handle async authorize functions with headers', async () => {
@@ -873,8 +871,8 @@ describe('HonoEndpointAdaptor', () => {
873
871
  const invalidResponse = await app.request('/protected', {
874
872
  headers: { Authorization: 'Bearer invalid-token' },
875
873
  });
876
- expect(invalidResponse.status).toBe(401);
877
- expect(await invalidResponse.json()).toEqual({ error: 'Unauthorized' });
874
+ expect(invalidResponse.status).toBe(403);
875
+ expect(await invalidResponse.json()).toEqual({ error: 'Forbidden' });
878
876
  });
879
877
 
880
878
  it('should authorize with services available', async () => {
@@ -924,7 +922,7 @@ describe('HonoEndpointAdaptor', () => {
924
922
  const invalidResponse = await app.request('/protected', {
925
923
  headers: { Authorization: 'Bearer invalid-token' },
926
924
  });
927
- expect(invalidResponse.status).toBe(401);
925
+ expect(invalidResponse.status).toBe(403);
928
926
  });
929
927
 
930
928
  it('should authorize with session', async () => {
@@ -966,7 +964,7 @@ describe('HonoEndpointAdaptor', () => {
966
964
 
967
965
  // Test with no token (no session)
968
966
  const noTokenResponse = await app.request('/protected');
969
- expect(noTokenResponse.status).toBe(401);
967
+ expect(noTokenResponse.status).toBe(403);
970
968
  });
971
969
 
972
970
  it('should handle authorization errors', async () => {
@@ -1099,7 +1097,7 @@ describe('HonoEndpointAdaptor', () => {
1099
1097
  body: JSON.stringify({ role: 'viewer' }),
1100
1098
  });
1101
1099
 
1102
- expect(response.status).toBe(401);
1100
+ expect(response.status).toBe(403);
1103
1101
  });
1104
1102
  });
1105
1103
 
@@ -140,7 +140,7 @@ describe('MswEndpointAdaptor', () => {
140
140
  expect(body.name).toBe('Test User');
141
141
  });
142
142
 
143
- it('should return 401 when authorization fails', async () => {
143
+ it('should return 403 when authorization fails', async () => {
144
144
  const contextId = crypto.randomUUID();
145
145
  registerContext(contextId, {});
146
146
 
@@ -151,7 +151,7 @@ describe('MswEndpointAdaptor', () => {
151
151
  },
152
152
  });
153
153
 
154
- expect(response.status).toBe(401);
154
+ expect(response.status).toBe(403);
155
155
  });
156
156
 
157
157
  it('should return 200 when authorization passes', async () => {
@@ -491,7 +491,7 @@ describe('TestEndpointAdaptor', () => {
491
491
  services: mockServices,
492
492
  headers: { host: 'example.com' },
493
493
  }),
494
- ).rejects.toThrow('Unauthorized');
494
+ ).rejects.toThrow('Forbidden');
495
495
  });
496
496
 
497
497
  it('should allow when authorize uses body to allow', async () => {