id="disclosure-container-manage-test-queue-Manage Assistive Technology Versions"
aria-labelledby="disclosure-btn-manage-test-queue-Manage Assistive Technology Versions"
class="css-19fsyrg">
-
+
Select an assistive technology and manage its versions in the
ARIA-AT App
id="disclosure-container-manage-test-queue-Add Test Plans to the Test Queue"
aria-labelledby="disclosure-btn-manage-test-queue-Add Test Plans to the Test Queue"
class="css-19fsyrg">
-
+
Select a test plan, assistive technology and browser to add a
new test plan report to the test queue.
+
+
+ Manage Required Reports
+
+
+
+
+
+
+
Update which assistive technology and browser combinations
+ require reports for the Candidate and Recommended phases
+
+
+ Phase
+ Select a Phase
+ Candidate
+ Recommended
+
+
+
+ Assistive Technology
+
+ Select an Assistive Technology
+
+ JAWS
+ NVDA
+ VoiceOver for macOS
+
+
+
+ Browser
+ Select a Browser
+
+
+
+
+ Add Required Reports
+
+
+
+
+ Required Reports
+
+
+
+
+
+ Phase
+ AT
+ Browser
+ Edit
+
+
+
+
+
+ Candidate
+
+ JAWS
+ Chrome
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Candidate
+
+ NVDA
+ Chrome
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Candidate
+
+ VoiceOver for macOS
+ Safari
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Recommended
+
+ JAWS
+ Firefox
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Recommended
+
+ JAWS
+ Chrome
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Recommended
+
+ NVDA
+ Firefox
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Recommended
+
+ NVDA
+ Chrome
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Recommended
+
+ VoiceOver for macOS
+ Safari
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+ Recommended
+
+ VoiceOver for macOS
+ Chrome
+
+
+
+ Edit
+
+ Remove
+
+
+
+
+
+
+
+
Alert Example
diff --git a/server/graphql-schema.js b/server/graphql-schema.js
index b6b50adfa..00b2db807 100644
--- a/server/graphql-schema.js
+++ b/server/graphql-schema.js
@@ -786,6 +786,31 @@ const graphqlSchema = gql`
unexpectedBehaviors: [UnexpectedBehavior]
}
+ """
+ See TestResult type for more information.
+ The return type for createRequiredReport.
+ """
+ type RequiredReport {
+ atId: ID!
+ browserId: ID!
+ phase: TestPlanVersionPhase!
+ }
+
+ """
+ The fields on the RequiredReportOperations type which can be used or update the
+ RequiredReports.
+ """
+ input RequiredReportOperationsInput {
+ """
+ See AtVersion type for more information.
+ """
+ inputAtId: ID!
+ """
+ See AtVersion type for more information.
+ """
+ inputBrowserId: ID!
+ }
+
"""
Minimal plain representation of a ScenarioResult.
"""
@@ -1316,6 +1341,12 @@ const graphqlSchema = gql`
findOrCreateAtVersion(input: AtVersionInput!): AtVersion!
}
+ type RequiredReportOperations {
+ createRequiredReport: RequiredReport!
+ updateRequiredReport(atId: ID!, browserId: ID!): RequiredReport!
+ deleteRequiredReport: RequiredReport!
+ }
+
"""
Mutations scoped to an existing AtVersion.
"""
@@ -1571,6 +1602,14 @@ const graphqlSchema = gql`
Delete a CollectionJob
"""
deleteCollectionJob(id: ID!): NoResponse!
+ """
+ Get the available mutations for the given RequiredReport.
+ """
+ requiredReport(
+ atId: ID!
+ browserId: ID!
+ phase: TestPlanVersionPhase!
+ ): RequiredReportOperations!
}
`;
diff --git a/server/models/services/AtBrowserService b/server/models/services/AtBrowserService
new file mode 100644
index 000000000..f3de0767e
--- /dev/null
+++ b/server/models/services/AtBrowserService
@@ -0,0 +1,25 @@
+const ModelService = require('./ModelService.js');
+const { AtBrowsers } = require('../');
+const { AT_BROWSERS_ATTRIBUTES } = require('./helpers');
+
+const updateAtBrowser = async ({
+ atId,
+ browserId,
+ updateParams = {},
+ atBrowsersAttributes = AT_BROWSERS_ATTRIBUTES,
+ transaction
+}) => {
+ await ModelService.update(AtBrowsers, {
+ where: { atId, browserId },
+ values: updateParams,
+ transaction
+ });
+
+ return ModelService.getByQuery(AtBrowsers, {
+ where: { atId, browserId },
+ attributes: atBrowsersAttributes,
+ transaction
+ });
+};
+
+module.exports = { updateAtBrowser };
diff --git a/server/models/services/helpers.js b/server/models/services/helpers.js
index 402787495..3db63d195 100644
--- a/server/models/services/helpers.js
+++ b/server/models/services/helpers.js
@@ -12,7 +12,8 @@ const {
UserRoles,
UserAts,
CollectionJob,
- CollectionJobTestStatus
+ CollectionJobTestStatus,
+ AtBrowsers
} = require('../index');
/**
@@ -32,6 +33,7 @@ module.exports = {
AT_VERSION_ATTRIBUTES: getSequelizeModelAttributes(AtVersion),
BROWSER_ATTRIBUTES: getSequelizeModelAttributes(Browser),
BROWSER_VERSION_ATTRIBUTES: getSequelizeModelAttributes(BrowserVersion),
+ AT_BROWSERS_ATTRIBUTES: getSequelizeModelAttributes(AtBrowsers),
ROLE_ATTRIBUTES: getSequelizeModelAttributes(Role),
TEST_PLAN_ATTRIBUTES: getSequelizeModelAttributes(TestPlan),
TEST_PLAN_VERSION_ATTRIBUTES: getSequelizeModelAttributes(TestPlanVersion),
diff --git a/server/resolvers/RequiredReportOperations/createRequiredReportResolver.js b/server/resolvers/RequiredReportOperations/createRequiredReportResolver.js
new file mode 100644
index 000000000..2bf27341d
--- /dev/null
+++ b/server/resolvers/RequiredReportOperations/createRequiredReportResolver.js
@@ -0,0 +1,28 @@
+const { AuthenticationError } = require('apollo-server');
+const { updateAtBrowser } = require('../../models/services/AtBrowserService');
+
+const createRequiredReportResolver = async (
+ { parentContext: { atId, browserId, phase } },
+ _,
+ context
+) => {
+ const { user, transaction } = context;
+ if (!user?.roles.find(role => role.name === 'ADMIN')) {
+ throw new AuthenticationError();
+ }
+
+ let updateParams = {};
+
+ if (phase === 'CANDIDATE') {
+ updateParams = { isCandidate: true };
+ }
+ if (phase === 'RECOMMENDED') {
+ updateParams = { isRecommended: true };
+ }
+
+ await updateAtBrowser({ atId, browserId, updateParams, transaction });
+
+ return { atId, browserId, phase };
+};
+
+module.exports = createRequiredReportResolver;
diff --git a/server/resolvers/RequiredReportOperations/deleteRequiredReportResolver.js b/server/resolvers/RequiredReportOperations/deleteRequiredReportResolver.js
new file mode 100644
index 000000000..d1e97f410
--- /dev/null
+++ b/server/resolvers/RequiredReportOperations/deleteRequiredReportResolver.js
@@ -0,0 +1,28 @@
+const { AuthenticationError } = require('apollo-server');
+const { updateAtBrowser } = require('../../models/services/AtBrowserService');
+
+const deleteRequiredReportResolver = async (
+ { parentContext: { atId, browserId, phase } },
+ _,
+ context
+) => {
+ const { user, transaction } = context;
+ if (!user?.roles.find(role => role.name === 'ADMIN')) {
+ throw new AuthenticationError();
+ }
+
+ let updateParams = {};
+
+ if (phase === 'CANDIDATE') {
+ updateParams = { isCandidate: false };
+ }
+ if (phase === 'RECOMMENDED') {
+ updateParams = { isRecommended: false };
+ }
+
+ await updateAtBrowser({ atId, browserId, updateParams, transaction });
+
+ return { atId, browserId, phase };
+};
+
+module.exports = deleteRequiredReportResolver;
diff --git a/server/resolvers/RequiredReportOperations/index.js b/server/resolvers/RequiredReportOperations/index.js
new file mode 100644
index 000000000..1a1a91c11
--- /dev/null
+++ b/server/resolvers/RequiredReportOperations/index.js
@@ -0,0 +1,9 @@
+const createRequiredReport = require('./createRequiredReportResolver');
+const updateRequiredReport = require('./updateRequiredReportResolver');
+const deleteRequiredReport = require('./deleteRequiredReportResolver');
+
+module.exports = {
+ createRequiredReport,
+ updateRequiredReport,
+ deleteRequiredReport
+};
diff --git a/server/resolvers/RequiredReportOperations/updateRequiredReportResolver.js b/server/resolvers/RequiredReportOperations/updateRequiredReportResolver.js
new file mode 100644
index 000000000..a27c3e1f4
--- /dev/null
+++ b/server/resolvers/RequiredReportOperations/updateRequiredReportResolver.js
@@ -0,0 +1,46 @@
+const { AuthenticationError } = require('apollo-server');
+const { updateAtBrowser } = require('../../models/services/AtBrowserService');
+
+const updateRequiredReportResolver = async (
+ { parentContext: { atId, browserId, phase } },
+ { atId: inputAtId, browserId: inputBrowserId },
+ context
+) => {
+ const { user, transaction } = context;
+ if (!user?.roles.find(role => role.name === 'ADMIN')) {
+ throw new AuthenticationError();
+ }
+
+ let updateParams = {};
+
+ // These conditionals will change values in the At/Browsers table
+ // in the database. Each updateAtBrowser() call changes the boolean value
+ // for a particular row in the database. The booleans for two row need to be
+ // changed. So we call updateAtBrowser() twice.
+ if (phase === 'CANDIDATE') {
+ updateParams = { isCandidate: false };
+ await updateAtBrowser({ atId, browserId, updateParams, transaction });
+ updateParams = { isCandidate: true };
+ await updateAtBrowser({
+ atId: inputAtId,
+ browserId: inputBrowserId,
+ updateParams,
+ transaction
+ });
+ }
+ if (phase === 'RECOMMENDED') {
+ updateParams = { isRecommended: false };
+ await updateAtBrowser({ atId, browserId, updateParams, transaction });
+ updateParams = { isRecommended: true };
+ await updateAtBrowser({
+ atId: inputAtId,
+ browserId: inputBrowserId,
+ updateParams,
+ transaction
+ });
+ }
+
+ return { atId: inputAtId, browserId: inputBrowserId, phase };
+};
+
+module.exports = updateRequiredReportResolver;
diff --git a/server/resolvers/index.js b/server/resolvers/index.js
index 58bfd1d80..cf7364cd4 100644
--- a/server/resolvers/index.js
+++ b/server/resolvers/index.js
@@ -15,6 +15,7 @@ const addViewer = require('./addViewerResolver');
const mutateAt = require('./mutateAtResolver');
const mutateAtVersion = require('./mutateAtVersionResolver');
const mutateBrowser = require('./mutateBrowserResolver');
+const mutateRequiredReport = require('./mutateRequiredReportResolver');
const mutateTestPlanReport = require('./mutateTestPlanReportResolver');
const mutateTestPlanRun = require('./mutateTestPlanRunResolver');
const mutateTestResult = require('./mutateTestResultResolver');
@@ -34,6 +35,7 @@ const AtOperations = require('./AtOperations');
const AtVersionOperations = require('./AtVersionOperations');
const BrowserOperations = require('./BrowserOperations');
const TestPlan = require('./TestPlan');
+const RequiredReportOperations = require('./RequiredReportOperations');
const TestPlanVersion = require('./TestPlanVersion');
const TestPlanReport = require('./TestPlanReport');
const TestPlanReportOperations = require('./TestPlanReportOperations');
@@ -75,6 +77,7 @@ const resolvers = {
testResult: mutateTestResult,
testPlanVersion: mutateTestPlanVersion,
collectionJob: mutateCollectionJob,
+ requiredReport: mutateRequiredReport,
createTestPlanReport,
updateMe,
addViewer,
@@ -99,6 +102,7 @@ const resolvers = {
TestResultOperations,
TestPlanVersionOperations,
CollectionJobOperations,
+ RequiredReportOperations,
AtVersion
};
diff --git a/server/resolvers/mutateRequiredReportResolver.js b/server/resolvers/mutateRequiredReportResolver.js
new file mode 100644
index 000000000..e0b2b8533
--- /dev/null
+++ b/server/resolvers/mutateRequiredReportResolver.js
@@ -0,0 +1,9 @@
+const mutateRequiredReportResolver = (
+ _,
+ { atId, browserId, phase },
+ context // eslint-disable-line no-unused-vars
+) => {
+ return { parentContext: { atId, browserId, phase } };
+};
+
+module.exports = mutateRequiredReportResolver;
diff --git a/server/tests/integration/graphql.test.js b/server/tests/integration/graphql.test.js
index 7ffbf8c69..93a8b777f 100644
--- a/server/tests/integration/graphql.test.js
+++ b/server/tests/integration/graphql.test.js
@@ -801,6 +801,27 @@ describe('graphql', () => {
}
}
deleteCollectionJob(id: 1)
+ requiredReport(atId: 1, browserId: 1, phase: CANDIDATE) {
+ __typename
+ createRequiredReport {
+ __typename
+ atId
+ browserId
+ phase
+ }
+ updateRequiredReport(atId: 1, browserId: 1) {
+ __typename
+ atId
+ browserId
+ phase
+ }
+ deleteRequiredReport {
+ __typename
+ atId
+ browserId
+ phase
+ }
+ }
}
`,
{