Skip to content

Commit

Permalink
Merge pull request #1866 from Giveth/update-verify-approve-conditions
Browse files Browse the repository at this point in the history
Update verify approve conditions
  • Loading branch information
divine-comedian authored Dec 18, 2024
2 parents f0c3fc8 + b3dfb59 commit 445fe68
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 30 deletions.
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 @@ -417,24 +417,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,
);

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);
});

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

0 comments on commit 445fe68

Please sign in to comment.