Skip to content

Commit dd3d22e

Browse files
build(deps-dev): upgrade Jest from v29 to v30.2.0
Upgrade jest, jest-environment-jsdom, jest-util to 30.2.0 and @types/jest to 30.0.0. Update test assertions to use computed RGB color values as the newer jsdom resolves named CSS colors to RGB.
1 parent cd9596e commit dd3d22e

8 files changed

Lines changed: 2174 additions & 1068 deletions

File tree

package-lock.json

Lines changed: 1765 additions & 1053 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"@rollup/plugin-typescript": "^12.1.2",
7373
"@testing-library/jest-dom": "^6.6.3",
7474
"@testing-library/react": "^16.1.0",
75-
"@types/jest": "^29.5.14",
75+
"@types/jest": "^30.0.0",
7676
"@types/react": "^19.2.10",
7777
"@types/react-dom": "^19.2.3",
7878
"eslint": "^9.39.2",
@@ -81,9 +81,9 @@
8181
"eslint-plugin-react": "^7.37.5",
8282
"eslint-plugin-react-hooks": "^7.0.1",
8383
"globals": "^17.0.0",
84-
"jest": "^29.7.0",
85-
"jest-environment-jsdom": "^29.7.0",
86-
"jest-util": "^29.7.0",
84+
"jest": "^30.2.0",
85+
"jest-environment-jsdom": "^30.2.0",
86+
"jest-util": "^30.2.0",
8787
"prettier": "^3.5.3",
8888
"prettier-config-standard": "^7.0.0",
8989
"prettier-plugin-multiline-arrays": "^4.1.3",

src/components/ider/AttachDiskImage.test.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ describe('AttachDiskImage', () => {
195195
<AttachDiskImage {...defaultProps} containerStyle={customStyle} />
196196
)
197197

198-
expect(container.firstChild).toHaveStyle('background-color: red')
198+
expect(container.firstChild).toHaveStyle('background-color: rgb(255, 0, 0)')
199199
})
200200

201201
/**
@@ -223,7 +223,7 @@ describe('AttachDiskImage', () => {
223223
render(<AttachDiskImage {...defaultProps} buttonStyle={customStyle} />)
224224

225225
expect(screen.getByText('ider.start')).toHaveStyle(
226-
'background-color: purple'
226+
'background-color: rgb(128, 0, 128)'
227227
)
228228
})
229229

@@ -251,7 +251,7 @@ describe('AttachDiskImage', () => {
251251
render(<AttachDiskImage {...defaultProps} fileSelectStyle={customStyle} />)
252252

253253
expect(screen.getByText('ider.selectFile')).toHaveStyle(
254-
'background-color: green'
254+
'background-color: rgb(0, 128, 0)'
255255
)
256256
})
257257

src/components/ider/ider.test.tsx

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424

2525
import { render } from '@testing-library/react'
2626
import { IDER } from './ider'
27+
import {
28+
AMTRedirector,
29+
AMTIDER
30+
} from '@device-management-toolkit/ui-toolkit/core'
2731

2832
/**
2933
* Mock the ui-toolkit/core dependencies
@@ -263,4 +267,119 @@ describe('IDER', () => {
263267

264268
expect(container.firstChild).toBeNull()
265269
})
270+
271+
/**
272+
* Sector stats tracks floppy read operations
273+
*
274+
* When the IDER session is active and data is read from the
275+
* virtual floppy device, the sector stats should be tracked.
276+
*/
277+
it('should track floppy read in sector stats', () => {
278+
const mockFile = new File(['test'], 'test.iso', {
279+
type: 'application/octet-stream'
280+
})
281+
const { rerender } = render(
282+
<IDER {...defaultProps} cdrom={mockFile} iderState={0} />
283+
)
284+
285+
// Start IDER
286+
rerender(<IDER {...defaultProps} cdrom={mockFile} iderState={1} />)
287+
288+
// Get the AMTIDER instance created during startIder
289+
const iderInstance = (AMTIDER as unknown as jest.Mock).mock.results[0]?.value
290+
if (iderInstance?.sectorStats) {
291+
iderInstance.sectorStats(1, 0, 100, 0, 10) // mode=read, dev=floppy
292+
expect(iderInstance.floppyRead).toBe(10 * 512)
293+
}
294+
})
295+
296+
/**
297+
* Sector stats tracks CD-ROM read operations
298+
*
299+
* CD-ROM read operations use a larger sector size (2048 bytes)
300+
* compared to floppy (512 bytes).
301+
*/
302+
it('should track cdrom read in sector stats', () => {
303+
const mockFile = new File(['test'], 'test.iso', {
304+
type: 'application/octet-stream'
305+
})
306+
const { rerender } = render(
307+
<IDER {...defaultProps} cdrom={mockFile} iderState={0} />
308+
)
309+
310+
rerender(<IDER {...defaultProps} cdrom={mockFile} iderState={1} />)
311+
312+
const iderInstance = (AMTIDER as unknown as jest.Mock).mock.results[0]?.value
313+
if (iderInstance?.sectorStats) {
314+
iderInstance.sectorStats(1, 1, 100, 0, 5) // mode=read, dev=cdrom
315+
expect(iderInstance.cdromRead).toBe(5 * 2048)
316+
}
317+
})
318+
319+
/**
320+
* Sector stats tracks floppy write operations
321+
*/
322+
it('should track floppy write in sector stats', () => {
323+
const mockFile = new File(['test'], 'test.iso', {
324+
type: 'application/octet-stream'
325+
})
326+
const { rerender } = render(
327+
<IDER {...defaultProps} cdrom={mockFile} iderState={0} />
328+
)
329+
330+
rerender(<IDER {...defaultProps} cdrom={mockFile} iderState={1} />)
331+
332+
const iderInstance = (AMTIDER as unknown as jest.Mock).mock.results[0]?.value
333+
if (iderInstance?.sectorStats) {
334+
iderInstance.sectorStats(0, 0, 100, 0, 8) // mode=write, dev=floppy
335+
expect(iderInstance.floppyWrite).toBe(8 * 512)
336+
}
337+
})
338+
339+
/**
340+
* Sector stats tracks CD-ROM write operations
341+
*/
342+
it('should track cdrom write in sector stats', () => {
343+
const mockFile = new File(['test'], 'test.iso', {
344+
type: 'application/octet-stream'
345+
})
346+
const { rerender } = render(
347+
<IDER {...defaultProps} cdrom={mockFile} iderState={0} />
348+
)
349+
350+
rerender(<IDER {...defaultProps} cdrom={mockFile} iderState={1} />)
351+
352+
const iderInstance = (AMTIDER as unknown as jest.Mock).mock.results[0]?.value
353+
if (iderInstance?.sectorStats) {
354+
iderInstance.sectorStats(0, 1, 100, 0, 3) // mode=write, dev=cdrom
355+
expect(iderInstance.cdromWrite).toBe(3 * 2048)
356+
}
357+
})
358+
359+
/**
360+
* Connection state change callback is invoked
361+
*
362+
* When the WebSocket connection state changes, the onConnectionStateChange
363+
* callback should be fired. This is set up during startIder.
364+
*/
365+
it('should handle connection state change callback', () => {
366+
const mockFile = new File(['test'], 'test.iso', {
367+
type: 'application/octet-stream'
368+
})
369+
const { rerender } = render(
370+
<IDER {...defaultProps} cdrom={mockFile} iderState={0} />
371+
)
372+
373+
rerender(<IDER {...defaultProps} cdrom={mockFile} iderState={1} />)
374+
375+
// Get the redirector instance
376+
const redirectorInstance = (AMTRedirector as unknown as jest.Mock).mock
377+
.results[0]?.value
378+
if (redirectorInstance?.onStateChanged) {
379+
// Should not throw when invoked
380+
expect(() => {
381+
redirectorInstance.onStateChanged(redirectorInstance, 2)
382+
}).not.toThrow()
383+
}
384+
})
266385
})

src/components/kvm/ConnectButton.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ describe('ConnectButton', () => {
118118
/>
119119
)
120120

121-
expect(screen.getByRole('button')).toHaveStyle('background-color: red')
121+
expect(screen.getByRole('button')).toHaveStyle('background-color: rgb(255, 0, 0)')
122122
})
123123

124124
/**

src/components/kvm/UI.test.tsx

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919
*/
2020

2121
import { useEffect } from 'react'
22-
import { render, screen } from '@testing-library/react'
22+
import { render, screen, fireEvent } from '@testing-library/react'
2323
import { KVM } from './UI'
24+
import {
25+
AMTKvmDataRedirector,
26+
KeyBoardHelper
27+
} from '@device-management-toolkit/ui-toolkit/core'
2428

2529
/**
2630
* Mock the Header component
@@ -154,7 +158,7 @@ describe('KVM', () => {
154158
<KVM {...defaultProps} containerStyle={customStyle} />
155159
)
156160

157-
expect(container.firstChild).toHaveStyle('background-color: blue')
161+
expect(container.firstChild).toHaveStyle('background-color: rgb(0, 0, 255)')
158162
})
159163

160164
/**
@@ -221,4 +225,56 @@ describe('KVM', () => {
221225
// The actual enforcement happens inside the component
222226
expect(screen.getByTestId('mock-canvas')).toBeInTheDocument()
223227
})
228+
229+
/**
230+
* Clicking Connect starts KVM connection
231+
*
232+
* When autoConnect is true and the user clicks Connect,
233+
* the KVM WebSocket connection should be started.
234+
*/
235+
it('should start KVM when clicking Connect', () => {
236+
const startSpy = jest.spyOn(AMTKvmDataRedirector.prototype, 'start')
237+
const grabSpy = jest.spyOn(KeyBoardHelper.prototype, 'GrabKeyInput')
238+
239+
render(<KVM {...defaultProps} autoConnect={true} />)
240+
241+
fireEvent.click(screen.getByText('Connect'))
242+
243+
expect(startSpy).toHaveBeenCalled()
244+
expect(grabSpy).toHaveBeenCalled()
245+
246+
startSpy.mockRestore()
247+
grabSpy.mockRestore()
248+
})
249+
250+
/**
251+
* Component stops KVM when device changes
252+
*
253+
* When the deviceId prop changes, the component should stop
254+
* the current KVM connection and reinitialize for the new device.
255+
*/
256+
it('should stop KVM when deviceId changes', () => {
257+
const stopSpy = jest.spyOn(AMTKvmDataRedirector.prototype, 'stop')
258+
259+
const { rerender } = render(<KVM {...defaultProps} />)
260+
261+
rerender(<KVM {...defaultProps} deviceId='new-device-id' />)
262+
263+
expect(stopSpy).toHaveBeenCalled()
264+
265+
stopSpy.mockRestore()
266+
})
267+
268+
/**
269+
* Mouse events are forwarded to MouseHelper
270+
*
271+
* The PureCanvas component receives mouse event handlers that
272+
* forward events to the MouseHelper for remote desktop interaction.
273+
*/
274+
it('should render canvas for mouse events', () => {
275+
render(<KVM {...defaultProps} />)
276+
277+
const canvas = screen.getByTestId('mock-canvas')
278+
expect(canvas).toBeInTheDocument()
279+
})
224280
})

src/components/sol/Sol.test.tsx

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
* the Sol component's UI logic in isolation.
2727
*/
2828

29-
import { render, screen, fireEvent } from '@testing-library/react'
29+
import { render, screen, fireEvent, act } from '@testing-library/react'
3030
import { Sol } from './Sol'
31+
import { AMTRedirector } from '@device-management-toolkit/ui-toolkit/core'
3132

3233
/**
3334
* Mock the Terminal component
@@ -39,7 +40,8 @@ import { Sol } from './Sol'
3940
*/
4041
jest.mock('./Terminal', () => ({
4142
__esModule: true,
42-
default: () => <div data-testid='mock-terminal'>Terminal</div>
43+
default: () => <div data-testid='mock-terminal'>Terminal</div>,
44+
Term: () => <div data-testid='mock-terminal'>Terminal</div>
4345
}))
4446

4547
/**
@@ -160,7 +162,7 @@ describe('Sol', () => {
160162
<Sol {...defaultProps} containerStyle={customStyle} />
161163
)
162164

163-
expect(container.firstChild).toHaveStyle('background-color: green')
165+
expect(container.firstChild).toHaveStyle('background-color: rgb(0, 128, 0)')
164166
})
165167

166168
/**
@@ -184,7 +186,7 @@ describe('Sol', () => {
184186
const customStyle = { backgroundColor: 'purple' }
185187
render(<Sol {...defaultProps} buttonStyle={customStyle} />)
186188

187-
expect(screen.getByRole('button')).toHaveStyle('background-color: purple')
189+
expect(screen.getByRole('button')).toHaveStyle('background-color: rgb(128, 0, 128)')
188190
})
189191

190192
/**
@@ -263,4 +265,61 @@ describe('Sol', () => {
263265
// Terminal should not be visible when not connected
264266
expect(screen.queryByTestId('mock-terminal')).not.toBeInTheDocument()
265267
})
268+
269+
/**
270+
* Disconnect button shown when connected
271+
*
272+
* After connection state changes to 3 (ready), the button
273+
* text should change to 'sol.disconnect' and the terminal should appear.
274+
*/
275+
it('should show disconnect button and terminal when connected', () => {
276+
render(<Sol {...defaultProps} />)
277+
278+
const mockRedirector = (AMTRedirector as jest.Mock).mock.results[0].value
279+
280+
act(() => {
281+
mockRedirector.onStateChanged(mockRedirector, 3)
282+
})
283+
284+
expect(screen.getByText('sol.disconnect')).toBeInTheDocument()
285+
expect(screen.getByTestId('mock-terminal')).toBeInTheDocument()
286+
})
287+
288+
/**
289+
* Clicking disconnect stops the SOL connection
290+
*
291+
* When the user clicks disconnect, the component should stop
292+
* the redirector and reset state to disconnected.
293+
*/
294+
it('should stop SOL when clicking disconnect', () => {
295+
render(<Sol {...defaultProps} />)
296+
297+
const mockRedirector = (AMTRedirector as jest.Mock).mock.results[0].value
298+
299+
// Simulate connected state
300+
act(() => {
301+
mockRedirector.onStateChanged(mockRedirector, 3)
302+
})
303+
304+
// Click disconnect
305+
fireEvent.click(screen.getByText('sol.disconnect'))
306+
307+
expect(mockRedirector.stop).toHaveBeenCalled()
308+
})
309+
310+
/**
311+
* Clicking connect starts the SOL connection
312+
*
313+
* When disconnected, clicking the connect button should initiate
314+
* the WebSocket connection to the AMT device.
315+
*/
316+
it('should start SOL when clicking connect', () => {
317+
render(<Sol {...defaultProps} />)
318+
319+
const mockRedirector = (AMTRedirector as jest.Mock).mock.results[0].value
320+
321+
fireEvent.click(screen.getByText('sol.connect'))
322+
323+
expect(mockRedirector.start).toHaveBeenCalled()
324+
})
266325
})

0 commit comments

Comments
 (0)