sockethub 4.0.1 → 5.0.0-alpha.1

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.
Files changed (139) hide show
  1. package/README.md +3 -3
  2. package/bin/sockethub +23 -19
  3. package/dist/bootstrap/init.js +14 -4
  4. package/dist/bootstrap/init.js.map +1 -1
  5. package/dist/bootstrap/platforms.js +81 -69
  6. package/dist/common.js +10 -12
  7. package/dist/common.js.map +1 -1
  8. package/dist/config.js +4 -22
  9. package/dist/config.js.map +1 -1
  10. package/dist/crypto.js +7 -8
  11. package/dist/crypto.js.map +1 -1
  12. package/dist/janitor.js +14 -9
  13. package/dist/janitor.js.map +1 -1
  14. package/dist/middleware/create-activity-object.js +19 -0
  15. package/dist/middleware/create-activity-object.js.map +1 -0
  16. package/dist/middleware/expand-activity-stream.js +33 -0
  17. package/dist/middleware/expand-activity-stream.js.map +1 -0
  18. package/dist/middleware/expand-activity-stream.test.data.js +360 -0
  19. package/dist/middleware/expand-activity-stream.test.data.js.map +1 -0
  20. package/dist/middleware/store-credentials.js +19 -0
  21. package/dist/middleware/store-credentials.js.map +1 -0
  22. package/dist/middleware/validate.js +77 -0
  23. package/dist/middleware/validate.js.map +1 -0
  24. package/dist/middleware/validate.test.data.js +321 -0
  25. package/dist/middleware/validate.test.data.js.map +1 -0
  26. package/dist/middleware.js +47 -49
  27. package/dist/middleware.js.map +1 -1
  28. package/dist/platform-instance.js +84 -66
  29. package/dist/platform-instance.js.map +1 -1
  30. package/dist/platform.js +50 -25
  31. package/dist/platform.js.map +1 -1
  32. package/dist/process-manager.js +7 -4
  33. package/dist/process-manager.js.map +1 -1
  34. package/dist/routes.js +8 -6
  35. package/dist/routes.js.map +1 -1
  36. package/dist/serve.js +3 -3
  37. package/dist/serve.js.map +1 -1
  38. package/dist/sockethub-client.js +2604 -0
  39. package/dist/sockethub-client.js.map +1 -0
  40. package/dist/sockethub-client.min.js +2 -0
  41. package/dist/sockethub-client.min.js.LICENSE.txt +24 -0
  42. package/dist/sockethub.js +75 -58
  43. package/dist/sockethub.js.map +1 -1
  44. package/dist/store.js +17 -0
  45. package/dist/store.js.map +1 -0
  46. package/package.json +48 -44
  47. package/src/bootstrap/init.ts +16 -2
  48. package/src/bootstrap/platforms.js +14 -18
  49. package/src/common.test.ts +44 -33
  50. package/src/common.ts +9 -17
  51. package/src/config.test.ts +16 -38
  52. package/src/config.ts +1 -23
  53. package/src/crypto.test.ts +15 -17
  54. package/src/crypto.ts +4 -5
  55. package/src/janitor.ts +19 -12
  56. package/src/middleware/create-activity-object.test.ts +10 -0
  57. package/src/middleware/create-activity-object.ts +13 -0
  58. package/src/middleware/expand-activity-stream.test.data.ts +365 -0
  59. package/src/middleware/expand-activity-stream.test.ts +78 -0
  60. package/src/middleware/expand-activity-stream.ts +27 -0
  61. package/src/middleware/store-credentials.test.ts +72 -0
  62. package/src/middleware/store-credentials.ts +16 -0
  63. package/src/{validate.d.ts → middleware/validate.d.ts} +0 -0
  64. package/src/middleware/validate.test.data.ts +320 -0
  65. package/src/middleware/validate.test.ts +47 -0
  66. package/src/middleware/validate.ts +49 -0
  67. package/src/middleware.test.ts +148 -0
  68. package/src/middleware.ts +46 -51
  69. package/src/platform-instance.test.ts +224 -196
  70. package/src/platform-instance.ts +74 -58
  71. package/src/platform.ts +44 -24
  72. package/src/process-manager.ts +7 -4
  73. package/src/routes.test.ts +32 -19
  74. package/src/routes.ts +7 -5
  75. package/src/serve.ts +1 -1
  76. package/src/sockethub-client.test.ts +235 -0
  77. package/src/sockethub-client.ts +164 -0
  78. package/src/sockethub.ts +96 -93
  79. package/src/store.test.ts +26 -0
  80. package/src/store.ts +17 -0
  81. package/tsconfig.json +8 -8
  82. package/views/examples/dummy.ejs +7 -7
  83. package/views/examples/feeds.ejs +10 -10
  84. package/views/examples/irc.ejs +65 -59
  85. package/views/examples/shared.js +31 -29
  86. package/views/examples/xmpp.ejs +49 -58
  87. package/webpack.minified.config.js +14 -0
  88. package/webpack.normal.config.js +14 -0
  89. package/coverage/clover.xml +0 -190
  90. package/coverage/coverage-final.json +0 -6
  91. package/coverage/lcov-report/base.css +0 -224
  92. package/coverage/lcov-report/block-navigation.js +0 -79
  93. package/coverage/lcov-report/common.ts.html +0 -143
  94. package/coverage/lcov-report/config.ts.html +0 -359
  95. package/coverage/lcov-report/crypto.ts.html +0 -203
  96. package/coverage/lcov-report/favicon.png +0 -0
  97. package/coverage/lcov-report/index.html +0 -171
  98. package/coverage/lcov-report/platform-instance.ts.html +0 -740
  99. package/coverage/lcov-report/prettify.css +0 -1
  100. package/coverage/lcov-report/prettify.js +0 -2
  101. package/coverage/lcov-report/routes.ts.html +0 -353
  102. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  103. package/coverage/lcov-report/sorter.js +0 -170
  104. package/coverage/lcov-report/src/common.ts.html +0 -143
  105. package/coverage/lcov-report/src/config.ts.html +0 -359
  106. package/coverage/lcov-report/src/crypto.ts.html +0 -182
  107. package/coverage/lcov-report/src/index.html +0 -156
  108. package/coverage/lcov-report/src/platform-instance.ts.html +0 -740
  109. package/coverage/lcov-report/src/routes/base.ts.html +0 -359
  110. package/coverage/lcov-report/src/routes/examples.ts.html +0 -311
  111. package/coverage/lcov-report/src/routes/index.html +0 -111
  112. package/coverage/lcov-report/src/services/http.ts.html +0 -239
  113. package/coverage/lcov-report/src/services/index.html +0 -111
  114. package/coverage/lcov-report/src/services/redis.ts.html +0 -140
  115. package/coverage/lcov-report/src/shared-resources.ts.html +0 -104
  116. package/coverage/lcov.info +0 -336
  117. package/coverage/tmp/coverage-21649-1621596477257-0.json +0 -1
  118. package/dist/bootstrap/platforms.js.map +0 -1
  119. package/dist/js/client.js +0 -177
  120. package/dist/js/client.js.map +0 -1
  121. package/dist/resource-manager.js +0 -66
  122. package/dist/resource-manager.js.map +0 -1
  123. package/dist/routes/base.js +0 -92
  124. package/dist/routes/base.js.map +0 -1
  125. package/dist/routes/examples.js +0 -93
  126. package/dist/routes/examples.js.map +0 -1
  127. package/dist/services/http.js +0 -67
  128. package/dist/services/http.js.map +0 -1
  129. package/dist/services/redis.js +0 -23
  130. package/dist/services/redis.js.map +0 -1
  131. package/dist/shared-resources.js +0 -11
  132. package/dist/shared-resources.js.map +0 -1
  133. package/dist/validate.js +0 -157
  134. package/dist/validate.js.map +0 -1
  135. package/jest.config.js +0 -18
  136. package/src/js/client.js +0 -190
  137. package/src/validate.ts +0 -147
  138. package/test/middleware-suite.js +0 -101
  139. package/test/validate-suite.js +0 -338
@@ -1,209 +1,237 @@
1
+ import proxyquire from 'proxyquire';
2
+ import { expect } from 'chai';
3
+ import * as sinon from 'sinon';
1
4
 
2
- import { fork } from 'child_process';
3
- import Queue from 'bull';
4
-
5
- import PlatformInstance, { platformInstances, PlatformInstanceParams } from "./platform-instance";
6
- import { getSocket } from "./serve";
7
-
8
- jest.mock('./crypto');
9
- jest.mock('child_process');
10
- jest.mock('ioredis');
11
- jest.mock('bull');
12
- jest.mock('socket.io');
13
- jest.mock('./serve');
14
-
15
- const socketMock = {
16
- emit: jest.fn()
17
- };
18
-
19
- jest.mock('./serve', () => ({
20
- __esModule: true,
21
- default: {
22
- io: {
23
- in: jest.fn().mockImplementation(() => {
24
- return {
25
- fetchSockets: jest.fn().mockImplementation(() => {
26
- return [ socketMock ]
27
- })
28
- }
29
- })
30
- }
31
- },
32
- getSocket: jest.fn().mockReturnValue(Promise.resolve({
33
- emit: jest.fn()
34
- }))
35
- }));
5
+ proxyquire.noPreserveCache();
6
+ proxyquire.noCallThru();
36
7
 
37
8
  const FORK_PATH = __dirname + '/platform.js';
38
9
 
39
- describe("platformInstances", () => {
40
- it('should have a platformInstances Map', () => {
41
- expect(platformInstances instanceof Map).toBe(true);
42
- });
43
- });
44
-
45
10
  describe("PlatformInstance", () => {
46
- let pi;
47
- let handlers = {
48
- 'callbackFunction': undefined
49
- };
11
+ let pi, sandbox, forkFake, socketMock, getSocketFake, PlatformInstance, platformInstances;
50
12
 
51
13
  beforeEach(() => {
52
- for (let handler of Object.keys(handlers)) {
53
- handlers[handler] = jest.spyOn(
54
- PlatformInstance.prototype as any, handler);
55
- }
56
-
57
- const params: PlatformInstanceParams = {
58
- identifier: 'platform identifier',
59
- platform: 'a platform name',
60
- parentId: 'the parentId'
61
- };
62
-
63
- pi = new PlatformInstance(params);
64
- platformInstances.set(pi.id, pi);
65
-
66
- pi.process = {
67
- on: jest.fn().mockName('pi.process.on'),
68
- removeListener: jest.fn().mockName('pi.process.removeListener'),
69
- removeAllListeners: jest.fn().mockName('pi.process.removeAllListeners'),
70
- unref: jest.fn().mockName('pi.process.unref'),
71
- kill: jest.fn().mockName('pi.process.kill'),
14
+ sandbox = sinon.createSandbox();
15
+ forkFake = sandbox.fake();
16
+ socketMock = {
17
+ emit: sandbox.spy()
72
18
  };
19
+ getSocketFake = sinon.fake.resolves(socketMock);
20
+
21
+ const PlatformInstanceMod = proxyquire('./platform-instance', {
22
+ 'bull': sandbox.stub().returns({
23
+ on: sandbox.stub()
24
+ }),
25
+ './store': {
26
+ redisConfig: {
27
+ createClient: () => {}
28
+ }
29
+ },
30
+ 'child_process': {
31
+ fork: forkFake,
32
+ ChildProcess: sandbox.stub()
33
+ },
34
+ './serve': {
35
+ 'io': {
36
+ 'in': sandbox.stub().returns({
37
+ fetchSockets: () => {
38
+ return [socketMock];
39
+ }
40
+ })
41
+ },
42
+ getSocket: getSocketFake
43
+ }
44
+ });
45
+ PlatformInstance = PlatformInstanceMod.default;
46
+ platformInstances = PlatformInstanceMod.platformInstances;
73
47
  });
74
48
 
75
49
  afterEach(() => {
76
- pi.destroy();
77
- });
78
-
79
- it("has certain accessible properties", () => {
80
- expect(pi.id).toBe('platform identifier');
81
- expect(pi.name).toBe('a platform name');
82
- expect(pi.parentId).toBe('the parentId');
83
- expect(pi.flaggedForTermination).toBe(false);
84
- expect(pi.global).toBe(true);
85
- expect(fork).toBeCalledWith(FORK_PATH, [
86
- 'the parentId', 'a platform name', 'platform identifier'
87
- ]);
88
- });
89
-
90
- it('adds a close and message handler when a session is registered', () => {
91
- pi.registerSession('my session id');
92
- expect(handlers.callbackFunction).nthCalledWith(1, 'close', 'my session id');
93
- expect(handlers.callbackFunction).nthCalledWith(2, 'message', 'my session id');
94
- expect(pi.sessions.has('my session id')).toBe(true);
95
- });
96
-
97
- it('is able to generate failure reports', () => {
98
- pi.registerSession('my session id');
99
- expect(pi.sessions.has('my session id')).toBe(true);
100
- pi.reportError('my session id', 'an error message');
101
- pi.sendToClient = jest.fn();
102
- pi.destroy = jest.fn();
103
- expect(pi.sessions.size).toBe(0);
104
- });
105
-
106
- it('initializes the job queue', () => {
107
- pi.initQueue('a secret');
108
- expect(pi.queue).toBeInstanceOf(Queue);
109
- });
110
-
111
- it("cleans up its references when destroyed", () => {
112
- expect(platformInstances.has('platform identifier')).toBeTruthy();
113
- pi.destroy();
114
- expect(platformInstances.has('platform identifier')).toBeFalsy();
115
- });
116
-
117
- it("updates its identifier when changed", () => {
118
- pi.updateIdentifier('foo bar');
119
- expect(pi.id).toBe('foo bar');
120
- expect(platformInstances.has('platform identifier')).toBeFalsy();
121
- expect(platformInstances.has('foo bar')).toBeTruthy();
122
- });
123
-
124
- it('sends messages to client using socket session id', () => {
125
- pi.sendToClient('my session id', 'message', {foo: 'this is a message object',
126
- sessionSecret: 'private data'});
127
- expect(getSocket).toBeCalledWith('my session id');
128
- });
129
-
130
- it('broadcasts to peers', () => {
131
- pi.sessions.add('other peer');
132
- pi.broadcastToSharedPeers('myself', {foo: 'bar'});
133
- expect(getSocket).toBeCalledWith('other peer');
134
- });
135
-
136
- it('broadcasts to peers when handling a completed job', () => {
137
- pi.sessions.add('other peer');
138
- pi.handleJobResult('completed', {data: {msg: {foo: 'bar'}}, remove: function () {}},
139
- undefined);
140
- expect(getSocket).toBeCalledWith('other peer');
141
- });
142
-
143
- it('appends completed result message when present', () => {
144
- pi.sendToClient = jest.fn();
145
- pi.broadcastToSharedPeers = jest.fn();
146
- pi.handleJobResult('completed', {data: {msg: {foo: 'bar'}}, remove: function () {}},
147
- 'a good result message');
148
- expect(pi.broadcastToSharedPeers).toHaveBeenCalled();
149
- expect(pi.sendToClient).toHaveBeenCalledWith(undefined, 'completed',
150
- {foo: 'bar', object: {'@type': 'result', content: 'a good result message'}});
151
- });
152
-
153
- it('appends failed result message when present', () => {
154
- pi.sendToClient = jest.fn();
155
- pi.broadcastToSharedPeers = jest.fn();
156
- pi.handleJobResult('failed', {data: {msg: {foo: 'bar'}}, remove: function () {}},
157
- 'a bad result message');
158
- expect(pi.broadcastToSharedPeers).toHaveBeenCalled();
159
- expect(pi.sendToClient).toHaveBeenCalledWith(undefined, 'failed',
160
- {foo: 'bar', object: {'@type': 'error', content: 'a bad result message'}});
161
- });
162
-
163
- it('close events from platform thread are reported', () => {
164
- pi.reportError = jest.fn();
165
- const close = pi.callbackFunction('close', 'my session id');
166
- close('error msg');
167
- expect(pi.reportError).toHaveBeenCalledWith(
168
- 'my session id', 'Error: session thread closed unexpectedly: error msg');
169
- });
170
-
171
- it('message events from platform thread are route based on command: error', () => {
172
- pi.reportError = jest.fn();
173
- const message = pi.callbackFunction('message', 'my session id');
174
- message(['error', 'error message']);
175
- expect(pi.reportError).toHaveBeenCalledWith(
176
- 'my session id', 'error message');
177
- });
178
-
179
- it('message events from platform thread are route based on command: updateActor', () => {
180
- pi.updateIdentifier = jest.fn();
181
- const message = pi.callbackFunction('message', 'my session id');
182
- message(['updateActor', undefined, {foo: 'bar'}]);
183
- expect(pi.updateIdentifier).toHaveBeenCalledWith({foo:'bar'});
184
- });
185
-
186
- it('message events from platform thread are route based on command: else', () => {
187
- pi.sendToClient = jest.fn();
188
- const message = pi.callbackFunction('message', 'my session id');
189
- message(['blah', {foo: 'bar'}]);
190
- expect(pi.sendToClient).toHaveBeenCalledWith(
191
- 'my session id', 'message', {foo:'bar'});
192
- });
193
- });
194
-
195
-
196
- describe('private instance per-actor', () => {
197
- it("is set as non-global when an actor is provided", () => {
198
- const params: PlatformInstanceParams = {
199
- identifier: 'id',
200
- platform: 'name',
201
- parentId: 'parentId',
202
- actor: 'actor string'
203
- };
204
- const pi = new PlatformInstance(params);
205
- expect(pi.global).toBe(false);
206
- expect(fork).toBeCalledWith(FORK_PATH, ['parentId', 'name', 'id']);
207
- pi.destroy();
50
+ sinon.restore();
51
+ });
52
+
53
+ describe('private instance per-actor', () => {
54
+ it("is set as non-global when an actor is provided", () => {
55
+ const pi = new PlatformInstance({
56
+ identifier: 'id',
57
+ platform: 'name',
58
+ parentId: 'parentId',
59
+ actor: 'actor string'
60
+ });
61
+ expect(pi.global).to.be.equal(false);
62
+ sandbox.assert.calledWith(forkFake, FORK_PATH, ['parentId', 'name', 'id']);
63
+ pi.destroy();
64
+ });
65
+ });
66
+
67
+ describe('PlatformInstance objects', () => {
68
+ beforeEach(() => {
69
+ pi = new PlatformInstance({
70
+ identifier: 'platform identifier',
71
+ platform: 'a platform name',
72
+ parentId: 'the parentId'
73
+ });
74
+ platformInstances.set(pi.id, pi);
75
+
76
+ pi.process = {
77
+ on: sandbox.spy(),
78
+ removeListener: sandbox.spy(),
79
+ removeAllListeners: sandbox.spy(),
80
+ unref: sandbox.spy(),
81
+ kill: sandbox.spy(),
82
+ };
83
+ });
84
+
85
+ afterEach(() => {
86
+ pi.destroy();
87
+ });
88
+
89
+ it('has expected properties', () => {
90
+ expect(typeof PlatformInstance).to.be.equal('function');
91
+ });
92
+
93
+ it('should have a platformInstances Map', () => {
94
+ expect(platformInstances instanceof Map).to.be.equal(true);
95
+ });
96
+
97
+ it("has certain accessible properties", () => {
98
+ expect(pi.id).to.be.equal('platform identifier');
99
+ expect(pi.name).to.be.equal('a platform name');
100
+ expect(pi.parentId).to.be.equal('the parentId');
101
+ expect(pi.flaggedForTermination).to.be.equal(false);
102
+ expect(pi.global).to.be.equal(true);
103
+ expect(forkFake.calledWith(FORK_PATH, [
104
+ 'the parentId', 'a platform name', 'platform identifier'
105
+ ])).to.be.ok;
106
+ });
107
+
108
+ describe('registerSession', () => {
109
+ beforeEach(() => {
110
+ pi.callbackFunction = sandbox.fake();
111
+ });
112
+
113
+ it('adds a close and message handler when a session is registered', () => {
114
+ pi.registerSession('my session id');
115
+ expect(pi.callbackFunction.callCount).to.equal(2);
116
+ sandbox.assert.calledWith(pi.callbackFunction, 'close', 'my session id');
117
+ sandbox.assert.calledWith(pi.callbackFunction, 'message', 'my session id');
118
+ expect(pi.sessions.has('my session id')).to.be.equal(true);
119
+ });
120
+
121
+ it('is able to generate failure reports', () => {
122
+ pi.registerSession('my session id');
123
+ expect(pi.sessions.has('my session id')).to.be.equal(true);
124
+ pi.reportError('my session id', 'an error message');
125
+ pi.sendToClient = sandbox.stub();
126
+ pi.destroy = sandbox.stub();
127
+ expect(pi.sessions.size).to.be.equal(0);
128
+ });
129
+ });
130
+
131
+ it('initializes the job queue', () => {
132
+ expect(pi.queue).to.be.undefined;
133
+ pi.initQueue('a secret');
134
+ expect(pi.queue).to.be.ok;
135
+ });
136
+
137
+ it("cleans up its references when destroyed", async () => {
138
+ pi.initQueue('a secret');
139
+ expect(pi.queue).to.be.ok;
140
+ expect(platformInstances.has('platform identifier')).to.be.true;
141
+ await pi.destroy();
142
+ expect(pi.queue).not.to.be.ok;
143
+ expect(platformInstances.has('platform identifier')).to.be.false;
144
+ });
145
+
146
+ it("updates its identifier when changed", () => {
147
+ pi.updateIdentifier('foo bar');
148
+ expect(pi.id).to.be.equal('foo bar');
149
+ expect(platformInstances.has('platform identifier')).to.be.false;
150
+ expect(platformInstances.has('foo bar')).to.be.true;
151
+ });
152
+
153
+ it('sends messages to client using socket session id', async () => {
154
+ await pi.sendToClient('my session id',
155
+ {foo: 'this is a message object', sessionSecret: 'private data'});
156
+ expect(getSocketFake.callCount).to.equal(1);
157
+ sandbox.assert.calledOnce(getSocketFake);
158
+ sandbox.assert.calledWith(getSocketFake, 'my session id');
159
+ sandbox.assert.calledOnce(socketMock.emit);
160
+ sandbox.assert.calledWith(
161
+ socketMock.emit, 'message', {foo:'this is a message object', context: 'a platform name'});
162
+ });
163
+
164
+ it('broadcasts to peers', async () => {
165
+ pi.sessions.add('other peer');
166
+ pi.sessions.add('another peer');
167
+ await pi.broadcastToSharedPeers('myself', {foo: 'bar'});
168
+ expect(getSocketFake.callCount).to.equal(2);
169
+ sandbox.assert.calledWith(getSocketFake, 'other peer');
170
+ });
171
+
172
+ describe('handleJobResult', () => {
173
+ beforeEach(() => {
174
+ pi.sendToClient = sandbox.fake();
175
+ pi.broadcastToSharedPeers = sandbox.fake();
176
+ });
177
+
178
+ it('broadcasts to peers when handling a completed job', async () => {
179
+ pi.sessions.add('other peer');
180
+ await pi.handleJobResult('completed', {msg: {foo: 'bar'}},
181
+ undefined);
182
+ expect(pi.sendToClient.callCount).to.equal(1);
183
+ expect(pi.broadcastToSharedPeers.callCount).to.equal(1);
184
+ });
185
+
186
+ it('appends completed result message when present', async () => {
187
+ await pi.handleJobResult('completed', {sessionId: 'a session id', msg: {foo: 'bar'}},
188
+ 'a good result message');
189
+ expect(pi.broadcastToSharedPeers.callCount).to.equal(1);
190
+ sandbox.assert.calledWith(pi.sendToClient, 'a session id',
191
+ {foo: 'bar'});
192
+ });
193
+
194
+ it('appends failed result message when present', async () => {
195
+ await pi.handleJobResult('failed', {sessionId: 'a session id', msg: {foo: 'bar'}},
196
+ 'a bad result message');
197
+ expect(pi.broadcastToSharedPeers.callCount).to.equal(1);
198
+ sandbox.assert.calledWith(pi.sendToClient, 'a session id',
199
+ {foo: 'bar', error: 'a bad result message'});
200
+ });
201
+ });
202
+
203
+ describe('callbackFunction', () => {
204
+ beforeEach(() => {
205
+ pi.reportError = sandbox.fake();
206
+ pi.sendToClient = sandbox.fake();
207
+ pi.updateIdentifier = sandbox.fake();
208
+ });
209
+
210
+ it('close events from platform thread are reported', () => {
211
+ const close = pi.callbackFunction('close', 'my session id');
212
+ close('error msg');
213
+ sandbox.assert.calledWith(pi.reportError,
214
+ 'my session id', 'Error: session thread closed unexpectedly: error msg');
215
+ });
216
+
217
+ it('message events from platform thread are route based on command: error', () => {
218
+ const message = pi.callbackFunction('message', 'my session id');
219
+ message(['error', 'error message']);
220
+ sandbox.assert.calledWith(pi.reportError, 'my session id', 'error message');
221
+ });
222
+
223
+ it('message events from platform thread are route based on command: updateActor', () => {
224
+ const message = pi.callbackFunction('message', 'my session id');
225
+ message(['updateActor', undefined, {foo: 'bar'}]);
226
+ sandbox.assert.calledWith(pi.updateIdentifier, {foo:'bar'});
227
+ });
228
+
229
+ it('message events from platform thread are route based on command: else', () => {
230
+ const message = pi.callbackFunction('message', 'my session id');
231
+ message(['blah', {foo: 'bar'}]);
232
+ sandbox.assert.calledWith(pi.sendToClient,
233
+ 'my session id', {foo:'bar'});
234
+ });
235
+ });
208
236
  });
209
237
  });