import { renderHook, act } from '@testing-library/react'; import { defaultParameters, useChangeMetadataParameters } from './useChangeMetadataParameters'; import { TrappedStatus } from '../../../types/metadata'; import { describe, expect, test } from 'vitest'; describe('useChangeMetadataParameters', () => { test('should initialize with default parameters', () => { const { result } = renderHook(() => useChangeMetadataParameters()); expect(result.current.parameters).toStrictEqual(defaultParameters); }); describe('parameter updates', () => { test.each([ { paramName: 'title', value: 'Test Document' }, { paramName: 'author', value: 'John Doe' }, { paramName: 'subject', value: 'Test Subject' }, { paramName: 'keywords', value: 'test, metadata' }, { paramName: 'creator', value: 'Test Creator' }, { paramName: 'producer', value: 'Test Producer' }, { paramName: 'creationDate', value: new Date('2025/01/17 14:30:00') }, { paramName: 'modificationDate', value: new Date('2025/01/17 15:30:00') }, { paramName: 'trapped', value: TrappedStatus.TRUE }, { paramName: 'deleteAll', value: true }, ] as const)('should update $paramName parameter', ({ paramName, value }) => { const { result } = renderHook(() => useChangeMetadataParameters()); act(() => { result.current.updateParameter(paramName, value); }); expect(result.current.parameters[paramName]).toBe(value); }); }); describe('validation', () => { test.each([ { description: 'deleteAll is true', updates: { deleteAll: true }, expected: true }, { description: 'has title', updates: { title: 'Test Document' }, expected: true }, { description: 'has author', updates: { author: 'John Doe' }, expected: true }, { description: 'has subject', updates: { subject: 'Test Subject' }, expected: true }, { description: 'has keywords', updates: { keywords: 'test' }, expected: true }, { description: 'has creator', updates: { creator: 'Test Creator' }, expected: true }, { description: 'has producer', updates: { producer: 'Test Producer' }, expected: true }, { description: 'has creation date', updates: { creationDate: new Date('2025/01/17 14:30:00') }, expected: true }, { description: 'has modification date', updates: { modificationDate: new Date('2025/01/17 14:30:00') }, expected: true }, { description: 'has trapped status', updates: { trapped: TrappedStatus.TRUE }, expected: true }, { description: 'no meaningful content', updates: {}, expected: false }, { description: 'whitespace only', updates: { title: ' ', author: ' ' }, expected: false }, ])('should validate correctly when $description', ({ updates, expected }) => { const { result } = renderHook(() => useChangeMetadataParameters()); act(() => { Object.entries(updates).forEach(([key, value]) => { result.current.updateParameter(key as keyof typeof updates, value); }); }); expect(result.current.validateParameters()).toBe(expected); }); test.each([ { description: 'valid creation date', updates: { title: 'Test', creationDate: new Date('2025/01/17 14:30:00') }, expected: true }, { description: 'valid modification date', updates: { title: 'Test', modificationDate: new Date('2025/01/17 14:30:00') }, expected: true }, { description: 'empty dates are valid', updates: { title: 'Test', creationDate: null, modificationDate: null }, expected: true }, ])('should validate dates correctly with $description', ({ updates, expected }) => { const { result } = renderHook(() => useChangeMetadataParameters()); act(() => { Object.entries(updates).forEach(([key, value]) => { result.current.updateParameter(key as keyof typeof updates, value); }); }); expect(result.current.validateParameters()).toBe(expected); }); }); describe('custom metadata', () => { test('should add custom metadata with sequential IDs', () => { const { result } = renderHook(() => useChangeMetadataParameters()); act(() => { result.current.addCustomMetadata(); }); expect(result.current.parameters.customMetadata).toHaveLength(1); expect(result.current.parameters.customMetadata[0]).toEqual({ key: '', value: '', id: expect.stringMatching(/^custom\d+$/) }); }); test('should remove custom metadata by ID', () => { const { result } = renderHook(() => useChangeMetadataParameters()); act(() => { result.current.addCustomMetadata(); }); const customId = result.current.parameters.customMetadata[0].id; act(() => { result.current.removeCustomMetadata(customId); }); expect(result.current.parameters.customMetadata).toHaveLength(0); }); test('should update custom metadata by ID', () => { const { result } = renderHook(() => useChangeMetadataParameters()); act(() => { result.current.addCustomMetadata(); }); const customId = result.current.parameters.customMetadata[0].id; act(() => { result.current.updateCustomMetadata(customId, 'Department', 'Engineering'); }); expect(result.current.parameters.customMetadata[0]).toEqual({ key: 'Department', value: 'Engineering', id: customId }); }); test('should validate with custom metadata', () => { const { result } = renderHook(() => useChangeMetadataParameters()); act(() => { result.current.addCustomMetadata(); }); const customId = result.current.parameters.customMetadata[0].id; act(() => { result.current.updateCustomMetadata(customId, 'Department', 'Engineering'); }); expect(result.current.validateParameters()).toBe(true); }); test('should generate unique IDs for multiple custom entries', () => { const { result } = renderHook(() => useChangeMetadataParameters()); for (let i = 0; i < 3; i++) { act(() => { result.current.addCustomMetadata(); }); } const ids = result.current.parameters.customMetadata.map(entry => entry.id); expect(ids).toHaveLength(3); expect(new Set(ids).size).toBe(3); // All unique expect(ids.every(id => id.startsWith('custom'))).toBe(true); }); }); test('should return correct endpoint name', () => { const { result } = renderHook(() => useChangeMetadataParameters()); expect(result.current.getEndpointName()).toBe('update-metadata'); }); });