diff --git a/app/javascript/components/insights-sub-report/container.jsx b/app/javascript/components/insights-sub-report/container.jsx
index bb6f08a26f..6197cb6de1 100644
--- a/app/javascript/components/insights-sub-report/container.jsx
+++ b/app/javascript/components/insights-sub-report/container.jsx
@@ -1,6 +1,6 @@
import { useEffect, useMemo } from "react";
import { useParams } from "react-router-dom";
-import { fromJS } from "immutable";
+import { fromJS, List } from "immutable";
import { useDispatch } from "react-redux";
import isNil from "lodash/isNil";
import isString from "lodash/isString";
@@ -168,7 +168,11 @@ const Component = () => {
.entrySeq()
.map(([valueKey, value]) => {
const hasTotalColumn = isGrouped
- ? value.some(elem => elem.get("data", fromJS([])).some(row => !isNil(row.get("total"))))
+ ? value.some(
+ elem =>
+ List.isList(elem.get("data")) &&
+ elem.get("data", fromJS([])).some(row => !isNil(row.get("total")))
+ )
: value.some(row => !isNil(row.get("total")));
const indicatorSubColumnKeys = getIndicatorSubcolumnKeys(value);
diff --git a/app/javascript/components/insights-sub-report/container.spec.js b/app/javascript/components/insights-sub-report/container.spec.js
new file mode 100644
index 0000000000..a5f7edbcdd
--- /dev/null
+++ b/app/javascript/components/insights-sub-report/container.spec.js
@@ -0,0 +1,129 @@
+import { fromJS } from "immutable";
+
+import { mountedComponent, screen } from "../../test-utils";
+
+import InsightsSubReport from "./container";
+
+describe("", () => {
+ const initialState = fromJS({
+ records: {
+ insights: {
+ selectedReport: {
+ id: "ghn_report",
+ name: "managed_reports.ghn_report.name",
+ description: "managed_reports.ghn_report.description",
+ module_id: "primeromodule-mrm",
+ subreports: ["ghn_report"],
+ report_data: {
+ ghn_report: {
+ data: {
+ verified_information: [
+ {
+ group_id: "boys",
+ data: [
+ {
+ id: "killing",
+ total: 2
+ }
+ ]
+ },
+ {
+ group_id: "girls",
+ data: []
+ },
+ {
+ group_id: "unknown",
+ data: []
+ },
+ {
+ group_id: "total",
+ data: [
+ {
+ id: "killing",
+ total: 2
+ }
+ ]
+ }
+ ],
+ verified_information_violations: [],
+ late_verification: [],
+ late_verification_violations: [],
+ unverified_information: [
+ {
+ group_id: "boys",
+ data: [
+ {
+ id: "killing",
+ total: 1
+ }
+ ]
+ },
+ {
+ group_id: "girls",
+ data: []
+ },
+ {
+ group_id: "unknown",
+ data: []
+ },
+ {
+ group_id: "total",
+ data: [
+ {
+ id: "killing",
+ total: 1
+ }
+ ]
+ }
+ ],
+ unverified_information_violations: [],
+ multiple_violations: [
+ {
+ data: {
+ unique_id: "26c0dfd0-4731-41d2-a6f5-689370cca821",
+ violations: ["killing"],
+ incident_id: "bb763213-2202-4e3d-a302-05bc96ed599b",
+ individual_age: null,
+ individual_sex: "male",
+ incident_short_id: "21ac674"
+ }
+ }
+ ]
+ },
+ metadata: {
+ display_graph: false,
+ lookups: {
+ multiple_violations: ["lookup-gender-unknown-total", "lookup-violation-type"]
+ },
+ table_type: "ghn_report",
+ order: [
+ "verified_information",
+ "verified_information_violations",
+ "late_verification",
+ "late_verification_violations",
+ "unverified_information",
+ "unverified_information_violations",
+ "multiple_violations"
+ ],
+ indicators_rows: {},
+ indicators_subcolumns: {}
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+
+ it("should render a MultipleViolationsIndicator component", () => {
+ mountedComponent(
+ ,
+ initialState,
+ {},
+ ["/insights/primeromodule-mrm/ghn_report/ghn_report"],
+ {},
+ "/insights/:moduleID/:id/:subReport"
+ );
+ expect(screen.getByText("managed_reports.ghn_report.sub_reports.multiple_violations")).toBeInTheDocument();
+ });
+});
diff --git a/app/javascript/components/insights-sub-report/container.unit.test.js b/app/javascript/components/insights-sub-report/container.unit.test.js
deleted file mode 100644
index da6b37d829..0000000000
--- a/app/javascript/components/insights-sub-report/container.unit.test.js
+++ /dev/null
@@ -1,161 +0,0 @@
-import { Route } from "react-router-dom";
-import { fromJS } from "immutable";
-
-import { setupMountedComponent } from "../../test";
-import TableValues from "../charts/table-values";
-
-import InsightsSubReport from "./container";
-
-describe("", () => {
- let component;
- const initialState = fromJS({
- records: {
- insights: {
- selectedReport: {
- id: "violations",
- name: "managed_reports.violations.name",
- description: "managed_reports.violations.description",
- module_id: "primeromodule-mrm",
- subreports: ["killing", "maiming"],
- report_data: {
- killing: {
- data: {
- violation: [
- {
- group_id: "2022-Q2",
- data: [
- {
- id: "boys",
- total: 2
- },
- {
- id: "girls",
- total: 2
- },
- {
- id: "total",
- total: 5
- }
- ]
- }
- ],
- perpetrators: [
- {
- group_id: "2022-Q2",
- data: [
- {
- id: "armed_force_1",
- boys: 1,
- total: 2,
- unknown: 1
- }
- ]
- }
- ]
- },
- metadata: {
- display_graph: true,
- lookups: {
- perpetrators: "lookup-armed-force-group-or-other-party",
- violation: "lookup-violation-tally-options"
- },
- table_type: "default",
- order: ["violation", "perpetrators"]
- }
- }
- }
- },
- filters: {
- grouped_by: "quarter",
- date_range: "this_quarter",
- date: "incident_date",
- subreport: "detention"
- },
- loading: false,
- errors: false
- }
- },
- forms: {
- options: {
- lookups: [
- {
- id: 1,
- unique_id: "lookup-violation-tally-options",
- name: {
- en: "Violation Tally Options"
- },
- values: [
- {
- id: "boys",
- display_text: {
- en: "Boys"
- }
- },
- {
- id: "girls",
- display_text: {
- en: "Girls"
- }
- },
- {
- id: "total",
- display_text: {
- en: "Total"
- }
- }
- ]
- },
- {
- id: 2,
- unique_id: "lookup-armed-force-group-or-other-party",
- name: {
- en: "Violation Tally Options"
- },
- values: [
- {
- id: "armed_force_1",
- display_text: {
- en: "Armed Force 1"
- }
- }
- ]
- }
- ]
- }
- }
- });
-
- beforeEach(() => {
- const routedComponent = initialProps => {
- return (
- }
- />
- );
- };
-
- ({ component } = setupMountedComponent(routedComponent, {}, initialState, [
- "/insights/primeromodule-mrm/violations/killing"
- ]));
- });
-
- it("should render component", () => {
- expect(component.find(InsightsSubReport)).to.have.lengthOf(1);
- });
-
- it("should render component", () => {
- const title = component.find(InsightsSubReport).find("h2");
-
- expect(title).to.have.lengthOf(1);
- expect(title.text()).to.be.equal("managed_reports.violations.description");
- });
-
- it("should render component", () => {
- expect(component.find(TableValues)).to.have.lengthOf(2);
- });
-
- it("should render component", () => {
- expect(component.find("h3")).to.have.lengthOf(2);
- });
-});
diff --git a/app/javascript/test-utils/mounted-component.js b/app/javascript/test-utils/mounted-component.js
index b7f5a13b28..980aaa8860 100644
--- a/app/javascript/test-utils/mounted-component.js
+++ b/app/javascript/test-utils/mounted-component.js
@@ -29,7 +29,7 @@ const FormikForm = ({ children }) => {
);
};
-function mountedComponent(Component, state = {}, options = {}, initialEntries = {}, formProps = {}, path = "") {
+function mountedComponent(Component, state = {}, options = {}, initialEntries = [], formProps = {}, path = "") {
const { store, history } = createMockStore(DEFAULT_STATE, state);
function FormProvider({ children }) {
diff --git a/buildspec.yml b/buildspec.yml
index 84e1ce5c51..bf47703c12 100644
--- a/buildspec.yml
+++ b/buildspec.yml
@@ -14,6 +14,7 @@ env:
SECRET_VARS_release_2_4: 'PrimeroCicdSecretrelease-2-4'
SECRET_VARS_release_2_5: 'PrimeroCicdSecretrelease-2-5'
SECRET_VARS_release_2_6: 'PrimeroCicdSecretrelease-2-6'
+ SECRET_VARS_release_2_7: 'PrimeroCicdSecretrelease-2-7'
phases:
pre_build: