Skip to content

Commit

Permalink
Merge branch 'staging' into 10421-story
Browse files Browse the repository at this point in the history
  • Loading branch information
Mwindo authored Jul 22, 2024
2 parents 483b217 + c159f1c commit 4c5b0a7
Show file tree
Hide file tree
Showing 46 changed files with 1,557 additions and 499 deletions.
96 changes: 72 additions & 24 deletions cypress/local-only/tests/integration/messages/messages.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
loginAsDocketClerk,
loginAsPetitionsClerk,
} from '../../../../helpers/authentication/login-as-helpers';
import { retry } from '../../../../helpers/retry';

describe('Messages', () => {
describe('Message filtering', () => {
Expand Down Expand Up @@ -161,6 +160,74 @@ describe('Messages', () => {
});
});

describe('Sorting on the Individual Message Inbox', () => {
it('individual inbox subject column', () => {
loginAsDocketClerk();
cy.get(
'[data-testid="message-individual-subject-header-button"]',
).click();
verifySubjectTitleOrder({
boxType: 'inbox',
isAscending: true,
prefix: 'Subject Line',
queueType: 'individual',
});
cy.get(
'[data-testid="message-individual-subject-header-button"]',
).click();
verifySubjectTitleOrder({
boxType: 'inbox',
isAscending: false,
prefix: 'Subject Line',
queueType: 'individual',
});
});

it('individual inbox received at column when defaulted to sort ascending', () => {
loginAsDocketClerk();
cy.get(
'[data-testid="message-individual-received-header-button"]',
).click();
verifySubjectTitleOrder({
boxType: 'inbox',
isAscending: false,
prefix: 'Subject Line',
queueType: 'individual',
});
cy.get(
'[data-testid="message-individual-received-header-button"]',
).click();
verifySubjectTitleOrder({
boxType: 'inbox',
isAscending: true,
prefix: 'Subject Line',
queueType: 'individual',
});
});

it('individual inbox docket number column', () => {
loginAsDocketClerk();
cy.get(
'[data-testid="message-individual-docket-number-header-button"]',
).click();
verifySubjectTitleOrder({
boxType: 'inbox',
isAscending: false,
prefix: 'Subject Line',
queueType: 'individual',
});
cy.get(
'[data-testid="message-individual-docket-number-header-button"]',
).click();
verifySubjectTitleOrder({
boxType: 'inbox',
isAscending: false,
prefix: 'Subject Line',
queueType: 'individual',
});
});
});

describe('Sorting on the Individual Message Completed', () => {
it('individual completed subject column', () => {
loginAsDocketClerk();
Expand Down Expand Up @@ -611,10 +678,7 @@ function sendMessages(DOCKET_CLERK_ID: string) {
}
}

function sendMessagesToCompletedTab(
DOCKET_CLERK_ID: string,
docketNumber: string,
) {
function sendMessagesToCompletedTab(DOCKET_CLERK_ID: string) {
for (let i = 0; i < 3; i++) {
cy.get('[data-testid="case-detail-menu-button"]').click();
cy.get('[data-testid="menu-button-add-new-message"]').click();
Expand All @@ -627,23 +691,7 @@ function sendMessagesToCompletedTab(
}

cy.login('docketclerk');
for (let i = 0; i < 3; i++) {
cy.get(`a[href^="/messages/${docketNumber}/message-detail"]`).eq(0).click();
cy.get('[data-testid="message-mark-as-complete"]').click();
cy.get('[data-testid="complete-message-body"]').type('MARK AS COMPLETE');
cy.get('[data-testid="modal-confirm"]').click();
cy.get('[data-testid="message-detail-warning-alert"]').should('exist');
cy.get('[data-testid="header-messages-link"]').click();
retry(() => {
cy.reload(true);
cy.get('[data-testid="inbox-tab-content"]').should('exist');
return cy.get('body').then(body => {
return (
body.find(`a[href^="/messages/${docketNumber}/message-detail"]`)
.length ===
2 - i
);
});
});
}
cy.get('[data-testid="all-messages-checkbox"]').click();
cy.get('[data-testid="message-batch-mark-as-complete"]').click();
cy.get('[data-testid="message-detail-success-alert"]').should('exist');
}
2 changes: 1 addition & 1 deletion docs/wiki/Messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
* Optional field - current functionality

**On Complete**
* App remains on Message Detail with completed warning displayed
* App remains on Message Detail with completed success alert displayed
* Message no longer displays in any user Inbox
* Completed message displays in My Messages > Completed and Section Messages > Completed
* Message thread displays as Completed on Message Detail screen
Expand Down
21 changes: 8 additions & 13 deletions shared/src/proxies/messages/completeMessageProxy.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import { ClientApplicationContext } from '@web-client/applicationContext';
import { post } from '../requests';

/**
* completeMessageInteractor
*
* @param {object} applicationContext the application context
* @param {object} providers the providers object
* @param {string} providers.message the message text
* @param {string} providers.parentMessageId the id of the parent message for the thread
* @returns {Promise<*>} the promise of the api call
*/
export const completeMessageInteractor = (
applicationContext,
{ message, parentMessageId },
) => {
applicationContext: ClientApplicationContext,
{
messages,
}: { messages: { messageBody: string; parentMessageId: string }[] },
): Promise<void> => {
const { parentMessageId } = messages[0];
return post({
applicationContext,
body: {
message,
messages,
},
endpoint: `/messages/${parentMessageId}/complete`,
});
Expand Down
2 changes: 1 addition & 1 deletion web-api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ app.delete(
);
app.post(
'/messages/:parentMessageId/complete',
lambdaWrapper(completeMessageLambda),
lambdaWrapper(completeMessageLambda, { isAsync: true }),
);
app.post('/messages/:messageId/read', lambdaWrapper(setMessageAsReadLambda));
app.get('/messages/:parentMessageId', lambdaWrapper(getMessageThreadLambda));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,10 @@ describe('completeMessageInteractor', () => {
toUserId: '6805d1ab-18d0-43ec-bafb-654e83405416',
},
];
const PARENT_MESSAGE_ID_1 = 'b8ff88da-89fe-46a6-bc37-dc2100c7b2bd';
const PARENT_MESSAGE_ID_2 = '4782edfe-618b-4315-9619-675403246bce';

it('throws unauthorized for a user without MESSAGES permission', async () => {
applicationContext.getCurrentUser.mockReturnValue({
role: ROLES.petitioner,
userId: '9bd0308c-2b06-4589-b36e-242398bea31b',
});

await expect(
completeMessageInteractor(applicationContext, {
message: 'hi',
parentMessageId: '123',
}),
).rejects.toThrow(UnauthorizedError);
});

it('calls persistence methods to mark the thread as replied to and complete the most recent message', async () => {
beforeAll(() => {
applicationContext.getCurrentUser.mockReturnValue({
role: ROLES.petitionsClerk,
userId: 'b9fcabc8-3c83-4cbf-9f4a-d2ecbdc591e1',
Expand All @@ -80,24 +68,49 @@ describe('completeMessageInteractor', () => {
applicationContext
.getPersistenceGateway()
.updateMessage.mockResolvedValue(mockMessages[1]);
applicationContext
.getNotificationGateway()
.sendNotificationToUser.mockResolvedValue();
});

const PARENT_MESSAGE_ID = 'b8ff88da-89fe-46a6-bc37-dc2100c7b2bd';
it('should throw unauthorized for a user without MESSAGES permission', async () => {
applicationContext.getCurrentUser.mockReturnValueOnce({
role: ROLES.petitioner,
userId: '9bd0308c-2b06-4589-b36e-242398bea31b',
});

await expect(
completeMessageInteractor(applicationContext, {
messages: [{ messageBody: 'hi', parentMessageId: '123' }],
}),
).rejects.toThrow(UnauthorizedError);
});

it('should call persistence methods to mark the thread as replied to and complete the most recent messages', async () => {
await completeMessageInteractor(applicationContext, {
message: 'the completed message',
parentMessageId: PARENT_MESSAGE_ID,
messages: [
{
messageBody: 'the completed message',
parentMessageId: PARENT_MESSAGE_ID_1,
},
{ messageBody: 'hi', parentMessageId: PARENT_MESSAGE_ID_2 },
],
});

expect(
applicationContext.getPersistenceGateway().markMessageThreadRepliedTo,
).toHaveBeenCalled();
).toHaveBeenCalledTimes(2);
expect(
applicationContext.getPersistenceGateway().markMessageThreadRepliedTo.mock
.calls[0][0].parentMessageId,
).toEqual(PARENT_MESSAGE_ID);
).toEqual(PARENT_MESSAGE_ID_1);
expect(
applicationContext.getPersistenceGateway().markMessageThreadRepliedTo.mock
.calls[1][0].parentMessageId,
).toEqual(PARENT_MESSAGE_ID_2);
expect(
applicationContext.getPersistenceGateway().updateMessage,
).toHaveBeenCalled();
).toHaveBeenCalledTimes(2);
expect(
applicationContext.getPersistenceGateway().updateMessage.mock.calls[0][0]
.message,
Expand All @@ -107,5 +120,56 @@ describe('completeMessageInteractor', () => {
completedByUserId: 'b9fcabc8-3c83-4cbf-9f4a-d2ecbdc591e1',
isCompleted: true,
});
expect(
applicationContext.getPersistenceGateway().updateMessage.mock.calls[1][0]
.message,
).toMatchObject({
completedBy: 'Test Petitionsclerk',
completedBySection: PETITIONS_SECTION,
completedByUserId: 'b9fcabc8-3c83-4cbf-9f4a-d2ecbdc591e1',
isCompleted: true,
});
});

it('should send a success message to the user', async () => {
await completeMessageInteractor(applicationContext, {
messages: [
{
messageBody: 'the completed message',
parentMessageId: PARENT_MESSAGE_ID_1,
},
],
});
expect(
applicationContext.getNotificationGateway().sendNotificationToUser.mock
.calls[0][0].message,
).toEqual({
action: 'message_completion_success',
completedMessageIds: [mockMessages[1].messageId],
});
});

it('should send an error message to the user', async () => {
applicationContext
.getPersistenceGateway()
.updateMessage.mockRejectedValueOnce(new Error('Bad!'));
await completeMessageInteractor(applicationContext, {
messages: [
{
messageBody: 'the completed message',
parentMessageId: PARENT_MESSAGE_ID_1,
},
],
});
expect(
applicationContext.getNotificationGateway().sendNotificationToUser.mock
.calls[0][0].message,
).toEqual({
action: 'message_completion_error',
alertError: {
message: 'Please try again',
title: 'Message(s) could not be completed',
},
});
});
});
Loading

0 comments on commit 4c5b0a7

Please sign in to comment.