diff --git a/misc/client-sdk-testsuite/src/public/index.html b/misc/client-sdk-testsuite/src/public/index.html
index 256a29f..1f39f5e 100644
--- a/misc/client-sdk-testsuite/src/public/index.html
+++ b/misc/client-sdk-testsuite/src/public/index.html
@@ -22,6 +22,9 @@
+
+
+
diff --git a/misc/client-sdk-testsuite/src/public/test/client-sdk.js b/misc/client-sdk-testsuite/src/public/test/client-sdk.js
index b8f8335..f1c1a90 100644
--- a/misc/client-sdk-testsuite/src/public/test/client-sdk.js
+++ b/misc/client-sdk-testsuite/src/public/test/client-sdk.js
@@ -21,128 +21,5 @@ describe('Edge', function() {
chai.assert.isNull(Edge._conn);
});
});
-
- describe('#send()', function() {
- this.timeout(5000);
-
- before(() => {
- return Edge.connect();
- });
-
- after(() => {
- Edge.disconnect();
- });
-
- it('should send a message to the server and echo back', function(done) {
- const now = new Date();
- const handler = evt => {
- chai.assert.equal(evt.detail.now, now.toJSON());
- Edge.removeEventListener('message', handler);
- done();
- }
-
- // Server should echo back message
- Edge.addEventListener('message', handler);
-
- // Send message to server
- Edge.send({ now });
- });
- });
});
-
-describe('Remote Procedure Call', function() {
-
- before(() => {
- return Edge.connect();
- });
-
- after(() => {
- Edge.disconnect();
- });
-
- it('should call the remote echo() method and resolve the returned value', function() {
- const foo = "bar";
-
- return Edge.rpc('echo', { foo })
- .then(result => {
- chai.assert.equal(result.foo, foo);
- });
- });
-
- it('should call the remote throwErrorFromClient() method and reject with an error', function() {
- return Edge.rpc('throwErrorFromClient')
- .catch(err => {
- // Assert that it's an "internal" error
- // See https://www.jsonrpc.org/specification#error_object
- chai.assert.equal(err.code, -32603);
- });
- });
-
- it('should call an unregistered method and reject with an error', function() {
- return Edge.rpc('unregisteredMethod')
- .catch(err => {
- // Assert that it's an "method not found" error
- // See https://www.jsonrpc.org/specification#error_object
- chai.assert.equal(err.code, -32601);
- });
- });
-
-
- it('should call the add() method repetitively and keep count of the sent values', function() {
- this.timeout(10000);
-
- const values = [];
- for(let i = 0; i <= 1000; i++) {
- values.push((Math.random() * 1000 | 0));
- }
- return Edge.rpc('reset')
- .then(() => {
- return Promise.all(values.map(v => Edge.rpc("add", {value: v})));
- })
- .then(() => Edge.rpc('total'))
- .then(remoteTotal => {
- const localTotal = values.reduce((t, v) => t+v);
- console.log("Remote total:", remoteTotal, "Local total:", localTotal);
- chai.assert.equal(remoteTotal, localTotal)
- })
- });
-
-});
-
-describe('File Module', function() {
-
- before(() => {
- return Edge.connect();
- });
-
- after(() => {
- Edge.disconnect();
- });
-
- it('should upload then download a blob', function() {
- const content = JSON.stringify({"date": new Date()});
- const blob = new Blob([content], {type: "application/json"});
-
- return Edge.upload(blob)
- .then(upload => upload.result())
- .then(result => {
-
- chai.assert.isNotEmpty(result.blobId);
- chai.assert.isNotEmpty(result.bucket);
-
- const blobUrl = Edge.blobUrl(result.bucket, result.blobId);
- chai.assert.isNotEmpty(blobUrl);
-
- return fetch(blobUrl)
- .then(res => res.text())
- .then(blobContent => {
- chai.assert.equal(content, blobContent);
- });
- })
- .catch(err => {
- chai.assert.fail(err);
- })
- });
-
-});
diff --git a/misc/client-sdk-testsuite/src/public/test/file-module.js b/misc/client-sdk-testsuite/src/public/test/file-module.js
new file mode 100644
index 0000000..aebf29b
--- /dev/null
+++ b/misc/client-sdk-testsuite/src/public/test/file-module.js
@@ -0,0 +1,36 @@
+describe('File Module', function () {
+
+ before(() => {
+ return Edge.connect();
+ });
+
+ after(() => {
+ Edge.disconnect();
+ });
+
+ it('should upload then download a blob', function () {
+ const content = JSON.stringify({ "date": new Date() });
+ const blob = new Blob([content], { type: "application/json" });
+
+ return Edge.upload(blob)
+ .then(upload => upload.result())
+ .then(result => {
+
+ chai.assert.isNotEmpty(result.blobId);
+ chai.assert.isNotEmpty(result.bucket);
+
+ const blobUrl = Edge.blobUrl(result.bucket, result.blobId);
+ chai.assert.isNotEmpty(blobUrl);
+
+ return fetch(blobUrl)
+ .then(res => res.text())
+ .then(blobContent => {
+ chai.assert.equal(content, blobContent);
+ });
+ })
+ .catch(err => {
+ chai.assert.fail(err);
+ })
+ });
+
+});
\ No newline at end of file
diff --git a/misc/client-sdk-testsuite/src/public/test/net-module.js b/misc/client-sdk-testsuite/src/public/test/net-module.js
new file mode 100644
index 0000000..d74c13e
--- /dev/null
+++ b/misc/client-sdk-testsuite/src/public/test/net-module.js
@@ -0,0 +1,49 @@
+describe('Net Module', function () {
+ this.timeout(5000);
+
+ before(() => {
+ return Edge.connect();
+ });
+
+ after(() => {
+ Edge.disconnect();
+ });
+
+ it('should broadcast a message from server', function (done) {
+ const message = { test: 'broadcast', now: Date.now() };
+
+ const handler = (evt) => {
+ const receivedMessage = evt.detail;
+ if (receivedMessage.test !== 'broadcast') return;
+
+ chai.assert.deepEqual(message, evt.detail);
+
+ Edge.removeEventListener('message', handler);
+ done();
+ };
+
+ Edge.addEventListener("message", handler);
+ Edge.send(message);
+ });
+
+ it('should send a message to the server and echo back', function(done) {
+ const now = new Date();
+
+ const handler = evt => {
+ const receivedMessage = evt.detail;
+ if (receivedMessage.test !== 'echo') return;
+
+ chai.assert.equal(receivedMessage.now, now.toJSON());
+
+ Edge.removeEventListener('message', handler);
+ done();
+ }
+
+ // Server should echo back message
+ Edge.addEventListener('message', handler);
+
+ // Send message to server
+ Edge.send({ test: 'echo', now });
+ });
+
+});
\ No newline at end of file
diff --git a/misc/client-sdk-testsuite/src/public/test/rpc-module.js b/misc/client-sdk-testsuite/src/public/test/rpc-module.js
new file mode 100644
index 0000000..80b3e90
--- /dev/null
+++ b/misc/client-sdk-testsuite/src/public/test/rpc-module.js
@@ -0,0 +1,59 @@
+describe('Remote Procedure Call', function () {
+
+ before(() => {
+ return Edge.connect();
+ });
+
+ after(() => {
+ Edge.disconnect();
+ });
+
+ it('should call the remote echo() method and resolve the returned value', function () {
+ const foo = "bar";
+
+ return Edge.rpc('echo', { foo })
+ .then(result => {
+ console.log(result);
+ chai.assert.equal(result.foo, foo);
+ });
+ });
+
+ it('should call the remote throwErrorFromClient() method and reject with an error', function () {
+ return Edge.rpc('throwErrorFromClient')
+ .catch(err => {
+ // Assert that it's an "internal" error
+ // See https://www.jsonrpc.org/specification#error_object
+ chai.assert.equal(err.code, -32603);
+ });
+ });
+
+ it('should call an unregistered method and reject with an error', function () {
+ return Edge.rpc('unregisteredMethod')
+ .catch(err => {
+ // Assert that it's an "method not found" error
+ // See https://www.jsonrpc.org/specification#error_object
+ chai.assert.equal(err.code, -32601);
+ });
+ });
+
+
+ it('should call the add() method repetitively and keep count of the sent values', function () {
+ this.timeout(10000);
+
+ const values = [];
+ for (let i = 0; i <= 1000; i++) {
+ values.push((Math.random() * 1000 | 0));
+ }
+ return Edge.rpc('reset')
+ .then(() => {
+ return Promise.all(values.map(v => Edge.rpc("add", { value: v })));
+ })
+ .then(() => Edge.rpc('total'))
+ .then(remoteTotal => {
+ const localTotal = values.reduce((t, v) => t + v);
+ console.log("Remote total:", remoteTotal, "Local total:", localTotal);
+ chai.assert.equal(remoteTotal, localTotal)
+ })
+ });
+
+});
diff --git a/misc/client-sdk-testsuite/src/server/main.js b/misc/client-sdk-testsuite/src/server/main.js
index b7e8a22..fe3af2a 100644
--- a/misc/client-sdk-testsuite/src/server/main.js
+++ b/misc/client-sdk-testsuite/src/server/main.js
@@ -14,9 +14,16 @@ function onInit() {
}
// Called for each client message
-function onClientMessage(ctx, data) {
- console.log("onClientMessage", data.now);
- net.send(ctx, { now: data.now });
+function onClientMessage(ctx, message) {
+ console.log("onClientMessage", message);
+
+ switch (message.test) {
+ case "broadcast":
+ net.broadcast(message);
+ break;
+ default:
+ net.send(ctx, message);
+ }
}
// Called for each blob upload request
diff --git a/modd.conf b/modd.conf
index 9ceaadf..9917520 100644
--- a/modd.conf
+++ b/modd.conf
@@ -1,6 +1,6 @@
**/*.go
-pkg/app/sdk/client/src/**/*.js
-pkg/app/sdk/client/src/**/*.ts
+pkg/sdk/client/src/**/*.js
+pkg/sdk/client/src/**/*.ts
misc/client-sdk-testsuite/src/**/*
modd.conf
{
diff --git a/pkg/sdk/client/src/client.ts b/pkg/sdk/client/src/client.ts
index 0be1b58..c3b91ca 100644
--- a/pkg/sdk/client/src/client.ts
+++ b/pkg/sdk/client/src/client.ts
@@ -93,6 +93,7 @@ export class Client extends EventTarget {
const { jsonrpc, id, error, result } = evt.detail;
if (jsonrpc !== '2.0' || id === undefined) return;
+ if (!evt.detail.hasOwnProperty("error") && !evt.detail.hasOwnProperty("result")) return;
// Prevent additional handlers to catch this event
evt.stopImmediatePropagation();