Skip to content

Commit f9a58d9

Browse files
committed
fix: restore services test/revert files and update metaschema-modules snapshots
1 parent 6e58099 commit f9a58d9

14 files changed

Lines changed: 435 additions & 3 deletions

File tree

packages/metaschema-modules/__tests__/__snapshots__/modules.test.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ exports[`db_meta_modules should have all expected module tables 1`] = `
3232
exports[`db_meta_modules should verify all module tables exist in metaschema_modules_public schema 1`] = `
3333
{
3434
"moduleTablesCount": 22,
35-
"totalTables": 25,
35+
"totalTables": 27,
3636
}
3737
`;
3838

@@ -148,13 +148,13 @@ exports[`db_meta_modules should verify field_module table structure 1`] = `
148148

149149
exports[`db_meta_modules should verify module table structures have database_id foreign keys 1`] = `
150150
{
151-
"constraintCount": 61798,
151+
"constraintCount": 64152,
152152
}
153153
`;
154154

155155
exports[`db_meta_modules should verify module tables have proper foreign key relationships 1`] = `
156156
{
157-
"constraintCount": 88589,
157+
"constraintCount": 91658,
158158
"foreignTables": [
159159
"database",
160160
"field",
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2+
3+
exports[`services functionality should handle complete meta workflow with services 1`] = `
4+
{
5+
"hash": null,
6+
"id": "[ID]",
7+
"label": null,
8+
"name": "my-meta-db",
9+
"owner_id": "[ID]",
10+
"schema_hash": null,
11+
}
12+
`;
13+
14+
exports[`services functionality should handle complete meta workflow with services 2`] = `
15+
{
16+
"anon_role": "anonymous",
17+
"database_id": "[ID]",
18+
"dbname": "test-database",
19+
"id": "[ID]",
20+
"is_public": true,
21+
"name": "public",
22+
"role_name": "authenticated",
23+
}
24+
`;
25+
26+
exports[`services functionality should handle complete meta workflow with services 3`] = `
27+
{
28+
"anon_role": "administrator",
29+
"database_id": "[ID]",
30+
"dbname": "test-database",
31+
"id": "[ID]",
32+
"is_public": true,
33+
"name": "admin",
34+
"role_name": "administrator",
35+
}
36+
`;
37+
38+
exports[`services functionality should handle complete meta workflow with services 4`] = `
39+
{
40+
"apple_touch_icon": null,
41+
"database_id": "[ID]",
42+
"dbname": "test-database",
43+
"description": "Website Description",
44+
"favicon": null,
45+
"id": "[ID]",
46+
"logo": null,
47+
"og_image": null,
48+
"title": "Website Title",
49+
}
50+
`;
51+
52+
exports[`services functionality should handle complete meta workflow with services 5`] = `
53+
{
54+
"api_id": "[ID]",
55+
"database_id": "[ID]",
56+
"domain": "pgpm.io",
57+
"id": "[ID]",
58+
"site_id": null,
59+
"subdomain": "api",
60+
}
61+
`;
62+
63+
exports[`services functionality should handle complete meta workflow with services 6`] = `
64+
{
65+
"api_id": null,
66+
"database_id": "[ID]",
67+
"domain": "pgpm.io",
68+
"id": "[ID]",
69+
"site_id": "[ID]",
70+
"subdomain": "app",
71+
}
72+
`;
73+
74+
exports[`services functionality should handle complete meta workflow with services 7`] = `
75+
{
76+
"api_id": "[ID]",
77+
"database_id": "[ID]",
78+
"domain": "pgpm.io",
79+
"id": "[ID]",
80+
"site_id": null,
81+
"subdomain": "admin",
82+
}
83+
`;
84+
85+
exports[`services functionality should handle complete meta workflow with services 8`] = `
86+
{
87+
"data": {
88+
"supportEmail": "support@interweb.co",
89+
},
90+
"database_id": "[ID]",
91+
"id": "[ID]",
92+
"name": "legal-emails",
93+
"site_id": "[ID]",
94+
}
95+
`;
96+
97+
exports[`services functionality should handle complete meta workflow with services 9`] = `
98+
{
99+
"api_id": "[ID]",
100+
"data": {
101+
"authenticate": "authenticate",
102+
"authenticate_schema": "services_private",
103+
},
104+
"database_id": "[ID]",
105+
"id": "[ID]",
106+
"name": "rls_module",
107+
}
108+
`;
109+
110+
exports[`services functionality should handle complete meta workflow with services 10`] = `
111+
{
112+
"data": {
113+
"auth_schema": "services_public",
114+
"forgot_password": "forgot_password",
115+
"reset_password": "reset_password",
116+
"send_verification_email": "send_verification_email",
117+
"set_password": "set_password",
118+
"sign_in": "login",
119+
"sign_up": "register",
120+
"verify_email": "verify_email",
121+
},
122+
"database_id": "[ID]",
123+
"id": "[ID]",
124+
"name": "user_auth_module",
125+
"site_id": "[ID]",
126+
}
127+
`;
128+
129+
exports[`services functionality should handle complete meta workflow with services 11`] = `
130+
{
131+
"api_id": "[ID]",
132+
"database_id": "[ID]",
133+
"id": "[ID]",
134+
"schema_id": "[ID]",
135+
}
136+
`;
137+
138+
exports[`services functionality should handle complete meta workflow with services 12`] = `
139+
{
140+
"api_id": "[ID]",
141+
"database_id": "[ID]",
142+
"id": "[ID]",
143+
"schema_id": "[ID]",
144+
}
145+
`;
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
import { getConnections, PgTestClient, snapshot } from 'pgsql-test';
2+
3+
let pg: PgTestClient;
4+
let teardown: () => Promise<void>;
5+
6+
describe('services functionality', () => {
7+
beforeAll(async () => {
8+
({ pg, teardown } = await getConnections());
9+
});
10+
11+
afterAll(async () => {
12+
await teardown();
13+
});
14+
15+
beforeEach(async () => {
16+
await pg.beforeEach();
17+
await pg.any(`GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO public`);
18+
});
19+
20+
afterEach(async () => {
21+
await pg.afterEach();
22+
});
23+
24+
it('should handle complete meta workflow with services', async () => {
25+
const objs: Record<string, any> = {
26+
tables: {},
27+
domains: {},
28+
apis: {},
29+
sites: {}
30+
};
31+
32+
const owner_id = '07281002-1699-4762-57e3-ab1b92243120';
33+
34+
const snap = (obj: any) => {
35+
expect(snapshot(obj)).toMatchSnapshot();
36+
};
37+
38+
const snapWithNormalizedDbname = (obj: any) => {
39+
const normalized = {
40+
...obj,
41+
dbname: 'test-database'
42+
};
43+
expect(snapshot(normalized)).toMatchSnapshot();
44+
};
45+
46+
// Step 1: Create database
47+
const [database] = await pg.any(
48+
`INSERT INTO metaschema_public.database (owner_id, name)
49+
VALUES ($1, $2)
50+
RETURNING *`,
51+
[owner_id, 'my-meta-db']
52+
);
53+
objs.db = database;
54+
const database_id = database.id;
55+
expect(snapshot(database)).toMatchSnapshot();
56+
57+
// Step 2: Create APIs first (since domains reference them)
58+
const [publicApi] = await pg.any(
59+
`INSERT INTO services_public.apis (database_id, name, role_name, anon_role)
60+
VALUES ($1, $2, $3, $4)
61+
RETURNING *`,
62+
[database_id, 'public', 'authenticated', 'anonymous']
63+
);
64+
objs.apis.public = publicApi;
65+
snapWithNormalizedDbname(publicApi);
66+
67+
const [adminApi] = await pg.any(
68+
`INSERT INTO services_public.apis (database_id, name, role_name, anon_role)
69+
VALUES ($1, $2, $3, $4)
70+
RETURNING *`,
71+
[database_id, 'admin', 'administrator', 'administrator']
72+
);
73+
objs.apis.admin = adminApi;
74+
snapWithNormalizedDbname(adminApi);
75+
76+
// Step 3: Create sites
77+
const [appSite] = await pg.any(
78+
`INSERT INTO services_public.sites (database_id, title, description)
79+
VALUES ($1, $2, $3)
80+
RETURNING *`,
81+
[database_id, 'Website Title', 'Website Description']
82+
);
83+
objs.sites.app = appSite;
84+
snapWithNormalizedDbname(appSite);
85+
86+
// Step 4: Register domains (linking to APIs and sites)
87+
const [apiDomain] = await pg.any(
88+
`INSERT INTO services_public.domains (database_id, api_id, domain, subdomain)
89+
VALUES ($1, $2, $3, $4)
90+
RETURNING *`,
91+
[database_id, objs.apis.public.id, 'pgpm.io', 'api']
92+
);
93+
objs.domains.api = apiDomain;
94+
expect(snapshot(apiDomain)).toMatchSnapshot();
95+
96+
const [appDomain] = await pg.any(
97+
`INSERT INTO services_public.domains (database_id, site_id, domain, subdomain)
98+
VALUES ($1, $2, $3, $4)
99+
RETURNING *`,
100+
[database_id, objs.sites.app.id, 'pgpm.io', 'app']
101+
);
102+
objs.domains.app = appDomain;
103+
expect(snapshot(appDomain)).toMatchSnapshot();
104+
105+
const [adminDomain] = await pg.any(
106+
`INSERT INTO services_public.domains (database_id, api_id, domain, subdomain)
107+
VALUES ($1, $2, $3, $4)
108+
RETURNING *`,
109+
[database_id, objs.apis.admin.id, 'pgpm.io', 'admin']
110+
);
111+
objs.domains.admin = adminDomain;
112+
expect(snapshot(adminDomain)).toMatchSnapshot();
113+
114+
const [baseDomain] = await pg.any(
115+
`INSERT INTO services_public.domains (database_id, domain)
116+
VALUES ($1, $2)
117+
RETURNING *`,
118+
[database_id, 'pgpm.io']
119+
);
120+
objs.domains.base = baseDomain;
121+
122+
// Step 5: Register modules
123+
const [siteModule1] = await pg.any(
124+
`INSERT INTO services_public.site_modules (database_id, site_id, name, data)
125+
VALUES ($1, $2, $3, $4::jsonb)
126+
RETURNING *`,
127+
[database_id, objs.sites.app.id, 'legal-emails', JSON.stringify({
128+
supportEmail: 'support@interweb.co'
129+
})]
130+
);
131+
expect(snapshot(siteModule1)).toMatchSnapshot();
132+
133+
const [apiModule] = await pg.any(
134+
`INSERT INTO services_public.api_modules (database_id, api_id, name, data)
135+
VALUES ($1, $2, $3, $4::jsonb)
136+
RETURNING *`,
137+
[database_id, objs.apis.public.id, 'rls_module', JSON.stringify({
138+
authenticate_schema: 'services_private',
139+
authenticate: 'authenticate'
140+
})]
141+
);
142+
expect(snapshot(apiModule)).toMatchSnapshot();
143+
144+
const [siteModule2] = await pg.any(
145+
`INSERT INTO services_public.site_modules (database_id, site_id, name, data)
146+
VALUES ($1, $2, $3, $4::jsonb)
147+
RETURNING *`,
148+
[database_id, objs.sites.app.id, 'user_auth_module', JSON.stringify({
149+
auth_schema: 'services_public',
150+
sign_in: 'login',
151+
sign_up: 'register',
152+
set_password: 'set_password',
153+
reset_password: 'reset_password',
154+
forgot_password: 'forgot_password',
155+
send_verification_email: 'send_verification_email',
156+
verify_email: 'verify_email'
157+
})]
158+
);
159+
expect(snapshot(siteModule2)).toMatchSnapshot();
160+
161+
// Step 6: Schema associations
162+
const [schema] = await pg.any(
163+
`INSERT INTO metaschema_public.schema (database_id, schema_name, name)
164+
VALUES ($1, $2, $3)
165+
RETURNING *`,
166+
[database_id, 'brand-public', 'public']
167+
);
168+
169+
const [publicAssoc] = await pg.any(
170+
`INSERT INTO services_public.api_schemas (database_id, schema_id, api_id)
171+
VALUES ($1, $2, $3)
172+
RETURNING *`,
173+
[database_id, schema.id, objs.apis.public.id]
174+
);
175+
176+
const [adminAssoc] = await pg.any(
177+
`INSERT INTO services_public.api_schemas (database_id, schema_id, api_id)
178+
VALUES ($1, $2, $3)
179+
RETURNING *`,
180+
[database_id, schema.id, objs.apis.admin.id]
181+
);
182+
183+
snap(publicAssoc);
184+
snap(adminAssoc);
185+
});
186+
187+
it('should register domain independently', async () => {
188+
const owner_id = '07281002-1699-4762-57e3-ab1b92243120';
189+
190+
// Create database first
191+
const [database] = await pg.any(
192+
`INSERT INTO metaschema_public.database (owner_id, name)
193+
VALUES ($1, $2)
194+
RETURNING *`,
195+
[owner_id, 'test-db-for-domain']
196+
);
197+
198+
// Then create domain
199+
const [domain] = await pg.any(
200+
`INSERT INTO services_public.domains (database_id, domain, subdomain)
201+
VALUES ($1, $2, $3)
202+
RETURNING *`,
203+
[database.id, 'example.com', 'api']
204+
);
205+
206+
expect(domain.database_id).toBe(database.id);
207+
expect(domain.domain).toBe('example.com');
208+
expect(domain.subdomain).toBe('api');
209+
});
210+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- Revert schemas/services_private/schema from pg
2+
3+
BEGIN;
4+
5+
DROP SCHEMA services_private;
6+
7+
COMMIT;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- Revert schemas/services_public/schema from pg
2+
3+
BEGIN;
4+
5+
DROP SCHEMA services_public;
6+
7+
COMMIT;

0 commit comments

Comments
 (0)