M: Setup testing mocks

This commit is contained in:
Ivan 2025-03-02 19:28:32 +03:00
parent 03578aa0b5
commit 338cb9543c
11 changed files with 176 additions and 18 deletions

View File

@ -66,6 +66,7 @@ This readme file is used mostly to document project dependencies and conventions
- eslint-plugin-simple-import-sort - eslint-plugin-simple-import-sort
- eslint-plugin-react-hooks - eslint-plugin-react-hooks
- eslint-plugin-tsdoc - eslint-plugin-tsdoc
- eslint-plugin-playwright
- babel-plugin-react-compiler - babel-plugin-react-compiler
- vite - vite
- jest - jest

View File

@ -77,18 +77,6 @@ class AuthSerializer(serializers.Serializer):
} }
class UserInfoSerializer(serializers.ModelSerializer):
''' Serializer: User data. '''
class Meta:
''' serializer metadata. '''
model = models.User
fields = [
'id',
'first_name',
'last_name',
]
class UserSerializer(serializers.ModelSerializer): class UserSerializer(serializers.ModelSerializer):
''' Serializer: User data. ''' ''' Serializer: User data. '''
id = serializers.IntegerField(read_only=True) id = serializers.IntegerField(read_only=True)

View File

@ -6,6 +6,7 @@ import reactCompilerPlugin from 'eslint-plugin-react-compiler';
import reactHooksPlugin from 'eslint-plugin-react-hooks'; import reactHooksPlugin from 'eslint-plugin-react-hooks';
import importPlugin from 'eslint-plugin-import'; import importPlugin from 'eslint-plugin-import';
import simpleImportSort from 'eslint-plugin-simple-import-sort'; import simpleImportSort from 'eslint-plugin-simple-import-sort';
import playwright from 'eslint-plugin-playwright';
export default [ export default [
...typescriptPlugin.configs.recommendedTypeChecked, ...typescriptPlugin.configs.recommendedTypeChecked,
@ -20,11 +21,16 @@ export default [
ecmaVersion: 'latest', ecmaVersion: 'latest',
sourceType: 'module', sourceType: 'module',
globals: { ...globals.browser, ...globals.es2020, ...globals.jest }, globals: { ...globals.browser, ...globals.es2020, ...globals.jest },
project: ['./tsconfig.json', './tsconfig.node.json'], project: ['./tsconfig.json', './tsconfig.vite.json', './tsconfig.test.json'],
projectService: true projectService: true
} }
} }
}, },
{
...playwright.configs['flat/recommended'],
files: ['tests/**'],
rules: { ...playwright.configs['flat/recommended'].rules }
},
{ {
plugins: { plugins: {
'react': reactPlugin, 'react': reactPlugin,

View File

@ -53,6 +53,7 @@
"babel-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216", "babel-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216",
"eslint": "^9.21.0", "eslint": "^9.21.0",
"eslint-plugin-import": "^2.31.0", "eslint-plugin-import": "^2.31.0",
"eslint-plugin-playwright": "^2.2.0",
"eslint-plugin-react": "^7.37.4", "eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216", "eslint-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216",
"eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-hooks": "^5.1.0",
@ -5738,6 +5739,54 @@
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
}, },
"node_modules/eslint-plugin-playwright": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-2.2.0.tgz",
"integrity": "sha512-qSQpAw7RcSzE3zPp8FMGkthaCWovHZ/BsXtpmnGax9vQLIovlh1bsZHEa2+j2lv9DWhnyeLM/qZmp7ffQZfQvg==",
"dev": true,
"license": "MIT",
"workspaces": [
"examples"
],
"dependencies": {
"globals": "^13.23.0"
},
"engines": {
"node": ">=16.6.0"
},
"peerDependencies": {
"eslint": ">=8.40.0"
}
},
"node_modules/eslint-plugin-playwright/node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"type-fest": "^0.20.2"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-plugin-playwright/node_modules/type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-plugin-react": { "node_modules/eslint-plugin-react": {
"version": "7.37.4", "version": "7.37.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz",

View File

@ -59,6 +59,7 @@
"babel-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216", "babel-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216",
"eslint": "^9.21.0", "eslint": "^9.21.0",
"eslint-plugin-import": "^2.31.0", "eslint-plugin-import": "^2.31.0",
"eslint-plugin-playwright": "^2.2.0",
"eslint-plugin-react": "^7.37.4", "eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216", "eslint-plugin-react-compiler": "^19.0.0-beta-21e868a-20250216",
"eslint-plugin-react-hooks": "^5.1.0", "eslint-plugin-react-hooks": "^5.1.0",

View File

@ -6,9 +6,8 @@ test('should load the homepage and display login button', async ({ page }) => {
await authAnonymous(page); await authAnonymous(page);
await page.goto('/'); await page.goto('/');
await page.waitForSelector('.h-full > .mr-1');
await expect(page).toHaveTitle('Концепт Портал'); await expect(page).toHaveTitle('Концепт Портал');
await page.click('.h-full > .mr-1'); await page.locator('.h-full > .mr-1').click();
await expect(page.getByText('Логин или email')).toBeVisible(); await expect(page.getByText('Логин или email')).toBeVisible();
}); });

View File

@ -1,9 +1,43 @@
import { type Page } from '@playwright/test'; import { type Page } from '@playwright/test';
import { type ICurrentUser } from '../../src/features/auth/backend/types';
import { BACKEND_URL } from '../constants'; import { BACKEND_URL } from '../constants';
const dataAnonymousAuth: ICurrentUser = {
id: null,
username: '',
is_staff: false,
editor: []
};
const dataAdminAuth: ICurrentUser = {
id: 1,
username: 'admin',
is_staff: true,
editor: []
};
const dataUserAuth: ICurrentUser = {
id: 2,
username: 'user',
is_staff: false,
editor: [2]
};
export async function authAnonymous(page: Page) { export async function authAnonymous(page: Page) {
await page.route(`${BACKEND_URL}/users/api/auth`, async route => { await page.route(`${BACKEND_URL}/users/api/auth`, async route => {
await route.fulfill({ json: { id: null } }); await route.fulfill({ json: dataAnonymousAuth });
});
}
export async function authAdmin(page: Page) {
await page.route(`${BACKEND_URL}/users/api/auth`, async route => {
await route.fulfill({ json: dataAdminAuth });
});
}
export async function authUser(page: Page) {
await page.route(`${BACKEND_URL}/users/api/auth`, async route => {
await route.fulfill({ json: dataUserAuth });
}); });
} }

View File

@ -0,0 +1,72 @@
import { type Page } from '@playwright/test';
import {
type IUpdateProfileDTO,
type IUserInfo,
type IUserProfile,
type IUserSignupDTO
} from '../../src/features/users/backend/types';
import { BACKEND_URL } from '../constants';
const dataActiveUsers: IUserInfo[] = [
{
id: 1,
first_name: 'Admin',
last_name: 'User'
},
{
id: 2,
first_name: 'User',
last_name: 'User'
}
];
let dataUserProfile: IUserProfile = {
id: 1,
username: 'user',
email: 'user@example.com',
first_name: 'User',
last_name: 'User'
};
export async function setupUsers(page: Page) {
await page.route(`${BACKEND_URL}/users/api/active-users`, async route => {
await route.fulfill({ json: dataActiveUsers });
});
}
export async function setupUserProfile(page: Page) {
await page.route(`${BACKEND_URL}/users/api/profile`, async route => {
await route.fulfill({ json: dataUserProfile });
});
}
export async function setupUserSignup(page: Page) {
await page.route(`${BACKEND_URL}/users/api/signup`, async route => {
const data = route.request().postDataJSON() as IUserSignupDTO;
const newID = dataActiveUsers.length + 1;
dataActiveUsers.push({
id: newID,
first_name: data.first_name,
last_name: data.last_name
});
dataUserProfile = {
id: newID,
username: data.username,
email: data.email,
first_name: data.first_name,
last_name: data.last_name
};
await route.fulfill({ json: dataUserProfile });
});
}
export async function setupUserProfileUpdate(page: Page) {
await page.route(`${BACKEND_URL}/users/api/profile`, async route => {
dataUserProfile = {
...dataUserProfile,
...(route.request().postDataJSON() as IUpdateProfileDTO)
};
await route.fulfill({ json: dataUserProfile });
});
}

View File

@ -28,5 +28,5 @@
}, },
"types": ["vite/client"], "types": ["vite/client"],
"include": ["src"], "include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }] "references": [{ "path": "./tsconfig.vite.json" }]
} }

View File

@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": ["playwright/test"],
"isolatedModules": false
},
"include": ["src", "tests"]
}

View File

@ -11,5 +11,5 @@
"@/*": ["*"] "@/*": ["*"]
} }
}, },
"include": ["vite.config.ts", "package.json", "playwright.config.ts", "tests", "src"] "include": ["vite.config.ts", "package.json", "playwright.config.ts"]
} }