const axios = require('axios');
jest.mock('axios'); // mock axios

const {
    addFriend,
    acceptFriend,
    rejectFriend,
    deleteFriend,
    getFriendsByUserId,
    getPendingRequests
} = require('../friends'); // 引入你的 API 方法

describe('Friends API Tests', () => {
    beforeEach(() => {
        jest.clearAllMocks(); // 每个测试前清除 mock 状态
    });

    test('addFriend should post friend request data', async () => {
        const mockFriendData = {
            friend1: 1,
            friend2: 2
        };
        axios.post.mockResolvedValue({ data: true });

        const response = await addFriend(mockFriendData);

        expect(axios.post).toHaveBeenCalledWith(
            'http://localhost:8080/friends/add',
            mockFriendData
        );
        expect(response.data).toBe(true);
    });

    test('acceptFriend should send accept request with params', async () => {
        axios.post.mockResolvedValue({ data: true });

        const response = await acceptFriend(1, 2);

        expect(axios.post).toHaveBeenCalledWith(
            'http://localhost:8080/friends/accept',
            null,
            { params: { friend1: 1, friend2: 2 } }
        );
        expect(response.data).toBe(true);
    });

    test('rejectFriend should delete pending friend request', async () => {
        axios.delete.mockResolvedValue({ data: true });

        const response = await rejectFriend(1, 2);

        expect(axios.delete).toHaveBeenCalledWith(
            'http://localhost:8080/friends/delete',
            { params: { friend1: 1, friend2: 2 } }
        );
        expect(response.data).toBe(true);
    });

    test('deleteFriend should delete a friend relationship', async () => {
        axios.delete.mockResolvedValue({ data: true });

        const response = await deleteFriend(3, 4);

        expect(axios.delete).toHaveBeenCalledWith(
            'http://localhost:8080/friends/delete',
            { params: { friend1: 3, friend2: 4 } }
        );
        expect(response.data).toBe(true);
    });

    test('getFriendsByUserId should get all accepted friends for user', async () => {
        const mockData = { data: [{ relationid: 1, friend1: 1, friend2: 2, status: 'accepted' }] };
        axios.get.mockResolvedValue(mockData);

        const response = await getFriendsByUserId(1);

        expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/friends/list/1');
        expect(response.data).toEqual(mockData.data);
    });

    test('getPendingRequests should fetch pending friend requests', async () => {
        const mockData = { data: [{ relationid: 2, friend1: 3, friend2: 1, status: 'pending' }] };
        axios.get.mockResolvedValue(mockData);

        const response = await getPendingRequests(1);

        expect(axios.get).toHaveBeenCalledWith('http://localhost:8080/friends/pending/1');
        expect(response.data).toEqual(mockData.data);
    });
});
