import { describe, it, expect, beforeEach, vi } from 'vitest'; import { mount } from '@vue/test-utils'; import { createVuetify } from 'vuetify'; import axios from 'axios'; import AdminPricingTiersView from '../../resources/js/views/admin/AdminPricingTiersView.vue'; vi.mock('axios'); // Auto-импорт компонентов/директив Vuetify подхватывает vite-plugin-vuetify // из vitest.config.ts (см. AdminBillingView.spec.ts). const vuetify = createVuetify(); const mockTiers = [ { tier_no: 1, leads_in_tier: 100, price_per_lead_kopecks: 50000, effective_from: '1970-01-01' }, { tier_no: 2, leads_in_tier: 200, price_per_lead_kopecks: 45000, effective_from: '1970-01-01' }, { tier_no: 3, leads_in_tier: 400, price_per_lead_kopecks: 40000, effective_from: '1970-01-01' }, { tier_no: 4, leads_in_tier: 800, price_per_lead_kopecks: 35000, effective_from: '1970-01-01' }, { tier_no: 5, leads_in_tier: 1500, price_per_lead_kopecks: 30000, effective_from: '1970-01-01' }, { tier_no: 6, leads_in_tier: 3000, price_per_lead_kopecks: 27000, effective_from: '1970-01-01' }, { tier_no: 7, leads_in_tier: null, price_per_lead_kopecks: 25000, effective_from: '1970-01-01' }, ]; describe('AdminPricingTiersView', () => { beforeEach(() => { // eslint-disable-next-line @typescript-eslint/no-explicit-any (axios.get as any).mockResolvedValue({ data: { data: { active: mockTiers, scheduled: {} } } }); // eslint-disable-next-line @typescript-eslint/no-explicit-any (axios.post as any).mockResolvedValue({ data: { effective_from: '2026-06-01' } }); // eslint-disable-next-line @typescript-eslint/no-explicit-any (axios.delete as any).mockResolvedValue({ data: { ok: true } }); }); it('renders 7 tier rows from /api/admin/pricing-tiers', async () => { const wrapper = mount(AdminPricingTiersView, { global: { plugins: [vuetify] } }); await new Promise((r) => setTimeout(r, 50)); expect(wrapper.text()).toContain('500.00'); expect(wrapper.text()).toContain('250.00'); }); it('shows "все свыше" for tier 7 with leads_in_tier=null', async () => { const wrapper = mount(AdminPricingTiersView, { global: { plugins: [vuetify] } }); await new Promise((r) => setTimeout(r, 50)); expect(wrapper.text()).toContain('все свыше'); }); it('opens editor dialog on button click', async () => { const wrapper = mount(AdminPricingTiersView, { global: { plugins: [vuetify] } }); await new Promise((r) => setTimeout(r, 50)); // eslint-disable-next-line @typescript-eslint/no-explicit-any expect((wrapper.vm as any).editorOpen).toBe(false); // eslint-disable-next-line @typescript-eslint/no-explicit-any (wrapper.vm as any).editorOpen = true; await wrapper.vm.$nextTick(); // eslint-disable-next-line @typescript-eslint/no-explicit-any expect((wrapper.vm as any).editorOpen).toBe(true); }); it('submits POST with editor payload', async () => { const wrapper = mount(AdminPricingTiersView, { global: { plugins: [vuetify] } }); await new Promise((r) => setTimeout(r, 50)); // eslint-disable-next-line @typescript-eslint/no-explicit-any await (wrapper.vm as any).submit(); expect(axios.post).toHaveBeenCalledWith( '/api/admin/pricing-tiers', expect.objectContaining({ tiers: expect.arrayContaining([expect.objectContaining({ tier_no: 7, leads_in_tier: null })]), }), ); }); it('confirmDelete triggers DELETE to /scheduled/{date}', async () => { window.confirm = vi.fn(() => true); const wrapper = mount(AdminPricingTiersView, { global: { plugins: [vuetify] } }); await new Promise((r) => setTimeout(r, 50)); // eslint-disable-next-line @typescript-eslint/no-explicit-any await (wrapper.vm as any).confirmDelete('2026-06-01'); expect(axios.delete).toHaveBeenCalledWith('/api/admin/pricing-tiers/scheduled/2026-06-01'); }); });