diff --git a/app/resources/js/views/ImportView.vue b/app/resources/js/views/ImportView.vue new file mode 100644 index 00000000..61b37aef --- /dev/null +++ b/app/resources/js/views/ImportView.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/app/tests/Frontend/ImportView.spec.ts b/app/tests/Frontend/ImportView.spec.ts new file mode 100644 index 00000000..7df4ed75 --- /dev/null +++ b/app/tests/Frontend/ImportView.spec.ts @@ -0,0 +1,74 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { mount, flushPromises } from '@vue/test-utils'; +import { createVuetify } from 'vuetify'; +import * as components from 'vuetify/components'; +import * as directives from 'vuetify/directives'; + +vi.mock('../../resources/js/api/imports', async (importOriginal) => { + const orig = await importOriginal(); + return { ...orig }; +}); + +const importsApi = await import('../../resources/js/api/imports'); +const ImportView = (await import('../../resources/js/views/ImportView.vue')).default; + +const vuetify = createVuetify({ components, directives }); + +function mountView() { + return mount(ImportView, { + global: { + plugins: [vuetify], + stubs: { UnknownStatusesDialog: true }, + }, + }); +} + +describe('ImportView', () => { + beforeEach(() => { + vi.restoreAllMocks(); + vi.spyOn(importsApi, 'listImports').mockResolvedValue([]); + vi.spyOn(importsApi, 'getUnknownStatuses').mockResolvedValue([]); + }); + + it('грузит историю импортов при монтировании', async () => { + const spy = vi.spyOn(importsApi, 'listImports').mockResolvedValue([ + { + id: 1, + filename: 'leads.csv', + status: 'done', + rows_total: 5, + rows_added: 5, + rows_updated: 0, + rows_skipped: 0, + unknown_statuses_count: 0, + dry_run: false, + error_message: null, + started_at: null, + finished_at: null, + }, + ]); + const wrapper = mountView(); + await flushPromises(); + + expect(spy).toHaveBeenCalled(); + expect(wrapper.text()).toContain('leads.csv'); + }); + + it('кнопка загрузки заблокирована без выбранного файла', async () => { + const wrapper = mountView(); + await flushPromises(); + + const uploadBtn = wrapper.find('[data-test="upload-btn"]'); + expect(uploadBtn.attributes('disabled')).toBeDefined(); + }); + + it('показывает баннер о неизвестных статусах', async () => { + vi.spyOn(importsApi, 'getUnknownStatuses').mockResolvedValue([ + { id: 1, status_ru: 'Архив', occurrences: 3 }, + ]); + const wrapper = mountView(); + await flushPromises(); + + expect(wrapper.find('[data-test="unknown-banner"]').exists()).toBe(true); + }); +});