@@ -30,4 +30,188 @@ describe('server/routes/functions', () => {
30
30
expect ( Array . isArray ( JSON . parse ( response . body ) ) ) . toBe ( true )
31
31
await app . close ( )
32
32
} )
33
+
34
+ test ( 'should return 404 for non-existent function' , async ( ) => {
35
+ const app = build ( )
36
+ const response = await app . inject ( {
37
+ method : 'GET' ,
38
+ url : '/functions/non-existent-function' ,
39
+ headers : {
40
+ pg : TEST_CONNECTION_STRING ,
41
+ } ,
42
+ } )
43
+ expect ( response . statusCode ) . toBe ( 404 )
44
+ await app . close ( )
45
+ } )
46
+
47
+ test ( 'should create function, retrieve, update, delete' , async ( ) => {
48
+ const app = build ( )
49
+ const response = await app . inject ( {
50
+ method : 'POST' ,
51
+ url : '/functions' ,
52
+ headers : {
53
+ pg : TEST_CONNECTION_STRING ,
54
+ } ,
55
+ payload : {
56
+ name : 'test_function' ,
57
+ schema : 'public' ,
58
+ language : 'plpgsql' ,
59
+ definition : 'BEGIN RETURN 42; END;' ,
60
+ return_type : 'integer' ,
61
+ } ,
62
+ } )
63
+ expect ( response . statusCode ) . toBe ( 200 )
64
+ expect ( response . json ( ) ) . toMatchInlineSnapshot ( `
65
+ {
66
+ "args": [],
67
+ "argument_types": "",
68
+ "behavior": "VOLATILE",
69
+ "complete_statement": "CREATE OR REPLACE FUNCTION public.test_function()
70
+ RETURNS integer
71
+ LANGUAGE plpgsql
72
+ AS $function$BEGIN RETURN 42; END;$function$
73
+ ",
74
+ "config_params": null,
75
+ "definition": "BEGIN RETURN 42; END;",
76
+ "id": expect.any(Number),
77
+ "identity_argument_types": "",
78
+ "is_set_returning_function": false,
79
+ "language": "plpgsql",
80
+ "name": "test_function",
81
+ "return_type": "integer",
82
+ "return_type_id": 23,
83
+ "return_type_relation_id": null,
84
+ "schema": "public",
85
+ "security_definer": false,
86
+ }
87
+ ` )
88
+
89
+ const { id } = response . json ( )
90
+
91
+ const retrieveResponse = await app . inject ( {
92
+ method : 'GET' ,
93
+ url : `/functions/${ id } ` ,
94
+ headers : {
95
+ pg : TEST_CONNECTION_STRING ,
96
+ } ,
97
+ } )
98
+ expect ( retrieveResponse . statusCode ) . toBe ( 200 )
99
+ expect ( retrieveResponse . json ( ) ) . toMatchInlineSnapshot ( `
100
+ {
101
+ "args": [],
102
+ "argument_types": "",
103
+ "behavior": "VOLATILE",
104
+ "complete_statement": "CREATE OR REPLACE FUNCTION public.test_function()
105
+ RETURNS integer
106
+ LANGUAGE plpgsql
107
+ AS $function$BEGIN RETURN 42; END;$function$
108
+ ",
109
+ "config_params": null,
110
+ "definition": "BEGIN RETURN 42; END;",
111
+ "id": ${ id } ,
112
+ "identity_argument_types": "",
113
+ "is_set_returning_function": false,
114
+ "language": "plpgsql",
115
+ "name": "test_function",
116
+ "return_type": "integer",
117
+ "return_type_id": 23,
118
+ "return_type_relation_id": null,
119
+ "schema": "public",
120
+ "security_definer": false,
121
+ }
122
+ ` )
123
+
124
+ const updateResponse = await app . inject ( {
125
+ method : 'PATCH' ,
126
+ url : `/functions/${ id } ` ,
127
+ headers : {
128
+ pg : TEST_CONNECTION_STRING ,
129
+ } ,
130
+ payload : {
131
+ name : 'test_function' ,
132
+ schema : 'public' ,
133
+ language : 'plpgsql' ,
134
+ definition : 'BEGIN RETURN 50; END;' ,
135
+ return_type : 'integer' ,
136
+ } ,
137
+ } )
138
+ expect ( updateResponse . statusCode ) . toBe ( 200 )
139
+ expect ( updateResponse . json ( ) ) . toMatchInlineSnapshot ( `
140
+ {
141
+ "args": [],
142
+ "argument_types": "",
143
+ "behavior": "VOLATILE",
144
+ "complete_statement": "CREATE OR REPLACE FUNCTION public.test_function()
145
+ RETURNS integer
146
+ LANGUAGE plpgsql
147
+ AS $function$BEGIN RETURN 50; END;$function$
148
+ ",
149
+ "config_params": null,
150
+ "definition": "BEGIN RETURN 50; END;",
151
+ "id": ${ id } ,
152
+ "identity_argument_types": "",
153
+ "is_set_returning_function": false,
154
+ "language": "plpgsql",
155
+ "name": "test_function",
156
+ "return_type": "integer",
157
+ "return_type_id": 23,
158
+ "return_type_relation_id": null,
159
+ "schema": "public",
160
+ "security_definer": false,
161
+ }
162
+ ` )
163
+
164
+ const deleteResponse = await app . inject ( {
165
+ method : 'DELETE' ,
166
+ url : `/functions/${ id } ` ,
167
+ headers : {
168
+ pg : TEST_CONNECTION_STRING ,
169
+ } ,
170
+ } )
171
+ expect ( deleteResponse . statusCode ) . toBe ( 200 )
172
+ expect ( deleteResponse . json ( ) ) . toMatchInlineSnapshot ( `
173
+ {
174
+ "args": [],
175
+ "argument_types": "",
176
+ "behavior": "VOLATILE",
177
+ "complete_statement": "CREATE OR REPLACE FUNCTION public.test_function()
178
+ RETURNS integer
179
+ LANGUAGE plpgsql
180
+ AS $function$BEGIN RETURN 50; END;$function$
181
+ ",
182
+ "config_params": null,
183
+ "definition": "BEGIN RETURN 50; END;",
184
+ "id": ${ id } ,
185
+ "identity_argument_types": "",
186
+ "is_set_returning_function": false,
187
+ "language": "plpgsql",
188
+ "name": "test_function",
189
+ "return_type": "integer",
190
+ "return_type_id": 23,
191
+ "return_type_relation_id": null,
192
+ "schema": "public",
193
+ "security_definer": false,
194
+ }
195
+ ` )
196
+ } )
197
+
198
+ test ( 'should return 400 for invalid payload' , async ( ) => {
199
+ const app = build ( )
200
+ const response = await app . inject ( {
201
+ method : 'POST' ,
202
+ url : '/functions' ,
203
+ headers : {
204
+ pg : TEST_CONNECTION_STRING ,
205
+ } ,
206
+ payload : {
207
+ name : 'test_function12' ,
208
+ } ,
209
+ } )
210
+ expect ( response . statusCode ) . toBe ( 400 )
211
+ expect ( response . json ( ) ) . toMatchInlineSnapshot ( `
212
+ {
213
+ "error": "syntax error at or near "NULL"",
214
+ }
215
+ ` )
216
+ } )
33
217
} )
0 commit comments