openvibers/openvibe.network Commits
bench: one grant to push notifications (the model watch) (#436)
Changes
@@@ -644,6 +644,11 @@ const DEFAULT_GRANTS = [// other services' above. It publishes bench.* events and answers no other service today, so no Search grant.['bench', 'ai.run.create', 'openvibe.ai', ['ai.generate']],['bench', 'events.subscription.manage', 'openvibe.events', []],++ // Bench's model watch (Bench B10): when a followed score moves beyond its interval, or a model overtakes the one++ // someone follows, Bench pushes that person one notification through Network as app 'bench' (Bench's++ // server/watch/watch.js resolves the watch's user id, then pushes with openvibe-sdk/notifications). Its own name++ // only, as Live's, Actor's and Today's: Bench holds nothing else of Network's notifications.++ ['bench', 'network.notifications.push', SELF_AUDIENCE, ['bench']],// OpenVibe.Design's Arena moves onto Bench (contracts 0.238.0): it creates tasks and rounds, reads rounds and boards,// and casts the Arena's judgements on openvibe.bench. The earlier vision.ui.check grant stays for its UI check.['design', 'bench.task.create', 'openvibe.bench', []],nnew file mode 100644@@@ -0,0 +1,25 @@++/**++ * OpenVibe.Bench's notification grant (Bench B10, the model watch): when a followed score moves beyond its interval,++ * or a model overtakes the one someone follows, Bench pushes that person one notification through Network as app++ * 'bench'. It is the one grant Bench holds for notifications, and each is a capability the pinned contracts offer,++ * active.++ *++ * node test/bench-notify-grants.test.js++ */++'use strict';++const assert = require('assert');++const contracts = require('openvibe-contracts');++const principals = require('../server/identity/principals');++++const rows = principals.DEFAULT_GRANTS.filter((g) => g[0] === 'bench' && g[2] === principals.SELF_AUDIENCE);++const held = new Map(rows.map((g) => [g[1], g[3]]));++++assert.deepStrictEqual(held.get('network.notifications.push'), ['bench'], 'bench pushes as its own app only');++assert.strictEqual(rows.filter((g) => g[1] === 'network.notifications.push').length, 1, 'exactly one push grant');++++for (const g of rows) {++ const cap = contracts.capabilities.get(g[1]);++ assert.ok(cap && cap.status === 'active', `${g[1]} is an active capability`);++}++++console.log(`bench notify grants: ${rows.length}`);@@@ -172,11 +172,12 @@ const server = http.createServer(app);assert.strictEqual(t.status, 200, JSON.stringify(t.body));assert.deepStrictEqual(t.body.scope.split(' '), ['bench.entry.create', 'bench.judgement.cast', 'bench.round.create', 'bench.task.create'], 'Games submits priced matches and automatic outcomes');-- // OpenVibe.Bench (contracts 0.238.0): the account export/deletion pair, its account-event subscriptions, and-- // ai.run.create (namespace ai.generate) to run its pinned rounds; it publishes bench.* events and indexes nothing.++ // OpenVibe.Bench (contracts 0.238.0): the account export/deletion pair, its account-event subscriptions,++ // ai.run.create (namespace ai.generate) to run its pinned rounds, and (B10) the model watch's one notification++ // push under its own name; it publishes bench.* events and indexes nothing.await db.prepare("UPDATE oauth_clients SET client_secret = 'bench-secret' WHERE client_id = 'bench'").run();t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.network' });-- assert.deepStrictEqual(t.body.scope.split(' '), ['network.account.deletion.confirm', 'network.account.export.contribute'], 'Bench answers account export and deletion');++ assert.deepStrictEqual(t.body.scope.split(' '), ['network.account.deletion.confirm', 'network.account.export.contribute', 'network.notifications.push'], 'Bench answers account export and deletion, and pushes its watch notices');t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.events' });assert.strictEqual(t.body.scope, 'events.subscription.manage', 'Bench subscribes to the account events at boot');t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.ai' });
@@ -644,6 +644,11 @@ const DEFAULT_GRANTS = [
@@ -644,6 +644,11 @@ const DEFAULT_GRANTS = [
// other services' above. It publishes bench.* events and answers no other service today, so no Search grant.
// other services' above. It publishes bench.* events and answers no other service today, so no Search grant.
['bench', 'ai.run.create', 'openvibe.ai', ['ai.generate']],
['bench', 'ai.run.create', 'openvibe.ai', ['ai.generate']],
['bench', 'events.subscription.manage', 'openvibe.events', []],
['bench', 'events.subscription.manage', 'openvibe.events', []],
+ // Bench's model watch (Bench B10): when a followed score moves beyond its interval, or a model overtakes the one
+ // someone follows, Bench pushes that person one notification through Network as app 'bench' (Bench's
+ // server/watch/watch.js resolves the watch's user id, then pushes with openvibe-sdk/notifications). Its own name
+ // only, as Live's, Actor's and Today's: Bench holds nothing else of Network's notifications.
+ ['bench', 'network.notifications.push', SELF_AUDIENCE, ['bench']],
// OpenVibe.Design's Arena moves onto Bench (contracts 0.238.0): it creates tasks and rounds, reads rounds and boards,
// OpenVibe.Design's Arena moves onto Bench (contracts 0.238.0): it creates tasks and rounds, reads rounds and boards,
// and casts the Arena's judgements on openvibe.bench. The earlier vision.ui.check grant stays for its UI check.
// and casts the Arena's judgements on openvibe.bench. The earlier vision.ui.check grant stays for its UI check.
['design', 'bench.task.create', 'openvibe.bench', []],
['design', 'bench.task.create', 'openvibe.bench', []],
new file mode 100644
new file mode 100644
@@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
+/**
+ * OpenVibe.Bench's notification grant (Bench B10, the model watch): when a followed score moves beyond its interval,
+ * or a model overtakes the one someone follows, Bench pushes that person one notification through Network as app
+ * 'bench'. It is the one grant Bench holds for notifications, and each is a capability the pinned contracts offer,
+ * active.
+ *
+ * node test/bench-notify-grants.test.js
+ */
+'use strict';
+const assert = require('assert');
+const contracts = require('openvibe-contracts');
+const principals = require('../server/identity/principals');
+
+const rows = principals.DEFAULT_GRANTS.filter((g) => g[0] === 'bench' && g[2] === principals.SELF_AUDIENCE);
+const held = new Map(rows.map((g) => [g[1], g[3]]));
+
+assert.deepStrictEqual(held.get('network.notifications.push'), ['bench'], 'bench pushes as its own app only');
+assert.strictEqual(rows.filter((g) => g[1] === 'network.notifications.push').length, 1, 'exactly one push grant');
+
+for (const g of rows) {
+ const cap = contracts.capabilities.get(g[1]);
+ assert.ok(cap && cap.status === 'active', `${g[1]} is an active capability`);
+}
+
+console.log(`bench notify grants: ${rows.length}`);
@@ -172,11 +172,12 @@ const server = http.createServer(app);
@@ -172,11 +172,12 @@ const server = http.createServer(app);
assert.strictEqual(t.status, 200, JSON.stringify(t.body));
assert.strictEqual(t.status, 200, JSON.stringify(t.body));
assert.deepStrictEqual(t.body.scope.split(' '), ['bench.entry.create', 'bench.judgement.cast', 'bench.round.create', 'bench.task.create'], 'Games submits priced matches and automatic outcomes');
assert.deepStrictEqual(t.body.scope.split(' '), ['bench.entry.create', 'bench.judgement.cast', 'bench.round.create', 'bench.task.create'], 'Games submits priced matches and automatic outcomes');
- // OpenVibe.Bench (contracts 0.238.0): the account export/deletion pair, its account-event subscriptions, and
- // ai.run.create (namespace ai.generate) to run its pinned rounds; it publishes bench.* events and indexes nothing.
+ // OpenVibe.Bench (contracts 0.238.0): the account export/deletion pair, its account-event subscriptions,
+ // ai.run.create (namespace ai.generate) to run its pinned rounds, and (B10) the model watch's one notification
+ // push under its own name; it publishes bench.* events and indexes nothing.
await db.prepare("UPDATE oauth_clients SET client_secret = 'bench-secret' WHERE client_id = 'bench'").run();
await db.prepare("UPDATE oauth_clients SET client_secret = 'bench-secret' WHERE client_id = 'bench'").run();
t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.network' });
t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.network' });
- assert.deepStrictEqual(t.body.scope.split(' '), ['network.account.deletion.confirm', 'network.account.export.contribute'], 'Bench answers account export and deletion');
+ assert.deepStrictEqual(t.body.scope.split(' '), ['network.account.deletion.confirm', 'network.account.export.contribute', 'network.notifications.push'], 'Bench answers account export and deletion, and pushes its watch notices');
t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.events' });
t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.events' });
assert.strictEqual(t.body.scope, 'events.subscription.manage', 'Bench subscribes to the account events at boot');
assert.strictEqual(t.body.scope, 'events.subscription.manage', 'Bench subscribes to the account events at boot');
t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.ai' });
t = await token({ client_id: 'bench', client_secret: 'bench-secret', audience: 'openvibe.ai' });