0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-03 21:48:55 -05:00

refactor(test): refactor log, dashboard, me (#1692)

* refactor(test): refactor me,logs, dashboard

refactor me,logs, dashboard

* fix(test): cr update

cr update
This commit is contained in:
simeng-li 2022-07-28 10:30:37 +08:00 committed by GitHub
parent 939dc0eac8
commit 0957899d57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 136 additions and 127 deletions

View file

@ -0,0 +1,31 @@
import { authedAdminApi } from './api';
export type StatisticsData = {
count: number;
delta: number;
};
export type TotalUserCountData = {
totalUserCount: number;
};
export type NewUserStatistics = {
today: StatisticsData;
last7Days: StatisticsData;
};
export type ActiveUserStatistics = {
dauCurve: StatisticsData[];
dau: StatisticsData;
wau: StatisticsData;
mau: StatisticsData;
};
export const getTotalUsersCount = () =>
authedAdminApi.get('dashboard/users/total').json<TotalUserCountData>();
export const getNewUsersData = () =>
authedAdminApi.get('dashboard/users/new').json<NewUserStatistics>();
export const getActiveUsersData = () =>
authedAdminApi.get('dashboard/users/active').json<ActiveUserStatistics>();

View file

@ -4,5 +4,8 @@ export * from './application';
export * from './sign-in-experience';
export * from './admin-user';
export * from './session';
export * from './logs';
export * from './dashboard';
export * from './me';
export { default as api, authedAdminApi } from './api';

View file

@ -0,0 +1,7 @@
import { Log } from '@logto/schemas';
import { authedAdminApi } from './api';
export const getLogs = () => authedAdminApi.get('logs').json<Log[]>();
export const getLog = (logId: string) => authedAdminApi.get(`logs/${logId}`).json<Log>();

View file

@ -0,0 +1,35 @@
import { ArbitraryObject, UserInfo } from '@logto/schemas';
import api from './api';
export const getCurrentUserInfo = (userId: string) =>
api.get(`me`, { headers: { 'development-user-id': userId } }).json<UserInfo>();
export const getCurrentUserCustomData = (userId: string) =>
api
.get('me/custom-data', {
headers: {
'development-user-id': userId,
},
})
.json<ArbitraryObject>();
export const updateCurrentUserCustomData = (userId: string, payload: Record<string, unknown>) =>
api.patch('me/custom-data', {
headers: {
'development-user-id': userId,
},
json: {
customData: payload,
},
});
export const changeCurrentUserPassword = (userId: string, password: string) =>
api.patch('me/password', {
headers: {
'development-user-id': userId,
},
json: {
password,
},
});

View file

@ -1,5 +1,4 @@
import { User } from '@logto/schemas';
import { demoAppApplicationId } from '@logto/schemas/lib/seeds';
import { assert } from '@silverhand/essentials';
import {
@ -8,7 +7,6 @@ import {
signInWithUsernameAndPassword,
} from '@/api';
import MockClient from '@/client';
import { demoAppRedirectUri, logtoUrl } from '@/constants';
import { generateUsername, generatePassword } from '@/utils';
export const createUserByAdmin = (_username?: string, _password?: string) => {
@ -63,29 +61,3 @@ export const signIn = async (username: string, password: string) => {
assert(client.isAuthenticated, new Error('Sign in failed'));
};
export const registerUserAndSignIn = async () => {
const client = new MockClient({
endpoint: logtoUrl,
appId: demoAppApplicationId,
persistAccessToken: false,
});
await client.initSession(demoAppRedirectUri);
assert(client.interactionCookie, new Error('Session not found'));
const username = generateUsername();
const password = generatePassword();
await registerUserWithUsernameAndPassword(username, password, client.interactionCookie);
const { redirectTo } = await signInWithUsernameAndPassword(
username,
password,
client.interactionCookie
);
await client.processSession(redirectTo);
assert(client.isAuthenticated, new Error('Sign in failed'));
};

View file

@ -1,45 +1,26 @@
import { authedAdminApi } from '@/api';
import { registerUserAndSignIn } from '@/helpers';
type StatisticsData = {
count: number;
delta: number;
};
import { getTotalUsersCount, getNewUsersData, getActiveUsersData, StatisticsData } from '@/api';
import { createUserByAdmin, registerNewUser, signIn } from '@/helpers';
import { generateUsername, generatePassword } from '@/utils';
describe('admin console dashboard', () => {
it('should get total user count successfully', async () => {
type TotalUserCountData = {
totalUserCount: number;
};
const { totalUserCount: originTotalUserCount } = await getTotalUsersCount();
const { totalUserCount: originTotalUserCount } = await authedAdminApi
.get('dashboard/users/total')
.json<TotalUserCountData>();
const password = generatePassword();
const username = generateUsername();
await createUserByAdmin(username, password);
await registerUserAndSignIn();
const { totalUserCount } = await authedAdminApi
.get('dashboard/users/total')
.json<TotalUserCountData>();
const { totalUserCount } = await getTotalUsersCount();
expect(totalUserCount).toBe(originTotalUserCount + 1);
});
it('should get new user statistics successfully', async () => {
type NewUserStatistics = {
today: StatisticsData;
last7Days: StatisticsData;
};
const originUserStatistics = await getNewUsersData();
const originUserStatistics = await authedAdminApi
.get('dashboard/users/new')
.json<NewUserStatistics>();
await registerNewUser(generateUsername(), generatePassword());
await registerUserAndSignIn();
const newUserStatistics = await authedAdminApi
.get('dashboard/users/new')
.json<NewUserStatistics>();
const newUserStatistics = await getNewUsersData();
const keyToCompare: Array<keyof StatisticsData> = ['count', 'delta'];
@ -50,31 +31,24 @@ describe('admin console dashboard', () => {
});
it('should get active user statistics successfully', async () => {
type ActiveUserStatistics = {
dauCurve: StatisticsData[];
dau: StatisticsData;
wau: StatisticsData;
mau: StatisticsData;
};
const originActiveUserStatistics = await getActiveUsersData();
const originActiveUserStatistics = await authedAdminApi
.get('dashboard/users/active')
.json<ActiveUserStatistics>();
const password = generatePassword();
const username = generateUsername();
await createUserByAdmin(username, password);
await registerUserAndSignIn();
await signIn(username, password);
const activeUserStatistics = await authedAdminApi
.get('dashboard/users/active')
.json<ActiveUserStatistics>();
const newActiveUserStatistics = await getActiveUsersData();
expect(activeUserStatistics.dauCurve.length).toBeGreaterThan(0);
expect(newActiveUserStatistics.dauCurve.length).toBeGreaterThan(0);
const keyToCompare: Array<keyof StatisticsData> = ['count', 'delta'];
for (const key of keyToCompare) {
expect(activeUserStatistics.dau[key]).toBe(originActiveUserStatistics.dau[key] + 1);
expect(activeUserStatistics.wau[key]).toBe(originActiveUserStatistics.wau[key] + 1);
expect(activeUserStatistics.mau[key]).toBe(originActiveUserStatistics.mau[key] + 1);
expect(newActiveUserStatistics.dau[key]).toBe(originActiveUserStatistics.dau[key] + 1);
expect(newActiveUserStatistics.wau[key]).toBe(originActiveUserStatistics.wau[key] + 1);
expect(newActiveUserStatistics.mau[key]).toBe(originActiveUserStatistics.mau[key] + 1);
}
});
});

View file

@ -1,22 +1,30 @@
import { LogDto } from '@logto/schemas';
import { assert } from '@silverhand/essentials';
import { authedAdminApi } from '@/api';
import { registerUserAndSignIn } from '@/helpers';
import { getLogs, getLog } from '@/api';
import { registerNewUser } from '@/helpers';
import { generateUsername, generatePassword } from '@/utils';
describe('admin console logs', () => {
const username = generateUsername();
const password = generatePassword();
it('should get logs and visit log details successfully', async () => {
await registerUserAndSignIn();
await registerNewUser(username, password);
const logs = await authedAdminApi.get('logs').json<LogDto[]>();
const logs = await getLogs();
expect(logs.length).toBeGreaterThan(0);
const registerLog = logs.filter(
({ type, payload }) =>
type === 'RegisterUsernamePassword' &&
(payload as Record<string, unknown>).username === username
);
const log = logs[0];
assert(log, new Error('Log is not valid'));
expect(registerLog.length).toBeGreaterThan(0);
const logDetails = await authedAdminApi.get(`logs/${log.id}`).json<LogDto>();
assert(registerLog[0], new Error('Log is not valid'));
expect(logDetails.id).toBe(log.id);
const logDetails = await getLog(registerLog[0].id);
expect(logDetails).toMatchObject(registerLog[0]);
});
});

View file

@ -1,15 +1,20 @@
import { ArbitraryObject, UserInfo, userInfoSelectFields } from '@logto/schemas';
import { userInfoSelectFields } from '@logto/schemas';
import { assert } from '@silverhand/essentials';
import { api } from '@/api';
import { createUserByAdmin } from '@/helpers';
import {
getCurrentUserInfo,
getCurrentUserCustomData,
updateCurrentUserCustomData,
changeCurrentUserPassword,
} from '@/api';
import { createUserByAdmin, signIn } from '@/helpers';
import { generatePassword } from '@/utils';
describe('api `/me`', () => {
it('should get user info successfully', async () => {
const user = await createUserByAdmin();
const userInfo = await api
.get(`me`, { headers: { 'development-user-id': user.id } })
.json<UserInfo>();
const userInfo = await getCurrentUserInfo(user.id);
expect(userInfo.id).toBe(user.id);
@ -20,56 +25,30 @@ describe('api `/me`', () => {
it('should get user custom data successfully', async () => {
const user = await createUserByAdmin();
const customData = await api
.get('me/custom-data', {
headers: {
'development-user-id': user.id,
},
})
.json<ArbitraryObject>();
const customData = await getCurrentUserCustomData(user.id);
expect(customData).toEqual({});
});
it('should update user custom data successfully', async () => {
const user = await createUserByAdmin();
const headers = Object.freeze({
'development-user-id': user.id,
});
const foo = 'bar';
const newCustomData = {
foo: 'bar',
};
await updateCurrentUserCustomData(user.id, { foo });
await api.patch('me/custom-data', {
headers,
json: {
customData: newCustomData,
},
});
const customData = await getCurrentUserCustomData(user.id);
const customData = await api
.get('me/custom-data', {
headers,
})
.json<ArbitraryObject>();
expect(customData).toEqual(newCustomData);
expect(customData).toEqual({ foo });
});
it('should change user password successfully', async () => {
const user = await createUserByAdmin();
const password = generatePassword();
const changePasswordResponse = await api.patch('me/password', {
headers: {
'development-user-id': user.id,
},
json: {
password,
},
});
expect(changePasswordResponse.statusCode).toBe(204);
await changeCurrentUserPassword(user.id, password);
assert(user.username, new Error('empty username'));
void expect(signIn(user.username, password)).resolves.not.toThrow();
});
});