diff --git a/packages/firebase/__tests__/funtions/__snapshots__/common.test.ts.snap b/packages/firebase/__tests__/funtions/__snapshots__/common.test.ts.snap index 235f07577..3805af90c 100644 --- a/packages/firebase/__tests__/funtions/__snapshots__/common.test.ts.snap +++ b/packages/firebase/__tests__/funtions/__snapshots__/common.test.ts.snap @@ -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", ] `; diff --git a/packages/firebase/__tests__/funtions/common.test.ts b/packages/firebase/__tests__/funtions/common.test.ts index 1c444d1c2..ca1a23454 100644 --- a/packages/firebase/__tests__/funtions/common.test.ts +++ b/packages/firebase/__tests__/funtions/common.test.ts @@ -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', () => { diff --git a/packages/firebase/__tests__/funtions/proposal.test.ts b/packages/firebase/__tests__/funtions/proposal.test.ts index 173725f74..8ed0932a8 100644 --- a/packages/firebase/__tests__/funtions/proposal.test.ts +++ b/packages/firebase/__tests__/funtions/proposal.test.ts @@ -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', + funding: 300, + cardId: `test-card-id-for-common-${commonId}` +}); + describe('Proposal Related Cloud Functions', () => { afterAll(async () => { await test.cleanup(); @@ -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', () => { diff --git a/packages/firebase/__tests__/helpers/createTestCommon.ts b/packages/firebase/__tests__/helpers/createTestCommon.ts index 4e3fda2ed..13569881a 100644 --- a/packages/firebase/__tests__/helpers/createTestCommon.ts +++ b/packages/firebase/__tests__/helpers/createTestCommon.ts @@ -3,7 +3,7 @@ import { ICommonEntity } from '@common/types'; import { commonApp } from './supertests'; import { getTestAuthToken } from './auth'; -export const createTestCommon = async (userId = 'test-user'): Promise => { +export const createTestCommon = async (userId = 'test-user', zeroContribution = true): Promise => { const payload = { name: 'Common Test', image: 'https://llandscapes-10674.kxcdn.com/wp-content/uploads/2019/07/lighting.jpg', @@ -11,7 +11,7 @@ export const createTestCommon = async (userId = 'test-user'): Promise; @@ -73,7 +73,7 @@ export const createCommon = async ( description, contributionType, contributionAmount, - fundingGoalDeadline + zeroContribution, } = payload; // @todo Check if user exists @@ -81,7 +81,6 @@ export const createCommon = async ( const common = await commonDb.add({ name, image, - fundingGoalDeadline, rules: (rules as ICommonRule[]) || [], links: (links as ICommonLink[]) || [], @@ -97,7 +96,8 @@ export const createCommon = async ( contributionType, founderId: userId, - minFeeToJoin: contributionAmount + minFeeToJoin: contributionAmount, + zeroContribution, }, register: 'na' diff --git a/packages/firebase/functions/src/proposals/business/createJoinRequest.ts b/packages/firebase/functions/src/proposals/business/createJoinRequest.ts index fed7a78b5..15b3219bd 100644 --- a/packages/firebase/functions/src/proposals/business/createJoinRequest.ts +++ b/packages/firebase/functions/src/proposals/business/createJoinRequest.ts @@ -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)}`, diff --git a/packages/firebase/functions/src/util/tests/helpers/mockers/commons/getCommon.mocker.ts b/packages/firebase/functions/src/util/tests/helpers/mockers/commons/getCommon.mocker.ts index f657c39b2..fa1127c78 100644 --- a/packages/firebase/functions/src/util/tests/helpers/mockers/commons/getCommon.mocker.ts +++ b/packages/firebase/functions/src/util/tests/helpers/mockers/commons/getCommon.mocker.ts @@ -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: [ diff --git a/packages/types/src/entities/ICommonEntity.ts b/packages/types/src/entities/ICommonEntity.ts index 559b76cd9..452af5f43 100644 --- a/packages/types/src/entities/ICommonEntity.ts +++ b/packages/types/src/entities/ICommonEntity.ts @@ -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 */ @@ -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 {