Skip to content

Commit

Permalink
Merge branch 'main' into B-21710-remove-old-homsesafe-cert
Browse files Browse the repository at this point in the history
  • Loading branch information
brenna-everett-caci authored Jan 17, 2025
2 parents 68e5302 + 3c3d645 commit b6a54fe
Show file tree
Hide file tree
Showing 11 changed files with 887 additions and 62 deletions.
299 changes: 254 additions & 45 deletions .gitlab-ci.yml

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions pkg/gen/ghcapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions pkg/gen/ghcmessages/counseling_update_order_payload.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/handlers/ghcapi/internal/payloads/model_to_payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ func Order(order *models.Order) *ghcmessages.Order {
MoveCode: moveCode,
MoveTaskOrderID: moveTaskOrderID,
OriginDutyLocationGBLOC: ghcmessages.GBLOC(swag.StringValue(order.OriginDutyLocationGBLOC)),
HasDependents: order.HasDependents,
}

return &payload
Expand Down
4 changes: 4 additions & 0 deletions pkg/services/order/order_updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ func orderFromCounselingPayload(existingOrder models.Order, payload ghcmessages.
order.Entitlement.DBAuthorizedWeight = &weight
}

if payload.HasDependents != nil {
order.HasDependents = *payload.HasDependents
}

return order
}

Expand Down
66 changes: 55 additions & 11 deletions src/components/Office/AddOrdersForm/AddOrdersForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ToolTip from 'shared/ToolTip/ToolTip';
import { DatePickerInput, DropdownInput, DutyLocationInput } from 'components/form/fields';
import { Form } from 'components/form/Form';
import SectionWrapper from 'components/Customer/SectionWrapper';
import { ORDERS_PAY_GRADE_OPTIONS } from 'constants/orders';
import { ORDERS_PAY_GRADE_OPTIONS, ORDERS_TYPE } from 'constants/orders';
import { dropdownInputOptions } from 'utils/formatters';
import WizardNavigation from 'components/Customer/WizardNavigation/WizardNavigation';
import Callout from 'components/Callout';
Expand All @@ -39,6 +39,9 @@ const AddOrdersForm = ({
const [hasDependents, setHasDependents] = useState(false);
const [isOconusMove, setIsOconusMove] = useState(false);
const [enableUB, setEnableUB] = useState(false);
const [isHasDependentsDisabled, setHasDependentsDisabled] = useState(false);
const [prevOrderType, setPrevOrderType] = useState('');
const [filteredOrderTypeOptions, setFilteredOrderTypeOptions] = useState(ordersTypeOptions);

const validationSchema = Yup.object().shape({
ordersType: Yup.mixed()
Expand Down Expand Up @@ -95,9 +98,24 @@ const AddOrdersForm = ({
}
}, [currentDutyLocation, newDutyLocation, isOconusMove, hasDependents, enableUB]);

useEffect(() => {
const fetchData = async () => {
const alaskaEnabled = await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.ENABLE_ALASKA);

const updatedOptions = alaskaEnabled
? ordersTypeOptions
: ordersTypeOptions.filter(
(e) => e.key !== ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS && e.key !== ORDERS_TYPE.STUDENT_TRAVEL,
);

setFilteredOrderTypeOptions(updatedOptions);
};
fetchData();
}, [ordersTypeOptions]);

return (
<Formik initialValues={initialValues} validateOnMount validationSchema={validationSchema} onSubmit={onSubmit}>
{({ values, isValid, isSubmitting, handleSubmit, touched, setFieldValue }) => {
{({ values, isValid, isSubmitting, handleSubmit, handleChange, touched, setFieldValue }) => {
const isRetirementOrSeparation = ['RETIREMENT', 'SEPARATION'].includes(values.ordersType);
if (!values.origin_duty_location && touched.origin_duty_location) originMeta = 'Required';
else originMeta = null;
Expand All @@ -107,17 +125,37 @@ const AddOrdersForm = ({
const handleHasDependentsChange = (e) => {
// Declare a duplicate local scope of the field value
// for the form to prevent state race conditions
const fieldValueHasDependents = e.target.value === 'yes';
setHasDependents(e.target.value === 'yes');
setFieldValue('hasDependents', fieldValueHasDependents ? 'yes' : 'no');
if (fieldValueHasDependents && isOconusMove && enableUB) {
setShowAccompaniedTourField(true);
setShowDependentAgeFields(true);
if (e.target.value === '') {
setFieldValue('hasDependents', '');
} else {
setShowAccompaniedTourField(false);
setShowDependentAgeFields(false);
const fieldValueHasDependents = e.target.value === 'yes';
setHasDependents(e.target.value === 'yes');
setFieldValue('hasDependents', fieldValueHasDependents ? 'yes' : 'no');
if (fieldValueHasDependents && isOconusMove && enableUB) {
setShowAccompaniedTourField(true);
setShowDependentAgeFields(true);
} else {
setShowAccompaniedTourField(false);
setShowDependentAgeFields(false);
}
}
};
const handleOrderTypeChange = (e) => {
const { value } = e.target;
if (value === ORDERS_TYPE.STUDENT_TRAVEL || value === ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS) {
setHasDependentsDisabled(true);
handleHasDependentsChange({ target: { value: 'yes' } });
} else {
setHasDependentsDisabled(false);
if (
prevOrderType === ORDERS_TYPE.STUDENT_TRAVEL ||
prevOrderType === ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS
) {
handleHasDependentsChange({ target: { value: '' } });
}
}
setPrevOrderType(value);
};
return (
<Form className={`${formStyles.form}`}>
<ConnectedFlashMessage />
Expand All @@ -127,8 +165,12 @@ const AddOrdersForm = ({
<DropdownInput
label="Orders type"
name="ordersType"
options={ordersTypeOptions}
options={filteredOrderTypeOptions}
required
onChange={(e) => {
handleChange(e);
handleOrderTypeChange(e);
}}
isDisabled={isSafetyMoveSelected || isBluebarkMoveSelected}
/>
<DatePickerInput name="issueDate" label="Orders date" required />
Expand Down Expand Up @@ -206,6 +248,7 @@ const AddOrdersForm = ({
onChange={(e) => {
handleHasDependentsChange(e);
}}
disabled={isHasDependentsDisabled}
/>
<Field
as={Radio}
Expand All @@ -219,6 +262,7 @@ const AddOrdersForm = ({
onChange={(e) => {
handleHasDependentsChange(e);
}}
disabled={isHasDependentsDisabled}
/>
</div>
</FormGroup>
Expand Down
174 changes: 173 additions & 1 deletion src/components/Office/AddOrdersForm/AddOrdersForm.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Provider } from 'react-redux';
import AddOrdersForm from './AddOrdersForm';

import { dropdownInputOptions } from 'utils/formatters';
import { ORDERS_TYPE_OPTIONS } from 'constants/orders';
import { ORDERS_TYPE, ORDERS_TYPE_OPTIONS } from 'constants/orders';
import { configureStore } from 'shared/store';
import { isBooleanFlagEnabled } from 'utils/featureFlags';

Expand Down Expand Up @@ -126,6 +126,40 @@ describe('CreateMoveCustomerInfo Component', () => {
});
});

it('renders each option for orders type', async () => {
isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true));

const { getByLabelText } = render(
<Provider store={mockStore.store}>
<AddOrdersForm {...testProps} />
</Provider>,
);

const ordersTypeDropdown = getByLabelText('Orders type');
expect(ordersTypeDropdown).toBeInstanceOf(HTMLSelectElement);

await userEvent.selectOptions(ordersTypeDropdown, ORDERS_TYPE.PERMANENT_CHANGE_OF_STATION);
expect(ordersTypeDropdown).toHaveValue(ORDERS_TYPE.PERMANENT_CHANGE_OF_STATION);

await userEvent.selectOptions(ordersTypeDropdown, ORDERS_TYPE.LOCAL_MOVE);
expect(ordersTypeDropdown).toHaveValue(ORDERS_TYPE.LOCAL_MOVE);

await userEvent.selectOptions(ordersTypeDropdown, ORDERS_TYPE.RETIREMENT);
expect(ordersTypeDropdown).toHaveValue(ORDERS_TYPE.RETIREMENT);

await userEvent.selectOptions(ordersTypeDropdown, ORDERS_TYPE.SEPARATION);
expect(ordersTypeDropdown).toHaveValue(ORDERS_TYPE.SEPARATION);

await userEvent.selectOptions(ordersTypeDropdown, ORDERS_TYPE.TEMPORARY_DUTY);
expect(ordersTypeDropdown).toHaveValue(ORDERS_TYPE.TEMPORARY_DUTY);

await userEvent.selectOptions(ordersTypeDropdown, ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS);
expect(ordersTypeDropdown).toHaveValue(ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS);

await userEvent.selectOptions(ordersTypeDropdown, ORDERS_TYPE.STUDENT_TRAVEL);
expect(ordersTypeDropdown).toHaveValue(ORDERS_TYPE.STUDENT_TRAVEL);
});

it('shows an error message if trying to submit an invalid form', async () => {
const { getByRole, findAllByRole, getByLabelText } = render(
<Provider store={mockStore.store}>
Expand Down Expand Up @@ -194,6 +228,144 @@ describe('AddOrdersForm - OCONUS and Accompanied Tour Test', () => {
});
});
});

describe('AddOrdersForm - Student Travel, Early Return of Dependents Test', () => {
it('has dependents is yes and disabled when order type is student travel', async () => {
isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true));

render(
<Provider store={mockStore.store}>
<AddOrdersForm {...testProps} />
</Provider>,
);

await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.STUDENT_TRAVEL);

const hasDependentsYes = screen.getByLabelText('Yes');
const hasDependentsNo = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYes).toBeChecked();
expect(hasDependentsYes).toBeDisabled();
expect(hasDependentsNo).toBeDisabled();
});
});

it('has dependents is yes and disabled when order type is early return', async () => {
isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true));

render(
<Provider store={mockStore.store}>
<AddOrdersForm {...testProps} />
</Provider>,
);

await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS);
const hasDependentsYes = screen.getByLabelText('Yes');
const hasDependentsNo = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYes).toBeChecked();
expect(hasDependentsYes).toBeDisabled();
expect(hasDependentsNo).toBeDisabled();
});
});

it('has dependents becomes disabled and then re-enabled for order type student travel', async () => {
isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true));

render(
<Provider store={mockStore.store}>
<AddOrdersForm {...testProps} />
</Provider>,
);

await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.PERMANENT_CHANGE_OF_STATION);

const hasDependentsYesPermChg = screen.getByLabelText('Yes');
const hasDependentsNoPermChg = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYesPermChg).not.toBeChecked();
expect(hasDependentsYesPermChg).toBeEnabled();
expect(hasDependentsNoPermChg).not.toBeChecked();
expect(hasDependentsNoPermChg).toBeEnabled();
});

// set order type to value that disables and defaults "has dependents"
await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.STUDENT_TRAVEL);

const hasDependentsYesStudent = screen.getByLabelText('Yes');
const hasDependentsNoStudent = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYesStudent).toBeChecked();
expect(hasDependentsYesStudent).toBeDisabled();
expect(hasDependentsNoStudent).toBeDisabled();
});

// set order type to value the re-enables "has dependents"
await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.LOCAL_MOVE);

const hasDependentsYesLocalMove = screen.getByLabelText('Yes');
const hasDependentsNoLocalMove = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYesLocalMove).not.toBeChecked();
expect(hasDependentsYesLocalMove).toBeEnabled();
expect(hasDependentsNoLocalMove).not.toBeChecked();
expect(hasDependentsNoLocalMove).toBeEnabled();
});
});

it('has dependents becomes disabled and then re-enabled for order type early return', async () => {
isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true));

render(
<Provider store={mockStore.store}>
<AddOrdersForm {...testProps} />
</Provider>,
);

await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.PERMANENT_CHANGE_OF_STATION);

const hasDependentsYesPermChg = screen.getByLabelText('Yes');
const hasDependentsNoPermChg = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYesPermChg).not.toBeChecked();
expect(hasDependentsYesPermChg).toBeEnabled();
expect(hasDependentsNoPermChg).not.toBeChecked();
expect(hasDependentsNoPermChg).toBeEnabled();
});

// set order type to value that disables and defaults "has dependents"
await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.EARLY_RETURN_OF_DEPENDENTS);

const hasDependentsYesEarly = screen.getByLabelText('Yes');
const hasDependentsNoEarly = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYesEarly).toBeChecked();
expect(hasDependentsYesEarly).toBeDisabled();
expect(hasDependentsNoEarly).toBeDisabled();
});

// set order type to value the re-enables "has dependents"
await userEvent.selectOptions(screen.getByLabelText('Orders type'), ORDERS_TYPE.LOCAL_MOVE);

const hasDependentsYesLocalMove = screen.getByLabelText('Yes');
const hasDependentsNoLocalMove = screen.getByLabelText('No');

await waitFor(() => {
expect(hasDependentsYesLocalMove).not.toBeChecked();
expect(hasDependentsYesLocalMove).toBeEnabled();
expect(hasDependentsNoLocalMove).not.toBeChecked();
expect(hasDependentsNoLocalMove).toBeEnabled();
});
});
});

describe('AddOrdersForm - Edge Cases and Additional Scenarios', () => {
it('disables orders type when safety move is selected', async () => {
render(
Expand Down
Loading

0 comments on commit b6a54fe

Please sign in to comment.