From 674e484a7e4350e73e46e470002f540589633b04 Mon Sep 17 00:00:00 2001 From: Jamey Huffnagle Date: Mon, 19 Aug 2024 13:56:30 -0400 Subject: [PATCH] fix(app): Update isRunning runs statuses (#16045) Closes RQA-2892 --- .../hooks/__tests__/useRunStatuses.test.tsx | 93 ++++++++++++++++--- .../organisms/Devices/hooks/useRunStatuses.ts | 16 ++-- .../CalibrationDetails/OverflowMenu.tsx | 2 + .../__tests__/OverflowMenu.test.tsx | 32 ++++++- 4 files changed, 124 insertions(+), 19 deletions(-) diff --git a/app/src/organisms/Devices/hooks/__tests__/useRunStatuses.test.tsx b/app/src/organisms/Devices/hooks/__tests__/useRunStatuses.test.tsx index 9277ddafd10..db738d4cafd 100644 --- a/app/src/organisms/Devices/hooks/__tests__/useRunStatuses.test.tsx +++ b/app/src/organisms/Devices/hooks/__tests__/useRunStatuses.test.tsx @@ -5,8 +5,14 @@ import { RUN_STATUS_RUNNING, RUN_STATUS_STOPPED, RUN_STATUS_SUCCEEDED, + RUN_STATUS_AWAITING_RECOVERY, + RUN_STATUS_AWAITING_RECOVERY_PAUSED, + RUN_STATUS_STOP_REQUESTED, + RUN_STATUS_FINISHING, + RUN_STATUS_BLOCKED_BY_OPEN_DOOR, + RUN_STATUS_AWAITING_RECOVERY_BLOCKED_BY_OPEN_DOOR, } from '@opentrons/api-client' -import { vi, it, expect, describe, beforeEach, afterEach } from 'vitest' +import { vi, it, expect, describe, beforeEach } from 'vitest' import { useCurrentRunId } from '../../../../resources/runs' import { useRunStatus } from '../../../RunTimeControl/hooks' @@ -15,14 +21,11 @@ import { useRunStatuses } from '..' vi.mock('../../../../resources/runs') vi.mock('../../../RunTimeControl/hooks') -describe(' useRunStatuses ', () => { +describe('useRunStatuses', () => { beforeEach(() => { vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_RUNNING) vi.mocked(useCurrentRunId).mockReturnValue('123') }) - afterEach(() => { - vi.resetAllMocks() - }) it('returns everything as false when run status is null', () => { vi.mocked(useRunStatus).mockReturnValue(null) @@ -35,7 +38,7 @@ describe(' useRunStatuses ', () => { }) }) - it('returns true isRunStill and Terminal when run status is suceeded', () => { + it(`returns true isRunStill and Terminal when run status is ${RUN_STATUS_SUCCEEDED}`, () => { vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_SUCCEEDED) const result = useRunStatuses() expect(result).toStrictEqual({ @@ -46,7 +49,7 @@ describe(' useRunStatuses ', () => { }) }) - it('returns true isRunStill and Terminal when run status is stopped', () => { + it(`returns true isRunStill and Terminal when run status is ${RUN_STATUS_STOPPED}`, () => { vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_STOPPED) const result = useRunStatuses() expect(result).toStrictEqual({ @@ -57,7 +60,7 @@ describe(' useRunStatuses ', () => { }) }) - it('returns true isRunStill and Terminal when run status is failed', () => { + it(`returns true isRunStill and Terminal when run status is ${RUN_STATUS_FAILED}`, () => { vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_FAILED) const result = useRunStatuses() expect(result).toStrictEqual({ @@ -68,7 +71,7 @@ describe(' useRunStatuses ', () => { }) }) - it('returns true isRunStill and isRunIdle when run status is idle', () => { + it(`returns true isRunStill and isRunIdle when run status is ${RUN_STATUS_IDLE}`, () => { vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_IDLE) const result = useRunStatuses() expect(result).toStrictEqual({ @@ -79,7 +82,7 @@ describe(' useRunStatuses ', () => { }) }) - it('returns true isRunRunning when status is running', () => { + it(`returns true isRunRunning when status is ${RUN_STATUS_RUNNING}`, () => { vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_RUNNING) const result = useRunStatuses() expect(result).toStrictEqual({ @@ -90,7 +93,7 @@ describe(' useRunStatuses ', () => { }) }) - it('returns true isRunRunning when status is paused', () => { + it(`returns true isRunRunning when status is ${RUN_STATUS_PAUSED}`, () => { vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_PAUSED) const result = useRunStatuses() expect(result).toStrictEqual({ @@ -100,4 +103,72 @@ describe(' useRunStatuses ', () => { isRunIdle: false, }) }) + + it(`returns true isRunRunning when status is ${RUN_STATUS_AWAITING_RECOVERY}`, () => { + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_AWAITING_RECOVERY) + const result = useRunStatuses() + expect(result).toStrictEqual({ + isRunRunning: true, + isRunStill: false, + isRunTerminal: false, + isRunIdle: false, + }) + }) + + it(`returns true isRunRunning when status is ${RUN_STATUS_AWAITING_RECOVERY_PAUSED}`, () => { + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_AWAITING_RECOVERY_PAUSED) + const result = useRunStatuses() + expect(result).toStrictEqual({ + isRunRunning: true, + isRunStill: false, + isRunTerminal: false, + isRunIdle: false, + }) + }) + + it(`returns true isRunRunning when status is ${RUN_STATUS_STOP_REQUESTED}`, () => { + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_STOP_REQUESTED) + const result = useRunStatuses() + expect(result).toStrictEqual({ + isRunRunning: true, + isRunStill: false, + isRunTerminal: false, + isRunIdle: false, + }) + }) + + it(`returns true isRunRunning when status is ${RUN_STATUS_FINISHING}`, () => { + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_FINISHING) + const result = useRunStatuses() + expect(result).toStrictEqual({ + isRunRunning: true, + isRunStill: false, + isRunTerminal: false, + isRunIdle: false, + }) + }) + + it(`returns true isRunRunning when status is ${RUN_STATUS_BLOCKED_BY_OPEN_DOOR}`, () => { + vi.mocked(useRunStatus).mockReturnValue(RUN_STATUS_BLOCKED_BY_OPEN_DOOR) + const result = useRunStatuses() + expect(result).toStrictEqual({ + isRunRunning: true, + isRunStill: false, + isRunTerminal: false, + isRunIdle: false, + }) + }) + + it(`returns true isRunRunning when status is ${RUN_STATUS_AWAITING_RECOVERY_BLOCKED_BY_OPEN_DOOR}`, () => { + vi.mocked(useRunStatus).mockReturnValue( + RUN_STATUS_AWAITING_RECOVERY_BLOCKED_BY_OPEN_DOOR + ) + const result = useRunStatuses() + expect(result).toStrictEqual({ + isRunRunning: true, + isRunStill: false, + isRunTerminal: false, + isRunIdle: false, + }) + }) }) diff --git a/app/src/organisms/Devices/hooks/useRunStatuses.ts b/app/src/organisms/Devices/hooks/useRunStatuses.ts index bf1c550efa0..39c15251c7a 100644 --- a/app/src/organisms/Devices/hooks/useRunStatuses.ts +++ b/app/src/organisms/Devices/hooks/useRunStatuses.ts @@ -5,6 +5,10 @@ import { RUN_STATUS_IDLE, RUN_STATUS_PAUSED, RUN_STATUS_RUNNING, + RUN_STATUS_STOP_REQUESTED, + RUN_STATUS_FINISHING, + RUN_STATUS_BLOCKED_BY_OPEN_DOOR, + RUN_STATUS_AWAITING_RECOVERY_BLOCKED_BY_OPEN_DOOR, } from '@opentrons/api-client' import { useCurrentRunId } from '../../../resources/runs' import { useRunStatus } from '../../RunTimeControl/hooks' @@ -23,16 +27,14 @@ export function useRunStatuses(): RunStatusesInfo { const runStatus = useRunStatus(currentRunId) const isRunIdle = runStatus === RUN_STATUS_IDLE const isRunRunning = - // todo(mm, 2024-03-13): This excludes statuses like: - // * RUN_STATUS_FINISHING - // * RUN_STATUS_STOP_REQUESTED - // * RUN_STATUS_BLOCKED_BY_OPEN_DOOR - // * RUN_STATUS_AWAITING_RECOVERY_BLOCKED_BY_OPEN_DOOR - // And it's not clear whether that's intentional. runStatus === RUN_STATUS_PAUSED || runStatus === RUN_STATUS_RUNNING || runStatus === RUN_STATUS_AWAITING_RECOVERY || - runStatus === RUN_STATUS_AWAITING_RECOVERY_PAUSED + runStatus === RUN_STATUS_AWAITING_RECOVERY_PAUSED || + runStatus === RUN_STATUS_STOP_REQUESTED || + runStatus === RUN_STATUS_FINISHING || + runStatus === RUN_STATUS_BLOCKED_BY_OPEN_DOOR || + runStatus === RUN_STATUS_AWAITING_RECOVERY_BLOCKED_BY_OPEN_DOOR const isRunTerminal = runStatus != null ? (RUN_STATUSES_TERMINAL as RunStatus[]).includes(runStatus) diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/OverflowMenu.tsx b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/OverflowMenu.tsx index d6048011a57..7e9ac21ee77 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/OverflowMenu.tsx +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/OverflowMenu.tsx @@ -214,6 +214,8 @@ export function OverflowMenu({ css={css` border-radius: ${BORDERS.borderRadius8}; `} + disabled={isRunning} + aria-label={`CalibrationOverflowMenu_button_calibrate`} > {t( ot3PipCal == null diff --git a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx index f35f4d64997..3bdb82574c5 100644 --- a/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx +++ b/app/src/organisms/RobotSettingsCalibration/CalibrationDetails/__tests__/OverflowMenu.test.tsx @@ -3,7 +3,7 @@ import { fireEvent, screen } from '@testing-library/react' import { when } from 'vitest-when' import '@testing-library/jest-dom/vitest' import { describe, it, expect, vi, beforeEach } from 'vitest' -import { OT3_PIPETTES } from '@opentrons/shared-data' +import { OT3_PIPETTES, isFlexPipette } from '@opentrons/shared-data' import { useDeleteCalibrationMutation, useAllPipetteOffsetCalibrationsQuery, @@ -27,6 +27,7 @@ import { import { renderWithProviders } from '../../../../__testing-utils__' import { useIsEstopNotDisengaged } from '../../../../resources/devices/hooks/useIsEstopNotDisengaged' import { OverflowMenu } from '../OverflowMenu' + import type { Mount } from '@opentrons/components' const render = ( @@ -51,6 +52,14 @@ vi.mock('file-saver', async importOriginal => { saveAs: vi.fn(), } }) + +vi.mock('@opentrons/shared-data', async () => { + const actual = await vi.importActual('@opentrons/shared-data') + return { + ...actual, + isFlexPipette: vi.fn(), + } +}) vi.mock('@opentrons/react-api-client') vi.mock('../../../../redux/sessions/selectors') vi.mock('../../../../redux/discovery') @@ -113,6 +122,7 @@ describe('OverflowMenu', () => { }, } as any) when(useIsEstopNotDisengaged).calledWith(ROBOT_NAME).thenReturn(false) + vi.mocked(isFlexPipette).mockReturnValue(false) }) it('should render Overflow menu buttons - pipette offset calibrations', () => { @@ -186,6 +196,7 @@ describe('OverflowMenu', () => { ...props, pipetteName: OT3_PIPETTE_NAME, } + vi.mocked(isFlexPipette).mockReturnValue(true) render(props) const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' @@ -212,6 +223,7 @@ describe('OverflowMenu', () => { ...props, pipetteName: OT3_PIPETTE_NAME, } + vi.mocked(isFlexPipette).mockReturnValue(true) render(props) const button = screen.getByLabelText( 'CalibrationOverflowMenu_button_pipetteOffset' @@ -302,4 +314,22 @@ describe('OverflowMenu', () => { screen.getByLabelText('CalibrationOverflowMenu_button_pipetteOffset') ).toBeDisabled() }) + + it('should disable the calibration overflow menu option when the run is running', () => { + vi.mocked(useRunStatuses).mockReturnValue({ + ...RUN_STATUSES, + isRunRunning: true, + }) + vi.mocked(isFlexPipette).mockReturnValue(true) + + render(props) + + fireEvent.click( + screen.getByLabelText('CalibrationOverflowMenu_button_pipetteOffset') + ) + + expect( + screen.getByLabelText('CalibrationOverflowMenu_button_calibrate') + ).toBeDisabled() + }) })