Skip to content

Commit

Permalink
feat: Vendor verification (#1208)
Browse files Browse the repository at this point in the history
* First attempt at migrations and seeds for vendors

* Correct vendors resolver

* vendorByNameResolver

* vendorById

* Add self to vendors for testing

* Association with "company" by User

* Improve gql interface for vendor queries

* Temporarily disallow admins for user and prevent review for incorrect vendors

* First pass on limiting reviews to appropriate vendors

* reduce default deep fetching of user vendor ats

* schema test

* Add and update spec tests for Vendor table

* Correct location for vendors schema test

* Further testing adjustments, Vendor

* User company updates, testing schema

* Update mocks for Vendor

* Remove User.company from schema testing

* Associate vendor with fake vendor user

* Set vendors back to previous state

* Add self back to admins.txt

* Trim vendor company name

* Remove unnecessary company from TestPlanReportStatusDialogMock, update snapshots
  • Loading branch information
stalgiag authored Sep 25, 2024
1 parent 34d7aac commit b8b13d4
Show file tree
Hide file tree
Showing 31 changed files with 940 additions and 51 deletions.
45 changes: 33 additions & 12 deletions client/components/CandidateReview/TestPlans/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import ClippedProgressBar from '@components/common/ClippedProgressBar';
import { dates } from 'shared';
import './TestPlans.css';
import { calculations } from 'shared';
import { UserPropType } from '../../common/proptypes';

const FullHeightContainer = styled(Container)`
min-height: calc(100vh - 64px);
Expand Down Expand Up @@ -177,7 +178,7 @@ const None = styled.span`
}
`;

const TestPlans = ({ testPlanVersions }) => {
const TestPlans = ({ testPlanVersions, me }) => {
const [atExpandTableItems, setAtExpandTableItems] = useState({
1: true,
2: true,
Expand Down Expand Up @@ -503,20 +504,39 @@ const TestPlans = ({ testPlanVersions }) => {
.filter(t => t.isCandidateReview === true)
.filter(t => uniqueFilter(t, uniqueLinks, 'link'));

const canReview =
me.roles.includes('ADMIN') ||
(me.roles.includes('VENDOR') &&
me.company.ats.some(at => at.id === atId));

const getTitleEl = () => {
if (canReview) {
return (
<Link
to={`/candidate-test-plan/${testPlanVersion.id}/${atId}`}
>
{getTestPlanVersionTitle(testPlanVersion, {
includeVersionString: true
})}{' '}
({testsCount} Test
{testsCount === 0 || testsCount > 1 ? `s` : ''})
</Link>
);
}
return (
<>
{getTestPlanVersionTitle(testPlanVersion, {
includeVersionString: true
})}{' '}
({testsCount} Test
{testsCount === 0 || testsCount > 1 ? `s` : ''})
</>
);
};
return (
dataExists && (
<tr key={testPlanVersion.id}>
<th>
<Link
to={`/candidate-test-plan/${testPlanVersion.id}/${atId}`}
>
{getTestPlanVersionTitle(testPlanVersion, {
includeVersionString: true
})}{' '}
({testsCount} Test
{testsCount === 0 || testsCount > 1 ? `s` : ''})
</Link>
</th>
<th>{getTitleEl()}</th>
<CenteredTd>
<i>
{dates.convertDateToString(
Expand Down Expand Up @@ -778,6 +798,7 @@ TestPlans.propTypes = {
)
})
).isRequired,
me: UserPropType.isRequired,
triggerPageUpdate: PropTypes.func
};

Expand Down
6 changes: 5 additions & 1 deletion client/components/CandidateReview/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import { useQuery } from '@apollo/client';
import PageStatus from '../common/PageStatus';
import TestPlans from './TestPlans';
import { CANDIDATE_REVIEW_PAGE_QUERY } from './queries';
import { ME_QUERY } from '../App/queries';

const CandidateReview = () => {
const { loading, data, error } = useQuery(CANDIDATE_REVIEW_PAGE_QUERY, {
fetchPolicy: 'cache-and-network'
});

const { data: meData } = useQuery(ME_QUERY);
const { me } = meData;

if (error) {
return (
<PageStatus
Expand All @@ -33,7 +37,7 @@ const CandidateReview = () => {

const testPlanVersions = data.testPlanVersions;

return <TestPlans testPlanVersions={testPlanVersions} />;
return <TestPlans testPlanVersions={testPlanVersions} me={me} />;
};

export default CandidateReview;
17 changes: 14 additions & 3 deletions client/components/ConfirmAuth/index.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React from 'react';
import { Navigate } from 'react-router-dom';
import { Navigate, useParams } from 'react-router-dom';
import PropTypes from 'prop-types';
import { useQuery } from '@apollo/client';
import { ME_QUERY } from '../App/queries';
import { evaluateAuth } from '../../utils/evaluateAuth';

const ConfirmAuth = ({ children, requiredPermission }) => {
const ConfirmAuth = ({ children, requiredPermission, requireVendorForAt }) => {
const { data } = useQuery(ME_QUERY);
const { atId } = useParams();

const auth = evaluateAuth(data && data.me ? data.me : {});
const { roles, username, isAdmin, isSignedIn } = auth;
const company = data && data.me ? data.me.company : null;

if (!username) return <Navigate to={{ pathname: '/invalid-request' }} />;

Expand All @@ -21,6 +23,14 @@ const ConfirmAuth = ({ children, requiredPermission }) => {
return <Navigate to="/404" replace />;
}

// Check if the user's company is the vendor for the associated At
if (requireVendorForAt && !isAdmin) {
const isVendorForAt = company && company.ats.some(at => at.id === atId);
if (!isVendorForAt) {
return <Navigate to="/404" replace />;
}
}

return children;
};

Expand All @@ -29,7 +39,8 @@ ConfirmAuth.propTypes = {
PropTypes.arrayOf(PropTypes.node),
PropTypes.node
]).isRequired,
requiredPermission: PropTypes.string
requiredPermission: PropTypes.string,
requireVendorForAt: PropTypes.bool
};

export default ConfirmAuth;
6 changes: 6 additions & 0 deletions client/components/common/fragments/Me.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ const ME_FIELDS = gql`
id
username
roles
company {
id
ats {
id
}
}
}
`;

Expand Down
15 changes: 14 additions & 1 deletion client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,20 @@ window.signMeInAsTester = username => {
};

window.signMeInAsVendor = username => {
return signMeInCommon({ username, roles: [{ name: 'VENDOR' }] });
return signMeInCommon({
username,
roles: [{ name: 'VENDOR' }],
company: {
id: '1',
name: 'vispero',
ats: [
{
id: '1',
name: 'JAWS'
}
]
}
});
};

window.startTestTransaction = async () => {
Expand Down
2 changes: 1 addition & 1 deletion client/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default () => (
exact
path="/candidate-test-plan/:testPlanVersionId/:atId"
element={
<ConfirmAuth requiredPermission="VENDOR">
<ConfirmAuth requiredPermission="VENDOR" requireVendorForAt={true}>
<CandidateTestPlanRun />
</ConfirmAuth>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export default testQueuePageQuery => [
__typename: 'User',
id: '1',
username: 'foo-bar',
roles: ['ADMIN', 'TESTER']
roles: ['ADMIN', 'TESTER'],
company: {
id: '1',
name: 'Company',
ats: []
}
},
users: [
{
Expand All @@ -18,23 +23,38 @@ export default testQueuePageQuery => [
username: 'foo-bar',
roles: ['ADMIN', 'TESTER'],
isBot: false,
ats: []
ats: [],
company: {
id: '1',
name: 'Company',
ats: []
}
},
{
__typename: 'User',
id: '4',
username: 'bar-foo',
roles: ['TESTER'],
isBot: false,
ats: []
ats: [],
company: {
id: '1',
name: 'Company',
ats: []
}
},
{
__typename: 'User',
id: '5',
username: 'boo-far',
roles: ['TESTER'],
isBot: false,
ats: []
ats: [],
company: {
id: '1',
name: 'Company',
ats: []
}
}
],
ats: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export default testQueuePageQuery => [
__typename: 'User',
id: '4',
username: 'bar-foo',
roles: ['TESTER']
roles: ['TESTER'],
company: {
id: '1',
name: 'Company',
ats: []
}
},
users: [
{
Expand All @@ -18,23 +23,38 @@ export default testQueuePageQuery => [
username: 'foo-bar',
roles: ['ADMIN', 'TESTER'],
isBot: false,
ats: []
ats: [],
company: {
id: '1',
name: 'Company',
ats: []
}
},
{
__typename: 'User',
id: '4',
username: 'bar-foo',
roles: ['TESTER'],
isBot: false,
ats: []
ats: [],
company: {
id: '1',
name: 'Company',
ats: []
}
},
{
__typename: 'User',
id: '5',
username: 'boo-far',
roles: ['TESTER'],
isBot: false,
ats: []
ats: [],
company: {
id: '1',
name: 'Company',
ats: []
}
}
],
ats: [],
Expand Down
36 changes: 34 additions & 2 deletions client/tests/e2e/snapshots/saved/_candidate-review.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,23 @@ <h3>
</th>
<td class="css-niacka"><i>Jul 6, 2022</i></td>
<td class="css-niacka"><i>Jan 2, 2023</i></td>
<td class="css-niacka"></td>
<td class="css-niacka">
<span class="changes-requested css-awg8i9"
><svg
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="flag"
class="svg-inline--fa fa-flag"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512">
<path
fill="currentColor"
d="M64 32C64 14.3 49.7 0 32 0S0 14.3 0 32V64 368 480c0 17.7 14.3 32 32 32s32-14.3 32-32V352l64.3-16.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30V66.1c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L64 48V32z"></path></svg
>Changes requested for 1 test</span
>
</td>
<td class="css-niacka">
<a aria-label="97%" href="/candidate-test-plan/24/1"
><div class="progress clipped">
Expand Down Expand Up @@ -317,7 +333,23 @@ <h3 class="css-8wvxfl">Review Status Summary</h3>
<tbody>
<tr>
<td>Modal Dialog Example V22.05.26</td>
<td class="css-niacka"></td>
<td class="css-niacka">
<span class="changes-requested css-awg8i9"
><svg
aria-hidden="true"
focusable="false"
data-prefix="fas"
data-icon="flag"
class="svg-inline--fa fa-flag"
role="img"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512">
<path
fill="currentColor"
d="M64 32C64 14.3 49.7 0 32 0S0 14.3 0 32V64 368 480c0 17.7 14.3 32 32 32s32-14.3 32-32V352l64.3-16.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30V66.1c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L64 48V32z"></path></svg
>Changes requested for 1 test</span
>
</td>
<td class="css-niacka"></td>
<td class="css-niacka"></td>
</tr>
Expand Down
Loading

0 comments on commit b8b13d4

Please sign in to comment.