@sockethub/server 5.0.0-alpha.3 → 5.0.0-alpha.6
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 +54 -60
- package/bin/sockethub +4 -3
- package/package.json +42 -60
- package/res/socket.io.js +4908 -0
- package/res/sockethub-client.js +602 -0
- package/res/sockethub-client.min.js +19 -0
- package/sockethub.config.example.json +2 -3
- package/src/bootstrap/init.d.ts +20 -7
- package/src/bootstrap/init.test.ts +211 -0
- package/src/bootstrap/init.ts +152 -75
- package/src/bootstrap/load-platforms.ts +151 -0
- package/src/config.test.ts +27 -22
- package/src/config.ts +82 -78
- package/src/defaults.json +24 -16
- package/src/index.ts +67 -27
- package/src/janitor.test.ts +211 -0
- package/src/janitor.ts +145 -77
- package/src/listener.ts +151 -57
- package/src/middleware/create-activity-object.test.ts +28 -8
- package/src/middleware/create-activity-object.ts +17 -8
- package/src/middleware/expand-activity-stream.test.data.ts +332 -346
- package/src/middleware/expand-activity-stream.test.ts +65 -66
- package/src/middleware/expand-activity-stream.ts +29 -19
- package/src/middleware/store-credentials.test.ts +74 -62
- package/src/middleware/store-credentials.ts +15 -15
- package/src/middleware/validate.test.data.ts +240 -242
- package/src/middleware/validate.test.ts +39 -78
- package/src/middleware/validate.ts +63 -39
- package/src/middleware.test.ts +168 -138
- package/src/middleware.ts +62 -43
- package/src/platform-instance.test.ts +507 -213
- package/src/platform-instance.ts +337 -219
- package/src/platform.test.ts +375 -0
- package/src/platform.ts +306 -139
- package/src/process-manager.ts +75 -51
- package/src/routes.test.ts +43 -89
- package/src/routes.ts +40 -77
- package/src/sentry.test.ts +106 -0
- package/src/sentry.ts +19 -0
- package/src/sockethub.ts +186 -153
- package/src/util.ts +5 -0
- package/coverage/tmp/coverage-93126-1649152190997-0.json +0 -1
- package/dist/bootstrap/init.d.ts +0 -18
- package/dist/bootstrap/init.js +0 -63
- package/dist/bootstrap/init.js.map +0 -1
- package/dist/bootstrap/platforms.js +0 -75
- package/dist/common.d.ts +0 -3
- package/dist/common.js +0 -20
- package/dist/common.js.map +0 -1
- package/dist/config.d.ts +0 -6
- package/dist/config.js +0 -102
- package/dist/config.js.map +0 -1
- package/dist/crypto.d.ts +0 -10
- package/dist/crypto.js +0 -38
- package/dist/crypto.js.map +0 -1
- package/dist/defaults.json +0 -28
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -25
- package/dist/index.js.map +0 -1
- package/dist/janitor.d.ts +0 -15
- package/dist/janitor.js +0 -89
- package/dist/janitor.js.map +0 -1
- package/dist/listener.d.ts +0 -28
- package/dist/listener.js +0 -91
- package/dist/listener.js.map +0 -1
- package/dist/middleware/create-activity-object.d.ts +0 -6
- package/dist/middleware/create-activity-object.js +0 -19
- package/dist/middleware/create-activity-object.js.map +0 -1
- package/dist/middleware/expand-activity-stream.d.ts +0 -2
- package/dist/middleware/expand-activity-stream.js +0 -33
- package/dist/middleware/expand-activity-stream.js.map +0 -1
- package/dist/middleware/expand-activity-stream.test.data.d.ts +0 -480
- package/dist/middleware/expand-activity-stream.test.data.js +0 -360
- package/dist/middleware/expand-activity-stream.test.data.js.map +0 -1
- package/dist/middleware/store-credentials.d.ts +0 -3
- package/dist/middleware/store-credentials.js +0 -19
- package/dist/middleware/store-credentials.js.map +0 -1
- package/dist/middleware/validate.d.ts +0 -2
- package/dist/middleware/validate.js +0 -58
- package/dist/middleware/validate.js.map +0 -1
- package/dist/middleware/validate.test.data.d.ts +0 -532
- package/dist/middleware/validate.test.data.js +0 -263
- package/dist/middleware/validate.test.data.js.map +0 -1
- package/dist/middleware.d.ts +0 -10
- package/dist/middleware.js +0 -54
- package/dist/middleware.js.map +0 -1
- package/dist/platform-instance.d.ts +0 -77
- package/dist/platform-instance.js +0 -211
- package/dist/platform-instance.js.map +0 -1
- package/dist/platform.d.ts +0 -6
- package/dist/platform.js +0 -187
- package/dist/platform.js.map +0 -1
- package/dist/process-manager.d.ts +0 -11
- package/dist/process-manager.js +0 -78
- package/dist/process-manager.js.map +0 -1
- package/dist/routes.d.ts +0 -13
- package/dist/routes.js +0 -83
- package/dist/routes.js.map +0 -1
- package/dist/sockethub.d.ts +0 -39
- package/dist/sockethub.js +0 -119
- package/dist/sockethub.js.map +0 -1
- package/dist/store.d.ts +0 -5
- package/dist/store.js +0 -17
- package/dist/store.js.map +0 -1
- package/src/bootstrap/platforms.js +0 -75
- package/src/common.test.ts +0 -54
- package/src/common.ts +0 -14
- package/src/config.d.ts +0 -2
- package/src/crypto.d.ts +0 -5
- package/src/crypto.test.ts +0 -41
- package/src/crypto.ts +0 -41
- package/src/janitor.d.ts +0 -8
- package/src/middleware/validate.d.ts +0 -1
- package/src/middleware.d.ts +0 -21
- package/src/sockethub.d.ts +0 -1
- package/src/store.test.ts +0 -28
- package/src/store.ts +0 -17
- package/test/init-suite.js +0 -41
- package/test/queue.functional.test.js +0 -0
- package/test/sockethub-suite.js +0 -25
- package/tsconfig.json +0 -18
- package/views/examples/dummy.ejs +0 -93
- package/views/examples/feeds.ejs +0 -90
- package/views/examples/irc.ejs +0 -239
- package/views/examples/shared.js +0 -72
- package/views/examples/xmpp.ejs +0 -191
- package/views/index.ejs +0 -17
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
|
2
|
+
import * as sinon from "sinon";
|
|
3
|
+
import { crypto } from "@sockethub/crypto";
|
|
4
|
+
import type {
|
|
5
|
+
ActivityStream,
|
|
6
|
+
CredentialsObject,
|
|
7
|
+
PlatformCallback,
|
|
8
|
+
PlatformInterface,
|
|
9
|
+
} from "@sockethub/schemas";
|
|
10
|
+
import type { JobDataDecrypted } from "@sockethub/data-layer";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Tests for platform.ts credential handling logic
|
|
14
|
+
*
|
|
15
|
+
* Since platform.ts runs as a separate process and uses process.argv,
|
|
16
|
+
* we test the core credential handling behavior by simulating the
|
|
17
|
+
* getJobHandler logic.
|
|
18
|
+
*/
|
|
19
|
+
describe("platform.ts credential handling", () => {
|
|
20
|
+
let sandbox: sinon.SinonSandbox;
|
|
21
|
+
let mockPlatform: Partial<PlatformInterface>;
|
|
22
|
+
let mockCredentialStore: any;
|
|
23
|
+
let mockJob: JobDataDecrypted;
|
|
24
|
+
let validCredentials: CredentialsObject;
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
sandbox = sinon.createSandbox();
|
|
28
|
+
|
|
29
|
+
validCredentials = {
|
|
30
|
+
type: "credentials",
|
|
31
|
+
context: "xmpp",
|
|
32
|
+
actor: {
|
|
33
|
+
id: "testuser@localhost",
|
|
34
|
+
type: "person",
|
|
35
|
+
name: "Test User",
|
|
36
|
+
},
|
|
37
|
+
object: {
|
|
38
|
+
type: "credentials",
|
|
39
|
+
userAddress: "testuser@localhost",
|
|
40
|
+
password: "testpassword",
|
|
41
|
+
server: "xmpp://localhost:5222",
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
mockPlatform = {
|
|
46
|
+
config: {
|
|
47
|
+
persist: true,
|
|
48
|
+
initialized: false,
|
|
49
|
+
requireCredentials: ["connect"],
|
|
50
|
+
},
|
|
51
|
+
credentialsHash: undefined,
|
|
52
|
+
connect: sandbox.stub(),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
mockCredentialStore = {
|
|
56
|
+
get: sandbox.stub().resolves(validCredentials),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
mockJob = {
|
|
60
|
+
sessionId: "test-session-123",
|
|
61
|
+
title: "xmpp-job-1",
|
|
62
|
+
msg: {
|
|
63
|
+
type: "connect",
|
|
64
|
+
context: "xmpp",
|
|
65
|
+
actor: { id: "testuser@localhost", type: "person" },
|
|
66
|
+
sessionSecret: "secret123",
|
|
67
|
+
},
|
|
68
|
+
} as JobDataDecrypted;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
afterEach(() => {
|
|
72
|
+
sandbox.restore();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe("credentialsHash updates after successful platform calls", () => {
|
|
76
|
+
it("should set credentialsHash after successful connect on first call", async () => {
|
|
77
|
+
// Initially no hash
|
|
78
|
+
expect(mockPlatform.credentialsHash).toBeUndefined();
|
|
79
|
+
|
|
80
|
+
// Simulate the platform.ts credential handling flow
|
|
81
|
+
const credentials = await mockCredentialStore.get(
|
|
82
|
+
mockJob.msg.actor.id,
|
|
83
|
+
mockPlatform.credentialsHash,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// Create the wrapper callback that platform.ts uses
|
|
87
|
+
let capturedErr: Error | null = null;
|
|
88
|
+
let capturedResult: ActivityStream | null = null;
|
|
89
|
+
const doneCallback: PlatformCallback = (err, result) => {
|
|
90
|
+
capturedErr = err;
|
|
91
|
+
capturedResult = result;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const wrappedCallback: PlatformCallback = (err, result) => {
|
|
95
|
+
if (!err) {
|
|
96
|
+
// This is what platform.ts does
|
|
97
|
+
mockPlatform.credentialsHash = crypto.objectHash(
|
|
98
|
+
credentials.object,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
doneCallback(err, result);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Simulate platform connect call succeeding
|
|
105
|
+
(mockPlatform.connect as sinon.SinonStub).callsFake(
|
|
106
|
+
(_msg, _creds, callback) => {
|
|
107
|
+
callback(null, { type: "success" });
|
|
108
|
+
},
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// Call platform method with wrapped callback
|
|
112
|
+
mockPlatform.connect(mockJob.msg, credentials, wrappedCallback);
|
|
113
|
+
|
|
114
|
+
// Verify credentialsHash was set
|
|
115
|
+
expect(mockPlatform.credentialsHash).toBeDefined();
|
|
116
|
+
expect(mockPlatform.credentialsHash).toBe(
|
|
117
|
+
crypto.objectHash(credentials.object),
|
|
118
|
+
);
|
|
119
|
+
expect(capturedErr).toBeNull();
|
|
120
|
+
expect(capturedResult).toEqual({ type: "success" });
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("should NOT update credentialsHash when platform call fails", async () => {
|
|
124
|
+
const initialHash = crypto.objectHash(validCredentials.object);
|
|
125
|
+
mockPlatform.credentialsHash = initialHash;
|
|
126
|
+
|
|
127
|
+
const credentials = await mockCredentialStore.get(
|
|
128
|
+
mockJob.msg.actor.id,
|
|
129
|
+
mockPlatform.credentialsHash,
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
let capturedErr: Error | null = null;
|
|
133
|
+
const doneCallback: PlatformCallback = (err, result) => {
|
|
134
|
+
capturedErr = err;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const wrappedCallback: PlatformCallback = (err, result) => {
|
|
138
|
+
if (!err) {
|
|
139
|
+
mockPlatform.credentialsHash = crypto.objectHash(
|
|
140
|
+
credentials.object,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
doneCallback(err, result);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Simulate platform connect call failing
|
|
147
|
+
(mockPlatform.connect as sinon.SinonStub).callsFake(
|
|
148
|
+
(_msg, _creds, callback) => {
|
|
149
|
+
callback(new Error("connection failed"), null);
|
|
150
|
+
},
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
mockPlatform.connect(mockJob.msg, credentials, wrappedCallback);
|
|
154
|
+
|
|
155
|
+
// Verify credentialsHash was NOT changed
|
|
156
|
+
expect(mockPlatform.credentialsHash).toBe(initialHash);
|
|
157
|
+
expect(capturedErr).toBeDefined();
|
|
158
|
+
expect(capturedErr?.message).toBe("connection failed");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("should update credentialsHash on subsequent successful calls", async () => {
|
|
162
|
+
// First call sets hash
|
|
163
|
+
const firstHash = crypto.objectHash(validCredentials.object);
|
|
164
|
+
mockPlatform.credentialsHash = firstHash;
|
|
165
|
+
|
|
166
|
+
// Second call with same credentials
|
|
167
|
+
const credentials = await mockCredentialStore.get(
|
|
168
|
+
mockJob.msg.actor.id,
|
|
169
|
+
mockPlatform.credentialsHash,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const wrappedCallback: PlatformCallback = (err, result) => {
|
|
173
|
+
if (!err) {
|
|
174
|
+
mockPlatform.credentialsHash = crypto.objectHash(
|
|
175
|
+
credentials.object,
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
(mockPlatform.connect as sinon.SinonStub).callsFake(
|
|
181
|
+
(_msg, _creds, callback) => {
|
|
182
|
+
callback(null, { type: "success" });
|
|
183
|
+
},
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
mockPlatform.connect(mockJob.msg, credentials, wrappedCallback);
|
|
187
|
+
|
|
188
|
+
// Hash should still be the same (same credentials)
|
|
189
|
+
expect(mockPlatform.credentialsHash).toBe(firstHash);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe("CredentialsStore.get() validation behavior", () => {
|
|
194
|
+
it("should pass credentialsHash to CredentialsStore.get() for validation", async () => {
|
|
195
|
+
const existingHash = crypto.objectHash(validCredentials.object);
|
|
196
|
+
mockPlatform.credentialsHash = existingHash;
|
|
197
|
+
|
|
198
|
+
await mockCredentialStore.get(
|
|
199
|
+
mockJob.msg.actor.id,
|
|
200
|
+
mockPlatform.credentialsHash,
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
sinon.assert.calledOnce(mockCredentialStore.get);
|
|
204
|
+
sinon.assert.calledWith(
|
|
205
|
+
mockCredentialStore.get,
|
|
206
|
+
mockJob.msg.actor.id,
|
|
207
|
+
existingHash,
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("should pass undefined when no credentialsHash exists", async () => {
|
|
212
|
+
mockPlatform.credentialsHash = undefined;
|
|
213
|
+
|
|
214
|
+
await mockCredentialStore.get(
|
|
215
|
+
mockJob.msg.actor.id,
|
|
216
|
+
mockPlatform.credentialsHash,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
sinon.assert.calledWith(
|
|
220
|
+
mockCredentialStore.get,
|
|
221
|
+
mockJob.msg.actor.id,
|
|
222
|
+
undefined,
|
|
223
|
+
);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("should handle CredentialsStore.get() rejection", async () => {
|
|
227
|
+
mockCredentialStore.get.rejects(
|
|
228
|
+
new Error("invalid credentials for testuser@localhost"),
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
await mockCredentialStore.get(
|
|
233
|
+
mockJob.msg.actor.id,
|
|
234
|
+
mockPlatform.credentialsHash,
|
|
235
|
+
);
|
|
236
|
+
expect.unreachable("Should have thrown");
|
|
237
|
+
} catch (err) {
|
|
238
|
+
expect(err.message).toContain("invalid credentials");
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
describe("Wrapper callback behavior", () => {
|
|
244
|
+
it("should call doneCallback after updating credentialsHash", async () => {
|
|
245
|
+
const credentials = await mockCredentialStore.get(
|
|
246
|
+
mockJob.msg.actor.id,
|
|
247
|
+
mockPlatform.credentialsHash,
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const doneCallbackSpy = sandbox.spy();
|
|
251
|
+
let hashSetBeforeDone = false;
|
|
252
|
+
|
|
253
|
+
const wrappedCallback: PlatformCallback = (err, result) => {
|
|
254
|
+
if (!err) {
|
|
255
|
+
mockPlatform.credentialsHash = crypto.objectHash(
|
|
256
|
+
credentials.object,
|
|
257
|
+
);
|
|
258
|
+
hashSetBeforeDone = mockPlatform.credentialsHash !==
|
|
259
|
+
undefined;
|
|
260
|
+
}
|
|
261
|
+
doneCallbackSpy(err, result);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
(mockPlatform.connect as sinon.SinonStub).callsFake(
|
|
265
|
+
(_msg, _creds, callback) => {
|
|
266
|
+
callback(null, { type: "success" });
|
|
267
|
+
},
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
mockPlatform.connect(mockJob.msg, credentials, wrappedCallback);
|
|
271
|
+
|
|
272
|
+
// Verify order: hash set, then done called
|
|
273
|
+
expect(hashSetBeforeDone).toBeTrue();
|
|
274
|
+
sinon.assert.calledOnce(doneCallbackSpy);
|
|
275
|
+
sinon.assert.calledWith(doneCallbackSpy, null, { type: "success" });
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("should pass through errors without updating hash", async () => {
|
|
279
|
+
const initialHash = crypto.objectHash(validCredentials.object);
|
|
280
|
+
mockPlatform.credentialsHash = initialHash;
|
|
281
|
+
|
|
282
|
+
const credentials = await mockCredentialStore.get(
|
|
283
|
+
mockJob.msg.actor.id,
|
|
284
|
+
mockPlatform.credentialsHash,
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
const doneCallbackSpy = sandbox.spy();
|
|
288
|
+
const testError = new Error("platform error");
|
|
289
|
+
|
|
290
|
+
const wrappedCallback: PlatformCallback = (err, result) => {
|
|
291
|
+
if (!err) {
|
|
292
|
+
mockPlatform.credentialsHash = crypto.objectHash(
|
|
293
|
+
credentials.object,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
doneCallbackSpy(err, result);
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
(mockPlatform.connect as sinon.SinonStub).callsFake(
|
|
300
|
+
(_msg, _creds, callback) => {
|
|
301
|
+
callback(testError, null);
|
|
302
|
+
},
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
mockPlatform.connect(mockJob.msg, credentials, wrappedCallback);
|
|
306
|
+
|
|
307
|
+
// Hash unchanged
|
|
308
|
+
expect(mockPlatform.credentialsHash).toBe(initialHash);
|
|
309
|
+
// Error passed through
|
|
310
|
+
sinon.assert.calledOnce(doneCallbackSpy);
|
|
311
|
+
sinon.assert.calledWith(doneCallbackSpy, testError, null);
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
describe("Integration scenarios", () => {
|
|
316
|
+
it("should handle complete flow: fetch credentials -> call platform -> update hash -> callback", async () => {
|
|
317
|
+
const flowLog: string[] = [];
|
|
318
|
+
|
|
319
|
+
// Step 1: Fetch credentials
|
|
320
|
+
flowLog.push("fetch-start");
|
|
321
|
+
const credentials = await mockCredentialStore.get(
|
|
322
|
+
mockJob.msg.actor.id,
|
|
323
|
+
mockPlatform.credentialsHash,
|
|
324
|
+
);
|
|
325
|
+
flowLog.push("fetch-success");
|
|
326
|
+
|
|
327
|
+
// Step 2: Create wrapped callback
|
|
328
|
+
const doneCallback: PlatformCallback = (err, result) => {
|
|
329
|
+
flowLog.push("done-callback");
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const wrappedCallback: PlatformCallback = (err, result) => {
|
|
333
|
+
flowLog.push("wrapped-callback-start");
|
|
334
|
+
if (!err) {
|
|
335
|
+
mockPlatform.credentialsHash = crypto.objectHash(
|
|
336
|
+
credentials.object,
|
|
337
|
+
);
|
|
338
|
+
flowLog.push("hash-updated");
|
|
339
|
+
}
|
|
340
|
+
doneCallback(err, result);
|
|
341
|
+
flowLog.push("wrapped-callback-end");
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// Step 3: Call platform method
|
|
345
|
+
(mockPlatform.connect as sinon.SinonStub).callsFake(
|
|
346
|
+
(_msg, _creds, callback) => {
|
|
347
|
+
flowLog.push("platform-method-executing");
|
|
348
|
+
callback(null, { type: "success" });
|
|
349
|
+
flowLog.push("platform-method-callback-done");
|
|
350
|
+
},
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
flowLog.push("call-platform-start");
|
|
354
|
+
mockPlatform.connect(mockJob.msg, credentials, wrappedCallback);
|
|
355
|
+
flowLog.push("call-platform-end");
|
|
356
|
+
|
|
357
|
+
// Verify flow order
|
|
358
|
+
expect(flowLog).toEqual([
|
|
359
|
+
"fetch-start",
|
|
360
|
+
"fetch-success",
|
|
361
|
+
"call-platform-start",
|
|
362
|
+
"platform-method-executing",
|
|
363
|
+
"wrapped-callback-start",
|
|
364
|
+
"hash-updated",
|
|
365
|
+
"done-callback",
|
|
366
|
+
"wrapped-callback-end",
|
|
367
|
+
"platform-method-callback-done",
|
|
368
|
+
"call-platform-end",
|
|
369
|
+
]);
|
|
370
|
+
|
|
371
|
+
// Verify final state
|
|
372
|
+
expect(mockPlatform.credentialsHash).toBeDefined();
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
});
|