Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/MarkUsProject/Markus into…
Browse files Browse the repository at this point in the history
… update-contributors
  • Loading branch information
hemmatio committed Jan 12, 2025
2 parents a9fb1c2 + 7081a51 commit c4b8e4e
Show file tree
Hide file tree
Showing 31 changed files with 829 additions and 3,167 deletions.
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
- Pin `mistune` Python dependency to preserve compatibility with `nbconvert` (#7371)
- Cache playwright's chromium installation on GitHub Actions (#7372)
- Fix broken link to the Vagrant installation guide in `README.md` (#7349)
- Fix `extra_hosts` configuration in `compose.yaml` (#7375)
- Convert front-end tests from enzyme to react testing library; add `@testing-library/user-event` (#7379)

## [v2.6.1]

Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/Grader/marking.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
// designate $next_criteria as the currently selected criteria
function activeCriterion($next_criteria) {
if (!$next_criteria.hasClass("active-criterion")) {
$criteria_list = $(".marks-list > li");
const $criteria_list = $(".marks-list > li");
// remove all previous active-criterion (there should only be one)
$criteria_list.removeClass("active-criterion");
// scroll the $next_criteria to the top of the criterion bar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class GraderDistributionModal extends React.Component {
</label>
<input
className={`input-${grader.user_name}`}
id={`input-${grader.user_name}`}
type="number"
step="0.01"
min="0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class SubmissionFileUploadModal extends React.Component {
);
} else if (this.props.requiredFiles.length >= 1) {
fileRenameInput = [
<datalist id="fileInput_datalist">
<datalist id="fileInput_datalist" key={`datalist-${filesToShow}`}>
{filesToShow.map(filename => {
return <option key={filename} value={filename}></option>;
})}
Expand All @@ -103,6 +103,7 @@ class SubmissionFileUploadModal extends React.Component {
disabled={this.state.newFiles.length !== 1}
title={I18n.t("submissions.student.one_file_allowed")}
id={"rename-box"}
key={"datalist-textbox"}
/>,
];
} else {
Expand Down Expand Up @@ -155,6 +156,7 @@ class SubmissionFileUploadModal extends React.Component {
name={"new_files"}
multiple={true}
onChange={this.handleFileUpload}
title={I18n.t("modals.file_upload.file_input_label")}
/>
</div>
<label htmlFor={"rename-box"}>
Expand Down
1 change: 1 addition & 0 deletions app/javascript/Components/Result/marks_panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ export class FlexibleCriterionInput extends React.Component {
a.id
)
}
href="#"
className={"red-text"}
>
{"-" + a.deduction}
Expand Down
16 changes: 2 additions & 14 deletions app/javascript/Components/Result/submission_selector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,19 +178,6 @@ export class SubmissionSelector extends React.Component {
return "";
}

const url = Routes.next_grouping_course_result_path(this.props.course_id, this.props.result_id);

const progressBarWidth =
this.props.num_collected > 0 ? this.props.num_marked / this.props.num_collected : 1;
let progressBarColour;
if (progressBarWidth > 0.75) {
progressBarColour = "green";
} else if (progressBarWidth > 0.35) {
progressBarColour = "#FBC02D";
} else {
progressBarColour = "#FE2A2A";
}

let meterLow = 0;
let meterHigh = 1;
if (this.props.num_collected !== null && this.props.num_collected !== undefined) {
Expand All @@ -199,7 +186,7 @@ export class SubmissionSelector extends React.Component {
}

return (
<div className="submission-selector-container">
<div className="submission-selector-container" data-testid="submission-selector-container">
<div className="submission-selector">
<button
className="button previous"
Expand All @@ -226,6 +213,7 @@ export class SubmissionSelector extends React.Component {
low={meterLow}
high={meterHigh}
optimum={this.props.num_collected}
data-testid="progress-bar"
>
{this.props.num_marked}/{this.props.num_collected}
</meter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import {AssignmentSummaryTable} from "../assignment_summary_table";
import {render, screen, fireEvent, cleanup, waitFor} from "@testing-library/react";
import {render, screen, fireEvent} from "@testing-library/react";

describe("For the AssignmentSummaryTable's display of inactive groups", () => {
let groups_sample;
Expand Down
3 changes: 1 addition & 2 deletions app/javascript/Components/__tests__/binary_viewer.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import {render, screen, cleanup, waitFor, fireEvent} from "@testing-library/react";
import {render, screen, waitFor, fireEvent} from "@testing-library/react";
import {BinaryViewer} from "../Result/binary_viewer";
import fetchMock from "jest-fetch-mock";

Expand All @@ -19,7 +19,6 @@ describe("BinaryViewer", () => {
afterEach(() => {
jest.clearAllMocks();
fetchMock.resetMocks();
cleanup();
});

it("should fetch content when a URL is passed but not show it until requested by the user", async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import {render, screen, fireEvent, waitFor, cleanup} from "@testing-library/react";
import {render, screen, fireEvent, waitFor} from "@testing-library/react";
import CreateTagModal from "../Modals/create_tag_modal";
import Modal from "react-modal";
import fetchMock from "jest-fetch-mock";
Expand Down Expand Up @@ -37,7 +37,6 @@ describe("CreateTagModal", () => {

afterEach(() => {
fetchMock.resetMocks();
cleanup();
});

it("should be called with correct params on successful submit", async () => {
Expand Down
3 changes: 1 addition & 2 deletions app/javascript/Components/__tests__/edit_tag_modal.test.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import {render, screen, fireEvent, waitFor, cleanup} from "@testing-library/react";
import {render, screen, fireEvent, waitFor} from "@testing-library/react";
import EditTagModal from "../Modals/edit_tag_modal";
import Modal from "react-modal";
import fetchMock from "jest-fetch-mock";
Expand Down Expand Up @@ -34,7 +34,6 @@ describe("EditTagModal", () => {

afterEach(() => {
fetchMock.resetMocks();
cleanup();
});

it("should be called with correct params on successful submit", async () => {
Expand Down
3 changes: 1 addition & 2 deletions app/javascript/Components/__tests__/file_viewer.test.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React from "react";
import {render, screen, cleanup} from "@testing-library/react";
import {render, screen} from "@testing-library/react";
import {FileViewer} from "../Result/file_viewer";
import fetchMock from "jest-fetch-mock";

describe("FileViewer", () => {
afterEach(() => {
fetchMock.resetMocks();
cleanup();
});

it("should not render oversized files", async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {shallow} from "enzyme";
import {render, screen} from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import {GraderDistributionModal} from "../Modals/graders_distribution_modal";

Expand All @@ -10,12 +11,7 @@ const createExampleForm = () => {
};

describe("GraderDistributionModal", () => {
let wrapper, props;
const getWrapper = props => {
return shallow(<GraderDistributionModal {...props} />);
};
const fakeEvent = {preventDefault: jest.fn()};
let mockRef;
let props;
const form1 = createExampleForm();
beforeEach(() => {
props = {
Expand All @@ -31,24 +27,32 @@ describe("GraderDistributionModal", () => {
});

it("should display as many rows as there are graders", () => {
wrapper = getWrapper(props);

expect(wrapper.find(".modal-inline-label").length).toBe(2);
render(<GraderDistributionModal {...props} />);
for (let grader of props.graders) {
expect(screen.getByRole("spinbutton", {name: grader.user_name, hidden: true})).toBeTruthy();
}
});

it("should close on submit", () => {
wrapper = getWrapper(props);

wrapper.find("form").simulate("submit", fakeEvent);
it("should close on submit", async () => {
render(<GraderDistributionModal {...props} />);
let submit = screen.getByRole("button", {
name: I18n.t("graders.actions.randomly_assign_graders"),
hidden: true,
});
await userEvent.click(submit);

expect(props.onSubmit).toHaveBeenCalled();
expect(props.isOpen).toBeFalsy();
});

it("should call setWeighting with value of 1 on build", () => {
wrapper = getWrapper(props);
it("should call setWeighting with value of 1 on build", async () => {
render(<GraderDistributionModal {...props} />);
let submit = screen.getByRole("button", {
name: I18n.t("graders.actions.randomly_assign_graders"),
hidden: true,
});
await userEvent.click(submit);

wrapper.find("form").simulate("submit", fakeEvent);
expect(props.onSubmit).toHaveBeenCalledWith({
1: "1",
2: "1",
Expand Down
34 changes: 20 additions & 14 deletions app/javascript/Components/__tests__/instructor_table.test.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {mount} from "enzyme";
import {render, screen} from "@testing-library/react";

import {InstructorTable} from "../instructor_table";

Expand All @@ -14,18 +14,24 @@ global.fetch = jest.fn(() =>
);

describe("For the InstructorTable's display of instructors", () => {
let wrapper, instructors_sample;
let instructors_sample;

describe("when some instructors are fetched", () => {
const instructors_in_one_row = (wrapper, instructor) => {
// Find the row
const row = wrapper.find({children: instructor.user_name}).parent();
// Expect the row to contain these information
expect(row.children({children: instructor.first_name})).toBeTruthy();
expect(row.children({children: instructor.last_name})).toBeTruthy();
if (instructor.email) {
expect(row.children({children: instructor.email})).toBeTruthy();
const instructors_in_one_row = instructor => {
const rows = screen.getAllByRole("row");
for (let row of rows) {
const cells = Array.from(row.childNodes).map(c => c.textContent);
if (cells[0] === instructor.user_name) {
expect(cells[1]).toEqual(instructor.first_name);
expect(cells[2]).toEqual(instructor.last_name);
if (instructor.email) {
expect(cells[3]).toEqual(instructor.email);
}
return;
}
}
// If the loop ends without finding the instructor, raise an error
throw `Could not find row for ${instructor.user_name}`;
};

beforeAll(() => {
Expand Down Expand Up @@ -56,11 +62,11 @@ describe("For the InstructorTable's display of instructors", () => {
counts: {all: 2, active: 1, inactive: 1},
}),
});
wrapper = mount(<InstructorTable course_id={1} />);
render(<InstructorTable course_id={1} />);
});

it("each instructor is displayed as a row of the table", () => {
instructors_sample.forEach(instructor => instructors_in_one_row(wrapper, instructor));
instructors_sample.forEach(instructor => instructors_in_one_row(instructor));
});
});

Expand All @@ -76,11 +82,11 @@ describe("For the InstructorTable's display of instructors", () => {
counts: {all: 0, active: 0, inactive: 0},
}),
});
wrapper = mount(<InstructorTable course_id={1} />);
render(<InstructorTable course_id={1} />);
});

it("No rows found is shown", () => {
expect(wrapper.find({children: "No rows found"})).toBeTruthy();
expect(screen.queryByText("No rows found")).toBeTruthy();
});
});
});
53 changes: 19 additions & 34 deletions app/javascript/Components/__tests__/markdown_editor.test.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {shallow} from "enzyme";
import {render, screen} from "@testing-library/react";
import userEvent from "@testing-library/user-event";

import MarkdownEditor from "../markdown_editor";

const basicProps = {
Expand All @@ -12,54 +14,37 @@ const basicProps = {
};

describe("MarkdownEditor", () => {
let props, wrapper;
const getWrapper = () => {
return shallow(<MarkdownEditor {...props} />);
};
let props;
beforeEach(() => {
props = {...basicProps};
});

it("should properly handle the text input change", () => {
wrapper = getWrapper(props);

const inputBox = wrapper.find("#new_annotation_content");

expect(inputBox.exists()).toBeTruthy();

const event = {
target: {
value: "Hello world",
},
};
it("should properly handle the text input change", async () => {
render(<MarkdownEditor {...props} />);

inputBox.simulate("change", event);
const inputBox = screen.getByRole("textbox");
await userEvent.type(inputBox, "Hello world");

expect(props.handleChange).toHaveBeenCalledWith(event);
expect(props.handleChange).toHaveBeenCalled();
});

it("should show autocomplete if desired", () => {
it("should show autocomplete if desired", async () => {
props.show_autocomplete = true;
props.annotation_text_id = "id";
wrapper = getWrapper(props);
render(<MarkdownEditor {...props} />);

const annotationList = wrapper.find("#annotation_text_list");

expect(annotationList.exists()).toBeTruthy();
const autocompleteList = screen.queryByTestId("markdown-editor-autocomplete-root");
expect(autocompleteList).toBeTruthy();
});

it("should properly display and pass down props to the preview tab", () => {
it("should properly display and pass down props to the preview tab", async () => {
props.content = "arma virumque cano";
wrapper = getWrapper(props);

//At 1 because it is the 2nd tab
wrapper.find("Tab").at(1).simulate("click");

const preview = wrapper.find("#markdown-preview");
render(<MarkdownEditor {...props} />);

expect(preview.exists()).toBeTruthy();
await userEvent.click(screen.getByRole("tab", {name: "Preview"}));

expect(preview.props().content).toBe(props.content);
expect(preview.props().updateAnnotationCompletion).toBe(props.updateAnnotationCompletion);
const preview = document.querySelector("#annotation-preview");
expect(preview).toBeTruthy();
expect(preview.textContent.trim()).toEqual(props.content);
});
});
Loading

0 comments on commit c4b8e4e

Please sign in to comment.