Skip to content

Commit

Permalink
refactor(app): replace RobotWorkSpace in DeckThumbnail with BaseDeck (#…
Browse files Browse the repository at this point in the history
…13875)

* refactor(app): replace RobotWorkSpace in DeckThumbnail with BaseDeck
  • Loading branch information
koji authored Nov 7, 2023
1 parent 07d518f commit d7c25b2
Show file tree
Hide file tree
Showing 9 changed files with 554 additions and 248 deletions.
313 changes: 254 additions & 59 deletions app/src/molecules/DeckThumbnail/__tests__/DeckThumbnail.test.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,108 @@
import * as React from 'react'
import { when, resetAllWhenMocks } from 'jest-when'
import {
getRobotTypeFromLoadedLabware,
FLEX_ROBOT_TYPE,
getDeckDefFromRobotType,
getRobotTypeFromLoadedLabware,
OT2_ROBOT_TYPE,
} from '@opentrons/shared-data'
import ot2StandardDeckDef from '@opentrons/shared-data/deck/definitions/3/ot2_standard.json'
import { renderWithProviders } from '@opentrons/components'
import { simpleAnalysisFileFixture } from '@opentrons/api-client'
import ot3StandardDeckDef from '@opentrons/shared-data/deck/definitions/3/ot3_standard.json'
import fixture_tiprack_300_ul from '@opentrons/shared-data/labware/fixtures/2/fixture_tiprack_300_ul.json'
import {
BaseDeck,
EXTENDED_DECK_CONFIG_FIXTURE,
partialComponentPropsMatcher,
renderWithProviders,
} from '@opentrons/components'
import {
parseInitialLoadedLabwareByAdapter,
parseLabwareInfoByLiquidId,
simpleAnalysisFileFixture,
} from '@opentrons/api-client'

import { i18n } from '../../../i18n'
import { useAttachedModules } from '../../../organisms/Devices/hooks'
import { getStandardDeckViewLayerBlockList } from '../utils/getStandardDeckViewLayerBlockList'
import { getDeckConfigFromProtocolCommands } from '../../../resources/deck_configuration/utils'
import { getAttachedProtocolModuleMatches } from '../../../organisms/ProtocolSetupModulesAndDeck/utils'
import { getProtocolModulesInfo } from '../../../organisms/Devices/ProtocolRun/utils/getProtocolModulesInfo'
import { getLabwareRenderInfo } from '../../../organisms/Devices/ProtocolRun/utils/getLabwareRenderInfo'
import { mockProtocolModuleInfo } from '../../../organisms/ProtocolSetupLabware/__fixtures__'
import { mockFetchModulesSuccessActionPayloadModules } from '../../../redux/modules/__fixtures__'
import { DeckThumbnail } from '../'
import type { LoadedLabware, RunTimeCommand } from '@opentrons/shared-data'

jest.mock('@opentrons/shared-data', () => {
const actualSharedData = jest.requireActual('@opentrons/shared-data')
return {
...actualSharedData,
getRobotTypeFromLoadedLabware: jest.fn(),
getDeckDefFromRobotType: jest.fn(),
}
})
jest.mock('@opentrons/components', () => {
const actualComponents = jest.requireActual('@opentrons/components')
return {
...actualComponents,
Module: jest.fn(({ def, x, y, children }) => (
<div>
mock Module ({x},{y}) {def.model} {children}
</div>
)),
LabwareRender: jest.fn(({ definition }) => (
<div>mock LabwareRender {definition.parameters.loadName}</div>
)),
}
})
import type {
LabwareDefinition2,
LoadedLabware,
ModuleModel,
ModuleType,
RunTimeCommand,
} from '@opentrons/shared-data'

jest.mock('@opentrons/components/src/hardware-sim/BaseDeck')
jest.mock('@opentrons/api-client')
jest.mock('@opentrons/shared-data/js/helpers')
jest.mock('../../../redux/config')
jest.mock('../../../resources/deck_configuration/utils')
jest.mock('../../../organisms/ProtocolSetupModulesAndDeck/utils')
jest.mock('../../../organisms/Devices/ProtocolRun/utils/getProtocolModulesInfo')
jest.mock('../../../organisms/Devices/hooks')
jest.mock('../../../organisms/Devices/ProtocolRun/utils/getLabwareRenderInfo')

const mockgetRobotTypeFromLoadedLabware = getRobotTypeFromLoadedLabware as jest.MockedFunction<
const mockGetRobotTypeFromLoadedLabware = getRobotTypeFromLoadedLabware as jest.MockedFunction<
typeof getRobotTypeFromLoadedLabware
>

const mockgetDeckDefFromRobotType = getDeckDefFromRobotType as jest.MockedFunction<
const mockGetDeckDefFromRobotType = getDeckDefFromRobotType as jest.MockedFunction<
typeof getDeckDefFromRobotType
>
const mockParseInitialLoadedLabwareByAdapter = parseInitialLoadedLabwareByAdapter as jest.MockedFunction<
typeof parseInitialLoadedLabwareByAdapter
>
const mockParseLabwareInfoByLiquidId = parseLabwareInfoByLiquidId as jest.MockedFunction<
typeof parseLabwareInfoByLiquidId
>
const mockUseAttachedModules = useAttachedModules as jest.MockedFunction<
typeof useAttachedModules
>
const mockGetDeckConfigFromProtocolCommands = getDeckConfigFromProtocolCommands as jest.MockedFunction<
typeof getDeckConfigFromProtocolCommands
>
const mockGetLabwareRenderInfo = getLabwareRenderInfo as jest.MockedFunction<
typeof getLabwareRenderInfo
>
const mockGetProtocolModulesInfo = getProtocolModulesInfo as jest.MockedFunction<
typeof getProtocolModulesInfo
>
const mockGetAttachedProtocolModuleMatches = getAttachedProtocolModuleMatches as jest.MockedFunction<
typeof getAttachedProtocolModuleMatches
>
const mockBaseDeck = BaseDeck as jest.MockedFunction<typeof BaseDeck>

const protocolAnalysis = simpleAnalysisFileFixture as any
const commands: RunTimeCommand[] = simpleAnalysisFileFixture.commands as any
const labware: LoadedLabware[] = simpleAnalysisFileFixture.labware as any
const MOCK_300_UL_TIPRACK_ID = '300_ul_tiprack_id'
const MOCK_MAGNETIC_MODULE_COORDS = [10, 20, 0]
const MOCK_SECOND_MAGNETIC_MODULE_COORDS = [100, 200, 0]
const MOCK_300_UL_TIPRACK_COORDS = [30, 40, 0]
const mockMagneticModule = {
moduleId: 'someMagneticModule',
model: 'magneticModuleV2' as ModuleModel,
type: 'magneticModuleType' as ModuleType,
labwareOffset: { x: 5, y: 5, z: 5 },
cornerOffsetFromSlot: { x: 1, y: 1, z: 1 },
dimensions: {
xDimension: 100,
yDimension: 100,
footprintXDimension: 50,
footprintYDimension: 50,
labwareInterfaceXDimension: 80,
labwareInterfaceYDimension: 120,
},
twoDimensionalRendering: { children: [] },
}

const render = (props: React.ComponentProps<typeof DeckThumbnail>) => {
return renderWithProviders(<DeckThumbnail {...props} />, {
Expand All @@ -54,47 +112,184 @@ const render = (props: React.ComponentProps<typeof DeckThumbnail>) => {

describe('DeckThumbnail', () => {
beforeEach(() => {
when(mockgetRobotTypeFromLoadedLabware)
when(mockGetRobotTypeFromLoadedLabware)
.calledWith(labware)
.mockReturnValue('OT-2 Standard')
when(mockgetDeckDefFromRobotType)
.calledWith('OT-2 Standard')
.mockReturnValue(OT2_ROBOT_TYPE)
when(mockGetDeckDefFromRobotType)
.calledWith(OT2_ROBOT_TYPE)
.mockReturnValue(ot2StandardDeckDef as any)
when(mockParseInitialLoadedLabwareByAdapter)
.calledWith(commands)
.mockReturnValue({})
when(mockParseLabwareInfoByLiquidId)
.calledWith(commands)
.mockReturnValue({})
mockUseAttachedModules.mockReturnValue(
mockFetchModulesSuccessActionPayloadModules
)
when(mockGetDeckConfigFromProtocolCommands)
.calledWith(commands)
.mockReturnValue(EXTENDED_DECK_CONFIG_FIXTURE)
when(mockGetLabwareRenderInfo).mockReturnValue({})
when(mockGetProtocolModulesInfo)
.calledWith(protocolAnalysis, ot2StandardDeckDef as any)
.mockReturnValue(mockProtocolModuleInfo)
when(mockGetAttachedProtocolModuleMatches)
.calledWith(
mockFetchModulesSuccessActionPayloadModules,
mockProtocolModuleInfo
)
.mockReturnValue([
{
moduleId: mockMagneticModule.moduleId,
x: MOCK_MAGNETIC_MODULE_COORDS[0],
y: MOCK_MAGNETIC_MODULE_COORDS[1],
z: MOCK_MAGNETIC_MODULE_COORDS[2],
moduleDef: mockMagneticModule as any,
nestedLabwareDef: null,
nestedLabwareDisplayName: null,
nestedLabwareId: null,
slotName: '1',
protocolLoadOrder: 1,
attachedModuleMatch: null,
},
{
moduleId: mockMagneticModule.moduleId,
x: MOCK_SECOND_MAGNETIC_MODULE_COORDS[0],
y: MOCK_SECOND_MAGNETIC_MODULE_COORDS[1],
z: MOCK_SECOND_MAGNETIC_MODULE_COORDS[2],
moduleDef: mockMagneticModule as any,
nestedLabwareDef: null,
nestedLabwareDisplayName: null,
nestedLabwareId: null,
slotName: '2',
protocolLoadOrder: 0,
attachedModuleMatch: null,
},
])
when(mockBaseDeck)
.calledWith(
partialComponentPropsMatcher({
robotType: OT2_ROBOT_TYPE,
deckLayerBlocklist: getStandardDeckViewLayerBlockList(OT2_ROBOT_TYPE),
})
)
.mockReturnValue(<div>mock BaseDeck</div>)
})
afterEach(() => {
resetAllWhenMocks()
jest.clearAllMocks()
})

it('renders loaded equipment from protocol analysis file', () => {
const { queryByText } = render({ commands, labware })
expect(queryByText('mock Module (0,0) magneticModuleV2')).not.toBeFalsy()
expect(
queryByText('mock Module (265,0) temperatureModuleV2')
).not.toBeFalsy()
expect(
queryByText('mock LabwareRender opentrons_96_tiprack_300ul')
).not.toBeFalsy()
expect(
queryByText(
'mock LabwareRender opentrons_24_aluminumblock_generic_2ml_screwcap'
)
).not.toBeFalsy()
expect(
queryByText('mock LabwareRender nest_96_wellplate_100ul_pcr_full_skirt')
).not.toBeFalsy()
})
it('renders an OT-2 deck view when the protocol is an OT-2 protocol', () => {
when(mockgetRobotTypeFromLoadedLabware)
.calledWith(labware)
.mockReturnValue('OT-2 Standard')
render({ commands, labware })
expect(mockgetDeckDefFromRobotType).toHaveBeenCalledWith('OT-2 Standard')
const { getByText } = render({
protocolAnalysis: protocolAnalysis,
})
getByText('mock BaseDeck')
})

it('renders an OT-3 deck view when the protocol is an OT-3 protocol', () => {
when(mockgetRobotTypeFromLoadedLabware)
// ToDo (kk:11/06/2023) update this test later
// const mockLabwareLocations = [
// {
// labwareLocation: { slotName: 'C1' },
// definition: fixture_tiprack_300_ul as LabwareDefinition2,
// topLabwareId: '300_ul_tiprack_id',
// topLabwareDisplayName: 'fresh tips',
// },
// ]
// const mockModuleLocations = [
// {
// moduleModel: 'magneticModuleV2',
// moduleLocation: { slotName: 'C1' },
// innerProps: {},
// nestedLabwareDef: null,
// },
// {
// moduleModel: 'magneticModuleV2',
// moduleLocation: { slotName: 'B1' },
// innerProps: {},
// nestedLabwareDef: null,
// },
// ]
when(mockGetRobotTypeFromLoadedLabware)
.calledWith(labware)
.mockReturnValue('OT-3 Standard')
render({ commands, labware })
expect(mockgetDeckDefFromRobotType).toHaveBeenCalledWith('OT-3 Standard')
.mockReturnValue(FLEX_ROBOT_TYPE)
when(mockGetDeckDefFromRobotType)
.calledWith(FLEX_ROBOT_TYPE)
.mockReturnValue(ot3StandardDeckDef as any)
when(mockParseInitialLoadedLabwareByAdapter)
.calledWith(commands)
.mockReturnValue({})
mockUseAttachedModules.mockReturnValue(
mockFetchModulesSuccessActionPayloadModules
)
when(mockGetDeckConfigFromProtocolCommands)
.calledWith(commands)
.mockReturnValue(EXTENDED_DECK_CONFIG_FIXTURE)
when(mockGetLabwareRenderInfo).mockReturnValue({
[MOCK_300_UL_TIPRACK_ID]: {
labwareDef: fixture_tiprack_300_ul as LabwareDefinition2,
displayName: 'fresh tips',
x: MOCK_300_UL_TIPRACK_COORDS[0],
y: MOCK_300_UL_TIPRACK_COORDS[1],
z: MOCK_300_UL_TIPRACK_COORDS[2],
slotName: 'C1',
},
})
when(mockGetProtocolModulesInfo)
.calledWith(protocolAnalysis, ot3StandardDeckDef as any)
.mockReturnValue(mockProtocolModuleInfo)
when(mockGetAttachedProtocolModuleMatches)
.calledWith(
mockFetchModulesSuccessActionPayloadModules,
mockProtocolModuleInfo
)
.mockReturnValue([
{
moduleId: mockMagneticModule.moduleId,
x: MOCK_MAGNETIC_MODULE_COORDS[0],
y: MOCK_MAGNETIC_MODULE_COORDS[1],
z: MOCK_MAGNETIC_MODULE_COORDS[2],
moduleDef: mockMagneticModule as any,
nestedLabwareDef: null,
nestedLabwareDisplayName: null,
nestedLabwareId: null,
slotName: 'C1',
protocolLoadOrder: 1,
attachedModuleMatch: null,
},
{
moduleId: mockMagneticModule.moduleId,
x: MOCK_SECOND_MAGNETIC_MODULE_COORDS[0],
y: MOCK_SECOND_MAGNETIC_MODULE_COORDS[1],
z: MOCK_SECOND_MAGNETIC_MODULE_COORDS[2],
moduleDef: mockMagneticModule as any,
nestedLabwareDef: null,
nestedLabwareDisplayName: null,
nestedLabwareId: null,
slotName: 'B1',
protocolLoadOrder: 0,
attachedModuleMatch: null,
},
])
when(mockBaseDeck)
.calledWith(
partialComponentPropsMatcher({
robotType: FLEX_ROBOT_TYPE,
deckLayerBlocklist: getStandardDeckViewLayerBlockList(
FLEX_ROBOT_TYPE
),
deckConfig: EXTENDED_DECK_CONFIG_FIXTURE,
labwareLocations: expect.anything(),
moduleLocations: expect.anything(),
})
)
.mockReturnValue(<div>mock BaseDeck</div>)

const { getByText } = render({
protocolAnalysis: protocolAnalysis,
})
getByText('mock BaseDeck')
})
})
Loading

0 comments on commit d7c25b2

Please sign in to comment.