import { loginThunk, loginSuccess, loginFailure, fetchCards, fetchCardsSuccess, fetchCardsFailure } from '../actions'; // Adjust the path based on your file structure
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import fetchMock from 'jest-fetch-mock';

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

fetchMock.enableMocks();

describe('Redux Actions', () => {
    let store;

    beforeEach(() => {
        store = mockStore({});
        fetch.resetMocks();
        Object.defineProperty(window, 'localStorage', {
            value: {
                setItem: jest.fn(),
                getItem: jest.fn(),
                removeItem: jest.fn(),
                clear: jest.fn(),
            },
            writable: true,
        });
    });

    describe('Login Thunk', () => {
        it('dispatches LOGIN_SUCCESS when login is successful', async () => {
            fetch.mockResponseOnce(JSON.stringify({
                accessToken: 'fakeAccessToken',
                refreshToken: 'fakeRefreshToken',
                username: 'validUser',
            }), { status: 200 });

            const expectedActions = [
                { type: 'LOGIN_SUCCESS', payload: 'validUser' }
            ];

            await store.dispatch(loginThunk('validUser', 'password'));
            expect(store.getActions()).toEqual(expectedActions);
            expect(window.localStorage.setItem).toHaveBeenCalledWith('accessToken', 'fakeAccessToken');
            expect(window.localStorage.setItem).toHaveBeenCalledWith('refreshToken', 'fakeRefreshToken');
        });

        it('dispatches LOGIN_FAILURE when login fails', async () => {
            fetch.mockResponseOnce(JSON.stringify({ message: 'Invalid credentials' }), { status: 401 });

            const expectedActions = [
                { type: 'LOGIN_FAILURE', payload: 'Invalid credentials' }
            ];

            await store.dispatch(loginThunk('invalidUser', 'wrongPassword'));
            expect(store.getActions()).toEqual(expectedActions);
        });

        it('dispatches LOGIN_FAILURE on network error', async () => {
            fetch.mockReject(new Error('Network error'));

            const expectedActions = [
                { type: 'LOGIN_FAILURE', payload: 'Network error' }
            ];

            await store.dispatch(loginThunk('anyUser', 'password'));
            expect(store.getActions()).toEqual(expectedActions);
        });
    });

    describe('Fetch Cards Thunk', () => {
        it('dispatches FETCH_CARDS_SUCCESS when fetching cards is successful', async () => {
            const mockCards = [{ id: 1, title: 'Card 1' }, { id: 2, title: 'Card 2' }];
            fetch.mockResponseOnce(JSON.stringify(mockCards), { status: 200 });

            const expectedActions = [
                { type: 'FETCH_CARDS_SUCCESS', payload: mockCards }
            ];

            await store.dispatch(fetchCards('searchTerm'));
            expect(store.getActions()).toEqual(expectedActions);
        });

        it('dispatches FETCH_CARDS_FAILURE when fetching cards fails', async () => {
            fetch.mockReject(new Error('Failed to fetch cards'));

            const expectedActions = [
                { type: 'FETCH_CARDS_FAILURE', payload: 'Failed to fetch cards' }
            ];

            await store.dispatch(fetchCards('searchTerm'));
            expect(store.getActions()).toEqual(expectedActions);
        });
    });
});
actions.js import { fetchWithAuth } from './api.js';

export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
export const FETCH_CARDS_SUCCESS = 'FETCH_CARDS_SUCCESS';
export const FETCH_CARDS_FAILURE = 'FETCH_CARDS_FAILURE';

export const loginSuccess = (username) => ({
    type: LOGIN_SUCCESS,
    payload: username
});

export const loginFailure = (error) => ({
    type: LOGIN_FAILURE,
    payload: error
});


export const loginThunk = (username, password) => {
    return async (dispatch) => {
        try {
            const response = await fetch('http://localhost:5000/login', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ username, password })
            });

            if (response.status === 200) {
                const data = await response.json();
                localStorage.setItem('accessToken', data.accessToken);
                localStorage.setItem('refreshToken', data.refreshToken);
                dispatch(loginSuccess(data.username));
            } else {
                const { message } = await response.json();
                dispatch(loginFailure(message));
            }
        } catch {
            dispatch(loginFailure('Network error'));
        }
    };
};
export const fetchCardsSuccess = (cards) => ({
    type: FETCH_CARDS_SUCCESS,
    payload: cards
});

export const fetchCardsFailure = (error) => ({
    type: FETCH_CARDS_FAILURE,
    payload: error
});

export const fetchCards = (searchTerm = '') => {
    return async (dispatch) => {
        try {
            const response = await fetchWithAuth(
                `http://localhost:5000/api/cards?search=${encodeURIComponent(searchTerm)}`
            );

            if (!response.ok) {
                throw new Error('Failed to fetch cards');
            }

            const data = await response.json();
            dispatch(fetchCardsSuccess(data));
        } catch (error) {
            console.error(error);
            dispatch(fetchCardsFailure(error.message));
        }
    };
};

export const logout = () => {
    return (dispatch) => {
        localStorage.removeItem('accessToken');
        localStorage.removeItem('refreshToken');
        localStorage.removeItem('username');
        dispatch({ type: 'LOGOUT' });
    };
};  FAIL  src/Components/Redux/__tests__/actions.test.js
  Redux Actions
    Login Thunk
      ✕ dispatches LOGIN_SUCCESS when login is successful
      ✕ dispatches LOGIN_FAILURE when login fails
      ✕ dispatches LOGIN_FAILURE on network error
    Fetch Cards Thunk
      ✕ dispatches FETCH_CARDS_SUCCESS when fetching cards is successful
      ✕ dispatches FETCH_CARDS_FAILURE when fetching cards fails

  ● Redux Actions › Login Thunk › dispatches LOGIN_SUCCESS when login is successful

    TypeError: middleware is not a function

      13 |
      14 |     beforeEach(() => {
    > 15 |         store = mockStore({});
         |                 ^
      16 |         fetch.resetMocks();
      17 |         Object.defineProperty(window, 'localStorage', {
      18 |             value: {

      at node_modules/redux/src/applyMiddleware.ts:54:49
          at Array.map (<anonymous>)
      at node_modules/redux/src/applyMiddleware.ts:54:31
      at mockStore (node_modules/redux-mock-store/lib/index.js:85:12)
      at Object.<anonymous> (src/Components/Redux/__tests__/actions.test.js:15:17)

  ● Redux Actions › Login Thunk › dispatches LOGIN_FAILURE when login fails

    TypeError: middleware is not a function

      13 |
      14 |     beforeEach(() => {
    > 15 |         store = mockStore({});
         |                 ^
      16 |         fetch.resetMocks();
      17 |         Object.defineProperty(window, 'localStorage', {
      18 |             value: {

      at node_modules/redux/src/applyMiddleware.ts:54:49
          at Array.map (<anonymous>)
      at node_modules/redux/src/applyMiddleware.ts:54:31
      at mockStore (node_modules/redux-mock-store/lib/index.js:85:12)
      at Object.<anonymous> (src/Components/Redux/__tests__/actions.test.js:15:17)

  ● Redux Actions › Login Thunk › dispatches LOGIN_FAILURE on network error

    TypeError: middleware is not a function

      13 |
      14 |     beforeEach(() => {
    > 15 |         store = mockStore({});
         |                 ^
      16 |         fetch.resetMocks();
      17 |         Object.defineProperty(window, 'localStorage', {
      18 |             value: {

      at node_modules/redux/src/applyMiddleware.ts:54:49
          at Array.map (<anonymous>)
      at node_modules/redux/src/applyMiddleware.ts:54:31
      at mockStore (node_modules/redux-mock-store/lib/index.js:85:12)
      at Object.<anonymous> (src/Components/Redux/__tests__/actions.test.js:15:17)

  ● Redux Actions › Fetch Cards Thunk › dispatches FETCH_CARDS_SUCCESS when fetching cards is successful

    TypeError: middleware is not a function

      13 |
      14 |     beforeEach(() => {
    > 15 |         store = mockStore({});
         |                 ^
      16 |         fetch.resetMocks();
      17 |         Object.defineProperty(window, 'localStorage', {
      18 |             value: {

      at node_modules/redux/src/applyMiddleware.ts:54:49
          at Array.map (<anonymous>)
      at node_modules/redux/src/applyMiddleware.ts:54:31
      at mockStore (node_modules/redux-mock-store/lib/index.js:85:12)
      at Object.<anonymous> (src/Components/Redux/__tests__/actions.test.js:15:17)

  ● Redux Actions › Fetch Cards Thunk › dispatches FETCH_CARDS_FAILURE when fetching cards fails

    TypeError: middleware is not a function

      13 |
      14 |     beforeEach(() => {
    > 15 |         store = mockStore({});
         |                 ^
      16 |         fetch.resetMocks();
      17 |         Object.defineProperty(window, 'localStorage', {
      18 |             value: {

      at node_modules/redux/src/applyMiddleware.ts:54:49
          at Array.map (<anonymous>)
      at node_modules/redux/src/applyMiddleware.ts:54:31
      at mockStore (node_modules/redux-mock-store/lib/index.js:85:12)
      at Object.<anonymous> (src/Components/Redux/__tests__/actions.test.js:15:17)

Test Suites: 1 failed, 1 total
Tests:       5 failed, 5 total
Snapshots:   0 total
Time:        0.501 s, estimated 1 s
Ran all test suites.
superhell@HOME-PC:~/spring-react$