extensions.test.ts119 lines · main
1import { afterAll, beforeAll, expect, test } from 'vitest'
2
3import pgMeta from '../src/index'
4import { cleanupRoot, createTestDatabase } from './db/utils'
5
6beforeAll(async () => {
7 // Any global setup if needed
8})
9
10afterAll(async () => {
11 await cleanupRoot()
12})
13
14const withTestDatabase = (
15 name: string,
16 fn: (db: Awaited<ReturnType<typeof createTestDatabase>>) => Promise<void>
17) => {
18 test(name, async () => {
19 const db = await createTestDatabase()
20 try {
21 await fn(db)
22 } finally {
23 await db.cleanup()
24 }
25 })
26}
27
28withTestDatabase('list extensions', async ({ executeQuery }) => {
29 const { sql, zod } = await pgMeta.extensions.list()
30 const res = zod.parse(await executeQuery(sql))
31
32 expect(res.find(({ name }) => name === 'hstore')).toMatchInlineSnapshot(
33 { default_version: expect.stringMatching(/^\d+.\d+$/) },
34 `
35 {
36 "comment": "data type for storing sets of (key, value) pairs",
37 "default_version": StringMatching /\\^\\\\d\\+\\.\\\\d\\+\\$/,
38 "installed_version": null,
39 "name": "hstore",
40 "schema": null,
41 }
42 `
43 )
44})
45
46withTestDatabase('retrieve, create, update, delete extension', async ({ executeQuery }) => {
47 // Create extensions schema
48 await executeQuery('CREATE SCHEMA extensions;')
49 // Create extension
50 const { sql: createSql } = await pgMeta.extensions.create({ name: 'hstore', version: '1.4' })
51 await executeQuery(createSql)
52
53 // Retrieve extension
54 const { sql: retrieveSql, zod: retrieveZod } = await pgMeta.extensions.retrieve({
55 name: 'hstore',
56 })
57 const retrieve = await executeQuery(retrieveSql)
58 const res = retrieveZod.parse(retrieve[0])
59 expect(res).toMatchInlineSnapshot(
60 {
61 default_version: expect.stringMatching(/^\d+.\d+$/),
62 },
63 `
64 {
65 "comment": "data type for storing sets of (key, value) pairs",
66 "default_version": StringMatching /\\^\\\\d\\+\\.\\\\d\\+\\$/,
67 "installed_version": "1.4",
68 "name": "hstore",
69 "schema": "public",
70 }
71 `
72 )
73
74 // Update extension
75 const { sql: updateSql } = await pgMeta.extensions.update('hstore', {
76 update: true,
77 schema: 'extensions',
78 })
79 await executeQuery(updateSql)
80
81 // Verify update
82 const { sql: verifyUpdateSql } = await pgMeta.extensions.retrieve({ name: 'hstore' })
83 const updateRes = retrieveZod.parse((await executeQuery(verifyUpdateSql))[0])
84 expect(updateRes).toMatchInlineSnapshot(
85 {
86 default_version: expect.stringMatching(/^\d+.\d+$/),
87 installed_version: expect.stringMatching(/^\d+.\d+$/),
88 },
89 `
90 {
91 "comment": "data type for storing sets of (key, value) pairs",
92 "default_version": StringMatching /\\^\\\\d\\+\\.\\\\d\\+\\$/,
93 "installed_version": StringMatching /\\^\\\\d\\+\\.\\\\d\\+\\$/,
94 "name": "hstore",
95 "schema": "extensions",
96 }
97 `
98 )
99
100 // Remove extension
101 const { sql: removeSql } = await pgMeta.extensions.remove('hstore')
102 await executeQuery(removeSql)
103
104 // Verify removal
105 const { sql: verifyRemoveSql } = await pgMeta.extensions.retrieve({ name: 'hstore' })
106 const finalRes = retrieveZod.parse((await executeQuery(verifyRemoveSql))[0])
107 expect(finalRes).toMatchInlineSnapshot(
108 { default_version: expect.stringMatching(/^\d+.\d+$/) },
109 `
110 {
111 "comment": "data type for storing sets of (key, value) pairs",
112 "default_version": StringMatching /\\^\\\\d\\+\\.\\\\d\\+\\$/,
113 "installed_version": null,
114 "name": "hstore",
115 "schema": null,
116 }
117 `
118 )
119})