@proteinjs/user-server 1.5.4 → 1.7.0
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/CHANGELOG.md +33 -0
- package/dist/generated/index.d.ts +1 -4
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +4 -5
- package/dist/generated/index.js.map +1 -1
- package/dist/src/authorization/userCache.d.ts.map +1 -1
- package/dist/src/authorization/userCache.js +18 -3
- package/dist/src/authorization/userCache.js.map +1 -1
- package/dist/src/routes/avatar.d.ts +19 -0
- package/dist/src/routes/avatar.d.ts.map +1 -0
- package/dist/src/routes/avatar.js +108 -0
- package/dist/src/routes/avatar.js.map +1 -0
- package/dist/src/routes/devLogin.d.ts +15 -5
- package/dist/src/routes/devLogin.d.ts.map +1 -1
- package/dist/src/routes/devLogin.js +61 -13
- package/dist/src/routes/devLogin.js.map +1 -1
- package/dist/src/services/Signup.d.ts +16 -1
- package/dist/src/services/Signup.d.ts.map +1 -1
- package/dist/src/services/Signup.js +49 -15
- package/dist/src/services/Signup.js.map +1 -1
- package/dist/src/services/UpdateUserInfo.d.ts +40 -2
- package/dist/src/services/UpdateUserInfo.d.ts.map +1 -1
- package/dist/src/services/UpdateUserInfo.js +183 -12
- package/dist/src/services/UpdateUserInfo.js.map +1 -1
- package/dist/test/DevLogin.test.d.ts +2 -0
- package/dist/test/DevLogin.test.d.ts.map +1 -0
- package/dist/test/DevLogin.test.js +261 -0
- package/dist/test/DevLogin.test.js.map +1 -0
- package/dist/test/UpdateUserInfoAvatar.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoAvatar.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoAvatar.test.js +337 -0
- package/dist/test/UpdateUserInfoAvatar.test.js.map +1 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.js +94 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.js.map +1 -0
- package/dist/test/UserCacheMissingAccount.test.d.ts +2 -0
- package/dist/test/UserCacheMissingAccount.test.d.ts.map +1 -0
- package/dist/test/UserCacheMissingAccount.test.js +104 -0
- package/dist/test/UserCacheMissingAccount.test.js.map +1 -0
- package/dist/test/UserServerTestEnvironment.d.ts +26 -0
- package/dist/test/UserServerTestEnvironment.d.ts.map +1 -0
- package/dist/test/UserServerTestEnvironment.js +202 -0
- package/dist/test/UserServerTestEnvironment.js.map +1 -0
- package/dist/test/avatarRoute.test.d.ts +2 -0
- package/dist/test/avatarRoute.test.d.ts.map +1 -0
- package/dist/test/avatarRoute.test.js +222 -0
- package/dist/test/avatarRoute.test.js.map +1 -0
- package/generated/index.ts +4 -5
- package/jest.config.js +4 -1
- package/package.json +8 -5
- package/src/authorization/userCache.ts +17 -2
- package/src/heic-decode.d.ts +13 -0
- package/src/routes/avatar.ts +57 -0
- package/src/routes/devLogin.ts +50 -7
- package/src/services/Signup.ts +42 -11
- package/src/services/UpdateUserInfo.ts +124 -13
- package/test/DevLogin.test.ts +159 -0
- package/test/UpdateUserInfoAvatar.test.ts +174 -0
- package/test/UpdateUserInfoSessionRefresh.test.ts +37 -0
- package/test/UserCacheMissingAccount.test.ts +42 -0
- package/test/UserServerTestEnvironment.ts +97 -0
- package/test/avatarRoute.test.ts +111 -0
- package/test/emulatorLock.globalSetup.js +11 -0
- package/test/emulatorLock.globalTeardown.js +8 -0
- package/test/emulatorLock.js +124 -0
- package/test/fixtures/fixture.heic +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
var db_1 = require("@proteinjs/db");
|
|
40
|
+
var user_1 = require("@proteinjs/user");
|
|
41
|
+
var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
|
|
42
|
+
var UpdateUserInfo_1 = require("../src/services/UpdateUserInfo");
|
|
43
|
+
var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
|
|
44
|
+
/**
|
|
45
|
+
* The rename-staleness wart, red-before-green: UpdateUserInfo.updateName wrote the DB but never
|
|
46
|
+
* refreshed the server session cache (userCache serializes the user into session data), so every
|
|
47
|
+
* read through UserRepo in the same request context — and any long-lived context that keeps its
|
|
48
|
+
* session data, e.g. socket sessions — kept serving the OLD name until re-login. The fix routes
|
|
49
|
+
* every user-info mutation through one helper that persists AND refreshes the session cache.
|
|
50
|
+
*/
|
|
51
|
+
describe('UpdateUserInfo.updateName — persists AND refreshes the server session cache', function () {
|
|
52
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
53
|
+
return __generator(this, function (_a) {
|
|
54
|
+
switch (_a.label) {
|
|
55
|
+
case 0: return [4 /*yield*/, testEnv.beforeAll()];
|
|
56
|
+
case 1:
|
|
57
|
+
_a.sent();
|
|
58
|
+
return [2 /*return*/];
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}); });
|
|
62
|
+
afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
63
|
+
return __generator(this, function (_a) {
|
|
64
|
+
switch (_a.label) {
|
|
65
|
+
case 0: return [4 /*yield*/, testEnv.afterAll()];
|
|
66
|
+
case 1:
|
|
67
|
+
_a.sent();
|
|
68
|
+
return [2 /*return*/];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}); });
|
|
72
|
+
it('updates the user row and the session-cached user in the same stroke', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
73
|
+
var user, row;
|
|
74
|
+
return __generator(this, function (_a) {
|
|
75
|
+
switch (_a.label) {
|
|
76
|
+
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Old Name', email: 'rename@test.local' })];
|
|
77
|
+
case 1:
|
|
78
|
+
user = _a.sent();
|
|
79
|
+
testEnv.actAs(user);
|
|
80
|
+
return [4 /*yield*/, new UpdateUserInfo_1.UpdateUserInfo().updateName('New Name')];
|
|
81
|
+
case 2:
|
|
82
|
+
_a.sent();
|
|
83
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { id: user.id })];
|
|
84
|
+
case 3:
|
|
85
|
+
row = _a.sent();
|
|
86
|
+
expect(row.name).toBe('New Name');
|
|
87
|
+
// Outcome 2 (the wart): the session cache must serve the new name too. RED pre-fix.
|
|
88
|
+
expect(new user_1.UserRepo().getUser().name).toBe('New Name');
|
|
89
|
+
return [2 /*return*/];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}); });
|
|
93
|
+
});
|
|
94
|
+
//# sourceMappingURL=UpdateUserInfoSessionRefresh.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpdateUserInfoSessionRefresh.test.js","sourceRoot":"","sources":["../../test/UpdateUserInfoSessionRefresh.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAA8C;AAC9C,wCAAmD;AACnD,yEAAwE;AACxE,iEAAgE;AAEhE,IAAM,OAAO,GAAG,IAAI,qDAAyB,EAAE,CAAC;AAEhD;;;;;;GAMG;AACH,QAAQ,CAAC,6EAA6E,EAAE;IACtF,SAAS,CAAC;;;wBACR,qBAAM,OAAO,CAAC,SAAS,EAAE,EAAA;;oBAAzB,SAAyB,CAAC;;;;SAC3B,CAAC,CAAC;IAEH,QAAQ,CAAC;;;wBACP,qBAAM,OAAO,CAAC,QAAQ,EAAE,EAAA;;oBAAxB,SAAwB,CAAC;;;;SAC1B,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE;;;;wBAC3D,qBAAM,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAA;;oBAAjF,IAAI,GAAG,SAA0E;oBACvF,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAEpB,qBAAM,IAAI,+BAAc,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAA;;oBAAjD,SAAiD,CAAC;oBAGtC,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAA;;oBAA7D,GAAG,GAAG,SAAuD;oBACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAElC,oFAAoF;oBACpF,MAAM,CAAC,IAAI,eAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;;;;SACxD,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserCacheMissingAccount.test.d.ts","sourceRoot":"","sources":["../../test/UserCacheMissingAccount.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
var userCache_1 = require("../src/authorization/userCache");
|
|
40
|
+
var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
|
|
41
|
+
var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
|
|
42
|
+
/**
|
|
43
|
+
* Missing-account session crash, red-before-green: a session can outlive its account (user row
|
|
44
|
+
* deleted, or a dev auto-login for a never-created email). userCache.create looked the user up
|
|
45
|
+
* and unconditionally `delete`d the password off the result — `db.get` returns undefined for a
|
|
46
|
+
* missing row, the delete threw, and the rejection escaped wrapRoute's session-cache build
|
|
47
|
+
* (outside its try/catch) as an unhandled rejection that downed the whole process.
|
|
48
|
+
*
|
|
49
|
+
* The seam: userCache.create resolves a missing account to the unauthenticated guest session —
|
|
50
|
+
* the client sees no authenticated user and re-logs — never a throw.
|
|
51
|
+
*/
|
|
52
|
+
describe('userCache.create — session referencing a missing account', function () {
|
|
53
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
54
|
+
return __generator(this, function (_a) {
|
|
55
|
+
switch (_a.label) {
|
|
56
|
+
case 0: return [4 /*yield*/, testEnv.beforeAll()];
|
|
57
|
+
case 1:
|
|
58
|
+
_a.sent();
|
|
59
|
+
return [2 /*return*/];
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}); });
|
|
63
|
+
afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
64
|
+
return __generator(this, function (_a) {
|
|
65
|
+
switch (_a.label) {
|
|
66
|
+
case 0: return [4 /*yield*/, testEnv.afterAll()];
|
|
67
|
+
case 1:
|
|
68
|
+
_a.sent();
|
|
69
|
+
return [2 /*return*/];
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}); });
|
|
73
|
+
it('resolves to the unauthenticated guest session instead of throwing', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
74
|
+
var user;
|
|
75
|
+
return __generator(this, function (_a) {
|
|
76
|
+
switch (_a.label) {
|
|
77
|
+
case 0: return [4 /*yield*/, userCache_1.userCache.create('stale-session', 'deleted-account@test.local')];
|
|
78
|
+
case 1:
|
|
79
|
+
user = _a.sent();
|
|
80
|
+
expect(user.id).toBe('guest');
|
|
81
|
+
expect(user.roles).toEqual([]);
|
|
82
|
+
return [2 /*return*/];
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}); });
|
|
86
|
+
it('still resolves a real account normally', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
87
|
+
var created, user;
|
|
88
|
+
return __generator(this, function (_a) {
|
|
89
|
+
switch (_a.label) {
|
|
90
|
+
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Real User', email: 'real-account@test.local' })];
|
|
91
|
+
case 1:
|
|
92
|
+
created = _a.sent();
|
|
93
|
+
return [4 /*yield*/, userCache_1.userCache.create('live-session', 'real-account@test.local')];
|
|
94
|
+
case 2:
|
|
95
|
+
user = _a.sent();
|
|
96
|
+
expect(user.id).toBe(created.id);
|
|
97
|
+
expect(user.email).toBe('real-account@test.local');
|
|
98
|
+
expect(user.password).toBeUndefined();
|
|
99
|
+
return [2 /*return*/];
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}); });
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=UserCacheMissingAccount.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserCacheMissingAccount.test.js","sourceRoot":"","sources":["../../test/UserCacheMissingAccount.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4DAA2D;AAC3D,yEAAwE;AAExE,IAAM,OAAO,GAAG,IAAI,qDAAyB,EAAE,CAAC;AAEhD;;;;;;;;;GASG;AACH,QAAQ,CAAC,0DAA0D,EAAE;IACnE,SAAS,CAAC;;;wBACR,qBAAM,OAAO,CAAC,SAAS,EAAE,EAAA;;oBAAzB,SAAyB,CAAC;;;;SAC3B,CAAC,CAAC;IAEH,QAAQ,CAAC;;;wBACP,qBAAM,OAAO,CAAC,QAAQ,EAAE,EAAA;;oBAAxB,SAAwB,CAAC;;;;SAC1B,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE;;;;wBAEzD,qBAAM,qBAAS,CAAC,MAAM,CAAC,eAAe,EAAE,4BAA4B,CAAC,EAAA;;oBAA5E,IAAI,GAAG,SAAqE;oBAElF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC9B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;;;;SAChC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE;;;;wBAC3B,qBAAM,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,EAAA;;oBAA3F,OAAO,GAAG,SAAiF;oBAEpF,qBAAM,qBAAS,CAAC,MAAM,CAAC,cAAc,EAAE,yBAAyB,CAAC,EAAA;;oBAAxE,IAAI,GAAG,SAAiE;oBAE9E,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;oBACnD,MAAM,CAAE,IAAY,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,CAAC;;;;SAChD,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SpannerDriver } from '@proteinjs/db-driver-spanner';
|
|
2
|
+
import { User } from '@proteinjs/user';
|
|
3
|
+
/**
|
|
4
|
+
* Emulator-backed test environment for user-server integration tests (Spanner emulator on
|
|
5
|
+
* SPANNER_EMULATOR_HOST, provisioned on demand). Same shape as chat-server's ChatTestEnvironment:
|
|
6
|
+
* seed deterministic session storage + db driver into the SourceRepository cache, load the tables
|
|
7
|
+
* the suites touch, drop them on the way out.
|
|
8
|
+
*/
|
|
9
|
+
export declare class UserServerTestEnvironment {
|
|
10
|
+
readonly spannerDriver: SpannerDriver;
|
|
11
|
+
private dropTestTable;
|
|
12
|
+
private userRepo;
|
|
13
|
+
beforeAll(): Promise<void>;
|
|
14
|
+
afterAll(): Promise<void>;
|
|
15
|
+
/** Insert a user row (as system) and return it. */
|
|
16
|
+
createUser(args: {
|
|
17
|
+
name: string;
|
|
18
|
+
email: string;
|
|
19
|
+
roles?: string[];
|
|
20
|
+
}): Promise<User>;
|
|
21
|
+
/** Seed the session cache with `user` — the identity service calls and scoped db ops run under. */
|
|
22
|
+
actAs(user: User): void;
|
|
23
|
+
private loadTables;
|
|
24
|
+
private dropTables;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=UserServerTestEnvironment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserServerTestEnvironment.d.ts","sourceRoot":"","sources":["../../test/UserServerTestEnvironment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAK7D,OAAO,EAAwB,IAAI,EAAY,MAAM,iBAAiB,CAAC;AAmBvE;;;;;GAKG;AACH,qBAAa,yBAAyB;IACpC,QAAQ,CAAC,aAAa,gBAInB;IACH,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,QAAQ,CAAkB;IAE5B,SAAS;IAqBT,QAAQ;IAMd,mDAAmD;IAC7C,UAAU,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxF,mGAAmG;IACnG,KAAK,CAAC,IAAI,EAAE,IAAI;YAIF,UAAU;YAOV,UAAU;CAKzB"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.UserServerTestEnvironment = void 0;
|
|
40
|
+
var db_1 = require("@proteinjs/db");
|
|
41
|
+
var db_driver_spanner_1 = require("@proteinjs/db-driver-spanner");
|
|
42
|
+
var test_1 = require("@proteinjs/db-driver-spanner/test");
|
|
43
|
+
var db_file_1 = require("@proteinjs/db-file");
|
|
44
|
+
var server_api_1 = require("@proteinjs/server-api");
|
|
45
|
+
var reflection_1 = require("@proteinjs/reflection");
|
|
46
|
+
var user_1 = require("@proteinjs/user");
|
|
47
|
+
/** In-memory SessionDataStorage seeded into the SourceRepository cache (tests don't load the
|
|
48
|
+
* generated source graph, so `Session` would otherwise find no implementation). */
|
|
49
|
+
var TestSessionDataStorage = /** @class */ (function () {
|
|
50
|
+
function TestSessionDataStorage() {
|
|
51
|
+
this.environment = 'node';
|
|
52
|
+
}
|
|
53
|
+
TestSessionDataStorage.prototype.setData = function (data) {
|
|
54
|
+
TestSessionDataStorage.data = data;
|
|
55
|
+
};
|
|
56
|
+
TestSessionDataStorage.prototype.getData = function () {
|
|
57
|
+
return TestSessionDataStorage.data;
|
|
58
|
+
};
|
|
59
|
+
return TestSessionDataStorage;
|
|
60
|
+
}());
|
|
61
|
+
/**
|
|
62
|
+
* Emulator-backed test environment for user-server integration tests (Spanner emulator on
|
|
63
|
+
* SPANNER_EMULATOR_HOST, provisioned on demand). Same shape as chat-server's ChatTestEnvironment:
|
|
64
|
+
* seed deterministic session storage + db driver into the SourceRepository cache, load the tables
|
|
65
|
+
* the suites touch, drop them on the way out.
|
|
66
|
+
*/
|
|
67
|
+
var UserServerTestEnvironment = /** @class */ (function () {
|
|
68
|
+
function UserServerTestEnvironment() {
|
|
69
|
+
this.spannerDriver = new db_driver_spanner_1.SpannerDriver({
|
|
70
|
+
projectId: 'proteinjs-test',
|
|
71
|
+
instanceName: 'proteinjs-test',
|
|
72
|
+
databaseName: 'test',
|
|
73
|
+
});
|
|
74
|
+
this.dropTestTable = (0, test_1.getDropTestTable)(this.spannerDriver);
|
|
75
|
+
this.userRepo = new user_1.UserRepo();
|
|
76
|
+
}
|
|
77
|
+
UserServerTestEnvironment.prototype.beforeAll = function () {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
79
|
+
var objectCache;
|
|
80
|
+
var _this = this;
|
|
81
|
+
return __generator(this, function (_a) {
|
|
82
|
+
switch (_a.label) {
|
|
83
|
+
case 0:
|
|
84
|
+
// The emulator wipes its in-memory instances on any container restart (and CI service
|
|
85
|
+
// containers start empty) — self-provision so suites never depend on out-of-band setup.
|
|
86
|
+
return [4 /*yield*/, test_1.SpannerEmulatorProvisioner.ensureProvisioned({
|
|
87
|
+
projectId: 'proteinjs-test',
|
|
88
|
+
instanceName: 'proteinjs-test',
|
|
89
|
+
databaseName: 'test',
|
|
90
|
+
})];
|
|
91
|
+
case 1:
|
|
92
|
+
// The emulator wipes its in-memory instances on any container restart (and CI service
|
|
93
|
+
// containers start empty) — self-provision so suites never depend on out-of-band setup.
|
|
94
|
+
_a.sent();
|
|
95
|
+
objectCache = reflection_1.SourceRepository.get().objectCache;
|
|
96
|
+
objectCache['@proteinjs/server-api/SessionDataStorage'] = [new TestSessionDataStorage()];
|
|
97
|
+
objectCache['@proteinjs/db/DefaultDbDriverFactory'] = [{ getDbDriver: function () { return _this.spannerDriver; } }];
|
|
98
|
+
server_api_1.Session.setData({
|
|
99
|
+
sessionId: 'test-session',
|
|
100
|
+
user: 'guest',
|
|
101
|
+
data: {},
|
|
102
|
+
});
|
|
103
|
+
return [4 /*yield*/, this.loadTables(user_1.tables)];
|
|
104
|
+
case 2:
|
|
105
|
+
_a.sent();
|
|
106
|
+
return [4 /*yield*/, this.loadTables(db_file_1.tables)];
|
|
107
|
+
case 3:
|
|
108
|
+
_a.sent();
|
|
109
|
+
return [2 /*return*/];
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
UserServerTestEnvironment.prototype.afterAll = function () {
|
|
115
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
116
|
+
return __generator(this, function (_a) {
|
|
117
|
+
switch (_a.label) {
|
|
118
|
+
case 0: return [4 /*yield*/, this.dropTables(db_file_1.tables)];
|
|
119
|
+
case 1:
|
|
120
|
+
_a.sent();
|
|
121
|
+
return [4 /*yield*/, this.dropTables(user_1.tables)];
|
|
122
|
+
case 2:
|
|
123
|
+
_a.sent();
|
|
124
|
+
test_1.SpannerEmulatorProvisioner.release();
|
|
125
|
+
return [2 /*return*/];
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
/** Insert a user row (as system) and return it. */
|
|
131
|
+
UserServerTestEnvironment.prototype.createUser = function (args) {
|
|
132
|
+
var _a;
|
|
133
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
134
|
+
return __generator(this, function (_b) {
|
|
135
|
+
switch (_b.label) {
|
|
136
|
+
case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().insert(user_1.tables.User, {
|
|
137
|
+
name: args.name,
|
|
138
|
+
email: args.email,
|
|
139
|
+
password: 'test',
|
|
140
|
+
emailVerified: true,
|
|
141
|
+
roles: (_a = args.roles) !== null && _a !== void 0 ? _a : [],
|
|
142
|
+
})];
|
|
143
|
+
case 1: return [2 /*return*/, _b.sent()];
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
/** Seed the session cache with `user` — the identity service calls and scoped db ops run under. */
|
|
149
|
+
UserServerTestEnvironment.prototype.actAs = function (user) {
|
|
150
|
+
this.userRepo.setUser(user);
|
|
151
|
+
};
|
|
152
|
+
UserServerTestEnvironment.prototype.loadTables = function (tables) {
|
|
153
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
154
|
+
var dbDriver, _i, _a, table;
|
|
155
|
+
return __generator(this, function (_b) {
|
|
156
|
+
switch (_b.label) {
|
|
157
|
+
case 0:
|
|
158
|
+
dbDriver = db_1.Db.getDefaultDbDriver();
|
|
159
|
+
_i = 0, _a = Object.values(tables);
|
|
160
|
+
_b.label = 1;
|
|
161
|
+
case 1:
|
|
162
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
163
|
+
table = _a[_i];
|
|
164
|
+
return [4 /*yield*/, dbDriver.getTableManager().loadTable(table)];
|
|
165
|
+
case 2:
|
|
166
|
+
_b.sent();
|
|
167
|
+
_b.label = 3;
|
|
168
|
+
case 3:
|
|
169
|
+
_i++;
|
|
170
|
+
return [3 /*break*/, 1];
|
|
171
|
+
case 4: return [2 /*return*/];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
UserServerTestEnvironment.prototype.dropTables = function (tables) {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
178
|
+
var _i, _a, table;
|
|
179
|
+
return __generator(this, function (_b) {
|
|
180
|
+
switch (_b.label) {
|
|
181
|
+
case 0:
|
|
182
|
+
_i = 0, _a = Object.values(tables);
|
|
183
|
+
_b.label = 1;
|
|
184
|
+
case 1:
|
|
185
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
186
|
+
table = _a[_i];
|
|
187
|
+
return [4 /*yield*/, this.dropTestTable(table)];
|
|
188
|
+
case 2:
|
|
189
|
+
_b.sent();
|
|
190
|
+
_b.label = 3;
|
|
191
|
+
case 3:
|
|
192
|
+
_i++;
|
|
193
|
+
return [3 /*break*/, 1];
|
|
194
|
+
case 4: return [2 /*return*/];
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
return UserServerTestEnvironment;
|
|
200
|
+
}());
|
|
201
|
+
exports.UserServerTestEnvironment = UserServerTestEnvironment;
|
|
202
|
+
//# sourceMappingURL=UserServerTestEnvironment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserServerTestEnvironment.js","sourceRoot":"","sources":["../../test/UserServerTestEnvironment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatarRoute.test.d.ts","sourceRoot":"","sources":["../../test/avatarRoute.test.ts"],"names":[],"mappings":""}
|