import React from 'react';
import { vi, describe, it, expect, beforeEach } from 'vitest';
import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';
import { useConfig, useSession } from '@openmrs/esm-framework';
import { receiptOperationTypeMock, returnOperationTypeMock, stockIssueOperationtypeMock } from '@mocks';
import { useStockOperations } from '../stock-operations.resource';
import { useStockOperationTypes } from '../../stock-lookups/stock-lookups.resource';
import useParties from './hooks/useParties';
import StockOperationForm from './stock-operation-form.component';
const mockUseParties = vi.mocked(useParties);
const mockUseStockOperationTypes = vi.mocked(useStockOperationTypes);
const mockUseStockOperations = vi.mocked(useStockOperations);
const mockUseConfig = vi.mocked(useConfig);
const mockUseSession = vi.mocked(useSession);
vi.mock('../../stock-lookups/stock-lookups.resource', () => ({
useStockOperationTypes: vi.fn(),
useUsers: vi.fn().mockReturnValue({ items: { results: [] }, isLoading: false }),
useUser: vi.fn().mockReturnValue({ data: { display: 'Test User' }, isLoading: false, error: null }),
}));
vi.mock('../stock-operations.resource', () => ({
operationStatusColor: vi.fn(() => 'some-color'),
getStockOperationLinks: vi.fn(),
useStockOperations: vi.fn().mockReturnValue({
items: { results: [] },
isLoading: false,
error: null,
}),
useStockOperation: vi.fn().mockReturnValue({
items: undefined,
isLoading: false,
error: null,
}),
useStockOperationAndItems: vi.fn().mockReturnValue({
items: undefined,
isLoading: false,
error: null,
}),
}));
vi.mock('../../stock-items/stock-items.resource', () => ({
useStockItem: vi.fn(),
useStockItems: vi.fn().mockReturnValue({
isLoading: false,
error: null,
items: {},
}),
}));
vi.mock('./hooks/useFilterableStockItems', () => ({
useFilterableStockItems: vi.fn().mockReturnValue({
stockItemsList: [],
setLimit: vi.fn(),
setRepresentation: vi.fn(),
setSearchString: vi.fn(),
isLoading: false,
}),
}));
vi.mock('./hooks/useParties', () => ({ default: vi.fn() }));
vi.mock('react-hook-form', () => ({
useForm: vi.fn().mockReturnValue({
watch: vi.fn(),
formState: {
errors: {},
},
resetField: vi.fn(),
getValues: vi.fn(),
setValue: vi.fn(),
handleSubmit: vi.fn(),
trigger: vi.fn().mockReturnValue(true),
}),
useFormContext: vi.fn().mockReturnValue({
watch: vi.fn(),
formState: {
errors: {},
},
resetField: vi.fn(),
getValues: vi.fn(),
setValue: vi.fn(),
handleSubmit: vi.fn(),
trigger: vi.fn().mockReturnValue(true),
}),
Controller: ({ render }) => render({ field: {}, fieldState: {} }),
FormProvider: ({ children }: { children: React.ReactNode }) => <>{children}>,
}));
vi.mock('../../stock-items/add-stock-item/batch-information/batch-information.resource', () => ({
useStockItemBatchInformationHook: vi.fn().mockReturnValue({
items: [],
totalCount: 0,
currentPage: 1,
currentPageSize: 10,
setCurrentPage: vi.fn(),
setPageSize: vi.fn(),
pageSizes: [],
isLoading: false,
error: undefined,
setSearchString: vi.fn(),
setStockItemUuid: vi.fn(),
setLocationUuid: vi.fn(),
setPartyUuid: vi.fn(),
setStockBatchUuid: vi.fn(),
}),
}));
describe('Stock Operation form step 3 (stock submision)', () => {
beforeEach(() => {
mockUseStockOperationTypes.mockReturnValue({
types: { results: [], links: [], totalCount: 0 },
isLoading: false,
error: null,
});
mockUseStockOperations.mockReturnValue({
items: { results: [], links: [], totalCount: 0 },
isLoading: false,
error: null,
});
mockUseConfig.mockReturnValue({ autoPopulateResponsiblePerson: true });
mockUseParties.mockReturnValue({
destinationParties: [],
sourceParties: [],
isLoading: false,
error: undefined,
sourceTags: [],
destinationTags: [],
parties: [],
mutate: vi.fn(),
sourcePartiesFilter: () => true,
destinationPartiesFilter: () => true,
});
mockUseSession.mockReturnValue({
authenticated: true,
sessionId: 'test-session-id',
user: {
uuid: 'test-user-uuid',
display: 'Test User',
username: 'testuser',
systemId: 'test-system-id',
userProperties: {},
person: { uuid: 'test-person-uuid' },
privileges: [],
roles: [],
retired: false,
links: [],
locale: 'en',
allowedLocales: ['en'],
},
sessionLocation: {
uuid: 'test-location-uuid',
display: 'Test Location',
links: [],
},
});
});
it('should have previous btn and not next btn', async () => {
render(
,
);
// MOVE TO STEP 2
await userEvent.click(screen.getByRole('button', { name: /next/i }));
// MOVE TO STEP3
await userEvent.click(screen.getByRole('button', { name: /next/i }));
expect(screen.queryByRole('button', { name: /next/i })).not.toBeInTheDocument();
expect(screen.getByTestId('previous-btn')).toBeInTheDocument();
});
it('should render require approval radio button and save button', async () => {
render(
,
);
// MOVE TO STEP 2
await userEvent.click(screen.getByRole('button', { name: /next/i }));
// MOVE TO STEP3
await userEvent.click(screen.getByRole('button', { name: /next/i }));
// Shouls have save button
expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument();
expect(screen.getAllByRole('radio', { name: /yes|no/i })).toHaveLength(2);
});
it('should render submitForReview button when require aprroval radion button is checked yes', async () => {
render(
,
);
// MOVE TO STEP 2
await userEvent.click(screen.getByRole('button', { name: /next/i }));
// MOVE TO STEP3
await userEvent.click(screen.getByRole('button', { name: /next/i }));
const yesRadioButton = screen.getByRole('radio', { name: /yes/i });
expect(yesRadioButton).toBeInTheDocument();
// Submit for review shouldnt be in doc
expect(screen.queryByRole('button', { name: /submit for review/i })).not.toBeInTheDocument();
await userEvent.click(yesRadioButton);
// On require aprooval should now show
expect(screen.getByRole('button', { name: /submit for review/i })).toBeInTheDocument();
});
it('should render complete button when require aprroval radion button is checked no', async () => {
render(
,
);
// MOVE TO STEP 2
await userEvent.click(screen.getByRole('button', { name: /next/i }));
// MOVE TO STEP3
await userEvent.click(screen.getByRole('button', { name: /next/i }));
const noRadioButton = screen.getByRole('radio', { name: /no/i });
expect(noRadioButton).toBeInTheDocument();
await userEvent.click(noRadioButton);
// On require aprooval should now show complete btn
expect(screen.getByTestId('complete-button')).toBeInTheDocument();
});
it('should render dispatch btn for stock return operation and dont require aproval', async () => {
render(
,
);
// MOVE TO STEP 2
await userEvent.click(screen.getByRole('button', { name: /next/i }));
// MOVE TO STEP3
await userEvent.click(screen.getByRole('button', { name: /next/i }));
const noRadioButton = screen.getByRole('radio', { name: /no/i });
expect(noRadioButton).toBeInTheDocument();
await userEvent.click(noRadioButton);
// On require aprooval should now show complete btn
expect(screen.getByTestId('dipatch-button')).toBeInTheDocument();
});
it('should render dispatch btn for stock issue operation and dont require aproval', async () => {
render(
,
);
// MOVE TO STEP 2
await userEvent.click(screen.getByRole('button', { name: /next/i }));
// MOVE TO STEP3
await userEvent.click(screen.getByRole('button', { name: /next/i }));
const noRadioButton = screen.getByRole('radio', { name: /no/i });
expect(noRadioButton).toBeInTheDocument();
await userEvent.click(noRadioButton);
// On require approval should now show complete btn
expect(screen.getByTestId('dipatch-button')).toBeInTheDocument();
});
});