🧪 Add some tests

master
Antoine PEREDERII 8 months ago
parent cde37fcdd8
commit a043f05832

@ -14,4 +14,4 @@ steps:
settings:
sonar_host: https://codefirst.iut.uca.fr/sonar/
sonar_token:
from_secret: SECRET_SONAR_LOGINg
from_secret: SECRET_SONAR_LOGIN

@ -0,0 +1,26 @@
import React from 'react';
import { shallow } from 'enzyme';
import Categ from './Categ';
import { Text, View } from 'react-native';
import {describe, expect, it} from "@jest/globals";
describe('Categ Component', () => {
it('renders correctly', () => {
const category = { name: 'Test Category' };
const wrapper = shallow(<Categ category={category} />);
expect(wrapper).toMatchSnapshot();
});
it('displays category name', () => {
const category = { name: 'Test Category' };
const wrapper = shallow(<Categ category={category} />);
expect(wrapper.find(Text).prop('children')).toEqual(category.name);
});
it('applies correct styles', () => {
const category = { name: 'Test Category' };
const wrapper = shallow(<Categ category={category} />);
const containerStyle = wrapper.find(View).prop('style');
expect(containerStyle).toEqual(expect.objectContaining(styles.bottomContainer));
});
});

@ -0,0 +1,36 @@
import React from 'react';
import { shallow } from 'enzyme';
import Categs from './Categs';
import { FlatList } from 'react-native';
import Categ from './Categ';
import { Category } from '../model/Category';
import {describe, expect, it} from "@jest/globals";
describe('Categs Component', () => {
const categories: Category[] = [
new Category('Category 1', 10),
new Category('Category 2', 5),
new Category('Category 3', 15),
];
it('renders correctly', () => {
const wrapper = shallow(<Categs categories={categories} />);
expect(wrapper).toMatchSnapshot();
});
it('renders FlatList with correct props', () => {
const wrapper = shallow(<Categs categories={categories} />);
const flatList = wrapper.find(FlatList);
expect(flatList.exists()).toBeTruthy();
expect(flatList.prop('showsHorizontalScrollIndicator')).toBe(false);
expect(flatList.prop('horizontal')).toBe(true);
expect(flatList.prop('data')).toEqual(categories.sort((a, b) => b.number - a.number));
expect(flatList.prop('keyExtractor')).toBeInstanceOf(Function);
expect(flatList.prop('renderItem')).toBeInstanceOf(Function);
});
it('renders correct number of Categ components', () => {
const wrapper = shallow(<Categs categories={categories} />);
expect(wrapper.find(Categ)).toHaveLength(categories.length);
});
});

@ -0,0 +1,54 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import JokeDetail from '../path/to/JokeDetail';
import {describe} from "@jest/globals"; // Remplacez le chemin par le bon chemin
describe('JokeDetail Component', () => {
const sampleJoke = {
id: '1',
type: 'Sample',
image: 'sample-image-url',
description: () => 'Sample Joke Description'
};
const customJoke = {
id: '2',
type: 'Custom',
image: 'custom-image-url',
description: () => 'Custom Joke Description'
};
test('renders joke image', () => {
const { getByTestId } = render(<JokeDetail joke={sampleJoke} />);
const jokeImage = getByTestId('joke-image');
expect(jokeImage).toBeTruthy();
});
test('renders joke description when toggled', () => {
const { getByText } = render(<JokeDetail joke={sampleJoke} />);
const toggleButton = getByText('LA CHUTE');
fireEvent.press(toggleButton);
const jokeDescription = getByText('Sample Joke Description');
expect(jokeDescription).toBeTruthy();
});
test('toggles favorite icon when pressed', () => {
const { getByTestId } = render(<JokeDetail joke={sampleJoke} />);
const favoriteButton = getByTestId('favorite-button');
fireEvent.press(favoriteButton);
expect(favoriteButton.props.source).toEqual(require('../assets/plain_favorite_icon.png'));
});
test('calls deleteCustomJokes and updates list when delete button is pressed for custom joke', () => {
const deleteMock = jest.fn();
const dispatchMock = jest.fn();
jest.mock('../redux/thunk/DeleteThunk', () => ({ deleteCustomJoke: deleteMock }));
jest.mock('react-redux', () => ({ useDispatch: () => dispatchMock }));
const { getByTestId } = render(<JokeDetail joke={customJoke} />);
const deleteButton = getByTestId('delete-button');
fireEvent.press(deleteButton);
expect(deleteMock).toHaveBeenCalledWith(customJoke.id);
expect(dispatchMock).toHaveBeenCalledTimes(2); // Assuming one dispatch for delete and one for update list
});
});

@ -0,0 +1,25 @@
import { Category } from './Category';
import {describe, expect, it} from "@jest/globals";
describe('Category Class Constructor', () => {
it('should create a new Category object', () => {
const category = new Category('name', 5);
expect(category).toBeDefined();
expect(category.name).toBe('name');
expect(category.number).toBe(5);
});
});
describe('Category Class Accessors', () => {
it('should set and get the name correctly', () => {
const category = new Category('name', 5);
category.name = 'newName';
expect(category.name).toBe('newName');
});
it('should set and get the number correctly', () => {
const category = new Category('name', 5);
category.number = 10;
expect(category.number).toBe(10);
});
});

@ -0,0 +1,35 @@
import { CustomJoke } from './CustomJoke';
import {describe, expect, test} from "@jest/globals"; // Remplacez le chemin par le bon chemin
describe('CustomJoke Class', () => {
const id = '1';
const type = 'Custom';
const setup = 'Why did the developer go broke?';
const image = 'custom-image-url';
const punchline = 'Because he used up all his cache';
test('creates a new instance of CustomJoke', () => {
const customJoke = new CustomJoke(id, type, setup, image, punchline);
expect(customJoke).toBeInstanceOf(CustomJoke);
expect(customJoke.id).toEqual(id);
expect(customJoke.type).toEqual(type);
expect(customJoke.setup).toEqual(setup);
expect(customJoke.punchline).toEqual(punchline);
expect(customJoke.image).toEqual(image);
});
test('updates CustomJoke properties', () => {
const newSetup = 'Why do programmers prefer dark mode?';
const newImage = 'new-custom-image-url';
const newPunchline = 'Because light attracts bugs';
const customJoke = new CustomJoke(id, type, setup, image, punchline);
customJoke.setup = newSetup;
customJoke.image = newImage;
customJoke.punchline = newPunchline;
expect(customJoke.setup).toEqual(newSetup);
expect(customJoke.image).toEqual(newImage);
expect(customJoke.punchline).toEqual(newPunchline);
});
});

@ -0,0 +1,61 @@
const { Joke } = require('./Joke');
const {expect, it, beforeEach, describe} = require("@jest/globals");
// Mock class extending the abstract Joke class
class MockJoke extends Joke {
constructor(type, setup, punchline, image) {
super(type, setup, punchline, image);
}
}
// Test the Joke class
describe('Joke Class', () => {
let joke;
beforeEach(() => {
joke = new MockJoke('type', 'setup', 'punchline', 'image');
});
// Test the constructor
it('should create a new Joke object', () => {
expect(joke).toBeDefined();
expect(joke.type).toBe('type');
expect(joke.setup).toBe('setup');
expect(joke.punchline).toBe('punchline');
expect(joke.image).toBe('image');
});
// Test the summary() method
it('should return a summary of the joke', () => {
expect(joke.summary()).toBe('punchline');
});
// Test the description() method
it('should return a textual description of the joke', () => {
expect(joke.description()).toBe('type, punchline');
});
// Test setting and getting the type
it('should set and get the type correctly', () => {
joke.type = 'newType';
expect(joke.type).toBe('newType');
});
// Test setting and getting the setup
it('should set and get the setup correctly', () => {
joke.setup = 'newSetup';
expect(joke.setup).toBe('newSetup');
});
// Test setting and getting the punchline
it('should set and get the punchline correctly', () => {
joke.punchline = 'newPunchline';
expect(joke.punchline).toBe('newPunchline');
});
// Test setting and getting the image
it('should set and get the image correctly', () => {
joke.image = 'newImage';
expect(joke.image).toBe('newImage');
});
});

12048
src/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -7,27 +7,57 @@
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
"web": "expo start --web",
"test": "jest"
},
"dependencies": {
"@jest/globals": "^29.7.0",
"@react-native-async-storage/async-storage": "^1.23.1",
"@react-navigation/bottom-tabs": "^6.5.11",
"@react-navigation/native": "^6.1.10",
"@react-navigation/stack": "^6.3.21",
"@reduxjs/toolkit": "^2.2.1",
"@testing-library/jest-native": "^5.4.3",
"@testing-library/react-native": "^12.4.5",
"@types/react": "~18.2.45",
"enzyme": "^3.11.0",
"expo": "~50.0.3",
"expo-status-bar": "~1.11.1",
"jest": "^29.7.0",
"jest-expo": "^50.0.4",
"react": "18.2.0",
"react-native": "0.73.2",
"react-native-gesture-handler": "^2.15.0",
"react-native-safe-area-context": "^4.9.0",
"react-redux": "^9.1.0",
"redux": "^5.0.1",
"redux-thunk": "^3.1.0",
"typescript": "^5.3.0"
},
"devDependencies": {
"@babel/core": "^7.20.0"
"@babel/core": "^7.20.0",
"@types/fetch-mock": "^7.3.8",
"@types/redux-mock-store": "^1.0.6",
"fetch-mock": "^9.11.0",
"redux-mock-store": "^1.5.4"
},
"jest": {
"preset": "jest-expo",
"verbose": true,
"transformIgnorePatterns": [
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)"
],
"testMatch": [
"**.test.js"
],
"testEnvironment": "node",
"testEnvironmentOptions": {
"browsers": [
"chrome",
"firefox",
"safari"
]
}
},
"private": true
}

@ -0,0 +1,23 @@
import { ActionType, Action, setCategoriesList } from './CategoryAction';
import { Category } from '../../model/Category';
import {describe, expect, it} from "@jest/globals";
describe('Actions', () => {
describe('setCategoriesList', () => {
it('should create an action to set categories list', () => {
const categoriesList: Category[] = [
new Category('Category 1', 1),
new Category('Category 2', 2)
];
const expectedAction: Action = {
type: ActionType.FETCH_CATEGORIES,
payload: categoriesList,
};
const action = setCategoriesList(categoriesList);
expect(action).toEqual(expectedAction);
});
});
});

@ -0,0 +1,56 @@
import { ActionType, Action, setPostJoke, setCustomJokesList, setCustomJokeById, setDeleteJoke } from './CustomJoke';
import { CustomJoke } from '../../model/CustomJoke';
import {describe, expect, it} from "@jest/globals";
describe('Actions', () => {
describe('setPostJoke', () => {
it('should create an action to post a custom joke', () => {
const customJoke: CustomJoke = new CustomJoke('1', 'pun', 'Setup', 'https://example.com/image.jpg', 'Punchline');
const expectedAction: Action = {
type: ActionType.POST_CUSTOM_JOKE,
payload: customJoke,
};
const action = setPostJoke(customJoke);
expect(action).toEqual(expectedAction);
});
});
describe('setCustomJokesList', () => {
it('should create an action to set custom jokes list', () => {
const customJokesList: CustomJoke[] = [
new CustomJoke('1', 'pun', 'Setup 1', 'https://example.com/image1.jpg', 'Punchline 1'),
new CustomJoke('2', 'pun', 'Setup 2', 'https://example.com/image2.jpg', 'Punchline 2')
];
const expectedAction: Action = {
type: ActionType.FETCH_CUSTOM_JOKES,
payload: customJokesList,
};
const action = setCustomJokesList(customJokesList);
expect(action).toEqual(expectedAction);
});
});
describe('setCustomJokeById', () => {
it('should create an action to set custom joke by ID', () => {
const customJoke: CustomJoke = new CustomJoke('1', 'pun', 'Setup', 'https://example.com/image.jpg', 'Punchline');
const expectedAction: Action = {
type: ActionType.FETCH_JOKES_BY_ID,
payload: customJoke,
};
const action = setCustomJokeById(customJoke);
expect(action).toEqual(expectedAction);
});
});
describe('setDeleteJoke', () => {
it('should create an action to delete a custom joke', () => {
const jokeId = '1';
const expectedAction: Action = {
type: ActionType.DELETE_CUSTOM_JOKE,
payload: jokeId,
};
const action = setDeleteJoke(jokeId);
expect(action).toEqual(expectedAction);
});
});
});

@ -0,0 +1,32 @@
import { ActionType, Action, setJokesList, setJokeById } from './SampleAction';
import { SampleJoke } from '../../model/SampleJoke';
import {describe, expect, it} from "@jest/globals";
describe('Actions', () => {
describe('setJokesList', () => {
it('should create an action to set jokes list', () => {
const jokesList: SampleJoke[] = [
new SampleJoke(1, 'pun', 'Setup 1', 'https://example.com/image1.jpg', 'Punchline 1'),
new SampleJoke(2, 'pun', 'Setup 2', 'https://example.com/image2.jpg', 'Punchline 2')
];
const expectedAction: Action = {
type: ActionType.FETCH_JOKES,
payload: jokesList,
};
const action = setJokesList(jokesList);
expect(action).toEqual(expectedAction);
});
});
describe('setJokeById', () => {
it('should create an action to set joke by ID', () => {
const joke: SampleJoke = new SampleJoke(1, 'pun', 'Setup', 'https://example.com/image.jpg', 'Punchline');
const expectedAction: Action = {
type: ActionType.FETCH_JOKES_BY_ID,
payload: joke,
};
const action = setJokeById(joke);
expect(action).toEqual(expectedAction);
});
});
});

@ -0,0 +1,23 @@
import categoryReducer from './CategoryReducer';
import { ActionType as CategoryActionType } from '../actions/CategoryAction';
import { Category } from '../../model/Category';
import {describe, expect, it} from "@jest/globals";
describe('Category Reducer', () => {
it('should handle FETCH_CATEGORIES', () => {
const categories = [
new Category('Category 1', 1),
new Category('Category 2', 2)
];
const action = {
type: CategoryActionType.FETCH_CATEGORIES,
payload: categories
};
expect(categoryReducer(undefined, action)).toEqual({
categories: categories
});
});
});

@ -0,0 +1,29 @@
import customReducer from './CustomReducer';
import { ActionType } from '../actions/CustomJoke';
import { CustomJoke } from '../../model/CustomJoke';
import {describe, expect, it} from "@jest/globals";
describe('Custom Reducer', () => {
it('should return the initial state', () => {
expect(customReducer(undefined, {})).toEqual({
customJokes: [],
customJoke: null,
jokeId: ''
});
});
it('should handle POST_CUSTOM_JOKE', () => {
const customJoke: CustomJoke = new CustomJoke('1', 'pun', 'Setup', 'https://example.com/image.jpg', 'Punchline');
const action = {
type: ActionType.POST_CUSTOM_JOKE,
payload: customJoke
};
expect(customReducer(undefined, action)).toEqual({
customJokes: [],
customJoke: customJoke,
jokeId: ''
});
});
});

@ -0,0 +1,22 @@
import themeReducer from './DarkModeReducer';
import { ActionType } from '../actions/DarkModeAction';
import {describe, expect, it} from "@jest/globals";
describe('Theme Reducer', () => {
// it('should return the initial state', () => {
// expect(themeReducer(undefined, {})).toEqual({
// theme: 'dark'
// });
// });
it('should handle SET_THEME', () => {
const action = {
type: ActionType.SET_THEME,
payload: 'light'
};
expect(themeReducer(undefined, action)).toEqual({
theme: 'light'
});
});
});

@ -0,0 +1,61 @@
// Importez les réducteurs et les types d'action appropriés
import categoryReducer from './CategoryReducer';
import customReducer from './CustomReducer';
import themeReducer from './DarkModeReducer';
import sampleReducer from './SampleReducer';
import { ActionType as CategoryActionType } from '../actions/CategoryAction';
import { ActionType as CustomActionType } from '../actions/CustomJoke';
import { ActionType as ThemeActionType } from '../actions/DarkModeAction';
import { ActionType as SampleActionType } from '../actions/SampleAction';
import { Category } from '../../model/Category';
import { CustomJoke } from '../../model/CustomJoke';
import { SampleJoke } from '../../model/SampleJoke';
import {describe, expect, it} from "@jest/globals";
// Tester categoryReducer
describe('Category Reducer', () => {
it('should return the initial state', () => {
expect(categoryReducer(undefined, {})).toEqual({
categories: []
});
});
// Ajouter d'autres tests pour categoryReducer si nécessaire...
});
// Tester customReducer
describe('Custom Reducer', () => {
it('should return the initial state', () => {
expect(customReducer(undefined, {})).toEqual({
customJokes: [],
customJoke: null,
jokeId: ''
});
});
// Ajouter d'autres tests pour customReducer si nécessaire...
});
// Tester themeReducer
describe('Theme Reducer', () => {
it('should return the initial state', () => {
expect(themeReducer(undefined, {})).toEqual({
theme: 'dark'
});
});
// Ajouter d'autres tests pour themeReducer si nécessaire...
});
// Tester sampleReducer
describe('Sample Reducer', () => {
it('should return the initial state', () => {
expect(sampleReducer(undefined, {})).toEqual({
jokes: [],
favoriteJokes: [],
joke: null,
});
});
// Ajouter d'autres tests pour sampleReducer si nécessaire...
});

@ -0,0 +1,29 @@
import store from './store';
import {describe, expect, it} from "@jest/globals";
describe('Redux Store Configuration', () => {
it('should have sampleReducer', () => {
expect(store.getState().sampleReducer).toBeDefined();
});
it('should have categoryReducer', () => {
expect(store.getState().categoryReducer).toBeDefined();
});
it('should have customReducer', () => {
expect(store.getState().customReducer).toBeDefined();
});
it('should have themeReducer', () => {
expect(store.getState().theme).toBeDefined();
});
it('should have favoriteReducer', () => {
expect(store.getState().favorite).toBeDefined();
});
it('should have a configured store', () => {
expect(store).toBeDefined();
expect(store.getState()).toBeDefined();
});
});

@ -0,0 +1,52 @@
import fetchMock from 'fetch-mock';
import thunk from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import { deleteItem } from './DeleteThunk'; // Assurez-vous d'importer correctement votre thunk
import { setDeleteJoke } from '../actions/CustomJoke';
import {afterEach, describe, expect, it, jest} from "@jest/globals";
const middlewares = [thunk];
// @ts-ignore
const mockStore = configureMockStore(middlewares);
describe('deleteItem Thunk', () => {
afterEach(() => {
fetchMock.restore();
});
it('dispatches setDeleteJoke after successful DELETE request', async () => {
const jokeId = '123';
const expectedActions = [setDeleteJoke(jokeId)];
fetchMock.deleteOnce(`https://iut-weather-api.azurewebsites.net/jokes/${jokeId}`, {
status: 200,
});
const store = mockStore({});
// @ts-ignore
await store.dispatch(deleteItem(jokeId));
expect(store.getActions()).toEqual(expectedActions);
});
it('logs an error message if DELETE request fails', async () => {
const jokeId = '123';
fetchMock.deleteOnce(`https://iut-weather-api.azurewebsites.net/jokes/${jokeId}`, {
status: 500,
});
const consoleSpy = jest.spyOn(console, 'log');
consoleSpy.mockImplementation(() => {});
const store = mockStore({});
// @ts-ignore
await store.dispatch(deleteItem(jokeId));
expect(consoleSpy).toHaveBeenCalledWith('Erreur lors de la requête DELETE');
consoleSpy.mockRestore();
});
});

@ -0,0 +1,81 @@
import fetchMock from 'fetch-mock';
import thunk from 'redux-thunk';
import configureMockStore from 'redux-mock-store';
import { getItem, getJokeById, getCustomJokeById } from './GetByThunk'; // Assurez-vous d'importer correctement vos thunks
import { setJokeById } from '../actions/SampleAction';
import {setCustomJokeById} from "../actions/CustomJoke";
import { SampleJoke } from '../../model/SampleJoke';
import { CustomJoke } from '../../model/CustomJoke';
import {afterEach, describe, expect, it, jest} from "@jest/globals";
const middlewares = [thunk];
// @ts-ignore
const mockStore = configureMockStore(middlewares);
describe('getItem Thunk', () => {
afterEach(() => {
fetchMock.restore();
});
it('dispatches setJokeById after successful GET request for SampleJoke', async () => {
const jokeId = 1;
const expectedJoke = new SampleJoke(jokeId, 'type', 'setup', 'image');
fetchMock.getOnce(`https://iut-weather-api.azurewebsites.net/jokes/samples/${jokeId}`, {
status: 200,
body: {
id: jokeId,
type: 'type',
setup: 'setup',
image: 'image',
},
});
const store = mockStore({});
// @ts-ignore
await store.dispatch(getJokeById(parseInt(jokeId)));
expect(store.getActions()).toEqual([setJokeById(expectedJoke)]);
});
it('dispatches setCustomJokeById after successful GET request for CustomJoke', async () => {
const jokeId = '1';
const expectedJoke = new CustomJoke(jokeId, 'type', 'setup', 'image');
fetchMock.getOnce(`https://iut-weather-api.azurewebsites.net/jokes/${jokeId}`, {
status: 200,
body: {
id: jokeId,
type: 'type',
setup: 'setup',
image: 'image',
},
});
const store = mockStore({});
// @ts-ignore
await store.dispatch(getCustomJokeById(jokeId));
expect(store.getActions()).toEqual([setCustomJokeById(expectedJoke)]);
});
it('logs an error message if GET request fails', async () => {
const jokeId = '1';
fetchMock.getOnce(`https://iut-weather-api.azurewebsites.net/jokes/samples/${jokeId}`, {
status: 500,
});
const consoleSpy = jest.spyOn(console, 'log');
consoleSpy.mockImplementation(() => {});
const store = mockStore({});
// @ts-ignore
await store.dispatch(getJokeById(parseInt(jokeId)));
expect(consoleSpy).toHaveBeenCalledWith('Error---------');
});
});

@ -0,0 +1,84 @@
import fetchMock from 'fetch-mock';
import configureMockStore from 'redux-mock-store';
import { getLastSampleJokesList, getCategoriesList } from './GetThunk';
import { setCategoriesList } from '../actions/CategoryAction';
import { SampleJoke } from '../../model/SampleJoke';
import { Category } from '../../model/Category';
import {afterEach, describe, expect, it, jest} from "@jest/globals";
import {setJokesList} from "../actions/SampleAction";
import thunk from "redux-thunk";
const middlewares = [thunk];
// @ts-ignore
const mockStore = configureMockStore(middlewares);
describe('getList Thunk', () => {
afterEach(() => {
fetchMock.restore();
});
it('dispatches setJokesList after successful GET request for LastSampleJokesList', async () => {
const expectedJokesList = [
new SampleJoke('1', 'type1', 'setup1', 'image1'),
new SampleJoke('2', 'type2', 'setup2', 'image2'),
];
fetchMock.getOnce('https://iut-weather-api.azurewebsites.net/jokes/lasts', {
status: 200,
body: expectedJokesList.map(joke => ({
id: joke.id,
type: joke.type,
setup: joke.setup,
image: joke.image,
})),
});
const store = mockStore({});
// @ts-ignore
await store.dispatch(getLastSampleJokesList());
expect(store.getActions()).toEqual([setJokesList(expectedJokesList)]);
});
it('dispatches setCategoriesList after successful GET request for CategoriesList', async () => {
const expectedCategoriesList = [
new Category('Category1', 1),
new Category('Category2', 2),
];
fetchMock.getOnce('https://iut-weather-api.azurewebsites.net/jokes/categories/top', {
status: 200,
body: expectedCategoriesList.map(category => ({
name: category.name,
number: category.number,
})),
});
const store = mockStore({});
// @ts-ignore
await store.dispatch(getCategoriesList());
expect(store.getActions()).toEqual([setCategoriesList(expectedCategoriesList)]);
});
// Tests similaires pour les autres fonctions thunks
it('logs an error message if GET request fails', async () => {
fetchMock.getOnce('https://iut-weather-api.azurewebsites.net/jokes/lasts', {
status: 500,
});
const consoleSpy = jest.spyOn(console, 'log');
consoleSpy.mockImplementation(() => {});
const store = mockStore({});
// @ts-ignore
await store.dispatch(getLastSampleJokesList());
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('Error In getList'));
});
});

@ -0,0 +1,67 @@
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetchMock from 'fetch-mock';
import { setPostJoke } from '../actions/CustomJoke';
import { setItem, postCustomJoke } from './PostThunk';
import {afterEach, describe, expect, it, jest} from "@jest/globals";
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
describe('setItem Thunk', () => {
afterEach(() => {
fetchMock.restore();
});
it('dispatches setPostJoke after successful POST request', async () => {
const mockResponse = { id: '123', type: 'pun', setup: 'Why was the math book sad?', punchline: 'Because it had too many problems.' };
fetchMock.postOnce('https://iut-weather-api.azurewebsites.net/jokes', {
body: mockResponse,
headers: { 'content-type': 'application/json' }
});
const expectedActions = [
setPostJoke(mockResponse)
];
const store = mockStore({});
await store.dispatch(setItem('https://iut-weather-api.azurewebsites.net/jokes', 'pun', 'Why was the math book sad?', 'Because it had too many problems.'));
expect(store.getActions()).toEqual(expectedActions);
});
it('logs an error message if POST request fails', async () => {
fetchMock.postOnce('https://iut-weather-api.azurewebsites.net/jokes', 404);
const consoleSpy = jest.spyOn(console, 'log');
consoleSpy.mockImplementation(() => {});
const store = mockStore({});
await store.dispatch(setItem('https://iut-weather-api.azurewebsites.net/jokes', 'pun', 'Why was the math book sad?', 'Because it had too many problems.'));
expect(consoleSpy).toHaveBeenCalledWith('Erreur lors de la requête POST');
consoleSpy.mockRestore();
});
});
describe('postCustomJoke Thunk', () => {
afterEach(() => {
fetchMock.restore();
});
it('calls setItem with correct parameters', async () => {
const uri = 'https://iut-weather-api.azurewebsites.net/jokes';
const type = 'pun';
const setup = 'Why was the math book sad?';
const punchline = 'Because it had too many problems.';
const store = mockStore({});
const setItemSpy = jest.spyOn(global, 'setItem');
setItemSpy.mockResolvedValueOnce();
await store.dispatch(postCustomJoke(type, setup, punchline));
expect(setItemSpy).toHaveBeenCalledWith(uri, type, setup, punchline);
setItemSpy.mockRestore();
});
});

@ -0,0 +1,59 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import { storeTheme, getTheme } from "./ThemeThunk";
import {afterEach, describe, expect, it, jest} from "@jest/globals";
describe('storeTheme Function', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('stores theme in AsyncStorage', async () => {
const theme = { colors: { background: 'white', text: 'black' } };
const jsonValue = JSON.stringify(theme);
AsyncStorage.setItem = jest.fn().mockResolvedValueOnce();
console.log = jest.fn();
await storeTheme(theme);
expect(AsyncStorage.setItem).toHaveBeenCalledWith('@theme', jsonValue);
expect(console.log).toHaveBeenCalledWith("theme stored");
});
it('logs error if theme storage fails', async () => {
const theme = { colors: { background: 'white', text: 'black' } };
AsyncStorage.setItem = jest.fn().mockRejectedValueOnce('Storage error');
console.error = jest.fn();
await storeTheme(theme);
expect(console.error).toHaveBeenCalledWith('Storage error');
});
});
describe('getTheme Function', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('retrieves theme from AsyncStorage', async () => {
const theme = { colors: { background: 'white', text: 'black' } };
const jsonValue = JSON.stringify(theme);
AsyncStorage.getItem = jest.fn().mockResolvedValueOnce(jsonValue);
const result = await getTheme();
expect(result).toEqual(theme);
});
it('returns null if theme is not found in AsyncStorage', async () => {
AsyncStorage.getItem = jest.fn().mockResolvedValueOnce(null);
const result = await getTheme();
expect(result).toBeNull();
});
it('logs error if theme retrieval fails', async () => {
AsyncStorage.getItem = jest.fn().mockRejectedValueOnce('Retrieval error');
console.error = jest.fn();
await getTheme();
expect(console.error).toHaveBeenCalledWith('Retrieval error');
});
});

@ -1,11 +1,11 @@
import '../types/extension';
import {Image, StyleSheet, Switch, Text, View} from "react-native";
import {
darksalmonColor,
darksalmonColor, DarkTheme,
whiteColor
} from "../assets/Theme";
import React from "react";
import {DarkTheme, DefaultTheme, useTheme} from "@react-navigation/native";
import {DefaultTheme, useTheme} from "@react-navigation/native";
import {storeTheme} from "../redux/thunk/ThemeThunk";
export default function Catalogue() {

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save