|
6 | 6 | import axios from 'axios'; |
7 | 7 | import { beforeEach, describe, expect, it, vi } from 'vitest'; |
8 | 8 | import type { FiveMClient } from '../../FiveMClient'; |
| 9 | +import { SlotAction } from '../../models/ff-models'; |
9 | 10 | import type { FlashForgeClient } from '../../tcpapi/FlashForgeClient'; |
10 | 11 | import { Commands } from '../server/Commands'; |
11 | 12 | import { Endpoints } from '../server/Endpoints'; |
@@ -495,6 +496,100 @@ describe('Control', () => { |
495 | 496 | }); |
496 | 497 | }); |
497 | 498 |
|
| 499 | + describe('AD5X material station (IFS) slot operations', () => { |
| 500 | + beforeEach(() => { |
| 501 | + mockedAxios.post.mockResolvedValue({ |
| 502 | + status: 200, |
| 503 | + data: { code: 0, message: 'Success' }, |
| 504 | + }); |
| 505 | + mockFiveMClient.isAD5X = true; |
| 506 | + }); |
| 507 | + |
| 508 | + it('should configure a slot and strip the leading # from the color', async () => { |
| 509 | + const result = await control.configureSlot(1, 'PLA', '#FF0000'); |
| 510 | + |
| 511 | + expect(result).toBe(true); |
| 512 | + expect(mockedAxios.post).toHaveBeenCalledWith( |
| 513 | + `http://printer:8898${Endpoints.Control}`, |
| 514 | + expect.objectContaining({ |
| 515 | + payload: { |
| 516 | + cmd: Commands.MaterialStationConfigCmd, |
| 517 | + args: { slot: 1, mt: 'PLA', rgb: 'FF0000' }, |
| 518 | + }, |
| 519 | + }), |
| 520 | + expect.any(Object) |
| 521 | + ); |
| 522 | + }); |
| 523 | + |
| 524 | + it('should accept a color that already lacks a # prefix', async () => { |
| 525 | + await control.configureSlot(2, 'PETG', '46328E'); |
| 526 | + |
| 527 | + expect(mockedAxios.post).toHaveBeenCalledWith( |
| 528 | + `http://printer:8898${Endpoints.Control}`, |
| 529 | + expect.objectContaining({ |
| 530 | + payload: { |
| 531 | + cmd: Commands.MaterialStationConfigCmd, |
| 532 | + args: { slot: 2, mt: 'PETG', rgb: '46328E' }, |
| 533 | + }, |
| 534 | + }), |
| 535 | + expect.any(Object) |
| 536 | + ); |
| 537 | + }); |
| 538 | + |
| 539 | + it('should send a load slot action', async () => { |
| 540 | + const result = await control.slotAction(1, SlotAction.Load); |
| 541 | + |
| 542 | + expect(result).toBe(true); |
| 543 | + expect(mockedAxios.post).toHaveBeenCalledWith( |
| 544 | + `http://printer:8898${Endpoints.Control}`, |
| 545 | + expect.objectContaining({ |
| 546 | + payload: { |
| 547 | + cmd: Commands.MaterialStationCmd, |
| 548 | + args: { slot: 1, action: 0 }, |
| 549 | + }, |
| 550 | + }), |
| 551 | + expect.any(Object) |
| 552 | + ); |
| 553 | + }); |
| 554 | + |
| 555 | + it('should send unload and cancel slot actions with the correct codes', async () => { |
| 556 | + await control.slotAction(3, SlotAction.Unload); |
| 557 | + expect(mockedAxios.post).toHaveBeenLastCalledWith( |
| 558 | + `http://printer:8898${Endpoints.Control}`, |
| 559 | + expect.objectContaining({ |
| 560 | + payload: { |
| 561 | + cmd: Commands.MaterialStationCmd, |
| 562 | + args: { slot: 3, action: 1 }, |
| 563 | + }, |
| 564 | + }), |
| 565 | + expect.any(Object) |
| 566 | + ); |
| 567 | + |
| 568 | + await control.slotAction(0, SlotAction.Cancel); |
| 569 | + expect(mockedAxios.post).toHaveBeenLastCalledWith( |
| 570 | + `http://printer:8898${Endpoints.Control}`, |
| 571 | + expect.objectContaining({ |
| 572 | + payload: { |
| 573 | + cmd: Commands.MaterialStationCmd, |
| 574 | + args: { slot: 0, action: 2 }, |
| 575 | + }, |
| 576 | + }), |
| 577 | + expect.any(Object) |
| 578 | + ); |
| 579 | + }); |
| 580 | + |
| 581 | + it('should refuse slot operations on non-AD5X printers', async () => { |
| 582 | + mockFiveMClient.isAD5X = false; |
| 583 | + |
| 584 | + const configResult = await control.configureSlot(1, 'PLA', '#FF0000'); |
| 585 | + const actionResult = await control.slotAction(1, SlotAction.Load); |
| 586 | + |
| 587 | + expect(configResult).toBe(false); |
| 588 | + expect(actionResult).toBe(false); |
| 589 | + expect(mockedAxios.post).not.toHaveBeenCalled(); |
| 590 | + }); |
| 591 | + }); |
| 592 | + |
498 | 593 | describe('sendJobControlCmd', () => { |
499 | 594 | it('should send job control command', async () => { |
500 | 595 | mockedAxios.post.mockResolvedValue({ |
|
0 commit comments