Add preliminary support for notifications api

This commit is contained in:
Ryan Kelly 2015-03-27 21:21:53 +11:00
Родитель 770d17876a
Коммит 43dc35c646
5 изменённых файлов: 212 добавлений и 2 удалений

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

@ -12,8 +12,9 @@
define([
'client/auth/api',
'client/token/api',
'client/profile/api'
], function (AuthAPI, TokenAPI, ProfileAPI) {
'client/profile/api',
'client/notifications/api'
], function (AuthAPI, TokenAPI, ProfileAPI, NotificationsAPI) {
'use strict';
/**
@ -95,6 +96,25 @@ define([
* });
*/
this.profile = new ProfileAPI(clientId, options);
/**
* Fetch notification events from the server. Implements {{#crossLink "NotificationsAPI"}}{{/crossLink}}.
* @property notifications
* @type {Object}
*
* @example
* var fxaRelierClient = new FxaRelierClient('<client_id>', {
* clientSecret: <client_secret>
* });
* fxaRelierClient.token.tradeCode(<code>)
* .then(function (token) {
* return fxaRelierClient.notifications.events(token);
* })
* .then(function (events) {
* // do something to handle the events.
* });
*/
this.notifications = new NotificationsAPI(options);
}
FxaRelierClient.prototype = {

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

@ -30,6 +30,12 @@ define([], function () {
* @type {String}
*/
DEFAULT_PROFILE_HOST: 'https://profile.accounts.firefox.com/v1',
/**
* Default notifications server url
* @property DEFAULT_NOTIFICATIONS_SERVER
* @type {String}
*/
DEFAULT_NOTIFICATIONS_SERVER: 'https://notifications.accounts.firefox.com/v1',
/**
* Sign in action
* @property SIGNIN_ACTION

112
client/notifications/api.js Normal file
Просмотреть файл

@ -0,0 +1,112 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
define([
'p-promise',
'client/lib/constants',
'client/lib/xhr'
], function (p, Constants, Xhr) {
/**
* @class NotificationAPI
* @constructor
* @param {Object} [options={}] - configuration
* @param {String} [options.notificationPos]
* Position at which to start reading events (defaults to head of stream)
* @param {String} [options.notificationsServer]
* Firefox Accounts Notifications Server url
*/
function NotificationsAPI(options) {
options = options || {};
if (options.notificationsPos) {
this._curPos = options.notificationsPos;
} else {
this._curPos = this.head();
}
this._notificationsServer = options.notifictionsServer || Constants.DEFAULT_NOTIFICATIONS_SERVER;
}
NotificationsAPI.prototype = {
/**
* Find the current head position in the event stream. See:
* https://github.com/mozilla/fxa-notification-server/blob/master/docs/api.md#get-v1eventshead
*
* @method head
* @param {String} token
* OAuth token for accessing the API
* @param {Object} [options={}] - configuration
* @param {String} [options.xhr]
* XMLHttpRequest compatible object to use to make the request.
* @returns {Promise}
* Response resolves to the reported head position.
*/
head: function (token, options) {
if (! token) {
return p.reject(new Error('token is required'));
}
if (! options.headers) {
options.headers = {};
}
options.headers.Authorization = 'Bearer ' + token;
var endpoint = this._notificationsServer + 'events/head';
return Xhr.get(endpoint, {}, options)
.then(function (res) {
return res.pos;
});
},
/**
* Read events from the notification stream. See:
* https://github.com/mozilla/fxa-notification-server/blob/master/docs/api.md#get-v1events
*
* @method events
* @param {String} token
* OAuth token for accessing the API
* @param {Object} [options={}] - configuration
* @param {String} [options.num]
* The number of events to fetch (default 1000)
* @param {String} [options.iss]
* Only fetch events from this issuer
* @param {String} [options.uid]
* Only fetch events relevant to this uid
* @param {String} [options.rid]
* Only fetch events relevant to this rid
* @param {String} [options.xhr]
* XMLHttpRequest compatible object to use to make the request.
* @returns {Promise}
* Response resolves to a list of events.
*/
events: function (token, options) {
if (! token) {
return p.reject(new Error('clientSecret is required'));
}
if (! options.headers) {
options.headers = {};
}
options.headers.Authorization = 'Bearer ' + token;
var endpoint = this._notificationsServer + 'events';
endpoint += '?pos=' + this._curPos;
if (options.iss) {
endpoint += '&iss=' + options.iss;
}
if (options.uid) {
endpoint += '&uid=' + options.uid;
}
if (options.rid) {
endpoint += '&rid=' + options.rid;
}
return Xhr.get(endpoint, {}, options)
.then(function (res) {
// Advance position for subsequent reads.
this._curPos = res.next_pos;
// Return the events.
return res.events;
});
}
};
return NotificationsAPI;
});

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

@ -0,0 +1,71 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
define([
'intern!bdd',
'intern/chai!assert',
'tests/addons/responder',
'client/notifications/api',
'client/lib/constants'
], function (bdd, assert, Responder, NotificationsAPI, Constants) {
'use strict';
bdd.describe('NotificationsAPI', function () {
var api;
var responder;
bdd.beforeEach(function () {
api = new NotificationsAPI({
notificationsPos: '0'
});
responder = new Responder();
});
bdd.afterEach(function () {
responder.restore();
});
bdd.describe('head', function () {
bdd.it('fetches and returns the head position in the stream', function () {
var endpoint = Constants.DEFAULT_NOTIFICATIONS_SERVER + 'events/head';
var mockXHR = responder.respondWith('GET', endpoint, {
body: JSON.stringify({
pos: '2'
})
});
return api.head('token', {
xhr: mockXHR
})
.then(function (pos) {
assert.equal(pos, '2');
});
});
});
bdd.describe('events', function () {
bdd.it('fetches events from current position in the stream', function () {
var endpoint = Constants.DEFAULT_NOTIFICATIONS_SERVER + 'events';
endpoint += '?pos=0';
var mockXHR = responder.respondWith('GET', endpoint, {
body: JSON.stringify({
next_pos: '3',
events: ['event0', 'event1', 'event2']
})
});
return api.events('token', {
xhr: mockXHR
})
.then(function (events) {
assert.equal(events.length, 3);
assert.equal(events[0], 'event0');
assert.equal(events[1], 'event1');
assert.equal(events[2], 'event2');
});
});
});
});
});

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

@ -11,5 +11,6 @@ define([
'./spec/auth/lightbox/lightbox',
'./spec/token/api',
'./spec/profile/api',
'./spec/notifications/api',
'./spec/lib/xhr'
], function () {});