From 45dc86ae017941d5fd8f9a2a2850a781f922d012 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Wed, 31 Jan 2024 14:25:36 +0000 Subject: [PATCH 1/6] initial commit, began adding data to redux until api endpoint is merged --- .../Multi-Moves/MultiMovesLandingPage.jsx | 36 +++++++++++++++++-- src/sagas/onboarding.js | 13 +++++++ src/services/internalApi.js | 12 +++++++ src/shared/Entities/modules/moves.js | 6 ++++ src/shared/Entities/modules/oktaUser.js | 2 -- src/shared/Entities/reducer.js | 2 ++ src/shared/Entities/schema.js | 8 +++++ 7 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx index 33bc7c01b2e..9038575e5db 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx @@ -21,9 +21,17 @@ import { loadInternalSchema } from 'shared/Swagger/ducks'; import { loadUser } from 'store/auth/actions'; import { initOnboarding } from 'store/onboarding/actions'; import Helper from 'components/Customer/Home/Helper'; +import { customerRoutes } from 'constants/routes'; +import { withContext } from 'shared/AppContext'; +import withRouter from 'utils/routing'; +import requireCustomerState from 'containers/requireCustomerState/requireCustomerState'; +import { selectIsProfileComplete, selectServiceMemberFromLoggedInUser } from 'store/entities/selectors'; -const MultiMovesLandingPage = () => { +const MultiMovesLandingPage = ({ serviceMemberMoves }) => { const [setErrorState] = useState({ hasError: false, error: undefined, info: undefined }); + const navigate = useNavigate(); + console.log('serviceMemberMoves', serviceMemberMoves); + // ! This is just used for testing and viewing different variations of data that MilMove will use // user can add params of ?moveData=PCS, etc to view different views let moves; @@ -146,4 +154,28 @@ const MultiMovesLandingPage = () => { ); }; -export default MultiMovesLandingPage; +MultiMovesLandingPage.defaultProps = { + serviceMember: null, +}; + +const mapStateToProps = (state) => { + const serviceMember = selectServiceMemberFromLoggedInUser(state); + const { serviceMemberMoves } = state.entities; + + return { + isProfileComplete: selectIsProfileComplete(state), + serviceMember, + serviceMemberMoves, + }; +}; + +// in order to avoid setting up proxy server only for storybook, pass in stub function so API requests don't fail +const mergeProps = (stateProps, dispatchProps, ownProps) => ({ + ...stateProps, + ...dispatchProps, + ...ownProps, +}); + +export default withContext( + withRouter(connect(mapStateToProps, mergeProps)(requireCustomerState(MultiMovesLandingPage))), +); diff --git a/src/sagas/onboarding.js b/src/sagas/onboarding.js index f4a4ff0a48c..2f8908b3bff 100644 --- a/src/sagas/onboarding.js +++ b/src/sagas/onboarding.js @@ -11,6 +11,7 @@ import { getLoggedInUser, getMTOShipmentsForMove, createServiceMember as createServiceMemberApi, + getOrdersForServiceMember, } from 'services/internalApi'; import { addEntities } from 'shared/Entities/actions'; @@ -29,6 +30,18 @@ export function* fetchCustomerData() { yield put(addEntities(mtoShipments)); } + // if we have user data, we can load multiple move data + if (user) { + const currentMove = []; + const previousMoves = []; + const { serviceMembers } = user; + const [serviceMemberId] = Object.keys(serviceMembers); + const currentMoveData = yield call(getOrdersForServiceMember, serviceMemberId); + currentMove.push(currentMoveData); + const serviceMemberMoves = { currentMove: currentMoveData, previousMoves }; + yield put(addEntities({ serviceMemberMoves })); + } + return user; } diff --git a/src/services/internalApi.js b/src/services/internalApi.js index 43c65e78bc2..7d1aef9c78e 100644 --- a/src/services/internalApi.js +++ b/src/services/internalApi.js @@ -239,6 +239,18 @@ export async function deleteUpload(uploadId) { } /** MOVES */ +export async function getAllMoves(serviceMemberId) { + return makeInternalRequest( + 'moves.getAllMoves', + { + serviceMemberId, + }, + { + normalize: false, + }, + ); +} + export async function getMove(moveId) { return makeInternalRequest( 'moves.showMove', diff --git a/src/shared/Entities/modules/moves.js b/src/shared/Entities/modules/moves.js index be25b95ffb3..1b65bd243bb 100644 --- a/src/shared/Entities/modules/moves.js +++ b/src/shared/Entities/modules/moves.js @@ -18,6 +18,7 @@ const cancelMoveLabel = 'Moves.CancelMove'; export const loadMoveLabel = 'Moves.loadMove'; export const getMoveDatesSummaryLabel = 'Moves.getMoveDatesSummary'; export const getMoveByLocatorOperation = 'move.getMove'; +export const getAllMovesLabel = 'move.getAllMoves'; export default function reducer(state = {}, action) { switch (action.type) { @@ -32,6 +33,11 @@ export default function reducer(state = {}, action) { } } +export function getAllMoves(serviceMemberId, label = getAllMovesLabel) { + const swaggerTag = 'moves.getAllMoves'; + return swaggerRequest(getClient, swaggerTag, { serviceMemberId }, { label }); +} + export function getMoveByLocator(locator, label = getMoveByLocatorOperation) { return swaggerRequest(getGHCClient, getMoveByLocatorOperation, { locator }, { label }); } diff --git a/src/shared/Entities/modules/oktaUser.js b/src/shared/Entities/modules/oktaUser.js index 8ae9edc6e8c..1ed6c6615db 100644 --- a/src/shared/Entities/modules/oktaUser.js +++ b/src/shared/Entities/modules/oktaUser.js @@ -10,7 +10,5 @@ export function getOktaUser() { // load Okta user export function selectOktaUser(state) { - // console.log('loading from entities', state); - return get(state, `entities.oktaUser`); } diff --git a/src/shared/Entities/reducer.js b/src/shared/Entities/reducer.js index b791602d280..92717f52d73 100644 --- a/src/shared/Entities/reducer.js +++ b/src/shared/Entities/reducer.js @@ -45,6 +45,7 @@ const initialState = { personallyProcuredMoves: {}, mtoShipments: {}, reimbursements: {}, + serviceMemberMoves: {}, signedCertifications: {}, oktaUser: {}, }; @@ -77,5 +78,6 @@ export function entitiesReducer(state = initialState, action) { oktaUser: action.oktaUser || {}, }; } + return state; } diff --git a/src/shared/Entities/schema.js b/src/shared/Entities/schema.js index 72635713ab5..c3b895e74f1 100644 --- a/src/shared/Entities/schema.js +++ b/src/shared/Entities/schema.js @@ -42,6 +42,14 @@ export const move = new schema.Entity('moves', { }); export const moves = new schema.Array(move); +export const currentMove = new schema.Array(move); +export const previousMoves = new schema.Array(move); + +export const multiMoves = new schema.Entity('multiMoves', { + currentMove: currentMove, + previousMoves: previousMoves, +}); + // Orders export const order = new schema.Entity('orders'); From 421d632fe0f310ed6a77f9f00b950ab44596d6cc Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Wed, 31 Jan 2024 22:41:12 +0000 Subject: [PATCH 2/6] changed some values of dashboard due to API object returning different values, updated swagger to allow for move status, need to finish tests --- pkg/gen/internalapi/embedded_spec.go | 8 + pkg/gen/internalmessages/internal_move.go | 17 ++ pkg/handlers/internalapi/moves.go | 1 + pkg/models/move.go | 1 + .../Multi-Moves/MultiMovesLandingPage.jsx | 107 +++++------ .../MultiMovesLandingPage.test.jsx | 167 +++++++++++++++++- .../MultiMovesMoveContainer.jsx | 38 ++-- .../MultiMovesMoveInfoList.jsx | 53 +++++- src/sagas/onboarding.js | 20 +-- src/store/entities/selectors.js | 5 + swagger-def/internal.yaml | 3 + swagger/internal.yaml | 3 + 12 files changed, 325 insertions(+), 98 deletions(-) diff --git a/pkg/gen/internalapi/embedded_spec.go b/pkg/gen/internalapi/embedded_spec.go index e3735537ce7..c86f85a6dac 100644 --- a/pkg/gen/internalapi/embedded_spec.go +++ b/pkg/gen/internalapi/embedded_spec.go @@ -4203,6 +4203,10 @@ func init() { "orders": { "type": "object" }, + "status": { + "type": "string", + "readOnly": true + }, "updatedAt": { "type": "string", "format": "date-time", @@ -12308,6 +12312,10 @@ func init() { "orders": { "type": "object" }, + "status": { + "type": "string", + "readOnly": true + }, "updatedAt": { "type": "string", "format": "date-time", diff --git a/pkg/gen/internalmessages/internal_move.go b/pkg/gen/internalmessages/internal_move.go index 13947c3d8aa..723d1c2b0b9 100644 --- a/pkg/gen/internalmessages/internal_move.go +++ b/pkg/gen/internalmessages/internal_move.go @@ -49,6 +49,10 @@ type InternalMove struct { // orders Orders interface{} `json:"orders,omitempty"` + // status + // Read Only: true + Status string `json:"status,omitempty"` + // updated at // Read Only: true // Format: date-time @@ -170,6 +174,10 @@ func (m *InternalMove) ContextValidate(ctx context.Context, formats strfmt.Regis res = append(res, err) } + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateUpdatedAt(ctx, formats); err != nil { res = append(res, err) } @@ -221,6 +229,15 @@ func (m *InternalMove) contextValidateMtoShipments(ctx context.Context, formats return nil } +func (m *InternalMove) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "status", "body", string(m.Status)); err != nil { + return err + } + + return nil +} + func (m *InternalMove) contextValidateUpdatedAt(ctx context.Context, formats strfmt.Registry) error { if err := validate.ReadOnly(ctx, "updatedAt", "body", strfmt.DateTime(m.UpdatedAt)); err != nil { diff --git a/pkg/handlers/internalapi/moves.go b/pkg/handlers/internalapi/moves.go index 03705f53526..5508aabb389 100644 --- a/pkg/handlers/internalapi/moves.go +++ b/pkg/handlers/internalapi/moves.go @@ -159,6 +159,7 @@ func payloadForInternalMove(storer storage.FileStorer, list models.Moves) []*int CreatedAt: *handlers.FmtDateTime(move.CreatedAt), ETag: eTag, ID: *handlers.FmtUUID(move.ID), + Status: string(move.Status), MtoShipments: *payloadShipments, MoveCode: move.Locator, Orders: move.Orders, diff --git a/pkg/models/move.go b/pkg/models/move.go index 265b3e1c0ad..b8bf7f2ce60 100644 --- a/pkg/models/move.go +++ b/pkg/models/move.go @@ -416,6 +416,7 @@ func FetchMovesByOrderID(db *pop.Connection, orderID uuid.UUID) (Moves, error) { "Orders.UploadedOrders", "Orders.ServiceMember", "Orders.ServiceMember.User", + "Orders.OriginDutyLocation.Address", "Orders.OriginDutyLocation.TransportationOffice", "Orders.OriginDutyLocation.TransportationOffice.Address", "Orders.NewDutyLocation.Address", diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx index 9038575e5db..ea109f8ef24 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx @@ -5,15 +5,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import styles from './MultiMovesLandingPage.module.scss'; import MultiMovesMoveHeader from './MultiMovesMoveHeader/MultiMovesMoveHeader'; import MultiMovesMoveContainer from './MultiMovesMoveContainer/MultiMovesMoveContainer'; -import { - mockMovesPCS, - mockMovesSeparation, - mockMovesRetirement, - mockMovesNoPreviousMoves, - mockMovesNoCurrentMoveWithPreviousMoves, - mockMovesNoCurrentOrPreviousMoves, -} from './MultiMovesTestData'; +import { detectFlags } from 'utils/featureFlags'; import { generatePageTitle } from 'hooks/custom'; import { milmoveLogger } from 'utils/milmoveLog'; import retryPageLoading from 'utils/retryPageLoading'; @@ -25,42 +18,11 @@ import { customerRoutes } from 'constants/routes'; import { withContext } from 'shared/AppContext'; import withRouter from 'utils/routing'; import requireCustomerState from 'containers/requireCustomerState/requireCustomerState'; -import { selectIsProfileComplete, selectServiceMemberFromLoggedInUser } from 'store/entities/selectors'; +import { selectAllMoves, selectIsProfileComplete, selectServiceMemberFromLoggedInUser } from 'store/entities/selectors'; -const MultiMovesLandingPage = ({ serviceMemberMoves }) => { +const MultiMovesLandingPage = ({ serviceMember, serviceMemberMoves }) => { const [setErrorState] = useState({ hasError: false, error: undefined, info: undefined }); const navigate = useNavigate(); - console.log('serviceMemberMoves', serviceMemberMoves); - - // ! This is just used for testing and viewing different variations of data that MilMove will use - // user can add params of ?moveData=PCS, etc to view different views - let moves; - const currentUrl = new URL(window.location.href); - const moveDataSource = currentUrl.searchParams.get('moveData'); - switch (moveDataSource) { - case 'PCS': - moves = mockMovesPCS; - break; - case 'retirement': - moves = mockMovesRetirement; - break; - case 'separation': - moves = mockMovesSeparation; - break; - case 'noPreviousMoves': - moves = mockMovesNoPreviousMoves; - break; - case 'noCurrentMove': - moves = mockMovesNoCurrentMoveWithPreviousMoves; - break; - case 'noMoves': - moves = mockMovesNoCurrentOrPreviousMoves; - break; - default: - moves = mockMovesPCS; - break; - } - // ! end of test data useEffect(() => { const fetchData = async () => { @@ -69,11 +31,6 @@ const MultiMovesLandingPage = ({ serviceMemberMoves }) => { loadUser(); initOnboarding(); document.title = generatePageTitle('MilMove'); - - const script = document.createElement('script'); - script.src = '//rum-static.pingdom.net/pa-6567b05deff3250012000426.js'; - script.async = true; - document.body.appendChild(script); } catch (error) { const { message } = error; milmoveLogger.error({ message, info: null }); @@ -89,21 +46,53 @@ const MultiMovesLandingPage = ({ serviceMemberMoves }) => { fetchData(); }, [setErrorState]); - return ( + const flags = detectFlags(process.env.NODE_ENV, window.location.host, window.location.search); + + // handles logic when user clicks "Create a Move" button + // if they have previous moves, they'll need to validate their profile + // if they do not have previous moves, then they don't need to validate + const handleCreateMoveBtnClick = () => { + if (serviceMemberMoves && serviceMemberMoves.previousMoves && serviceMemberMoves.previousMoves.length !== 0) { + const profileEditPath = customerRoutes.PROFILE_PATH; + navigate(profileEditPath, { state: { needsToVerifyProfile: true } }); + } else { + navigate(customerRoutes.MOVE_HOME_PAGE); + } + }; + + // ! WILL ONLY SHOW IF MULTIMOVE FLAG IS TRUE + return flags.multiMove ? (
-

First Last

+

+ {serviceMember.first_name} {serviceMember.last_name} +

- -

- We can put information at the top here - potentially important contact info or basic instructions on how - to start a move? -

-
+ {serviceMemberMoves && serviceMemberMoves.previousMoves && serviceMemberMoves.previousMoves.length === 0 ? ( + +

+ Select "Create a Move" to get started.
+
+ If you encounter any issues please contact your local Transportation Office or the Help Desk for further + assistance. +

+
+ ) : ( + +

+ Select "Create a Move" to get started.
+
+ Once you have validated your profile, pleasee click the "Validate" button and proceed to + starting your move.
+ If you encounter any issues please contact your local Transportation Office or the Help Desk for further + assistance. +

+
+ )}
- {moves.currentMove.length > 0 ? ( + {serviceMemberMoves && serviceMemberMoves.currentMove && serviceMemberMoves.currentMove.length !== 0 ? ( <>
- +
) : ( @@ -130,13 +119,13 @@ const MultiMovesLandingPage = ({ serviceMemberMoves }) => {
You do not have a current move.
)} - {moves.previousMoves.length > 0 ? ( + {serviceMemberMoves && serviceMemberMoves.previousMoves && serviceMemberMoves.previousMoves.length !== 0 ? ( <>
- +
) : ( @@ -160,7 +149,7 @@ MultiMovesLandingPage.defaultProps = { const mapStateToProps = (state) => { const serviceMember = selectServiceMemberFromLoggedInUser(state); - const { serviceMemberMoves } = state.entities; + const serviceMemberMoves = selectAllMoves(state); return { isProfileComplete: selectIsProfileComplete(state), diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx index e19c56cff35..0af53508496 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx @@ -4,6 +4,8 @@ import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; // For additional matchers like toBeInTheDocument import MultiMovesLandingPage from './MultiMovesLandingPage'; +import { MockProviders } from 'testUtils'; + // Mock external dependencies jest.mock('utils/featureFlags', () => ({ detectFlags: jest.fn(() => ({ multiMove: true })), @@ -21,13 +23,166 @@ jest.mock('shared/Swagger/ducks', () => ({ loadInternalSchema: jest.fn(), })); +const defaultProps = { + serviceMember: { + id: v4(), + first_name: 'Jim', + last_name: 'Bean', + }, + showLoggedInUser: jest.fn(), + isLoggedIn: true, + loggedInUserIsLoading: false, + loggedInUserSuccess: true, + isProfileComplete: true, + serviceMemberMoves: { + currentMove: [ + { + createdAt: '2024-01-31T16:29:53.290Z', + eTag: 'MjAyNC0wMS0zMVQxNjoyOTo1My4yOTA0OTRa', + id: '9211d4e2-5b92-42bb-9758-7ac1f329a8d6', + moveCode: 'YJ9M34', + orders: { + id: '40475a80-5340-4722-88d1-3cc9764414d6', + created_at: '2024-01-31T16:29:53.285657Z', + updated_at: '2024-01-31T16:29:53.285657Z', + service_member_id: '6686d242-e7af-4a06-afd7-7be423bfca2d', + issue_date: '2024-01-31T00:00:00Z', + report_by_date: '2024-02-09T00:00:00Z', + orders_type: 'PERMANENT_CHANGE_OF_STATION', + orders_type_detail: null, + has_dependents: false, + spouse_has_pro_gear: false, + OriginDutyLocation: { + id: '2d6eab7d-1a21-4f29-933e-ee8fa7dbc314', + created_at: '2024-01-26T16:46:34.047004Z', + updated_at: '2024-01-26T16:46:34.047004Z', + name: 'Tinker AFB, OK 73145', + affiliation: 'AIR_FORCE', + address_id: '7e3ea97c-da9f-4fa1-8a11-87063c857635', + Address: { + id: '7e3ea97c-da9f-4fa1-8a11-87063c857635', + created_at: '2024-01-26T16:46:34.047004Z', + updated_at: '2024-01-26T16:46:34.047004Z', + street_address_1: 'n/a', + street_address_2: null, + street_address_3: null, + city: 'Tinker AFB', + state: 'OK', + postal_code: '73145', + country: 'United States', + }, + transportation_office_id: '7876373d-57e4-4cde-b11f-c26a8feee9e8', + TransportationOffice: { + id: '7876373d-57e4-4cde-b11f-c26a8feee9e8', + shipping_office_id: 'c2c440ae-5394-4483-84fb-f872e32126bb', + ShippingOffice: null, + name: 'PPPO Tinker AFB - USAF', + Address: { + id: '410b18bc-b270-4b52-9211-532fffc6f59e', + created_at: '2018-05-28T14:27:40.597383Z', + updated_at: '2018-05-28T14:27:40.597383Z', + street_address_1: '7330 Century Blvd', + street_address_2: 'Bldg 469', + street_address_3: null, + city: 'Tinker AFB', + state: 'OK', + postal_code: '73145', + country: 'United States', + }, + address_id: '410b18bc-b270-4b52-9211-532fffc6f59e', + latitude: 35.429035, + longitude: -97.39955, + PhoneLines: null, + Emails: null, + hours: 'Monday – Friday: 0715 – 1600; Limited Service from 1130-1230', + services: 'Walk-In Help; Briefings; Appointments; QA Inspections', + note: null, + gbloc: 'HAFC', + created_at: '2018-05-28T14:27:40.605679Z', + updated_at: '2018-05-28T14:27:40.60568Z', + provides_ppm_closeout: true, + }, + provides_services_counseling: true, + }, + origin_duty_location_id: '2d6eab7d-1a21-4f29-933e-ee8fa7dbc314', + new_duty_location_id: '5c182566-0e6e-46f2-9eef-f07963783575', + NewDutyLocation: { + id: '5c182566-0e6e-46f2-9eef-f07963783575', + created_at: '2024-01-26T16:46:34.047004Z', + updated_at: '2024-01-26T16:46:34.047004Z', + name: 'Fort Sill, OK 73503', + affiliation: 'ARMY', + address_id: 'ed62ba0b-a3cb-47ac-81ae-5b27ade4592b', + Address: { + id: 'ed62ba0b-a3cb-47ac-81ae-5b27ade4592b', + created_at: '2024-01-26T16:46:34.047004Z', + updated_at: '2024-01-26T16:46:34.047004Z', + street_address_1: 'n/a', + street_address_2: null, + street_address_3: null, + city: 'Fort Sill', + state: 'OK', + postal_code: '73503', + country: 'United States', + }, + transportation_office_id: '7f5b64b8-979c-4cbd-890b-bffd6fdf56d9', + TransportationOffice: { + id: '7f5b64b8-979c-4cbd-890b-bffd6fdf56d9', + shipping_office_id: '5a3388e1-6d46-4639-ac8f-a8937dc26938', + ShippingOffice: null, + name: 'PPPO Fort Sill - USA', + Address: { + id: 'abbc0af9-2394-4e36-be84-811ad8f6060b', + created_at: '2018-05-28T14:27:35.538742Z', + updated_at: '2018-05-28T14:27:35.538743Z', + street_address_1: '4700 Mow Way Rd', + street_address_2: 'Room 110', + street_address_3: null, + city: 'Fort Sill', + state: 'OK', + postal_code: '73503', + country: 'United States', + }, + address_id: 'abbc0af9-2394-4e36-be84-811ad8f6060b', + latitude: 34.647964, + longitude: -98.41231, + PhoneLines: null, + Emails: null, + hours: 'Monday - Friday 0830-1530; Sat/Sun/Federal Holidays closed', + services: 'Walk-In Help; Appointments; QA Inspections; Appointments 06 and above', + note: null, + gbloc: 'JEAT', + created_at: '2018-05-28T14:27:35.547257Z', + updated_at: '2018-05-28T14:27:35.547257Z', + provides_ppm_closeout: true, + }, + provides_services_counseling: true, + }, + uploaded_orders_id: 'f779f6a2-48e2-47fe-87be-d93e8aa711fe', + status: 'DRAFT', + grade: 'E_7', + Entitlement: null, + entitlement_id: 'a1bf0035-4f28-45b8-af1a-556848d29e44', + UploadedAmendedOrders: null, + uploaded_amended_orders_id: null, + amended_orders_acknowledged_at: null, + origin_duty_location_gbloc: 'HAFC', + }, + status: 'DRAFT', + updatedAt: '0001-01-01T00:00:00.000Z', + }, + ], + previousMoves: [], + }, +}; + describe('MultiMovesLandingPage', () => { it('renders the component with retirement moves', () => { render(); // Check for specific elements expect(screen.getByTestId('customerHeader')).toBeInTheDocument(); - expect(screen.getByText('First Last')).toBeInTheDocument(); + expect(screen.getByTestId('welcomeHeader')).toBeInTheDocument(); expect(screen.getByText('Welcome to MilMove!')).toBeInTheDocument(); expect(screen.getByText('Create a Move')).toBeInTheDocument(); @@ -37,11 +192,17 @@ describe('MultiMovesLandingPage', () => { }); it('renders move data correctly', () => { - render(); + render( + + + , + ); + expect(screen.getByText('Jim Bean')).toBeInTheDocument(); + expect(screen.getByText('#YJ9M34')).toBeInTheDocument(); expect(screen.getByTestId('currentMoveHeader')).toBeInTheDocument(); expect(screen.getByTestId('currentMoveContainer')).toBeInTheDocument(); expect(screen.getByTestId('prevMovesHeader')).toBeInTheDocument(); - expect(screen.getByTestId('prevMovesContainer')).toBeInTheDocument(); + expect(screen.getByText('You have no previous moves.')).toBeInTheDocument(); }); }); diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx index 6c523feeded..e1ff51c889c 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx @@ -96,24 +96,28 @@ const MultiMovesMoveContainer = ({ moves }) => {

Shipments

- {m.mtoShipments.map((s, sIndex) => ( - -
- -
-
-

{generateShipmentTypeTitle(s.shipmentType)}

-
#{m.moveCode}
+ {m.mtoShipments && m.mtoShipments.length > 0 ? ( + m.mtoShipments.map((s, sIndex) => ( + +
+ +
+
+

{generateShipmentTypeTitle(s.shipmentType)}

+
#{m.moveCode}
+
-
- -
- - ))} + +
+ + )) + ) : ( +
No shipments in move yet.
+ )}
)}
diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx index 53bfb959e37..23bf245d0c5 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx @@ -3,7 +3,7 @@ import React from 'react'; import styles from './MultiMovesMoveInfoList.module.scss'; import descriptionListStyles from 'styles/descriptionList.module.scss'; -import { formatAddress } from 'utils/shipmentDisplay'; +import { formatDateForDatePicker } from 'shared/dates'; const MultiMovesMoveInfoList = ({ move }) => { const { orders } = move; @@ -19,6 +19,17 @@ const MultiMovesMoveInfoList = ({ move }) => { return 'Report by Date'; }; + // function that determines label based on order type + const getOrdersTypeLabel = (ordersType) => { + if (ordersType === 'SEPARATION') { + return 'Separation'; + } + if (ordersType === 'RETIREMENT') { + return 'Retirement'; + } + return 'Permanent Change of Station'; + }; + // destination duty location label will differ based on order type const getDestinationDutyLocationLabel = (ordersType) => { if (ordersType === 'SEPARATION') { @@ -30,6 +41,36 @@ const MultiMovesMoveInfoList = ({ move }) => { return 'Destination Duty Location'; }; + const toCamelCase = (str) => { + return str.replace(/_([a-z])/g, (match, letter) => letter.toUpperCase()); + }; + + const formatAddress = (address) => { + const camelCaseAddress = Object.keys(address).reduce((acc, key) => { + acc[toCamelCase(key)] = address[key]; + return acc; + }, {}); + + const { streetAddress1, streetAddress2, streetAddress3, city, state, postalCode, id } = camelCaseAddress; + + // Check for empty UUID + const isIdEmpty = id === '00000000-0000-0000-0000-000000000000'; + + // Check for null values and empty UUID + if (isIdEmpty) { + return '-'; + } + + return ( + <> + {streetAddress1 && <>{streetAddress1}, } + {streetAddress2 && <>{streetAddress2}, } + {streetAddress3 && <>{streetAddress3}, } + {city ? `${city}, ${state} ${postalCode}` : postalCode} + + ); + }; + return (
@@ -41,27 +82,27 @@ const MultiMovesMoveInfoList = ({ move }) => {
Orders Issue Date
-
{orders.date_issued || '-'}
+
{formatDateForDatePicker(orders.issue_date) || '-'}
Orders Type
-
{orders.ordersType || '-'}
+
{getOrdersTypeLabel(orders.orders_type) || '-'}
{getReportByLabel(orders.ordersType)}
-
{orders.reportByDate || '-'}
+
{formatDateForDatePicker(orders.report_by_date) || '-'}
Current Duty Location
-
{formatAddress(orders.originDutyLocation.address) || '-'}
+
{formatAddress(orders.OriginDutyLocation.Address) || '-'}
{getDestinationDutyLocationLabel(orders.ordersType)}
-
{formatAddress(orders.destinationDutyLocation.address) || '-'}
+
{formatAddress(orders.NewDutyLocation.Address) || '-'}
diff --git a/src/sagas/onboarding.js b/src/sagas/onboarding.js index 2f8908b3bff..6b862d2bcbc 100644 --- a/src/sagas/onboarding.js +++ b/src/sagas/onboarding.js @@ -11,7 +11,7 @@ import { getLoggedInUser, getMTOShipmentsForMove, createServiceMember as createServiceMemberApi, - getOrdersForServiceMember, + getAllMoves, } from 'services/internalApi'; import { addEntities } from 'shared/Entities/actions'; @@ -20,7 +20,6 @@ export function* fetchCustomerData() { const user = yield call(getLoggedInUser); yield put(addEntities(user)); - // TODO - fork/spawn additional API calls // Load MTO shipments if there is a move const { moves } = user; if (moves && Object.keys(moves).length > 0) { @@ -30,17 +29,12 @@ export function* fetchCustomerData() { yield put(addEntities(mtoShipments)); } - // if we have user data, we can load multiple move data - if (user) { - const currentMove = []; - const previousMoves = []; - const { serviceMembers } = user; - const [serviceMemberId] = Object.keys(serviceMembers); - const currentMoveData = yield call(getOrdersForServiceMember, serviceMemberId); - currentMove.push(currentMoveData); - const serviceMemberMoves = { currentMove: currentMoveData, previousMoves }; - yield put(addEntities({ serviceMemberMoves })); - } + // loading serviceMemberMoves for the user + const { serviceMembers } = user; + const key = Object.keys(serviceMembers)[0]; + const serviceMemberId = serviceMembers[key].id; + const allMoves = yield call(getAllMoves, serviceMemberId); + yield put(addEntities({ serviceMemberMoves: allMoves })); return user; } diff --git a/src/store/entities/selectors.js b/src/store/entities/selectors.js index fa12c58ed03..60a2057fe20 100644 --- a/src/store/entities/selectors.js +++ b/src/store/entities/selectors.js @@ -145,6 +145,11 @@ export const selectCurrentMove = (state) => { return activeMove || moves[0] || null; }; +export const selectAllMoves = (state) => { + if (state.entities.serviceMemberMoves) return state.entities.serviceMemberMoves; + return { currentMove: [], previousMoves: [] }; +}; + export const selectMoveIsApproved = createSelector(selectCurrentMove, (move) => move?.status === 'APPROVED'); export const selectMoveIsInDraft = createSelector(selectCurrentMove, (move) => move?.status === MOVE_STATUSES.DRAFT); diff --git a/swagger-def/internal.yaml b/swagger-def/internal.yaml index fb222c631b8..28d89f05997 100644 --- a/swagger-def/internal.yaml +++ b/swagger-def/internal.yaml @@ -2411,6 +2411,9 @@ definitions: type: string orders: type: object + status: + type: string + readOnly: true updatedAt: format: date-time type: string diff --git a/swagger/internal.yaml b/swagger/internal.yaml index e68fb98f2a2..dedb987c234 100644 --- a/swagger/internal.yaml +++ b/swagger/internal.yaml @@ -2444,6 +2444,9 @@ definitions: type: string orders: type: object + status: + type: string + readOnly: true updatedAt: format: date-time type: string From ae1bd4b7114a99d5beef5215dc1645660062a8cf Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Fri, 2 Feb 2024 14:52:00 +0000 Subject: [PATCH 3/6] updated tests to pass --- .../MultiMovesInfoList.test.jsx | 60 ++++++------ .../MultiMovesMoveInfoList.jsx | 7 +- .../MyMove/Multi-Moves/MultiMovesTestData.js | 96 +++++++++---------- src/sagas/onboarding.test.js | 52 ++++++++++ 4 files changed, 134 insertions(+), 81 deletions(-) diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx index 0fd14653ba2..e8be89ef030 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx @@ -8,12 +8,12 @@ describe('MultiMovesMoveInfoList', () => { const mockMoveSeparation = { status: 'DRAFT', orders: { - date_issued: '2022-01-01', - ordersType: 'SEPARATION', - reportByDate: '2022-02-01', - originDutyLocation: { + issue_date: '2022-01-01', + orders_type: 'SEPARATION', + report_by_date: '2022-02-01', + OriginDutyLocation: { name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -23,9 +23,9 @@ describe('MultiMovesMoveInfoList', () => { country: 'USA', }, }, - destinationDutyLocation: { + NewDutyLocation: { name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -41,12 +41,12 @@ describe('MultiMovesMoveInfoList', () => { const mockMoveRetirement = { status: 'DRAFT', orders: { - date_issued: '2022-01-01', - ordersType: 'RETIREMENT', - reportByDate: '2022-02-01', - originDutyLocation: { + issue_date: '2022-01-01', + orders_type: 'RETIREMENT', + report_by_date: '2022-02-01', + OriginDutyLocation: { name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -56,9 +56,9 @@ describe('MultiMovesMoveInfoList', () => { country: 'USA', }, }, - destinationDutyLocation: { + NewDutyLocation: { name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -74,12 +74,12 @@ describe('MultiMovesMoveInfoList', () => { const mockMovePCS = { status: 'DRAFT', orders: { - date_issued: '2022-01-01', - ordersType: 'PERMANENT_CHANGE_OF_DUTY_STATION', - reportByDate: '2022-02-01', - originDutyLocation: { + issue_date: '2022-01-01', + orders_type: 'PERMANENT_CHANGE_OF_DUTY_STATION', + report_by_date: '2022-02-01', + OriginDutyLocation: { name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -89,9 +89,9 @@ describe('MultiMovesMoveInfoList', () => { country: 'USA', }, }, - destinationDutyLocation: { + NewDutyLocation: { name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -111,13 +111,13 @@ describe('MultiMovesMoveInfoList', () => { expect(getByText('DRAFT')).toBeInTheDocument(); expect(getByText('Orders Issue Date')).toBeInTheDocument(); - expect(getByText('2022-01-01')).toBeInTheDocument(); + expect(getByText('01 Jan 2022')).toBeInTheDocument(); expect(getByText('Orders Type')).toBeInTheDocument(); - expect(getByText('SEPARATION')).toBeInTheDocument(); + expect(getByText('Separation')).toBeInTheDocument(); expect(getByText('Separation Date')).toBeInTheDocument(); - expect(getByText('2022-02-01')).toBeInTheDocument(); + expect(getByText('01 Feb 2022')).toBeInTheDocument(); expect(getByText('Current Duty Location')).toBeInTheDocument(); expect(getByText('HOR or PLEAD')).toBeInTheDocument(); @@ -130,13 +130,13 @@ describe('MultiMovesMoveInfoList', () => { expect(getByText('DRAFT')).toBeInTheDocument(); expect(getByText('Orders Issue Date')).toBeInTheDocument(); - expect(getByText('2022-01-01')).toBeInTheDocument(); + expect(getByText('01 Jan 2022')).toBeInTheDocument(); expect(getByText('Orders Type')).toBeInTheDocument(); - expect(getByText('RETIREMENT')).toBeInTheDocument(); + expect(getByText('Retirement')).toBeInTheDocument(); expect(getByText('Retirement Date')).toBeInTheDocument(); - expect(getByText('2022-02-01')).toBeInTheDocument(); + expect(getByText('01 Feb 2022')).toBeInTheDocument(); expect(getByText('Current Duty Location')).toBeInTheDocument(); expect(getByText('HOR, HOS, or PLEAD')).toBeInTheDocument(); @@ -149,13 +149,13 @@ describe('MultiMovesMoveInfoList', () => { expect(getByText('DRAFT')).toBeInTheDocument(); expect(getByText('Orders Issue Date')).toBeInTheDocument(); - expect(getByText('2022-01-01')).toBeInTheDocument(); + expect(getByText('01 Jan 2022')).toBeInTheDocument(); expect(getByText('Orders Type')).toBeInTheDocument(); - expect(getByText('PERMANENT_CHANGE_OF_DUTY_STATION')).toBeInTheDocument(); + expect(getByText('Permanent Change of Station')).toBeInTheDocument(); expect(getByText('Report by Date')).toBeInTheDocument(); - expect(getByText('2022-02-01')).toBeInTheDocument(); + expect(getByText('01 Feb 2022')).toBeInTheDocument(); expect(getByText('Current Duty Location')).toBeInTheDocument(); diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx index 23bf245d0c5..90b205f9d59 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesMoveInfoList.jsx @@ -41,6 +41,7 @@ const MultiMovesMoveInfoList = ({ move }) => { return 'Destination Duty Location'; }; + // converts return from API to camelCase to avoid linter errors const toCamelCase = (str) => { return str.replace(/_([a-z])/g, (match, letter) => letter.toUpperCase()); }; @@ -53,7 +54,7 @@ const MultiMovesMoveInfoList = ({ move }) => { const { streetAddress1, streetAddress2, streetAddress3, city, state, postalCode, id } = camelCaseAddress; - // Check for empty UUID + // Check for empty UUID (no address provided) const isIdEmpty = id === '00000000-0000-0000-0000-000000000000'; // Check for null values and empty UUID @@ -91,7 +92,7 @@ const MultiMovesMoveInfoList = ({ move }) => {
-
{getReportByLabel(orders.ordersType)}
+
{getReportByLabel(orders.orders_type)}
{formatDateForDatePicker(orders.report_by_date) || '-'}
@@ -101,7 +102,7 @@ const MultiMovesMoveInfoList = ({ move }) => {
-
{getDestinationDutyLocationLabel(orders.ordersType)}
+
{getDestinationDutyLocationLabel(orders.orders_type)}
{formatAddress(orders.NewDutyLocation.Address) || '-'}
diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesTestData.js b/src/pages/MyMove/Multi-Moves/MultiMovesTestData.js index e726b3fd346..e02213f3620 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesTestData.js +++ b/src/pages/MyMove/Multi-Moves/MultiMovesTestData.js @@ -7,10 +7,10 @@ export const mockMovesPCS = { status: 'DRAFT', orders: { id: 'testOrder1', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -20,10 +20,10 @@ export const mockMovesPCS = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -93,10 +93,10 @@ export const mockMovesPCS = { status: 'APPROVED', orders: { id: 'testOrder2', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -106,10 +106,10 @@ export const mockMovesPCS = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -177,10 +177,10 @@ export const mockMovesPCS = { status: 'APPROVED', orders: { id: 'testOrder3', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', @@ -190,10 +190,10 @@ export const mockMovesPCS = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', @@ -266,10 +266,10 @@ export const mockMovesRetirement = { status: 'SUBMITTED', orders: { id: 'testOrder1', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -279,10 +279,10 @@ export const mockMovesRetirement = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -352,10 +352,10 @@ export const mockMovesRetirement = { status: 'APPROVED', orders: { id: 'testOrder2', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -365,10 +365,10 @@ export const mockMovesRetirement = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -436,10 +436,10 @@ export const mockMovesRetirement = { status: 'APPROVED', orders: { id: 'testOrder3', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', @@ -449,10 +449,10 @@ export const mockMovesRetirement = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', @@ -525,10 +525,10 @@ export const mockMovesSeparation = { status: 'DRAFT', orders: { id: 'testOrder1', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -538,10 +538,10 @@ export const mockMovesSeparation = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -611,10 +611,10 @@ export const mockMovesSeparation = { status: 'APPROVED', orders: { id: 'testOrder2', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -624,10 +624,10 @@ export const mockMovesSeparation = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -695,10 +695,10 @@ export const mockMovesSeparation = { status: 'APPROVED', orders: { id: 'testOrder3', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', @@ -708,10 +708,10 @@ export const mockMovesSeparation = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', @@ -784,10 +784,10 @@ export const mockMovesNoPreviousMoves = { status: 'DRAFT', orders: { id: 'testOrder1', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -797,10 +797,10 @@ export const mockMovesNoPreviousMoves = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL1', name: 'Fort Bragg North Station', - address: { + Address: { streetAddress1: '123 Main Ave', streetAddress2: 'Apartment 9000', streetAddress3: '', @@ -875,10 +875,10 @@ export const mockMovesNoCurrentMoveWithPreviousMoves = { status: 'APPROVED', orders: { id: 'testOrder2', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -888,10 +888,10 @@ export const mockMovesNoCurrentMoveWithPreviousMoves = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL2', name: 'Fort Bragg South Station', - address: { + Address: { streetAddress1: '456 Oak St', streetAddress2: 'Apartment 8000', streetAddress3: '', @@ -959,10 +959,10 @@ export const mockMovesNoCurrentMoveWithPreviousMoves = { status: 'APPROVED', orders: { id: 'testOrder3', - destinationDutyLocation: { + NewDutyLocation: { id: 'testDDL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', @@ -972,10 +972,10 @@ export const mockMovesNoCurrentMoveWithPreviousMoves = { country: 'USA', }, }, - originDutyLocation: { + OriginDutyLocation: { id: 'testODL3', name: 'Fort Bragg East Station', - address: { + Address: { streetAddress1: '789 Pine Ave', streetAddress2: 'Apartment 7000', streetAddress3: '', diff --git a/src/sagas/onboarding.test.js b/src/sagas/onboarding.test.js index 988fc5ace2a..edfd14a86f5 100644 --- a/src/sagas/onboarding.test.js +++ b/src/sagas/onboarding.test.js @@ -19,6 +19,7 @@ import { getLoggedInUser, createServiceMember as createServiceMemberApi, getMTOShipmentsForMove, + getAllMoves, } from 'services/internalApi'; import { addEntities } from 'shared/Entities/actions'; @@ -53,6 +54,15 @@ describe('fetchCustomerData', () => { email: 'testuser@example.com', }, }, + serviceMembers: { + serviceMemberId: { + id: 'serviceMemberId', + }, + }, + }; + const mockMultipleMoveResponseData = { + currentMove: [], + previousMoves: [], }; it('makes an API call to request the logged in user', () => { @@ -63,6 +73,20 @@ describe('fetchCustomerData', () => { expect(generator.next(mockResponseData).value).toEqual(put(addEntities(mockResponseData))); }); + it('makes an API call to request multiple moves', () => { + expect(generator.next().value).toEqual(call(getAllMoves, 'serviceMemberId')); + }); + + it('stores the multiple move data in entities', () => { + expect(generator.next(mockMultipleMoveResponseData).value).toEqual( + put( + addEntities({ + serviceMemberMoves: mockMultipleMoveResponseData, + }), + ), + ); + }); + it('yields the user data to the caller', () => { expect(generator.next().value).toEqual(mockResponseData); }); @@ -82,11 +106,20 @@ describe('fetchCustomerData', () => { email: 'testuser@example.com', }, }, + serviceMembers: { + serviceMemberId: { + id: 'serviceMemberId', + }, + }, moves: { testMoveId: { id: 'testMoveId', }, }, + serviceMemberMoves: { + currentMove: [], + previousMoves: [], + }, }; const mockMTOResponseData = { @@ -97,6 +130,11 @@ describe('fetchCustomerData', () => { }, }; + const mockMultipleMoveResponseData = { + currentMove: [], + previousMoves: [], + }; + it('makes an API call to request the logged in user', () => { expect(generator.next().value).toEqual(call(getLoggedInUser)); }); @@ -113,6 +151,20 @@ describe('fetchCustomerData', () => { expect(generator.next(mockMTOResponseData).value).toEqual(put(addEntities(mockMTOResponseData))); }); + it('makes an API call to request multiple moves', () => { + expect(generator.next().value).toEqual(call(getAllMoves, 'serviceMemberId')); + }); + + it('stores the multiple move data in entities', () => { + expect(generator.next(mockMultipleMoveResponseData).value).toEqual( + put( + addEntities({ + serviceMemberMoves: mockMultipleMoveResponseData, + }), + ), + ); + }); + it('yields the user data to the caller', () => { expect(generator.next().value).toEqual(mockResponseData); }); From 73e2c748052a522fa9a679c59006fa984c49d689 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 22 Feb 2024 18:07:23 +0000 Subject: [PATCH 4/6] resolving conflicts --- .../MyMove/Multi-Moves/MultiMovesLandingPage.jsx | 6 ++++-- .../Multi-Moves/MultiMovesLandingPage.test.jsx | 12 +++++++++--- .../MultiMovesMoveContainer.jsx | 16 +++++++++++++++- .../MultiMovesInfoList.test.jsx | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx index ea109f8ef24..e0bd7b625b3 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.jsx @@ -1,6 +1,8 @@ import React, { useEffect, useState } from 'react'; import { Button } from '@trussworks/react-uswds'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { useNavigate } from 'react-router'; +import { connect } from 'react-redux'; import styles from './MultiMovesLandingPage.module.scss'; import MultiMovesMoveHeader from './MultiMovesMoveHeader/MultiMovesMoveHeader'; @@ -94,7 +96,7 @@ const MultiMovesLandingPage = ({ serviceMember, serviceMemberMoves }) => { )}
-
- ); + ) : null; }; MultiMovesLandingPage.defaultProps = { diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx index 0af53508496..8a685fde18c 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesLandingPage.test.jsx @@ -1,7 +1,9 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; +import { v4 } from 'uuid'; + +import '@testing-library/jest-dom/extend-expect'; -import '@testing-library/jest-dom/extend-expect'; // For additional matchers like toBeInTheDocument import MultiMovesLandingPage from './MultiMovesLandingPage'; import { MockProviders } from 'testUtils'; @@ -177,8 +179,12 @@ const defaultProps = { }; describe('MultiMovesLandingPage', () => { - it('renders the component with retirement moves', () => { - render(); + it('renders the component with moves', () => { + render( + + + , + ); // Check for specific elements expect(screen.getByTestId('customerHeader')).toBeInTheDocument(); diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx index e1ff51c889c..022c5a827ac 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.jsx @@ -2,6 +2,7 @@ import React, { useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import classnames from 'classnames'; import { Button } from '@trussworks/react-uswds'; +import { useNavigate } from 'react-router'; import MultiMovesMoveInfoList from '../MultiMovesMoveInfoList/MultiMovesMoveInfoList'; import ButtonDropdownMenu from '../../../../components/ButtonDropdownMenu/ButtonDropdownMenu'; @@ -9,9 +10,11 @@ import ButtonDropdownMenu from '../../../../components/ButtonDropdownMenu/Button import styles from './MultiMovesMoveContainer.module.scss'; import ShipmentContainer from 'components/Office/ShipmentContainer/ShipmentContainer'; +import { customerRoutes } from 'constants/routes'; const MultiMovesMoveContainer = ({ moves }) => { const [expandedMoves, setExpandedMoves] = useState({}); + const navigate = useNavigate(); // this expands the moves when the arrow is clicked const handleExpandClick = (index) => { @@ -63,13 +66,24 @@ const MultiMovesMoveContainer = ({ moves }) => { return 'Shipment'; }; + // sends user to the move page when clicking "Go to Move" btn + const handleGoToMoveClick = () => { + navigate(customerRoutes.MOVE_HOME_PAGE); + }; + const moveList = moves.map((m, index) => (

#{m.moveCode}

{m.status !== 'APPROVED' ? ( - ) : ( diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx index e8be89ef030..df800ea5369 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveInfoList/MultiMovesInfoList.test.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; // For expect assertions +import '@testing-library/jest-dom/extend-expect'; import MultiMovesMoveInfoList from './MultiMovesMoveInfoList'; From 08321bf5477b7e74f26e34bd7bbcdf93540f0590 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 22 Feb 2024 19:03:25 +0000 Subject: [PATCH 5/6] updated tests --- .../MultiMovesMoveContainer.test.jsx | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.test.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.test.jsx index d5a5d4555dc..f8755028ba1 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.test.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.test.jsx @@ -6,12 +6,18 @@ import { mockMovesPCS } from '../MultiMovesTestData'; import MultiMovesMoveContainer from './MultiMovesMoveContainer'; +import { MockProviders } from 'testUtils'; + describe('MultiMovesMoveContainer', () => { const mockCurrentMoves = mockMovesPCS.currentMove; const mockPreviousMoves = mockMovesPCS.previousMoves; it('renders current move list correctly', () => { - render(); + render( + + + , + ); expect(screen.getByTestId('move-info-container')).toBeInTheDocument(); expect(screen.getByText('#MOVECO')).toBeInTheDocument(); @@ -19,7 +25,11 @@ describe('MultiMovesMoveContainer', () => { }); it('renders previous move list correctly', () => { - render(); + render( + + + , + ); expect(screen.queryByText('#SAMPLE')).toBeInTheDocument(); expect(screen.queryByText('#EXAMPL')).toBeInTheDocument(); @@ -27,7 +37,11 @@ describe('MultiMovesMoveContainer', () => { }); it('expands and collapses moves correctly', () => { - render(); + render( + + + , + ); // Initially, the move details should not be visible expect(screen.queryByText('Shipment')).not.toBeInTheDocument(); From 834d27523d3795714e47530145ceb68b5751ada5 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 22 Feb 2024 19:38:38 +0000 Subject: [PATCH 6/6] updating forgotten about storybooks --- .../MultiMovesMoveContainer.stories.jsx | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.stories.jsx b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.stories.jsx index aa8d532ac87..aa59e8da8ac 100644 --- a/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.stories.jsx +++ b/src/pages/MyMove/Multi-Moves/MultiMovesMoveContainer/MultiMovesMoveContainer.stories.jsx @@ -4,18 +4,44 @@ import { mockMovesPCS, mockMovesRetirement, mockMovesSeparation } from '../Multi import MultiMovesMoveContainer from './MultiMovesMoveContainer'; +import { MockProviders } from 'testUtils'; + export default { title: 'Customer Components / MultiMovesContainer', }; -export const PCSCurrentMove = () => ; - -export const PCSPreviousMoves = () => ; - -export const RetirementCurrentMove = () => ; - -export const RetirementPreviousMoves = () => ; - -export const SeparationCurrentMove = () => ; - -export const SeparationPreviousMoves = () => ; +export const PCSCurrentMove = () => ( + + + +); + +export const PCSPreviousMoves = () => ( + + + +); + +export const RetirementCurrentMove = () => ( + + + +); + +export const RetirementPreviousMoves = () => ( + + + +); + +export const SeparationCurrentMove = () => ( + + + +); + +export const SeparationPreviousMoves = () => ( + + + +);