import { describe, expect, it } from 'vitest'; import { RESOURCE_CANVAS_CARD_HEIGHT } from '../src/view/project-development/resourceCanvasLayoutModel'; import { clampProjectResourceSectionZoom, defaultProjectResourceSectionHeight, projectResourceSectionHeightBounds, projectResourceSectionHeightKey, projectResourceSectionZoomFromWheel, RESOURCE_CANVAS_VERTICAL_INSET, RESOURCE_SECTION_DEFAULT_HEIGHT, RESOURCE_SECTION_HEIGHT_STEP, RESOURCE_SECTION_MIN_HEIGHT, RESOURCE_SECTION_ZOOM_DEFAULT, RESOURCE_SECTION_ZOOM_MAX, RESOURCE_SECTION_ZOOM_MIN, updateProjectResourceSectionHeight, updateProjectResourceSectionZoom, } from '../src/view/project-development/resourceSectionHeightModel'; describe('resource section height model', () => { it('isolates session keys by project, mode, and section', () => { expect( projectResourceSectionHeightKey({ projectId: 'project-a', mode: 'dependency', section: 'document', }), ).not.toBe( projectResourceSectionHeightKey({ projectId: 'project-a', mode: 'type', section: 'document', }), ); expect( projectResourceSectionHeightKey({ projectId: 'project-a', mode: 'dependency', section: 'document', }), ).not.toBe( projectResourceSectionHeightKey({ projectId: 'project-b', mode: 'dependency', section: 'document', }), ); }); it('keeps a full card row above the minimum and clamps to the canvas height', () => { expect(RESOURCE_SECTION_MIN_HEIGHT).toBeGreaterThan( RESOURCE_CANVAS_CARD_HEIGHT, ); const bounds = projectResourceSectionHeightBounds(480); expect(bounds).toEqual({ min: RESOURCE_SECTION_MIN_HEIGHT, max: 480 - RESOURCE_CANVAS_VERTICAL_INSET, }); let height = defaultProjectResourceSectionHeight(bounds); expect(height).toBe(RESOURCE_SECTION_DEFAULT_HEIGHT); height = updateProjectResourceSectionHeight(height, 'increase', bounds); expect(height).toBe( RESOURCE_SECTION_DEFAULT_HEIGHT + RESOURCE_SECTION_HEIGHT_STEP, ); height = updateProjectResourceSectionHeight(height, 'increase', bounds); expect(height).toBe(bounds.max); height = updateProjectResourceSectionHeight(height, 'reset', bounds); expect(height).toBe(RESOURCE_SECTION_DEFAULT_HEIGHT); }); it('uses the minimum as the hard upper bound only when the viewport is smaller', () => { const bounds = projectResourceSectionHeightBounds(120); expect(bounds.min).toBe(RESOURCE_SECTION_MIN_HEIGHT); expect(bounds.max).toBe(RESOURCE_SECTION_MIN_HEIGHT); expect( updateProjectResourceSectionHeight( RESOURCE_SECTION_DEFAULT_HEIGHT, 'increase', bounds, ), ).toBe(RESOURCE_SECTION_MIN_HEIGHT); }); it('clamps button and trackpad zoom deterministically', () => { expect( updateProjectResourceSectionZoom( RESOURCE_SECTION_ZOOM_DEFAULT, 'increase', ), ).toBe(1.1); expect(updateProjectResourceSectionZoom(1.1, 'decrease')).toBe(1); expect(updateProjectResourceSectionZoom(1.7, 'reset')).toBe(1); expect(clampProjectResourceSectionZoom(0.1)).toBe( RESOURCE_SECTION_ZOOM_MIN, ); expect(clampProjectResourceSectionZoom(4)).toBe(RESOURCE_SECTION_ZOOM_MAX); expect(projectResourceSectionZoomFromWheel(1, -100)).toBeGreaterThan(1); expect(projectResourceSectionZoomFromWheel(1, 100)).toBeLessThan(1); expect(projectResourceSectionZoomFromWheel(1.23, 0)).toBe(1.23); }); });