Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,221 @@
/*global ActivityClient,
BroadcastChannel,
MocksHelper,
bridge
*/
'use strict';
require('/services/test/unit/mock_bridge.js');
require('/views/shared/test/unit/mock_broadcast_channel.js');
require('/shared/js/event_dispatcher.js');
require('/services/js/activity/activity_client.js');
var MocksHelperForAttachment = new MocksHelper([
'bridge',
'BroadcastChannel'
]).init();
suite('ActivityClient >', function() {
const APP_INSTANCE_ID = 'fake-app-id';
var clientStub;
MocksHelperForAttachment.attachTestHelpers();
setup(function() {
clientStub = sinon.stub({
on: () => {},
off: () => {},
method: () => {}
});
this.sinon.stub(bridge, 'client').returns(clientStub);
});
teardown(function() {
ActivityClient.offAll();
});
suite('init()', function() {
test('throws if app instance id is not provided', function() {
assert.throws(() => ActivityClient.init());
});
test('bridge client is correctly initialized', function() {
ActivityClient.init(APP_INSTANCE_ID);
sinon.assert.calledOnce(bridge.client);
sinon.assert.calledWith(bridge.client, {
service: 'activity-service',
endpoint: sinon.match.instanceOf(BroadcastChannel).and(
sinon.match.has(
'name',
'activity-service-channel-' + APP_INSTANCE_ID
)
),
timeout: false
});
assert.isFalse(ActivityClient.hasPendingRequest());
});
});
suite('throws in exceptional cases', function() {
setup(function() {
ActivityClient.init(APP_INSTANCE_ID);
});
test('postResult throws if there is no activity request', function(done) {
ActivityClient.postResult('Result').then(() => {
throw new Error('postResult should be rejected!');
}, (e) => {
assert.instanceOf(e, Error);
}).then(done, done);
});
test('postError throws if there is no activity request', function(done) {
ActivityClient.postError('Error').then(() => {
throw new Error('postError should be rejected!');
}, (e) => {
assert.instanceOf(e, Error);
}).then(done, done);
});
});
suite('handling incoming activity requests> ', function() {
setup(function() {
ActivityClient.init(APP_INSTANCE_ID);
});
teardown(function() {
ActivityClient.offAll();
});
test('post error on concurrent request attempt', function() {
var onShareActivityRequest = sinon.stub();
ActivityClient.on('share-activity-request', onShareActivityRequest);
clientStub.on.withArgs('activity-request').yield({
name: 'share',
data: { body: 'text' }
});
assert.isTrue(ActivityClient.hasPendingRequest());
sinon.assert.calledOnce(onShareActivityRequest);
clientStub.on.withArgs('activity-request').yield({
name: 'share',
data: { body: 'text' }
});
sinon.assert.calledOnce(onShareActivityRequest);
sinon.assert.calledWith(
clientStub.method, 'postError', sinon.match.string
);
assert.isFalse(ActivityClient.hasPendingRequest());
});
test('notifies about "share" activity request', function() {
var onShareActivityRequest = sinon.stub();
var onNewActivityRequest = sinon.stub();
ActivityClient.on('share-activity-request', onShareActivityRequest);
ActivityClient.on('new-activity-request', onNewActivityRequest);
clientStub.on.withArgs('activity-request').yield({
name: 'share',
data: { body: 'text' }
});
sinon.assert.notCalled(onNewActivityRequest);
sinon.assert.calledOnce(onShareActivityRequest);
sinon.assert.calledWith(onShareActivityRequest, { body: 'text' });
});
test('notifies about "new" activity request', function() {
var onShareActivityRequest = sinon.stub();
var onNewActivityRequest = sinon.stub();
ActivityClient.on('share-activity-request', onShareActivityRequest);
ActivityClient.on('new-activity-request', onNewActivityRequest);
clientStub.on.withArgs('activity-request').yield({
name: 'new',
data: { number: '+123' }
});
sinon.assert.notCalled(onShareActivityRequest);
sinon.assert.calledOnce(onNewActivityRequest);
sinon.assert.calledWith(onNewActivityRequest, { number: '+123' });
});
});
suite('responding to activity request >', function() {
setup(function() {
ActivityClient.init(APP_INSTANCE_ID);
clientStub.on.withArgs('activity-request').yield({
name: 'new',
data: { number: '+123' }
});
assert.isTrue(ActivityClient.hasPendingRequest());
});
test('postResult correctly handles successful method call', function(done) {
clientStub.method.returns(Promise.resolve());
ActivityClient.postResult('Result').then(() => {
sinon.assert.calledOnce(clientStub.method);
sinon.assert.calledWith(clientStub.method, 'postResult', 'Result');
assert.isFalse(ActivityClient.hasPendingRequest());
}).then(done, done);
});
test('postResult correctly handles failed method call', function(done) {
var rejectReason = new Error('Fake reason');
clientStub.method.returns(Promise.reject(rejectReason));
ActivityClient.postResult('Result').then(() => {
throw new Error('postResult should be rejected!');
}, (e) => {
sinon.assert.calledOnce(clientStub.method);
sinon.assert.calledWith(clientStub.method, 'postResult', 'Result');
assert.isFalse(ActivityClient.hasPendingRequest());
assert.equal(e, rejectReason);
}).then(done, done);
});
test('postError correctly handles successful method call', function() {
ActivityClient.postError('Error');
sinon.assert.calledOnce(clientStub.method);
sinon.assert.calledWith(clientStub.method, 'postError', 'Error');
assert.isFalse(ActivityClient.hasPendingRequest());
});
test('postError correctly handles failed method call', function(done) {
var rejectReason = new Error('Fake reason');
clientStub.method.returns(Promise.reject(rejectReason));
ActivityClient.postError('Error').then(() => {
throw new Error('postError should be rejected!');
}, (e) => {
sinon.assert.calledOnce(clientStub.method);
sinon.assert.calledWith(clientStub.method, 'postError', 'Error');
assert.isFalse(ActivityClient.hasPendingRequest());
assert.equal(e, rejectReason);
}).then(done, done);
});
});
});

View file

@ -0,0 +1,146 @@
/*global ActivityShim,
bridge,
BroadcastChannel,
MocksHelper
*/
'use strict';
require('/services/test/unit/mock_bridge.js');
require('/shared/js/event_dispatcher.js');
require('/services/js/bridge_service_mixin.js');
require('/services/js/activity/activity_shim.js');
require('/views/shared/test/unit/mock_broadcast_channel.js');
var MocksHelperForAttachment = new MocksHelper([
'bridge',
'BroadcastChannel'
]).init();
suite('ActivityShim >', function() {
const APP_INSTANCE_ID = 'fake-app-id';
var serviceStub, setMessageHandlerStub;
MocksHelperForAttachment.attachTestHelpers();
setup(function() {
this.sinon.useFakeTimers();
serviceStub = sinon.stub({
method: () => {},
broadcast: () => {},
listen: () => {},
on: () => {}
});
setMessageHandlerStub = sinon.stub();
this.sinon.stub(bridge, 'service').returns(serviceStub);
});
suite('init()', function() {
test('throws if app instance id is not provided', function() {
assert.throws(() => ActivityShim.init());
});
test('bridge service is correctly initialized', function() {
ActivityShim.init(APP_INSTANCE_ID, setMessageHandlerStub);
sinon.assert.calledOnce(bridge.service);
sinon.assert.calledWith(bridge.service, 'activity-service');
sinon.assert.calledTwice(serviceStub.listen);
sinon.assert.calledWith(
serviceStub.listen,
sinon.match.instanceOf(BroadcastChannel).and(
sinon.match.has(
'name',
'activity-service-channel-' + APP_INSTANCE_ID
)
)
);
});
});
suite('activity system message >', function() {
setup(function() {
ActivityShim.init(APP_INSTANCE_ID, setMessageHandlerStub);
});
test('when client is not connected yet', function() {
sinon.assert.notCalled(setMessageHandlerStub);
});
suite('once client is connected', function() {
var activityRequest;
setup(function() {
activityRequest = sinon.stub({
postResult: () => {},
postError: () => {},
source: {
name: 'fake',
data: {
custom: 'custom'
}
}
});
serviceStub.on.withArgs('connected').yield();
setMessageHandlerStub.withArgs('activity').yield(activityRequest);
});
test('activity request is broadcasted', function() {
sinon.assert.calledWith(
serviceStub.broadcast, 'activity-request', activityRequest.source
);
});
test('postResult passes default arguments', function() {
serviceStub.method.withArgs('postResult').yield();
sinon.assert.calledOnce(activityRequest.postResult);
sinon.assert.calledWith(activityRequest.postResult, { success: true });
// Activity request is disposed after first postResult.
assert.throw(() => {
serviceStub.method.withArgs('postResult').yield();
});
sinon.assert.calledOnce(activityRequest.postResult);
});
test('postResult passes custom arguments', function() {
serviceStub.method.withArgs('postResult').yield({ custom: 'custom' });
sinon.assert.notCalled(activityRequest.postError);
sinon.assert.calledOnce(activityRequest.postResult);
sinon.assert.calledWith(
activityRequest.postResult, { custom: 'custom' }
);
// Activity request is disposed after first postResult.
assert.throw(() => {
serviceStub.method.withArgs('postResult').yield({ custom: 'custom' });
});
sinon.assert.calledOnce(activityRequest.postResult);
});
test('postError passes error reason', function() {
serviceStub.method.withArgs('postError').yield('error');
sinon.assert.notCalled(activityRequest.postResult);
sinon.assert.calledOnce(activityRequest.postError);
sinon.assert.calledWith(activityRequest.postError, 'error');
// Activity request is disposed after first postError.
assert.throw(() => {
serviceStub.method.withArgs('postError').yield('error');
});
sinon.assert.calledOnce(activityRequest.postError);
});
});
});
});

View file

@ -0,0 +1,13 @@
/* exported MockActivityClient */
(function(exports) {
'use strict';
exports.MockActivityClient = {
init: () => {},
postResult: () => Promise.resolve(),
postError: () => Promise.resolve(),
hasPendingRequest: () => false,
on: () => {}
};
})(window);

View file

@ -0,0 +1,9 @@
/* exported MockActivityShim */
(function(exports) {
'use strict';
exports.MockActivityShim = {
init: () => {}
};
})(window);