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:
parent
939dc0eac8
commit
0957899d57
8 changed files with 136 additions and 127 deletions
31
packages/integration-tests/src/api/dashboard.ts
Normal file
31
packages/integration-tests/src/api/dashboard.ts
Normal 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>();
|
|
@ -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';
|
||||
|
|
7
packages/integration-tests/src/api/logs.ts
Normal file
7
packages/integration-tests/src/api/logs.ts
Normal 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>();
|
35
packages/integration-tests/src/api/me.ts
Normal file
35
packages/integration-tests/src/api/me.ts
Normal 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,
|
||||
},
|
||||
});
|
|
@ -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'));
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue