import { describe, expect, it, beforeAll, vi, afterAll } from 'vitest'; import { createWrapper, axios } from 'app/test/vitest/helper'; import FormModel from 'src/components/FormModel.vue'; describe('FormModel', () => { const model = 'mockModel'; const url = 'mockUrl'; const formInitialData = { mockKey: 'mockVal' }; describe('modelValue', () => { it('should use the provided model', () => { const { vm } = mount({ propsData: { model: 'mockModel' } }); expect(vm.modelValue).toBe('mockModel'); }); it('should use the route meta title when model is not provided', () => { const { vm } = mount({}); expect(vm.modelValue).toBe('formModel_mockTitle'); }); }); describe('onMounted()', () => { let mockGet; beforeAll(() => { mockGet = vi.spyOn(axios, 'get').mockResolvedValue({ data: {} }); }); afterAll(() => { mockGet.mockRestore(); }); it('should not fetch when has formInitialData', () => { mount({ propsData: { url, model, autoLoad: true, formInitialData } }); expect(mockGet).not.toHaveBeenCalled(); }); it('should fetch when there is url and auto-load', () => { mount({ propsData: { url, model, autoLoad: true } }); expect(mockGet).toHaveBeenCalled(); }); it('should not observe changes', () => { const { vm } = mount({ propsData: { url, model, observeFormChanges: false, formInitialData }, }); expect(vm.hasChanges).toBe(true); vm.reset(); expect(vm.hasChanges).toBe(true); }); it('should observe changes', async () => { const { vm } = mount({ propsData: { url, model, formInitialData }, }); vm.state.set(model, { mockKey: 'mockVal' }); expect(vm.hasChanges).toBe(false); vm.formData.mockKey = 'newVal'; await vm.$nextTick(); expect(vm.hasChanges).toBe(true); }); }); describe.skip('watch()', () => { let wrapper; let vm; beforeAll(() => { wrapper = mount({ propsData: { url, model, formInitialData }, }); vm = wrapper.vm; }); it('should call updateAndEmit when arrayData.store.data changes', async () => { const updateAndEmitSpy = vi.spyOn(vm, 'updateAndEmit'); await vm.$nextTick(); console.log('vm.arrayData.store.data', vm.arrayData.store.data); vm.arrayData.store.data = { newData: 'newValue' }; await vm.$nextTick(); vm.arrayData.store.data = { newData: 'anotherVal' }; await vm.$nextTick(); expect(updateAndEmitSpy).toHaveBeenCalled(); }); it('should call reset and fetch when $props.url or $props.filter changes', async () => { const resetSpy = vi.spyOn(vm, 'reset'); const fetchSpy = vi.spyOn(vm, 'fetch'); wrapper.setProps({ url: 'newMockUrl' }); await wrapper.vm.$nextTick(); expect(resetSpy).toHaveBeenCalled(); expect(fetchSpy).toHaveBeenCalled(); }); }); describe('trimData()', () => { let vm; beforeAll(() => { vm = mount({}).vm; }); it('should trim whitespace from string values', () => { const data = { key1: ' value1 ', key2: ' value2 ' }; const trimmedData = vm.trimData(data); expect(trimmedData).toEqual({ key1: 'value1', key2: 'value2' }); }); it('should not modify non-string values', () => { const data = { key1: 123, key2: true, key3: null, key4: undefined }; const trimmedData = vm.trimData(data); expect(trimmedData).toEqual(data); }); }); describe('onUnmounted()', () => { it('should restore original data in the store if changes were made but not saved', async () => { const wrapper = mount({ propsData: { model, formInitialData } }); const vm = wrapper.vm; vm.formData.mockKey = 'newVal'; await vm.$nextTick(); await wrapper.unmount(); expect(vm.state.get(model)).toEqual(formInitialData); }); it('should clear the store on unmount if clearStoreOnUnmount is true', async () => { const wrapper = mount({ propsData: { model, formInitialData, clearStoreOnUnmount: true }, }); const vm = wrapper.vm; vm.hasChanges = false; await wrapper.unmount(); expect(vm.state.get(model)).toBeUndefined(); }); }); }); function mount({ propsData = {} }) { return createWrapper(FormModel, { propsData, }); }