b34b0dd7d6
Validators (Pushes and Pull Requests) / UI & Storage Validation (pull_request) Failing after 12s
Validators (Pushes and Pull Requests) / Database & Schema Validation (pull_request) Successful in 13s
Validators (Pushes and Pull Requests) / Core Validators & Database Setup (pull_request) Failing after 28s
Validators (Pushes and Pull Requests) / WBS & Audit Validations (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / .NET Contracts (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / Calibration & Performance (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / Operational Report & Decision Packet (pull_request) Has been skipped
Validators (Pushes and Pull Requests) / CI Workflow Lint (pull_request) Failing after 10s
Validators (Pushes and Pull Requests) / Security & Secrets (pull_request) Successful in 12s
Validators (Pushes and Pull Requests) / Notify PR Results (pull_request) Successful in 2s
Frontend CI Pipeline / ci-frontend-8-steps (pull_request) Failing after 2m50s
379 lines
11 KiB
TypeScript
379 lines
11 KiB
TypeScript
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('*')
|
|
})
|
|
})
|
|
})
|