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

Implement fix probelm of cancelled project when users just have one boosting #741

Merged
merged 3 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions src/repositories/powerBoostingRepository.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import {
assertThrowsAsync,
createProjectData,
generateRandomEtheriumAddress,
saveProjectDirectlyToDb,
saveUserDirectlyToDb,
} from '../../test/testUtils';
import {
cancelProjectBoosting,
findPowerBoostings,
findUserPowerBoosting,
findUsersWhoBoostedProject,
getPowerBoostingSnapshotRound,
insertSinglePowerBoosting,
setMultipleBoosting,
setSingleBoosting,
takePowerBoostingSnapshot,
} from './powerBoostingRepository';
import { assert, use } from 'chai';
Expand All @@ -20,10 +23,12 @@ import { PowerBoostingSnapshot } from '../entities/powerBoostingSnapshot';
import { getConnection } from 'typeorm';
import { Reaction } from '../entities/reaction';
import { findUsersWhoLikedProject } from './reactionRepository';
import { errorMessages } from '../utils/errorMessages';

describe('findUserPowerBoosting() testCases', findUserPowerBoostingTestCases);
describe('findPowerBoostings() testCases', findPowerBoostingsTestCases);
describe('setMultipleBoosting() testCases', setMultipleBoostingTestCases);
describe('setSingleBoosting() testCases', setSingleBoostingTestCases);
describe('power boosting snapshot testCases', powerBoostingSnapshotTests);
describe(
'findUsersWhoBoostedProject() testCases',
Expand Down Expand Up @@ -726,6 +731,134 @@ function setMultipleBoostingTestCases() {
});
}

function setSingleBoostingTestCases() {
it('should set single boosting with 100%, when boosted multi project', async () => {
const user = await saveUserDirectlyToDb(generateRandomEtheriumAddress());
const firstProject = await saveProjectDirectlyToDb(createProjectData());
const secondProject = await saveProjectDirectlyToDb(createProjectData());
const thirdProject = await saveProjectDirectlyToDb(createProjectData());
await setMultipleBoosting({
userId: user.id,
projectIds: [firstProject.id, secondProject.id, thirdProject.id],
percentages: [40, 20, 40],
});
await setSingleBoosting({
userId: user.id,
projectId: firstProject.id,
percentage: 100,
});
const [userPowerBoostings] = await findPowerBoostings({
userId: user.id,
orderBy: {
field: 'updatedAt',
direction: 'ASC',
},
});
assert.equal(userPowerBoostings.length, 1);
assert.equal(userPowerBoostings[0].percentage, 100);
assert.equal(userPowerBoostings[0].projectId, firstProject.id);
});
it('should set single boosting with 100%', async () => {
const user = await saveUserDirectlyToDb(generateRandomEtheriumAddress());
const firstProject = await saveProjectDirectlyToDb(createProjectData());

await setSingleBoosting({
userId: user.id,
projectId: firstProject.id,
percentage: 100,
});

const [userPowerBoostings] = await findPowerBoostings({
userId: user.id,
orderBy: {
field: 'updatedAt',
direction: 'ASC',
},
});

assert.equal(userPowerBoostings.length, 1);
assert.equal(userPowerBoostings[0].percentage, 100);
assert.equal(userPowerBoostings[0].projectId, firstProject.id);
});

it('should set single boosting with 0%, when boosted multi project', async () => {
const user = await saveUserDirectlyToDb(generateRandomEtheriumAddress());
const firstProject = await saveProjectDirectlyToDb(createProjectData());
const secondProject = await saveProjectDirectlyToDb(createProjectData());
const thirdProject = await saveProjectDirectlyToDb(createProjectData());
await setMultipleBoosting({
userId: user.id,
projectIds: [firstProject.id, secondProject.id, thirdProject.id],
percentages: [20, 40, 40],
});

await setSingleBoosting({
userId: user.id,
projectId: firstProject.id,
percentage: 0,
});
const [userPowerBoostings] = await findPowerBoostings({
userId: user.id,
orderBy: {
field: 'updatedAt',
direction: 'ASC',
},
});

assert.equal(userPowerBoostings.length, 2);

assert.isOk(
userPowerBoostings.find(
powerBoosting =>
powerBoosting.project.id === secondProject.id &&
powerBoosting.percentage === 50,
),
);
assert.isOk(
userPowerBoostings.find(
powerBoosting =>
powerBoosting.project.id === thirdProject.id &&
powerBoosting.percentage === 50,
),
);
});
it('should set single boosting with 0%', async () => {
const user = await saveUserDirectlyToDb(generateRandomEtheriumAddress());
const firstProject = await saveProjectDirectlyToDb(createProjectData());

await setSingleBoosting({
userId: user.id,
projectId: firstProject.id,
percentage: 100,
});

await cancelProjectBoosting({
userId: user.id,
projectId: firstProject.id,
});
const [userPowerBoostings] = await findPowerBoostings({
userId: user.id,
orderBy: {
field: 'updatedAt',
direction: 'ASC',
},
});

assert.equal(userPowerBoostings.length, 0);
});
it('should get error when set single boosting with something between 0-100', async () => {
const user = await saveUserDirectlyToDb(generateRandomEtheriumAddress());
const firstProject = await saveProjectDirectlyToDb(createProjectData());
await assertThrowsAsync(async () => {
await setSingleBoosting({
userId: user.id,
projectId: firstProject.id,
percentage: 70,
});
}, errorMessages.ERROR_GIVPOWER_BOOSTING_FIRST_PROJECT_100_PERCENT);
});
}

function powerBoostingSnapshotTests() {
it('should take snapshot of power boosting', async () => {
await PowerBoosting.clear();
Expand Down
23 changes: 20 additions & 3 deletions src/repositories/powerBoostingRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
import { PowerSnapshot } from '../entities/powerSnapshot';
import { getRoundNumberByDate } from '../utils/powerBoostingUtils';
import { getKeyByValue } from '../utils/utils';
import { Reaction } from '../entities/reaction';

const MAX_PROJECT_BOOST_LIMIT = Number(
process.env.GIVPOWER_BOOSTING_USER_PROJECTS_LIMIT || '20',
Expand Down Expand Up @@ -125,12 +124,30 @@ export const insertSinglePowerBoosting = async (params: {
}).save();
};

export const cancelProjectBoosting = async (params: {
userId: number;
projectId: number;
}): Promise<PowerBoosting[]> =>
_setSingleBoosting({
...params,
percentage: 0,
projectIsCanceled: true,
});

export const setSingleBoosting = async (params: {
userId: number;
projectId: number;
percentage: number;
}): Promise<PowerBoosting[]> =>
_setSingleBoosting({ ...params, projectIsCanceled: false });

const _setSingleBoosting = async (params: {
userId: number;
projectId: number;
percentage: number;
projectIsCanceled: boolean;
}): Promise<PowerBoosting[]> => {
const { userId, projectId, percentage } = params;
const { userId, projectId, percentage, projectIsCanceled } = params;

if (percentage < 0 || percentage > 100) {
throw new Error(
Expand Down Expand Up @@ -161,7 +178,7 @@ export const setSingleBoosting = async (params: {
const commitData: PowerBoosting[] = [];

if (otherProjectsPowerBoostings.length === 0) {
if (percentage !== 100)
if (percentage !== 100 && !projectIsCanceled)
throw new Error(
i18n.__(
translationErrorMessagesKeys.ERROR_GIVPOWER_BOOSTING_FIRST_PROJECT_100_PERCENT,
Expand Down
21 changes: 21 additions & 0 deletions src/services/powerBoostingService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,25 @@ function changeUserBoostingsAfterProjectCancelledTestCases() {
assert.equal(secondUserBoostings[0].percentage, 100);
assert.equal(secondUserBoostings[0].projectId, firstProject.id);
});
it('should change user percentage to zero when project cancelled, even when just has 1 boositng', async () => {
const user1 = await saveUserDirectlyToDb(generateRandomEtheriumAddress());
const projectThatWouldGetCancelled = await saveProjectDirectlyToDb(
createProjectData(),
);
await setMultipleBoosting({
userId: user1.id,
projectIds: [projectThatWouldGetCancelled.id],
percentages: [100],
});

await changeUserBoostingsAfterProjectCancelled({
projectId: projectThatWouldGetCancelled.id,
});

// Changing percentages is async we sleep some milli seconds to make sure all updates has been done
await sleep(100);
const firstUserBoostings = await findUserPowerBoosting(user1.id);

assert.equal(firstUserBoostings.length, 0);
});
}
5 changes: 2 additions & 3 deletions src/services/powerBoostingService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
cancelProjectBoosting,
findPowerBoostings,
setSingleBoosting,
} from '../repositories/powerBoostingRepository';

export const changeUserBoostingsAfterProjectCancelled = async (params: {
Expand All @@ -12,10 +12,9 @@ export const changeUserBoostingsAfterProjectCancelled = async (params: {
projectId,
});
powerBoostings.forEach(powerBoosting =>
setSingleBoosting({
cancelProjectBoosting({
userId: powerBoosting.userId,
projectId,
percentage: 0,
}),
);
};