Skip to content

Commit

Permalink
uncommit me
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohammer5 committed Sep 25, 2023
1 parent e01148b commit 1422199
Show file tree
Hide file tree
Showing 7 changed files with 330 additions and 7 deletions.
196 changes: 196 additions & 0 deletions src/pages/dataElements/New.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import { RenderResult, act, fireEvent, render, waitFor } from '@testing-library/react'
import React from 'react'
import { RouterProvider, createMemoryRouter } from 'react-router-dom'
import dataElementSchemaMock from '../../__mocks__/schema/dataElementsSchema.json'
import { useSchemaStore } from '../../lib/schemas/schemaStore'
import { ModelSchemas } from '../../lib/useLoadApp'
import { ComponentWithProvider } from '../../testUtils/TestComponentWithRouter'
import attributes from './__mocks__/attributes.json'
import categoryCombosPage1 from './__mocks__/categoryCombosPage1.json'
import { Component as New } from './New'

async function changeSingleSelect(
result: RenderResult,
selectLabel: string,
value: string
) {
const label = result.getByText(selectLabel)
expect(label).toBeTruthy()

const field = label.parentNode?.parentNode as HTMLElement
expect(field).toBeTruthy()

const trigger = field.querySelector('[data-test="dhis2-uicore-select-input"]') as HTMLElement
expect(trigger).toBeTruthy()

fireEvent.click(trigger)

await waitFor(() => {
expect(result.container.querySelector('[class*="layer"]')).toBeTruthy()
})

const optionSelector = `[data-value="${value}"]`
await waitFor(() => {
if (!result.container.querySelector(optionSelector)) {
throw new Error('Could not find option')
}
})

const optionElement = result.container.querySelector(optionSelector) as HTMLElement
fireEvent.click(optionElement)
}

describe('Data Elements / New', () => {
useSchemaStore.getState().setSchemas({
dataElement: dataElementSchemaMock,
} as unknown as ModelSchemas)

const customData = {
attributes: attributes,
categoryCombos: categoryCombosPage1,
}

it.only('should return to the list view when cancelling', async () => {
const List: React.FC = jest.fn(() => <div />)
const router = createMemoryRouter(
[
{ path: '/new', element: <New /> },
{ path: '/dataElements', element: <List /> },
],
{ initialEntries: ['/new'] }
)

const result = render(
<ComponentWithProvider dataForCustomProvider={customData}>
<RouterProvider router={router} />
</ComponentWithProvider>
)

await waitFor(() => {
expect(result.queryByText('Exit without saving')).toBeTruthy()
})

expect(List).toHaveBeenCalledTimes(0)

const cancelButton = result.queryByText('Exit without saving', {
selector: 'button',
})
fireEvent.click(cancelButton as HTMLButtonElement)

expect(List).toHaveBeenCalledTimes(1)
})

it('should not submit when required values are missing', async () => {
const router = createMemoryRouter([{ path: '/', element: <New /> }])
const result = render(
<ComponentWithProvider dataForCustomProvider={customData}>
<RouterProvider router={router} />
</ComponentWithProvider>
)

await waitFor(() => {
expect(result.queryByText('Create data element')).toBeTruthy()
})

const submitButton = result.queryByText('Create data element', {
selector: 'button',
})
fireEvent.click(submitButton as HTMLButtonElement)

await waitFor(() => {
expect(result.container.querySelector('.error')).toBeTruthy()
})

expect(
result.container.querySelectorAll(
'.error[data-test*="validation"]'
).length
).toBe(4)

expect(
result.container.querySelector('label[for="name"] + div .error')
).toBeTruthy()

expect(
result.container.querySelector(
'label[for="shortName"] + div .error'
)
).toBeTruthy()

expect(
result.container.querySelector(
'label[for="valueType"] + div .error'
)
).toBeTruthy()

expect(
result.container.querySelector(
'label[for="aggregationType"] + div .error'
)
).toBeTruthy()
})

it('should submit the data and return to the list view on success', async () => {
const List: React.FC = jest.fn(() => <div />)
const dataElementCustomData = jest.fn(() => Promise.resolve({}))
const router = createMemoryRouter(
[
{ path: '/new', element: <New /> },
{ path: '/dataElements', element: <List /> },
],
{
initialIndex: 0,
initialEntries: ['/new'],
}
)
const result = render(
<>
<div id="dhis2-portal-root" />
<ComponentWithProvider dataForCustomProvider={{
...customData,
dataElements: dataElementCustomData,
}}>
<RouterProvider router={router} />
</ComponentWithProvider>
</>
)

await waitFor(() => {
expect(result.queryByText('Create data element')).toBeTruthy()
})

act(() => {
fireEvent.change(
result.getByLabelText('Name (required)*') as HTMLElement,
{ target: { value: 'Data element name' } }
)
})

act(() => {
fireEvent.change(
result.getByLabelText('Short name (required)*') as HTMLElement,
{ target: { value: 'Data element name' } }
)
})

await act(async () => {
await changeSingleSelect(result, 'Value type (required)', 'TEXT')
})

await act(async () => {
await changeSingleSelect(result, 'Aggregation type (required)', 'SUM')
})

act(() => {
fireEvent.click(
result.queryByText('Create data element', {
selector: 'button',
}) as HTMLButtonElement
)
})

await waitFor(() => {
expect(List).toHaveBeenCalledTimes(1)
})
})
})
4 changes: 2 additions & 2 deletions src/pages/dataElements/New.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ export const Component = () => {

if (error && !loading) {
// @TODO(Edit): Implement error screen
return `Error: ${error.toString()}`
return <>Error: {error.toString()}</>
}

if (loading) {
// @TODO(Edit): Implement loading screen
return 'Loading...'
return <>Loading...</>
}

const initialValues = computeInitialValues(customAttributesQuery.data)
Expand Down
66 changes: 66 additions & 0 deletions src/pages/dataElements/__mocks__/attributes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[
{
"valueType": "TEXT",
"mandatory": false,
"optionSet": {
"options": [
{
"code": "INPUT",
"name": "Input",
"displayName": "Input",
"id": "Fr4igNnPYTv"
},
{
"code": "ACTIVITY",
"name": "Activity",
"displayName": "Activity",
"id": "xuAA8BQjdZq"
},
{
"code": "OUTPUT",
"name": "Output",
"displayName": "Output",
"id": "tpJ71rNdmeo"
},
{
"code": "IMPACT",
"name": "Impact",
"displayName": "Impact",
"id": "QIbgv5M77In"
}
]
},
"displayFormName": "Classification",
"id": "Z4X3J7jMLYV"
},
{
"valueType": "LONG_TEXT",
"mandatory": false,
"displayFormName": "Collection method",
"id": "qXS2NDUEAOS"
},
{
"valueType": "TEXT",
"mandatory": false,
"displayFormName": "NGO ID",
"id": "n2xYlNbsfko"
},
{
"valueType": "TEXT",
"mandatory": false,
"displayFormName": "PEPFAR ID",
"id": "dLHLR5O4YFI"
},
{
"valueType": "TEXT",
"mandatory": false,
"displayFormName": "Rationale",
"id": "AhsCAtM3L0g"
},
{
"valueType": "TEXT",
"mandatory": false,
"displayFormName": "Unit of measure",
"id": "Y1LUDU8sWBR"
}
]
45 changes: 45 additions & 0 deletions src/pages/dataElements/__mocks__/categoryCombosPage1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"pager": {
"page": 1,
"total": 23,
"pageSize": 10,
"nextPage": "https://debug.dhis2.org/dev/api/41/categoryCombos?page=2&pageSize=10&fields=id%2CdisplayName%2CisDefault&order=isDefault%3Adesc%2CdisplayName",
"pageCount": 3
},
"categoryCombos": [
{ "displayName": "default", "id": "bjDvmb4bfuf", "isDefault": true },
{ "displayName": "Births", "id": "m2jTvAj5kkm", "isDefault": false },
{
"displayName": "Commodities",
"id": "gbvX3pogf7p",
"isDefault": false
},
{
"displayName": "Fixed/Outreach",
"id": "KYYSTxeVw28",
"isDefault": false
},
{ "displayName": "Gender", "id": "dPmavA0qloX", "isDefault": false },
{
"displayName": "HIV Paed age+gender",
"id": "v1K6CE6bmtw",
"isDefault": false
},
{ "displayName": "HIV age", "id": "Wfan7UwK8CQ", "isDefault": false },
{
"displayName": "HIV age+gender",
"id": "jCNGsC2NawV",
"isDefault": false
},
{
"displayName": "Implementing Partner",
"id": "nM3u9s5a52V",
"isDefault": false
},
{
"displayName": "Implementing Partner and Projects",
"id": "O4VaNks6tta",
"isDefault": false
}
]
}
6 changes: 4 additions & 2 deletions src/pages/dataElements/form/DataElementFormFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
CategoryComboField,
ColorAndIconField,
DomainField,
LegendSetField,
// LegendSetField,
OptionSetField,
OptionSetCommentField,
ValueTypeField,
Expand Down Expand Up @@ -62,13 +62,15 @@ export function DataElementFormFields() {
helpText={i18n.t(
'A data element name should be concise and easy to recognize.'
)}
validate={(value) => (!value ? 'Required' : undefined)}
/>
</StandardFormField>

<StandardFormField>
<FieldRFF
component={InputFieldFF}
required
validate={(value) => (!value ? 'Required' : undefined)}
inputWidth="400px"
name="shortName"
label={i18n.t('Short name (required)')}
Expand Down Expand Up @@ -194,7 +196,7 @@ export function DataElementFormFields() {
</StandardFormSectionDescription>

<StandardFormField>
<LegendSetField />
{/* <LegendSetField /> */ ''}
</StandardFormField>
</StandardFormSection>

Expand Down
Loading

0 comments on commit 1422199

Please sign in to comment.