Skip to content

Commit

Permalink
Merge pull request #14280 from transcom/B-19531-Prime-Error
Browse files Browse the repository at this point in the history
B 19531 prime error
  • Loading branch information
r-mettler authored Nov 26, 2024
2 parents e609ef0 + 672e497 commit ea6139e
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 14 deletions.
6 changes: 6 additions & 0 deletions pkg/handlers/primeapiv2/mto_shipment.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ func (h CreateMTOShipmentHandler) Handle(params mtoshipmentops.CreateMTOShipment
case apperror.NotFoundError:
return mtoshipmentops.NewCreateMTOShipmentNotFound().WithPayload(
payloads.ClientError(handlers.NotFoundMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.EventError:
return mtoshipmentops.NewUpdateMTOShipmentBadRequest().WithPayload(
payloads.ClientError(handlers.InternalServerErrMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.InvalidInputError:
return mtoshipmentops.NewCreateMTOShipmentUnprocessableEntity().WithPayload(
payloads.ValidationError(err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest), e.ValidationErrors)), err
Expand Down Expand Up @@ -206,6 +209,9 @@ func (h UpdateMTOShipmentHandler) Handle(params mtoshipmentops.UpdateMTOShipment
case apperror.NotFoundError:
return mtoshipmentops.NewUpdateMTOShipmentNotFound().WithPayload(
payloads.ClientError(handlers.NotFoundMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.EventError:
return mtoshipmentops.NewUpdateMTOShipmentBadRequest().WithPayload(
payloads.ClientError(handlers.InternalServerErrMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.InvalidInputError:
payload := payloads.ValidationError(err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest), e.ValidationErrors)
return mtoshipmentops.NewUpdateMTOShipmentUnprocessableEntity().WithPayload(payload), err
Expand Down
36 changes: 36 additions & 0 deletions pkg/handlers/primeapiv2/mto_shipment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,42 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() {
suite.Contains(*typedResponse.Payload.Detail, unavailableMove.ID.String())
})

suite.Run("POST failure - 500 - App Event Internal DTOD Server Error", func() {
// Under Test: CreateMTOShipmentHandler
// Setup: Create a shipment with DTOD outage simulated or bad zip
// Expected: 500 Internal Server Error returned

handler, move := setupTestData(false)
req := httptest.NewRequest("POST", "/mto-shipments", nil)
handler.ShipmentCreator = &mockCreator

err := apperror.EventError{}

mockCreator.On("CreateShipment",
mock.AnythingOfType("*appcontext.appContext"),
mock.Anything,
).Return(nil, nil, err)

params := mtoshipmentops.CreateMTOShipmentParams{
HTTPRequest: req,
Body: &primev2messages.CreateMTOShipment{
MoveTaskOrderID: handlers.FmtUUID(move.ID),
Agents: nil,
CustomerRemarks: nil,
PointOfContact: "John Doe",
RequestedPickupDate: handlers.FmtDatePtr(models.TimePointer(time.Now())),
ShipmentType: primev2messages.NewMTOShipmentType(primev2messages.MTOShipmentTypeHHG),
PickupAddress: struct{ primev2messages.Address }{pickupAddress},
DestinationAddress: struct{ primev2messages.Address }{destinationAddress},
},
}

response := handler.Handle(params)
suite.IsType(&mtoshipmentops.CreateMTOShipmentInternalServerError{}, response)
typedResponse := response.(*mtoshipmentops.CreateMTOShipmentInternalServerError)
suite.Contains(*typedResponse.Payload.Detail, "An internal server error has occurred")
})

suite.Run("POST failure - 422 - modelType() not supported", func() {
// Under Test: CreateMTOShipmentHandler
// Setup: Create a shipment with service items that don't match the modeltype
Expand Down
6 changes: 6 additions & 0 deletions pkg/handlers/primeapiv3/mto_shipment.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ func (h CreateMTOShipmentHandler) Handle(params mtoshipmentops.CreateMTOShipment
case apperror.NotFoundError:
return mtoshipmentops.NewCreateMTOShipmentNotFound().WithPayload(
payloads.ClientError(handlers.NotFoundMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.EventError:
return mtoshipmentops.NewUpdateMTOShipmentBadRequest().WithPayload(
payloads.ClientError(handlers.InternalServerErrMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.InvalidInputError:
return mtoshipmentops.NewCreateMTOShipmentUnprocessableEntity().WithPayload(
payloads.ValidationError(err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest), e.ValidationErrors)), err
Expand Down Expand Up @@ -206,6 +209,9 @@ func (h UpdateMTOShipmentHandler) Handle(params mtoshipmentops.UpdateMTOShipment
case apperror.NotFoundError:
return mtoshipmentops.NewUpdateMTOShipmentNotFound().WithPayload(
payloads.ClientError(handlers.NotFoundMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.EventError:
return mtoshipmentops.NewUpdateMTOShipmentBadRequest().WithPayload(
payloads.ClientError(handlers.InternalServerErrMessage, err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest))), err
case apperror.InvalidInputError:
payload := payloads.ValidationError(err.Error(), h.GetTraceIDFromRequest(params.HTTPRequest), e.ValidationErrors)
return mtoshipmentops.NewUpdateMTOShipmentUnprocessableEntity().WithPayload(payload), err
Expand Down
36 changes: 36 additions & 0 deletions pkg/handlers/primeapiv3/mto_shipment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,42 @@ func (suite *HandlerSuite) TestCreateMTOShipmentHandler() {
suite.Contains(*typedResponse.Payload.Detail, unavailableMove.ID.String())
})

suite.Run("POST failure - 500 - App Event Internal DTOD Server Error", func() {
// Under Test: CreateMTOShipmentHandler
// Setup: Create a shipment with DTOD outage simulated or bad zip
// Expected: 500 Internal Server Error returned

handler, move := setupTestData(true, false)
req := httptest.NewRequest("POST", "/mto-shipments", nil)
handler.ShipmentCreator = &mockCreator

err := apperror.EventError{}

mockCreator.On("CreateShipment",
mock.AnythingOfType("*appcontext.appContext"),
mock.Anything,
).Return(nil, nil, err)

params := mtoshipmentops.CreateMTOShipmentParams{
HTTPRequest: req,
Body: &primev3messages.CreateMTOShipment{
MoveTaskOrderID: handlers.FmtUUID(move.ID),
Agents: nil,
CustomerRemarks: nil,
PointOfContact: "John Doe",
RequestedPickupDate: handlers.FmtDatePtr(models.TimePointer(time.Now())),
ShipmentType: primev3messages.NewMTOShipmentType(primev3messages.MTOShipmentTypeHHG),
PickupAddress: struct{ primev3messages.Address }{pickupAddress},
DestinationAddress: struct{ primev3messages.Address }{destinationAddress},
},
}

response := handler.Handle(params)
suite.IsType(&mtoshipmentops.CreateMTOShipmentInternalServerError{}, response)
typedResponse := response.(*mtoshipmentops.CreateMTOShipmentInternalServerError)
suite.Contains(*typedResponse.Payload.Detail, "An internal server error has occurred")
})

suite.Run("POST failure - 422 - MTO Shipment object not formatted correctly", func() {
// Under Test: CreateMTOShipmentHandler
// Setup: Create a shipment with service items that don't match the modeltype
Expand Down
4 changes: 2 additions & 2 deletions src/components/Customer/Review/TableDivider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { string } from 'prop-types';

import styles from './Review.module.scss';

const TableDivider = ({ className }) => (
export const TableDivider = ({ className }) => (
<tr>
<td className={`${styles['table-divider']} ${className}`} colSpan="100%" />
<td className={`${styles['table-divider']} ${className}`} data-testid="tableDivider" colSpan="100%" />
</tr>
);

Expand Down
12 changes: 12 additions & 0 deletions src/components/Customer/Review/TableDivider.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { render, screen } from '@testing-library/react';

import { TableDivider } from 'components/Customer/Review/TableDivider';

describe('TableDivider', () => {
it('verify table divider display', async () => {
render(<TableDivider className="Test" />);

expect(await screen.findByTestId('tableDivider')).toBeInTheDocument();
});
});
17 changes: 13 additions & 4 deletions src/pages/PrimeUI/Shipment/PrimeUIShipmentCreate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ const PrimeUIShipmentCreate = ({ setFlashMessage }) => {
const handleClose = () => {
navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID }));
};

const handleSetError = (error, invalidFieldsStr) => {
let detailedMessage = `${error?.response?.body.detail}${invalidFieldsStr}\n\nPlease refresh and Update Shipment again`;
if (error?.response?.body?.detail !== null && error?.response?.body?.detail !== undefined) {
detailedMessage = `${error?.response?.body.detail}\n\nPlease refresh and Update Shipment again`;
}
setErrorMessage({
title: `Prime API: ${error?.response?.body.title} `,
detail: detailedMessage,
});
};

const { mutateAsync: mutateCreateMTOShipment } = useMutation(createPrimeMTOShipmentV3, {
onSuccess: (createdMTOShipment) => {
setFlashMessage(
Expand All @@ -53,10 +65,7 @@ const PrimeUIShipmentCreate = ({ setFlashMessage }) => {
invalidFieldsStr += `\n${key} - ${value && value.length > 0 ? value[0] : ''} ;`;
});
}
setErrorMessage({
title: `Prime API: ${body.title} `,
detail: `${body.detail}${invalidFieldsStr}\n\nPlease try again`,
});
handleSetError(error, invalidFieldsStr);
} else {
setErrorMessage({
title: 'Unexpected error',
Expand Down
16 changes: 16 additions & 0 deletions src/pages/PrimeUI/Shipment/PrimeUIShipmentCreate.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,22 @@ describe('Error when submitting', () => {
).toBeInTheDocument();
});
});

it('Correctly displays a specific error message when an error response is returned', async () => {
createPrimeMTOShipmentV3.mockRejectedValue({ body: { title: 'Error', detail: 'The data entered no good.' } });
render(mockedComponent);

waitFor(async () => {
await userEvent.selectOptions(screen.getByLabelText('Shipment type'), 'HHG');

const saveButton = await screen.getByRole('button', { name: 'Save' });

expect(saveButton).not.toBeDisabled();
await userEvent.click(saveButton);
expect(screen.getByText('Prime API: Error')).toBeInTheDocument();
expect(screen.getByText('The data entered no good.')).toBeInTheDocument();
});
});
});

describe('Create PPM', () => {
Expand Down
21 changes: 13 additions & 8 deletions src/pages/PrimeUI/Shipment/PrimeUIShipmentUpdate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ const PrimeUIShipmentUpdate = ({ setFlashMessage }) => {
navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID }));
};

const handleSetError = (error, invalidFieldsStr) => {
let detailedMessage = `${error?.response?.body.detail}${invalidFieldsStr}\n\nPlease refresh and Update Shipment again`;
if (error?.response?.body?.detail !== null && error?.response?.body?.detail !== undefined) {
detailedMessage = `${error?.response?.body.detail}\n\nPlease refresh and Update Shipment again`;
}
setErrorMessage({
title: `Prime API: ${error?.response?.body.title} `,
detail: detailedMessage,
});
};

const { mutateAsync: mutateMTOShipmentStatus } = useMutation(updatePrimeMTOShipmentStatus, {
onSuccess: (updatedMTOShipment) => {
mtoShipments[mtoShipments.findIndex((mtoShipment) => mtoShipment.id === updatedMTOShipment.id)] =
Expand All @@ -62,10 +73,7 @@ const PrimeUIShipmentUpdate = ({ setFlashMessage }) => {
invalidFieldsStr += `\n${key} - ${value && value.length > 0 ? value[0] : ''} ;`;
});
}
setErrorMessage({
title: `Prime API: ${body.title} `,
detail: `${body.detail}${invalidFieldsStr}\n\nPlease cancel and Update Shipment again`,
});
handleSetError(error, invalidFieldsStr);
} else {
setErrorMessage({
title: 'Unexpected error',
Expand Down Expand Up @@ -93,10 +101,7 @@ const PrimeUIShipmentUpdate = ({ setFlashMessage }) => {
invalidFieldsStr += `\n${key} - ${value && value.length > 0 ? value[0] : ''} ;`;
});
}
setErrorMessage({
title: `Prime API: ${body.title} `,
detail: `${body.detail}${invalidFieldsStr}\n\nPlease cancel and Update Shipment again`,
});
handleSetError(error, invalidFieldsStr);
} else {
setErrorMessage({
title: 'Unexpected error',
Expand Down
18 changes: 18 additions & 0 deletions src/pages/PrimeUI/Shipment/PrimeUIShipmentUpdate.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -513,3 +513,21 @@ describe('Update Shipment Page for PPM', () => {
});
});
});

describe('Error Handling', () => {
it('Correctly displays a specific error message when an error response is returned', async () => {
updatePrimeMTOShipmentV3.mockRejectedValue({ body: { title: 'Error', detail: 'The data entered no good.' } });
render(mockedComponent);

waitFor(async () => {
await userEvent.selectOptions(screen.getByLabelText('Shipment type'), 'HHG');

const saveButton = await screen.getByRole('button', { name: 'Save' });

expect(saveButton).not.toBeDisabled();
await userEvent.click(saveButton);
expect(screen.getByText('Prime API: Error')).toBeInTheDocument();
expect(screen.getByText('The data entered no good.')).toBeInTheDocument();
});
});
});

0 comments on commit ea6139e

Please sign in to comment.