Skip to content

Commit

Permalink
Merge branch 'develop' into r2-2608-prevent-multiple-cases
Browse files Browse the repository at this point in the history
Conflicts:
	spec/requests/api/v2/children_controller_spec.rb
  • Loading branch information
dhernandez-quoin committed Sep 20, 2023
2 parents f60a3bd + 86572b1 commit bb48db6
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 119 deletions.
2 changes: 1 addition & 1 deletion app/controllers/api/v2/children_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def select_updated_fields
end

def family
authorize! :create, Child
authorize! :case_from_family, Child
@current_record = Child.find(family_params[:case_id])
@record = FamilyLinkageService.new_family_linked_child(
current_user, @current_record, family_params[:family_detail_id]
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/api/v2/families_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def query_scope
end

def create_case
authorize! :case_from_family, model_class
authorize! :case_from_family, Family
@current_record = Family.find(create_case_params[:family_id])
@record = @current_record.new_child_from_family_member(current_user, create_case_params['family_member_id'])
@record.save!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import PageContainer from "../../../page";
import LoadingIndicator from "../../../loading-indicator";
import { clearSelectedRecord, fetchRecord, saveRecord, setSelectedRecord } from "../../../records";
import { RECORD_TYPES, RECORD_TYPES_PLURAL, REFERRAL } from "../../../../config";
import { getIsProcessingSomeAttachment, getLoadingRecordState } from "../../../records/selectors";
import { getIsProcessingSomeAttachment, getLoadingRecordState, getSelectedRecord } from "../../../records/selectors";
import { clearRecordAttachments, fetchRecordsAlerts } from "../../../records/action-creators";
import useIncidentFromCase from "../../../records/use-incident-form-case";
import SaveAndRedirectDialog from "../../../save-and-redirect-dialog";
Expand Down Expand Up @@ -60,6 +60,7 @@ const Component = ({
}) => {
let submitForm = null;
const mobileDisplay = useMediaQuery(theme => theme.breakpoints.down("sm"));
const [selectedRecordChanged, setSelectedRecordChanged] = useState(false);

const { state: locationState } = useLocation();
const history = useHistory();
Expand Down Expand Up @@ -90,6 +91,7 @@ const Component = ({
const loadingRecord = useMemoizedSelector(state => getLoadingRecordState(state, params.recordType));
const errors = useMemoizedSelector(state => getErrors(state));
const selectedForm = useMemoizedSelector(state => getSelectedForm(state));
const selectedRecord = useMemoizedSelector(state => getSelectedRecord(state, params.recordType));
const isProcessingSomeAttachment = useMemoizedSelector(state =>
getIsProcessingSomeAttachment(state, params.recordType)
);
Expand Down Expand Up @@ -244,10 +246,17 @@ const Component = ({
}, [selectedForm]);

useEffect(() => {
if (containerMode.isShow && firstTab && shouldFetchRecord) {
if (params.id && selectedRecord && selectedRecord !== params.id && containerMode.isShow) {
setSelectedRecordChanged(true);
}
}, [selectedRecord, containerMode.isShow, params.id]);

useEffect(() => {
if (selectedRecordChanged && containerMode.isShow && firstTab) {
dispatch(setSelectedForm(firstTab.unique_id));
setSelectedRecordChanged(false);
}
}, [shouldFetchRecord]);
}, [selectedRecordChanged, containerMode.isShow, firstTab]);

const transitionProps = {
fetchable: isNotANewCase,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ const Component = ({
parentForm={form}
entryFilter={entryFilter}
parentTitle={parentTitle}
isFamilyMember={isFamilyMember}
isFamilyDetail={isFamilyDetail}
/>
</List>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ const Component = ({
parentForm,
isViolationAssociation,
entryFilter = false,
parentTitle
parentTitle,
isFamilyMember,
isFamilyDetail
}) => {
const i18n = useI18n();

Expand All @@ -63,6 +65,18 @@ const Component = ({

const { isEdit, isNew } = mode;

const canDeleteFamilySubform = index => {
if (isFamilyDetail) {
return !formik?.values?.family_id;
}

if (isFamilyMember) {
return !values[index]?.case_id;
}

return true;
};

const handleDelete = () => {
const index = selectedIndex;

Expand Down Expand Up @@ -173,7 +187,7 @@ const Component = ({
rest={{
onClick: () => handleOpenModal(index),
// TODO: disable only when there is no violation or association
disabled: isViolationSubform || isViolationAssociation
disabled: isViolationSubform || isViolationAssociation || !canDeleteFamilySubform(index)
}}
/>
) : null}
Expand Down Expand Up @@ -215,6 +229,8 @@ Component.propTypes = {
entryFilter: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]),
field: PropTypes.object.isRequired,
formik: PropTypes.object.isRequired,
isFamilyDetail: PropTypes.bool,
isFamilyMember: PropTypes.bool,
isTracesSubform: PropTypes.bool,
isViolationAssociation: PropTypes.bool,
isViolationSubform: PropTypes.bool,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { mountedComponent, screen } from "test-utils";

import { FieldRecord, FormSectionRecord } from "../../../records";

import SubformFields from "./component";

describe("<SubformFields />", () => {
const props = {
arrayHelpers: {},
parentForm: {
id: 33,
unique_id: "family_details",
description: {
en: "Family Details"
},
name: {
en: "Family Details"
},
visible: true,
is_first_tab: false,
order: 10,
order_form_group: 30,
parent_form: "case",
editable: true,
module_ids: ["primeromodule-cp"],
form_group_id: "identification_registration",
form_group_name: {
en: "Identification / Registration"
}
},
field: FieldRecord({
name: "family_details_section",
displayName: { en: "Family Details" },
subform_section_id: FormSectionRecord({
unique_id: "family_section",
collapsed_field_names: ["relation_name"],
fields: [
FieldRecord({
name: "relation_name",
visible: true,
type: "text_field"
}),
FieldRecord({
name: "relation_child_is_in_contact",
visible: true,
type: "text_field"
})
]
})
}),
locale: "en",
setDialogIsNew: () => {},
setOpen: () => {},
i18n: { t: value => value, locale: "en" },
values: [
{
relation_name: "Family1",
relation_child_is_in_contact: ""
}
],
mode: {
isShow: true
},
recordType: "cases"
};

it("renders the subform fields", () => {
mountedComponent(<SubformFields {...props} />);

expect(screen.queryByText("Family1")).toBeTruthy();
});

describe("when is violation or violation association", () => {
it("renders the Delete button disabled", () => {
mountedComponent(
<SubformFields
{...props}
isViolationSubform
isViolationAssociation
mode={{ isEdit: true }}
values={["something"]}
/>
);

expect(screen.queryAllByRole("button")[0]).toHaveAttribute("disabled");
});
});

describe("Family Detail subform", () => {
describe("when is associated to a family", () => {
it("renders the Delete button disabled", () => {
mountedComponent(
<SubformFields {...props} isFamilyDetail mode={{ isEdit: true }} formik={{ values: { family_id: "001" } }} />
);

expect(screen.queryAllByRole("button")).toHaveLength(2);
expect(screen.queryAllByRole("button")[0]).toHaveAttribute("disabled");
});
});

describe("when is not associated to a family", () => {
it("renders the Delete button enabled", () => {
mountedComponent(<SubformFields {...props} isFamilyDetail mode={{ isEdit: true }} formik={{ values: {} }} />);

expect(screen.queryAllByRole("button")).toHaveLength(2);
expect(screen.queryAllByRole("button")[0]).not.toHaveAttribute("disabled");
});
});
});

describe("Family Member subform", () => {
describe("when is associated to a case", () => {
it("renders the Delete button disabled", () => {
mountedComponent(
<SubformFields {...props} isFamilyMember mode={{ isEdit: true }} values={[{ case_id: "001" }]} />
);

expect(screen.queryAllByRole("button")).toHaveLength(2);
expect(screen.queryAllByRole("button")[0]).toHaveAttribute("disabled");
});
});

describe("when is not associated to a case", () => {
it("renders the Delete button enabled", () => {
mountedComponent(<SubformFields {...props} isFamilyMember mode={{ isEdit: true }} />);

expect(screen.queryAllByRole("button")).toHaveLength(2);
expect(screen.queryAllByRole("button")[0]).not.toHaveAttribute("disabled");
});
});
});
});

This file was deleted.

2 changes: 1 addition & 1 deletion app/services/permitted_field_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def permitted_registry_record_id
def permitted_family_id
return [] unless model_class == Child

if user.can?(:view_family_record, model_class)
if user.can?(:view_family_record, model_class) || user.can?(:case_from_family, model_class)
return %w[family_id family_id_display family_member_id family_name family_number]
end

Expand Down
4 changes: 4 additions & 0 deletions db/configuration/forms/family/family_details.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
matchable: true,
help_text_en: 'This field can be copied to/from the Case but is not s shared field and '\
'can be edited on the Family record.'),
Field.new(name: 'family_relation_is_caregiver',
type: 'tick_box',
display_name_en: 'Is this person the caregiver for one of the children in this family?',
tick_box_label_en: 'Yes'),
Field.new(name: 'family_relationship_notes',
type: 'textarea',
display_name_en: 'Notes on their role in the family.',
Expand Down
Loading

0 comments on commit bb48db6

Please sign in to comment.