Skip to content

Commit

Permalink
feat: Update test plan status dialog to show AT versions (#1065)
Browse files Browse the repository at this point in the history
* Add minimum or exact at version to reports

* Quick tweak

* Revert home copy change

* Remove unused field from createTestPlanReport

* Fix undefined var

* Prevent API from creating duplicate reports

* Add atVersion frontend

* Make sure automation dialog always shows when valid

* Make sure existing reports have a minimum at version

* Update status dialog for minimum exact AT versions

* Update server/resolvers/TestPlanVersion/testPlanReportStatusesResolver.js

Co-authored-by: Howard Edwards <[email protected]>

---------

Co-authored-by: Howard Edwards <[email protected]>
  • Loading branch information
alflennik and howard-e authored May 2, 2024
1 parent 6dff002 commit 3e38be7
Show file tree
Hide file tree
Showing 20 changed files with 5,888 additions and 2,068 deletions.
3 changes: 0 additions & 3 deletions client/components/DataManagement/DataManagementRow/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,6 @@ const DataManagementRow = ({
)}
<span role="listitem">
<TestPlanReportStatusDialogWithButton
ats={ats}
testPlanVersionId={latestVersion.id}
/>
</span>
Expand Down Expand Up @@ -971,7 +970,6 @@ const DataManagementRow = ({
)}
<span role="listitem">
<TestPlanReportStatusDialogWithButton
ats={ats}
testPlanVersionId={latestVersion.id}
/>
</span>
Expand Down Expand Up @@ -1060,7 +1058,6 @@ const DataManagementRow = ({
</VersionString>
<span role="listitem">
<TestPlanReportStatusDialogWithButton
ats={ats}
testPlanVersionId={latestVersion.id}
/>
</span>
Expand Down
92 changes: 30 additions & 62 deletions client/components/TestPlanReportStatusDialog/WithButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React, { useMemo, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { Button } from 'react-bootstrap';
import TestPlanReportStatusDialog from './index';
import { getRequiredReports } from './isRequired';
import { calculateTestPlanReportCompletionPercentage } from './calculateTestPlanReportCompletionPercentage';
import styled from '@emotion/styled';
import ReportStatusDot from '../common/ReportStatusDot';
Expand All @@ -26,7 +25,7 @@ const TestPlanReportStatusDialogButton = styled(Button)`
margin-top: auto;
`;

const TestPlanReportStatusDialogWithButton = ({ ats, testPlanVersionId }) => {
const TestPlanReportStatusDialogWithButton = ({ testPlanVersionId }) => {
const {
data: { testPlanVersion } = {},
refetch,
Expand All @@ -39,60 +38,48 @@ const TestPlanReportStatusDialogWithButton = ({ ats, testPlanVersionId }) => {
const buttonRef = useRef(null);

const [showDialog, setShowDialog] = useState(false);
const { testPlanReports } = testPlanVersion ?? {};

// TODO: Use the DB provided AtBrowsers combinations when doing the edit UI task
const requiredReports = useMemo(
() => getRequiredReports(testPlanVersion?.phase),
[testPlanVersion?.phase]
);
const { testPlanReportStatuses } = testPlanVersion ?? {};

const buttonLabel = useMemo(() => {
const initialCounts = { completed: 0, inProgress: 0, missing: 0 };
if (!testPlanReportStatuses) return;

const counts = requiredReports.reduce((acc, requiredReport) => {
const matchingReport = testPlanReports.find(
report =>
report.at.id === requiredReport.at.id &&
report.browser.id === requiredReport.browser.id
);
if (matchingReport) {
const counts = { completed: 0, inProgress: 0, missing: 0 };

testPlanReportStatuses.forEach(status => {
if (!status.isRequired) return;

const { testPlanReport } = status;

if (testPlanReport) {
const percentComplete =
calculateTestPlanReportCompletionPercentage(matchingReport);
if (percentComplete === 100 && matchingReport.markedFinalAt) {
acc.completed++;
calculateTestPlanReportCompletionPercentage(testPlanReport);

if (percentComplete === 100 && testPlanReport.markedFinalAt) {
counts.completed += 1;
} else {
acc.inProgress++;
counts.inProgress += 1;
}
} else {
acc.missing++;
counts.missing += 1;
}
return acc;
}, initialCounts);
});

// All AT/browser pairs that require a report have a complete report
if (counts.completed === requiredReports.length) {
if (counts.missing === 0 && counts.inProgress === 0) {
return (
<span>
<ReportStatusDot className="reports-complete" />
Required Reports <strong>Complete</strong>
</span>
);
}
// At least one AT/browser pair that requires a report does not have a complete report and is in the test queue.
// All other AT/browser pairs that require a report are either complete or are in the test queue.
else if (counts.inProgress > 0 && counts.missing === 0) {
} else if (counts.missing === 0 && counts.inProgress !== 0) {
return (
<span>
<ReportStatusDot className="reports-in-progress" />
Required Reports <strong>In Progress</strong>
</span>
);
}
// At least one of the AT/browser pairs that requires a report neither has a complete report nor has a run in the test queue.
// At the same time, at least one of the AT/browser pairs that requires a report either has a complete report or has a run in the test queue.
else if (
counts.missing > 0 &&
} else if (
counts.missing !== 0 &&
(counts.completed > 0 || counts.inProgress > 0)
) {
return (
Expand All @@ -101,26 +88,27 @@ const TestPlanReportStatusDialogWithButton = ({ ats, testPlanVersionId }) => {
Some Required Reports <strong>Missing</strong>
</span>
);
}
// For every AT/browser pair that requires a report, the report is neither complete nor in the test queue.
else if (counts.missing === requiredReports.length) {
} else if (
counts.missing !== 0 &&
counts.completed === 0 &&
counts.inProgress === 0
) {
return (
<span>
<ReportStatusDot className="reports-not-started" />
Required Reports <strong>Not Started</strong>
</span>
);
}
// Fallback case
else {
} else {
// Fallback case
return (
<span>
<ReportStatusDot className="reports-not-started" />
Some Reports Complete
</span>
);
}
}, [requiredReports, testPlanReports]);
}, [testPlanReportStatuses]);

if (
loading ||
Expand Down Expand Up @@ -149,32 +137,12 @@ const TestPlanReportStatusDialogWithButton = ({ ats, testPlanVersionId }) => {
buttonRef.current.focus();
}}
triggerUpdate={refetch}
ats={ats}
/>
</>
);
};

TestPlanReportStatusDialogWithButton.propTypes = {
ats: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
browsers: PropTypes.arrayOf(
PropTypes.shape({ id: PropTypes.string.isRequired }).isRequired
).isRequired,
candidateBrowsers: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired
}).isRequired
).isRequired,
recommendedBrowsers: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired
}).isRequired
).isRequired
}).isRequired
).isRequired,
testPlanVersionId: PropTypes.string.isRequired
};

Expand Down
Loading

0 comments on commit 3e38be7

Please sign in to comment.