Update javascript tests

This commit is contained in:
Sonny Bakker 2021-02-20 22:40:53 +01:00
parent 5ca819903c
commit 3818c7190e
4 changed files with 170 additions and 25 deletions

View file

@ -13,29 +13,30 @@ export const MARKING_POST = 'MARKING_POST';
export const MARK_POST_SAVED = 'MARK_POST_SAVED';
export const MARK_POST_UNSAVED = 'MARK_POST_UNSAVED';
export const TOGGLING_POST = 'TOGGLING_POST';
export const TOGGLED_POST = 'TOGGLED_POST';
export const requestPosts = () => ({ type: REQUEST_POSTS });
export const receivePost = post => ({ type: RECEIVE_POST, post });
export const receivePosts = (posts, next) => ({
type: RECEIVE_POSTS,
posts,
next,
});
export const receivePost = post => ({ type: RECEIVE_POST, post });
export const selectPost = post => ({ type: SELECT_POST, post });
export const unSelectPost = () => ({ type: UNSELECT_POST });
export const markingPostRead = () => ({ type: MARKING_POST });
export const postRead = (post, section) => ({
type: MARK_POST_READ,
post,
section,
});
export const markingPostRead = () => ({ type: MARKING_POST });
export const togglingPost = () => ({ type: TOGGLING_POST });
export const postToggled = post => ({ type: TOGGLED_POST, post });
export const markPostRead = (post, token) => {
return (dispatch, getState) => {
@ -68,10 +69,9 @@ export const markPostRead = (post, token) => {
};
};
// TODO add missing methods (postSaved & postUnsaved)
export const toggleSaved = (post, token) => {
return (dispatch, getState) => {
dispatch(togglingPostSaved());
dispatch(togglingPost());
const url = `/api/posts/${post.id}/`;
const options = {
@ -87,12 +87,7 @@ export const toggleSaved = (post, token) => {
.then(response => response.json())
.then(updatedPost => {
dispatch(receivePost({ ...updatedPost }));
if (updatedPost.saved) {
dispatch(postSaved({ ...updatedPost }));
} else {
dispatch(postUnsaved({ ...updatedPost }));
}
dispatch(postToggled({ ...updatedPost }));
})
.catch(error => {
dispatch(receivePost({}));

View file

@ -11,6 +11,7 @@ import {
RECEIVE_POSTS,
REQUEST_POSTS,
TOGGLING_POST,
TOGGLED_POST,
} from '../actions/posts.js';
import { SELECT_CATEGORY } from '../actions/categories.js';
import { SELECT_RULE } from '../actions/rules.js';
@ -72,9 +73,7 @@ export const posts = (state = { ...defaultState }, action) => {
return { ...state, isUpdating: true };
case MARK_POST_READ:
return { ...state, isUpdating: false };
case MARK_POST_SAVED:
return { ...state, isUpdating: false };
case MARK_POST_UNSAVED:
case TOGGLED_POST:
return { ...state, isUpdating: false };
default:
return state;

View file

@ -39,6 +39,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const expectedAction = {
@ -62,6 +63,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const expectedAction = {
@ -91,6 +93,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const rule = {
@ -111,6 +114,29 @@ describe('post actions', () => {
expect(actions.postRead(post, rule)).toEqual(expectedAction);
});
it('should create an action toggling post saved', () => {
const post = {
id: 2067,
remoteIdentifier: 'https://arstechnica.com/?p=1648607',
title:
'This amazing glitch puts Star Fox 64 ships in an unmodified Zelda cartridge',
body:
'"Stale-reference manipulation," 300-character file names, and a clash between worlds.',
author: 'Kyle Orland',
publicationDate: '2020-01-24T19:50:12Z',
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const expectedAction = {
type: actions.TOGGLING_POST,
};
expect(actions.togglingPost(post)).toEqual(expectedAction);
});
it('should create multiple actions to mark post read', () => {
const post = {
id: 2067,
@ -124,6 +150,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const rule = {
@ -143,7 +170,7 @@ describe('post actions', () => {
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: {
item: rule,
next: false,
@ -170,6 +197,65 @@ describe('post actions', () => {
});
});
it('should create multiple actions to toggle a post saved', () => {
const post = {
id: 2067,
remoteIdentifier: 'https://arstechnica.com/?p=1648607',
title:
'This amazing glitch puts Star Fox 64 ships in an unmodified Zelda cartridge',
body:
'"Stale-reference manipulation," 300-character file names, and a clash between worlds.',
author: 'Kyle Orland',
publicationDate: '2020-01-24T19:50:12Z',
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const rule = {
id: 1,
name: 'Test rule',
unread: 100,
category: 1,
url: 'http://feeds.arstechnica.com/arstechnica/index?fmt=xml',
favicon: 'https://cdn.arstechnica.net/favicon.ico',
};
fetchMock.patchOnce('/api/posts/2067/', {
body: { ...post, saved: true },
headers: { 'content-type': 'application/json' },
});
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: {
item: rule,
next: false,
lastReached: false,
post: {},
},
});
const expectedActions = [
{ type: actions.TOGGLING_POST },
{
type: actions.RECEIVE_POST,
post: { ...post, saved: true },
},
{
type: actions.TOGGLED_POST,
post: { ...post, saved: true },
},
];
return store.dispatch(actions.toggleSaved(post, 'TOKEN')).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it('should create multiple actions to fetch posts by rule', () => {
const posts = [
{
@ -184,6 +270,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 4,
read: false,
saved: false,
},
{
id: 2141,
@ -196,6 +283,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648757',
rule: 4,
read: false,
saved: false,
},
];
@ -222,7 +310,7 @@ describe('post actions', () => {
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: { item: {}, next: false, lastReached: false, post: {} },
});
@ -254,6 +342,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 4,
read: false,
saved: false,
},
{
id: 2141,
@ -266,6 +355,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648757',
rule: 4,
read: false,
saved: false,
},
];
@ -289,7 +379,7 @@ describe('post actions', () => {
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: { item: {}, next: false, lastReached: false, post: {} },
});
@ -320,7 +410,7 @@ describe('post actions', () => {
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: { item: {}, next: false, lastReached: false, post: {} },
});
@ -344,6 +434,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const rule = {
@ -364,7 +455,7 @@ describe('post actions', () => {
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: { item: { ...rule }, next: false, lastReached: false, post: {} },
});
@ -379,6 +470,55 @@ describe('post actions', () => {
});
});
it('should handle exceptions when toggling a post saved/unsaved', () => {
const post = {
id: 2067,
remoteIdentifier: 'https://arstechnica.com/?p=1648607',
title:
'This amazing glitch puts Star Fox 64 ships in an unmodified Zelda cartridge',
body:
'"Stale-reference manipulation," 300-character file names, and a clash between worlds.',
author: 'Kyle Orland',
publicationDate: '2020-01-24T19:50:12Z',
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
};
const rule = {
id: 4,
name: 'Ars Technica',
unread: 100,
category: 1,
url: 'http://feeds.arstechnica.com/arstechnica/index?fmt=xml',
favicon: 'https://cdn.arstechnica.net/favicon.ico',
};
const errorMessage = 'Permission denied';
fetchMock.patch(`/api/posts/${post.id}/`, () => {
throw new Error(errorMessage);
});
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: { item: { ...rule }, next: false, lastReached: false, post: {} },
});
const expectedActions = [
{ type: actions.TOGGLING_POST },
{ type: actions.RECEIVE_POST, post: {} },
{ type: errorActions.RECEIVE_API_ERROR, error: Error(errorMessage) },
];
return store.dispatch(actions.toggleSaved(post, 'FAKE_TOKEN')).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it('should handle exceptions when fetching posts by section', () => {
const rule = {
id: 4,
@ -399,7 +539,7 @@ describe('post actions', () => {
const store = mockStore({
categories: { items: {}, isFetching: false },
rules: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false },
posts: { items: {}, isFetching: false, isUpdating: false },
selected: { item: { ...rule }, next: false, lastReached: false, post: {} },
});

View file

@ -12,7 +12,7 @@ describe('post actions', () => {
it('should return state after requesting posts', () => {
const action = { type: actions.REQUEST_POSTS };
const expectedState = { ...defaultState, isFetching: true, isMarking: false };
const expectedState = { ...defaultState, isFetching: true, isUpdating: false };
expect(reducer(undefined, action)).toEqual(expectedState);
});
@ -30,6 +30,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 4,
read: false,
saved: false,
};
const action = {
@ -40,7 +41,7 @@ describe('post actions', () => {
const expectedState = {
...defaultState,
isFetching: false,
isMarking: false,
isUpdating: false,
items: { [post.id]: post },
};
@ -61,6 +62,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 4,
read: false,
saved: false,
},
{
id: 2141,
@ -73,6 +75,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648757',
rule: 4,
read: false,
saved: false,
},
];
@ -86,7 +89,7 @@ describe('post actions', () => {
const expectedState = {
...defaultState,
isFetching: false,
isMarking: false,
isUpdating: false,
items: expectedPosts,
};
@ -131,6 +134,7 @@ describe('post actions', () => {
url: 'https://www.bbc.co.uk/news/world-asia-china-51299195',
rule: 4,
read: false,
saved: false,
},
4638: {
id: 4638,
@ -143,6 +147,7 @@ describe('post actions', () => {
url: 'https://www.bbc.co.uk/news/world-europe-51294305',
rule: 4,
read: false,
saved: false,
},
};
@ -189,6 +194,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648607',
rule: 5,
read: false,
saved: false,
},
2141: {
id: 2141,
@ -201,6 +207,7 @@ describe('post actions', () => {
url: 'https://arstechnica.com/?p=1648757',
rule: 5,
read: false,
saved: false,
},
4637: {
id: 4637,
@ -213,6 +220,7 @@ describe('post actions', () => {
url: 'https://www.bbc.co.uk/news/world-asia-china-51299195',
rule: 4,
read: false,
saved: false,
},
4638: {
id: 4638,
@ -225,6 +233,7 @@ describe('post actions', () => {
url: 'https://www.bbc.co.uk/news/world-europe-51294305',
rule: 4,
read: false,
saved: false,
},
4589: {
id: 4589,
@ -238,6 +247,7 @@ describe('post actions', () => {
'https://tweakers.net/nieuws/162878/analyse-nintendo-verdiende-miljard-dollar-aan-mobiele-games.html',
rule: 7,
read: false,
saved: false,
},
4594: {
id: 4594,
@ -251,6 +261,7 @@ describe('post actions', () => {
'https://tweakers.net/nieuws/162870/samsung-kondigt-eerste-tablet-met-5g-aan.html',
rule: 7,
read: false,
saved: false,
},
};