diff --git a/Changelog.md b/Changelog.md index 33b0afc874..8a7a4aea11 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,7 @@ - Added support for all annotation types for POST /add_annotations (#8007) ### 🐛 Bug fixes +- Fixed bug where clicking a file link in the annotations tab would show a blank or oversized error for PDF files (#8017) - Fixed bug where clicking MarkUs logo in navbar on mobile would open the sidebar instead of redirecting to courses page (#7990) - Fixed bug where merge commits were incorrectly flagged as making a new assignment submission when no assignment files were changed (#7988) - Fixed shift+up/shift+down keybinding being suppressed when a criterion input had focus; active criterion now scrolls into view when navigated to via keyboard (#7989) diff --git a/app/javascript/Components/Result/left_pane.jsx b/app/javascript/Components/Result/left_pane.jsx index a86b11582d..7f7c07f9f8 100644 --- a/app/javascript/Components/Result/left_pane.jsx +++ b/app/javascript/Components/Result/left_pane.jsx @@ -57,9 +57,18 @@ export class LeftPane extends React.Component { // Display a given file. Used to changes files from the annotations panel. selectFile = (file, submission_file_id, focus_line, annotation_focus) => { + const parts = file.split("/"); + const filename = parts.pop(); + let node = this.props.submission_files; + for (const dir of parts) { + node = node.directories[dir]; + } + const fileEntry = node.files.find(f => f[0] === filename); + const type = fileEntry ? fileEntry[2] : null; this.submissionFilePanel.current.selectFile( file, submission_file_id, + type, focus_line, annotation_focus ); diff --git a/app/javascript/Components/__tests__/left_pane.test.jsx b/app/javascript/Components/__tests__/left_pane.test.jsx new file mode 100644 index 0000000000..5331cc606f --- /dev/null +++ b/app/javascript/Components/__tests__/left_pane.test.jsx @@ -0,0 +1,117 @@ +import React from "react"; +import {render} from "@testing-library/react"; +import {LeftPane} from "../Result/left_pane"; +import {renderInResultContext} from "./result_context_renderer"; + +jest.mock("../Result/annotation_panel", () => ({AnnotationPanel: () =>
})); +jest.mock("../Result/feedback_file_panel", () => ({FeedbackFilePanel: () =>
})); +jest.mock("../Result/remark_panel", () => ({RemarkPanel: () =>
})); +jest.mock("../test_run_table", () => ({TestRunTable: () =>
})); +jest.mock("../Result/submission_file_panel", () => { + const React = require("react"); + const MockSubmissionFilePanel = React.forwardRef((props, ref) => { + React.useImperativeHandle(ref, () => ({selectFile: jest.fn()})); + return null; + }); + MockSubmissionFilePanel.displayName = "MockSubmissionFilePanel"; + return {SubmissionFilePanel: MockSubmissionFilePanel}; +}); + +const flatFileData = { + files: [ + ["report.pdf", 1, "pdf"], + ["notes.txt", 2, "text"], + ], + directories: {}, + name: "", + path: [], +}; + +const nestedFileData = { + files: [["root.pdf", 1, "pdf"]], + directories: { + subdir: { + files: [["image.png", 2, "image"]], + directories: { + nested: { + files: [["data.csv", 3, "text"]], + directories: {}, + name: "nested", + path: ["subdir", "nested"], + }, + }, + name: "subdir", + path: ["subdir"], + }, + }, + name: "", + path: [], +}; + +const basicProps = { + loading: false, + allow_remarks: false, + annotation_categories: [], + annotations: [], + assignment_remark_message: "", + update_overall_comment: jest.fn(), + can_run_tests: false, + detailed_annotations: false, + enable_test: false, + feedback_files: [], + instructor_run: false, + overall_comment: "", + past_remark_due_date: false, + released_to_students: false, + remark_due_date: null, + remark_overall_comment: "", + remark_request_text: "", + remark_request_timestamp: null, + remark_submitted: false, + revision_identifier: "1", + submission_files: flatFileData, + student_view: false, + newAnnotation: jest.fn(), + addExistingAnnotation: jest.fn(), + editAnnotation: jest.fn(), + removeAnnotation: jest.fn(), + rmd_convert_enabled: false, +}; + +describe("LeftPane", () => { + describe("selectFile", () => { + it("passes the file type for a file at the root level", () => { + const leftPaneRef = React.createRef(); + renderInResultContext( + + ); + + leftPaneRef.current.selectFile("report.pdf", 1, undefined, 42); + + expect(leftPaneRef.current.submissionFilePanel.current.selectFile).toHaveBeenCalledWith( + "report.pdf", + 1, + "pdf", + undefined, + 42 + ); + }); + + it("passes the correct file type for a file in a nested subdirectory", () => { + const leftPaneRef = React.createRef(); + renderInResultContext( + + ); + + leftPaneRef.current.selectFile("subdir/image.png", 2, undefined, 42); + + expect(leftPaneRef.current.submissionFilePanel.current.selectFile).toHaveBeenCalledWith( + "subdir/image.png", + 2, + "image", + undefined, + 42 + ); + }); + }); +});