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:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
143
gaia/apps/sms/services/test/unit/conversation/conversation_client_test.js
Executable file
143
gaia/apps/sms/services/test/unit/conversation/conversation_client_test.js
Executable file
|
|
@ -0,0 +1,143 @@
|
|||
/*global bridge,
|
||||
ConversationClient,
|
||||
MocksHelper,
|
||||
streamClient,
|
||||
Thread
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
require('/services/test/unit/mock_bridge.js');
|
||||
require('/services/test/unit/mock_shared_worker.js');
|
||||
require('/services/test/unit/mock_threads.js');
|
||||
require('/services/js/conversation/conversation_client.js');
|
||||
|
||||
var MocksHelperForAttachment = new MocksHelper([
|
||||
'bridge',
|
||||
'SharedWorker',
|
||||
'streamClient',
|
||||
'Thread'
|
||||
]).init();
|
||||
|
||||
suite('ConversationClient >', function() {
|
||||
const APP_ID = 'fake-app-id';
|
||||
|
||||
var clientStub;
|
||||
|
||||
MocksHelperForAttachment.attachTestHelpers();
|
||||
|
||||
setup(function() {
|
||||
clientStub = sinon.stub({
|
||||
stream: () => {},
|
||||
plugin: () => {}
|
||||
});
|
||||
|
||||
clientStub.plugin.returns(clientStub);
|
||||
|
||||
this.sinon.spy(window, 'SharedWorker');
|
||||
|
||||
this.sinon.stub(bridge, 'client').returns(clientStub);
|
||||
});
|
||||
|
||||
test('throws if app instance id is not provided', function() {
|
||||
assert.throws(() => ConversationClient.init());
|
||||
});
|
||||
|
||||
test('bridge client is correctly initialized', function() {
|
||||
ConversationClient.init(APP_ID);
|
||||
|
||||
sinon.assert.calledWith(
|
||||
SharedWorker,
|
||||
'/services/js/conversation/conversation_service.js'
|
||||
);
|
||||
|
||||
sinon.assert.calledOnce(bridge.client);
|
||||
sinon.assert.calledWith(bridge.client, {
|
||||
service: 'conversation-service',
|
||||
endpoint: SharedWorker.lastCall.returnValue,
|
||||
timeout: false
|
||||
});
|
||||
sinon.assert.calledWith(clientStub.plugin, streamClient);
|
||||
});
|
||||
|
||||
suite('getAllConversations', function() {
|
||||
var streamStub, resolveStream, rejectStream;
|
||||
setup(function() {
|
||||
ConversationClient.init(APP_ID);
|
||||
|
||||
streamStub = sinon.stub({
|
||||
listen: () => {},
|
||||
closed: new Promise((resolve, reject) => {
|
||||
resolveStream = resolve;
|
||||
rejectStream = reject;
|
||||
})
|
||||
});
|
||||
|
||||
clientStub.stream.withArgs('getAllConversations', APP_ID).returns(
|
||||
streamStub
|
||||
);
|
||||
});
|
||||
|
||||
test('calls callback on every retrieved item', function() {
|
||||
var onConversationRetrievedStub = sinon.stub();
|
||||
|
||||
ConversationClient.getAllConversations(onConversationRetrievedStub);
|
||||
|
||||
sinon.assert.notCalled(onConversationRetrievedStub);
|
||||
|
||||
streamStub.listen.yield({ id: 1, body: 'body' });
|
||||
|
||||
sinon.assert.calledOnce(onConversationRetrievedStub);
|
||||
sinon.assert.calledWith(
|
||||
onConversationRetrievedStub, sinon.match({ id: 1, body: 'body'})
|
||||
);
|
||||
assert.instanceOf(onConversationRetrievedStub.lastCall.args[0], Thread);
|
||||
|
||||
streamStub.listen.yield({ id: 2, body: 'body2' });
|
||||
|
||||
sinon.assert.calledTwice(onConversationRetrievedStub);
|
||||
sinon.assert.calledWith(
|
||||
onConversationRetrievedStub, sinon.match({ id: 2, body: 'body2'})
|
||||
);
|
||||
assert.instanceOf(onConversationRetrievedStub.lastCall.args[0], Thread);
|
||||
});
|
||||
|
||||
test('is resolved when stream.closed is resolved', function(done) {
|
||||
var resolveStub = sinon.stub();
|
||||
|
||||
var streamPromise = ConversationClient.getAllConversations(() => {}).then(
|
||||
resolveStub
|
||||
);
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
sinon.assert.notCalled(resolveStub);
|
||||
|
||||
resolveStream();
|
||||
|
||||
return streamPromise;
|
||||
}).then(() => {
|
||||
sinon.assert.calledOnce(resolveStub);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('is rejected when stream.closed is rejected', function(done) {
|
||||
var rejectStub = sinon.stub();
|
||||
var error = new Error('Error');
|
||||
|
||||
var streamPromise = ConversationClient.getAllConversations(() => {}).then(
|
||||
() => { throw new Error('getAllConversations should be rejected'); },
|
||||
rejectStub
|
||||
);
|
||||
|
||||
Promise.resolve().then(() => {
|
||||
sinon.assert.notCalled(rejectStub);
|
||||
|
||||
rejectStream(error);
|
||||
|
||||
return streamPromise;
|
||||
}).catch(() => {
|
||||
sinon.assert.calledWith(rejectStub, error);
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
253
gaia/apps/sms/services/test/unit/conversation/conversation_service_test.js
Executable file
253
gaia/apps/sms/services/test/unit/conversation/conversation_service_test.js
Executable file
|
|
@ -0,0 +1,253 @@
|
|||
/*global bridge,
|
||||
ConversationService,
|
||||
Drafts,
|
||||
MocksHelper,
|
||||
MozMobileMessageClient
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
require('/services/test/unit/mock_bridge.js');
|
||||
require('/services/test/unit/mock_drafts.js');
|
||||
require(
|
||||
'/services/test/unit/moz_mobile_message/mock_moz_mobile_message_client.js'
|
||||
);
|
||||
require('/services/js/bridge_service_mixin.js');
|
||||
require('/services/js/conversation/conversation_service.js');
|
||||
|
||||
var MocksHelperForAttachment = new MocksHelper([
|
||||
'bridge',
|
||||
'Drafts',
|
||||
'Draft',
|
||||
'MozMobileMessageClient',
|
||||
'streamService'
|
||||
]).init();
|
||||
|
||||
suite('ConversationService >', function() {
|
||||
var serviceStub, mobileMessageClientStub;
|
||||
|
||||
const APP_INSTANCE_ID = 'fake-app-instance-id';
|
||||
|
||||
MocksHelperForAttachment.attachTestHelpers();
|
||||
|
||||
setup(function() {
|
||||
serviceStub = sinon.stub({
|
||||
method: () => {},
|
||||
stream: () => {},
|
||||
broadcast: () => {},
|
||||
listen: () => {},
|
||||
plugin: () => {}
|
||||
});
|
||||
|
||||
this.sinon.stub(bridge, 'service').withArgs('conversation-service').returns(
|
||||
serviceStub
|
||||
);
|
||||
|
||||
mobileMessageClientStub = sinon.stub({
|
||||
getThreads: () => {}
|
||||
});
|
||||
|
||||
this.sinon.stub(MozMobileMessageClient, 'forApp').withArgs(
|
||||
APP_INSTANCE_ID
|
||||
).returns(mobileMessageClientStub);
|
||||
|
||||
ConversationService.init();
|
||||
});
|
||||
|
||||
suite('getAllConversations >', function() {
|
||||
var serviceStreamStub, mobileMessageStreamStub, resolveMobileMessageStream,
|
||||
rejectMobileMessageStream, drafts, threadDraft, threads;
|
||||
|
||||
function threadToConversationSummary(thread, threadDraft) {
|
||||
return {
|
||||
id: thread.id,
|
||||
participants: thread.participants,
|
||||
body: thread.body,
|
||||
timestamp: thread.timestamp,
|
||||
status: { hasUnread: thread.unreadCount > 0, hasNewError: false },
|
||||
lastMessageType: thread.lastMessageType,
|
||||
draft: threadDraft || null
|
||||
};
|
||||
}
|
||||
|
||||
function draftToConversationSummary(draft) {
|
||||
return {
|
||||
id: draft.id,
|
||||
participants: draft.recipients,
|
||||
body: draft.content[0],
|
||||
timestamp: new Date(draft.timestamp),
|
||||
status: { hasUnread: false, hasNewError: false },
|
||||
lastMessageType: draft.type || 'sms',
|
||||
draft: draft
|
||||
};
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
serviceStreamStub = sinon.stub({
|
||||
write: () => {},
|
||||
close: () => {},
|
||||
abort: () => {}
|
||||
});
|
||||
|
||||
mobileMessageStreamStub = sinon.stub({
|
||||
listen: () => {},
|
||||
cancel: () => {},
|
||||
closed: new Promise((resolve, reject) => {
|
||||
resolveMobileMessageStream = resolve;
|
||||
rejectMobileMessageStream = reject;
|
||||
})
|
||||
});
|
||||
|
||||
mobileMessageClientStub.getThreads.returns(mobileMessageStreamStub);
|
||||
|
||||
drafts = [{
|
||||
id: 1,
|
||||
recipients: ['+1'],
|
||||
content: ['body1'],
|
||||
type: 'sms',
|
||||
timestamp: 1
|
||||
}, {
|
||||
id: 3,
|
||||
recipients: ['a@abc.xyz'],
|
||||
content: ['body3'],
|
||||
type: 'mms',
|
||||
timestamp: 3
|
||||
}];
|
||||
|
||||
threadDraft = {
|
||||
id: 100,
|
||||
recipients: ['+100'],
|
||||
content: ['body100'],
|
||||
type: 'sms',
|
||||
threadId: 5,
|
||||
timestamp: 100
|
||||
};
|
||||
|
||||
threads = [{
|
||||
id: 2,
|
||||
participants: ['+2'],
|
||||
body: 'body2',
|
||||
timestamp: 2,
|
||||
unreadCount: 0,
|
||||
lastMessageType: 'sms'
|
||||
}, {
|
||||
id: 4,
|
||||
participants: ['a@abc.xyz'],
|
||||
body: 'body4',
|
||||
timestamp: 4,
|
||||
unreadCount: 1,
|
||||
lastMessageType: 'mms'
|
||||
}, {
|
||||
id: 5,
|
||||
participants: ['+5'],
|
||||
body: 'body5',
|
||||
timestamp: 5,
|
||||
unreadCount: 0,
|
||||
lastMessageType: 'sms'
|
||||
}];
|
||||
|
||||
// Sort threads in the reverse order.
|
||||
threads.sort((threadA, threadB) => threadB.timestamp - threadA.timestamp);
|
||||
|
||||
this.sinon.stub(Drafts, 'getAllThreadless').returns(drafts.slice());
|
||||
this.sinon.stub(Drafts, 'byThreadId').returns(null);
|
||||
Drafts.byThreadId.withArgs(5).returns(threadDraft);
|
||||
});
|
||||
|
||||
test('mobileMessage stream is cancelled if main stream is cancelled',
|
||||
function() {
|
||||
ConversationService.getAllConversations(
|
||||
serviceStreamStub, APP_INSTANCE_ID
|
||||
);
|
||||
|
||||
serviceStreamStub.cancel('ReAsOn');
|
||||
|
||||
sinon.assert.calledOnce(mobileMessageStreamStub.cancel);
|
||||
sinon.assert.calledWith(mobileMessageStreamStub.cancel, 'ReAsOn');
|
||||
});
|
||||
|
||||
test('threads and drafts are returned in the correct order',
|
||||
function(done) {
|
||||
var getAllConversationsPromise = ConversationService.getAllConversations(
|
||||
serviceStreamStub, APP_INSTANCE_ID
|
||||
);
|
||||
|
||||
threads.forEach((thread) => {
|
||||
mobileMessageStreamStub.listen.yield(thread);
|
||||
});
|
||||
|
||||
resolveMobileMessageStream();
|
||||
|
||||
getAllConversationsPromise.then(() => {
|
||||
sinon.assert.callCount(serviceStreamStub.write, 5);
|
||||
sinon.assert.callOrder(
|
||||
serviceStreamStub.write.withArgs(
|
||||
sinon.match(threadToConversationSummary(threads[0], threadDraft))
|
||||
),
|
||||
serviceStreamStub.write.withArgs(
|
||||
sinon.match(threadToConversationSummary(threads[1]))
|
||||
),
|
||||
serviceStreamStub.write.withArgs(
|
||||
sinon.match(draftToConversationSummary(drafts[1]))
|
||||
),
|
||||
serviceStreamStub.write.withArgs(
|
||||
sinon.match(threadToConversationSummary(threads[2]))
|
||||
),
|
||||
serviceStreamStub.write.withArgs(
|
||||
sinon.match(draftToConversationSummary(drafts[0]))
|
||||
)
|
||||
);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('only drafts are returned if there is no threads', function(done) {
|
||||
var getAllConversationsPromise = ConversationService.getAllConversations(
|
||||
serviceStreamStub, APP_INSTANCE_ID
|
||||
);
|
||||
|
||||
resolveMobileMessageStream();
|
||||
|
||||
getAllConversationsPromise.then(() => {
|
||||
sinon.assert.callCount(serviceStreamStub.write, 2);
|
||||
sinon.assert.callOrder(
|
||||
serviceStreamStub.write.withArgs(
|
||||
sinon.match(draftToConversationSummary(drafts[1]))
|
||||
),
|
||||
serviceStreamStub.write.withArgs(
|
||||
sinon.match(draftToConversationSummary(drafts[0]))
|
||||
)
|
||||
);
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('stream is closed when mobileMessageStream is successfully closed',
|
||||
function(done) {
|
||||
var getAllConversationsPromise = ConversationService.getAllConversations(
|
||||
serviceStreamStub, APP_INSTANCE_ID
|
||||
);
|
||||
|
||||
resolveMobileMessageStream();
|
||||
|
||||
getAllConversationsPromise.then(() => {
|
||||
sinon.assert.called(serviceStreamStub.close);
|
||||
}, () => {
|
||||
throw new Error('getAllConversations should always be resolved');
|
||||
}).then(done, done);
|
||||
});
|
||||
|
||||
test('stream is aborted when mobileMessageStream is unexpectedly closed',
|
||||
function(done) {
|
||||
var getAllConversationsPromise = ConversationService.getAllConversations(
|
||||
serviceStreamStub, APP_INSTANCE_ID
|
||||
);
|
||||
|
||||
rejectMobileMessageStream(new Error('Exception'));
|
||||
|
||||
getAllConversationsPromise.then(() => {
|
||||
sinon.assert.calledWith(serviceStreamStub.abort, '[Error] Exception');
|
||||
}, () => {
|
||||
throw new Error('getAllConversations should always be resolved');
|
||||
}).then(done, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
10
gaia/apps/sms/services/test/unit/conversation/mock_conversation_client.js
Executable file
10
gaia/apps/sms/services/test/unit/conversation/mock_conversation_client.js
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
/* exported MockConversationClient */
|
||||
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
|
||||
exports.MockConversationClient = {
|
||||
init: () => {},
|
||||
getAllConversations: () => Promise.resolve()
|
||||
};
|
||||
})(window);
|
||||
Loading…
Reference in a new issue