Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create and serve paper petition fix #5791

Merged
merged 3 commits into from
Feb 19, 2025

Conversation

akuny
Copy link
Contributor

@akuny akuny commented Feb 18, 2025

Overview

This PR addresses an issue with the create-and-serve-paper-petition Cypress helper. As shown in the code below, the helper previously expected that four draft docket entries be rendered in the exact same order every time the helper runs:

cy.get('[data-testid="docket-entry-description-0"]').should(
    'have.text',
    'Notice of Attachments in the Nature of Evidence',
);
cy.get('[data-testid="docket-entry-description-1"]').should(
    'have.text',
    'Order',
);
cy.get('[data-testid="docket-entry-description-2"]').should(
    'have.text',
    'Order',
);
cy.get('[data-testid="docket-entry-description-3"]').should(
    'have.text',
    'Order to Show Cause',
);

However, there is no guarantee that these docket entries will appear in the UI in this exact order.

Issue in a Nutshell

When this Cypress helper creates a case and serves it to the IRS, the serveCaseToIrsInteractor interactor may include one or more calls to addDocketEntryForSystemGeneratedOrder wrapped in a Promise.all. A new Docket Entry is instantiated for each system generated order that needs to be created. Since these were all created on the same date, the receivedAt property will be identical for each DocketEntry entity, since the output of createISODateAtStartOfDayEST when called without an argument is the same for any given DocketEntry instantiated on the same day. So, they are sorted on a property that is identical across the board. In edge cases, it appears that these draft docket entries are created in a different sequence than the one expected, likely because the concurrent execution of Promise.all can lead to non-deterministic completion order

Fix

Instead of expecting these draft docket entries to appear in the same order every time, this PR changes the helper such that it still asserts all four draft docket entries are visible in the UI, but without being tied to a particular order.

Here are screenshots of the UI from the same test suite run with the fix in place:

1

2

Breadcrumbs

// web-client/src/views/DocketRecord/DraftDocumentViewer.tsx
<div className="document-viewer--documents-list">
{formattedDocketEntries.formattedDraftDocuments.map(
    (draftDocument, idx) => (
    <Button
    // ...
// web-client/src/presenter/computeds/formattedDocketEntries.ts

// inside `formattedDocketEntries`
const result = formatCase(applicationContext, caseDetail, user);
// ...
result.formattedDraftDocuments = result.draftDocuments.map(draftDocument => {
    return {
    ...draftDocument,
    descriptionDisplay: draftDocument.documentTitle,
    showDocumentViewerLink: permissions.UPDATE_CASE,
    };
});
// shared/src/business/utilities/getFormattedCaseDetail.ts

// inside `formatCase`
const result = cloneDeep(caseDetail);

if (result.docketEntries) {
    result.draftDocumentsUnsorted = result.docketEntries
        .filter(docketEntry => docketEntry.isDraft && !docketEntry.archived)
        .map(docketEntry => ({
            ...formatDocketEntry(applicationContext, docketEntry),
            editUrl: getEditUrl(docketEntry),
            signUrl: `/case-detail/${caseDetail.docketNumber}/edit-order/${docketEntry.docketEntryId}/sign`,
            signedAtFormatted: applicationContext
            .getUtilities()
            .formatDateString(docketEntry.signedAt, 'MMDDYY'),
            signedAtFormattedTZ: applicationContext
            .getUtilities()
            .formatDateString(docketEntry.signedAt, 'DATE_TIME_TZ'),
        }));

result.draftDocuments = sortBy(result.draftDocumentsUnsorted, 'receivedAt');

We see that formattedDocketEntries.formattedDraftDocuments is sorted by receivedAt.

Working backward: how was the case served?

// web-api/src/business/useCases/serveCaseToIrs/serveCaseToIrsInteractor.ts

if (caseEntity.noticeOfAttachments) {
    const { noticeOfAttachmentsInNatureOfEvidence } =
    SYSTEM_GENERATED_DOCUMENT_TYPES;
    generatedDocuments.push(
    applicationContext
        .getUseCaseHelpers()
        .addDocketEntryForSystemGeneratedOrder({
        applicationContext,
        authorizedUser,
        caseEntity,
        systemGeneratedDocument: noticeOfAttachmentsInNatureOfEvidence,
        }),
    );
}
// web-api/src/business/useCaseHelper/addDocketEntryForSystemGeneratedOrder.ts`

// inside `addDocketEntryForSystemGeneratedOrder`
const newDocketEntry = new DocketEntry(
    {
    documentTitle: systemGeneratedDocument.documentTitle,
    documentType: systemGeneratedDocument.documentType,
    draftOrderState: {
            docketNumber: caseEntity.docketNumber,
            documentTitle: systemGeneratedDocument.documentTitle,
            documentType: systemGeneratedDocument.documentType,
            eventCode: systemGeneratedDocument.eventCode,
            ...(isNotice && { freeText: systemGeneratedDocument.documentTitle }),
        },
    eventCode: systemGeneratedDocument.eventCode,
    ...(isNotice && { freeText: systemGeneratedDocument.documentTitle }),
    isDraft: true,
    isFileAttached: true,
    },
    { authorizedUser },
);

newDocketEntry.setFiledBy(authorizedUser);

caseEntity.addDocketEntry(newDocketEntry);
// shared/src/business/entities/DocketEntry.ts

// inside `DocketEntry` entity constructor
this.receivedAt = createISODateAtStartOfDayEST(rawDocketEntry.receivedAt);
// shared/src/business/utilities/DateHandler.ts

export const createISODateAtStartOfDayEST = (dateString?: string): string => {
  const dtObj = dateString
    ? DateTime.fromISO(dateString, { zone: USTC_TZ })
    : DateTime.now().setZone(USTC_TZ); // no `dateString` argument is provided in this scenario

  const iso = dtObj.startOf('day').setZone('utc').toISO();

  return iso!;
};

jimlerza and others added 2 commits February 18, 2025 10:23
bug: Only intercpet requests to our own API. Do not intercept other requests.
@akuny akuny added the to test label Feb 18, 2025
@akuny akuny marked this pull request as ready for review February 18, 2025 22:47
Copy link
Contributor

@Mwindo Mwindo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question for more context: are we certain that the order of orders (heh) doesn't matter? In other words, is the test wrongly expecting a particular order, which means we have a flaky test; or is the test correctly expecting a particular order, which means our application is not enforcing it properly? It seems like the former. If so, I'm happy to approve.

@En-8
Copy link
Contributor

En-8 commented Feb 19, 2025

Question for more context: are we certain that the order of orders (heh) doesn't matter? In other words, is the test wrongly expecting a particular order, which means we have a flaky test; or is the test correctly expecting a particular order, which means our application is not enforcing it properly? It seems like the former. If so, I'm happy to approve.

It's a good question. Our assumption based on sleuthing through the code is that the only expected ordering is based on the draft DocketEntry's receivedAt property, which is always the start of the day (in Eastern time) on which that DocketEntry was first created in memory.

Assuming our initial assumption is correct, the next question is whether or not we're missing a secondary sort. It seemed reasonable to think that the answer to the is probably "no", given any case in which we've got enough drafts created on the same day that this applies there's still relatively few of them, and never so many they fall off the page or have the experience otherwise improved (at least not more than marginally so) by a secondary sort.

I recognize this is quite a roll of assumptions -- maybe it's worth having a quick chat with Tenille and/or Chris to get their take.

@akuny
Copy link
Contributor Author

akuny commented Feb 19, 2025

I recognize this is quite a roll of assumptions

This is well put--we should walk through this PR in stand-up this morning, time permitting.

Copy link
Contributor

@Mwindo Mwindo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for asking about this in stand-up!

@akuny akuny merged commit cf4364b into ustaxcourt:test Feb 19, 2025
44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants