Skip to content

Commit

Permalink
#286 redux-ify notification
Browse files Browse the repository at this point in the history
  • Loading branch information
prayerslayer committed Sep 22, 2015
1 parent 79bd6bf commit 069fb9c
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 64 deletions.
5 changes: 0 additions & 5 deletions client/lib/common/src/data/notification/action-types.js

This file was deleted.

12 changes: 0 additions & 12 deletions client/lib/common/src/data/notification/actions.js

This file was deleted.

43 changes: 43 additions & 0 deletions client/lib/common/src/data/notification/notification-actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// import {createAction} from 'redux-actions';
// import * as Type from './notification-types';
import {Actions} from 'flummox';

function _addNotification(message, type) {
return [message, type];
}

function _removeNotification(id) {
return id;
}

function _removeNotificationsOlderThan(ms) {
return ms;
}


class NotificationActions extends Actions {

addNotification(message, type) {
return _addNotification(message, type);
}

removeNotification(id) {
return _removeNotification(id);
}

removeNotificationsOlderThan(ms) {
return _removeNotificationsOlderThan(ms);
}
}

export default NotificationActions;

// let addNotification = createAction(Type.ADD),
// removeNotification = createAction(Type.REMOVE),
// removeNotificationsOlderThan = createAction(Type.REMOVE_OLD);

// export {
// addNotification as addNotification,
// removeNotification as removeNotification,
// removeNotificationsOlderThan as removeNotificationsOlderThan
// };
102 changes: 102 additions & 0 deletions client/lib/common/src/data/notification/notification-store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/** global Date */
import uniq from 'uniqueid';
import * as Type from './notification-types';
import {Store} from 'flummox';

function NotificationStore(notifications = [], action) {
if (!action) {
return notifications;
}

if (action.type === Type.ADD_NOTIFICATION) {
// add
let [message, type] = action.payload;
notifications = notifications.concat([{
type: type || 'default',
message: message,
id: uniq(),
created: Date.now()
}]);
} else if (action.type === Type.REMOVE_NOTIFICATION) {
// remove
let id = action.payload;
notifications = notifications.filter(n => n.id !== id);
} else if (action.type === Type.REMOVE_NOTIFICATIONS_OLDER_THAN) {
// remove old
let now = Date.now(),
ms = action.payload;
notifications = notifications.filter(n => n.created > (now - ms));
}
return notifications;
}

export {
NotificationStore as NotificationStore
};

export default class NotificationStoreWrapper extends Store {
constructor(flux) {
super();

const notificationActions = flux.getActions('notification');

this._empty();

this.register(notificationActions.addNotification, this.receiveNotification);
this.register(notificationActions.removeNotification, this.deleteNotification);
this.register(notificationActions.removeNotificationsOlderThan, this.deleteOldNotifications);
}

/**
* Saves notification.
*/
receiveNotification([message, type]) {
this.setState({
redux: NotificationStore(this.state.redux, {
type: Type.ADD_NOTIFICATION,
payload: [message, type]
})
});
}

/**
* Removes notification with `id`.
*
* @param {number} id The ID of the notification
*/
deleteNotification(id) {
this.setState({
redux: NotificationStore(this.state.redux, {
type: Type.REMOVE_NOTIFICATION,
payload: id
})
});
}

/**
* Removes notifications older than `ms` ms.
*
* @param {number} ms The age of the notification in ms.
*/
deleteOldNotifications(ms) {
this.setState({
redux: NotificationStore(this.state.redux, {
type: Type.REMOVE_NOTIFICATIONS_OLDER_THAN,
payload: ms
})
});
}

/**
* Returns all notifications.
*/
getNotifications() {
return this.state.redux;
}

_empty() {
this.setState({
redux: NotificationStore()
});
}
}
10 changes: 10 additions & 0 deletions client/lib/common/src/data/notification/notification-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const TYPES = [
'ADD_NOTIFICATION',
'REMOVE_NOTIFICATION',
'REMOVE_NOTIFICATIONS_OLDER_THAN'
];

export default TYPES.reduce((obj, t) => {
obj[t] = t;
return obj;
}, {});
26 changes: 0 additions & 26 deletions client/lib/common/src/data/notification/store.js

This file was deleted.

87 changes: 66 additions & 21 deletions client/lib/common/test/notification/notification-store.test.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,78 @@
/* globals expect */
import Store from 'common/src/data/notification/store';
import * as Action from 'common/src/data/notification/actions';
import Type from 'common/src/data/notification/action-types';
import {Flummox} from 'flummox';
import StoreWrapper, {NotificationStore} from 'common/src/data/notification/notification-store';
import NotificationActions from 'common/src/data/notification/notification-actions';
import * as Type from 'common/src/data/notification/notification-types';

const FLUX_ID = 'notification';

class MockFlux extends Flummox {
constructor() {
super();

this.createActions(FLUX_ID, NotificationActions);
this.createStore(FLUX_ID, StoreWrapper, this);
}
}

describe('The redux notification store', () => {
it('should return an empty array without action', () => {
let state = NotificationStore();
expect(state.length).to.be.defined;
expect(state.length).to.equal(0);
});

it('should receive a notification', () => {
let state = NotificationStore([], {
type: Type.ADD_NOTIFICATION,
payload: ['Hello']
});
expect(state.length).equals(1);

let msg = state[0];
expect(msg.type).to.equal('default');
expect(msg.created).to.be.defined;
expect(msg.message).to.equal('Hello');
});
});

describe('The notification store', () => {
var store,
flux = new MockFlux();

beforeEach(() => {
store = flux.getStore(FLUX_ID);
});

afterEach(() => {
store._empty();
});

it('should receive a notification', () => {
let msgs = Store([], Action.addNotification('Test message'));
store.receiveNotification(['Hello']);
let msgs = store.getNotifications();
expect(msgs.length).to.equal(1);

let msg = msgs[0];
expect(msg.type).to.equal('default');
expect(msg.id).to.equal(1);
expect(msg.created).to.be.defined;
expect(msg.message).to.equal('Test message');
expect(msg.message).to.equal('Hello');
});

it('should delete a notification by id', () => {
store.receiveNotification(['Test message']);
expect(store.getNotifications().length).to.equal(1);
let {id} = store.getNotifications()[0];
store.deleteNotification(id);
expect(store.getNotifications().length).to.equal(0);
});

// it('should delete a notification by id', () => {
// store.receiveNotification(['Test message']);
// let {id} = store.getNotifications()[0];
// store.deleteNotification(id);
// expect(store.getNotifications().length).to.equal(0);
// });

// it('should delete old notifications', done => {
// store.receiveNotification(['Test message']);
// setTimeout(() => {
// store.deleteOldNotifications(50);
// expect(store.getNotifications().length).to.equal(0);
// done();
// }, 70);
// });
it('should delete old notifications', done => {
store.receiveNotification(['Test message']);
setTimeout(() => {
store.deleteOldNotifications(50);
expect(store.getNotifications().length).to.equal(0);
done();
}, 70);
});
});

0 comments on commit 069fb9c

Please sign in to comment.