Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/json schema form tests #453

Merged
merged 4 commits into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions cypress/integration/app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ describe("Basic e2e", function () {
cy.get("select[name='analysisType']").select("Reference Alignment")
cy.get("select[name='analysisType.referenceAlignment.assembly']").select("Standard")
cy.get("input[name='analysisType.referenceAlignment.assembly.accessionId']").type("Standard Accession Id")
cy.get("h4").contains("Sequence").parent().children("button").click()
cy.get("h4").contains("Sequence").parents().children("button").click()
cy.get("input[name='analysisType.referenceAlignment.sequence[0].accessionId']").type(
"Sequence Standard Accession Id"
)

// Experiment
cy.get("h2").contains("Experiment Reference").parent().children("button").click()
cy.get("h2").contains("Experiment Reference").parents().children("button").click()
cy.get("input[name='experimentRef[0].accessionId']").type("Experiment Test Accession Id")
cy.get("input[name='experimentRef[0].identifiers.submitterId.namespace']").type("Experiment Test Namespace")
cy.get("input[name='experimentRef[0].identifiers.submitterId.value']").type("Experiment Test Value")
Expand All @@ -89,31 +89,31 @@ describe("Basic e2e", function () {
cy.get("input[name='studyRef.identifiers.submitterId.value']").type("Study Test Value")

// Sample
cy.get("h2").contains("Sample Reference").parent().children("button").click()
cy.get("h2").contains("Sample Reference").parents().children("button").click()
cy.get("input[name='sampleRef[0].accessionId']").type("Sample Test Accession Id")
cy.get("input[name='sampleRef[0].identifiers.submitterId.namespace']").type("Sample Test Namespace")
cy.get("input[name='sampleRef[0].identifiers.submitterId.value']").type("Sample Test Value")

// Run
cy.get("h2").contains("Run Reference").parent().children("button").click()
cy.get("h2").contains("Run Reference").parents().children("button").click()
cy.get("input[name='runRef[0].accessionId']").type("Run Test Accession Id")
cy.get("input[name='runRef[0].identifiers.submitterId.namespace']").type("Run Test Namespace")
cy.get("input[name='runRef[0].identifiers.submitterId.value']").type("Run Test Value")

// Analysis
cy.get("h2").contains("Analysis Reference").parent().children("button").click()
cy.get("h2").contains("Analysis Reference").parents().children("button").click()
cy.get("input[name='analysisRef[0].accessionId']").type("Analysis Test Accession Id")
cy.get("input[name='analysisRef[0].identifiers.submitterId.namespace']").type("Analysis Test Namespace")
cy.get("input[name='analysisRef[0].identifiers.submitterId.value']").type("Analysis Test Value")

// Files
cy.get("h2").contains("Files").parent().children("button").click()
cy.get("h2").contains("Files").parents().children("button").click()
cy.get("input[name='files[0].filename']").type("filename 1")
cy.get("select[name='files[0].filetype']").select("other")
cy.get("select[name='files[0].checksumMethod']").select("MD5")
cy.get("input[name='files[0].checksum']").type("b1f4f9a523e36fd969f4573e25af4540")

cy.get("h2").contains("Files").parent().children("button").click()
cy.get("h2").contains("Files").parents().children("button").click()
cy.get("input[name='files[1].filename']").type("filename 2")
cy.get("select[name='files[1].filetype']").select("info")
cy.get("select[name='files[1].checksumMethod']").select("SHA-256")
Expand All @@ -136,7 +136,7 @@ describe("Basic e2e", function () {
.then($btn => $btn.click())
)

cy.get("h2").contains("Contacts").parent().children("button").click()
cy.get("h2").contains("Contacts").parents().children("button").click()
cy.get("[data-testid='contacts[0].name']").type("Test contact name")
cy.get("[data-testid='contacts[0].email']").type("email@test.com")
cy.get("[data-testid='contacts[0].telephoneNumber']").type(123456789)
Expand All @@ -154,8 +154,8 @@ describe("Basic e2e", function () {
cy.get("button[type=button]").contains("Next").click()

// Check the amount of submitted objects in each object type
cy.get("h6").contains("Study").parent("div").children().eq(1).should("have.text", 2)
cy.get("h6").contains("Analysis").parent("div").children().eq(1).should("have.text", 1)
cy.get("h6").contains("Study").parents("div").children().eq(1).should("have.text", 2)
cy.get("h6").contains("Analysis").parents("div").children().eq(1).should("have.text", 1)

// Navigate to publish
cy.get("button[type=button]").contains("Publish").click()
Expand Down
1 change: 1 addition & 0 deletions cypress/integration/draftTemplates.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe("draft selections and templates", function () {
cy.get("input[name='sampleName.taxonId']").type(123)
cy.get("button[type=button]").contains("Save as Draft").click()
cy.get("div[role=alert]", { timeout: 10000 }).contains("Draft saved with")
cy.get("ul[data-testid='Draft-objects']").find("li").should("have.length", 1)

// Navigate to summary
cy.get("button[type=button]").contains("Next").click()
Expand Down
4 changes: 2 additions & 2 deletions cypress/integration/editForm.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe("Populate form and render form elements by object data", function () {
cy.get("select[name='design.sampleDescriptor']").select(testData.sampleReference)
cy.get("input[data-testid='design.sampleDescriptor.label']").type(testData.individualSampleLabel)
// Expected Base Call Table
cy.get("div").contains("Expected Base Call Table").parent().children("button").click()
cy.get("div").contains("Expected Base Call Table").parents().children("button").click()
cy.get("input[name='design.spotDescriptor.readSpec.expectedBaseCallTable[0].baseCall']").type("Test base call")
cy.get("input[name='design.spotDescriptor.readSpec.expectedBaseCallTable[0].readGroupTag']").type(
"Test read group tag"
Expand All @@ -102,7 +102,7 @@ describe("Populate form and render form elements by object data", function () {

// Switch to select and fill Complex processing
cy.get("select[name='processing']").select(testData.complexProcessing)
cy.get("h2[data-testid='processing']").parent().children("button").click()
cy.get("h2[data-testid='processing']").parents().children("button").click()
cy.get(".MuiPaper-root > :nth-child(1) > .formSection > .array > .MuiButtonBase-root > .MuiButton-label").click()
cy.get("input[data-testid='processing[0].pipeline.pipeSection[0].stepIndex']").type(testData.stepIndex)
cy.get("select[name='processing[0].pipeline.pipeSection[0].prevStepIndex']", { force: true }).select(
Expand Down
16 changes: 8 additions & 8 deletions cypress/integration/linkingAccessionIds.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ describe("Linking Accession Ids", function () {
.then($btn => $btn.click())
)
cy.get("[data-testid='title']").type("Test Run title")
cy.get("h2[data-testid='experimentRef']").parent().children("button").click()
cy.get("h2[data-testid='experimentRef']").parents().children("button").click()
cy.get("[data-testid='experimentRef[0].label']").type("Test experiment label ref")
// Select experimentAccessionId
cy.get("select[name='experimentRef[0].accessionId']").then($el => {
Expand Down Expand Up @@ -155,23 +155,23 @@ describe("Linking Accession Ids", function () {
cy.get("select[name='studyRef.accessionId']").should("contain", " - Title:")

// Select experimentAccessionId
cy.get("div").contains("Experiment Reference").parent().children("button").click()
cy.get("div").contains("Experiment Reference").parents().children("button").click()
cy.get("select[name='experimentRef[0].accessionId']").then($el => {
const experimentAccessionId = cy.get("@experimentAccessionId")
$el.select(experimentAccessionId)
})
cy.get("select[name='experimentRef[0].accessionId']").should("contain", " - Title:")

// Select sampleAccessionId
cy.get("div").contains("Sample Reference").parent().children("button").click()
cy.get("div").contains("Sample Reference").parents().children("button").click()
cy.get("select[name='sampleRef[0].accessionId']").then($el => {
const sampleAccessionId = cy.get("@sampleAccessionId")
$el.select(sampleAccessionId)
})
cy.get("select[name='sampleRef[0].accessionId']").should("contain", " - Title:")

// Select runAccessionId
cy.get("div").contains("Run Reference").parent().children("button").click()
cy.get("div").contains("Run Reference").parents().children("button").click()
cy.get("select[name='runRef[0].accessionId']").then($el => {
const runAccessionId = cy.get("@runAccessionId")
$el.select(runAccessionId)
Expand All @@ -195,7 +195,7 @@ describe("Linking Accession Ids", function () {
cy.get("input[name='analysisType.referenceAlignment.assembly.accessionId']").type("Standard accessionId 2")

// Select the other Analysis AccessionId
cy.get("div").contains("Analysis Reference").parent().children("button").click()
cy.get("div").contains("Analysis Reference").parents().children("button").click()
cy.get("select[name='analysisRef[0].accessionId']").then($el => {
const analysisAccessionId = cy.get("@analysisAccessionId")
$el.select(analysisAccessionId)
Expand All @@ -219,7 +219,7 @@ describe("Linking Accession Ids", function () {
.then($btn => $btn.click())
)

cy.get("h2[data-testid='contacts']").parent().children("button").click()
cy.get("h2[data-testid='contacts']").parents().children("button").click()
cy.get("input[name='contacts[0].name']").type("Test contact name")
cy.get("input[name='contacts[0].email']").type("contact@hotmail.com")
cy.get("input[name='contacts[0].telephoneNumber']").type("Test phone number")
Expand Down Expand Up @@ -290,15 +290,15 @@ describe("Linking Accession Ids", function () {
cy.get("select[name='policyRef.accessionId']").should("contain", " - Title:")

// Select runAccessionId
cy.get("div").contains("Run Reference").parent().children("button").click()
cy.get("div").contains("Run Reference").parents().children("button").click()
cy.get("select[name='runRef[0].accessionId']").then($el => {
const runAccessionId = cy.get("@runAccessionId")
$el.select(runAccessionId)
})
cy.get("select[name='runRef[0].accessionId']").should("contain", " - Title:")

// Select analysisAccessionId
cy.get("div").contains("Analysis Reference").parent().children("button").click()
cy.get("div").contains("Analysis Reference").parents().children("button").click()
cy.get("select[name='analysisRef[0].accessionId']").then($el => {
const analysisAccessionId = cy.get("@analysisAccessionId")
$el.select(analysisAccessionId)
Expand Down
8 changes: 4 additions & 4 deletions cypress/integration/objectLinksAttributes.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe("render objects' links and attributes ", function () {
cy.get("select[name='descriptor.studyType']").select("Metagenomics")

// Add new Study Link
cy.get("div").contains("Study Links").parent().children("button").click()
cy.get("div").contains("Study Links").parents().children("button").click()

// Choose XRef Link
cy.get("select[name='studyLinks[0]']").select("XRef Link")
Expand All @@ -30,22 +30,22 @@ describe("render objects' links and attributes ", function () {
cy.get("input[name='studyLinks[0].label']").type("Test XRef Label")

// Add new URL Link
cy.get("div").contains("Study Links").parent().children("button").click()
cy.get("div").contains("Study Links").parents().children("button").click()
cy.get("select[name='studyLinks[1]']").select("URL Link")

cy.get("input[name='studyLinks[1].label']").type("Test URL Label")
cy.get("input[name='studyLinks[1].url']").type("https://testlink.com")

// Add new Entrez Link
cy.get("div").contains("Study Links").parent().children("button").click()
cy.get("div").contains("Study Links").parents().children("button").click()
cy.get("select[name='studyLinks[2]']").select("Entrez Link")

cy.get("select[name='studyLinks[2].entrezDb']").select("genome")
cy.get("input[name='studyLinks[2].entrezId']").type("Test Entrez Database ID")
cy.get("input[name='studyLinks[2].label']").type("Test Entrez Label")

// Choose Study Attributes
cy.get("div").contains("Study Attributes").parent().children("button").click()
cy.get("div").contains("Study Attributes").parents().children("button").click()

cy.get("input[name='studyAttributes[0].tag']").type("Test Attributes Tag")
cy.get("textarea[name='studyAttributes[0].value']").type("Test Attributes Value")
Expand Down
127 changes: 127 additions & 0 deletions src/__tests__/WizardJSONSchemaParser.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import React from "react"

import "@testing-library/jest-dom/extend-expect"
import { render, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { get } from "lodash"
import { useForm, FormProvider } from "react-hook-form"
import { Provider } from "react-redux"
import configureStore from "redux-mock-store"

import CustomSchema from "./fixtures/custom_schema.json"

import JSONSchemaParser from "components/NewDraftWizard/WizardForms/WizardJSONSchemaParser"
import { pathToName } from "utils/JSONSchemaUtils"

const mockStore = configureStore([])
const store = mockStore({})

const schema = CustomSchema

describe("Test form render by custom schema", () => {
beforeEach(() => {
const FormComponent = () => {
const methods = useForm()

return (
<Provider store={store}>
<FormProvider {...methods}>
<form id="hook-form">
<div>{JSONSchemaParser.buildFields(schema)}</div>
</form>
</FormProvider>
</Provider>
)
}

render(<FormComponent />)
})

const testLabels = source => {
const properties = source.properties

for (const key in properties) {
if (properties[key].title) {
// Required fields need to be queried with asterisk
if (source.required && source.required.find(reqProp => reqProp === key)) {
expect(screen.getByLabelText(properties[key].title + " *")).toBeDefined()
} else {
expect(screen.getByLabelText(properties[key].title)).toBeDefined()
}
}
}
}

it("should render form by schema", () => {
let headingCount = 1 // Initial header for schema title
let buttonCount = 0

const traverse = (object, path) => {
for (const prop in object.properties) {
const name = pathToName([...path, prop])
const source = object.properties[prop]

if (source.properties || source.items?.oneOf) {
// Eg. Study > Study Description
headingCount = ++headingCount
}

if (source.type === "array" && source.items?.oneOf) {
// Eg. Study > Study Links
buttonCount = ++buttonCount
}

if (source.enum) {
// Eg. Study > Study Links > Entrez Link > Database
expect(screen.getAllByTestId(`${name}-option`)).toHaveLength(
get(schema.properties, [path[0], "properties", prop, "enum"].join(".")).length
)
}

// Most fields are rendered with labels. Test that label exists in form
if (source.properties) testLabels(source)

// Loop through properties recursively
if (source.properties) traverse(source, [...path, prop])
}
}

traverse(schema, [])

expect(screen.getAllByRole("heading")).toHaveLength(headingCount)
expect(screen.getAllByRole("button", { name: "Add new item" })).toHaveLength(buttonCount)
})

it("should render fields when clicking 'Add new item' button", () => {
// Eg. Study > Study Links
const addNewItemButton = screen.getByRole("button", { name: "Add new item" })
userEvent.click(addNewItemButton)

const items = schema.properties.arrayFields.properties.oneOfArray.items
const select = screen.getByLabelText(items.title)
const selectedItem = items.oneOf[1]
userEvent.selectOptions(select, selectedItem.title)

testLabels(selectedItem)
})

it("should render option fields when selecting option", () => {
// Eg. Study > Study Links > Link Type
const options = schema.properties.oneOf.properties.oneOfField

const oneOfSelect = screen.getByLabelText(options.title)
expect(oneOfSelect).toBeDefined()

const source = options.oneOf[0]
userEvent.selectOptions(oneOfSelect, source.title)

// OneOf option fields are rendered as required
const properties = options.oneOf[0].properties

for (const key in properties) {
if (properties[key].title) {
expect(screen.getByLabelText(properties[key].title + " *")).toBeDefined()
}
}
})
})
Loading