Merge branch 'reducer-records' into 'develop'
Refactor some reducers with Immutable.Record See merge request soapbox-pub/soapbox-fe!1093
This commit is contained in:
commit
6be0b61569
|
@ -0,0 +1,17 @@
|
||||||
|
import { Record as ImmutableRecord, fromJS } from 'immutable';
|
||||||
|
|
||||||
|
import { normalizeNotification } from '../notification';
|
||||||
|
|
||||||
|
describe('normalizeNotification()', () => {
|
||||||
|
it('normalizes an empty map', () => {
|
||||||
|
const notification = fromJS({});
|
||||||
|
const result = normalizeNotification(notification);
|
||||||
|
|
||||||
|
expect(ImmutableRecord.isRecord(result)).toBe(true);
|
||||||
|
expect(result.type).toEqual('');
|
||||||
|
expect(result.account).toBe(null);
|
||||||
|
expect(result.target).toBe(null);
|
||||||
|
expect(result.status).toBe(null);
|
||||||
|
expect(result.id).toEqual('');
|
||||||
|
});
|
||||||
|
});
|
|
@ -60,7 +60,7 @@ const InstanceRecord = ImmutableRecord({
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build Mastodon configuration from Pleroma instance
|
// Build Mastodon configuration from Pleroma instance
|
||||||
const pleromaToMastodonConfig = instance => {
|
const pleromaToMastodonConfig = (instance: ImmutableMap<string, any>) => {
|
||||||
return ImmutableMap({
|
return ImmutableMap({
|
||||||
statuses: ImmutableMap({
|
statuses: ImmutableMap({
|
||||||
max_characters: instance.get('max_toot_chars'),
|
max_characters: instance.get('max_toot_chars'),
|
||||||
|
@ -75,10 +75,10 @@ const pleromaToMastodonConfig = instance => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the software's default attachment limit
|
// Get the software's default attachment limit
|
||||||
const getAttachmentLimit = software => software === PLEROMA ? Infinity : 4;
|
const getAttachmentLimit = (software: string) => software === PLEROMA ? Infinity : 4;
|
||||||
|
|
||||||
// Normalize instance (Pleroma, Mastodon, etc.) to Mastodon's format
|
// Normalize instance (Pleroma, Mastodon, etc.) to Mastodon's format
|
||||||
export const normalizeInstance = instance => {
|
export const normalizeInstance = (instance: ImmutableMap<string, any>) => {
|
||||||
const { software } = parseVersion(instance.get('version'));
|
const { software } = parseVersion(instance.get('version'));
|
||||||
const mastodonConfig = pleromaToMastodonConfig(instance);
|
const mastodonConfig = pleromaToMastodonConfig(instance);
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import {
|
||||||
|
Map as ImmutableMap,
|
||||||
|
Record as ImmutableRecord,
|
||||||
|
} from 'immutable';
|
||||||
|
|
||||||
|
// https://docs.joinmastodon.org/entities/notification/
|
||||||
|
const NotificationRecord = ImmutableRecord({
|
||||||
|
account: null,
|
||||||
|
chat_message: null, // pleroma:chat_mention
|
||||||
|
created_at: new Date(),
|
||||||
|
emoji: null, // pleroma:emoji_reaction
|
||||||
|
id: '',
|
||||||
|
status: null,
|
||||||
|
target: null, // move
|
||||||
|
type: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const normalizeNotification = (notification: ImmutableMap<string, any>) => {
|
||||||
|
return NotificationRecord(notification);
|
||||||
|
};
|
|
@ -11,7 +11,7 @@ import { IStatus } from 'soapbox/types';
|
||||||
import { mergeDefined, makeEmojiMap } from 'soapbox/utils/normalizers';
|
import { mergeDefined, makeEmojiMap } from 'soapbox/utils/normalizers';
|
||||||
|
|
||||||
const StatusRecord = ImmutableRecord({
|
const StatusRecord = ImmutableRecord({
|
||||||
account: ImmutableMap(),
|
account: null,
|
||||||
application: null,
|
application: null,
|
||||||
bookmarked: false,
|
bookmarked: false,
|
||||||
card: null,
|
card: null,
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
import {
|
import { Record as ImmutableRecord } from 'immutable';
|
||||||
Map as ImmutableMap,
|
|
||||||
List as ImmutableList,
|
|
||||||
OrderedSet as ImmutableOrderedSet,
|
|
||||||
} from 'immutable';
|
|
||||||
|
|
||||||
import reducer from '../admin';
|
import reducer from '../admin';
|
||||||
|
|
||||||
describe('admin reducer', () => {
|
describe('admin reducer', () => {
|
||||||
it('should return the initial state', () => {
|
it('should return the initial state', () => {
|
||||||
expect(reducer(undefined, {})).toEqual(ImmutableMap({
|
const result = reducer(undefined, {});
|
||||||
reports: ImmutableMap(),
|
expect(ImmutableRecord.isRecord(result)).toBe(true);
|
||||||
openReports: ImmutableOrderedSet(),
|
expect(result.needsReboot).toBe(false);
|
||||||
users: ImmutableMap(),
|
|
||||||
latestUsers: ImmutableOrderedSet(),
|
|
||||||
awaitingApproval: ImmutableOrderedSet(),
|
|
||||||
configs: ImmutableList(),
|
|
||||||
needsReboot: false,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { Record as ImmutableRecord, List as ImmutableList } from 'immutable';
|
||||||
|
|
||||||
import * as actions from 'soapbox/actions/alerts';
|
import {
|
||||||
|
ALERT_SHOW,
|
||||||
|
ALERT_DISMISS,
|
||||||
|
ALERT_CLEAR,
|
||||||
|
} from 'soapbox/actions/alerts';
|
||||||
|
import { applyActions } from 'soapbox/test_helpers';
|
||||||
|
|
||||||
import reducer from '../alerts';
|
import reducer from '../alerts';
|
||||||
|
|
||||||
|
@ -9,66 +14,65 @@ describe('alerts reducer', () => {
|
||||||
expect(reducer(undefined, {})).toEqual(ImmutableList());
|
expect(reducer(undefined, {})).toEqual(ImmutableList());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle ALERT_SHOW', () => {
|
describe('ALERT_SHOW', () => {
|
||||||
const state = ImmutableList([]);
|
it('imports the alert', () => {
|
||||||
const action = {
|
const action = {
|
||||||
type: actions.ALERT_SHOW,
|
type: ALERT_SHOW,
|
||||||
title: 'alert_title',
|
title: 'alert_title',
|
||||||
message: 'this is an alert message',
|
message: 'this is an alert message',
|
||||||
};
|
};
|
||||||
expect(reducer(state, action).toJS()).toMatchObject([
|
|
||||||
{
|
const expected = [{
|
||||||
key: 0,
|
key: 0,
|
||||||
message: 'this is an alert message',
|
message: 'this is an alert message',
|
||||||
title: 'alert_title',
|
title: 'alert_title',
|
||||||
},
|
}];
|
||||||
]);
|
|
||||||
|
const result = reducer(undefined, action);
|
||||||
|
expect(ImmutableRecord.isRecord(result.get(0))).toBe(true);
|
||||||
|
expect(result.toJS()).toMatchObject(expected);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should handle ALERT_DISMISS', () => {
|
describe('ALERT_CLEAR', () => {
|
||||||
// const state = ImmutableList([
|
it('deletes the alerts', () => {
|
||||||
// {
|
const actions = [{
|
||||||
// key: 0,
|
type: ALERT_SHOW,
|
||||||
// message: 'message_1',
|
title: 'Oops!',
|
||||||
// title: 'title_1',
|
message: 'Server is down',
|
||||||
// },
|
}, {
|
||||||
// {
|
type: ALERT_SHOW,
|
||||||
// key: 1,
|
title: 'Uh-oh!',
|
||||||
// message: 'message_2',
|
message: 'Shit done fucked up',
|
||||||
// title: 'title_2',
|
}, {
|
||||||
// },
|
type: ALERT_CLEAR,
|
||||||
// ]);
|
}];
|
||||||
// const action = {
|
|
||||||
// type: actions.ALERT_DISMISS,
|
|
||||||
// alert: { key: 0 },
|
|
||||||
// };
|
|
||||||
// expect(reducer(state, action).toJS()).toMatchObject([
|
|
||||||
// {
|
|
||||||
// key: 1,
|
|
||||||
// message: 'message_2',
|
|
||||||
// title: 'title_2',
|
|
||||||
// }
|
|
||||||
// ]);
|
|
||||||
// });
|
|
||||||
|
|
||||||
it('should handle ALERT_CLEAR', () => {
|
const result = applyActions(undefined, actions, reducer);
|
||||||
const state = ImmutableList([
|
expect(result.isEmpty()).toBe(true);
|
||||||
{
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ALERT_DISMISS', () => {
|
||||||
|
it('deletes an individual alert', () => {
|
||||||
|
const actions = [{
|
||||||
|
type: ALERT_SHOW,
|
||||||
|
title: 'Oops!',
|
||||||
|
message: 'Server is down',
|
||||||
|
}, {
|
||||||
|
type: ALERT_SHOW,
|
||||||
|
title: 'Uh-oh!',
|
||||||
|
message: 'Shit done fucked up',
|
||||||
|
}, {
|
||||||
|
type: ALERT_DISMISS,
|
||||||
|
alert: {
|
||||||
key: 0,
|
key: 0,
|
||||||
message: 'message_1',
|
|
||||||
title: 'title_1',
|
|
||||||
},
|
},
|
||||||
{
|
}];
|
||||||
key: 1,
|
|
||||||
message: 'message_2',
|
|
||||||
title: 'title_2',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
const action = {
|
|
||||||
type: actions.ALERT_CLEAR,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action).toJS()).toMatchObject({
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
const result = applyActions(undefined, actions, reducer);
|
||||||
|
expect(result.size).toEqual(1);
|
||||||
|
expect(result.get(0).key).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { Map as ImmutableMap } from 'immutable';
|
import { Record as ImmutableRecord } from 'immutable';
|
||||||
|
|
||||||
import reducer from '../meta';
|
import reducer from '../meta';
|
||||||
|
|
||||||
describe('meta reducer', () => {
|
describe('meta reducer', () => {
|
||||||
it('should return the initial state', () => {
|
it('should return the initial state', () => {
|
||||||
expect(reducer(undefined, {})).toEqual(ImmutableMap());
|
const result = reducer(undefined, {});
|
||||||
|
expect(ImmutableRecord.isRecord(result)).toBe(true);
|
||||||
|
expect(result.instance_fetch_failed).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
import { Map as ImmutableMap, OrderedMap as ImmutableOrderedMap, fromJS } from 'immutable';
|
import {
|
||||||
|
Map as ImmutableMap,
|
||||||
|
OrderedMap as ImmutableOrderedMap,
|
||||||
|
Record as ImmutableRecord,
|
||||||
|
} from 'immutable';
|
||||||
import { take } from 'lodash';
|
import { take } from 'lodash';
|
||||||
|
|
||||||
import intlMessages from 'soapbox/__fixtures__/intlMessages.json';
|
import intlMessages from 'soapbox/__fixtures__/intlMessages.json';
|
||||||
|
@ -24,27 +28,31 @@ import {
|
||||||
NOTIFICATIONS_MARK_READ_REQUEST,
|
NOTIFICATIONS_MARK_READ_REQUEST,
|
||||||
} from 'soapbox/actions/notifications';
|
} from 'soapbox/actions/notifications';
|
||||||
import { TIMELINE_DELETE } from 'soapbox/actions/timelines';
|
import { TIMELINE_DELETE } from 'soapbox/actions/timelines';
|
||||||
|
import { applyActions } from 'soapbox/test_helpers';
|
||||||
|
|
||||||
import reducer from '../notifications';
|
import reducer from '../notifications';
|
||||||
|
|
||||||
|
const initialState = reducer(undefined, {});
|
||||||
|
|
||||||
describe('notifications reducer', () => {
|
describe('notifications reducer', () => {
|
||||||
it('should return the initial state', () => {
|
it('should return the initial state', () => {
|
||||||
expect(reducer(undefined, {})).toEqual(ImmutableMap({
|
const expected = {
|
||||||
items: ImmutableOrderedMap(),
|
items: {},
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
top: false,
|
top: false,
|
||||||
unread: 0,
|
unread: 0,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
queuedNotifications: ImmutableOrderedMap(),
|
queuedNotifications: {},
|
||||||
totalQueuedNotificationsCount: 0,
|
totalQueuedNotificationsCount: 0,
|
||||||
lastRead: -1,
|
lastRead: -1,
|
||||||
}));
|
};
|
||||||
|
|
||||||
|
expect(ImmutableRecord.isRecord(initialState)).toBe(true);
|
||||||
|
expect(initialState.toJS()).toMatchObject(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('NOTIFICATIONS_EXPAND_SUCCESS', () => {
|
describe('NOTIFICATIONS_EXPAND_SUCCESS', () => {
|
||||||
it('imports the notifications', () => {
|
it('imports the notifications', () => {
|
||||||
const state = undefined;
|
|
||||||
|
|
||||||
const action = {
|
const action = {
|
||||||
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
||||||
notifications: take(notifications, 3),
|
notifications: take(notifications, 3),
|
||||||
|
@ -52,47 +60,17 @@ describe('notifications reducer', () => {
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
const result = reducer(undefined, action);
|
||||||
items: ImmutableOrderedMap([
|
|
||||||
['10744', ImmutableMap({
|
// The items are parsed as records
|
||||||
id: '10744',
|
expect(ImmutableOrderedMap.isOrderedMap(result.items)).toBe(true);
|
||||||
type: 'pleroma:emoji_reaction',
|
expect(ImmutableRecord.isRecord(result.items.get('10743'))).toBe(true);
|
||||||
account: '9vMAje101ngtjlMj7w',
|
|
||||||
target: null,
|
// We can get an item
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
expect(result.items.get('10744').emoji).toEqual('😢');
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: '😢',
|
// hasMore is set to false because `next` is null
|
||||||
chat_message: undefined,
|
expect(result.hasMore).toBe(false);
|
||||||
})],
|
|
||||||
['10743', ImmutableMap({
|
|
||||||
id: '10743',
|
|
||||||
type: 'favourite',
|
|
||||||
account: '9v5c6xSEgAi3Zu1Lv6',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
['10741', ImmutableMap({
|
|
||||||
id: '10741',
|
|
||||||
type: 'favourite',
|
|
||||||
account: '9v5cKMOPGqPcgfcWp6',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
]),
|
|
||||||
hasMore: false,
|
|
||||||
top: false,
|
|
||||||
unread: 0,
|
|
||||||
isLoading: false,
|
|
||||||
queuedNotifications: ImmutableOrderedMap(),
|
|
||||||
totalQueuedNotificationsCount: 0,
|
|
||||||
lastRead: -1,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('drops invalid notifications', () => {
|
it('drops invalid notifications', () => {
|
||||||
|
@ -109,200 +87,132 @@ describe('notifications reducer', () => {
|
||||||
skipLoading: true,
|
skipLoading: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const expected = ImmutableOrderedMap([
|
const result = reducer(undefined, action);
|
||||||
['4', fromJS({
|
|
||||||
id: '4',
|
|
||||||
type: 'mention',
|
|
||||||
account: '7',
|
|
||||||
target: null,
|
|
||||||
created_at: undefined,
|
|
||||||
status: 'a',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
]);
|
|
||||||
|
|
||||||
expect(reducer(undefined, action).get('items')).toEqual(expected);
|
// Only '4' is valid
|
||||||
|
expect(result.items.size).toEqual(1);
|
||||||
|
expect(result.items.get('4').id).toEqual('4');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_EXPAND_REQUEST', () => {
|
describe('NOTIFICATIONS_EXPAND_REQUEST', () => {
|
||||||
const state = ImmutableMap({
|
it('sets isLoading to true', () => {
|
||||||
isLoading: false,
|
const state = initialState.set('isLoading', false);
|
||||||
|
const action = { type: NOTIFICATIONS_EXPAND_REQUEST };
|
||||||
|
|
||||||
|
expect(reducer(state, action).isLoading).toBe(true);
|
||||||
});
|
});
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_EXPAND_REQUEST,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
isLoading: true,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_EXPAND_FAIL', () => {
|
describe('NOTIFICATIONS_EXPAND_FAIL', () => {
|
||||||
const state = ImmutableMap({
|
it('sets isLoading to false', () => {
|
||||||
isLoading: true,
|
const state = initialState.set('isLoading', true);
|
||||||
|
const action = { type: NOTIFICATIONS_EXPAND_FAIL };
|
||||||
|
|
||||||
|
expect(reducer(state, action).isLoading).toBe(false);
|
||||||
});
|
});
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_EXPAND_FAIL,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
isLoading: false,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_FILTER_SET', () => {
|
describe('NOTIFICATIONS_FILTER_SET', () => {
|
||||||
const state = ImmutableMap({
|
it('clears the items', () => {
|
||||||
items: ImmutableOrderedMap([
|
const actions = [{
|
||||||
['10744', ImmutableMap({
|
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
||||||
id: '10744',
|
notifications: [
|
||||||
type: 'pleroma:emoji_reaction',
|
{ id: '1', type: 'mention', status: { id: '4' }, account: { id: '7' } },
|
||||||
account: '9vMAje101ngtjlMj7w',
|
{ id: '2', type: 'mention', status: { id: '5' }, account: { id: '8' } },
|
||||||
target: null,
|
{ id: '3', type: 'mention', status: { id: '6' }, account: { id: '9' } },
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
],
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
next: null,
|
||||||
emoji: '😢',
|
skipLoading: true,
|
||||||
chat_message: undefined,
|
}, {
|
||||||
})],
|
|
||||||
['10743', ImmutableMap({
|
|
||||||
id: '10743',
|
|
||||||
type: 'favourite',
|
|
||||||
account: '9v5c6xSEgAi3Zu1Lv6',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
['10741', ImmutableMap({
|
|
||||||
id: '10741',
|
|
||||||
type: 'favourite',
|
|
||||||
account: '9v5cKMOPGqPcgfcWp6',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
]),
|
|
||||||
hasMore: false,
|
|
||||||
top: false,
|
|
||||||
unread: 1,
|
|
||||||
isLoading: false,
|
|
||||||
queuedNotifications: ImmutableOrderedMap(),
|
|
||||||
totalQueuedNotificationsCount: 0,
|
|
||||||
lastRead: -1,
|
|
||||||
});
|
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_FILTER_SET,
|
type: NOTIFICATIONS_FILTER_SET,
|
||||||
};
|
}];
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap(),
|
// Setup by expanding, then calling `NOTIFICATIONS_FILTER_SET`
|
||||||
hasMore: true,
|
const result = applyActions(initialState, actions, reducer);
|
||||||
top: false,
|
|
||||||
unread: 1,
|
// Setting the filter wipes notifications
|
||||||
isLoading: false,
|
expect(result.items.isEmpty()).toBe(true);
|
||||||
queuedNotifications: ImmutableOrderedMap(),
|
|
||||||
totalQueuedNotificationsCount: 0,
|
|
||||||
lastRead: -1,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_SCROLL_TOP by changing unread to 0 when top = true', () => {
|
it('sets hasMore to true', () => {
|
||||||
const state = ImmutableMap({
|
const state = initialState.set('hasMore', false);
|
||||||
unread: 1,
|
const action = { type: NOTIFICATIONS_FILTER_SET };
|
||||||
|
const result = reducer(state, action);
|
||||||
|
|
||||||
|
expect(result.hasMore).toBe(true);
|
||||||
});
|
});
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_SCROLL_TOP,
|
|
||||||
top: true,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
unread: 0,
|
|
||||||
top: true,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_SCROLL_TOP by not changing unread val when top = false', () => {
|
describe('NOTIFICATIONS_SCROLL_TOP', () => {
|
||||||
const state = ImmutableMap({
|
it('resets `unread` counter to 0 when top is true (ie, scrolled to the top)', () => {
|
||||||
unread: 3,
|
const state = initialState.set('unread', 1);
|
||||||
});
|
const action = { type: NOTIFICATIONS_SCROLL_TOP, top: true };
|
||||||
const action = {
|
const result = reducer(state, action);
|
||||||
type: NOTIFICATIONS_SCROLL_TOP,
|
|
||||||
top: false,
|
expect(result.unread).toEqual(0);
|
||||||
};
|
expect(result.top).toBe(true);
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
unread: 3,
|
|
||||||
top: false,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_UPDATE, when top = false, increment unread', () => {
|
it('leaves `unread` alone when top is false (ie, not scrolled to top)', () => {
|
||||||
const state = ImmutableMap({
|
const state = initialState.set('unread', 3);
|
||||||
items: ImmutableOrderedMap(),
|
const action = { type: NOTIFICATIONS_SCROLL_TOP, top: false };
|
||||||
top: false,
|
const result = reducer(state, action);
|
||||||
unread: 1,
|
|
||||||
|
expect(result.unread).toEqual(3);
|
||||||
|
expect(result.top).toBe(false);
|
||||||
});
|
});
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_UPDATE,
|
|
||||||
notification: notification,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap([
|
|
||||||
['10743', ImmutableMap({
|
|
||||||
id: '10743',
|
|
||||||
type: 'favourite',
|
|
||||||
account: '9v5c6xSEgAi3Zu1Lv6',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
]),
|
|
||||||
top: false,
|
|
||||||
unread: 2,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_UPDATE_QUEUE', () => {
|
describe('NOTIFICATIONS_UPDATE', () => {
|
||||||
const state = ImmutableMap({
|
it('imports the notification', () => {
|
||||||
items: ImmutableOrderedMap(),
|
const action = { type: NOTIFICATIONS_UPDATE, notification };
|
||||||
queuedNotifications: ImmutableOrderedMap(),
|
const result = reducer(initialState, action);
|
||||||
totalQueuedNotificationsCount: 0,
|
|
||||||
|
expect(result.items.get('10743').type).toEqual('favourite');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('increments `unread` counter when top is false', () => {
|
||||||
|
const action = { type: NOTIFICATIONS_UPDATE, notification };
|
||||||
|
const result = reducer(initialState, action);
|
||||||
|
|
||||||
|
expect(result.unread).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('NOTIFICATIONS_UPDATE_QUEUE', () => {
|
||||||
|
it('adds the notification to the queue (and increases the counter)', () => {
|
||||||
const action = {
|
const action = {
|
||||||
type: NOTIFICATIONS_UPDATE_QUEUE,
|
type: NOTIFICATIONS_UPDATE_QUEUE,
|
||||||
notification: notification,
|
notification,
|
||||||
intlMessages: intlMessages,
|
intlMessages,
|
||||||
intlLocale: 'en',
|
intlLocale: 'en',
|
||||||
};
|
};
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap(),
|
const result = reducer(initialState, action);
|
||||||
queuedNotifications: ImmutableOrderedMap([[notification.id, {
|
|
||||||
notification: notification,
|
// Doesn't add it as a regular item
|
||||||
intlMessages: intlMessages,
|
expect(result.items.isEmpty()).toBe(true);
|
||||||
intlLocale: 'en',
|
|
||||||
}]]),
|
// Adds it to the queued items
|
||||||
totalQueuedNotificationsCount: 1,
|
expect(result.queuedNotifications.size).toEqual(1);
|
||||||
}));
|
expect(result.totalQueuedNotificationsCount).toEqual(1);
|
||||||
|
expect(result.queuedNotifications.getIn(['10743', 'notification', 'type'])).toEqual('favourite');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_DEQUEUE', () => {
|
describe('NOTIFICATIONS_DEQUEUE', () => {
|
||||||
const state = ImmutableMap({
|
it('resets the queued counter to 0', () => {
|
||||||
items: ImmutableOrderedMap(),
|
const state = initialState.set('totalQueuedNotificationsCount', 1);
|
||||||
queuedNotifications: take(notifications, 1),
|
const action = { type: NOTIFICATIONS_DEQUEUE };
|
||||||
totalQueuedNotificationsCount: 1,
|
const result = reducer(state, action);
|
||||||
|
|
||||||
|
expect(result.totalQueuedNotificationsCount).toEqual(0);
|
||||||
});
|
});
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_DEQUEUE,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap(),
|
|
||||||
queuedNotifications: ImmutableOrderedMap(),
|
|
||||||
totalQueuedNotificationsCount: 0,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_EXPAND_SUCCESS with non-empty items and next set true', () => {
|
describe('NOTIFICATIONS_EXPAND_SUCCESS', () => {
|
||||||
|
it('with non-empty items and next set true', () => {
|
||||||
const state = ImmutableMap({
|
const state = ImmutableMap({
|
||||||
items: ImmutableOrderedMap([
|
items: ImmutableOrderedMap([
|
||||||
['10734', ImmutableMap({
|
['10734', ImmutableMap({
|
||||||
|
@ -313,19 +223,21 @@ describe('notifications reducer', () => {
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
created_at: '2020-06-10T02:54:39.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: '😢',
|
emoji: '😢',
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
]),
|
]),
|
||||||
unread: 1,
|
unread: 1,
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const action = {
|
const action = {
|
||||||
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
||||||
notifications: take(notifications, 3),
|
notifications: take(notifications, 3),
|
||||||
next: true,
|
next: true,
|
||||||
};
|
};
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
|
const expected = ImmutableMap({
|
||||||
items: ImmutableOrderedMap([
|
items: ImmutableOrderedMap([
|
||||||
['10744', ImmutableMap({
|
['10744', ImmutableMap({
|
||||||
id: '10744',
|
id: '10744',
|
||||||
|
@ -335,7 +247,7 @@ describe('notifications reducer', () => {
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
created_at: '2020-06-10T02:54:39.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: '😢',
|
emoji: '😢',
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10743', ImmutableMap({
|
['10743', ImmutableMap({
|
||||||
id: '10743',
|
id: '10743',
|
||||||
|
@ -344,8 +256,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
created_at: '2020-06-10T02:51:05.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10741', ImmutableMap({
|
['10741', ImmutableMap({
|
||||||
id: '10741',
|
id: '10741',
|
||||||
|
@ -354,8 +266,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
created_at: '2020-06-10T02:05:06.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10734', ImmutableMap({
|
['10734', ImmutableMap({
|
||||||
id: '10734',
|
id: '10734',
|
||||||
|
@ -365,28 +277,32 @@ describe('notifications reducer', () => {
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
created_at: '2020-06-10T02:54:39.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: '😢',
|
emoji: '😢',
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
]),
|
]),
|
||||||
unread: 1,
|
unread: 1,
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_EXPAND_SUCCESS with empty items and next set true', () => {
|
expect(reducer(state, action).toJS()).toEqual(expected.toJS());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with empty items and next set true', () => {
|
||||||
const state = ImmutableMap({
|
const state = ImmutableMap({
|
||||||
items: ImmutableOrderedMap(),
|
items: ImmutableOrderedMap(),
|
||||||
unread: 1,
|
unread: 1,
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const action = {
|
const action = {
|
||||||
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
||||||
notifications: take(notifications, 3),
|
notifications: take(notifications, 3),
|
||||||
next: true,
|
next: true,
|
||||||
};
|
};
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
|
const expected = ImmutableMap({
|
||||||
items: ImmutableOrderedMap([
|
items: ImmutableOrderedMap([
|
||||||
['10744', ImmutableMap({
|
['10744', ImmutableMap({
|
||||||
id: '10744',
|
id: '10744',
|
||||||
|
@ -396,7 +312,7 @@ describe('notifications reducer', () => {
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
created_at: '2020-06-10T02:54:39.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: '😢',
|
emoji: '😢',
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10743', ImmutableMap({
|
['10743', ImmutableMap({
|
||||||
id: '10743',
|
id: '10743',
|
||||||
|
@ -405,8 +321,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
created_at: '2020-06-10T02:51:05.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10741', ImmutableMap({
|
['10741', ImmutableMap({
|
||||||
id: '10741',
|
id: '10741',
|
||||||
|
@ -415,17 +331,21 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
created_at: '2020-06-10T02:05:06.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
]),
|
]),
|
||||||
unread: 1,
|
unread: 1,
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle ACCOUNT_BLOCK_SUCCESS', () => {
|
expect(reducer(state, action).toJS()).toEqual(expected.toJS());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ACCOUNT_BLOCK_SUCCESS', () => {
|
||||||
|
it('should handle', () => {
|
||||||
const state = ImmutableMap({
|
const state = ImmutableMap({
|
||||||
items: ImmutableOrderedMap([
|
items: ImmutableOrderedMap([
|
||||||
['10744', ImmutableMap({
|
['10744', ImmutableMap({
|
||||||
|
@ -436,7 +356,7 @@ describe('notifications reducer', () => {
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
created_at: '2020-06-10T02:54:39.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: '😢',
|
emoji: '😢',
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10743', ImmutableMap({
|
['10743', ImmutableMap({
|
||||||
id: '10743',
|
id: '10743',
|
||||||
|
@ -445,8 +365,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
created_at: '2020-06-10T02:51:05.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10741', ImmutableMap({
|
['10741', ImmutableMap({
|
||||||
id: '10741',
|
id: '10741',
|
||||||
|
@ -455,14 +375,14 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
created_at: '2020-06-10T02:05:06.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
const action = {
|
const action = {
|
||||||
type: ACCOUNT_BLOCK_SUCCESS,
|
type: ACCOUNT_BLOCK_SUCCESS,
|
||||||
relationship: relationship,
|
relationship,
|
||||||
};
|
};
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
expect(reducer(state, action)).toEqual(ImmutableMap({
|
||||||
items: ImmutableOrderedMap([
|
items: ImmutableOrderedMap([
|
||||||
|
@ -473,8 +393,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
created_at: '2020-06-10T02:51:05.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10741', ImmutableMap({
|
['10741', ImmutableMap({
|
||||||
id: '10741',
|
id: '10741',
|
||||||
|
@ -483,14 +403,16 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
created_at: '2020-06-10T02:05:06.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
]),
|
]),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle ACCOUNT_MUTE_SUCCESS', () => {
|
describe('ACCOUNT_MUTE_SUCCESS', () => {
|
||||||
|
it('should handle', () => {
|
||||||
const state = ImmutableMap({
|
const state = ImmutableMap({
|
||||||
items: ImmutableOrderedMap([
|
items: ImmutableOrderedMap([
|
||||||
['10744', ImmutableMap({
|
['10744', ImmutableMap({
|
||||||
|
@ -501,7 +423,7 @@ describe('notifications reducer', () => {
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
created_at: '2020-06-10T02:54:39.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: '😢',
|
emoji: '😢',
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10743', ImmutableMap({
|
['10743', ImmutableMap({
|
||||||
id: '10743',
|
id: '10743',
|
||||||
|
@ -510,8 +432,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
created_at: '2020-06-10T02:51:05.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10741', ImmutableMap({
|
['10741', ImmutableMap({
|
||||||
id: '10741',
|
id: '10741',
|
||||||
|
@ -520,8 +442,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
created_at: '2020-06-10T02:05:06.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
]),
|
]),
|
||||||
});
|
});
|
||||||
|
@ -538,8 +460,8 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
created_at: '2020-06-10T02:51:05.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
['10741', ImmutableMap({
|
['10741', ImmutableMap({
|
||||||
id: '10741',
|
id: '10741',
|
||||||
|
@ -548,157 +470,57 @@ describe('notifications reducer', () => {
|
||||||
target: null,
|
target: null,
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
created_at: '2020-06-10T02:05:06.000Z',
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
status: '9vvNxoo5EFbbnfdXQu',
|
||||||
emoji: undefined,
|
emoji: null,
|
||||||
chat_message: undefined,
|
chat_message: null,
|
||||||
})],
|
})],
|
||||||
]),
|
]),
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_CLEAR', () => {
|
|
||||||
const state = ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap(),
|
|
||||||
hasMore: true,
|
|
||||||
});
|
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_CLEAR,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap(),
|
|
||||||
hasMore: false,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle NOTIFICATIONS_MARK_READ_REQUEST', () => {
|
describe('NOTIFICATIONS_CLEAR', () => {
|
||||||
const state = ImmutableMap({
|
it('clears the items', () => {
|
||||||
items: ImmutableOrderedMap(),
|
const state = initialState.set('items', ImmutableOrderedMap([['1', {}], ['2', {}]]));
|
||||||
|
const action = { type: NOTIFICATIONS_CLEAR };
|
||||||
|
const result = reducer(state, action);
|
||||||
|
|
||||||
|
expect(result.items.isEmpty()).toBe(true);
|
||||||
});
|
});
|
||||||
const action = {
|
|
||||||
type: NOTIFICATIONS_MARK_READ_REQUEST,
|
|
||||||
lastRead: 35098814,
|
|
||||||
};
|
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap(),
|
|
||||||
lastRead: 35098814,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle TIMELINE_DELETE', () => {
|
describe('NOTIFICATIONS_MARK_READ_REQUEST', () => {
|
||||||
const state = ImmutableMap({
|
it('sets lastRead to the one in the action', () => {
|
||||||
items: ImmutableOrderedMap([
|
const action = { type: NOTIFICATIONS_MARK_READ_REQUEST, lastRead: '1234' };
|
||||||
['10744', ImmutableMap({
|
const result = reducer(undefined, action);
|
||||||
id: '10744',
|
|
||||||
type: 'pleroma:emoji_reaction',
|
expect(result.lastRead).toEqual('1234');
|
||||||
account: '9vMAje101ngtjlMj7w',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:54:39.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: '😢',
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
['10743', ImmutableMap({
|
|
||||||
id: '10743',
|
|
||||||
type: 'favourite',
|
|
||||||
account: '9v5c6xSEgAi3Zu1Lv6',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:51:05.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
['10741', ImmutableMap({
|
|
||||||
id: '10741',
|
|
||||||
type: 'favourite',
|
|
||||||
account: '9v5cKMOPGqPcgfcWp6',
|
|
||||||
target: null,
|
|
||||||
created_at: '2020-06-10T02:05:06.000Z',
|
|
||||||
status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
emoji: undefined,
|
|
||||||
chat_message: undefined,
|
|
||||||
})],
|
|
||||||
]),
|
|
||||||
});
|
});
|
||||||
const action = {
|
});
|
||||||
|
|
||||||
|
describe('TIMELINE_DELETE', () => {
|
||||||
|
it('deletes notifications corresponding to the status ID', () => {
|
||||||
|
const actions = [{
|
||||||
|
type: NOTIFICATIONS_EXPAND_SUCCESS,
|
||||||
|
notifications: [
|
||||||
|
{ id: '1', type: 'mention', status: { id: '4' }, account: { id: '7' } },
|
||||||
|
{ id: '2', type: 'mention', status: { id: '5' }, account: { id: '8' } },
|
||||||
|
{ id: '3', type: 'mention', status: { id: '6' }, account: { id: '9' } },
|
||||||
|
{ id: '4', type: 'mention', status: { id: '5' }, account: { id: '7' } },
|
||||||
|
],
|
||||||
|
next: null,
|
||||||
|
skipLoading: true,
|
||||||
|
}, {
|
||||||
type: TIMELINE_DELETE,
|
type: TIMELINE_DELETE,
|
||||||
id: '9vvNxoo5EFbbnfdXQu',
|
id: '5',
|
||||||
};
|
}];
|
||||||
expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
items: ImmutableOrderedMap(),
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Disable for now
|
// Setup by expanding, then calling `NOTIFICATIONS_FILTER_SET`
|
||||||
// https://gitlab.com/soapbox-pub/soapbox-fe/-/issues/432
|
const result = applyActions(initialState, actions, reducer);
|
||||||
//
|
|
||||||
// it('should handle TIMELINE_DISCONNECT', () => {
|
expect(result.items.size).toEqual(2);
|
||||||
// const state = ImmutableMap({
|
expect(result.items.get('5')).toBe(undefined);
|
||||||
// items: ImmutableOrderedSet([
|
});
|
||||||
// ImmutableMap({
|
});
|
||||||
// id: '10744',
|
|
||||||
// type: 'pleroma:emoji_reaction',
|
|
||||||
// account: '9vMAje101ngtjlMj7w',
|
|
||||||
// created_at: '2020-06-10T02:54:39.000Z',
|
|
||||||
// status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
// emoji: '😢',
|
|
||||||
// chat_message: undefined,
|
|
||||||
// }),
|
|
||||||
// ImmutableMap({
|
|
||||||
// id: '10743',
|
|
||||||
// type: 'favourite',
|
|
||||||
// account: '9v5c6xSEgAi3Zu1Lv6',
|
|
||||||
// created_at: '2020-06-10T02:51:05.000Z',
|
|
||||||
// status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
// emoji: undefined,
|
|
||||||
// chat_message: undefined,
|
|
||||||
// }),
|
|
||||||
// ImmutableMap({
|
|
||||||
// id: '10741',
|
|
||||||
// type: 'favourite',
|
|
||||||
// account: '9v5cKMOPGqPcgfcWp6',
|
|
||||||
// created_at: '2020-06-10T02:05:06.000Z',
|
|
||||||
// status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
// emoji: undefined,
|
|
||||||
// chat_message: undefined,
|
|
||||||
// }),
|
|
||||||
// ]),
|
|
||||||
// });
|
|
||||||
// const action = {
|
|
||||||
// type: TIMELINE_DISCONNECT,
|
|
||||||
// timeline: 'home',
|
|
||||||
// };
|
|
||||||
// expect(reducer(state, action)).toEqual(ImmutableMap({
|
|
||||||
// items: ImmutableOrderedSet([
|
|
||||||
// null,
|
|
||||||
// ImmutableMap({
|
|
||||||
// id: '10744',
|
|
||||||
// type: 'pleroma:emoji_reaction',
|
|
||||||
// account: '9vMAje101ngtjlMj7w',
|
|
||||||
// created_at: '2020-06-10T02:54:39.000Z',
|
|
||||||
// status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
// emoji: '😢',
|
|
||||||
// chat_message: undefined,
|
|
||||||
// }),
|
|
||||||
// ImmutableMap({
|
|
||||||
// id: '10743',
|
|
||||||
// type: 'favourite',
|
|
||||||
// account: '9v5c6xSEgAi3Zu1Lv6',
|
|
||||||
// created_at: '2020-06-10T02:51:05.000Z',
|
|
||||||
// status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
// emoji: undefined,
|
|
||||||
// chat_message: undefined,
|
|
||||||
// }),
|
|
||||||
// ImmutableMap({
|
|
||||||
// id: '10741',
|
|
||||||
// type: 'favourite',
|
|
||||||
// account: '9v5cKMOPGqPcgfcWp6',
|
|
||||||
// created_at: '2020-06-10T02:05:06.000Z',
|
|
||||||
// status: '9vvNxoo5EFbbnfdXQu',
|
|
||||||
// emoji: undefined,
|
|
||||||
// chat_message: undefined,
|
|
||||||
// }),
|
|
||||||
// ]),
|
|
||||||
// }));
|
|
||||||
// });
|
|
||||||
|
|
||||||
describe('MARKER_FETCH_SUCCESS', () => {
|
describe('MARKER_FETCH_SUCCESS', () => {
|
||||||
it('sets lastRead', () => {
|
it('sets lastRead', () => {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
Map as ImmutableMap,
|
Map as ImmutableMap,
|
||||||
List as ImmutableList,
|
List as ImmutableList,
|
||||||
Set as ImmutableSet,
|
Set as ImmutableSet,
|
||||||
|
Record as ImmutableRecord,
|
||||||
OrderedSet as ImmutableOrderedSet,
|
OrderedSet as ImmutableOrderedSet,
|
||||||
fromJS,
|
fromJS,
|
||||||
is,
|
is,
|
||||||
|
@ -20,7 +21,7 @@ import {
|
||||||
ADMIN_USERS_APPROVE_SUCCESS,
|
ADMIN_USERS_APPROVE_SUCCESS,
|
||||||
} from '../actions/admin';
|
} from '../actions/admin';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const ReducerRecord = ImmutableRecord({
|
||||||
reports: ImmutableMap(),
|
reports: ImmutableMap(),
|
||||||
openReports: ImmutableOrderedSet(),
|
openReports: ImmutableOrderedSet(),
|
||||||
users: ImmutableMap(),
|
users: ImmutableMap(),
|
||||||
|
@ -126,7 +127,7 @@ function handleReportDiffs(state, reports) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function admin(state = initialState, action) {
|
export default function admin(state = ReducerRecord(), action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case ADMIN_CONFIG_FETCH_SUCCESS:
|
case ADMIN_CONFIG_FETCH_SUCCESS:
|
||||||
case ADMIN_CONFIG_UPDATE_SUCCESS:
|
case ADMIN_CONFIG_UPDATE_SUCCESS:
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import {
|
import {
|
||||||
Map as ImmutableMap,
|
Map as ImmutableMap,
|
||||||
|
Record as ImmutableRecord,
|
||||||
OrderedSet as ImmutableOrderedSet,
|
OrderedSet as ImmutableOrderedSet,
|
||||||
fromJS,
|
fromJS,
|
||||||
} from 'immutable';
|
} from 'immutable';
|
||||||
|
|
||||||
import { ADMIN_LOG_FETCH_SUCCESS } from 'soapbox/actions/admin';
|
import { ADMIN_LOG_FETCH_SUCCESS } from 'soapbox/actions/admin';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const ReducerRecord = ImmutableRecord({
|
||||||
items: ImmutableMap(),
|
items: ImmutableMap(),
|
||||||
index: ImmutableOrderedSet(),
|
index: ImmutableOrderedSet(),
|
||||||
total: 0,
|
total: 0,
|
||||||
|
@ -34,7 +35,7 @@ const importItems = (state, items, total) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function admin_log(state = initialState, action) {
|
export default function admin_log(state = ReducerRecord(), action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case ADMIN_LOG_FETCH_SUCCESS:
|
case ADMIN_LOG_FETCH_SUCCESS:
|
||||||
return importItems(state, action.items, action.total);
|
return importItems(state, action.items, action.total);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import { Record as ImmutableRecord, List as ImmutableList } from 'immutable';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ALERT_SHOW,
|
ALERT_SHOW,
|
||||||
|
@ -6,21 +6,38 @@ import {
|
||||||
ALERT_CLEAR,
|
ALERT_CLEAR,
|
||||||
} from '../actions/alerts';
|
} from '../actions/alerts';
|
||||||
|
|
||||||
const initialState = ImmutableList([]);
|
const AlertRecord = ImmutableRecord({
|
||||||
|
key: 0,
|
||||||
|
title: '',
|
||||||
|
message: '',
|
||||||
|
severity: 'info',
|
||||||
|
actionLabel: '',
|
||||||
|
actionLink: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialState = ImmutableList();
|
||||||
|
|
||||||
|
// Get next key based on last alert
|
||||||
|
const getNextKey = state => state.size > 0 ? state.last().get('key') + 1 : 0;
|
||||||
|
|
||||||
|
// Import the alert
|
||||||
|
const importAlert = (state, alert) => {
|
||||||
|
const key = getNextKey(state);
|
||||||
|
const record = AlertRecord({ ...alert, key });
|
||||||
|
return state.push(record);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delete an alert by its key
|
||||||
|
const deleteAlert = (state, alert) => {
|
||||||
|
return state.filterNot(item => item.key === alert.key);
|
||||||
|
};
|
||||||
|
|
||||||
export default function alerts(state = initialState, action) {
|
export default function alerts(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case ALERT_SHOW:
|
case ALERT_SHOW:
|
||||||
return state.push(ImmutableMap({
|
return importAlert(state, action);
|
||||||
key: state.size > 0 ? state.last().get('key') + 1 : 0,
|
|
||||||
title: action.title,
|
|
||||||
message: action.message,
|
|
||||||
severity: action.severity || 'info',
|
|
||||||
actionLabel: action.actionLabel,
|
|
||||||
actionLink: action.actionLink,
|
|
||||||
}));
|
|
||||||
case ALERT_DISMISS:
|
case ALERT_DISMISS:
|
||||||
return state.filterNot(item => item.get('key') === action.alert.key);
|
return deleteAlert(state, action.alert);
|
||||||
case ALERT_CLEAR:
|
case ALERT_CLEAR:
|
||||||
return state.clear();
|
return state.clear();
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { Map as ImmutableMap } from 'immutable';
|
import { Record as ImmutableRecord } from 'immutable';
|
||||||
|
|
||||||
import { INSTANCE_FETCH_FAIL } from 'soapbox/actions/instance';
|
import { INSTANCE_FETCH_FAIL } from 'soapbox/actions/instance';
|
||||||
|
|
||||||
const initialState = ImmutableMap();
|
const ReducerRecord = ImmutableRecord({
|
||||||
|
instance_fetch_failed: false,
|
||||||
|
});
|
||||||
|
|
||||||
export default function meta(state = initialState, action) {
|
export default function meta(state = ReducerRecord(), action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case INSTANCE_FETCH_FAIL:
|
case INSTANCE_FETCH_FAIL:
|
||||||
return state.set('instance_fetch_failed', true);
|
return state.set('instance_fetch_failed', true);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Map as ImmutableMap, OrderedMap as ImmutableOrderedMap, fromJS } from 'immutable';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
MARKER_FETCH_SUCCESS,
|
Record as ImmutableRecord,
|
||||||
MARKER_SAVE_REQUEST,
|
OrderedMap as ImmutableOrderedMap,
|
||||||
MARKER_SAVE_SUCCESS,
|
fromJS,
|
||||||
} from 'soapbox/actions/markers';
|
} from 'immutable';
|
||||||
|
|
||||||
|
import { normalizeNotification } from 'soapbox/normalizers/notification';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ACCOUNT_BLOCK_SUCCESS,
|
ACCOUNT_BLOCK_SUCCESS,
|
||||||
|
@ -12,6 +12,11 @@ import {
|
||||||
FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
|
||||||
FOLLOW_REQUEST_REJECT_SUCCESS,
|
FOLLOW_REQUEST_REJECT_SUCCESS,
|
||||||
} from '../actions/accounts';
|
} from '../actions/accounts';
|
||||||
|
import {
|
||||||
|
MARKER_FETCH_SUCCESS,
|
||||||
|
MARKER_SAVE_REQUEST,
|
||||||
|
MARKER_SAVE_SUCCESS,
|
||||||
|
} from '../actions/markers';
|
||||||
import {
|
import {
|
||||||
NOTIFICATIONS_UPDATE,
|
NOTIFICATIONS_UPDATE,
|
||||||
NOTIFICATIONS_EXPAND_SUCCESS,
|
NOTIFICATIONS_EXPAND_SUCCESS,
|
||||||
|
@ -27,7 +32,7 @@ import {
|
||||||
} from '../actions/notifications';
|
} from '../actions/notifications';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const ReducerRecord = ImmutableRecord({
|
||||||
items: ImmutableOrderedMap(),
|
items: ImmutableOrderedMap(),
|
||||||
hasMore: true,
|
hasMore: true,
|
||||||
top: false,
|
top: false,
|
||||||
|
@ -48,16 +53,16 @@ const comparator = (a, b) => {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const notificationToMap = notification => ImmutableMap({
|
const minifyNotification = notification => {
|
||||||
id: notification.id,
|
return notification.mergeWith((o, n) => n || o, {
|
||||||
type: notification.type,
|
account: notification.getIn(['account', 'id']),
|
||||||
account: notification.account.id,
|
status: notification.getIn(['status', 'id']),
|
||||||
target: notification.target ? notification.target.id : null,
|
|
||||||
created_at: notification.created_at,
|
|
||||||
status: notification.status ? notification.status.id : null,
|
|
||||||
emoji: notification.emoji,
|
|
||||||
chat_message: notification.chat_message,
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const fixNotification = notification => {
|
||||||
|
return minifyNotification(normalizeNotification(notification));
|
||||||
|
};
|
||||||
|
|
||||||
const isValid = notification => {
|
const isValid = notification => {
|
||||||
try {
|
try {
|
||||||
|
@ -88,7 +93,7 @@ const countFuture = (notifications, lastId) => {
|
||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeNotification = (state, notification) => {
|
const importNotification = (state, notification) => {
|
||||||
const top = state.get('top');
|
const top = state.get('top');
|
||||||
|
|
||||||
if (!top) state = state.update('unread', unread => unread + 1);
|
if (!top) state = state.update('unread', unread => unread + 1);
|
||||||
|
@ -98,7 +103,7 @@ const normalizeNotification = (state, notification) => {
|
||||||
map = map.take(20);
|
map = map.take(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map.set(notification.id, notificationToMap(notification)).sort(comparator);
|
return map.set(notification.id, fixNotification(notification)).sort(comparator);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -106,7 +111,7 @@ const processRawNotifications = notifications => (
|
||||||
ImmutableOrderedMap(
|
ImmutableOrderedMap(
|
||||||
notifications
|
notifications
|
||||||
.filter(isValid)
|
.filter(isValid)
|
||||||
.map(n => [n.id, notificationToMap(n)]),
|
.map(n => [n.id, fixNotification(n)]),
|
||||||
));
|
));
|
||||||
|
|
||||||
const expandNormalizedNotifications = (state, notifications, next) => {
|
const expandNormalizedNotifications = (state, notifications, next) => {
|
||||||
|
@ -176,23 +181,23 @@ const importMarker = (state, marker) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function notifications(state = initialState, action) {
|
export default function notifications(state = ReducerRecord(), action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case NOTIFICATIONS_EXPAND_REQUEST:
|
case NOTIFICATIONS_EXPAND_REQUEST:
|
||||||
return state.set('isLoading', true);
|
return state.set('isLoading', true);
|
||||||
case NOTIFICATIONS_EXPAND_FAIL:
|
case NOTIFICATIONS_EXPAND_FAIL:
|
||||||
return state.set('isLoading', false);
|
return state.set('isLoading', false);
|
||||||
case NOTIFICATIONS_FILTER_SET:
|
case NOTIFICATIONS_FILTER_SET:
|
||||||
return state.set('items', ImmutableOrderedMap()).set('hasMore', true);
|
return state.delete('items').set('hasMore', true);
|
||||||
case NOTIFICATIONS_SCROLL_TOP:
|
case NOTIFICATIONS_SCROLL_TOP:
|
||||||
return updateTop(state, action.top);
|
return updateTop(state, action.top);
|
||||||
case NOTIFICATIONS_UPDATE:
|
case NOTIFICATIONS_UPDATE:
|
||||||
return normalizeNotification(state, action.notification);
|
return importNotification(state, action.notification);
|
||||||
case NOTIFICATIONS_UPDATE_QUEUE:
|
case NOTIFICATIONS_UPDATE_QUEUE:
|
||||||
return updateNotificationsQueue(state, action.notification, action.intlMessages, action.intlLocale);
|
return updateNotificationsQueue(state, action.notification, action.intlMessages, action.intlLocale);
|
||||||
case NOTIFICATIONS_DEQUEUE:
|
case NOTIFICATIONS_DEQUEUE:
|
||||||
return state.withMutations(mutable => {
|
return state.withMutations(mutable => {
|
||||||
mutable.set('queuedNotifications', ImmutableOrderedMap());
|
mutable.delete('queuedNotifications');
|
||||||
mutable.set('totalQueuedNotificationsCount', 0);
|
mutable.set('totalQueuedNotificationsCount', 0);
|
||||||
});
|
});
|
||||||
case NOTIFICATIONS_EXPAND_SUCCESS:
|
case NOTIFICATIONS_EXPAND_SUCCESS:
|
||||||
|
@ -205,7 +210,7 @@ export default function notifications(state = initialState, action) {
|
||||||
case FOLLOW_REQUEST_REJECT_SUCCESS:
|
case FOLLOW_REQUEST_REJECT_SUCCESS:
|
||||||
return filterNotificationIds(state, [action.id], 'follow_request');
|
return filterNotificationIds(state, [action.id], 'follow_request');
|
||||||
case NOTIFICATIONS_CLEAR:
|
case NOTIFICATIONS_CLEAR:
|
||||||
return state.set('items', ImmutableOrderedMap()).set('hasMore', false);
|
return state.delete('items').set('hasMore', false);
|
||||||
case NOTIFICATIONS_MARK_READ_REQUEST:
|
case NOTIFICATIONS_MARK_READ_REQUEST:
|
||||||
return state.set('lastRead', action.lastRead);
|
return state.set('lastRead', action.lastRead);
|
||||||
case MARKER_FETCH_SUCCESS:
|
case MARKER_FETCH_SUCCESS:
|
||||||
|
@ -214,16 +219,6 @@ export default function notifications(state = initialState, action) {
|
||||||
return importMarker(state, fromJS(action.marker));
|
return importMarker(state, fromJS(action.marker));
|
||||||
case TIMELINE_DELETE:
|
case TIMELINE_DELETE:
|
||||||
return deleteByStatus(state, action.id);
|
return deleteByStatus(state, action.id);
|
||||||
|
|
||||||
// Disable for now
|
|
||||||
// https://gitlab.com/soapbox-pub/soapbox-fe/-/issues/432
|
|
||||||
//
|
|
||||||
// case TIMELINE_DISCONNECT:
|
|
||||||
// // This is kind of a hack - `null` renders a LoadGap in the component
|
|
||||||
// // https://github.com/tootsuite/mastodon/pull/6886
|
|
||||||
// return action.timeline === 'home' ?
|
|
||||||
// state.update('items', items => items.first() ? ImmutableOrderedSet([null]).union(items) : items) :
|
|
||||||
// state;
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,3 +33,8 @@ export const createComponent = (children, props = {}) => {
|
||||||
</Provider>,
|
</Provider>,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Apply actions to the state, one at a time
|
||||||
|
export const applyActions = (state, actions, reducer) => {
|
||||||
|
return actions.reduce((state, action) => reducer(state, action), state);
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue