All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 13m30s
109 lines
4.3 KiB
TypeScript
109 lines
4.3 KiB
TypeScript
// src/pages/admin/components/AddressForm.test.tsx
|
|
import React from 'react';
|
|
import { screen, fireEvent } from '@testing-library/react';
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { AddressForm } from './AddressForm';
|
|
import { createMockAddress } from '../../../tests/utils/mockFactories';
|
|
import { renderWithProviders } from '../../../tests/utils/renderWithProviders';
|
|
|
|
// Mock child components and icons to isolate the form's logic
|
|
vi.mock('lucide-react', () => ({
|
|
MapPinIcon: () => <div data-testid="map-pin-icon" />,
|
|
}));
|
|
|
|
vi.mock('../../../components/LoadingSpinner', () => ({
|
|
LoadingSpinner: () => <div data-testid="loading-spinner" />,
|
|
}));
|
|
|
|
describe('AddressForm', () => {
|
|
const mockOnAddressChange = vi.fn();
|
|
const mockOnGeocode = vi.fn();
|
|
|
|
const defaultProps = {
|
|
address: {},
|
|
onAddressChange: mockOnAddressChange,
|
|
onGeocode: mockOnGeocode,
|
|
isGeocoding: false,
|
|
};
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('should render all address fields correctly', () => {
|
|
renderWithProviders(<AddressForm {...defaultProps} />);
|
|
|
|
expect(screen.getByRole('heading', { name: /home address/i })).toBeInTheDocument();
|
|
expect(screen.getByLabelText(/address line 1/i)).toBeInTheDocument();
|
|
expect(screen.getByLabelText(/address line 2/i)).toBeInTheDocument();
|
|
expect(screen.getByLabelText(/city/i)).toBeInTheDocument();
|
|
expect(screen.getByLabelText(/province \/ state/i)).toBeInTheDocument();
|
|
expect(screen.getByLabelText(/postal \/ zip code/i)).toBeInTheDocument();
|
|
expect(screen.getByLabelText(/country/i)).toBeInTheDocument();
|
|
expect(screen.getByRole('button', { name: /re-geocode/i })).toBeInTheDocument();
|
|
});
|
|
|
|
it('should display values from the address prop', () => {
|
|
const fullAddress = createMockAddress({
|
|
address_line_1: '123 Main St',
|
|
city: 'Anytown',
|
|
country: 'Canada',
|
|
});
|
|
renderWithProviders(<AddressForm {...defaultProps} address={fullAddress} />);
|
|
|
|
expect(screen.getByLabelText(/address line 1/i)).toHaveValue('123 Main St');
|
|
expect(screen.getByLabelText(/city/i)).toHaveValue('Anytown');
|
|
expect(screen.getByLabelText(/country/i)).toHaveValue('Canada');
|
|
});
|
|
|
|
it('should call onAddressChange with the correct field and value for all inputs', () => {
|
|
renderWithProviders(<AddressForm {...defaultProps} />);
|
|
|
|
const inputs = [
|
|
{ label: /address line 1/i, name: 'address_line_1', value: '123 St' },
|
|
{ label: /address line 2/i, name: 'address_line_2', value: 'Apt 4' },
|
|
{ label: /city/i, name: 'city', value: 'Metropolis' },
|
|
{ label: /province \/ state/i, name: 'province_state', value: 'NY' },
|
|
{ label: /postal \/ zip code/i, name: 'postal_code', value: '10001' },
|
|
{ label: /country/i, name: 'country', value: 'USA' },
|
|
];
|
|
|
|
inputs.forEach(({ label, name, value }) => {
|
|
const input = screen.getByLabelText(label);
|
|
fireEvent.change(input, { target: { value } });
|
|
expect(mockOnAddressChange).toHaveBeenCalledWith(name, value);
|
|
});
|
|
});
|
|
|
|
it('should call onGeocode when the "Re-Geocode" button is clicked', () => {
|
|
renderWithProviders(<AddressForm {...defaultProps} />);
|
|
|
|
const geocodeButton = screen.getByRole('button', { name: /re-geocode/i });
|
|
fireEvent.click(geocodeButton);
|
|
|
|
expect(mockOnGeocode).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should show MapPinIcon when not geocoding', () => {
|
|
renderWithProviders(<AddressForm {...defaultProps} isGeocoding={false} />);
|
|
expect(screen.getByTestId('map-pin-icon')).toBeInTheDocument();
|
|
expect(screen.queryByTestId('loading-spinner')).not.toBeInTheDocument();
|
|
});
|
|
|
|
describe('when isGeocoding is true', () => {
|
|
it('should disable the button and show a loading spinner', () => {
|
|
renderWithProviders(<AddressForm {...defaultProps} isGeocoding={true} />);
|
|
|
|
const geocodeButton = screen.getByRole('button', { name: /re-geocode/i });
|
|
expect(geocodeButton).toBeDisabled();
|
|
|
|
// The button itself contains a spinner when loading
|
|
expect(geocodeButton.querySelector('[data-testid="loading-spinner"]')).toBeInTheDocument();
|
|
// A second spinner is shown next to the title
|
|
expect(screen.getAllByTestId('loading-spinner')).toHaveLength(2);
|
|
// MapPinIcon should be hidden
|
|
expect(screen.queryByTestId('map-pin-icon')).not.toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|