diff --git a/packages/integration-tests/src/helper.ts b/packages/integration-tests/src/helper.ts index 3bb752191..8591a5985 100644 --- a/packages/integration-tests/src/helper.ts +++ b/packages/integration-tests/src/helper.ts @@ -1,6 +1,16 @@ import { User } from '@logto/schemas'; +import { demoAppApplicationId } from '@logto/schemas/lib/seeds'; +import { assert } from '@silverhand/essentials'; import { authedAdminApi } from './api'; +import LogtoClient from './client/logto-client'; +import { demoAppRedirectUri, logtoUrl } from './constants'; +import { + visitSignInUri, + registerUserWithUsernameAndPassword, + consentUserAndGetSignInCallbackUri, + signInWithUsernameAndPassword, +} from './ui-actions'; import { generateUsername, generatePassword } from './utils'; export const createUser = () => { @@ -16,3 +26,34 @@ export const createUser = () => { }) .json(); }; + +export const registerUserAndSignIn = async () => { + const logtoClient = new LogtoClient({ + endpoint: logtoUrl, + appId: demoAppApplicationId, + persistAccessToken: false, + }); + + await logtoClient.signIn(demoAppRedirectUri); + + assert(logtoClient.navigateUrl, new Error('Unable to navigate to sign in uri')); + + const interactionCookie = await visitSignInUri(logtoClient.navigateUrl); + + const username = generateUsername(); + const password = generatePassword(); + + await registerUserWithUsernameAndPassword(username, password, interactionCookie); + + const interactionCookieWithSession = await signInWithUsernameAndPassword( + username, + password, + interactionCookie + ); + + const signInCallbackUri = await consentUserAndGetSignInCallbackUri(interactionCookieWithSession); + + await logtoClient.handleSignInCallback(signInCallbackUri); + + assert(logtoClient.isAuthenticated, new Error('Sign in failed')); +}; diff --git a/packages/integration-tests/tests/dashboard.test.ts b/packages/integration-tests/tests/dashboard.test.ts new file mode 100644 index 000000000..c3f99d608 --- /dev/null +++ b/packages/integration-tests/tests/dashboard.test.ts @@ -0,0 +1,80 @@ +import { authedAdminApi } from '@/api'; +import { registerUserAndSignIn } from '@/helper'; + +type StatisticsData = { + count: number; + delta: number; +}; + +describe('admin console dashboard', () => { + it('should get total user count successfully', async () => { + type TotalUserCountData = { + totalUserCount: number; + }; + + const { totalUserCount: originTotalUserCount } = await authedAdminApi + .get('dashboard/users/total') + .json(); + + await registerUserAndSignIn(); + + const { totalUserCount } = await authedAdminApi + .get('dashboard/users/total') + .json(); + + expect(totalUserCount).toBe(originTotalUserCount + 1); + }); + + it('should get new user statistics successfully', async () => { + type NewUserStatistics = { + today: StatisticsData; + last7Days: StatisticsData; + }; + + const originUserStatistics = await authedAdminApi + .get('dashboard/users/new') + .json(); + + await registerUserAndSignIn(); + + const newUserStatistics = await authedAdminApi + .get('dashboard/users/new') + .json(); + + const keyToCompare: Array = ['count', 'delta']; + + for (const key of keyToCompare) { + expect(newUserStatistics.today[key]).toBe(originUserStatistics.today[key] + 1); + expect(newUserStatistics.last7Days[key]).toBe(originUserStatistics.last7Days[key] + 1); + } + }); + + it('should get active user statistics successfully', async () => { + type ActiveUserStatistics = { + dauCurve: StatisticsData[]; + dau: StatisticsData; + wau: StatisticsData; + mau: StatisticsData; + }; + + const originActiveUserStatistics = await authedAdminApi + .get('dashboard/users/active') + .json(); + + await registerUserAndSignIn(); + + const activeUserStatistics = await authedAdminApi + .get('dashboard/users/active') + .json(); + + expect(activeUserStatistics.dauCurve.length).toBeGreaterThan(0); + + const keyToCompare: Array = ['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); + } + }); +}); diff --git a/packages/integration-tests/tests/username-password-flow.test.ts b/packages/integration-tests/tests/username-password-flow.test.ts index d9de7243f..973389c16 100644 --- a/packages/integration-tests/tests/username-password-flow.test.ts +++ b/packages/integration-tests/tests/username-password-flow.test.ts @@ -1,49 +1,9 @@ -import { LogtoConfig } from '@logto/node'; -import { demoAppApplicationId } from '@logto/schemas/lib/seeds'; - -import LogtoClient from '@/client/logto-client'; -import { demoAppRedirectUri, logtoUrl } from '@/constants'; -import { - consentUserAndGetSignInCallbackUri, - registerUserWithUsernameAndPassword, - signInWithUsernameAndPassword, - visitSignInUri, -} from '@/ui-actions'; -import { generatePassword, generateUsername } from '@/utils'; +import { registerUserAndSignIn } from '@/helper'; describe('username and password flow', () => { it('should register and sign in with username and password successfully', async () => { - const logtoConfig: LogtoConfig = { - endpoint: logtoUrl, - appId: demoAppApplicationId, - persistAccessToken: false, - }; - - const logtoClient = new LogtoClient(logtoConfig); - - await logtoClient.signIn(demoAppRedirectUri); - - expect(logtoClient.navigateUrl).toBeTruthy(); - - const interactionCookie = await visitSignInUri(logtoClient.navigateUrl); - - const username = generateUsername(); - const password = generatePassword(); - - await registerUserWithUsernameAndPassword(username, password, interactionCookie); - - const interactionCookieWithSession = await signInWithUsernameAndPassword( - username, - password, - interactionCookie - ); - - const signInCallbackUri = await consentUserAndGetSignInCallbackUri( - interactionCookieWithSession - ); - - await logtoClient.handleSignInCallback(signInCallbackUri); - - expect(logtoClient.isAuthenticated).toBeTruthy(); + expect(async () => { + await registerUserAndSignIn(); + }).not.toThrow(); }); });