#14 Add integration tests for answering questions
This commit is contained in:
parent
8afea80dd2
commit
a70dd7d6a5
|
@ -0,0 +1,84 @@
|
|||
import { MockedResponse } from "@apollo/client/testing";
|
||||
import {
|
||||
ADD_ANSWER,
|
||||
AddAnswerResponse,
|
||||
AddAnswerVariables,
|
||||
EDIT_ANSWER,
|
||||
EditAnswerPayload,
|
||||
EditAnswerResponse,
|
||||
EditAnswerVariables,
|
||||
} from "./answer";
|
||||
import { answersMock } from "../queries/answer.mock";
|
||||
import { CandidatePosition } from "../../components/CandidatePositionLegend";
|
||||
import { FullAnswerResponse } from "../queries/answer";
|
||||
|
||||
const editAnswerVariables: EditAnswerVariables = {
|
||||
id: "a22",
|
||||
text: "New answer",
|
||||
};
|
||||
|
||||
const getEditedAnswerMock = (): EditAnswerPayload | null => {
|
||||
const originalAnswer = answersMock.find(
|
||||
(a) => a.id === editAnswerVariables.id
|
||||
);
|
||||
return originalAnswer
|
||||
? {
|
||||
answer: {
|
||||
...originalAnswer,
|
||||
text:
|
||||
editAnswerVariables.text === undefined
|
||||
? originalAnswer.text
|
||||
: editAnswerVariables.text,
|
||||
position:
|
||||
editAnswerVariables.position === undefined
|
||||
? originalAnswer.position
|
||||
: editAnswerVariables.position,
|
||||
},
|
||||
__typename: "UpdateAnswerPayload",
|
||||
}
|
||||
: null;
|
||||
};
|
||||
|
||||
export const editAnswerMock: Array<MockedResponse<EditAnswerResponse>> = [
|
||||
{
|
||||
request: {
|
||||
query: EDIT_ANSWER,
|
||||
variables: editAnswerVariables,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
updateAnswer: getEditedAnswerMock(),
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const addAnswerVariables: AddAnswerVariables = {
|
||||
position: CandidatePosition.positive,
|
||||
questionRowId: 3,
|
||||
personRowId: 2,
|
||||
};
|
||||
|
||||
const addedAnswerMock: FullAnswerResponse = {
|
||||
id: "newA",
|
||||
...addAnswerVariables,
|
||||
text: addAnswerVariables.text !== undefined ? addAnswerVariables.text : null,
|
||||
__typename: "Answer",
|
||||
};
|
||||
|
||||
export const addAnswerMock: Array<MockedResponse<AddAnswerResponse>> = [
|
||||
{
|
||||
request: {
|
||||
query: ADD_ANSWER,
|
||||
variables: addAnswerVariables,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
createAnswer: {
|
||||
answer: addedAnswerMock,
|
||||
__typename: "CreateAnswerPayload",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
|
@ -105,7 +105,6 @@ const addAnswerToQuestion = (
|
|||
answersByQuestionRowId: (
|
||||
answerRefs: NodesCacheRefs = { nodes: [] }
|
||||
): NodesCacheRefs => {
|
||||
console.log(answerRefs);
|
||||
return { nodes: [...answerRefs.nodes, newAnswerRef] };
|
||||
},
|
||||
},
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
import { MockedResponse } from "@apollo/client/testing";
|
||||
import {
|
||||
AnswerPositionResponse,
|
||||
FullAnswerResponse,
|
||||
GET_ALL_QUESTION_ANSWERS,
|
||||
GET_ANSWER_BY_QUESTION_AND_PERSON,
|
||||
GetAllQuestionAnswersResponse,
|
||||
GetAllQuestionAnswersVariables,
|
||||
GetAnswerByQuestionAndPersonResponse,
|
||||
GetAnswerByQuestionAndPersonVariables,
|
||||
QuestionAnswerResponse,
|
||||
} from "./answer";
|
||||
import { CandidatePosition } from "../../components/CandidatePositionLegend";
|
||||
|
||||
export const answersMock: Array<FullAnswerResponse> = [
|
||||
{
|
||||
id: "a12",
|
||||
text: null,
|
||||
position: CandidatePosition.neutral,
|
||||
questionRowId: 1,
|
||||
personRowId: 2,
|
||||
__typename: "Answer",
|
||||
},
|
||||
{
|
||||
id: "a22",
|
||||
text: "Answer 2",
|
||||
position: CandidatePosition.positive,
|
||||
questionRowId: 2,
|
||||
personRowId: 2,
|
||||
__typename: "Answer",
|
||||
},
|
||||
];
|
||||
|
||||
const getAnswersForQuestionRowId = (
|
||||
questionRowId: number
|
||||
): Array<FullAnswerResponse> => {
|
||||
return answersMock.filter((answ) => answ.questionRowId === questionRowId);
|
||||
};
|
||||
|
||||
const getAnswersPositionForQuestionRowId = (
|
||||
questionRowId: number
|
||||
): Array<AnswerPositionResponse> => {
|
||||
return getAnswersForQuestionRowId(questionRowId).map((answer) => ({
|
||||
__typename: answer.__typename,
|
||||
id: answer.id,
|
||||
position: answer.position,
|
||||
}));
|
||||
};
|
||||
|
||||
export const questionAnswersMock: Array<QuestionAnswerResponse> = [
|
||||
{
|
||||
id: "q1",
|
||||
rowId: 1,
|
||||
title: "Question 1?",
|
||||
description: "Further information for Q1",
|
||||
categoryByCategoryRowId: {
|
||||
id: "c1",
|
||||
rowId: 1,
|
||||
title: "Category 1",
|
||||
__typename: "Category",
|
||||
},
|
||||
answersByQuestionRowId: {
|
||||
nodes: getAnswersPositionForQuestionRowId(1),
|
||||
__typename: "AnswersConnection",
|
||||
},
|
||||
__typename: "Question",
|
||||
},
|
||||
{
|
||||
id: "q2",
|
||||
rowId: 2,
|
||||
title: "Question 2?",
|
||||
description: "Further information for Q2",
|
||||
categoryByCategoryRowId: null,
|
||||
answersByQuestionRowId: {
|
||||
nodes: getAnswersPositionForQuestionRowId(2),
|
||||
__typename: "AnswersConnection",
|
||||
},
|
||||
__typename: "Question",
|
||||
},
|
||||
{
|
||||
id: "q3",
|
||||
rowId: 3,
|
||||
title: "Question 3?",
|
||||
description: null,
|
||||
categoryByCategoryRowId: null,
|
||||
answersByQuestionRowId: {
|
||||
nodes: getAnswersPositionForQuestionRowId(3),
|
||||
__typename: "AnswersConnection",
|
||||
},
|
||||
__typename: "Question",
|
||||
},
|
||||
];
|
||||
|
||||
export const getAllQuestionAnswersMock: Array<
|
||||
MockedResponse<GetAllQuestionAnswersResponse>
|
||||
> = [
|
||||
{
|
||||
request: {
|
||||
query: GET_ALL_QUESTION_ANSWERS,
|
||||
variables: {
|
||||
personRowId: 2,
|
||||
} as GetAllQuestionAnswersVariables,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
allQuestions: {
|
||||
nodes: questionAnswersMock,
|
||||
__typename: "QuestionsConnection",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const getAnswerByQuestionAndPersonMock: Array<
|
||||
MockedResponse<GetAnswerByQuestionAndPersonResponse>
|
||||
> = [
|
||||
...questionAnswersMock.map((q, index) => ({
|
||||
request: {
|
||||
query: GET_ANSWER_BY_QUESTION_AND_PERSON,
|
||||
variables: {
|
||||
personRowId: 2,
|
||||
questionRowId: index + 1,
|
||||
} as GetAnswerByQuestionAndPersonVariables,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
answerByQuestionRowIdAndPersonRowId:
|
||||
getAnswersForQuestionRowId(index + 1)[0] || null,
|
||||
},
|
||||
},
|
||||
})),
|
||||
];
|
|
@ -150,7 +150,7 @@ export default function EditAnswerSection(
|
|||
loading={loading}
|
||||
/>
|
||||
<EditAnswerText
|
||||
remoteText={remoteAnswer?.text || ""}
|
||||
remoteText={remoteAnswer?.text}
|
||||
onSaveClick={handleSaveText}
|
||||
loading={loading}
|
||||
/>
|
||||
|
|
|
@ -25,7 +25,7 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||
);
|
||||
|
||||
interface EditAnswerTextSectionProps {
|
||||
remoteText: string;
|
||||
remoteText: string | null | undefined;
|
||||
loading?: boolean;
|
||||
|
||||
onSaveClick(text: string): void;
|
||||
|
@ -35,7 +35,8 @@ export default function EditAnswerText(
|
|||
props: EditAnswerTextSectionProps
|
||||
): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const [answerText, setAnswerText] = useState<string>(props.remoteText);
|
||||
const initialAnswer = props.remoteText || "Antwort hinzufügen...";
|
||||
const [answerText, setAnswerText] = useState<string>(initialAnswer);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
|
@ -56,7 +57,7 @@ export default function EditAnswerText(
|
|||
<ButtonWithSpinner
|
||||
color="default"
|
||||
className={classes.button}
|
||||
onClick={() => setAnswerText(props.remoteText)}
|
||||
onClick={() => setAnswerText(initialAnswer)}
|
||||
loading={props.loading}
|
||||
>
|
||||
Zurücksetzen
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
import { Container, Paper, Typography } from "@material-ui/core";
|
||||
import { Container } from "@material-ui/core";
|
||||
import React from "react";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { useQuery } from "@apollo/client";
|
||||
import {
|
||||
GET_ALL_QUESTION_ANSWERS,
|
||||
GetAllQuestionAnswersResponse,
|
||||
GetAllQuestionAnswersVariables,
|
||||
} from "../backend/queries/answer";
|
||||
import { getJsonWebToken } from "../jwt/jwt";
|
||||
import AccordionQuestionAnswer from "./AccordionQuestionAnswer";
|
||||
import { CandidatePositionLegend } from "./CandidatePositionLegend";
|
||||
import QuestionAnswersList from "./QuestionAnswerList";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
container: {
|
||||
|
@ -17,12 +9,6 @@ const useStyles = makeStyles((theme) => ({
|
|||
paddingBottom: theme.spacing(4),
|
||||
flexDirection: "column",
|
||||
},
|
||||
root: {
|
||||
width: "100%",
|
||||
padding: theme.spacing(1),
|
||||
marginBottom: theme.spacing(3),
|
||||
backgroundColor: theme.palette.background.default,
|
||||
},
|
||||
}));
|
||||
|
||||
interface MainPageCandidateProps {
|
||||
|
@ -32,32 +18,10 @@ interface MainPageCandidateProps {
|
|||
export function MainPageCandidate(
|
||||
props: MainPageCandidateProps
|
||||
): React.ReactElement {
|
||||
const personRowId = getJsonWebToken()?.person_row_id;
|
||||
const questionAnswers = useQuery<
|
||||
GetAllQuestionAnswersResponse,
|
||||
GetAllQuestionAnswersVariables
|
||||
>(GET_ALL_QUESTION_ANSWERS, {
|
||||
variables: {
|
||||
personRowId,
|
||||
},
|
||||
}).data?.allQuestions.nodes;
|
||||
const classes = useStyles();
|
||||
|
||||
return (
|
||||
<Container maxWidth="lg" className={classes.container}>
|
||||
<Paper className={classes.root}>
|
||||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>
|
||||
Fragen
|
||||
</Typography>
|
||||
<CandidatePositionLegend />
|
||||
{questionAnswers?.map((question) => (
|
||||
<AccordionQuestionAnswer
|
||||
key={question.rowId}
|
||||
personRowId={props.personRowId}
|
||||
question={question}
|
||||
/>
|
||||
))}
|
||||
</Paper>
|
||||
<QuestionAnswersList personRowId={props.personRowId} />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import React from "react";
|
||||
import { useQuery } from "@apollo/client";
|
||||
import {
|
||||
GET_ALL_QUESTION_ANSWERS,
|
||||
GetAllQuestionAnswersResponse,
|
||||
GetAllQuestionAnswersVariables,
|
||||
} from "../backend/queries/answer";
|
||||
import { Paper, Typography } from "@material-ui/core";
|
||||
import { CandidatePositionLegend } from "./CandidatePositionLegend";
|
||||
import AccordionQuestionAnswer from "./AccordionQuestionAnswer";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
width: "100%",
|
||||
padding: theme.spacing(1),
|
||||
marginBottom: theme.spacing(3),
|
||||
backgroundColor: theme.palette.background.default,
|
||||
},
|
||||
}));
|
||||
|
||||
interface QuestionAnswerListProps {
|
||||
personRowId: number;
|
||||
}
|
||||
|
||||
export default function QuestionAnswersList(
|
||||
props: QuestionAnswerListProps
|
||||
): React.ReactElement {
|
||||
const classes = useStyles();
|
||||
const questionAnswers = useQuery<
|
||||
GetAllQuestionAnswersResponse,
|
||||
GetAllQuestionAnswersVariables
|
||||
>(GET_ALL_QUESTION_ANSWERS, {
|
||||
variables: {
|
||||
personRowId: props.personRowId,
|
||||
},
|
||||
}).data?.allQuestions.nodes;
|
||||
|
||||
return (
|
||||
<Paper className={classes.root}>
|
||||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>
|
||||
Fragen
|
||||
</Typography>
|
||||
<CandidatePositionLegend />
|
||||
{questionAnswers?.map((question) => (
|
||||
<AccordionQuestionAnswer
|
||||
key={question.rowId}
|
||||
personRowId={props.personRowId}
|
||||
question={question}
|
||||
/>
|
||||
))}
|
||||
</Paper>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
import React from "react";
|
||||
import {
|
||||
findByRole,
|
||||
findByText,
|
||||
fireEvent,
|
||||
render,
|
||||
screen,
|
||||
waitFor,
|
||||
} from "@testing-library/react";
|
||||
import { MockedProvider, MockedResponse } from "@apollo/client/testing";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import { SnackbarProvider } from "notistack";
|
||||
import {
|
||||
getAllQuestionAnswersMock,
|
||||
getAnswerByQuestionAndPersonMock,
|
||||
questionAnswersMock,
|
||||
} from "../backend/queries/answer.mock";
|
||||
import {
|
||||
addAnswerMock,
|
||||
editAnswerMock,
|
||||
} from "../backend/mutations/answer.mock";
|
||||
import {
|
||||
getNegativePositionPath,
|
||||
getNeutralPositionPath,
|
||||
getPositivePositionPath,
|
||||
getSkippedPositionPath,
|
||||
queryAllIconButtons,
|
||||
} from "./test-helper";
|
||||
import QuestionAnswersList from "../components/QuestionAnswerList";
|
||||
|
||||
describe("The AnswerList", () => {
|
||||
test("displays the existing answers, but not the details of it", async () => {
|
||||
renderQuestionAnswerList();
|
||||
|
||||
const questionAnswerCards = await waitForQuestionsToRender();
|
||||
questionAnswerCards.forEach((card) => {
|
||||
expect(card.innerHTML).toMatch(/Question [1-3]/);
|
||||
});
|
||||
const saveButtons = screen.queryAllByRole("button", { name: /speichern/i });
|
||||
expect(saveButtons).toHaveLength(0);
|
||||
expect(questionAnswerCards[0].innerHTML).toContain(
|
||||
getNeutralPositionPath()
|
||||
);
|
||||
expect(questionAnswerCards[1].innerHTML).toContain(
|
||||
getPositivePositionPath()
|
||||
);
|
||||
expect(questionAnswerCards[2].innerHTML).toContain(
|
||||
getSkippedPositionPath()
|
||||
);
|
||||
});
|
||||
|
||||
test("enables resetting an answer to the last saved state", async () => {
|
||||
renderQuestionAnswerList(editAnswerMock);
|
||||
|
||||
const questionAnswerCards = await waitForQuestionsToRender();
|
||||
let answerSection = await expandAccordionAndGetAnswerSection(
|
||||
questionAnswerCards[1]
|
||||
);
|
||||
expect(answerSection).toBeDefined();
|
||||
answerSection = answerSection as AccordionAnswerSection;
|
||||
|
||||
const { textField, resetButton } = answerSection;
|
||||
|
||||
expect(textField.outerHTML).toContain("Answer 2");
|
||||
// change answer title
|
||||
fireEvent.change(textField, {
|
||||
target: { value: "New answer" },
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(textField.outerHTML).toContain("New answer");
|
||||
});
|
||||
|
||||
// reset and verify
|
||||
fireEvent.click(resetButton);
|
||||
await waitFor(() => {
|
||||
expect(textField.outerHTML).toContain("Answer 2");
|
||||
});
|
||||
});
|
||||
|
||||
test("enables editing an answer", async () => {
|
||||
renderQuestionAnswerList(editAnswerMock);
|
||||
|
||||
const questionAnswerCards = await waitForQuestionsToRender();
|
||||
let answerSection = await expandAccordionAndGetAnswerSection(
|
||||
questionAnswerCards[1]
|
||||
);
|
||||
expect(answerSection).toBeDefined();
|
||||
answerSection = answerSection as AccordionAnswerSection;
|
||||
|
||||
const { textField, saveButton, resetButton } = answerSection;
|
||||
expect(textField.outerHTML).toContain("Answer 2");
|
||||
// change answer title
|
||||
fireEvent.change(textField, {
|
||||
target: { value: "New answer" },
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(textField.outerHTML).toContain("New answer");
|
||||
});
|
||||
|
||||
// call backend and assert apollo cache update (i.e a subsequent reset should reset to the new answer)
|
||||
fireEvent.click(saveButton);
|
||||
fireEvent.change(textField, {
|
||||
target: { value: "something else" },
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(textField.outerHTML).toContain("something else");
|
||||
});
|
||||
fireEvent.click(resetButton);
|
||||
await waitFor(() => {
|
||||
expect(textField.outerHTML).toContain("New answer");
|
||||
});
|
||||
});
|
||||
|
||||
test("enables adding an answer via setting the position", async () => {
|
||||
renderQuestionAnswerList(addAnswerMock);
|
||||
|
||||
const questionAnswerCards = await waitForQuestionsToRender();
|
||||
const questionWithoutAnswerCard = questionAnswerCards[2];
|
||||
let answerSection = await expandAccordionAndGetAnswerSection(
|
||||
questionWithoutAnswerCard
|
||||
);
|
||||
expect(answerSection).toBeDefined();
|
||||
answerSection = answerSection as AccordionAnswerSection;
|
||||
|
||||
const { positionIconButtons } = answerSection;
|
||||
expect(positionIconButtons.skipped.outerHTML).toContain(
|
||||
'aria-pressed="true"'
|
||||
);
|
||||
expect(positionIconButtons.positive.outerHTML).toContain(
|
||||
'aria-pressed="false"'
|
||||
);
|
||||
|
||||
// press "positive" icon button and wait for accordion header to change -> apollo cache update successful
|
||||
fireEvent.click(positionIconButtons.positive);
|
||||
await waitFor(() => {
|
||||
expect(questionAnswerCards[2].innerHTML).toContain(
|
||||
getPositivePositionPath()
|
||||
);
|
||||
});
|
||||
expect(positionIconButtons.skipped.outerHTML).toContain(
|
||||
'aria-pressed="false"'
|
||||
);
|
||||
expect(positionIconButtons.positive.outerHTML).toContain(
|
||||
'aria-pressed="true"'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function renderQuestionAnswerList(additionalMocks?: Array<MockedResponse>) {
|
||||
const initialMocks = [
|
||||
...getAllQuestionAnswersMock,
|
||||
...getAnswerByQuestionAndPersonMock,
|
||||
];
|
||||
const allMocks = additionalMocks
|
||||
? [...initialMocks, ...additionalMocks]
|
||||
: initialMocks;
|
||||
return render(
|
||||
<MockedProvider mocks={allMocks}>
|
||||
<MemoryRouter>
|
||||
<SnackbarProvider>
|
||||
<QuestionAnswersList personRowId={2} />
|
||||
</SnackbarProvider>
|
||||
</MemoryRouter>
|
||||
</MockedProvider>
|
||||
);
|
||||
}
|
||||
|
||||
const waitForQuestionsToRender = async (): Promise<Array<HTMLElement>> => {
|
||||
const numberOfAnswersInMockQuery = questionAnswersMock.length;
|
||||
let questionAnswerCards: Array<HTMLElement> = [];
|
||||
await waitFor(() => {
|
||||
questionAnswerCards = screen.queryAllByRole("button", {
|
||||
name: /Question [1-3]/,
|
||||
});
|
||||
expect(questionAnswerCards.length).toEqual(numberOfAnswersInMockQuery);
|
||||
});
|
||||
return questionAnswerCards;
|
||||
};
|
||||
|
||||
const getSaveAnswerButton = (parent: HTMLElement) => {
|
||||
return findByRole(parent, "button", { name: /speichern/i });
|
||||
};
|
||||
|
||||
const getResetAnswerButton = (parent: HTMLElement) => {
|
||||
return findByRole(parent, "button", { name: /zurücksetzen/i });
|
||||
};
|
||||
|
||||
interface PositionIconButtons {
|
||||
positive: HTMLElement;
|
||||
neutral: HTMLElement;
|
||||
negative: HTMLElement;
|
||||
skipped: HTMLElement;
|
||||
}
|
||||
|
||||
const getCandidatePositionButtons = async (
|
||||
parent: HTMLElement
|
||||
): Promise<PositionIconButtons> => {
|
||||
const labelAboveButtons = await findByText(parent, /Deine Position/i);
|
||||
const parentElement = labelAboveButtons.parentElement as HTMLElement;
|
||||
const positive = queryAllIconButtons(
|
||||
getPositivePositionPath(),
|
||||
parentElement
|
||||
)[0];
|
||||
const neutral = queryAllIconButtons(
|
||||
getNeutralPositionPath(),
|
||||
parentElement
|
||||
)[0];
|
||||
const negative = queryAllIconButtons(
|
||||
getNegativePositionPath(),
|
||||
parentElement
|
||||
)[0];
|
||||
const skipped = queryAllIconButtons(
|
||||
getSkippedPositionPath(),
|
||||
parentElement
|
||||
)[0];
|
||||
expect(positive).toBeDefined();
|
||||
expect(neutral).toBeDefined();
|
||||
expect(negative).toBeDefined();
|
||||
expect(skipped).toBeDefined();
|
||||
return {
|
||||
positive,
|
||||
neutral,
|
||||
negative,
|
||||
skipped,
|
||||
};
|
||||
};
|
||||
|
||||
interface AccordionAnswerSection {
|
||||
positionIconButtons: PositionIconButtons;
|
||||
textField: HTMLElement;
|
||||
saveButton: HTMLElement;
|
||||
resetButton: HTMLElement;
|
||||
}
|
||||
|
||||
const expandAccordionAndGetAnswerSection = async (
|
||||
accordionExpandArea: HTMLElement
|
||||
): Promise<AccordionAnswerSection | undefined> => {
|
||||
fireEvent.click(accordionExpandArea);
|
||||
let fullAccordion = accordionExpandArea.parentElement;
|
||||
expect(fullAccordion).not.toBeNull();
|
||||
fullAccordion = fullAccordion as HTMLElement;
|
||||
const textField = await findByRole(fullAccordion, "textbox");
|
||||
const saveButton = await getSaveAnswerButton(fullAccordion);
|
||||
const resetButton = await getResetAnswerButton(fullAccordion);
|
||||
const positionIconButtons = await getCandidatePositionButtons(fullAccordion);
|
||||
return {
|
||||
positionIconButtons,
|
||||
textField,
|
||||
saveButton,
|
||||
resetButton,
|
||||
};
|
||||
};
|
|
@ -9,6 +9,10 @@ import {
|
|||
import EditIcon from "@material-ui/icons/Edit";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import AddIcon from "@material-ui/icons/Add";
|
||||
import {
|
||||
CandidatePosition,
|
||||
getIconForPosition,
|
||||
} from "../components/CandidatePositionLegend";
|
||||
|
||||
const memoizedGetIconPath = (icon: JSX.Element) => {
|
||||
const cache: { path?: string } = {};
|
||||
|
@ -30,6 +34,31 @@ const memoizedGetIconPath = (icon: JSX.Element) => {
|
|||
const getEditIconPath = memoizedGetIconPath(<EditIcon />);
|
||||
const getDeleteIconPath = memoizedGetIconPath(<DeleteIcon />);
|
||||
const getAddIconPath = memoizedGetIconPath(<AddIcon />);
|
||||
export const getPositivePositionPath = memoizedGetIconPath(
|
||||
getIconForPosition(CandidatePosition.positive)
|
||||
);
|
||||
export const getNeutralPositionPath = memoizedGetIconPath(
|
||||
getIconForPosition(CandidatePosition.neutral)
|
||||
);
|
||||
export const getNegativePositionPath = memoizedGetIconPath(
|
||||
getIconForPosition(CandidatePosition.negative)
|
||||
);
|
||||
export const getSkippedPositionPath = memoizedGetIconPath(
|
||||
getIconForPosition(CandidatePosition.skipped)
|
||||
);
|
||||
|
||||
export const queryAllIconButtons = (
|
||||
iconPath: string,
|
||||
container?: HTMLElement
|
||||
): HTMLElement[] => {
|
||||
return (container
|
||||
? queryAllByRole(container, "button")
|
||||
: screen.queryAllByRole("button")
|
||||
).filter(
|
||||
(button) =>
|
||||
button.innerHTML.includes("svg") && button.innerHTML.includes(iconPath)
|
||||
);
|
||||
};
|
||||
|
||||
// sorry, I found no better way to find a specific icon button...
|
||||
export const queryAllEditIconButtons = (
|
||||
|
|
Loading…
Reference in New Issue