Skip to content

Commit e99a48d

Browse files
committed
Add a test for OpenSeadragonComponent
1 parent 6f67d33 commit e99a48d

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { render } from '@tests/utils/test-utils';
2+
import OpenSeadragon from 'openseadragon';
3+
import OpenSeadragonComponent from '../../../src/components/OpenSeadragonComponent';
4+
5+
vi.mock('openseadragon');
6+
7+
describe('OpenSeadragonComponent', () => {
8+
let addOnceHandler;
9+
let fitBoundsWithConstraints;
10+
11+
beforeEach(() => {
12+
addOnceHandler = vi.fn();
13+
fitBoundsWithConstraints = vi.fn();
14+
15+
// Mock methods used in the component
16+
OpenSeadragon.mockImplementation(() => ({
17+
addHandler: vi.fn(),
18+
addOnceHandler,
19+
canvas: {},
20+
destroy: vi.fn(),
21+
innerTracker: {},
22+
removeAllHandlers: vi.fn(),
23+
viewport: {
24+
centerSpringX: { target: { value: 0 } },
25+
centerSpringY: { target: { value: 0 } },
26+
fitBounds: vi.fn(),
27+
fitBoundsWithConstraints,
28+
zoomSpring: { target: { value: 1 } },
29+
},
30+
world: { addOnceHandler },
31+
}));
32+
33+
OpenSeadragon.Rect = vi.fn((x, y, width, height) => ({
34+
height, width, x, y,
35+
}));
36+
});
37+
38+
/**
39+
* Invoke the most recently registered tile-loaded handler
40+
*/
41+
function invokeTileLoadedHandler() {
42+
// Extract and invoke the most recently registered 'tile-loaded' handler
43+
// to simulate OSD firing the event when tiles finish loading
44+
// OSD provides addOnceHandler to register events on viewer
45+
const { lastCall } = addOnceHandler.mock; // Vitest's lastCall
46+
const [_eventName, tileLoadedHandler] = lastCall || [];
47+
if (tileLoadedHandler) tileLoadedHandler();
48+
}
49+
50+
/**
51+
* Render component and complete initial tile loading
52+
* @param {Array} bounds - Initial bounds
53+
* @returns {object} Render result
54+
*/
55+
function renderAndInitialize(bounds = [0, 0, 5000, 3000]) {
56+
const result = render(
57+
<OpenSeadragonComponent windowId="test" viewerConfig={{ bounds }} />,
58+
);
59+
60+
// Component registers a 'tile-loaded' handler during mount to set initial viewport
61+
invokeTileLoadedHandler();
62+
63+
// Clear mocks after initialization
64+
fitBoundsWithConstraints.mockClear();
65+
addOnceHandler.mockClear();
66+
67+
return result;
68+
}
69+
70+
it('resets zoom and center when bounds change', () => {
71+
const { rerender } = renderAndInitialize();
72+
73+
// Change bounds to different dimensions
74+
rerender(
75+
<OpenSeadragonComponent windowId="test" viewerConfig={{ bounds: [0, 0, 3000, 2000] }} />,
76+
);
77+
78+
// Component registered a 'tile-loaded' handler when bounds change
79+
invokeTileLoadedHandler();
80+
81+
// Should call fitBoundsWithConstraints with the new bounds to reset zoom and center
82+
expect(fitBoundsWithConstraints).toHaveBeenCalledWith(
83+
expect.objectContaining({
84+
height: 2000,
85+
width: 3000,
86+
x: 0,
87+
y: 0,
88+
}),
89+
true,
90+
);
91+
});
92+
93+
it('does not reset zoom when bounds remain the same', () => {
94+
const { rerender } = renderAndInitialize();
95+
96+
// Rerender with same bounds
97+
rerender(
98+
<OpenSeadragonComponent windowId="test" viewerConfig={{ bounds: [0, 0, 5000, 3000] }} />,
99+
);
100+
101+
// Should not register a new tile-loaded handler
102+
expect(addOnceHandler).not.toHaveBeenCalled();
103+
104+
// Should not call fitBoundsWithConstraints
105+
expect(fitBoundsWithConstraints).not.toHaveBeenCalled();
106+
});
107+
});

0 commit comments

Comments
 (0)