Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ Array [
"You must provide a valid URL",
"image is a required field",
"byline is a required field",
"fundingGoalDeadline is a required field",
"contributionAmount is a required field",
]
`;
2 changes: 1 addition & 1 deletion packages/firebase/__tests__/funtions/common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const validCommonCreationPayload = {
description: 'hey there, am i descriptive',
contributionType: 'one-time',
contributionAmount: 6500,
fundingGoalDeadline: new Date().getTime()
zeroContribution: true,
};

describe('Common Related Cloud Functions', () => {
Expand Down
78 changes: 78 additions & 0 deletions packages/firebase/__tests__/funtions/proposal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ const validFundingData = (commonId: string) => ({
title: 'I need money'
});

const validJoinDataZeroContribution = (commonId: string) => ({
commonId,
description: 'I wanna be a part, but without paying',
funding: 0,
cardId: `test-card-id-for-common-${commonId}`
});

const invalidJoinDataZeroContribution = (commonId: string) => ({
commonId,
description: 'I wanna be a part, but pay less that $5',
Copy link

@lpetkov-sw lpetkov-sw Apr 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo here: that -> than But no important at all :D

funding: 300,
cardId: `test-card-id-for-common-${commonId}`
});

describe('Proposal Related Cloud Functions', () => {
afterAll(async () => {
await test.cleanup();
Expand Down Expand Up @@ -168,6 +182,70 @@ describe('Proposal Related Cloud Functions', () => {
expect(response.body.type).toBe('join');
expect(response.body.commonId).toBe(common.id);
});

it('should make a join request when funding = 0 and 0 contribution is allowed', async () => {
// Setup
const joinerId = v4();
const founderId = v4();

const authToken = await getTestAuthToken(joinerId);
const common = await createTestCommon(founderId);

const response = await proposalsApp
.post(joinEndpoint)
.send(validJoinDataZeroContribution(common.id))
.set({
Authorization: authToken
});

expect(response.body.message).toBe('Join request successfully created!');
expect(response.body.proposerId).toBe(joinerId);
expect(response.body.type).toBe('join');
expect(response.body.commonId).toBe(common.id);

});

it('should not make a join request when 0 < funding < 5 and 0 contribution is allowed', async () => {
// Setup
const joinerId = v4();
const founderId = v4();

const authToken = await getTestAuthToken(joinerId);
const common = await createTestCommon(founderId);

const response = await proposalsApp
.post(joinEndpoint)
.send(invalidJoinDataZeroContribution(common.id))
.set({
Authorization: authToken
});

expect(response.body.error.includes(`The funding cannot be less than the minimum required funding`)).toBeTruthy();
expect(response.body.errorCode).toBe('GenericError');
expect(response.body.errorMessage).toBe('Your join request cannot be created, because the min fee to join is $65.00, but you provided $3.00');
expect(response.status).toBe(400);
});

it('should not make a join request when funding = 0 and 0 contribution is not allowed', async () => {
// Setup
const joinerId = v4();
const founderId = v4();

const authToken = await getTestAuthToken(joinerId);
const common = await createTestCommon(founderId, false); //@askAlexI if he's ok with that (having a second argument for zeroContribution) :)

const response = await proposalsApp
.post(joinEndpoint)
.send(validJoinDataZeroContribution(common.id))
.set({
Authorization: authToken
});

expect(response.body.error.includes(`The funding cannot be less than the minimum required funding`)).toBeTruthy();
expect(response.body.errorCode).toBe('GenericError');
expect(response.body.errorMessage).toBe('Your join request cannot be created, because the min fee to join is $65.00, but you provided $0.00');
expect(response.status).toBe(400);
});
});

describe('Funding Proposal Creation', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/firebase/__tests__/helpers/createTestCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { ICommonEntity } from '@common/types';
import { commonApp } from './supertests';
import { getTestAuthToken } from './auth';

export const createTestCommon = async (userId = 'test-user'): Promise<ICommonEntity> => {
export const createTestCommon = async (userId = 'test-user', zeroContribution = true): Promise<ICommonEntity> => {
const payload = {
name: 'Common Test',
image: 'https://llandscapes-10674.kxcdn.com/wp-content/uploads/2019/07/lighting.jpg',
byline: 'basically this is a test common',
description: 'hey there, am i descriptive',
contributionType: 'one-time',
contributionAmount: 6500,
fundingGoalDeadline: new Date().getTime() / 1000
zeroContribution,
};

const authToken = await getTestAuthToken(userId);
Expand Down
12 changes: 6 additions & 6 deletions packages/firebase/functions/src/common/business/createCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ const createCommonDataValidationScheme = yup.object({

description: yup.string().required(),

fundingGoalDeadline: yup.number().required(),

contributionAmount: yup.number().min(0).required(),

contributionType: yup
Expand All @@ -39,7 +37,9 @@ const createCommonDataValidationScheme = yup.object({

rules: yup.array(commonRuleValidationSchema).optional(),

links: yup.array(linkValidationSchema).optional()
links: yup.array(linkValidationSchema).optional(),

zeroContribution: yup.boolean(),
});

type CreateCommonPayload = yup.InferType<typeof createCommonDataValidationScheme>;
Expand Down Expand Up @@ -73,15 +73,14 @@ export const createCommon = async (
description,
contributionType,
contributionAmount,
fundingGoalDeadline
zeroContribution,
} = payload;

// @todo Check if user exists

const common = await commonDb.add({
name,
image,
fundingGoalDeadline,

rules: (rules as ICommonRule[]) || [],
links: (links as ICommonLink[]) || [],
Expand All @@ -97,7 +96,8 @@ export const createCommon = async (
contributionType,

founderId: userId,
minFeeToJoin: contributionAmount
minFeeToJoin: contributionAmount,
zeroContribution,
},

register: 'na'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ export const createJoinRequest = async (payload: CreateRequestToJoinPayload): Pr
);
}

// Check if the request is funded with less than required amount
if (common.metadata.minFeeToJoin > payload.funding) {
if (common.metadata.minFeeToJoin > payload.funding
&& (!common.metadata.zeroContribution || payload.funding !== 0)) {
throw new CommonError('The funding cannot be less than the minimum required funding', {
userMessage: `Your join request cannot be created, because the min fee to join is $${(common.metadata.minFeeToJoin / 100)
.toFixed(2)}, but you provided $${(payload.funding / 100).toFixed(2)}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ jest.mock('../../../../../common/database/getCommon', () =>
return {
links: [],
image: 'https://firebasestorage.googleapis.com/v0/b/common-staging-50741.appspot.com/o/public_img%2Fimg_1605603725987.jpg?alt=media&token=4fc5ab99-8f38-49f0-8d6e-83a94b30db60',
fundingGoalDeadline: 1606206379,
metadata: {
minFeeToJoin: 700,
description: 'testetest',
founderId: 'Xlun3Ux94Zfc73axkiuVdkktOWf1',
byline: 'testtestetstetst',
contributionType: contributionType
contributionType: contributionType,
zeroContribution: true,
},
raised: 0,
rules: [
Expand Down
11 changes: 5 additions & 6 deletions packages/types/src/entities/ICommonEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ export interface ICommonEntity extends IBaseEntity {
*/
raised: number;

/**
* The timestamp after witch you are able to
* create funding proposals
*/
fundingGoalDeadline: number;

/**
* List of all users, that are members of this common
*/
Expand Down Expand Up @@ -111,6 +105,11 @@ export interface ICommonMetadata {
* or only when they join
*/
contributionType: ContributionType;

/**
* Allow users to join common with zero contribution
*/
zeroContribution: boolean;
}

export interface ICommonUpdate {
Expand Down