@prosopo/env 3.6.22 → 3.6.24

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @prosopo/env@3.6.22 build:cjs
2
+ > @prosopo/env@3.6.24 build:cjs
3
3
  > NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
4
4
 
5
5
  ViteCommonJSConfig: .
@@ -52,4 +52,4 @@ dist/cjs/index.cjs 0.34 kB │ gzip: 0.18 kB
52
52
  dist/cjs/provider.cjs 1.27 kB │ gzip: 0.56 kB
53
53
  dist/cjs/env.cjs 5.73 kB │ gzip: 1.79 kB
54
54
 
55
- ✓ built in 33ms
55
+ ✓ built in 76ms
@@ -1,8 +1,8 @@
1
1
 
2
- > @prosopo/env@3.6.22 build:tsc
2
+ > @prosopo/env@3.6.24 build:tsc
3
3
  > tsc --build --verbose
4
4
 
5
- 11:41:21 PM - Projects in this build:
5
+ 1:57:56 PM - Projects in this build:
6
6
  * ../../dev/config/tsconfig.json
7
7
  * ../locale/tsconfig.json
8
8
  * ../util/tsconfig.json
@@ -21,39 +21,39 @@
21
21
  * ../types-env/tsconfig.json
22
22
  * tsconfig.json
23
23
 
24
- 11:41:21 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
24
+ 1:57:56 PM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
25
25
 
26
- 11:41:21 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
26
+ 1:57:56 PM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
27
27
 
28
- 11:41:21 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
28
+ 1:57:56 PM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
29
29
 
30
- 11:41:21 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
30
+ 1:57:56 PM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/logger.ts' is older than output '../logger/tsconfig.tsbuildinfo'
31
31
 
32
- 11:41:21 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
32
+ 1:57:56 PM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
33
33
 
34
- 11:41:21 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/procaptcha/api.ts' is older than output '../types/tsconfig.tsbuildinfo'
34
+ 1:57:56 PM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
35
35
 
36
- 11:41:21 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/error.ts' is older than output '../common/tsconfig.tsbuildinfo'
36
+ 1:57:56 PM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/index.ts' is older than output '../common/tsconfig.tsbuildinfo'
37
37
 
38
- 11:41:21 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/IpInfoService.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
38
+ 1:57:56 PM - Project '../ipinfo/tsconfig.json' is up to date because newest input '../ipinfo/src/types.ts' is older than output '../ipinfo/tsconfig.tsbuildinfo'
39
39
 
40
- 11:41:21 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/index.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
40
+ 1:57:56 PM - Project '../api-route/tsconfig.json' is up to date because newest input '../api-route/src/apiRoutes.ts' is older than output '../api-route/tsconfig.tsbuildinfo'
41
41
 
42
- 11:41:21 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/index.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
42
+ 1:57:56 PM - Project '../redis-client/tsconfig.json' is up to date because newest input '../redis-client/src/redisClient.ts' is older than output '../redis-client/tsconfig.tsbuildinfo'
43
43
 
44
- 11:41:21 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
44
+ 1:57:56 PM - Project '../api/tsconfig.json' is up to date because newest input '../api/src/index.ts' is older than output '../api/tsconfig.tsbuildinfo'
45
45
 
46
- 11:41:21 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/transformRule.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
46
+ 1:57:56 PM - Project '../user-access-policy/tsconfig.json' is up to date because newest input '../user-access-policy/src/ruleRecord.ts' is older than output '../user-access-policy/tsconfig.tsbuildinfo'
47
47
 
48
- 11:41:21 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/types/captcha.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
48
+ 1:57:56 PM - Project '../types-database/tsconfig.json' is up to date because newest input '../types-database/src/types.test-d.ts' is older than output '../types-database/tsconfig.tsbuildinfo'
49
49
 
50
- 11:41:21 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/mongoGlobalSetup.ts' is older than output '../database/tsconfig.tsbuildinfo'
50
+ 1:57:56 PM - Project '../database/tsconfig.json' is up to date because newest input '../database/src/tests/unit/redisCacheEscalation.unit.test.ts' is older than output '../database/tsconfig.tsbuildinfo'
51
51
 
52
- 11:41:21 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
52
+ 1:57:56 PM - Project '../keyring/tsconfig.json' is up to date because newest input '../keyring/src/index.ts' is older than output '../keyring/tsconfig.tsbuildinfo'
53
53
 
54
- 11:41:21 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/env.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
54
+ 1:57:56 PM - Project '../types-env/tsconfig.json' is up to date because newest input '../types-env/src/index.ts' is older than output '../types-env/tsconfig.tsbuildinfo'
55
55
 
56
- 11:41:21 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
56
+ 1:57:56 PM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
57
57
 
58
- 11:41:21 PM - Building project '/home/runner/work/captcha/captcha/packages/env/tsconfig.json'...
58
+ 1:57:56 PM - Building project '/home/runner/work/captcha/captcha/packages/env/tsconfig.json'...
59
59
 
@@ -1,9 +1,9 @@
1
1
 
2
- > @prosopo/env@3.6.22 build
2
+ > @prosopo/env@3.6.24 build
3
3
  > npm run build:cross-env -- --mode ${NODE_ENV:-development}
4
4
 
5
5
 
6
- > @prosopo/env@3.6.22 build:cross-env
6
+ > @prosopo/env@3.6.24 build:cross-env
7
7
  > vite build --config vite.esm.config.ts --mode production
8
8
 
9
9
  ViteEsmConfig: .
@@ -57,4 +57,4 @@ dist/index.js 0.21 kB │ gzip: 0.13 kB
57
57
  dist/provider.js 1.17 kB │ gzip: 0.53 kB
58
58
  dist/env.js 5.44 kB │ gzip: 1.75 kB
59
59
 
60
- ✓ built in 43ms
60
+ ✓ built in 62ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @prosopo/env
2
2
 
3
+ ## 3.6.24
4
+ ### Patch Changes
5
+
6
+ - 38396b4: test(env): cover environment accessors, readiness paths and provider cleanup
7
+ - Updated dependencies [9fec7bd]
8
+ - Updated dependencies [2aabe73]
9
+ - Updated dependencies [bcef918]
10
+ - @prosopo/common@3.1.49
11
+ - @prosopo/types@5.0.1
12
+ - @prosopo/logger@2.0.5
13
+ - @prosopo/database@4.0.1
14
+ - @prosopo/ipinfo@0.3.2
15
+ - @prosopo/keyring@2.9.64
16
+ - @prosopo/types-env@2.10.21
17
+
18
+ ## 3.6.23
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [787017b]
22
+ - Updated dependencies [787017b]
23
+ - Updated dependencies [787017b]
24
+ - Updated dependencies [6f19cde]
25
+ - @prosopo/database@4.0.0
26
+ - @prosopo/types@5.0.0
27
+ - @prosopo/ipinfo@0.3.1
28
+ - @prosopo/keyring@2.9.63
29
+ - @prosopo/types-env@2.10.20
30
+
3
31
  ## 3.6.22
4
32
  ### Patch Changes
5
33
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=env.accessors.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.accessors.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/env.accessors.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,298 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ const { mockProviderDatabase, mockIpInfoInit, mockAddPair, mockGetPair } = vi.hoisted(() => ({
3
+ mockProviderDatabase: vi.fn(),
4
+ mockIpInfoInit: vi.fn(),
5
+ mockAddPair: vi.fn(),
6
+ mockGetPair: vi.fn(),
7
+ }));
8
+ vi.mock("@prosopo/database", () => ({
9
+ ProviderDatabase: mockProviderDatabase,
10
+ }));
11
+ vi.mock("@prosopo/ipinfo", () => ({
12
+ IpInfoService: vi.fn().mockImplementation(function () {
13
+ return { initialize: mockIpInfoInit };
14
+ }),
15
+ }));
16
+ vi.mock("@prosopo/keyring", () => ({
17
+ Keyring: vi.fn().mockImplementation(function () {
18
+ return { addPair: mockAddPair };
19
+ }),
20
+ getPair: mockGetPair,
21
+ }));
22
+ import { Environment } from "../env.js";
23
+ const buildConfig = (overrides = {}) => ({
24
+ defaultEnvironment: "test",
25
+ logLevel: "info",
26
+ account: { secret: "//Alice", password: undefined },
27
+ database: {
28
+ test: {
29
+ endpoint: "mongodb://127.0.0.1:27017",
30
+ dbname: "test",
31
+ authSource: "admin",
32
+ type: "mongo",
33
+ },
34
+ },
35
+ redisConnection: { url: "redis://localhost", password: "" },
36
+ maxmindDbPath: undefined,
37
+ ipApi: undefined,
38
+ ...overrides,
39
+ });
40
+ const stubPair = (overrides = {}) => ({
41
+ address: "addr",
42
+ isLocked: false,
43
+ unlock: vi.fn(),
44
+ ...overrides,
45
+ });
46
+ const buildEnv = (config = buildConfig()) => {
47
+ const env = new Environment(config, stubPair());
48
+ env.logger = {
49
+ debug: vi.fn(),
50
+ info: vi.fn(),
51
+ warn: vi.fn(),
52
+ error: vi.fn(),
53
+ };
54
+ return env;
55
+ };
56
+ const mockDb = (overrides = {}) => ({
57
+ connect: vi.fn().mockResolvedValue(undefined),
58
+ connected: true,
59
+ connection: { readyState: 1 },
60
+ getMostRecentDatasetId: vi
61
+ .fn()
62
+ .mockResolvedValue("0xdataset"),
63
+ ...overrides,
64
+ });
65
+ beforeEach(() => {
66
+ mockProviderDatabase.mockReset();
67
+ mockIpInfoInit.mockReset();
68
+ mockIpInfoInit.mockResolvedValue(undefined);
69
+ mockAddPair.mockReset();
70
+ mockAddPair.mockImplementation((pair) => pair);
71
+ mockGetPair.mockReset();
72
+ mockGetPair.mockImplementation(() => stubPair());
73
+ delete process.env.MAINTENANCE_MODE;
74
+ });
75
+ afterEach(() => {
76
+ delete process.env.MAINTENANCE_MODE;
77
+ });
78
+ describe("Environment construction", () => {
79
+ it("derives the pair from the config secret when none is supplied", () => {
80
+ const env = new Environment(buildConfig());
81
+ expect(mockGetPair).toHaveBeenCalledWith("//Alice");
82
+ expect(env.getPair()).toBeDefined();
83
+ });
84
+ it("registers the supplied pair with the keyring", () => {
85
+ buildEnv();
86
+ expect(mockAddPair).toHaveBeenCalled();
87
+ });
88
+ it("assigns a 32 character env id", () => {
89
+ expect(buildEnv().envId).toHaveLength(32);
90
+ });
91
+ });
92
+ describe("Environment accessors", () => {
93
+ it("throws from getDb before the DB is set up", () => {
94
+ expect(() => buildEnv().getDb()).toThrow();
95
+ });
96
+ it("returns the db once it is set", () => {
97
+ const env = buildEnv();
98
+ const db = mockDb();
99
+ env.db = db;
100
+ expect(env.getDb()).toBe(db);
101
+ });
102
+ it("throws from getAssetsResolver before it is set up", () => {
103
+ expect(() => buildEnv().getAssetsResolver()).toThrow();
104
+ });
105
+ it("returns the assets resolver once it is set", () => {
106
+ const env = buildEnv();
107
+ const resolver = {};
108
+ env.assetsResolver = resolver;
109
+ expect(env.getAssetsResolver()).toBe(resolver);
110
+ });
111
+ it("throws from getPair when there is no pair", () => {
112
+ const env = buildEnv();
113
+ env.pair = undefined;
114
+ expect(() => env.getPair()).toThrow();
115
+ });
116
+ it("throws from getSigner when there is no pair", async () => {
117
+ const env = buildEnv();
118
+ env.pair = undefined;
119
+ await expect(env.getSigner()).rejects.toMatchObject({
120
+ translationKey: "CONTRACT.SIGNER_UNDEFINED",
121
+ });
122
+ });
123
+ it("wraps a keyring failure from getSigner", async () => {
124
+ const env = buildEnv();
125
+ mockAddPair.mockImplementation(() => {
126
+ throw new Error("bad pair");
127
+ });
128
+ await expect(env.getSigner()).rejects.toMatchObject({
129
+ translationKey: "CONTRACT.SIGNER_UNDEFINED",
130
+ });
131
+ });
132
+ it("returns the re-registered pair from getSigner", async () => {
133
+ const env = buildEnv();
134
+ const registered = stubPair({ address: "registered" });
135
+ mockAddPair.mockImplementation(() => registered);
136
+ await expect(env.getSigner()).resolves.toBe(registered);
137
+ });
138
+ });
139
+ describe("Environment.buildDatabase", () => {
140
+ it("returns undefined when no database is configured at all", () => {
141
+ const env = buildEnv(buildConfig({ database: undefined }));
142
+ expect(env.buildDatabase()).toBeUndefined();
143
+ expect(mockProviderDatabase).not.toHaveBeenCalled();
144
+ });
145
+ it("returns undefined when the current environment has no database", () => {
146
+ const env = buildEnv(buildConfig({ database: { other: undefined } }));
147
+ expect(env.buildDatabase()).toBeUndefined();
148
+ });
149
+ it("passes the mongo and redis config through to the database", () => {
150
+ mockProviderDatabase.mockImplementation(function () {
151
+ return mockDb();
152
+ });
153
+ buildEnv().buildDatabase();
154
+ expect(mockProviderDatabase.mock.calls[0]?.[0]).toMatchObject({
155
+ mongo: {
156
+ url: "mongodb://127.0.0.1:27017",
157
+ dbname: "test",
158
+ authSource: "admin",
159
+ },
160
+ redis: { url: "redis://localhost", password: "" },
161
+ });
162
+ });
163
+ });
164
+ describe("Environment.importDatabase", () => {
165
+ it("wraps a construction failure in a DATABASE_IMPORT_FAILED error", async () => {
166
+ mockProviderDatabase.mockImplementation(function () {
167
+ throw new Error("bad config");
168
+ });
169
+ await expect(buildEnv().importDatabase()).rejects.toMatchObject({
170
+ translationKey: "DATABASE.DATABASE_IMPORT_FAILED",
171
+ });
172
+ });
173
+ it("is a no-op when there is no database configured", async () => {
174
+ const env = buildEnv(buildConfig({ database: undefined }));
175
+ await expect(env.importDatabase()).resolves.toBeUndefined();
176
+ expect(env.db).toBeUndefined();
177
+ });
178
+ });
179
+ describe("Environment.isReady", () => {
180
+ it("returns immediately when already ready", async () => {
181
+ const env = buildEnv();
182
+ env.ready = true;
183
+ await env.isReady();
184
+ expect(mockProviderDatabase).not.toHaveBeenCalled();
185
+ expect(mockIpInfoInit).not.toHaveBeenCalled();
186
+ });
187
+ it("unlocks a locked pair using the configured password", async () => {
188
+ const unlock = vi.fn();
189
+ const config = buildConfig({
190
+ account: { secret: "//Alice", password: "hunter2" },
191
+ });
192
+ const env = buildEnv(config);
193
+ env.pair = stubPair({ isLocked: true, unlock });
194
+ mockProviderDatabase.mockImplementation(function () {
195
+ return mockDb();
196
+ });
197
+ await env.isReady();
198
+ expect(unlock).toHaveBeenCalledWith("hunter2");
199
+ });
200
+ it("resolves and records the most recent dataset id", async () => {
201
+ mockProviderDatabase.mockImplementation(function () {
202
+ return mockDb();
203
+ });
204
+ const env = buildEnv();
205
+ await env.isReady();
206
+ expect(env.datasetId).toBe("0xdataset");
207
+ });
208
+ it("warns but stays ready when there are no datasets", async () => {
209
+ mockProviderDatabase.mockImplementation(function () {
210
+ return mockDb({
211
+ getMostRecentDatasetId: vi
212
+ .fn()
213
+ .mockResolvedValue(undefined),
214
+ });
215
+ });
216
+ const env = buildEnv();
217
+ await env.isReady();
218
+ expect(env.ready).toBe(true);
219
+ expect(env.datasetId).toBeUndefined();
220
+ expect(env.logger.warn).toHaveBeenCalled();
221
+ });
222
+ it("tolerates a failing dataset lookup", async () => {
223
+ mockProviderDatabase.mockImplementation(function () {
224
+ return mockDb({
225
+ getMostRecentDatasetId: vi
226
+ .fn()
227
+ .mockRejectedValue(new Error("mongo down")),
228
+ });
229
+ });
230
+ const env = buildEnv();
231
+ await env.isReady();
232
+ expect(env.ready).toBe(true);
233
+ expect(env.logger.warn).toHaveBeenCalled();
234
+ });
235
+ it("reconnects an existing but disconnected database", async () => {
236
+ const connect = vi.fn().mockResolvedValue(undefined);
237
+ const env = buildEnv();
238
+ env.db = mockDb({
239
+ connect,
240
+ connected: false,
241
+ connection: { readyState: 0 },
242
+ });
243
+ await env.isReady();
244
+ expect(connect).toHaveBeenCalledTimes(1);
245
+ expect(mockProviderDatabase).not.toHaveBeenCalled();
246
+ expect(env.ready).toBe(true);
247
+ });
248
+ it("leaves an already connected database alone", async () => {
249
+ const connect = vi.fn().mockResolvedValue(undefined);
250
+ const env = buildEnv();
251
+ env.db = mockDb({ connect });
252
+ await env.isReady();
253
+ expect(connect).not.toHaveBeenCalled();
254
+ });
255
+ it("skips the dataset lookup once a dataset id is known", async () => {
256
+ const getMostRecentDatasetId = vi
257
+ .fn()
258
+ .mockResolvedValue("0xother");
259
+ const env = buildEnv();
260
+ env.db = mockDb({ getMostRecentDatasetId });
261
+ env.datasetId = "0xalready";
262
+ await env.isReady();
263
+ expect(getMostRecentDatasetId).not.toHaveBeenCalled();
264
+ expect(env.datasetId).toBe("0xalready");
265
+ });
266
+ it("wraps an ip info initialisation failure", async () => {
267
+ mockProviderDatabase.mockImplementation(function () {
268
+ return mockDb();
269
+ });
270
+ mockIpInfoInit.mockRejectedValue(new Error("maxmind missing"));
271
+ await expect(buildEnv().isReady()).rejects.toMatchObject({
272
+ translationKey: "GENERAL.ENVIRONMENT_NOT_READY",
273
+ });
274
+ });
275
+ it("does not build a database when none is configured", async () => {
276
+ const env = buildEnv(buildConfig({ database: undefined }));
277
+ await env.isReady();
278
+ expect(env.ready).toBe(true);
279
+ expect(env.db).toBeUndefined();
280
+ });
281
+ });
282
+ describe("Environment.connectDatabaseInBackground", () => {
283
+ it("does nothing when no database is configured", () => {
284
+ const env = buildEnv(buildConfig({ database: undefined }));
285
+ env.connectDatabaseInBackground();
286
+ expect(env.db).toBeUndefined();
287
+ });
288
+ it("warns rather than throwing when the handle cannot be built", () => {
289
+ mockProviderDatabase.mockImplementation(function () {
290
+ throw new Error("bad config");
291
+ });
292
+ const env = buildEnv();
293
+ expect(() => env.connectDatabaseInBackground()).not.toThrow();
294
+ expect(env.logger.warn).toHaveBeenCalled();
295
+ expect(env.db).toBeUndefined();
296
+ });
297
+ });
298
+ //# sourceMappingURL=env.accessors.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.accessors.unit.test.js","sourceRoot":"","sources":["../../src/tests/env.accessors.unit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider.unit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/provider.unit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,140 @@
1
+ import { ScheduledTaskStatus } from "@prosopo/types";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ const { mockProviderDatabase, mockIpInfoInit, mockClearAllSessionRecords, mockRedisWriteQueue, } = vi.hoisted(() => ({
4
+ mockProviderDatabase: vi.fn(),
5
+ mockIpInfoInit: vi.fn().mockResolvedValue(undefined),
6
+ mockClearAllSessionRecords: vi.fn(),
7
+ mockRedisWriteQueue: vi.fn(),
8
+ }));
9
+ vi.mock("@prosopo/database", () => ({
10
+ ProviderDatabase: mockProviderDatabase,
11
+ RedisWriteQueue: mockRedisWriteQueue,
12
+ }));
13
+ vi.mock("@prosopo/ipinfo", () => ({
14
+ IpInfoService: vi.fn().mockImplementation(function () {
15
+ return { initialize: mockIpInfoInit };
16
+ }),
17
+ }));
18
+ vi.mock("@prosopo/keyring", () => ({
19
+ Keyring: vi.fn().mockImplementation(function () {
20
+ return { addPair: vi.fn((pair) => pair) };
21
+ }),
22
+ getPair: vi.fn(() => ({ address: "addr", isLocked: false, unlock: vi.fn() })),
23
+ }));
24
+ import { ProviderEnvironment } from "../provider.js";
25
+ const buildConfig = () => ({
26
+ defaultEnvironment: "test",
27
+ logLevel: "info",
28
+ account: { secret: "//Alice", password: undefined },
29
+ database: {
30
+ test: {
31
+ endpoint: "mongodb://127.0.0.1:27017",
32
+ dbname: "test",
33
+ authSource: "admin",
34
+ type: "mongo",
35
+ },
36
+ },
37
+ redisConnection: { url: "redis://localhost", password: "" },
38
+ maxmindDbPath: undefined,
39
+ ipApi: undefined,
40
+ });
41
+ const mockDb = (overrides = {}) => ({
42
+ connected: true,
43
+ cleanupScheduledTaskStatus: vi
44
+ .fn()
45
+ .mockResolvedValue(undefined),
46
+ getRedisConnection: vi.fn(() => ({ redis: true })),
47
+ ...overrides,
48
+ });
49
+ const buildEnv = (db) => {
50
+ const env = new ProviderEnvironment(buildConfig(), {
51
+ address: "addr",
52
+ isLocked: false,
53
+ unlock: vi.fn(),
54
+ });
55
+ env.logger = {
56
+ debug: vi.fn(),
57
+ info: vi.fn(),
58
+ warn: vi.fn(),
59
+ error: vi.fn(),
60
+ };
61
+ if (db) {
62
+ env.db = db;
63
+ }
64
+ return env;
65
+ };
66
+ beforeEach(() => {
67
+ mockClearAllSessionRecords.mockReset();
68
+ mockClearAllSessionRecords.mockResolvedValue(undefined);
69
+ mockRedisWriteQueue.mockReset();
70
+ mockRedisWriteQueue.mockImplementation(function () {
71
+ return { clearAllSessionRecords: mockClearAllSessionRecords };
72
+ });
73
+ delete process.env.MAINTENANCE_MODE;
74
+ });
75
+ afterEach(() => {
76
+ delete process.env.MAINTENANCE_MODE;
77
+ });
78
+ describe("ProviderEnvironment.cleanup", () => {
79
+ it("skips both cleanups when there is no database", () => {
80
+ const env = buildEnv();
81
+ env.cleanup();
82
+ expect(mockRedisWriteQueue).not.toHaveBeenCalled();
83
+ expect(env.logger.warn).toHaveBeenCalled();
84
+ });
85
+ it("skips both cleanups when the database is not connected", () => {
86
+ const db = mockDb({ connected: false });
87
+ const env = buildEnv(db);
88
+ env.cleanup();
89
+ expect(db.cleanupScheduledTaskStatus).not.toHaveBeenCalled();
90
+ expect(mockRedisWriteQueue).not.toHaveBeenCalled();
91
+ });
92
+ it("skips both cleanups in maintenance mode even with a connected database", () => {
93
+ process.env.MAINTENANCE_MODE = "true";
94
+ const db = mockDb();
95
+ const env = buildEnv(db);
96
+ env.cleanup();
97
+ expect(db.cleanupScheduledTaskStatus).not.toHaveBeenCalled();
98
+ expect(mockRedisWriteQueue).not.toHaveBeenCalled();
99
+ });
100
+ it("resets running scheduled tasks and clears redis sessions", () => {
101
+ const db = mockDb();
102
+ const env = buildEnv(db);
103
+ env.cleanup();
104
+ expect(db.cleanupScheduledTaskStatus).toHaveBeenCalledWith(ScheduledTaskStatus.Running);
105
+ expect(db.getRedisConnection).toHaveBeenCalled();
106
+ expect(mockClearAllSessionRecords).toHaveBeenCalledTimes(1);
107
+ });
108
+ it("logs rather than rejecting when the scheduled task cleanup fails", async () => {
109
+ const db = mockDb({
110
+ cleanupScheduledTaskStatus: vi
111
+ .fn()
112
+ .mockRejectedValue(new Error("mongo down")),
113
+ });
114
+ const env = buildEnv(db);
115
+ env.cleanup();
116
+ await Promise.resolve();
117
+ await Promise.resolve();
118
+ expect(env.logger.error).toHaveBeenCalled();
119
+ });
120
+ it("logs rather than rejecting when the redis session wipe fails", async () => {
121
+ mockClearAllSessionRecords.mockRejectedValue(new Error("redis down"));
122
+ const env = buildEnv(mockDb());
123
+ env.cleanup();
124
+ await Promise.resolve();
125
+ await Promise.resolve();
126
+ expect(env.logger.error).toHaveBeenCalled();
127
+ });
128
+ it("warns and continues when there is no redis connection", () => {
129
+ const db = mockDb({
130
+ getRedisConnection: vi.fn(() => {
131
+ throw new Error("no redis");
132
+ }),
133
+ });
134
+ const env = buildEnv(db);
135
+ expect(() => env.cleanup()).not.toThrow();
136
+ expect(db.cleanupScheduledTaskStatus).toHaveBeenCalled();
137
+ expect(env.logger.warn).toHaveBeenCalled();
138
+ });
139
+ });
140
+ //# sourceMappingURL=provider.unit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.unit.test.js","sourceRoot":"","sources":["../../src/tests/provider.unit.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prosopo/env",
3
- "version": "3.6.22",
3
+ "version": "3.6.24",
4
4
  "description": "Path env prosopo environment",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,17 +26,17 @@
26
26
  "typecheck": "tsc --project tsconfig.types.json"
27
27
  },
28
28
  "dependencies": {
29
- "@prosopo/ipinfo": "0.3.0",
30
- "@prosopo/common": "3.1.48",
31
- "@prosopo/logger": "2.0.4",
32
- "@prosopo/database": "3.15.21",
33
- "@prosopo/keyring": "2.9.62",
34
- "@prosopo/types": "4.10.0",
35
- "@prosopo/types-env": "2.10.19",
29
+ "@prosopo/ipinfo": "0.3.2",
30
+ "@prosopo/common": "3.1.49",
31
+ "@prosopo/logger": "2.0.5",
32
+ "@prosopo/database": "4.0.1",
33
+ "@prosopo/keyring": "2.9.64",
34
+ "@prosopo/types": "5.0.1",
35
+ "@prosopo/types-env": "2.10.21",
36
36
  "@prosopo/util-crypto": "13.5.30"
37
37
  },
38
38
  "devDependencies": {
39
- "@prosopo/config": "3.3.5",
39
+ "@prosopo/config": "3.3.7",
40
40
  "@types/node": "22.10.2",
41
41
  "@vitest/coverage-v8": "4.1.10",
42
42
  "concurrently": "9.0.1",