components/frontend/src/metric/Target.test.js
import { render, screen, waitFor } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import * as fetch_server_api from "../api/fetch_server_api"
import { DataModel } from "../context/DataModel"
import { EDIT_REPORT_PERMISSION, Permissions } from "../context/Permissions"
import { Target } from "./Target"
jest.mock("../api/fetch_server_api.js")
const dataModel = {
metrics: {
violations: {
unit: "violations",
direction: "<",
name: "Violations",
default_scale: "count",
scales: ["count", "percentage"],
},
violations_with_default_target: {
target: "100",
unit: "violations",
direction: "<",
name: "Violations",
default_scale: "count",
scales: ["count", "percentage"],
},
source_version: {
unit: "",
direction: "<",
name: "Source version",
default_scale: "version_number",
scales: ["version_number"],
},
},
}
function renderMetricTarget(metric) {
render(
<Permissions.Provider value={[EDIT_REPORT_PERMISSION]}>
<DataModel.Provider value={dataModel}>
<Target
metric={metric}
metric_uuid="metric_uuid"
target_type="target"
label="Target"
reload={() => {
/* Dummy implementation */
}}
/>
</DataModel.Provider>
</Permissions.Provider>,
)
}
it("sets the metric integer target", async () => {
fetch_server_api.fetch_server_api = jest.fn().mockResolvedValue({ ok: true })
renderMetricTarget({ type: "violations", target: "10" })
await userEvent.type(screen.getByDisplayValue("10"), "42{Enter}", {
initialSelectionStart: 0,
initialSelectionEnd: 2,
})
expect(fetch_server_api.fetch_server_api).toHaveBeenLastCalledWith("post", "metric/metric_uuid/attribute/target", {
target: "42",
})
})
it("sets the metric version target", async () => {
fetch_server_api.fetch_server_api = jest.fn().mockResolvedValue({ ok: true })
renderMetricTarget({ type: "source_version", target: "10" })
await userEvent.type(screen.getByDisplayValue("10"), "4.2{Enter}", {
initialSelectionStart: 0,
initialSelectionEnd: 2,
})
expect(fetch_server_api.fetch_server_api).toHaveBeenLastCalledWith("post", "metric/metric_uuid/attribute/target", {
target: "4.2",
})
})
it("displays the default target if changed", () => {
renderMetricTarget({ type: "violations_with_default_target" })
expect(screen.queryAllByText(/default:/).length).toBe(1)
})
it("shows help", async () => {
renderMetricTarget({ type: "violations", target: "10", near_target: "15" })
await userEvent.tab()
await waitFor(() => {
expect(screen.queryAllByText(/How measurement values are evaluated/).length).toBe(1)
})
})
function expectVisible(...matchers) {
matchers.forEach((matcher) => expect(screen.queryAllByText(matcher).length).toBe(1))
}
function expectNotVisible(...matchers) {
matchers.forEach((matcher) => expect(screen.queryAllByText(matcher).length).toBe(0))
}
it("shows help for evaluated metric without tech debt", async () => {
renderMetricTarget({ type: "violations", target: "10", near_target: "15" })
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target met/,
/≦ 10 violations/,
/Near target met/,
/10 - 15 violations/,
/Target not met/,
/> 15 violations/,
)
expectNotVisible(/Debt target met/)
})
})
it("shows help for evaluated metric with tech debt", async () => {
renderMetricTarget({
type: "violations",
target: "10",
debt_target: "15",
near_target: "20",
accept_debt: true,
})
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target met/,
/≦ 10 violations/,
/Debt target met/,
/10 - 15 violations/,
/Near target met/,
/15 - 20 violations/,
/Target not met/,
/> 20 violations/,
)
})
})
it("shows help for evaluated metric with tech debt if debt target is missing", async () => {
renderMetricTarget({ type: "violations", target: "10", near_target: "20", accept_debt: true })
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target met/,
/≦ 10 violations/,
/Near target met/,
/10 - 20 violations/,
/Target not met/,
/> 20 violations/,
)
expectNotVisible(/Debt target met/)
})
})
it("shows help for evaluated metric with tech debt with end date", async () => {
renderMetricTarget({
type: "violations",
target: "10",
debt_target: "15",
near_target: "20",
accept_debt: true,
debt_end_date: "3000-01-01",
})
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target met/,
/≦ 10 violations/,
/Debt target met/,
/10 - 15 violations/,
/Near target met/,
/15 - 20 violations/,
/Target not met/,
/> 20 violations/,
)
})
})
it("shows help for evaluated metric with tech debt with end date in the past", async () => {
renderMetricTarget({
type: "violations",
target: "10",
debt_target: "15",
near_target: "20",
accept_debt: true,
debt_end_date: "2000-01-01",
})
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target met/,
/≦ 10 violations/,
/Near target met/,
/10 - 20 violations/,
/Target not met/,
/> 20 violations/,
)
expectNotVisible(/Debt target met/)
})
})
it("shows help for evaluated metric with tech debt completely overlapping near target", async () => {
renderMetricTarget({
type: "violations",
target: "10",
debt_target: "20",
near_target: "20",
accept_debt: true,
})
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target met/,
/≦ 10 violations/,
/Debt target met/,
/10 - 20 violations/,
/Target not met/,
/> 20 violations/,
)
expectNotVisible(/Near target met/)
})
})
it("shows help for evaluated metric without tech debt and target completely overlapping near target", async () => {
renderMetricTarget({ type: "violations", target: "10", near_target: "10" })
await userEvent.tab()
await waitFor(() => {
expectVisible(/Target met/, /≦ 10 violations/, /Target not met/, /> 10 violations/)
expectNotVisible(/Debt target met/, /Near target met/)
})
})
it("shows help for evaluated more-is-better metric without tech debt", async () => {
renderMetricTarget({ type: "violations", target: "15", near_target: "10", direction: ">" })
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target not met/,
/< 10 violations/,
/Near target met/,
/10 - 15 violations/,
/Target met/,
/≧ 15 violations/,
)
expectNotVisible(/Debt target met/)
})
})
it("shows help for evaluated more-is-better metric with tech debt", async () => {
renderMetricTarget({
type: "violations",
target: "15",
near_target: "5",
debt_target: "10",
accept_debt: true,
direction: ">",
})
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target not met/,
/< 5 violations/,
/Near target met/,
/5 - 10 violations/,
/Debt target met/,
/10 - 15 violations/,
/Target met/,
/≧ 15 violations/,
)
})
})
it("shows help for evaluated more-is-better metric with tech debt and missing debt target", async () => {
renderMetricTarget({
type: "violations",
target: "15",
near_target: "5",
accept_debt: true,
direction: ">",
})
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target not met/,
/< 5 violations/,
/Near target met/,
/5 - 15 violations/,
/Target met/,
/≧ 15 violations/,
)
expectNotVisible(/Debt target met/)
})
})
it("shows help for evaluated more-is-better metric with tech debt completely overlapping near target", async () => {
renderMetricTarget({
type: "violations",
target: "15",
near_target: "5",
debt_target: "5",
accept_debt: true,
direction: ">",
})
await userEvent.tab()
await waitFor(() => {
expectVisible(
/Target not met/,
/< 5 violations/,
/Debt target met/,
/5 - 15 violations/,
/Target met/,
/≧ 15 violations/,
)
expectNotVisible(/Near target met/)
})
})
it("shows help for evaluated more-is-better metric without tech debt and target completely overlapping near target", async () => {
renderMetricTarget({ type: "violations", target: "15", near_target: "15", direction: ">" })
await userEvent.tab()
await waitFor(() => {
expectVisible(/Target not met/, /< 15 violations/, /Target met/, /≧ 15 violations/)
expectNotVisible(/Near target met/, /Debt target met/)
})
})
it("shows help for evaluated metric without tech debt and zero target completely overlapping near target", async () => {
renderMetricTarget({ type: "violations", target: "0", near_target: "0", direction: ">" })
await userEvent.tab()
await waitFor(() => {
expectVisible(/Target met/, /≧ 0 violations/)
expectNotVisible(/Debt target met/, /Near target met/, /Target not met/)
})
})
it("shows help for informative metric", async () => {
renderMetricTarget({ type: "violations", evaluate_targets: false })
await userEvent.tab()
await waitFor(() => {
expectVisible(/Informative/, /violations are not evaluated/)
expectNotVisible(/Target met/, /Debt target met/, /Near target met/, /Target not met/)
})
})