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

Update verify approve conditions #1866

Merged
merged 15 commits into from
Dec 18, 2024
Merged
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
"test:qfRoundService": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/qfRoundService.test.ts",
"test:project": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/entities/project.test.ts",
"test:projectsTab": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/server/adminJs/tabs/projectsTab.test.ts",
"test:projectVerificationTab": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/server/adminJs/tabs/projectVerificationTab.test.ts",
"test:syncUsersModelScore": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/cronJobs/syncUsersModelScore.test.ts",
"test:notifyDonationsWithSegment": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/cronJobs/notifyDonationsWithSegment.test.ts",
"test:checkProjectVerificationStatus": "NODE_ENV=test mocha ./test/pre-test-scripts.ts ./src/services/cronJobs/checkProjectVerificationStatus.test.ts",
Expand Down
22 changes: 9 additions & 13 deletions src/repositories/projectVerificationRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,24 +393,20 @@ export const approveProject = async (params: {
return project.save();
};

export const approveMultipleProjects = async (params: {
export const approveMultipleProjects = async ({
approved,
projectsIds,
}: {
approved: boolean;
projectsIds: string[] | number[];
}): Promise<UpdateResult> => {
if (params.approved) {
await Project.query(`
UPDATE project
SET "verificationStatus" = NULL
WHERE id IN (${params.projectsIds?.join(',')})
`);
}

return Project.createQueryBuilder('project')
.update<Project>(Project, {
isGivbackEligible: params.approved,
.update<Project>(Project)
.set({
isGivbackEligible: approved,
...(approved && { verificationStatus: null, verified: true }),
})
.where('project.id IN (:...ids)')
.setParameter('ids', params.projectsIds)
.where('project.id IN (:...ids)', { ids: projectsIds })
.returning('*')
.updateEntity(true)
.execute();
Expand Down
151 changes: 151 additions & 0 deletions src/server/adminJs/tabs/projectVerificationTab.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { assert } from 'chai';
import {
createProjectData,
saveProjectDirectlyToDb,
SEED_DATA,
} from '../../../../test/testUtils';
import { PROJECT_VERIFICATION_STATUSES } from '../../../entities/projectVerificationForm';
import { User } from '../../../entities/user';
import {
createProjectVerificationForm,
findProjectVerificationFormById,
} from '../../../repositories/projectVerificationRepository';
import { findUserById } from '../../../repositories/userRepository';
import { approveVerificationForms } from './projectVerificationTab';
import { findProjectById } from '../../../repositories/projectRepository';

describe(
'approveGivbacksEligibilityForm() TestCases',
approveGivbacksEligibilityFormTestCases,
);

MohammadPCh marked this conversation as resolved.
Show resolved Hide resolved
function approveGivbacksEligibilityFormTestCases() {
it('Should throw error if Givback Eligibility Form is on draft', async () => {
const project = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
verified: true,
listed: true,
});

const projectVerificationForm = await createProjectVerificationForm({
projectId: project.id,
userId: project.adminUserId,
});

projectVerificationForm.status = PROJECT_VERIFICATION_STATUSES.DRAFT;
await projectVerificationForm.save();

const adminUser = await findUserById(SEED_DATA.ADMIN_USER.id);

await approveVerificationForms(
{
currentAdmin: adminUser as User,
h: {},
resource: {},
records: [],
},
{
query: {
recordIds: String(projectVerificationForm.id),
},
},
true,
);

const updatedForm = await findProjectVerificationFormById(
projectVerificationForm.id,
);
assert.isOk(updatedForm);
assert.equal(updatedForm?.status, PROJECT_VERIFICATION_STATUSES.DRAFT);
});
MohammadPCh marked this conversation as resolved.
Show resolved Hide resolved

it('Should be able approve Givback Eligibility Form for not draft form', async () => {
const project = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
verified: true,
listed: true,
isGivbackEligible: false,
});

const projectVerificationForm = await createProjectVerificationForm({
projectId: project.id,
userId: project.adminUserId,
});
projectVerificationForm.status = PROJECT_VERIFICATION_STATUSES.SUBMITTED;
await projectVerificationForm.save();

const adminUser = await findUserById(SEED_DATA.ADMIN_USER.id);

await approveVerificationForms(
{
currentAdmin: adminUser as User,
h: {},
resource: {},
records: [],
},
{
query: {
recordIds: String(projectVerificationForm.id),
},
},
true,
);

const updatedForm = await findProjectVerificationFormById(
projectVerificationForm.id,
);
const updatedProject = await findProjectById(project.id);
assert.isOk(updatedForm);
assert.equal(updatedForm?.status, PROJECT_VERIFICATION_STATUSES.VERIFIED);
assert.isTrue(updatedProject?.isGivbackEligible);
// assert.equal(updatedProject?.verificationFormStatus);
});

it('Should be able to reject Givback Eligibility Form for not draft form', async () => {
const project = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
verified: true,
listed: true,
isGivbackEligible: false,
});

const projectVerificationForm = await createProjectVerificationForm({
projectId: project.id,
userId: project.adminUserId,
});
projectVerificationForm.status = PROJECT_VERIFICATION_STATUSES.SUBMITTED;
await projectVerificationForm.save();

const adminUser = await findUserById(SEED_DATA.ADMIN_USER.id);

await approveVerificationForms(
{
currentAdmin: adminUser as User,
h: {},
resource: {},
records: [],
},
{
query: {
recordIds: String(projectVerificationForm.id),
},
},
false,
);

const updatedForm = await findProjectVerificationFormById(
projectVerificationForm.id,
);
const updatedProject = await findProjectById(project.id);

assert.isOk(updatedForm);
assert.equal(updatedForm?.status, PROJECT_VERIFICATION_STATUSES.REJECTED);
assert.isFalse(updatedProject?.isGivbackEligible);
});
}
23 changes: 21 additions & 2 deletions src/server/adminJs/tabs/projectVerificationTab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,25 @@ export const approveVerificationForms = async (
? PROJECT_VERIFICATION_STATUSES.VERIFIED
: PROJECT_VERIFICATION_STATUSES.REJECTED;
const formIds = request?.query?.recordIds?.split(',');

logger.info('approveVerificationForms() formIds', formIds);

// Preliminary check for DRAFT status
const draftProjects = await ProjectVerificationForm.createQueryBuilder(
'form',
)
.where('form.id IN (:...formIds)', { formIds })
.andWhere('form.status = :status', {
status: PROJECT_VERIFICATION_STATUSES.DRAFT,
})
.getMany();

if (draftProjects.length > 0) {
throw new Error(
`Cannot ${approved ? 'approve' : 'reject'} project${draftProjects.length > 1 ? 's' : ''} in DRAFT status.`,
);
}

// call repositories
const projectsForms = await verifyMultipleForms({
verificationStatus,
Expand All @@ -261,7 +280,7 @@ export const approveVerificationForms = async (
return project.id;
});

// need to requery them as the RAW is not an entity
// need to re-query them as the RAW is not an entity
const verificationForms = await ProjectVerificationForm.createQueryBuilder(
'projectVerificationForm',
)
Expand Down Expand Up @@ -294,7 +313,7 @@ export const approveVerificationForms = async (
}`;
} catch (error) {
logger.error('verifyVerificationForm() error', error);
responseMessage = `Bulk verify failed ${error.message}`;
responseMessage = `Bulk verify failed: ${error.message}`;
responseType = 'danger';
}
return {
Expand Down
80 changes: 78 additions & 2 deletions src/server/adminJs/tabs/projectsTab.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,14 @@ describe(
);

describe('verifyProjects() test cases', verifyProjectsTestCases);

describe('listDelist() test cases', listDelistTestCases);

describe(
'addToFeaturedProjectUpdate() TestCases',
addToFeaturedProjectUpdateTestCases,
);

describe(
'exportProjectsWithFiltersToCsv() test cases',
exportProjectsWithFiltersToCsvTestCases,
Expand All @@ -63,6 +66,74 @@ describe(
updateStatusOfProjectsTestCases,
);

describe('unverifyProjects() test cases', unverifyProjectsTestCases);

function unverifyProjectsTestCases() {
it('Should unverify project if isGivbacksEligible is false', async () => {
const project = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
verified: true,
listed: true,
reviewStatus: ReviewStatus.Listed,
isGivbackEligible: false,
});
const adminUser = await findUserById(SEED_DATA.ADMIN_USER.id);
await verifyProjects(
{
currentAdmin: adminUser as User,
h: {},
resource: {},
records: [],
},
{
query: {
recordIds: String(project.id),
},
},
false,
);

const updatedProject = await findProjectById(project.id);
assert.isOk(updatedProject);
assert.isFalse(updatedProject?.verified);
assert.isTrue(updatedProject?.listed);
assert.equal(updatedProject?.reviewStatus, ReviewStatus.Listed);
});

it('Should not unverify project if isGivbacksEligible is true', async () => {
const project = await saveProjectDirectlyToDb({
...createProjectData(),
slug: String(new Date().getTime()),
verified: true,
listed: true,
reviewStatus: ReviewStatus.Listed,
isGivbackEligible: true,
});
const adminUser = await findUserById(SEED_DATA.ADMIN_USER.id);
await verifyProjects(
{
currentAdmin: adminUser as User,
h: {},
resource: {},
records: [],
},
{
query: {
recordIds: String(project.id),
},
},
false,
);

const updatedProject = await findProjectById(project.id);
assert.isOk(updatedProject);
assert.isTrue(updatedProject?.verified);
assert.isTrue(updatedProject?.listed);
assert.equal(updatedProject?.reviewStatus, ReviewStatus.Listed);
});
}

function updateStatusOfProjectsTestCases() {
it('should deList and unverified project, when changing status of one project to cancelled', async () => {
const project = await saveProjectDirectlyToDb({
Expand Down Expand Up @@ -421,8 +492,9 @@ function listDelistTestCases() {
);
});
}

function verifyProjectsTestCases() {
it('should unverify projects when the badge is revoked and set verification form as draft', async () => {
it('should not change verification status of projects when the badge is revoked and set verification form as draft', async () => {
const project = await saveProjectDirectlyToDb({
...createProjectData(),
title: String(new Date().getTime()),
Expand Down Expand Up @@ -474,7 +546,7 @@ function verifyProjectsTestCases() {
project.id,
);
assert.isOk(updatedProject);
assert.isFalse(updatedProject?.verified);
assert.isTrue(updatedProject?.verified);
assert.isTrue(updatedProject?.listed);
assert.equal(updatedProject?.reviewStatus, ReviewStatus.Listed);
assert.equal(
Expand All @@ -496,6 +568,7 @@ function verifyProjectsTestCases() {
);
assert.equal(updatedProject?.verificationStatus, RevokeSteps.Revoked);
});

it('should not change listed(true) status when verifying project and set verification form as verified', async () => {
const project = await saveProjectDirectlyToDb({
...createProjectData(),
Expand Down Expand Up @@ -598,6 +671,7 @@ function verifyProjectsTestCases() {
listed: true,
reviewStatus: ReviewStatus.Listed,
verificationStatus: RevokeSteps.Revoked,
isGivbackEligible: false,
});
const projectVerificationForm = await createProjectVerificationForm({
projectId: project.id,
Expand Down Expand Up @@ -654,6 +728,7 @@ function verifyProjectsTestCases() {
verified: true,
listed: false,
reviewStatus: ReviewStatus.NotListed,
isGivbackEligible: false,
});
const adminUser = await findUserById(SEED_DATA.ADMIN_USER.id);
await verifyProjects(
Expand Down Expand Up @@ -724,6 +799,7 @@ function verifyProjectsTestCases() {
title: String(new Date().getTime()),
slug: String(new Date().getTime()),
verified: true,
isGivbackEligible: false,
});
const adminUser = await findUserById(SEED_DATA.ADMIN_USER.id);
await verifyProjects(
Expand Down
Loading
Loading