Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
79289457c9 | |||
5f386c0f4e | |||
33c8f863a1 | |||
|
dd16f42995 | ||
f3e93bae19 | |||
07728cbbb0 | |||
17697d7f77 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.idea
|
.idea
|
||||||
|
coverage/
|
1
__mocks__/fileMock.js
Normal file
1
__mocks__/fileMock.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = 'test-file-stub';
|
11
__tests__/AccountButtons.test.tsx
Normal file
11
__tests__/AccountButtons.test.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import AccountButtons from '../src/components/account/AccountButtons.jsx';
|
||||||
|
|
||||||
|
describe('AccountButtons Component', () => {
|
||||||
|
it('should render the Back link', () => {
|
||||||
|
render(<AccountButtons registered={false} />);
|
||||||
|
const backLinkElement = screen.getByRole('link', { name: /back/i });
|
||||||
|
expect(backLinkElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
18
__tests__/ActionButton.test.tsx
Normal file
18
__tests__/ActionButton.test.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen, fireEvent } from '@testing-library/react';
|
||||||
|
import ActionButton from '../src/components/account/ActionButton.jsx';
|
||||||
|
|
||||||
|
describe('ActionButton Component', () => {
|
||||||
|
it('should render with the correct title and call the action when clicked', () => {
|
||||||
|
const mockAction = jest.fn();
|
||||||
|
const title = 'Click Me';
|
||||||
|
|
||||||
|
render(<ActionButton action={mockAction} title={title} />);
|
||||||
|
|
||||||
|
const buttonElement = screen.getByText(title);
|
||||||
|
expect(buttonElement).toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.click(buttonElement);
|
||||||
|
expect(mockAction).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
23
__tests__/Card.test.tsx
Normal file
23
__tests__/Card.test.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen, fireEvent } from '@testing-library/react';
|
||||||
|
import Card from '../src/components/home/Card.jsx';
|
||||||
|
|
||||||
|
describe('Card Component', () => {
|
||||||
|
it('should render the Card component with the given ID', () => {
|
||||||
|
const testId = '123';
|
||||||
|
render(<Card id={testId} color={"FFA500FF"}/>);
|
||||||
|
|
||||||
|
const cardElement = screen.getByText(/123/i);
|
||||||
|
expect(cardElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should store the ID in local storage when clicked', () => {
|
||||||
|
const testId = '456';
|
||||||
|
render(<Card id={testId} color={"FFA500FF"}/>);
|
||||||
|
|
||||||
|
const cardElement = screen.getByText(/456/i);
|
||||||
|
fireEvent.click(cardElement);
|
||||||
|
|
||||||
|
expect(localStorage.setItem).toHaveBeenCalledWith('selectedId', testId);
|
||||||
|
});
|
||||||
|
});
|
24
__tests__/Helloitem.test.tsx
Normal file
24
__tests__/Helloitem.test.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import HelloItem from '../src/components/account/HelloItem.jsx';
|
||||||
|
|
||||||
|
describe('HelloItem Component', () => {
|
||||||
|
it('should display a personalized greeting when nickname is provided', () => {
|
||||||
|
const nickname = 'JohnDoe';
|
||||||
|
const id = '12345';
|
||||||
|
|
||||||
|
render(<HelloItem nickname={nickname} id={id} />);
|
||||||
|
|
||||||
|
const greetingElement = screen.getByText(`Hello, ${nickname}!`);
|
||||||
|
const idElement = screen.getByText(`Your ID: ${id}`);
|
||||||
|
expect(greetingElement).toBeInTheDocument();
|
||||||
|
expect(idElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display a default message when nickname is not provided', () => {
|
||||||
|
render(<HelloItem nickname="" id="12345" />);
|
||||||
|
|
||||||
|
const defaultMessage = screen.getByText("You don't have an account :(");
|
||||||
|
expect(defaultMessage).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
60
__tests__/Home.test.jsx
Normal file
60
__tests__/Home.test.jsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import configureStore from "redux-mock-store";
|
||||||
|
import Home from "src/pages/Home";
|
||||||
|
import { useGetChatsQuery } from "src/backend/redux/api_slice";
|
||||||
|
|
||||||
|
// Mock Redux store
|
||||||
|
const mockStore = configureStore([]);
|
||||||
|
|
||||||
|
// Mock the useGetChatsQuery hook
|
||||||
|
jest.mock("src/backend/redux/api_slice", () => ({
|
||||||
|
useGetChatsQuery: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("Home Page", () => {
|
||||||
|
let store;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
store = mockStore({});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders Home page with loading state", () => {
|
||||||
|
useGetChatsQuery.mockReturnValue({ isLoading: true });
|
||||||
|
|
||||||
|
render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<Home />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByText(/loading/i)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders Home page with chat data", () => {
|
||||||
|
const chatsData = [{ id: 1, name: "Chat 1" }, { id: 2, name: "Chat 2" }];
|
||||||
|
useGetChatsQuery.mockReturnValue({ data: chatsData, isLoading: false });
|
||||||
|
|
||||||
|
render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<Home />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByText("Chat 1")).toBeInTheDocument();
|
||||||
|
expect(screen.getByText("Chat 2")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders error message when fetching chats fails", () => {
|
||||||
|
useGetChatsQuery.mockReturnValue({ error: true, isLoading: false });
|
||||||
|
|
||||||
|
render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<Home />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByText(/error/i)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
41
__tests__/InputField.test.tsx
Normal file
41
__tests__/InputField.test.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen, fireEvent } from '@testing-library/react';
|
||||||
|
import InputField from '../src/components/reg/InputField.jsx';
|
||||||
|
|
||||||
|
describe('InputField Component', () => {
|
||||||
|
it('should render with the correct title and placeholder', () => {
|
||||||
|
const title = 'Username';
|
||||||
|
const placeholder = 'Enter your username';
|
||||||
|
|
||||||
|
render(<InputField title={title} placeholder={placeholder} value="" setValue={() => {}} />);
|
||||||
|
|
||||||
|
const titleElement = screen.getByText(title);
|
||||||
|
const inputElement = screen.getByPlaceholderText(placeholder);
|
||||||
|
|
||||||
|
expect(titleElement).toBeInTheDocument();
|
||||||
|
expect(inputElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call setValue on input change', () => {
|
||||||
|
const mockSetValue = jest.fn();
|
||||||
|
const newValue = 'testUser';
|
||||||
|
|
||||||
|
render(<InputField title="Username" value="" setValue={mockSetValue} />);
|
||||||
|
|
||||||
|
const inputElement = screen.getByRole('textbox');
|
||||||
|
fireEvent.change(inputElement, { target: { value: newValue } });
|
||||||
|
|
||||||
|
expect(mockSetValue).toHaveBeenCalledWith(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call submit function when Enter key is pressed', () => {
|
||||||
|
const mockSubmit = jest.fn();
|
||||||
|
|
||||||
|
render(<InputField title="Username" value="" setValue={() => {}} submit={mockSubmit} />);
|
||||||
|
|
||||||
|
const inputElement = screen.getByRole('textbox');
|
||||||
|
fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' });
|
||||||
|
|
||||||
|
expect(mockSubmit).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
16
__tests__/NavButton.test.tsx
Normal file
16
__tests__/NavButton.test.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import NavButton from '../src/components/init/NavButton.jsx';
|
||||||
|
|
||||||
|
describe('NavButton Component', () => {
|
||||||
|
it('should render the NavButton with the correct text and link', () => {
|
||||||
|
const navLink = '/home';
|
||||||
|
const buttonText = 'Go Home';
|
||||||
|
|
||||||
|
render(<NavButton nav={navLink} text={buttonText} />);
|
||||||
|
|
||||||
|
const linkElement = screen.getByText(buttonText);
|
||||||
|
expect(linkElement).toBeInTheDocument();
|
||||||
|
expect(linkElement.closest('a')).toHaveAttribute('href', navLink);
|
||||||
|
});
|
||||||
|
});
|
23
__tests__/Search.test.tsx
Normal file
23
__tests__/Search.test.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen, fireEvent } from '@testing-library/react';
|
||||||
|
import Search from '../src/components/home/Search.jsx';
|
||||||
|
|
||||||
|
describe('Search Component', () => {
|
||||||
|
it('should render the Search button', () => {
|
||||||
|
render(<Search search={() => {}} item="testItem" />);
|
||||||
|
const searchButton = screen.getByText(/find/i);
|
||||||
|
expect(searchButton).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the search function with the correct item when clicked', () => {
|
||||||
|
const mockSearch = jest.fn();
|
||||||
|
const item = 'testItem';
|
||||||
|
|
||||||
|
render(<Search search={mockSearch} item={item} />);
|
||||||
|
|
||||||
|
const searchButton = screen.getByText(/find/i);
|
||||||
|
fireEvent.click(searchButton);
|
||||||
|
|
||||||
|
expect(mockSearch).toHaveBeenCalledWith(item);
|
||||||
|
});
|
||||||
|
});
|
52
__tests__/SignIn.test.jsx
Normal file
52
__tests__/SignIn.test.jsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { render, screen, fireEvent } from "@testing-library/react";
|
||||||
|
import SignIn from "src/pages/SignIn";
|
||||||
|
import { displayMessage } from "src/backend/notifications/notifications";
|
||||||
|
import { post } from "src/backend/api";
|
||||||
|
|
||||||
|
// Mock the displayMessage and post functions
|
||||||
|
jest.mock("src/backend/notifications/notifications", () => ({
|
||||||
|
displayMessage: jest.fn(),
|
||||||
|
}));
|
||||||
|
jest.mock("src/backend/api", () => ({
|
||||||
|
post: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("SignIn Page", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("renders SignIn form", () => {
|
||||||
|
render(<SignIn />);
|
||||||
|
expect(screen.getByLabelText(/username/i)).toBeInTheDocument();
|
||||||
|
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
|
||||||
|
expect(screen.getByText(/sign in/i)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("displays error message on failed login", async () => {
|
||||||
|
post.mockResolvedValueOnce({ ok: false, data: { message: "Invalid credentials" } });
|
||||||
|
|
||||||
|
render(<SignIn />);
|
||||||
|
fireEvent.change(screen.getByLabelText(/username/i), { target: { value: "user" } });
|
||||||
|
fireEvent.change(screen.getByLabelText(/password/i), { target: { value: "password" } });
|
||||||
|
fireEvent.click(screen.getByText(/sign in/i));
|
||||||
|
|
||||||
|
expect(await screen.findByText(/invalid credentials/i)).toBeInTheDocument();
|
||||||
|
expect(displayMessage).toHaveBeenCalledWith("Invalid credentials", "error");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("displays additional info message after multiple login attempts", async () => {
|
||||||
|
post.mockResolvedValueOnce({ ok: false, data: { message: "Invalid credentials" } });
|
||||||
|
|
||||||
|
render(<SignIn />);
|
||||||
|
fireEvent.change(screen.getByLabelText(/username/i), { target: { value: "user" } });
|
||||||
|
fireEvent.change(screen.getByLabelText(/password/i), { target: { value: "password" } });
|
||||||
|
|
||||||
|
// Simulate two failed login attempts
|
||||||
|
fireEvent.click(screen.getByText(/sign in/i));
|
||||||
|
fireEvent.click(screen.getByText(/sign in/i));
|
||||||
|
|
||||||
|
expect(displayMessage).toHaveBeenCalledWith("Note that you need to enter your ID name", "info");
|
||||||
|
});
|
||||||
|
});
|
13
__tests__/helloworld.test.tsx.no
Normal file
13
__tests__/helloworld.test.tsx.no
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
describe('Hello World Test', () => {
|
||||||
|
it('should display hello world', () => {
|
||||||
|
// Render a simple component
|
||||||
|
render(<div>Hello World</div>);
|
||||||
|
|
||||||
|
// Check if "Hello World" is in the document
|
||||||
|
const helloWorldElement = screen.getByText(/hello world/i);
|
||||||
|
expect(helloWorldElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
7
babel.config.js
Normal file
7
babel.config.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@babel/preset-env',
|
||||||
|
'@babel/preset-react',
|
||||||
|
'@babel/preset-typescript'],
|
||||||
|
};
|
||||||
|
|
28
jest.config.ts
Normal file
28
jest.config.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import type { Config } from 'jest';
|
||||||
|
import { defaults } from 'jest-config';
|
||||||
|
|
||||||
|
const config: Config = {
|
||||||
|
clearMocks: true,
|
||||||
|
collectCoverage: true,
|
||||||
|
collectCoverageFrom: [
|
||||||
|
"src/components/**/*.{js,jsx,ts,tsx}", // Include all components
|
||||||
|
"src/pages/**/*.{js,jsx,ts,tsx}",
|
||||||
|
"!src/**/*.test.{js,jsx,ts,tsx}", // Exclude test files
|
||||||
|
"!src/**/index.{js,jsx,ts,tsx}", // Optionally exclude index files
|
||||||
|
],
|
||||||
|
coverageDirectory: "coverage",
|
||||||
|
coverageProvider: "v8",
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||||
|
testEnvironment: "jsdom",
|
||||||
|
// transform: {
|
||||||
|
// '^.+\\.(ts|tsx|js|jsx)$': 'babel-jest',
|
||||||
|
// },
|
||||||
|
moduleNameMapper: {
|
||||||
|
"^@/src/(.*)$": "<rootDir>/src/$1", // Map '@/src' to the 'src' folder
|
||||||
|
"^src/(.*)$": "<rootDir>/src/$1", // Map 'src' to the 'src' folder
|
||||||
|
"\\.(svg|png|jpg|jpeg|gif)$": "<rootDir>/__mocks__/fileMock.js", // Add this line
|
||||||
|
},
|
||||||
|
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx', 'js', 'jsx'],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
17
jest.setup.ts
Normal file
17
jest.setup.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { jest } from '@jest/globals';
|
||||||
|
import '@testing-library/jest-dom';
|
||||||
|
import mockedConfig from './bro.config.js'
|
||||||
|
|
||||||
|
jest.mock('@brojs/cli', () => {
|
||||||
|
return {
|
||||||
|
getNavigations() {
|
||||||
|
return mockedConfig.navigations
|
||||||
|
},
|
||||||
|
getNavigationsValue(key) {
|
||||||
|
return mockedConfig.navigations[key]
|
||||||
|
},
|
||||||
|
getConfigValue(key) {
|
||||||
|
return mockedConfig.config[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
5000
package-lock.json
generated
5000
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@ -28,8 +28,25 @@
|
|||||||
"start": "brojs server --port=8099 --with-open-browser",
|
"start": "brojs server --port=8099 --with-open-browser",
|
||||||
"build": "npm run clean && brojs build --dev",
|
"build": "npm run clean && brojs build --dev",
|
||||||
"build:prod": "npm run clean && brojs build",
|
"build:prod": "npm run clean && brojs build",
|
||||||
"clean": "rimraf dist"
|
"clean": "rimraf dist",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watchAll"
|
||||||
},
|
},
|
||||||
"name": "enterfront",
|
"name": "enterfront",
|
||||||
"version": "0.5.4"
|
"version": "0.5.4",
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.25.8",
|
||||||
|
"@babel/preset-env": "^7.25.8",
|
||||||
|
"@babel/preset-react": "^7.25.7",
|
||||||
|
"@babel/preset-typescript": "^7.25.7",
|
||||||
|
"@testing-library/jest-dom": "^6.6.2",
|
||||||
|
"@testing-library/react": "^16.0.1",
|
||||||
|
"@types/jest": "^29.5.13",
|
||||||
|
"babel-jest": "^29.7.0",
|
||||||
|
"jest": "^29.7.0",
|
||||||
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
|
"redux-mock-store": "^1.5.4",
|
||||||
|
"ts-jest": "^29.2.5",
|
||||||
|
"ts-node": "^10.9.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import {getConfigValue} from "@brojs/cli";
|
|||||||
const LOCAL = "http://localhost:8099";
|
const LOCAL = "http://localhost:8099";
|
||||||
const DEV = "https://dev.bro-js.ru";
|
const DEV = "https://dev.bro-js.ru";
|
||||||
|
|
||||||
export const BASE_API_URL = DEV + getConfigValue("enterfront.api");
|
export const BASE_API_URL = LOCAL + getConfigValue("enterfront.api");
|
||||||
|
|
||||||
// fetch(`${BASE_API_URL}/books/list`)
|
// fetch(`${BASE_API_URL}/books/list`)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ const InputField = (props) => {
|
|||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
if (props.submit) {
|
if (props.submit) {
|
||||||
props.enter(props.submit);
|
props.submit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"target": "es6",
|
"target": "es6",
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"typeRoots": ["node_modules/@types", "src/typings"],
|
"typeRoots": ["node_modules/@types", "src/typings"],
|
||||||
"types" : ["webpack-env", "node"],
|
"types" : ["webpack-env", "node", "jest"],
|
||||||
"resolveJsonModule": true
|
"resolveJsonModule": true
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
|
Loading…
Reference in New Issue
Block a user