@dbos-inc/koa-serve 2.11.6-preview.gcb74958171
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.
- package/README.md +1 -0
- package/dist/src/dboshttp.d.ts +76 -0
- package/dist/src/dboshttp.d.ts.map +1 -0
- package/dist/src/dboshttp.js +122 -0
- package/dist/src/dboshttp.js.map +1 -0
- package/dist/src/dboskoa.d.ts +54 -0
- package/dist/src/dboskoa.d.ts.map +1 -0
- package/dist/src/dboskoa.js +333 -0
- package/dist/src/dboskoa.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +12 -0
- package/dist/src/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/jest.config.js +8 -0
- package/package.json +43 -0
- package/src/dboshttp.ts +185 -0
- package/src/dboskoa.ts +415 -0
- package/src/index.ts +14 -0
- package/tests/argsource.test.ts +153 -0
- package/tests/auth.test.ts +208 -0
- package/tests/basic.test.ts +73 -0
- package/tests/cors.test.ts +292 -0
- package/tests/endpoints.test.ts +517 -0
- package/tests/validation.test.ts +539 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import Koa from 'koa';
|
|
2
|
+
import Router from '@koa/router';
|
|
3
|
+
|
|
4
|
+
import { DBOS, DefaultArgRequired } from '@dbos-inc/dbos-sdk';
|
|
5
|
+
|
|
6
|
+
import { ArgSources, DBOSKoa } from '../src';
|
|
7
|
+
|
|
8
|
+
import request from 'supertest';
|
|
9
|
+
import bodyParser from '@koa/bodyparser';
|
|
10
|
+
|
|
11
|
+
const dhttp = new DBOSKoa();
|
|
12
|
+
|
|
13
|
+
describe('httpserver-argsource-tests', () => {
|
|
14
|
+
let app: Koa;
|
|
15
|
+
let appRouter: Router;
|
|
16
|
+
|
|
17
|
+
beforeAll(async () => {
|
|
18
|
+
DBOS.setConfig({
|
|
19
|
+
name: 'dbos-koa-test',
|
|
20
|
+
userDbclient: 'pg-node',
|
|
21
|
+
});
|
|
22
|
+
return Promise.resolve();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
beforeEach(async () => {
|
|
26
|
+
DBOS.registerLifecycleCallback(dhttp);
|
|
27
|
+
const _classes = [ArgTestEndpoints];
|
|
28
|
+
await DBOS.launch();
|
|
29
|
+
DBOS.setUpHandlerCallback();
|
|
30
|
+
app = new Koa();
|
|
31
|
+
appRouter = new Router();
|
|
32
|
+
dhttp.registerWithApp(app, appRouter);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(async () => {
|
|
36
|
+
await DBOS.shutdown();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('get-query', async () => {
|
|
40
|
+
const response1 = await request(app.callback()).get('/getquery?name=alice');
|
|
41
|
+
expect(response1.statusCode).toBe(200);
|
|
42
|
+
expect(response1.text).toBe('hello alice');
|
|
43
|
+
const response2 = await request(app.callback()).get('/getquery').send({ name: 'alice' });
|
|
44
|
+
expect(response2.statusCode).toBe(400);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('get-body', async () => {
|
|
48
|
+
const response1 = await request(app.callback()).get('/getbody?name=alice');
|
|
49
|
+
expect(response1.statusCode).toBe(400);
|
|
50
|
+
const response2 = await request(app.callback()).get('/getbody').send({ name: 'alice' });
|
|
51
|
+
expect(response2.statusCode).toBe(200);
|
|
52
|
+
expect(response2.text).toBe('hello alice');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('get-default', async () => {
|
|
56
|
+
const response1 = await request(app.callback()).get('/getdefault?name=alice');
|
|
57
|
+
expect(response1.statusCode).toBe(200);
|
|
58
|
+
expect(response1.text).toBe('hello alice');
|
|
59
|
+
const response2 = await request(app.callback()).get('/getdefault').send({ name: 'alice' });
|
|
60
|
+
expect(response2.statusCode).toBe(400);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('get-auto', async () => {
|
|
64
|
+
const response1 = await request(app.callback()).get('/getauto?name=alice');
|
|
65
|
+
expect(response1.statusCode).toBe(200);
|
|
66
|
+
expect(response1.text).toBe('hello alice');
|
|
67
|
+
const response2 = await request(app.callback()).get('/getauto').send({ name: 'alice' });
|
|
68
|
+
expect(response2.statusCode).toBe(200);
|
|
69
|
+
expect(response2.text).toBe('hello alice');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('post-query', async () => {
|
|
73
|
+
const response1 = await request(app.callback()).post('/postquery?name=alice');
|
|
74
|
+
expect(response1.statusCode).toBe(200);
|
|
75
|
+
expect(response1.text).toBe('hello alice');
|
|
76
|
+
const response2 = await request(app.callback()).post('/postquery').send({ name: 'alice' });
|
|
77
|
+
expect(response2.statusCode).toBe(400);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('post-body', async () => {
|
|
81
|
+
const response1 = await request(app.callback()).post('/postbody?name=alice');
|
|
82
|
+
expect(response1.statusCode).toBe(400);
|
|
83
|
+
const response2 = await request(app.callback()).post('/postbody').send({ name: 'alice' });
|
|
84
|
+
expect(response2.statusCode).toBe(200);
|
|
85
|
+
expect(response2.text).toBe('hello alice');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('post-default', async () => {
|
|
89
|
+
const response1 = await request(app.callback()).post('/postdefault?name=alice');
|
|
90
|
+
expect(response1.statusCode).toBe(400);
|
|
91
|
+
const response2 = await request(app.callback()).post('/postdefault').send({ name: 'alice' });
|
|
92
|
+
expect(response2.statusCode).toBe(200);
|
|
93
|
+
expect(response2.text).toBe('hello alice');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('post-auto', async () => {
|
|
97
|
+
const response1 = await request(app.callback()).post('/postauto?name=alice');
|
|
98
|
+
expect(response1.statusCode).toBe(200);
|
|
99
|
+
expect(response1.text).toBe('hello alice');
|
|
100
|
+
const response2 = await request(app.callback()).post('/postauto').send({ name: 'alice' });
|
|
101
|
+
expect(response2.statusCode).toBe(200);
|
|
102
|
+
expect(response2.text).toBe('hello alice');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
@dhttp.koaBodyParser(
|
|
106
|
+
bodyParser({
|
|
107
|
+
enableTypes: ['json'],
|
|
108
|
+
parsedMethods: ['GET', 'POST'],
|
|
109
|
+
}),
|
|
110
|
+
)
|
|
111
|
+
@DefaultArgRequired
|
|
112
|
+
class ArgTestEndpoints {
|
|
113
|
+
@dhttp.getApi('/getquery')
|
|
114
|
+
static async getQuery(@dhttp.argSource(ArgSources.QUERY) name: string) {
|
|
115
|
+
return Promise.resolve(`hello ${name}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@dhttp.getApi('/getbody')
|
|
119
|
+
static async getBody(@dhttp.argSource(ArgSources.BODY) name: string) {
|
|
120
|
+
return Promise.resolve(`hello ${name}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@dhttp.getApi('/getdefault')
|
|
124
|
+
static async getDefault(@dhttp.argSource(ArgSources.DEFAULT) name: string) {
|
|
125
|
+
return Promise.resolve(`hello ${name}`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@dhttp.getApi('/getauto')
|
|
129
|
+
static async getAuto(@dhttp.argSource(ArgSources.AUTO) name: string) {
|
|
130
|
+
return Promise.resolve(`hello ${name}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@dhttp.postApi('/postquery')
|
|
134
|
+
static async postQuery(@dhttp.argSource(ArgSources.QUERY) name: string) {
|
|
135
|
+
return Promise.resolve(`hello ${name}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@dhttp.postApi('/postbody')
|
|
139
|
+
static async postBody(@dhttp.argSource(ArgSources.BODY) name: string) {
|
|
140
|
+
return Promise.resolve(`hello ${name}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@dhttp.postApi('/postdefault')
|
|
144
|
+
static async postDefault(@dhttp.argSource(ArgSources.DEFAULT) name: string) {
|
|
145
|
+
return Promise.resolve(`hello ${name}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@dhttp.postApi('/postauto')
|
|
149
|
+
static async postAuto(@dhttp.argSource(ArgSources.AUTO) name: string) {
|
|
150
|
+
return Promise.resolve(`hello ${name}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import Koa from 'koa';
|
|
2
|
+
import Router from '@koa/router';
|
|
3
|
+
|
|
4
|
+
import { DBOS, Error as DBOSError } from '@dbos-inc/dbos-sdk';
|
|
5
|
+
|
|
6
|
+
import { DBOSKoa, DBOSKoaAuthContext } from '../src';
|
|
7
|
+
|
|
8
|
+
import request from 'supertest';
|
|
9
|
+
|
|
10
|
+
const dhttp = new DBOSKoa();
|
|
11
|
+
|
|
12
|
+
interface TestKvTable {
|
|
13
|
+
id?: number;
|
|
14
|
+
value?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('httpserver-defsec-tests', () => {
|
|
18
|
+
let app: Koa;
|
|
19
|
+
let appRouter: Router;
|
|
20
|
+
|
|
21
|
+
const testTableName = 'dbos_test_kv';
|
|
22
|
+
|
|
23
|
+
beforeAll(async () => {
|
|
24
|
+
DBOS.setConfig({
|
|
25
|
+
name: 'dbos-koa-test',
|
|
26
|
+
userDbclient: 'pg-node',
|
|
27
|
+
});
|
|
28
|
+
return Promise.resolve();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
beforeEach(async () => {
|
|
32
|
+
DBOS.registerLifecycleCallback(dhttp);
|
|
33
|
+
const _classes = [TestEndpointDefSec, SecondClass];
|
|
34
|
+
await DBOS.launch();
|
|
35
|
+
await DBOS.queryUserDB(`DROP TABLE IF EXISTS ${testTableName};`);
|
|
36
|
+
await DBOS.queryUserDB(`CREATE TABLE IF NOT EXISTS ${testTableName} (id SERIAL PRIMARY KEY, value TEXT);`);
|
|
37
|
+
middlewareCounter = 0;
|
|
38
|
+
middlewareCounter2 = 0;
|
|
39
|
+
middlewareCounterG = 0;
|
|
40
|
+
app = new Koa();
|
|
41
|
+
appRouter = new Router();
|
|
42
|
+
dhttp.registerWithApp(app, appRouter);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
afterEach(async () => {
|
|
46
|
+
await DBOS.shutdown();
|
|
47
|
+
jest.restoreAllMocks();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('get-hello', async () => {
|
|
51
|
+
const response = await request(app.callback()).get('/hello');
|
|
52
|
+
expect(response.statusCode).toBe(200);
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
54
|
+
expect(response.body.message).toBe('hello!');
|
|
55
|
+
expect(middlewareCounter).toBe(1);
|
|
56
|
+
expect(middlewareCounter2).toBe(2); // Middleware runs from left to right.
|
|
57
|
+
expect(middlewareCounterG).toBe(1);
|
|
58
|
+
await request(app.callback()).get('/goodbye');
|
|
59
|
+
expect(middlewareCounterG).toBe(2);
|
|
60
|
+
await request(app.callback()).get('/nosuchendpoint');
|
|
61
|
+
expect(middlewareCounterG).toBe(3);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('get-hello-name', async () => {
|
|
65
|
+
const response = await request(app.callback()).get('/hello/alice');
|
|
66
|
+
expect(response.statusCode).toBe(200);
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
68
|
+
expect(response.body.message).toBe('hello, alice!');
|
|
69
|
+
expect(middlewareCounter).toBe(1);
|
|
70
|
+
expect(middlewareCounterG).toBe(1);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('not-authenticated', async () => {
|
|
74
|
+
const response = await request(app.callback()).get('/requireduser?name=alice');
|
|
75
|
+
expect(response.statusCode).toBe(401);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('not-you', async () => {
|
|
79
|
+
const response = await request(app.callback()).get('/requireduser?name=alice&userid=go_away');
|
|
80
|
+
expect(response.statusCode).toBe(401);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('not-authorized', async () => {
|
|
84
|
+
const response = await request(app.callback()).get('/requireduser?name=alice&userid=bob');
|
|
85
|
+
expect(response.statusCode).toBe(403);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('authorized', async () => {
|
|
89
|
+
const response = await request(app.callback()).get('/requireduser?name=alice&userid=a_real_user');
|
|
90
|
+
expect(response.statusCode).toBe(200);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// The handler is authorized, then its child workflow and transaction should also be authroized.
|
|
94
|
+
test('cascade-authorized', async () => {
|
|
95
|
+
const response = await request(app.callback()).get('/workflow?name=alice&userid=a_real_user');
|
|
96
|
+
expect(response.statusCode).toBe(200);
|
|
97
|
+
|
|
98
|
+
const txnResponse = await request(app.callback()).get('/transaction?name=alice&userid=a_real_user');
|
|
99
|
+
expect(txnResponse.statusCode).toBe(200);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// We can directly test a transaction with passed in authorizedRoles.
|
|
103
|
+
test('direct-transaction-test', async () => {
|
|
104
|
+
await DBOS.withAuthedContext('user', ['user'], async () => {
|
|
105
|
+
const res = await TestEndpointDefSec.testTranscation('alice');
|
|
106
|
+
expect(res).toBe('hello 1');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Unauthorized.
|
|
110
|
+
await expect(TestEndpointDefSec.testTranscation('alice')).rejects.toThrow(
|
|
111
|
+
new DBOSError.DBOSNotAuthorizedError('User does not have a role with permission to call testTranscation', 403),
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
async function authTestMiddleware(ctx: DBOSKoaAuthContext) {
|
|
116
|
+
if (ctx.requiredRole.length > 0) {
|
|
117
|
+
const { userid } = ctx.koaContext.request.query;
|
|
118
|
+
const uid = userid?.toString();
|
|
119
|
+
|
|
120
|
+
if (!uid || uid.length === 0) {
|
|
121
|
+
return Promise.reject(new DBOSError.DBOSNotAuthorizedError('Not logged in.', 401));
|
|
122
|
+
} else {
|
|
123
|
+
if (uid === 'go_away') {
|
|
124
|
+
return Promise.reject(new DBOSError.DBOSNotAuthorizedError('Go away.', 401));
|
|
125
|
+
}
|
|
126
|
+
return Promise.resolve({
|
|
127
|
+
authenticatedUser: uid,
|
|
128
|
+
authenticatedRoles: uid === 'a_real_user' ? ['user'] : ['other'],
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let middlewareCounter = 0;
|
|
136
|
+
const testMiddleware: Koa.Middleware = async (ctx, next) => {
|
|
137
|
+
middlewareCounter++;
|
|
138
|
+
await next();
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
let middlewareCounter2 = 0;
|
|
142
|
+
const testMiddleware2: Koa.Middleware = async (ctx, next) => {
|
|
143
|
+
middlewareCounter2 = middlewareCounter + 1;
|
|
144
|
+
await next();
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
let middlewareCounterG = 0;
|
|
148
|
+
const testMiddlewareG: Koa.Middleware = async (ctx, next) => {
|
|
149
|
+
middlewareCounterG = middlewareCounterG + 1;
|
|
150
|
+
await next();
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
@DBOS.defaultRequiredRole(['user'])
|
|
154
|
+
@dhttp.authentication(authTestMiddleware)
|
|
155
|
+
@dhttp.koaMiddleware(testMiddleware, testMiddleware2)
|
|
156
|
+
@dhttp.koaGlobalMiddleware(testMiddlewareG)
|
|
157
|
+
class TestEndpointDefSec {
|
|
158
|
+
@DBOS.requiredRole([])
|
|
159
|
+
@dhttp.getApi('/hello')
|
|
160
|
+
static async hello() {
|
|
161
|
+
return Promise.resolve({ message: 'hello!' });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@DBOS.requiredRole([])
|
|
165
|
+
@dhttp.getApi('/hello/:name')
|
|
166
|
+
static async helloName(name: string) {
|
|
167
|
+
return Promise.resolve({ message: `hello, ${name}!` });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@dhttp.getApi('/requireduser')
|
|
171
|
+
static async testAuth(name: string) {
|
|
172
|
+
return Promise.resolve(`Please say hello to ${name}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@DBOS.transaction()
|
|
176
|
+
static async testTranscation(name: string) {
|
|
177
|
+
const { rows } = await DBOS.pgClient.query<TestKvTable>(
|
|
178
|
+
`INSERT INTO ${testTableName}(value) VALUES ($1) RETURNING id`,
|
|
179
|
+
[name],
|
|
180
|
+
);
|
|
181
|
+
return `hello ${rows[0].id}`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@DBOS.workflow()
|
|
185
|
+
static async testWorkflow(name: string) {
|
|
186
|
+
const res = await TestEndpointDefSec.testTranscation(name);
|
|
187
|
+
return res;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@dhttp.getApi('/workflow')
|
|
191
|
+
static async testWfEndpoint(name: string) {
|
|
192
|
+
return await TestEndpointDefSec.testWorkflow(name);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@dhttp.getApi('/transaction')
|
|
196
|
+
static async testTxnEndpoint(name: string) {
|
|
197
|
+
return await TestEndpointDefSec.testTranscation(name);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
class SecondClass {
|
|
202
|
+
@DBOS.requiredRole([])
|
|
203
|
+
@dhttp.getApi('/goodbye')
|
|
204
|
+
static async bye() {
|
|
205
|
+
return Promise.resolve({ message: 'bye!' });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Koa from 'koa';
|
|
2
|
+
import Router from '@koa/router';
|
|
3
|
+
|
|
4
|
+
import { DBOS } from '@dbos-inc/dbos-sdk';
|
|
5
|
+
|
|
6
|
+
import { DBOSKoa } from '../src';
|
|
7
|
+
|
|
8
|
+
import request from 'supertest';
|
|
9
|
+
|
|
10
|
+
const dhttp = new DBOSKoa();
|
|
11
|
+
|
|
12
|
+
let middlewareCounter = 0;
|
|
13
|
+
const testMiddleware: Koa.Middleware = async (_ctx, next) => {
|
|
14
|
+
middlewareCounter++;
|
|
15
|
+
await next();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
let middlewareCounter2 = 0;
|
|
19
|
+
const testMiddleware2: Koa.Middleware = async (_ctx, next) => {
|
|
20
|
+
middlewareCounter2 = middlewareCounter2 + 1;
|
|
21
|
+
await next();
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
let middlewareCounterG = 0;
|
|
25
|
+
const testMiddlewareG: Koa.Middleware = async (_ctx, next) => {
|
|
26
|
+
middlewareCounterG = middlewareCounterG + 1;
|
|
27
|
+
expect(DBOS.logger).toBeDefined();
|
|
28
|
+
await next();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
@dhttp.koaGlobalMiddleware(testMiddlewareG)
|
|
32
|
+
@dhttp.koaGlobalMiddleware(testMiddleware, testMiddleware2)
|
|
33
|
+
export class HTTPEndpoints {
|
|
34
|
+
@dhttp.getApi('/foobar')
|
|
35
|
+
static async foobar(arg: string) {
|
|
36
|
+
return Promise.resolve(`ARG: ${arg}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe('decoratorless-api-tests', () => {
|
|
41
|
+
let app: Koa;
|
|
42
|
+
let appRouter: Router;
|
|
43
|
+
|
|
44
|
+
beforeAll(async () => {
|
|
45
|
+
DBOS.setConfig({
|
|
46
|
+
name: 'dbos-koa-test',
|
|
47
|
+
});
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
beforeEach(async () => {
|
|
52
|
+
middlewareCounter = middlewareCounter2 = middlewareCounterG = 0;
|
|
53
|
+
DBOS.registerLifecycleCallback(dhttp);
|
|
54
|
+
await DBOS.launch();
|
|
55
|
+
DBOS.logRegisteredEndpoints();
|
|
56
|
+
app = new Koa();
|
|
57
|
+
appRouter = new Router();
|
|
58
|
+
dhttp.registerWithApp(app, appRouter);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
afterEach(async () => {
|
|
62
|
+
await DBOS.shutdown();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('simple-functions', async () => {
|
|
66
|
+
const response1 = await request(app.callback()).get('/foobar?arg=A');
|
|
67
|
+
expect(response1.statusCode).toBe(200);
|
|
68
|
+
expect(response1.text).toBe('ARG: A');
|
|
69
|
+
expect(middlewareCounter).toBe(1);
|
|
70
|
+
expect(middlewareCounter2).toBe(1);
|
|
71
|
+
expect(middlewareCounterG).toBe(1);
|
|
72
|
+
});
|
|
73
|
+
});
|