Add preliminary support for notifications api
This commit is contained in:
Родитель
770d17876a
Коммит
43dc35c646
|
@ -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
|
||||
|
|
|
@ -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 () {});
|
||||
|
|
Загрузка…
Ссылка в новой задаче