Merge branch 'release-0.7.5' into dev

This commit is contained in:
Andre Rodrigues 2013-05-15 01:10:40 +01:00
Родитель 5bc8721762 1718f03f82
Коммит b6fa4c48aa
9 изменённых файлов: 1275 добавлений и 655 удалений

Просмотреть файл

@ -94,21 +94,20 @@ ApnsService.prototype.send = function (tags, payload, callback) {
/**
* Creates a native registration.
*
* @param {string} token The device token.
* @param {object|function} [optionsOrCallback] The request options or callback function.
* @param {function(error, response)} callback The callback function.
* @param {string} token The device token.
* @param {string|array} tags The tags.
* @param {object|function} [optionsOrCallback] The request options or callback function.
* @param {string} [optionsOrCallback.registrationId] The registration identifier.
* @param {function(error, response)} callback The callback function.
* @return {undefined}
*/
ApnsService.prototype.createNativeRegistration = function (token, optionsOrCallback, callback) {
ApnsService.prototype.createNativeRegistration = function (token, tags, optionsOrCallback, callback) {
var options;
azureutil.normalizeArgs(optionsOrCallback, callback, function (o, c) { options = o; callback = c; });
validate.isValidFunction(callback);
var registrationXml = registrationResult.serialize('AppleRegistrationDescription', {
DeviceToken: token
});
var registrationXml = this._createBody('AppleRegistrationDescription', token, tags, null, options);
var webResource = WebResource.post(this.notificationHubService.hubName + '/registrations');
this.notificationHubService._executeRequest(webResource, registrationXml, registrationResult, null, callback);
@ -200,8 +199,8 @@ ApnsService.prototype.listRegistrationsByToken = function (token, optionsOrCallb
validate.isValidFunction(callback);
var webResource = WebResource.get(this.hubName + '/registrations/')
.withQueryOption('$filter', 'deviceToken eq \'' + token + '\'');
var webResource = WebResource.get(this.notificationHubService.hubName + '/registrations/')
.withQueryOption('$filter', 'DeviceToken eq \'' + token.toUpperCase() + '\'');
if (options) {
if (options.top) {
@ -213,42 +212,66 @@ ApnsService.prototype.listRegistrationsByToken = function (token, optionsOrCallb
}
}
this._executeRequest(webResource, null, registrationResult, null, callback);
this.notificationHubService._executeRequest(webResource, null, registrationResult, null, callback);
};
/**
* Creates a template registration body.
*
* @param {string} token The device token.
* @param {json} template The template for the registration.
* @param {string} elementName The element name.
* @param {string} token The device token.
* @param {string|array} tags The tags.
* @return {string} The template body.
*/
ApnsService.prototype._createTemplateBody = function (token, tags, template) {
var registration = {
DeviceToken: token
};
ApnsService.prototype._createBody = function (elementName, token, tags, template) {
var registration = {};
var payload = _.clone(template);
if (payload.payload) {
Object.keys(payload.payload).forEach(function (property) {
payload[property] = payload.payload[property];
});
if (tags) {
if (_.isArray(tags)) {
tags = tags.join(',');
}
delete payload.payload;
registration.Tags = tags;
}
if (payload.expiry) {
registration['Expiry'] = payload.expiry;
delete payload.expiry;
registration.DeviceToken = token;
if (template) {
var payload = _.clone(template);
if (payload.payload) {
Object.keys(payload.payload).forEach(function (property) {
payload[property] = payload.payload[property];
});
delete payload.payload;
}
if (payload.expiry) {
registration['Expiry'] = payload.expiry;
delete payload.expiry;
}
if (!_.isString(payload)) {
payload = JSON.stringify({ aps: payload });
}
registration.BodyTemplate = '<![CDATA[' + payload + ']]>';
}
if (!_.isString(payload)) {
payload = JSON.stringify({ aps: payload });
}
return registrationResult.serialize(elementName, registration);
};
registration['BodyTemplate'] = '<![CDATA[' + payload + ']]>';
return registrationResult.serialize('AppleTemplateRegistrationDescription', registration);
/**
* Creates a template registration body.
*
* @param {string} token The device token.
* @param {string|array} tags The tags.
* @param {json} template The template for the registration.
* @param {object|function} [options] The request options or callback function.
* @return {string} The template body.
*/
ApnsService.prototype._createTemplateBody = function (token, tags, template, options) {
return this._createBody('AppleTemplateRegistrationDescription', token, tags, template, options);
};
module.exports = ApnsService;

Просмотреть файл

@ -339,30 +339,18 @@ WnsService.prototype.send = function (tags, payload, type, optionsOrCallback, ca
* Sends an APNS notification.
*
* @param {string} channel The device channel uri.
* @param {string|array} tags The tags.
* @param {object|function} [optionsOrCallback] The request options or callback function.
* @param {string} [optionsOrCallback.registrationId] The registration identifier.
* @param {function(error, response)} callback The callback function.
* @return {undefined}
*/
WnsService.prototype.createNativeRegistration = function (channel, optionsOrCallback, callback) {
WnsService.prototype.createNativeRegistration = function (channel, tags, optionsOrCallback, callback) {
var options;
azureutil.normalizeArgs(optionsOrCallback, callback, function (o, c) { options = o; callback = c; });
validate.isValidFunction(callback);
var registration = {
ChannelUri: channel
};
var registrationXml;
if (options && options.registrationId) {
registrationXml = registrationResult.serialize('WindowsRegistrationDescription', registration, {
id: 'https://ciserversb.servicebus.windows.net/' + this.notificationHubService.hubName + '/Registrations/' + options.registrationId,
title: options.registrationId
});
} else {
registrationXml = registrationResult.serialize('WindowsRegistrationDescription', registration);
}
var registrationXml = this._createBody('WindowsRegistrationDescription', channel, tags, null, options);
var webResource = WebResource.post(this.notificationHubService.hubName + '/registrations')
.withHeader(HeaderConstants.CONTENT_TYPE, 'application/atom+xml;type=entry;charset=utf-8')
@ -449,8 +437,8 @@ WnsService.prototype.listRegistrationsByChannel = function (channel, optionsOrCa
validate.isValidFunction(callback);
var webResource = WebResource.get(this.hubName + '/registrations/')
.withQueryOption('$filter', 'ChannelUri eq \'' + encodeURIComponent(channel) + '\'');
var webResource = WebResource.get(this.notificationHubService.hubName + '/registrations/')
.withQueryOption('$filter', 'ChannelUri eq \'' + channel + '\'');
if (options) {
if (options.top) {
@ -462,31 +450,25 @@ WnsService.prototype.listRegistrationsByChannel = function (channel, optionsOrCa
}
}
this._executeRequest(webResource, null, registrationResult, null, callback);
this.notificationHubService._executeRequest(webResource, null, registrationResult, null, callback);
};
/**
* Creates a template registration body.
*
* @param {string} elementName The element name.
* @param {string} channel The device channel uri.
* @param {string|array} tags The device channel uri.
* @param {string|array} tags The tags.
* @param {json} template The template for the registration.
* @param {object|function} [options] The request options or callback function.
* @param {object|function} [options.pnsCredentialName] The pns credentials to use.
* @param {object|function} [options.headers] The wns headers to include.
* @return {undefined}
*/
WnsService.prototype._createTemplateBody = function (channel, tags, template, options) {
var registration = {
ChannelUri: channel,
BodyTemplate: '<![CDATA[' + template + ']]>'
};
WnsService.prototype._createBody = function (elementName, channel, tags, template, options) {
var registration = { };
if (options) {
if (options.pnsCredentialName) {
registration['PnsCredentialName'] = options.pnsCredentialName;
}
if (options.expirationTime) {
if (_.isDate(options.expirationTime)) {
options.expirationTime = new Date(options.expirationTime);
@ -495,27 +477,60 @@ WnsService.prototype._createTemplateBody = function (channel, tags, template, op
registration['ExpirationTime'] = options.expirationTime.toISOString();
}
if (options.headers) {
registration['WnsHeaders'] = [];
Object.keys(options.headers).forEach(function (headerName) {
registration['WnsHeaders'].push({ WnsHeader: { Header: headerName, Value: options.headers[headerName] } });
});
}
if (tags) {
if (_.isArray(tags)) {
tags = tags.join(',');
}
if (!registration['WnsHeaders']) {
registration['WnsHeaders'] = [];
}
registration['WnsHeaders'].push({ WnsHeader: { Header: 'X-WNS-Tag', Value: tags } });
if (options.pnsCredentialName) {
registration['PnsCredentialName'] = options.pnsCredentialName;
}
}
return registrationResult.serialize('WindowsTemplateRegistrationDescription', registration);
if (tags) {
if (_.isArray(tags)) {
tags = tags.join(',');
}
registration.Tags = tags;
}
registration.ChannelUri = channel;
if (template) {
registration.BodyTemplate = '<![CDATA[' + template + ']]>';
}
if (options) {
if (options.headers) {
registration.WnsHeaders = { WnsHeader: [] };
Object.keys(options.headers).forEach(function (headerName) {
registration.WnsHeaders.WnsHeader.push({ Header: headerName, Value: options.headers[headerName] });
});
}
}
var registrationXml;
if (options && options.registrationId) {
registrationXml = registrationResult.serialize(elementName, registration, {
id: 'https://ciserversb.servicebus.windows.net/' + this.notificationHubService.hubName + '/Registrations/' + options.registrationId,
title: options.registrationId
});
} else {
registrationXml = registrationResult.serialize(elementName, registration);
}
return registrationXml;
};
/**
* Creates a template registration body.
*
* @param {string} channel The device channel uri.
* @param {string|array} tags The tags.
* @param {json} template The template for the registration.
* @param {object|function} [options] The request options or callback function.
* @param {object|function} [options.pnsCredentialName] The pns credentials to use.
* @param {object|function} [options.headers] The wns headers to include.
* @return {undefined}
*/
WnsService.prototype._createTemplateBody = function (channel, tags, template, options) {
return this._createBody('WindowsTemplateRegistrationDescription', channel, tags, template, options);
};
module.exports = WnsService;

Просмотреть файл

@ -153,12 +153,14 @@ OdataHandler.prototype._setProperty = function (entity, propertyName, value, typ
* - { stringValue: 'my string', myInt: 3 }
*/
OdataHandler.prototype.serialize = function (entity, skipType) {
var self = this;
var properties = {};
Object.keys(entity).forEach(function (name) {
if (name !== '_') {
properties[OdataHandler.NSDATA + ':' + name] = { };
properties[OdataHandler.NSDATA + ':' + name][Constants.XML_METADATA_MARKER] = {};
var propertyName = self._xmlQualifyXmlTagName(name, self.nsData);
properties[propertyName] = { };
properties[propertyName][Constants.XML_METADATA_MARKER] = {};
var propertyType = null;
var propertyValue = null;
@ -183,16 +185,19 @@ OdataHandler.prototype.serialize = function (entity, skipType) {
properties[OdataHandler.NSDATA + ':' + name][Constants.XML_VALUE_MARKER] = propertyValue;
if (!skipType && propertyType !== null) {
properties[OdataHandler.NSDATA + ':' + name][Constants.XML_METADATA_MARKER][OdataHandler.NSMETA + ':type'] = propertyType;
properties[OdataHandler.NSDATA + ':' + name][Constants.XML_METADATA_MARKER][self._xmlQualifyXmlTagName('type', self.nsMeta)] = propertyType;
}
if (azureutil.stringIsEmpty(propertyValue)) {
properties[OdataHandler.NSDATA + ':' + name][Constants.XML_METADATA_MARKER][OdataHandler.NSMETA + ':null'] = true;
properties[OdataHandler.NSDATA + ':' + name][Constants.XML_METADATA_MARKER][self._xmlQualifyXmlTagName('null', self.nsMeta)] = true;
}
}
});
return atomHandler.serializeEntry({ 'm:properties': properties }, [
var content = {};
content[self._xmlQualifyXmlTagName('properties', self.nsMeta)] = properties;
return atomHandler.serializeEntry(content, [
{
key: OdataHandler.NSDATA,
url: 'http://schemas.microsoft.com/ado/2007/08/dataservices'

Просмотреть файл

@ -58,7 +58,7 @@ suite('azure', function () {
}
if (!originalAzureStorageDnsSuffix && process.env[ServiceClient.EnvironmentVariables.AZURE_STORAGE_DNS_SUFFIX]) {
originalAzureStorageDnsSuffix = process.env[ServiceClient.EnvironmentVariables.AZURE_STORAGE_DNS_SUFFIX];
originalAzureStorageDnsSuffix = process.env[ServiceClient.EnvironmentVariables.AZURE_STORAGE_DNS_SUFFIX];
}
// On the first run store the previous azure storage account / azure storage access key from the environment
if (!originalServiceBusNamespace && process.env[ServiceClient.EnvironmentVariables.AZURE_SERVICEBUS_NAMESPACE]) {

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -104,7 +104,7 @@ describe('APNS notifications registrations', function () {
});
it('should work', function (done) {
notificationHubService.apns.createNativeRegistration(tokenId, function (error, registration) {
notificationHubService.apns.createNativeRegistration(tokenId, null, function (error, registration) {
should.not.exist(error);
registrationId = registration.RegistrationId;
@ -112,6 +112,52 @@ describe('APNS notifications registrations', function () {
});
});
});
describe('list', function () {
beforeEach(function (done) {
notificationHubService.apns.createNativeRegistration(tokenId, [ 'mytag'], done);
});
it('should work without filtering', function (done) {
notificationHubService.listRegistrations(function (err, list) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(1);
done();
});
});
it('should work with tag filtering with the wrong tag', function (done) {
notificationHubService.listRegistrationsByTag('tag', { top: 10, skip: 0 }, function (err, list) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(0);
done();
});
});
it('should work with tag filtering with the right tag', function (done) {
notificationHubService.listRegistrationsByTag('mytag', { top: 10, skip: 0 }, function (err, list) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(1);
done();
});
});
it('should work with token filtering', function (done) {
notificationHubService.apns.listRegistrationsByToken(tokenId, { top: 10, skip: 0 }, function (err, list, rsp) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(1);
done();
});
});
});
});
describe('template', function () {
@ -153,7 +199,7 @@ describe('APNS notifications registrations', function () {
registrationId = registration.RegistrationId;
done();
});
});
});
afterEach(function (done) {
@ -172,7 +218,7 @@ describe('APNS notifications registrations', function () {
should.not.exist(error);
done();
});
});
});
});
});

Просмотреть файл

@ -17,7 +17,6 @@ var _ = require('underscore');
var should = require('should');
var sinon = require('sinon');
var fs = require('fs');
// Test includes
var testutil = require('../../util/util');
@ -110,7 +109,7 @@ describe('Notification hubs', function () {
ApnsCertificate: 'secret1',
CertificateKey: 'secret2'
}
}
};
sandbox.stub(service, '_executeRequest', function (webResource, payload, resultHandler, validators, callback) {
payload.should.include('<WnsCredential><Properties><Property><Name>PackageSid</Name><Value>secret1</Value></Property>' +
@ -248,34 +247,34 @@ describe('Notification hubs', function () {
}
},
function () {
var setupHub = function () {
service.getNotificationHub(hubName, function (err, hub) {
if (err) {
setupHub();
} else {
var fullRule = hub.AuthorizationRules.AuthorizationRule.filter(function (rule) {
return rule.KeyName === 'DefaultFullSharedAccessSignature';
})[0];
var setupHub = function () {
service.getNotificationHub(hubName, function (err, hub) {
if (err) {
setupHub();
} else {
var fullRule = hub.AuthorizationRules.AuthorizationRule.filter(function (rule) {
return rule.KeyName === 'DefaultFullSharedAccessSignature';
})[0];
var endpoint = 'https://' + process.env.AZURE_SERVICEBUS_NAMESPACE + '.servicebus.windows.net';
notificationHubService = azure.createNotificationHubService(hubName, endpoint, fullRule.KeyName, fullRule.PrimaryKey);
suiteUtil.setupService(notificationHubService);
var endpoint = 'https://' + process.env.AZURE_SERVICEBUS_NAMESPACE + '.servicebus.windows.net';
notificationHubService = azure.createNotificationHubService(hubName, endpoint, fullRule.KeyName, fullRule.PrimaryKey);
suiteUtil.setupService(notificationHubService);
var listenRule = hub.AuthorizationRules.AuthorizationRule.filter(function (rule) {
return rule.KeyName === 'DefaultListenSharedAccessSignature';
})[0];
var listenRule = hub.AuthorizationRules.AuthorizationRule.filter(function (rule) {
return rule.KeyName === 'DefaultListenSharedAccessSignature';
})[0];
var endpoint = 'https://' + process.env.AZURE_SERVICEBUS_NAMESPACE + '.servicebus.windows.net';
notificationListenHubService = azure.createNotificationHubService(hubName, endpoint, listenRule.KeyName, listenRule.PrimaryKey);
suiteUtil.setupService(notificationListenHubService);
endpoint = 'https://' + process.env.AZURE_SERVICEBUS_NAMESPACE + '.servicebus.windows.net';
notificationListenHubService = azure.createNotificationHubService(hubName, endpoint, listenRule.KeyName, listenRule.PrimaryKey);
suiteUtil.setupService(notificationListenHubService);
done();
}
});
};
done();
}
});
};
setupHub();
});
setupHub();
});
});
it('should be able to execute an operation', function (done) {
@ -325,7 +324,7 @@ describe('Notification hubs', function () {
done();
});
});
});
});
});

Просмотреть файл

@ -93,7 +93,7 @@ describe('WNS notifications registrations', function () {
});
it('should work', function (done) {
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', { registrationId: 'myname' }, function (error, registration) {
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', null, { registrationId: 'myname' }, function (error, registration) {
should.not.exist(error);
registrationId = registration.RegistrationId;
@ -106,7 +106,7 @@ describe('WNS notifications registrations', function () {
var registrationId;
beforeEach(function (done) {
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', function (err, registration) {
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', null, function (err, registration) {
registrationId = registration.RegistrationId;
done();
@ -126,7 +126,7 @@ describe('WNS notifications registrations', function () {
var registrationId;
beforeEach(function (done) {
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', function (err, registration) {
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', null, function (err, registration) {
registrationId = registration.RegistrationId;
done();
@ -146,14 +146,8 @@ describe('WNS notifications registrations', function () {
});
describe('list', function () {
var registrationId;
beforeEach(function (done) {
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', function (err, registration) {
registrationId = registration.RegistrationId;
done();
});
notificationHubService.wns.createNativeRegistration('http://db3.notify.windows.com/fake/superfake', [ 'mytag'], done);
});
it('should work without filtering', function (done) {
@ -166,8 +160,8 @@ describe('WNS notifications registrations', function () {
});
});
it('should work with tag filtering', function (done) {
notificationHubService.listRegistrationsByTag('tag', function (err, list) {
it('should work with tag filtering with the wrong tag', function (done) {
notificationHubService.listRegistrationsByTag('tag', { top: 10, skip: 0 }, function (err, list) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(0);
@ -175,6 +169,26 @@ describe('WNS notifications registrations', function () {
done();
});
});
it('should work with tag filtering with the right tag', function (done) {
notificationHubService.listRegistrationsByTag('mytag', { top: 10, skip: 0 }, function (err, list) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(1);
done();
});
});
it('should work with channel filtering', function (done) {
notificationHubService.wns.listRegistrationsByChannel('http://db3.notify.windows.com/fake/superfake', { top: 10, skip: 0 }, function (err, list, rsp) {
should.not.exist(err);
should.exist(list);
list.length.should.equal(1);
done();
});
});
});
});