linagora-rse
Version:
283 lines (258 loc) • 8.84 kB
JavaScript
;
var chai = require('chai');
var expect = chai.expect;
var mockery = require('mockery');
var q = require('q');
describe('The google contact importer', function() {
var deps, dependencies, mappingMock, passportRefreshMock, requestMock, optionsMock, xml2jsMock;
var response, body;
var accessToken = 1234;
beforeEach(function() {
mappingMock = {
toVcard: function() {}
};
response = { statusCode: 200 };
body = {
feed: {
'openSearch:startIndex': [0],
'openSearch:totalResults': [199],
entry: [
{ id: 1, link: [{$: { type: 'image/*' }}] },
{ id: 2, link: [{$: { type: 'image/*' }}] },
{ id: 3, link: [{$: { type: 'image/*' }}] }
]
}
};
requestMock = function(option, callback) {
callback(null, response, null);
};
passportRefreshMock = {
requestNewAccessToken: function(name, refresh_token, callback) {
callback(null, accessToken);
}
};
xml2jsMock = {
parseString: function(xml, callback) {
callback(null, body);
body.feed['openSearch:startIndex'][0] += 50;
}
};
optionsMock = {
account: {
data: {
refresh_token: 'abcde'
}
}
};
dependencies = {
logger: {
info: function() {},
error: function() {},
debug: function() {},
warn: function() {}
},
'contact-import': {
constants: {
CONTACT_IMPORT_ERROR: {
ACCOUNT_ERROR: 'contact:import:account:error',
API_CLIENT_ERROR: 'contact:import:api:error',
CONTACT_CLIENT_ERROR: 'contact:import:contact:error'
}
},
lib: {
import: {
buildErrorMessage: function() {
return {};
},
createContact: function() {
return q.resolve({});
}
}
}
}
};
deps = function(name) {
return dependencies[name];
};
mockery.registerMock('./mapping', function() { return mappingMock; });
mockery.registerMock('passport-oauth2-refresh', passportRefreshMock);
mockery.registerMock('request', requestMock);
mockery.registerMock('xml2js', xml2jsMock);
});
var getImporter = function() {
return require('../../../backend/lib/importer')(deps);
};
describe('The importContact function', function() {
it('should refresh the access token', function(done) {
passportRefreshMock.requestNewAccessToken = function(name, refresh_token) {
expect(name).to.equal('google-authz');
expect(refresh_token).to.equal(optionsMock.account.data.refresh_token);
done();
};
getImporter().importContact(optionsMock);
});
it('should reject if can not refresh the access token', function(done) {
var err = new Error('can not refresh access token');
passportRefreshMock.requestNewAccessToken = function(name, refresh_token, callback) {
callback(err, accessToken);
};
getImporter().importContact(optionsMock).then(null, function(error) {
expect(error).to.deep.equal(err);
done();
});
});
it('should send request to google server with correct options', function(done) {
requestMock = function(option) {
expect(option).to.deep.equal({
method: 'GET',
url: 'https://www.google.com/m8/feeds/contacts/default/full?max-results=50',
headers: { 'GData-Version': '3.0', Authorization: 'Bearer 1234' }
});
done();
};
mockery.registerMock('request', requestMock);
getImporter().importContact(optionsMock);
});
it('should reject if request to google server returns error', function(done) {
const errorObject = new Error('something wrong');
const type = dependencies['contact-import'].constants.CONTACT_IMPORT_ERROR.API_CLIENT_ERROR;
const errorMessage = {
type: type,
error: errorObject
};
dependencies['contact-import'].lib.import.buildErrorMessage = function(type, error) {
expect(type).to.equal(type);
expect(error).to.deep.equal(errorObject);
return errorMessage;
};
requestMock = function(option, callback) {
callback(errorObject, {statusCode: 500});
};
mockery.registerMock('request', requestMock);
getImporter().importContact(optionsMock).then(null, function(err) {
expect(err).to.deep.equal(errorMessage);
done();
});
});
it('should reject if request to google server returns error in respone body instead of error object', function(done) {
const statusCode = 403;
const body = '<errors></errors>';
const bodyParsed = {
errors: {
error: [
{
internalReason: 'something wrong',
code: 'error code'
}
]
}
};
const errorObject = {
statusCode: statusCode,
message: bodyParsed.errors.error[0].internalReason,
code: bodyParsed.errors.error[0].code,
allErrors: bodyParsed.errors.error
};
const type = dependencies['contact-import'].constants.CONTACT_IMPORT_ERROR.API_CLIENT_ERROR;
xml2jsMock.parseString = function(xml, callback) {
expect(xml).to.equal(body);
callback(null, bodyParsed);
};
const errorMessage = {
type: type,
errorObject: errorObject
};
dependencies['contact-import'].lib.import.buildErrorMessage = function(type, error) {
expect(type).to.equal(errorMessage.type);
expect(error).to.deep.equal(errorMessage.errorObject);
return errorMessage;
};
requestMock = function(option, callback) {
callback(null, { statusCode: statusCode }, body);
};
mockery.registerMock('request', requestMock);
getImporter().importContact(optionsMock).then(null, function(err) {
expect(err).to.deep.equal(errorMessage);
done();
});
});
it('should send multiple request to google server to get all contacts', function(done) {
var count = 0;
requestMock = function(option, callback) {
var defaultUrl = 'https://www.google.com/m8/feeds/contacts/default/full?max-results=50';
var url = count > 0 ? defaultUrl + '&start-index=' + count * 50 : defaultUrl;
count++;
expect(option).to.deep.equal({
method: 'GET',
url: url,
headers: { 'GData-Version': '3.0', Authorization: 'Bearer 1234' }
});
if (count === 3) {
done();
}
callback(null, response, null);
};
mockery.registerMock('request', requestMock);
getImporter().importContact(optionsMock);
});
it('should reject if can not parse the response from google', function(done) {
var error = new Error('can not parse string');
xml2jsMock.parseString = function(body, callback) {
callback(error);
};
mockery.registerMock('xml2js', xml2jsMock);
getImporter().importContact(optionsMock).then(null, function(err) {
expect(err).to.deep.equal(error);
done();
});
});
it('should create contact if the response from google is correct', function(done) {
var count = 0;
dependencies['contact-import'].lib.import.createContact = function(json, opt) {
expect(opt).to.equal(optionsMock);
count++;
};
getImporter().importContact(optionsMock).then(function() {
expect(count).to.equal(12);
done();
});
});
it('should get all contact photo if gd:etag exist', function(done) {
var count = 0;
body.feed['openSearch:totalResults'] = [49];
var googleContactPhotoURL = 'https://www.google.com/m8/feeds/photos/media/';
var contactLink = [{
$: {
type: 'image/*',
'gd:etag': 1234,
href: googleContactPhotoURL
}
}];
body = {
feed: {
'openSearch:startIndex': [0],
'openSearch:totalResults': [49],
entry: [
{ id: 1, link: contactLink },
{ id: 2, link: contactLink },
{ id: 3, link: contactLink }
]
}
};
requestMock = function(option, callback) {
if (option.url === googleContactPhotoURL) {
count++;
callback(null, response, 'my photo');
} else {
callback(null, response, null);
}
};
mockery.registerMock('request', requestMock);
mockery.registerMock('xml2js', xml2jsMock);
getImporter().importContact(optionsMock).then(function() {
expect(count).to.equal(3);
done();
});
});
});
});