• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MarkUsProject / Markus / 12456166531

22 Dec 2024 05:11PM UTC coverage: 91.758% (-0.002%) from 91.76%
12456166531

push

github

web-flow
Refactor file viewer components (#7270)

* Return extra file information for submission files
* Remove get_file route
* Move HEIC/HEIF file handling to the image viewer
* Refactor text viewer to fetch content from URL
* Cancel promises and state updates after component unmount
* Add `max_content_size` param to `/download_file`
* Handle (413 Content Too Large) when fetching file content
* Add binary file extensions

623 of 1357 branches covered (45.91%)

Branch coverage included in aggregate %.

115 of 149 new or added lines in 9 files covered. (77.18%)

2 existing lines in 2 files now uncovered.

41180 of 44201 relevant lines covered (93.17%)

120.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.41
/app/javascript/Components/Result/file_viewer.jsx
1
import React from "react";
2

3
import {ImageViewer} from "./image_viewer";
4
import {TextViewer} from "./text_viewer";
5
import {PDFViewer} from "./pdf_viewer";
6
import {NotebookViewer} from "./notebook_viewer";
7
import {BinaryViewer} from "./binary_viewer";
8
import {URLViewer} from "./url_viewer";
9

10
export class FileViewer extends React.Component {
11
  state = {
3✔
12
    loading: false,
13
    errorMessage: null,
14
  };
15

16
  mounted = false;
3✔
17

18
  setLoading = loading => {
3✔
19
    if (this.mounted) {
10✔
20
      this.setState({loading: loading});
7✔
21
    }
22
  };
23

24
  setErrorMessage = message => {
3✔
25
    if (this.mounted) {
1!
26
      this.setState({errorMessage: message});
1✔
27
    }
28
  };
29

30
  componentDidMount() {
31
    this.mounted = true;
3✔
32
  }
33

34
  componentWillUnmount() {
35
    this.mounted = false;
1✔
36
  }
37

38
  componentDidUpdate(prevProps, prevState, snapshot) {
39
    if (this.props !== prevProps) {
10✔
40
      this.setState({
2✔
41
        loading: false,
42
        errorMessage: null,
43
      });
44
    }
45
  }
46

47
  getViewer() {
48
    const commonProps = {
13✔
49
      submission_file_id: this.props.selectedFile,
50
      annotations: this.props.annotations ? this.props.annotations : [],
13!
51
      released_to_students: this.props.released_to_students,
52
      resultView: !!this.props.result_id,
53
      course_id: this.props.course_id,
54
      key: `${this.props.selectedFileType}-viewer`,
55
      url: this.props.selectedFileURL,
56
      setLoadingCallback: this.setLoading,
57
      setErrorMessageCallback: this.setErrorMessage,
58
    };
59

60
    if (this.props.selectedFileType === "image") {
13!
NEW
61
      return <ImageViewer mime_type={this.props.mime_type} {...commonProps} />;
×
62
    } else if (this.props.selectedFileType === "pdf") {
13!
NEW
63
      return <PDFViewer annotationFocus={this.props.annotationFocus} {...commonProps} />;
×
64
    } else if (this.props.selectedFileType === "jupyter-notebook") {
13!
NEW
65
      return <NotebookViewer annotationFocus={this.props.annotationFocus} {...commonProps} />;
×
66
    } else if (this.props.selectedFileType === "binary") {
13!
NEW
67
      return <BinaryViewer content={this.state.content} {...commonProps} />;
×
68
    } else if (this.props.selectedFileType === "markusurl") {
13!
UNCOV
69
      return <URLViewer externalUrl={this.state.content} {...commonProps} />;
×
70
    } else if (this.props.selectedFileType !== "") {
13!
71
      return (
13✔
72
        <TextViewer
73
          type={this.props.selectedFileType}
74
          focusLine={this.props.focusLine}
75
          {...commonProps}
76
        />
77
      );
78
    } else {
79
      return "";
×
80
    }
81
  }
82

83
  render() {
84
    const viewer = this.getViewer();
13✔
85
    const outerDivStyle = {
13✔
86
      display: this.state.loading || this.state.errorMessage ? "none" : "block",
39✔
87
      height: "100%",
88
    };
89
    return (
13✔
90
      <React.Fragment>
91
        <div style={outerDivStyle}>{viewer}</div>
92
        {this.state.errorMessage && <p>{this.state.errorMessage}</p>}
15✔
93
        {this.state.loading && !this.state.errorMessage && <p>{I18n.t("working")}</p>}
13!
94
      </React.Fragment>
95
    );
96
  }
97
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc