import { createWrapper } from 'app/test/vitest/helper';
import CrudModel from 'components/CrudModel.vue';
import { vi, afterEach, beforeEach, beforeAll, describe, expect, it } from 'vitest';

describe('CrudModel', () => {
    let vm;
    beforeAll(() => {
        vm = createWrapper(CrudModel, {
            global: {
                stubs: [
                    'vnPaginate',
                    'useState',
                    'arrayData',
                    'useStateStore',
                    'vue-i18n',
                ],
                mocks: {
                    validate: vi.fn(),
                },
            },
            propsData: {
                dataRequired: {
                    fk: 1,
                },
                dataKey: 'crudModelKey',
                model: 'crudModel',
                url: 'crudModelUrl',
            },
        }).vm;
    });

    beforeEach(() => {
        vm.fetch([]);
    });

    afterEach(() => {
        vi.clearAllMocks();
    });

    describe('insert()', () => {
        it('should new element in list with index 0 if formData not has data', () => {
            vm.insert();

            expect(vm.formData.length).toEqual(1);
            expect(vm.formData[0].fk).toEqual(1);
            expect(vm.formData[0].$index).toEqual(0);
        });
    });

    describe('getChanges()', () => {
        it('should return correct updates and creates', async () => {
            vm.fetch([
                { id: 1, name: 'New name one' },
                { id: 2, name: 'New name two' },
                { id: 3, name: 'Bruce Wayne' },
            ]);

            vm.originalData = [
                { id: 1, name: 'Tony Starks' },
                { id: 2, name: 'Jessica Jones' },
                { id: 3, name: 'Bruce Wayne' },
            ];

            vm.insert();
            const result = vm.getChanges();

            const expected = {
                creates: [
                    {
                        $index: 3,
                        fk: 1,
                    },
                ],
                updates: [
                    {
                        data: {
                            name: 'New name one',
                        },
                        where: {
                            id: 1,
                        },
                    },
                    {
                        data: {
                            name: 'New name two',
                        },
                        where: {
                            id: 2,
                        },
                    },
                ],
            };

            expect(result).toEqual(expected);
        });
    });

    describe('getDifferences()', () => {
        it('should return the differences between two objects', async () => {
            const obj1 = {
                a: 1,
                b: 2,
                c: 3,
            };
            const obj2 = {
                a: null,
                b: 4,
                d: 5,
            };

            const result = vm.getDifferences(obj1, obj2);

            expect(result).toEqual({
                a: null,
                b: 4,
                d: 5,
            });
        });
    });
});