import { describe, it, expect, beforeEach } from 'vitest' import { mount } from '@vue/test-utils' import SupplierField from './SupplierField.vue' describe('SupplierField (Domain Field)', () => { const defaultProps = { modelValue: '' } describe('Rendering', () => { it('renders supplier search input', () => { const wrapper = mount(SupplierField, { props: defaultProps }) const input = wrapper.find('input[type="text"]') expect(input.exists()).toBe(true) expect(input.attributes('placeholder')).toContain('Search') }) it('displays supplier details when selected', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) // Simulate selection wrapper.vm.selectedSupplier = { id: 'SUP-001', name: 'Premium Electronics Co.', email: 'sales@premium-elec.com', phone: '010-1111-2222', city: 'Seoul', status: 'ACTIVE', rating: 5, joinedDate: '2023-01-15', leadTimeDays: 3, minOrderAmount: 500000, paymentTerms: 'Net 30', onTimeDeliveryRate: 98 } await wrapper.vm.$nextTick() expect(wrapper.find('.card').exists()).toBe(true) expect(wrapper.text()).toContain('Premium Electronics Co.') }) }) describe('Supplier Search', () => { it('performs search on input change', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) const input = wrapper.find('input[type="text"]') await input.setValue('Premium') await new Promise((resolve) => setTimeout(resolve, 400)) expect(wrapper.vm.searchResults.length).toBeGreaterThan(0) }) it('clears results when search empty', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) const input = wrapper.find('input[type="text"]') await input.setValue('Test') await new Promise((resolve) => setTimeout(resolve, 400)) expect(wrapper.vm.searchResults.length).toBeGreaterThan(0) await input.setValue('') expect(wrapper.vm.searchResults).toHaveLength(0) }) it('shows loading state during search', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) const input = wrapper.find('input[type="text"]') input.element.value = 'Search' input.trigger('input') expect(wrapper.vm.isSearching).toBe(true) await new Promise((resolve) => setTimeout(resolve, 400)) expect(wrapper.vm.isSearching).toBe(false) }) }) describe('Supplier Selection', () => { it('selects supplier and shows details', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) const input = wrapper.find('input[type="text"]') await input.setValue('Premium') await new Promise((resolve) => setTimeout(resolve, 400)) if (wrapper.vm.searchResults.length > 0) { await wrapper.vm.selectSupplier(wrapper.vm.searchResults[0]) expect(wrapper.vm.selectedSupplier).not.toBeNull() expect(wrapper.emitted('update:modelValue')).toBeDefined() } }) it('emits select event with supplier data', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) const input = wrapper.find('input[type="text"]') await input.setValue('Standard') await new Promise((resolve) => setTimeout(resolve, 400)) if (wrapper.vm.searchResults.length > 0) { await wrapper.vm.selectSupplier(wrapper.vm.searchResults[0]) const emitted = wrapper.emitted('select') expect(emitted).toBeDefined() } }) }) describe('Supplier Details Display', () => { beforeEach(() => { const supplier = { id: 'SUP-002', name: 'Standard Parts Supplier', email: 'contact@standard-parts.com', phone: '010-3333-4444', city: 'Busan', status: 'ACTIVE', rating: 4, joinedDate: '2022-06-20', leadTimeDays: 7, minOrderAmount: 300000, paymentTerms: 'Net 45', onTimeDeliveryRate: 92 } }) it('displays supplier information', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) const supplier = { id: 'SUP-002', name: 'Standard Parts Supplier', email: 'contact@standard-parts.com', phone: '010-3333-4444', city: 'Busan', status: 'ACTIVE', rating: 4, joinedDate: '2022-06-20', leadTimeDays: 7, minOrderAmount: 300000, paymentTerms: 'Net 45', onTimeDeliveryRate: 92 } wrapper.vm.selectedSupplier = supplier await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Standard Parts Supplier') expect(wrapper.text()).toContain('contact@standard-parts.com') expect(wrapper.text()).toContain('Busan') }) it('displays terms and conditions', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-002', name: 'Standard Parts Supplier', email: 'contact@standard-parts.com', phone: '010-3333-4444', city: 'Busan', status: 'ACTIVE', rating: 4, joinedDate: '2022-06-20', leadTimeDays: 7, minOrderAmount: 300000, paymentTerms: 'Net 45', onTimeDeliveryRate: 92 } await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Lead Time') expect(wrapper.text()).toContain('7 days') expect(wrapper.text()).toContain('Payment Terms') expect(wrapper.text()).toContain('Net 45') }) }) describe('Status Display', () => { it('shows correct status badge for ACTIVE supplier', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-001', name: 'Premium Electronics', email: 'sales@premium.com', phone: '010-1111-2222', city: 'Seoul', status: 'ACTIVE', rating: 5, joinedDate: '2023-01-15', leadTimeDays: 3, minOrderAmount: 500000, paymentTerms: 'Net 30', onTimeDeliveryRate: 98 } await wrapper.vm.$nextTick() expect(wrapper.vm.statusClass).toContain('bg-success') }) it('shows correct status badge for TRIAL supplier', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-004', name: 'International Imports', email: 'trade@intl.com', phone: '010-7777-8888', city: 'Seoul', status: 'TRIAL', rating: 4, joinedDate: '2024-08-01', leadTimeDays: 21, minOrderAmount: 1000000, paymentTerms: 'Prepaid', onTimeDeliveryRate: 88 } await wrapper.vm.$nextTick() expect(wrapper.vm.statusClass).toContain('bg-warning') }) }) describe('Delivery Reliability', () => { it('shows warning for low delivery rate', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-003', name: 'Budget Components', email: 'procurement@budget.com', phone: '010-5555-6666', city: 'Incheon', status: 'ACTIVE', rating: 3, joinedDate: '2021-11-10', leadTimeDays: 14, minOrderAmount: 200000, paymentTerms: 'COD', onTimeDeliveryRate: 78 } await wrapper.vm.$nextTick() expect(wrapper.vm.reliabilityClass).toContain('text-danger') expect(wrapper.text()).toContain('Delivery Reliability') }) }) describe('Lead Time Display', () => { it('shows green for fast lead time (< 7 days)', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-001', name: 'Premium Electronics', email: 'sales@premium.com', phone: '010-1111-2222', city: 'Seoul', status: 'ACTIVE', rating: 5, joinedDate: '2023-01-15', leadTimeDays: 3, minOrderAmount: 500000, paymentTerms: 'Net 30', onTimeDeliveryRate: 98 } await wrapper.vm.$nextTick() expect(wrapper.vm.leadTimeClass).toContain('text-success') }) it('shows warning for medium lead time (7-14 days)', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-002', name: 'Standard Parts', email: 'contact@standard.com', phone: '010-3333-4444', city: 'Busan', status: 'ACTIVE', rating: 4, joinedDate: '2022-06-20', leadTimeDays: 7, minOrderAmount: 300000, paymentTerms: 'Net 45', onTimeDeliveryRate: 92 } await wrapper.vm.$nextTick() expect(wrapper.vm.leadTimeClass).toContain('text-warning') }) it('shows danger for long lead time (> 14 days)', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-004', name: 'International Imports', email: 'trade@intl.com', phone: '010-7777-8888', city: 'Seoul', status: 'TRIAL', rating: 4, joinedDate: '2024-08-01', leadTimeDays: 21, minOrderAmount: 1000000, paymentTerms: 'Prepaid', onTimeDeliveryRate: 88 } await wrapper.vm.$nextTick() expect(wrapper.vm.leadTimeClass).toContain('text-danger') }) }) describe('Clear Functionality', () => { it('clears selection when clear button clicked', async () => { const wrapper = mount(SupplierField, { props: defaultProps }) wrapper.vm.selectedSupplier = { id: 'SUP-001', name: 'Premium Electronics', email: 'sales@premium.com', phone: '010-1111-2222', city: 'Seoul', status: 'ACTIVE', rating: 5, joinedDate: '2023-01-15', leadTimeDays: 3, minOrderAmount: 500000, paymentTerms: 'Net 30', onTimeDeliveryRate: 98 } await wrapper.vm.$nextTick() expect(wrapper.vm.selectedSupplier).not.toBeNull() wrapper.vm.clearSelection() expect(wrapper.vm.selectedSupplier).toBeNull() expect(wrapper.vm.searchQuery).toBe('') }) }) describe('Accessibility', () => { it('has proper label', () => { const wrapper = mount(SupplierField, { props: defaultProps }) expect(wrapper.text()).toContain('Supplier') }) it('shows required indicator', () => { const wrapper = mount(SupplierField, { props: defaultProps }) expect(wrapper.text()).toContain('*') }) }) })