diff --git a/app/assets/javascripts/Components/Result/image_viewer.jsx b/app/assets/javascripts/Components/Result/image_viewer.jsx
index d624e511d5..e8afc9e91f 100644
--- a/app/assets/javascripts/Components/Result/image_viewer.jsx
+++ b/app/assets/javascripts/Components/Result/image_viewer.jsx
@@ -188,10 +188,10 @@ export class ImageViewer extends React.PureComponent {
level: Math.floor(this.state.zoom * 100),
})}
- {I18n.t("results.zoom_in")}+
+ {I18n.t("results.zoom_in_image")}+
- {I18n.t("results.zoom_out")}-
+ {I18n.t("results.zoom_out_image")}-
diff --git a/app/assets/javascripts/Components/Result/pdf_viewer.jsx b/app/assets/javascripts/Components/Result/pdf_viewer.jsx
index 80f6253fa7..fa308b0468 100644
--- a/app/assets/javascripts/Components/Result/pdf_viewer.jsx
+++ b/app/assets/javascripts/Components/Result/pdf_viewer.jsx
@@ -84,7 +84,10 @@ export class PDFViewer extends React.PureComponent {
};
rotate = () => {
- annotation_manager.rotateClockwise90();
+ if (this.props.resultView) {
+ annotation_manager.rotateClockwise90();
+ }
+
this.setState(({rotationInDegrees}) => ({
rotationInDegrees: (rotationInDegrees + 90) % 360,
}));
@@ -129,7 +132,7 @@ export class PDFViewer extends React.PureComponent {
acc[value] = `${(value * 100).toFixed(0)} %`;
return acc;
},
- {"page-width": "Fit to page width"}
+ {"page-width": I18n.t("results.fit_to_page_width")}
);
return valueToDisplayName;
diff --git a/app/assets/javascripts/Components/__tests__/pdf_viewer.test.jsx b/app/assets/javascripts/Components/__tests__/pdf_viewer.test.jsx
new file mode 100644
index 0000000000..586b38906c
--- /dev/null
+++ b/app/assets/javascripts/Components/__tests__/pdf_viewer.test.jsx
@@ -0,0 +1,116 @@
+import React from "react";
+import {render, screen, fireEvent} from "@testing-library/react";
+import {PDFViewer} from "../Result/pdf_viewer";
+
+describe("PDFViewer", () => {
+ let mockPdfViewer;
+ let mockAnnotationManager;
+
+ beforeEach(() => {
+ mockPdfViewer = {
+ setDocument: jest.fn(),
+ pagesRotation: 0,
+ currentScaleValue: "page-width",
+ };
+
+ mockAnnotationManager = {
+ rotateClockwise90: jest.fn(),
+ };
+
+ global.pdfjsViewer = {
+ EventBus: class {
+ on = jest.fn();
+ },
+ PDFViewer: jest.fn(() => mockPdfViewer),
+ };
+
+ global.annotation_manager = mockAnnotationManager;
+
+ render(
);
+ });
+
+ afterEach(() => {
+ jest.restoreAllMocks();
+ delete global.pdfjsViewer;
+ delete global.annotation_manager;
+ });
+
+ describe("rotation", () => {
+ let rotateButton;
+
+ beforeEach(() => {
+ rotateButton = screen.getByText(I18n.t("results.rotate_image"));
+ });
+
+ it("initially has a rotation of 0", async () => {
+ expect(mockPdfViewer.pagesRotation).toBe(0);
+ });
+
+ it("rotates to 90 degrees when rotate button is clicked once", () => {
+ fireEvent.click(rotateButton);
+
+ expect(mockAnnotationManager.rotateClockwise90).toHaveBeenCalledTimes(1);
+ expect(mockPdfViewer.pagesRotation).toBe(90);
+ });
+
+ it("rotates back to 0 degrees when rotate button is clicked four times", () => {
+ for (let i = 0; i < 4; i++) {
+ fireEvent.click(rotateButton);
+ }
+
+ expect(mockAnnotationManager.rotateClockwise90).toHaveBeenCalledTimes(4);
+ expect(mockPdfViewer.pagesRotation).toBe(0);
+ });
+ });
+
+ describe("zoom", () => {
+ it("has default zoom 'page-width' on initial render", () => {
+ expect(mockPdfViewer.currentScaleValue).toBe("page-width");
+ });
+
+ it("updates zoom to 100% (1.0) when the option is selected from dropdown", () => {
+ const dropdown = screen.getByTestId("dropdown");
+ fireEvent.click(dropdown);
+
+ const option100 = screen.getByText("100 %");
+ fireEvent.click(option100);
+
+ expect(mockPdfViewer.currentScaleValue).toBe("1.0");
+ });
+
+ it("updates zoom to 90% (0.9) when the option is selected from dropdown", () => {
+ const dropdown = screen.getByTestId("dropdown");
+ fireEvent.click(dropdown);
+
+ const option110 = screen.getByText("90 %");
+ fireEvent.click(option110);
+
+ expect(mockPdfViewer.currentScaleValue).toBe("0.9");
+ });
+
+ it("updates zoom to 120% (1.2) when the option is selected from dropdown", () => {
+ const dropdown = screen.getByTestId("dropdown");
+ fireEvent.click(dropdown);
+
+ const option120 = screen.getByText("120 %");
+ fireEvent.click(option120);
+
+ expect(mockPdfViewer.currentScaleValue).toBe("1.2");
+ });
+
+ it("resets zoom to 'page-width' when the option is selected after selecting another zoom", () => {
+ // set some arbitrary zoom first
+ const dropdown = screen.getByTestId("dropdown");
+ fireEvent.click(dropdown);
+ const option120 = screen.getByText("120 %");
+ fireEvent.click(option120);
+
+ // now put it back to page width
+ fireEvent.click(dropdown);
+ const fitToPageWidthOption = screen.getByText(I18n.t("results.fit_to_page_width"));
+ fireEvent.click(fitToPageWidthOption);
+
+ expect(mockPdfViewer.currentScaleValue).toBe("page-width");
+ });
+ });
+});
diff --git a/app/views/exam_templates/_student_info.html.erb b/app/views/exam_templates/_student_info.html.erb
index f1ac84b126..e16efe0222 100644
--- a/app/views/exam_templates/_student_info.html.erb
+++ b/app/views/exam_templates/_student_info.html.erb
@@ -37,9 +37,9 @@