Skip to content
This repository has been archived by the owner on May 10, 2023. It is now read-only.

Commit

Permalink
fix: move user stats to user endpoint (fixes #423)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelKohler committed Jun 27, 2021
1 parent dce4d72 commit 28f87f3
Show file tree
Hide file tree
Showing 12 changed files with 34 additions and 26 deletions.
5 changes: 1 addition & 4 deletions server/routes/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ router.get('/', async (req, res) => {
if (locales.length === 1 && !locales[0]) {
return res.json({
all: {},
user: {},
userUnreviewed: {},
totals: { total: 0, languages: 0},
});
Expand All @@ -26,16 +25,14 @@ router.get('/', async (req, res) => {
debug('GET_STATS', sessionUserId);

try {
const [{ all, totals }, user, userUnreviewed] = await Promise.all([
const [{ all, totals }, userUnreviewed] = await Promise.all([
sentences.getStats(locales),
sentences.getUserAddedSentencesPerLocale(sessionUserId),
sentences.getUnreviewedByYouCountForLocales(locales, sessionUserId),
]);

res.json({
all,
totals,
user,
userUnreviewed,
});
} catch (error) {
Expand Down
7 changes: 6 additions & 1 deletion server/routes/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const debug = require('debug')('sentencecollector:routes:users');
const express = require('express');
const sentences = require('../lib/sentences');
const users = require('../lib/users');

const router = express.Router(); // eslint-disable-line new-cap
Expand All @@ -13,7 +14,11 @@ router.get('/whoami', async (req, res) => {
try {
if (user && user.email) {
const extendedUser = await users.get(user.email);
return res.json(extendedUser);
const userStats = await sentences.getUserAddedSentencesPerLocale(user.email);
return res.json({
...extendedUser,
userStats,
});
}
} catch (err) {
// ignoring catch as we send a 404 anyway
Expand Down
12 changes: 1 addition & 11 deletions server/tests/routes/stats.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@ const totalStats = {
languages: 1,
};

const userStats = {
en: {
total: 5,
validated: 3,
},
};

const userUnreviewedStats = {
en: 2,
};
Expand All @@ -33,7 +26,6 @@ test.beforeEach((t) => {
all: allStats,
totals: totalStats,
});
t.context.sandbox.stub(sentences, 'getUserAddedSentencesPerLocale').resolves(userStats);
t.context.sandbox.stub(sentences, 'getUnreviewedByYouCountForLocales').resolves(userUnreviewedStats);
});

Expand All @@ -51,7 +43,6 @@ test.serial('should get stats', async (t) => {
t.deepEqual(response.body, {
all: allStats,
totals: totalStats,
user: userStats,
userUnreviewed: userUnreviewedStats,
});
});
Expand All @@ -69,13 +60,12 @@ test.serial('should return default stats if no locale passed', async (t) => {
total: 0,
languages: 0,
},
user: {},
userUnreviewed: {},
});
});

test.serial('should pass on error message', async (t) => {
sentences.getUserAddedSentencesPerLocale.rejects(new Error('nope'));
sentences.getUnreviewedByYouCountForLocales.rejects(new Error('nope'));

const response = await request(app)
.get('/sentence-collector/stats?locales=en,de');
Expand Down
8 changes: 5 additions & 3 deletions web/src/actions/login.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const userInfo = {
email: 'foo@example.com',
languages: ['en'],
settings: {},
userStats: {},
};
let dispatch: jest.Mock;
let getState: jest.Mock;
Expand Down Expand Up @@ -34,16 +35,17 @@ describe('checkCurrentUser', () => {
await login.checkCurrentUser()(dispatch, getState, null);
expect((backend.sendRequest as jest.Mock).mock.calls[0][0]).toEqual('users/whoami');
expect(dispatch.mock.calls[0][0]).toEqual({
username: userInfo.email,
type: login.ACTION_USER_INFO_RECEIVED,
username: userInfo.email,
userStats: userInfo.userStats,
});
expect(dispatch.mock.calls[1][0]).toEqual({
languages: userInfo.languages,
type: languages.ACTION_ADD_LANGUAGE_SUCCESS,
languages: userInfo.languages,
});
expect(dispatch.mock.calls[2][0]).toEqual({
newSettings: userInfo.settings,
type: settings.ACTION_SETTINGS_CHANGED,
newSettings: userInfo.settings,
});
});

Expand Down
4 changes: 3 additions & 1 deletion web/src/actions/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { AnyAction } from 'redux';
import type { ThunkAction } from 'redux-thunk';

import { sendRequest } from '../backend';
import type { RootState } from '../types';
import type { RootState, UserStats } from '../types';
import { addLanguageSuccess } from './languages';
import { settingsChanged } from './settings';

Expand All @@ -15,6 +15,7 @@ type UserInfo = {
languages: string[]
settings: Record<string, unknown>
email: string
userStats: UserStats
}

export function afterLogin(): ThunkAction<void, RootState, unknown, AnyAction> {
Expand Down Expand Up @@ -58,5 +59,6 @@ export function userInfoReceived(userInfo: UserInfo) {
return {
type: ACTION_USER_INFO_RECEIVED,
username: userInfo.email,
userStats: userInfo.userStats,
};
}
2 changes: 1 addition & 1 deletion web/src/containers/profile.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ beforeEach(() => {
username,
allLanguages,
languages: ['en'],
stats: { user: {} },
userStats: {},
pendingLanguages: false,
useSwipeReview: false,
errorMessage: '',
Expand Down
4 changes: 2 additions & 2 deletions web/src/containers/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export default function Profile() {
errorMessage: settingsErrorMessage,
} = useSelector((state: RootState) => state.settings);
const {
stats: { user: languageStats = {} },
allLanguages,
languages,
pendingLanguages,
} = useSelector((state: RootState) => state.languages);
const { userStats } = useSelector((state: RootState) => state.login);

const dispatch = useDispatch();

Expand Down Expand Up @@ -50,7 +50,7 @@ export default function Profile() {

<PersonalLanguageInfo
languages={extendedLanguages}
languageStats={languageStats}
languageStats={userStats}
onRemove={onRemove}
pendingLanguages={pendingLanguages}
/>
Expand Down
1 change: 0 additions & 1 deletion web/src/reducers/languages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ test('should use initial state', async () => {
expect(newState).toEqual({
stats: {
all: {},
user: {},
userUnreviewed: {},
totals: {
total: 0,
Expand Down
1 change: 0 additions & 1 deletion web/src/reducers/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export type LanguageState = {
export const INITIAL_STATE: LanguageState = {
stats: {
all: {},
user: {},
userUnreviewed: {},
totals: {
total: 0,
Expand Down
8 changes: 8 additions & 0 deletions web/src/reducers/login.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ test('should use initial state', async () => {
expect(newState).toEqual({
authed: false,
username: '',
userStats: {},
});
});

Expand All @@ -42,11 +43,18 @@ test('should reduce logout success', async () => {

test('should reduce user info', async () => {
const username = 'testUser';
const userStats = {
en: {
added: 5,
},
};
const newState = loginReducer(combineState({}), {
type: login.ACTION_USER_INFO_RECEIVED,
username,
userStats,
});

expect(newState.authed).toEqual(true);
expect(newState.username).toEqual(username);
expect(newState.userStats).toEqual(userStats);
});
5 changes: 5 additions & 0 deletions web/src/reducers/login.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { AnyAction } from 'redux';

import type { UserStats } from '../types';

import {
ACTION_LOGOUT,
ACTION_LOGIN_SUCCESS,
Expand All @@ -9,11 +11,13 @@ import {
export type LoginState = {
authed: boolean
username: string
userStats: UserStats
}

export const INITIAL_STATE: LoginState = {
authed: false,
username: '',
userStats: {},
};

export default function(state = INITIAL_STATE, action: AnyAction): LoginState {
Expand All @@ -30,6 +34,7 @@ export default function(state = INITIAL_STATE, action: AnyAction): LoginState {
return Object.assign({}, state, {
authed: true,
username: action.username,
userStats: action.userStats,
});

default:
Expand Down
3 changes: 2 additions & 1 deletion web/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ export type TotalStats = {

export type LanguageStats = {
userUnreviewed: Record<string, number>
user: Record<string, PersonalLanguageStatsEntry>
all: StatsRecordByLanguage
totals: TotalStats
}

export type UserStats = Record<string, PersonalLanguageStatsEntry>

export type SentenceRecord = {
id?: number
sentence: string
Expand Down

0 comments on commit 28f87f3

Please sign in to comment.