github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/public/src/__tests__/ProgressBar.test.tsx (about)

     1  import React from "react"
     2  import { Assignment, Submission } from "../../proto/qf/types_pb"
     3  import ProgressBar, { Progress } from "../components/ProgressBar"
     4  import { initializeOvermind } from "./TestHelpers"
     5  import { Provider } from "overmind-react"
     6  import { render } from "@testing-library/react"
     7  
     8  type ProgressBarTest = {
     9      desc: string,
    10      submission: Submission,
    11      assignment: Assignment,
    12      want: string
    13      assignmentIndex?: number
    14  }
    15  
    16  
    17  describe("ProgressBar", () => {
    18      React.useLayoutEffect = React.useEffect
    19  
    20  
    21      const progressBarTests: ProgressBarTest[] = [
    22          {
    23              desc: "100% Progress Bar",
    24              submission: new Submission({
    25                  score: 100,
    26              }),
    27              assignment: new Assignment({ scoreLimit: 100 }),
    28              want: "100 %"
    29          },
    30          {
    31              desc: "0% Progress Bar",
    32              submission: new Submission({ score: 0 }),
    33              assignment: new Assignment({ scoreLimit: 100 }),
    34              want: "0 %"
    35          },
    36          {
    37              desc: "50% Progress Bar",
    38              submission: new Submission({ score: 50 }),
    39              assignment: new Assignment({ scoreLimit: 100 }),
    40              want: "50 %"
    41          },
    42          {
    43              desc: "50% Progress Bar, with 75% scorelimit",
    44              submission: new Submission({ score: 50 }),
    45              assignment: new Assignment({ scoreLimit: 75 }),
    46              want: "50 %"
    47          },
    48          {
    49              desc: "75% Progress Bar, with 50% scorelimit",
    50              submission: new Submission({ score: 75 }),
    51              assignment: new Assignment({ scoreLimit: 50 }),
    52              want: "75 %"
    53          },
    54          {
    55              desc: "75% Progress Bar, with 75% scorelimit",
    56              submission: new Submission({ score: 75 }),
    57              assignment: new Assignment({ scoreLimit: 75 }),
    58              want: "75 %"
    59          },
    60          {
    61              desc: "Progress Bar without score",
    62              submission: new Submission(),
    63              assignment: new Assignment({ scoreLimit: 100 }),
    64              want: "0 %"
    65          },
    66          {
    67              desc: "Progress Bar without scorelimit",
    68              submission: new Submission({ score: 50 }),
    69              assignment: new Assignment(),
    70              want: "50 %"
    71          },
    72          {
    73              desc: "Progress Bar without score and scorelimit",
    74              submission: new Submission(),
    75              assignment: new Assignment(),
    76              want: "0 %"
    77          },
    78          {
    79              desc: "Progress Bar with incorrect index",
    80              submission: new Submission({ score: 50 }),
    81              assignment: new Assignment({ scoreLimit: 100 }),
    82              want: "0 %",
    83              assignmentIndex: 10
    84          }
    85      ]
    86  
    87      test.each(progressBarTests)(`[Progress.LAB] $desc`, (test) => {
    88          labTest(test, true)
    89      })
    90  
    91      test.each(progressBarTests)(`[Progress.LAB - Without Submission] $desc`, (test) => {
    92          labTest(test, false)
    93      })
    94  
    95  
    96      test.each(progressBarTests)(`[Progress.NAV] $desc`, (test) => {
    97          const overmind = initializeOvermind({ assignments: { "1": [test.assignment] }, submissions: { "1": [test.submission] } })
    98  
    99          const { container } = render(
   100              <Provider value={overmind}>
   101                  <ProgressBar courseID={"1"} assignmentIndex={0} submission={test.submission} type={Progress.NAV} />
   102              </Provider>
   103          )
   104  
   105  
   106          const bar = container.getElementsByTagName("div").item(0)
   107          expect(bar?.style).toHaveProperty("right", `${100 - test.submission.score}%`)
   108          expect(bar?.style).toHaveProperty(
   109              "border-bottom",
   110              test.submission.score >= test.assignment.scoreLimit
   111                  ? "2px solid green"
   112                  : "2px solid yellow"
   113          )
   114      })
   115  })
   116  
   117  const labTest = (test: ProgressBarTest, withSubmission: boolean) => {
   118      const overmind = initializeOvermind({ assignments: { "1": test.assignment ? [test.assignment] : [] }, submissions: { "1": test.submission ? [test.submission] : [] } })
   119  
   120      const { container } = render(
   121          <Provider value={overmind}>
   122              <ProgressBar courseID={"1"} assignmentIndex={test.assignmentIndex ?? 0} submission={withSubmission ? test.submission : undefined} type={Progress.LAB} />
   123          </Provider>
   124      )
   125  
   126      // Incorrect assignment index should not have a secondary bar
   127      const hasSecondary = test.submission.score < test.assignment.scoreLimit && test.assignmentIndex === undefined
   128      // Given an invalid assignment index, we expect the bar to be empty
   129      // However, if we pass a submission, we expect the bar to be filled to the correct percentage
   130      const score = test.assignmentIndex === undefined || withSubmission
   131          ? test.submission.score
   132          : 0
   133  
   134      const bars = container.getElementsByClassName("progress-bar")
   135      expect(bars).toHaveLength(hasSecondary ? 2 : 1)
   136      if (hasSecondary) {
   137          const secondary = container.getElementsByClassName("progressbar-secondary").item(0)
   138          if (!secondary) {
   139              fail()
   140          }
   141          expect(secondary.getAttribute("style")).toContain(`width: ${test.assignment.scoreLimit - test.submission.score}%`)
   142          expect(secondary.textContent).toEqual(`${test.assignment.scoreLimit - test.submission.score} %`)
   143      }
   144  
   145      expect(container.getElementsByClassName("progress-bar bg-primary").item(0)?.getAttribute("style")).toContain(`width: ${score}%`)
   146      expect(bars[0].textContent).toContain(test.want)
   147  }