diff --git a/doc/changelog.md b/doc/changelog.md index 83e5b86dc..b7ef8f30c 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -15,7 +15,7 @@ Syntax: `- short text describing the change _(Your Name)_` - _()_ - _()_ - _()_ -- _()_ +- Add tests for hooks in frontend/layers _(Lukas Anton Lakits)_ - _()_ - _()_ - _()_ diff --git a/frontend/src/__test_utils__/msw_handlers/plants.ts b/frontend/src/__test_utils__/msw_handlers/plants.ts index 9ff5821fd..b4d3ca600 100644 --- a/frontend/src/__test_utils__/msw_handlers/plants.ts +++ b/frontend/src/__test_utils__/msw_handlers/plants.ts @@ -1,5 +1,11 @@ import { http, HttpResponse } from 'msw'; -import { Page, PlantsSummaryDto } from '@/api_types/definitions'; +import { + Page, + PlantsSummaryDto, + RelationDto, + RelationsDto, + RelationType, +} from '@/api_types/definitions'; import { baseApiUrl } from '@/config'; const allPlants: PlantsSummaryDto[] = [ @@ -20,6 +26,24 @@ const allPlants: PlantsSummaryDto[] = [ }, ]; +const allRelationPartners: RelationDto[] = [ + { + id: 1, + relation: RelationType.Neutral, + }, + { + id: 2, + relation: RelationType.Antagonist, + }, +]; + +const allRelations: RelationsDto[] = [ + { + id: 1, + relations: [allRelationPartners[0], allRelationPartners[1]], + }, +]; + export const handlers = [ http.get(`${baseApiUrl}/api/plants/:id`, () => { return HttpResponse.json(allPlants[0]); @@ -40,4 +64,13 @@ export const handlers = [ return HttpResponse.json(response); }), + + http.get(`${baseApiUrl}/api/:mapId/1/layers/plants/relations`, ({ request }) => { + const url = new URL(request.url); + + const plantId = parseInt(url.searchParams.get('plant_id') ?? '-1'); + return HttpResponse.json(allRelations[plantId - 1]); + }), ]; + +export const allPlantsForTesting = allPlants; diff --git a/frontend/src/features/map_planning/layers/plant/hooks/relationsHookApi.test.tsx b/frontend/src/features/map_planning/layers/plant/hooks/relationsHookApi.test.tsx new file mode 100644 index 000000000..db0e4d6a4 --- /dev/null +++ b/frontend/src/features/map_planning/layers/plant/hooks/relationsHookApi.test.tsx @@ -0,0 +1,44 @@ +import { renderHook, screen, waitFor } from '@testing-library/react'; +import { expect } from 'vitest'; +import { mockServerErrorOnce } from '@/__test_utils__/msw'; +import '@/__test_utils__/setup'; +import '@/__test_utils__/setupSessionStorageAuth'; +import { createQueryHookWrapper } from '@/__test_utils__/utils'; +import { RelationType } from '@/api_types/definitions'; +import { useRelations } from '@/features/map_planning/layers/plant/hooks/relationsHookApi'; + +describe('useRelations', () => { + const renderUseRelations = () => + renderHook( + () => + useRelations({ + mapId: 1, + plantId: 1, + enabled: true, + }), + { + wrapper: createQueryHookWrapper(), + }, + ); + + it('should return the two relations for the plant', async () => { + const { result } = renderUseRelations(); + + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + expect(result.current.data).toBeDefined(); + expect(result.current.data?.has(1)); + expect(result.current.data?.has(2)); + expect(result.current.data?.get(1)?.id == 1); + expect(result.current.data?.get(1)?.relation == RelationType.Neutral); + expect(result.current.data?.get(2)?.relation == RelationType.Antagonist); + }); + + it('should cause a toast to appear on failing hook', async () => { + mockServerErrorOnce(); + const { result } = renderUseRelations(); + + await waitFor(() => expect(result.current.isError).toBe(true)); + expect(result.current.error).toBeDefined(); + await screen.findByRole('alert'); + }); +}); diff --git a/frontend/src/features/map_planning/layers/plant/hooks/useSelectPlantForPlanting.test.tsx b/frontend/src/features/map_planning/layers/plant/hooks/useSelectPlantForPlanting.test.tsx new file mode 100644 index 000000000..3677f7e47 --- /dev/null +++ b/frontend/src/features/map_planning/layers/plant/hooks/useSelectPlantForPlanting.test.tsx @@ -0,0 +1,26 @@ +import { renderHook, waitFor } from '@testing-library/react'; +import { expect } from 'vitest'; +import { allPlantsForTesting } from '@/__test_utils__/msw_handlers/plants'; +import '@/__test_utils__/setup'; +import '@/__test_utils__/setupSessionStorageAuth'; +import { useSelectPlantForPlanting } from '@/features/map_planning/layers/plant/hooks/useSelectPlantForPlanting'; +import { useSelectedPlantForPlanting } from '@/features/map_planning/layers/plant/hooks/useSelectedPlantForPlanting'; + +describe('useSelectPlantForPlanting', () => { + const renderUseSelectPlantForPlanting = () => renderHook(() => useSelectPlantForPlanting()); + + it('should set the given plant as plant for planting', async () => { + const { result } = renderUseSelectPlantForPlanting(); + const plantForPlanting = allPlantsForTesting[0]; + + await waitFor(() => + expect( + result.current.actions.selectPlantForPlanting({ plant: plantForPlanting, seed: null }), + ).toBeUndefined(), + ); + const selectedPlant = renderHook(() => useSelectedPlantForPlanting()); + expect(selectedPlant.result.current).toBeDefined(); + expect(selectedPlant.result.current?.plant).toBe(plantForPlanting); + expect(selectedPlant.result.current?.seed).toBeNull(); + }); +});