@contember/engine-server 1.1.0-alpha.4 → 1.1.0-alpha.7
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/alpine.dockerfile +1 -1
- package/debian.dockerfile +1 -1
- package/dist/src/bootstrap/index.js +5 -1
- package/dist/src/bootstrap/index.js.map +1 -1
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/configSchema.d.ts +10 -8
- package/dist/src/config/configSchema.d.ts.map +1 -1
- package/dist/src/config/configSchema.js +74 -51
- package/dist/src/config/configSchema.js.map +1 -1
- package/dist/src/config/projectConfigResolver.d.ts.map +1 -1
- package/dist/src/config/projectConfigResolver.js +30 -2
- package/dist/src/config/projectConfigResolver.js.map +1 -1
- package/dist/src/http/index.js +5 -1
- package/dist/src/http/index.js.map +1 -1
- package/dist/src/project/index.js +5 -1
- package/dist/src/project/index.js.map +1 -1
- package/dist/src/start.js +5 -1
- package/dist/src/start.js.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/utils/cluster.js.map +1 -1
- package/dist/src/utils/index.js +5 -1
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/sentry.js +5 -1
- package/dist/src/utils/sentry.js.map +1 -1
- package/dist/tests/e2e/http.test.d.ts +2 -0
- package/dist/tests/e2e/http.test.d.ts.map +1 -0
- package/dist/tests/e2e/http.test.js +275 -0
- package/dist/tests/e2e/http.test.js.map +1 -0
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -23
- package/src/config/configSchema.ts +9 -8
- package/src/config/projectConfigResolver.ts +7 -4
- package/src/tsconfig.json +3 -0
- package/tests/e2e/http.test.ts +303 -0
- package/tests/start-server.sh +16 -0
- package/vite.config.js +3 -0
- package/dist/tests/cases/http.d.ts +0 -2
- package/dist/tests/cases/http.d.ts.map +0 -1
- package/dist/tests/cases/http.js +0 -298
- package/dist/tests/cases/http.js.map +0 -1
- package/tests/cases/http.ts +0 -340
package/dist/tests/cases/http.js
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
-
};
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
const supertest_1 = __importDefault(require("supertest"));
|
|
26
|
-
const src_1 = require("../../src");
|
|
27
|
-
const engine_api_tester_1 = require("@contember/engine-api-tester");
|
|
28
|
-
const nodeAssert = __importStar(require("assert"));
|
|
29
|
-
const assert = __importStar(require("uvu/assert"));
|
|
30
|
-
const uvu_1 = require("uvu");
|
|
31
|
-
const prom_client_1 = __importDefault(require("prom-client"));
|
|
32
|
-
const schema_migrations_1 = require("@contember/schema-migrations");
|
|
33
|
-
const engine_common_1 = require("@contember/engine-common");
|
|
34
|
-
const dbCredentials = (dbName) => {
|
|
35
|
-
return {
|
|
36
|
-
host: String(process.env.TEST_DB_HOST),
|
|
37
|
-
port: Number(process.env.TEST_DB_PORT),
|
|
38
|
-
user: String(process.env.TEST_DB_USER),
|
|
39
|
-
password: String(process.env.TEST_DB_PASSWORD),
|
|
40
|
-
database: dbName,
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
const rootToken = String(process.env.CONTEMBER_ROOT_TOKEN);
|
|
44
|
-
const loginToken = String(process.env.CONTEMBER_LOGIN_TOKEN);
|
|
45
|
-
// Used to allow prettier formatting of GraphQL queries
|
|
46
|
-
const gql = (strings) => {
|
|
47
|
-
nodeAssert.strictEqual(strings.length, 1);
|
|
48
|
-
return strings[0];
|
|
49
|
-
};
|
|
50
|
-
const projectConfig = {
|
|
51
|
-
db: dbCredentials(String(process.env.TEST_DB_NAME)),
|
|
52
|
-
name: 'test',
|
|
53
|
-
slug: 'test',
|
|
54
|
-
stages: [{ name: 'prod', slug: 'prod' }],
|
|
55
|
-
};
|
|
56
|
-
const createContainer = (debug) => {
|
|
57
|
-
prom_client_1.default.register.clear();
|
|
58
|
-
const tenantConfig = {
|
|
59
|
-
db: dbCredentials(String(process.env.TEST_DB_NAME_TENANT)),
|
|
60
|
-
mailer: {},
|
|
61
|
-
credentials: {
|
|
62
|
-
rootToken,
|
|
63
|
-
loginToken,
|
|
64
|
-
},
|
|
65
|
-
secrets: {},
|
|
66
|
-
};
|
|
67
|
-
return new src_1.MasterContainerFactory().createBuilder({
|
|
68
|
-
debugMode: debug,
|
|
69
|
-
serverConfig: {
|
|
70
|
-
logging: {},
|
|
71
|
-
port: 0,
|
|
72
|
-
monitoringPort: 0,
|
|
73
|
-
http: {},
|
|
74
|
-
},
|
|
75
|
-
projectConfigResolver: () => projectConfig,
|
|
76
|
-
tenantConfigResolver: () => tenantConfig,
|
|
77
|
-
plugins: [],
|
|
78
|
-
processType: src_1.ProcessType.singleNode,
|
|
79
|
-
}).build();
|
|
80
|
-
};
|
|
81
|
-
const executeGraphql = (query, options = {}) => {
|
|
82
|
-
const container = createContainer(options.debug || false);
|
|
83
|
-
return (0, supertest_1.default)(container.koa.callback())
|
|
84
|
-
.post(options.path || '/content/test/prod')
|
|
85
|
-
.set('Authorization', 'Bearer ' + (options.authorizationToken || rootToken))
|
|
86
|
-
.send({
|
|
87
|
-
query,
|
|
88
|
-
variables: options.variables || {},
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
const signIn = async (email, password) => {
|
|
92
|
-
const response2 = await executeGraphql(gql `
|
|
93
|
-
mutation ($email: String!, $password: String!) {
|
|
94
|
-
signIn(email: $email, password: $password) {
|
|
95
|
-
ok
|
|
96
|
-
result {
|
|
97
|
-
token
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
`, {
|
|
102
|
-
variables: { email, password },
|
|
103
|
-
authorizationToken: loginToken,
|
|
104
|
-
path: '/tenant',
|
|
105
|
-
});
|
|
106
|
-
return response2.body.data.signIn.result.token;
|
|
107
|
-
};
|
|
108
|
-
uvu_1.test.before(async () => {
|
|
109
|
-
try {
|
|
110
|
-
const connection = await (0, engine_api_tester_1.recreateDatabase)(String(process.env.TEST_DB_NAME));
|
|
111
|
-
await connection.end();
|
|
112
|
-
const tenantConnection = await (0, engine_api_tester_1.recreateDatabase)(String(process.env.TEST_DB_NAME_TENANT));
|
|
113
|
-
const migrationsResolver = new schema_migrations_1.MigrationsResolver(schema_migrations_1.MigrationFilesManager.createForProject((0, engine_api_tester_1.getExampleProjectDirectory)(), 'sample'));
|
|
114
|
-
const container = createContainer(false);
|
|
115
|
-
await container.initializer.initialize();
|
|
116
|
-
const { slug, name, ...config } = projectConfig;
|
|
117
|
-
const groupContainer = await container.projectGroupContainerResolver.getProjectGroupContainer(undefined);
|
|
118
|
-
const tenantContainer = groupContainer.tenantContainer;
|
|
119
|
-
const result = await tenantContainer.projectManager.createProject(tenantContainer.databaseContext, { slug, name, config: config, secrets: {} }, undefined);
|
|
120
|
-
if (!result) {
|
|
121
|
-
throw new Error('Project already exists');
|
|
122
|
-
}
|
|
123
|
-
const projectContainer = await groupContainer.projectContainerResolver.getProjectContainer(slug);
|
|
124
|
-
if (!projectContainer) {
|
|
125
|
-
throw new Error('Should not happen');
|
|
126
|
-
}
|
|
127
|
-
await groupContainer.systemContainer.projectInitializer.initialize(projectContainer.systemDatabaseContextFactory, projectConfig, new engine_common_1.Logger(() => null), await migrationsResolver.getMigrations());
|
|
128
|
-
await tenantConnection.end();
|
|
129
|
-
}
|
|
130
|
-
catch (e) {
|
|
131
|
-
// eslint-disable-next-line no-console
|
|
132
|
-
console.error(e);
|
|
133
|
-
process.exit(1);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
(0, uvu_1.test)('show homepage', async () => {
|
|
137
|
-
await (0, supertest_1.default)(createContainer(false).koa.callback()) //
|
|
138
|
-
.get('/')
|
|
139
|
-
.expect(200)
|
|
140
|
-
.expect('App is running');
|
|
141
|
-
});
|
|
142
|
-
(0, uvu_1.test)('Content API: create & read tag', async () => {
|
|
143
|
-
await executeGraphql(gql `
|
|
144
|
-
mutation {
|
|
145
|
-
createTag(data: { label: "graphql" }) {
|
|
146
|
-
ok
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
`)
|
|
150
|
-
.expect(response => {
|
|
151
|
-
assert.equal(response.body.data, {
|
|
152
|
-
createTag: {
|
|
153
|
-
ok: true,
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
|
-
})
|
|
157
|
-
.expect(200);
|
|
158
|
-
await executeGraphql(gql `
|
|
159
|
-
query {
|
|
160
|
-
listTag(filter: { label: { eq: "graphql" } }) {
|
|
161
|
-
label
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
`)
|
|
165
|
-
.expect(response => {
|
|
166
|
-
assert.equal(response.body.data, {
|
|
167
|
-
listTag: [
|
|
168
|
-
{
|
|
169
|
-
label: 'graphql',
|
|
170
|
-
},
|
|
171
|
-
],
|
|
172
|
-
});
|
|
173
|
-
})
|
|
174
|
-
.expect(200);
|
|
175
|
-
});
|
|
176
|
-
(0, uvu_1.test)('Content API: X-Contember-Ref header', async () => {
|
|
177
|
-
await executeGraphql(gql `
|
|
178
|
-
mutation {
|
|
179
|
-
createTag(data: { label: "typescript" }) {
|
|
180
|
-
ok
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
`).expect(200);
|
|
184
|
-
const response = await executeGraphql(gql `
|
|
185
|
-
query {
|
|
186
|
-
listTag(filter: { label: { eq: "typescript" } }) {
|
|
187
|
-
label
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
`)
|
|
191
|
-
.set('X-Contember-Ref', 'None')
|
|
192
|
-
.expect(response => {
|
|
193
|
-
assert.equal(response.body.data, {
|
|
194
|
-
listTag: [
|
|
195
|
-
{
|
|
196
|
-
label: 'typescript',
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
});
|
|
200
|
-
})
|
|
201
|
-
.expect(200);
|
|
202
|
-
const eventKey = response.get('X-Contember-Ref');
|
|
203
|
-
await executeGraphql(gql `
|
|
204
|
-
query {
|
|
205
|
-
listTag {
|
|
206
|
-
label
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
`)
|
|
210
|
-
.set('X-Contember-Ref', eventKey)
|
|
211
|
-
.expect(304);
|
|
212
|
-
// ignored for mutation
|
|
213
|
-
await executeGraphql(gql `
|
|
214
|
-
mutation {
|
|
215
|
-
createTag(data: { label: "typescript" }) {
|
|
216
|
-
ok
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
`)
|
|
220
|
-
.set('X-Contember-Ref', eventKey)
|
|
221
|
-
.expect(200);
|
|
222
|
-
});
|
|
223
|
-
(0, uvu_1.test)('Content API: invalid schema error', async () => {
|
|
224
|
-
await executeGraphql(gql `
|
|
225
|
-
mutation {
|
|
226
|
-
createFoo(data: { label: "graphql" }) {
|
|
227
|
-
ok
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
`)
|
|
231
|
-
.expect(400)
|
|
232
|
-
.expect(response => {
|
|
233
|
-
assert.equal(response.body.errors[0].message, 'Cannot query field "createFoo" on type "Mutation". Did you mean "createPost" or "createTag"?');
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
(0, uvu_1.test)('Tenant API: sign up, add to a project and check project access', async () => {
|
|
237
|
-
const signUpResponse = await executeGraphql(gql `
|
|
238
|
-
mutation {
|
|
239
|
-
signUp(email: "john@doe.com", password: "123456") {
|
|
240
|
-
ok
|
|
241
|
-
result {
|
|
242
|
-
person {
|
|
243
|
-
identity {
|
|
244
|
-
id
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
`, { path: '/tenant' }).expect(200);
|
|
251
|
-
const identityId = signUpResponse.body.data.signUp.result.person.identity.id;
|
|
252
|
-
const authKey = await signIn('john@doe.com', '123456');
|
|
253
|
-
await executeGraphql(gql `
|
|
254
|
-
query {
|
|
255
|
-
listTag {
|
|
256
|
-
id
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
`, { authorizationToken: authKey })
|
|
260
|
-
.expect(404)
|
|
261
|
-
.expect({ errors: [{ message: 'Project test NOT found', code: 404 }] });
|
|
262
|
-
await executeGraphql(gql `
|
|
263
|
-
query {
|
|
264
|
-
listTag {
|
|
265
|
-
id
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
`, { authorizationToken: authKey, debug: true })
|
|
269
|
-
.expect(403)
|
|
270
|
-
.expect({
|
|
271
|
-
errors: [{ message: 'You are not allowed to access project test', code: 403 }],
|
|
272
|
-
identity: { roles: ['person'] },
|
|
273
|
-
});
|
|
274
|
-
await executeGraphql(gql `
|
|
275
|
-
mutation ($identity: String!) {
|
|
276
|
-
addProjectMember(identityId: $identity, projectSlug: "test", memberships: [{ role: "admin", variables: [] }]) {
|
|
277
|
-
ok
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
`, { path: '/tenant', variables: { identity: identityId } })
|
|
281
|
-
.expect(200)
|
|
282
|
-
.expect(response => {
|
|
283
|
-
assert.equal(response.body.data, { addProjectMember: { ok: true } });
|
|
284
|
-
});
|
|
285
|
-
await executeGraphql(gql `
|
|
286
|
-
query {
|
|
287
|
-
listAuthor {
|
|
288
|
-
id
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
`, { authorizationToken: authKey })
|
|
292
|
-
.expect(response => {
|
|
293
|
-
assert.equal(response.body.data, { listAuthor: [] });
|
|
294
|
-
})
|
|
295
|
-
.expect(200);
|
|
296
|
-
});
|
|
297
|
-
uvu_1.test.run();
|
|
298
|
-
//# sourceMappingURL=http.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../tests/cases/http.ts"],"names":[],"mappings":"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"}
|
package/tests/cases/http.ts
DELETED
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
import supertest from 'supertest'
|
|
2
|
-
import { MasterContainerFactory, ProcessType } from '../../src'
|
|
3
|
-
import { getExampleProjectDirectory, recreateDatabase } from '@contember/engine-api-tester'
|
|
4
|
-
import * as nodeAssert from 'assert'
|
|
5
|
-
import * as assert from 'uvu/assert'
|
|
6
|
-
import { test } from 'uvu'
|
|
7
|
-
import prom from 'prom-client'
|
|
8
|
-
import { MigrationFilesManager, MigrationsResolver } from '@contember/schema-migrations'
|
|
9
|
-
import { Logger } from '@contember/engine-common'
|
|
10
|
-
|
|
11
|
-
const dbCredentials = (dbName: string) => {
|
|
12
|
-
return {
|
|
13
|
-
host: String(process.env.TEST_DB_HOST),
|
|
14
|
-
port: Number(process.env.TEST_DB_PORT),
|
|
15
|
-
user: String(process.env.TEST_DB_USER),
|
|
16
|
-
password: String(process.env.TEST_DB_PASSWORD),
|
|
17
|
-
database: dbName,
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const rootToken = String(process.env.CONTEMBER_ROOT_TOKEN)
|
|
22
|
-
const loginToken = String(process.env.CONTEMBER_LOGIN_TOKEN)
|
|
23
|
-
|
|
24
|
-
// Used to allow prettier formatting of GraphQL queries
|
|
25
|
-
const gql = (strings: TemplateStringsArray) => {
|
|
26
|
-
nodeAssert.strictEqual(strings.length, 1)
|
|
27
|
-
return strings[0]
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const projectConfig = {
|
|
31
|
-
db: dbCredentials(String(process.env.TEST_DB_NAME)),
|
|
32
|
-
name: 'test',
|
|
33
|
-
slug: 'test',
|
|
34
|
-
stages: [{ name: 'prod', slug: 'prod' }],
|
|
35
|
-
}
|
|
36
|
-
const createContainer = (debug: boolean) => {
|
|
37
|
-
prom.register.clear()
|
|
38
|
-
const tenantConfig = {
|
|
39
|
-
db: dbCredentials(String(process.env.TEST_DB_NAME_TENANT)),
|
|
40
|
-
mailer: {},
|
|
41
|
-
credentials: {
|
|
42
|
-
rootToken,
|
|
43
|
-
loginToken,
|
|
44
|
-
},
|
|
45
|
-
secrets: {},
|
|
46
|
-
}
|
|
47
|
-
return new MasterContainerFactory().createBuilder({
|
|
48
|
-
debugMode: debug,
|
|
49
|
-
serverConfig: {
|
|
50
|
-
logging: {},
|
|
51
|
-
port: 0,
|
|
52
|
-
monitoringPort: 0,
|
|
53
|
-
http: {},
|
|
54
|
-
},
|
|
55
|
-
projectConfigResolver: () => projectConfig,
|
|
56
|
-
tenantConfigResolver: () => tenantConfig,
|
|
57
|
-
plugins: [],
|
|
58
|
-
processType: ProcessType.singleNode,
|
|
59
|
-
}).build()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const executeGraphql = (
|
|
63
|
-
query: string,
|
|
64
|
-
options: { authorizationToken?: string; path?: string; variables?: Record<string, any>; debug?: boolean } = {},
|
|
65
|
-
) => {
|
|
66
|
-
const container = createContainer(options.debug || false)
|
|
67
|
-
return supertest(container.koa.callback())
|
|
68
|
-
.post(options.path || '/content/test/prod')
|
|
69
|
-
.set('Authorization', 'Bearer ' + (options.authorizationToken || rootToken))
|
|
70
|
-
.send({
|
|
71
|
-
query,
|
|
72
|
-
variables: options.variables || {},
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const signIn = async (email: string, password: string): Promise<string> => {
|
|
77
|
-
const response2 = await executeGraphql(
|
|
78
|
-
gql`
|
|
79
|
-
mutation ($email: String!, $password: String!) {
|
|
80
|
-
signIn(email: $email, password: $password) {
|
|
81
|
-
ok
|
|
82
|
-
result {
|
|
83
|
-
token
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
`,
|
|
88
|
-
{
|
|
89
|
-
variables: { email, password },
|
|
90
|
-
authorizationToken: loginToken,
|
|
91
|
-
path: '/tenant',
|
|
92
|
-
},
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
return response2.body.data.signIn.result.token
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
test.before(async () => {
|
|
99
|
-
try {
|
|
100
|
-
const connection = await recreateDatabase(String(process.env.TEST_DB_NAME))
|
|
101
|
-
await connection.end()
|
|
102
|
-
const tenantConnection = await recreateDatabase(String(process.env.TEST_DB_NAME_TENANT))
|
|
103
|
-
const migrationsResolver = new MigrationsResolver(
|
|
104
|
-
MigrationFilesManager.createForProject(getExampleProjectDirectory(), 'sample'),
|
|
105
|
-
)
|
|
106
|
-
const container = createContainer(false)
|
|
107
|
-
await container.initializer.initialize()
|
|
108
|
-
|
|
109
|
-
const { slug, name, ...config } = projectConfig
|
|
110
|
-
const groupContainer = await container.projectGroupContainerResolver.getProjectGroupContainer(undefined)
|
|
111
|
-
const tenantContainer = groupContainer.tenantContainer
|
|
112
|
-
const result = await tenantContainer.projectManager.createProject(tenantContainer.databaseContext, { slug, name, config: config as any, secrets: {} }, undefined)
|
|
113
|
-
if (!result) {
|
|
114
|
-
throw new Error('Project already exists')
|
|
115
|
-
}
|
|
116
|
-
const projectContainer = await groupContainer.projectContainerResolver.getProjectContainer(slug)
|
|
117
|
-
if (!projectContainer) {
|
|
118
|
-
throw new Error('Should not happen')
|
|
119
|
-
}
|
|
120
|
-
await groupContainer.systemContainer.projectInitializer.initialize(
|
|
121
|
-
projectContainer.systemDatabaseContextFactory,
|
|
122
|
-
projectConfig,
|
|
123
|
-
new Logger(() => null),
|
|
124
|
-
await migrationsResolver.getMigrations(),
|
|
125
|
-
)
|
|
126
|
-
await tenantConnection.end()
|
|
127
|
-
} catch (e) {
|
|
128
|
-
// eslint-disable-next-line no-console
|
|
129
|
-
console.error(e)
|
|
130
|
-
process.exit(1)
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
test('show homepage', async () => {
|
|
135
|
-
await supertest(createContainer(false).koa.callback()) //
|
|
136
|
-
.get('/')
|
|
137
|
-
.expect(200)
|
|
138
|
-
.expect('App is running')
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
test('Content API: create & read tag', async () => {
|
|
142
|
-
await executeGraphql(
|
|
143
|
-
gql`
|
|
144
|
-
mutation {
|
|
145
|
-
createTag(data: { label: "graphql" }) {
|
|
146
|
-
ok
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
`,
|
|
150
|
-
)
|
|
151
|
-
.expect(response => {
|
|
152
|
-
assert.equal(response.body.data, {
|
|
153
|
-
createTag: {
|
|
154
|
-
ok: true,
|
|
155
|
-
},
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
.expect(200)
|
|
159
|
-
|
|
160
|
-
await executeGraphql(
|
|
161
|
-
gql`
|
|
162
|
-
query {
|
|
163
|
-
listTag(filter: { label: { eq: "graphql" } }) {
|
|
164
|
-
label
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
`,
|
|
168
|
-
)
|
|
169
|
-
.expect(response => {
|
|
170
|
-
assert.equal(response.body.data, {
|
|
171
|
-
listTag: [
|
|
172
|
-
{
|
|
173
|
-
label: 'graphql',
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
})
|
|
177
|
-
})
|
|
178
|
-
.expect(200)
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
test('Content API: X-Contember-Ref header', async () => {
|
|
182
|
-
await executeGraphql(
|
|
183
|
-
gql`
|
|
184
|
-
mutation {
|
|
185
|
-
createTag(data: { label: "typescript" }) {
|
|
186
|
-
ok
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
`,
|
|
190
|
-
).expect(200)
|
|
191
|
-
|
|
192
|
-
const response = await executeGraphql(
|
|
193
|
-
gql`
|
|
194
|
-
query {
|
|
195
|
-
listTag(filter: { label: { eq: "typescript" } }) {
|
|
196
|
-
label
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
`,
|
|
200
|
-
)
|
|
201
|
-
.set('X-Contember-Ref', 'None')
|
|
202
|
-
.expect(response => {
|
|
203
|
-
assert.equal(response.body.data, {
|
|
204
|
-
listTag: [
|
|
205
|
-
{
|
|
206
|
-
label: 'typescript',
|
|
207
|
-
},
|
|
208
|
-
],
|
|
209
|
-
})
|
|
210
|
-
})
|
|
211
|
-
.expect(200)
|
|
212
|
-
const eventKey = response.get('X-Contember-Ref')
|
|
213
|
-
await executeGraphql(
|
|
214
|
-
gql`
|
|
215
|
-
query {
|
|
216
|
-
listTag {
|
|
217
|
-
label
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
`,
|
|
221
|
-
)
|
|
222
|
-
.set('X-Contember-Ref', eventKey)
|
|
223
|
-
.expect(304)
|
|
224
|
-
|
|
225
|
-
// ignored for mutation
|
|
226
|
-
await executeGraphql(
|
|
227
|
-
gql`
|
|
228
|
-
mutation {
|
|
229
|
-
createTag(data: { label: "typescript" }) {
|
|
230
|
-
ok
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
`,
|
|
234
|
-
)
|
|
235
|
-
.set('X-Contember-Ref', eventKey)
|
|
236
|
-
.expect(200)
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
test('Content API: invalid schema error', async () => {
|
|
240
|
-
await executeGraphql(
|
|
241
|
-
gql`
|
|
242
|
-
mutation {
|
|
243
|
-
createFoo(data: { label: "graphql" }) {
|
|
244
|
-
ok
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
`,
|
|
248
|
-
)
|
|
249
|
-
.expect(400)
|
|
250
|
-
.expect(response => {
|
|
251
|
-
assert.equal(
|
|
252
|
-
response.body.errors[0].message,
|
|
253
|
-
'Cannot query field "createFoo" on type "Mutation". Did you mean "createPost" or "createTag"?',
|
|
254
|
-
)
|
|
255
|
-
})
|
|
256
|
-
})
|
|
257
|
-
|
|
258
|
-
test('Tenant API: sign up, add to a project and check project access', async () => {
|
|
259
|
-
const signUpResponse = await executeGraphql(
|
|
260
|
-
gql`
|
|
261
|
-
mutation {
|
|
262
|
-
signUp(email: "john@doe.com", password: "123456") {
|
|
263
|
-
ok
|
|
264
|
-
result {
|
|
265
|
-
person {
|
|
266
|
-
identity {
|
|
267
|
-
id
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
`,
|
|
274
|
-
{ path: '/tenant' },
|
|
275
|
-
).expect(200)
|
|
276
|
-
|
|
277
|
-
const identityId = signUpResponse.body.data.signUp.result.person.identity.id
|
|
278
|
-
|
|
279
|
-
const authKey = await signIn('john@doe.com', '123456')
|
|
280
|
-
await executeGraphql(
|
|
281
|
-
gql`
|
|
282
|
-
query {
|
|
283
|
-
listTag {
|
|
284
|
-
id
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
`,
|
|
288
|
-
{ authorizationToken: authKey },
|
|
289
|
-
)
|
|
290
|
-
.expect(404)
|
|
291
|
-
.expect({ errors: [{ message: 'Project test NOT found', code: 404 }] })
|
|
292
|
-
|
|
293
|
-
await executeGraphql(
|
|
294
|
-
gql`
|
|
295
|
-
query {
|
|
296
|
-
listTag {
|
|
297
|
-
id
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
`,
|
|
301
|
-
{ authorizationToken: authKey, debug: true },
|
|
302
|
-
)
|
|
303
|
-
.expect(403)
|
|
304
|
-
.expect({
|
|
305
|
-
errors: [{ message: 'You are not allowed to access project test', code: 403 }],
|
|
306
|
-
identity: { roles: ['person'] },
|
|
307
|
-
})
|
|
308
|
-
|
|
309
|
-
await executeGraphql(
|
|
310
|
-
gql`
|
|
311
|
-
mutation ($identity: String!) {
|
|
312
|
-
addProjectMember(identityId: $identity, projectSlug: "test", memberships: [{ role: "admin", variables: [] }]) {
|
|
313
|
-
ok
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
`,
|
|
317
|
-
{ path: '/tenant', variables: { identity: identityId } },
|
|
318
|
-
)
|
|
319
|
-
.expect(200)
|
|
320
|
-
.expect(response => {
|
|
321
|
-
assert.equal(response.body.data, { addProjectMember: { ok: true } })
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
await executeGraphql(
|
|
325
|
-
gql`
|
|
326
|
-
query {
|
|
327
|
-
listAuthor {
|
|
328
|
-
id
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
`,
|
|
332
|
-
{ authorizationToken: authKey },
|
|
333
|
-
)
|
|
334
|
-
.expect(response => {
|
|
335
|
-
assert.equal(response.body.data, { listAuthor: [] })
|
|
336
|
-
})
|
|
337
|
-
.expect(200)
|
|
338
|
-
})
|
|
339
|
-
|
|
340
|
-
test.run()
|