From e6d9420d8e4307c9a55125eb5e06f4f849843090 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 30 May 2022 10:40:55 +0200 Subject: [PATCH 001/119] migration to rename admin-pending-creations --- .../migrations/0037-contributions_table.ts | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 database/migrations/0037-contributions_table.ts diff --git a/database/migrations/0037-contributions_table.ts b/database/migrations/0037-contributions_table.ts new file mode 100644 index 000000000..983593f51 --- /dev/null +++ b/database/migrations/0037-contributions_table.ts @@ -0,0 +1,53 @@ +/* MIGRATION to rename ADMIN_PENDING_CREATION table and add columns + */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('RENAME TABLE `admin_pending_creations` TO `contributions`;') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `userId` `user_id` int(10);') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `created` `contribution_date` datetime;') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `date` `created_at` datetime;') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `moderator` `moderator_id` int(10);') + + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `contribution_link_id` int(10) unsigned DEFAULT NULL AFTER `moderator_id`;', + ) + + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `confirmed_by` int(10) unsigned DEFAULT NULL AFTER `contribution_link_id`;', + ) + + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `confirmed_at` datetime DEFAULT NULL AFTER `confirmed_by`;', + ) + + await queryFn( + 'ALTER TABLE `contributions` ADD COLUMN `deleted_at` datetime DEFAULT NULL AFTER `confirmed_at`;', + ) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn('ALTER TABLE `contributions` DROP COLUMN IF EXISTS `deleted_at`;') + + await queryFn('ALTER TABLE `contributions` DROP COLUMN IF EXISTS `confirmed_at`;') + + await queryFn('ALTER TABLE `contributions` DROP COLUMN IF EXISTS `confirmed_by`;') + + await queryFn('ALTER TABLE `contributions` DROP COLUMN IF EXISTS `contribution_link_id`;') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `moderator_id` `moderator` int(10);') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `created_at` `date` datetime;') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `contribution_date` `created` datetime;') + + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `user_id` `userId` int(10);') + + await queryFn('RENAME TABLE `contributions` TO `admin_pending_creations`;') +} From 617ea9a2b0e43bd6d5207d31814e0d7ea622dcfe Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 30 May 2022 10:56:54 +0200 Subject: [PATCH 002/119] contribution entity --- .../0037-contributions_table/Contribution.ts | 45 +++++++++++++++++++ database/entity/Contribution.ts | 1 + database/entity/index.ts | 4 +- .../migrations/0037-contributions_table.ts | 8 ++-- 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 database/entity/0037-contributions_table/Contribution.ts create mode 100644 database/entity/Contribution.ts diff --git a/database/entity/0037-contributions_table/Contribution.ts b/database/entity/0037-contributions_table/Contribution.ts new file mode 100644 index 000000000..997bef2c7 --- /dev/null +++ b/database/entity/0037-contributions_table/Contribution.ts @@ -0,0 +1,45 @@ +import Decimal from 'decimal.js-light' +import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm' +import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' + +@Entity('contributions') +export class Contribution extends BaseEntity { + @PrimaryGeneratedColumn('increment', { unsigned: true }) + id: number + + @Column({ unsigned: true, nullable: false, name: 'user_id' }) + userId: number + + @Column({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP', name: 'created_at' }) + createdAt: Date + + @Column({ type: 'datetime', nullable: false, name: 'contribution_date' }) + contributionDate: Date + + @Column({ length: 255, nullable: false, collation: 'utf8mb4_unicode_ci' }) + memo: string + + @Column({ + type: 'decimal', + precision: 40, + scale: 20, + nullable: false, + transformer: DecimalTransformer, + }) + amount: Decimal + + @Column({ unsigned: true, nullable: true, name: 'moderator_id' }) + moderatorId: number + + @Column({ unsigned: true, nullable: true, name: 'contribution_link_id' }) + contributionLinkId: number + + @Column({ unsigned: true, nullable: true, name: 'confirmed_by' }) + confirmedBy: number + + @Column({ nullable: true, name: 'confirmed_at' }) + confirmedAt: Date + + @Column({ nullable: true, name: 'deleted_at' }) + deletedAt: Date +} diff --git a/database/entity/Contribution.ts b/database/entity/Contribution.ts new file mode 100644 index 000000000..ccb227359 --- /dev/null +++ b/database/entity/Contribution.ts @@ -0,0 +1 @@ +export { Contribution } from './0037-contributions_table/Contribution' diff --git a/database/entity/index.ts b/database/entity/index.ts index 542333755..54495975c 100644 --- a/database/entity/index.ts +++ b/database/entity/index.ts @@ -5,10 +5,10 @@ import { Transaction } from './Transaction' import { TransactionLink } from './TransactionLink' import { User } from './User' import { UserSetting } from './UserSetting' -import { AdminPendingCreation } from './AdminPendingCreation' +import { Contribution } from './Contribution' export const entities = [ - AdminPendingCreation, + Contribution, LoginElopageBuys, LoginEmailOptIn, Migration, diff --git a/database/migrations/0037-contributions_table.ts b/database/migrations/0037-contributions_table.ts index 983593f51..163959a3a 100644 --- a/database/migrations/0037-contributions_table.ts +++ b/database/migrations/0037-contributions_table.ts @@ -9,9 +9,9 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `userId` `user_id` int(10);') - await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `created` `contribution_date` datetime;') + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `created` `created_at` datetime;') - await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `date` `created_at` datetime;') + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `date` `contribution_date` datetime;') await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `moderator` `moderator_id` int(10);') @@ -43,9 +43,9 @@ export async function downgrade(queryFn: (query: string, values?: any[]) => Prom await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `moderator_id` `moderator` int(10);') - await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `created_at` `date` datetime;') + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `created_at` `created` datetime;') - await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `contribution_date` `created` datetime;') + await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `contribution_date` `date` datetime;') await queryFn('ALTER TABLE `contributions` CHANGE COLUMN `user_id` `userId` int(10);') From 4c7fc10d8f13378759a30f51589282d1ccf338bb Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 30 May 2022 10:57:25 +0200 Subject: [PATCH 003/119] change DB version --- backend/src/config/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 559b8e9c5..011fd8c3a 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -10,7 +10,7 @@ Decimal.set({ }) const constants = { - DB_VERSION: '0036-unique_previous_in_transactions', + DB_VERSION: '0037-contributions_table', DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0 LOG4JS_CONFIG: 'log4js-config.json', // default log level on production should be info From 69a3cc0264f04c167d825603c50dbf0a6f26627a Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 30 May 2022 14:15:34 +0200 Subject: [PATCH 004/119] use new Contribution Data Model --- ...dingCreation.ts => PendingContribution.ts} | 2 +- backend/src/graphql/resolver/AdminResolver.ts | 127 +++++++++--------- 2 files changed, 68 insertions(+), 61 deletions(-) rename backend/src/graphql/model/{PendingCreation.ts => PendingContribution.ts} (93%) diff --git a/backend/src/graphql/model/PendingCreation.ts b/backend/src/graphql/model/PendingContribution.ts similarity index 93% rename from backend/src/graphql/model/PendingCreation.ts rename to backend/src/graphql/model/PendingContribution.ts index 500ba6f6b..e8991deb7 100644 --- a/backend/src/graphql/model/PendingCreation.ts +++ b/backend/src/graphql/model/PendingContribution.ts @@ -2,7 +2,7 @@ import { ObjectType, Field, Int } from 'type-graphql' import Decimal from 'decimal.js-light' @ObjectType() -export class PendingCreation { +export class PendingContribution { @Field(() => String) firstName: string diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 8c3d71b73..323df8a99 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -11,7 +11,7 @@ import { FindOperator, } from '@dbTools/typeorm' import { UserAdmin, SearchUsersResult } from '@model/UserAdmin' -import { PendingCreation } from '@model/PendingCreation' +import { PendingContribution } from '@model/PendingContribution' import { CreatePendingCreations } from '@model/CreatePendingCreations' import { UpdatePendingCreation } from '@model/UpdatePendingCreation' import { RIGHTS } from '@/auth/RIGHTS' @@ -25,7 +25,7 @@ import { TransactionLink, TransactionLinkResult } from '@model/TransactionLink' import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' import { TransactionRepository } from '@repository/Transaction' import { calculateDecay } from '@/util/decay' -import { AdminPendingCreation } from '@entity/AdminPendingCreation' +import { Contribution } from '@entity/Contribution' import { hasElopageBuys } from '@/util/hasElopageBuys' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User as dbUser } from '@entity/User' @@ -183,15 +183,15 @@ export class AdminResolver { const creations = await getUserCreation(user.id) const creationDateObj = new Date(creationDate) if (isCreationValid(creations, amount, creationDateObj)) { - const adminPendingCreation = AdminPendingCreation.create() - adminPendingCreation.userId = user.id - adminPendingCreation.amount = amount - adminPendingCreation.created = new Date() - adminPendingCreation.date = creationDateObj - adminPendingCreation.memo = memo - adminPendingCreation.moderator = moderator.id + const contribution = Contribution.create() + contribution.userId = user.id + contribution.amount = amount + contribution.createdAt = new Date() + contribution.contributionDate = creationDateObj + contribution.memo = memo + contribution.moderatorId = moderator.id - await AdminPendingCreation.save(adminPendingCreation) + await Contribution.save(contribution) } return getUserCreation(user.id) } @@ -200,20 +200,20 @@ export class AdminResolver { @Mutation(() => CreatePendingCreations) async createPendingCreations( @Arg('pendingCreations', () => [CreatePendingCreationArgs]) - pendingCreations: CreatePendingCreationArgs[], + contributions: CreatePendingCreationArgs[], @Ctx() context: Context, ): Promise { let success = false const successfulCreation: string[] = [] const failedCreation: string[] = [] - for (const pendingCreation of pendingCreations) { - await this.createPendingCreation(pendingCreation, context) + for (const contribution of contributions) { + await this.createPendingCreation(contribution, context) .then(() => { - successfulCreation.push(pendingCreation.email) + successfulCreation.push(contribution.email) success = true }) .catch(() => { - failedCreation.push(pendingCreation.email) + failedCreation.push(contribution.email) }) } return { @@ -239,34 +239,34 @@ export class AdminResolver { const moderator = getUser(context) - const pendingCreationToUpdate = await AdminPendingCreation.findOne({ id }) + const contributionToUpdate = await Contribution.findOne({ id }) - if (!pendingCreationToUpdate) { - throw new Error('No creation found to given id.') + if (!contributionToUpdate) { + throw new Error('No contribution found to given id.') } - if (pendingCreationToUpdate.userId !== user.id) { - throw new Error('user of the pending creation and send user does not correspond') + if (contributionToUpdate.userId !== user.id) { + throw new Error('user of the pending contribution and send user does not correspond') } const creationDateObj = new Date(creationDate) let creations = await getUserCreation(user.id) - if (pendingCreationToUpdate.date.getMonth() === creationDateObj.getMonth()) { - creations = updateCreations(creations, pendingCreationToUpdate) + if (contributionToUpdate.contributionDate.getMonth() === creationDateObj.getMonth()) { + creations = updateCreations(creations, contributionToUpdate) } // all possible cases not to be true are thrown in this function isCreationValid(creations, amount, creationDateObj) - pendingCreationToUpdate.amount = amount - pendingCreationToUpdate.memo = memo - pendingCreationToUpdate.date = new Date(creationDate) - pendingCreationToUpdate.moderator = moderator.id + contributionToUpdate.amount = amount + contributionToUpdate.memo = memo + contributionToUpdate.contributionDate = new Date(creationDate) + contributionToUpdate.moderatorId = moderator.id - await AdminPendingCreation.save(pendingCreationToUpdate) + await Contribution.save(contributionToUpdate) const result = new UpdatePendingCreation() result.amount = amount - result.memo = pendingCreationToUpdate.memo - result.date = pendingCreationToUpdate.date + result.memo = contributionToUpdate.memo + result.date = contributionToUpdate.contributionDate result.creation = await getUserCreation(user.id) @@ -274,24 +274,28 @@ export class AdminResolver { } @Authorized([RIGHTS.SEARCH_PENDING_CREATION]) - @Query(() => [PendingCreation]) - async getPendingCreations(): Promise { - const pendingCreations = await AdminPendingCreation.find() - if (pendingCreations.length === 0) { + @Query(() => [PendingContribution]) + async getPendingCreations(): Promise { + const contributions = await Contribution.find() + if (contributions.length === 0) { return [] } - const userIds = pendingCreations.map((p) => p.userId) + const userIds = contributions.map((p) => p.userId) const userCreations = await getUserCreations(userIds) const users = await dbUser.find({ where: { id: In(userIds) }, withDeleted: true }) - return pendingCreations.map((pendingCreation) => { - const user = users.find((u) => u.id === pendingCreation.userId) - const creation = userCreations.find((c) => c.id === pendingCreation.userId) + return contributions.map((contribution) => { + const user = users.find((u) => u.id === contribution.userId) + const creation = userCreations.find((c) => c.id === contribution.userId) return { - ...pendingCreation, - amount: pendingCreation.amount, + id: contribution.id, + userId: contribution.userId, + date: contribution.contributionDate, + memo: contribution.memo, + amount: contribution.amount, + moderator: contribution.moderatorId, firstName: user ? user.firstName : '', lastName: user ? user.lastName : '', email: user ? user.email : '', @@ -303,11 +307,11 @@ export class AdminResolver { @Authorized([RIGHTS.DELETE_PENDING_CREATION]) @Mutation(() => Boolean) async deletePendingCreation(@Arg('id', () => Int) id: number): Promise { - const pendingCreation = await AdminPendingCreation.findOne(id) - if (!pendingCreation) { + const contribution = await Contribution.findOne(id) + if (!contribution) { throw new Error('Creation not found for given id.') } - const res = await AdminPendingCreation.delete(pendingCreation) + const res = await contribution.softRemove() return !!res } @@ -317,26 +321,26 @@ export class AdminResolver { @Arg('id', () => Int) id: number, @Ctx() context: Context, ): Promise { - const pendingCreation = await AdminPendingCreation.findOne(id) - if (!pendingCreation) { + const contribution = await Contribution.findOne(id) + if (!contribution) { throw new Error('Creation not found to given id.') } const moderatorUser = getUser(context) - if (moderatorUser.id === pendingCreation.userId) + if (moderatorUser.id === contribution.userId) throw new Error('Moderator can not confirm own pending creation') - const user = await dbUser.findOneOrFail({ id: pendingCreation.userId }, { withDeleted: true }) + const user = await dbUser.findOneOrFail({ id: contribution.userId }, { withDeleted: true }) if (user.deletedAt) throw new Error('This user was deleted. Cannot confirm a creation.') - const creations = await getUserCreation(pendingCreation.userId, false) - if (!isCreationValid(creations, pendingCreation.amount, pendingCreation.date)) { + const creations = await getUserCreation(contribution.userId, false) + if (!isCreationValid(creations, contribution.amount, contribution.contributionDate)) { throw new Error('Creation is not valid!!') } const receivedCallDate = new Date() const transactionRepository = getCustomRepository(TransactionRepository) - const lastTransaction = await transactionRepository.findLastForUser(pendingCreation.userId) + const lastTransaction = await transactionRepository.findLastForUser(contribution.userId) let newBalance = new Decimal(0) let decay: Decay | null = null @@ -344,15 +348,15 @@ export class AdminResolver { decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, receivedCallDate) newBalance = decay.balance } - newBalance = newBalance.add(pendingCreation.amount.toString()) + newBalance = newBalance.add(contribution.amount.toString()) const transaction = new DbTransaction() transaction.typeId = TransactionTypeId.CREATION - transaction.memo = pendingCreation.memo - transaction.userId = pendingCreation.userId + transaction.memo = contribution.memo + transaction.userId = contribution.userId transaction.previous = lastTransaction ? lastTransaction.id : null - transaction.amount = pendingCreation.amount - transaction.creationDate = pendingCreation.date + transaction.amount = contribution.amount + transaction.creationDate = contribution.contributionDate transaction.balance = newBalance transaction.balanceDate = receivedCallDate transaction.decay = decay ? decay.decay : new Decimal(0) @@ -361,7 +365,10 @@ export class AdminResolver { throw new Error('Unable to confirm creation.') }) - await AdminPendingCreation.delete(pendingCreation) + contribution.confirmedAt = receivedCallDate + contribution.confirmedBy = moderatorUser.id + + await Contribution.save(contribution) return true } @@ -478,9 +485,9 @@ async function getUserCreations(ids: number[], includePending = true): Promise= ${dateFilter}` + AND contribution_date >= ${dateFilter}` : '' const unionQuery = await queryRunner.manager.query(` @@ -510,13 +517,13 @@ async function getUserCreations(ids: number[], includePending = true): Promise Date: Mon, 30 May 2022 14:50:58 +0200 Subject: [PATCH 005/119] add logger to admin resolver, log some tracing, fix seeds --- backend/src/graphql/resolver/AdminResolver.test.ts | 8 ++++---- backend/src/graphql/resolver/AdminResolver.ts | 12 +++++++++++- backend/src/seeds/factory/creation.ts | 8 ++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index 4771232ea..8d4efd283 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -25,7 +25,7 @@ import { User } from '@entity/User' /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import Decimal from 'decimal.js-light' -import { AdminPendingCreation } from '@entity/AdminPendingCreation' +import { Contribution } from '@entity/Contribution' import { Transaction as DbTransaction } from '@entity/Transaction' // mock account activation email to avoid console spam @@ -54,7 +54,7 @@ afterAll(async () => { let admin: User let user: User -let creation: AdminPendingCreation | void +let creation: Contribution | void describe('AdminResolver', () => { describe('delete user', () => { @@ -1275,8 +1275,8 @@ describe('AdminResolver', () => { }) describe('confirm two creations one after the other quickly', () => { - let c1: AdminPendingCreation | void - let c2: AdminPendingCreation | void + let c1: Contribution | void + let c2: Contribution | void beforeAll(async () => { const now = new Date() diff --git a/backend/src/graphql/resolver/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 323df8a99..7247faa8d 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -40,6 +40,7 @@ import { communityUser } from '@/util/communityUser' import { checkOptInCode, activationLink, printTimeDuration } from './UserResolver' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import CONFIG from '@/config' +import { backendLogger as logger } from '@/server/logger' // const EMAIL_OPT_IN_REGISTER = 1 // const EMAIL_OPT_UNKNOWN = 3 // elopage? @@ -169,6 +170,7 @@ export class AdminResolver { @Args() { email, amount, memo, creationDate }: CreatePendingCreationArgs, @Ctx() context: Context, ): Promise { + logger.trace('createPendingCreation...') const user = await dbUser.findOne({ email }, { withDeleted: true }) if (!user) { throw new Error(`Could not find user with email: ${email}`) @@ -180,7 +182,9 @@ export class AdminResolver { throw new Error('Creation could not be saved, Email is not activated') } const moderator = getUser(context) + logger.trace('moderator: ', moderator.id) const creations = await getUserCreation(user.id) + logger.trace('creations', creations) const creationDateObj = new Date(creationDate) if (isCreationValid(creations, amount, creationDateObj)) { const contribution = Contribution.create() @@ -191,6 +195,7 @@ export class AdminResolver { contribution.memo = memo contribution.moderatorId = moderator.id + logger.trace('contribution to save', contribution) await Contribution.save(contribution) } return getUserCreation(user.id) @@ -470,23 +475,27 @@ interface CreationMap { } async function getUserCreation(id: number, includePending = true): Promise { + logger.trace('getUserCreation', id, includePending) const creations = await getUserCreations([id], includePending) return creations[0] ? creations[0].creations : FULL_CREATION_AVAILABLE } async function getUserCreations(ids: number[], includePending = true): Promise { + logger.trace('getUserCreations:', ids, includePending) const months = getCreationMonths() + logger.trace('getUserCreations months', months) const queryRunner = getConnection().createQueryRunner() await queryRunner.connect() const dateFilter = 'last_day(curdate() - interval 3 month) + interval 1 day' + logger.trace('getUserCreations dateFilter', dateFilter) const unionString = includePending ? ` UNION SELECT contribution_date AS date, amount AS amount, user_id AS userId FROM contributions - WHERE userId IN (${ids.toString()}) + WHERE user_id IN (${ids.toString()}) AND contribution_date >= ${dateFilter}` : '' @@ -528,6 +537,7 @@ function updateCreations(creations: Decimal[], contribution: Contribution): Deci } function isCreationValid(creations: Decimal[], amount: Decimal, creationDate: Date) { + logger.trace('isCreationValid', creations, amount, creationDate) const index = getCreationIndex(creationDate.getMonth()) if (index < 0) { diff --git a/backend/src/seeds/factory/creation.ts b/backend/src/seeds/factory/creation.ts index e49be3758..dc17c4084 100644 --- a/backend/src/seeds/factory/creation.ts +++ b/backend/src/seeds/factory/creation.ts @@ -7,7 +7,7 @@ import { CreationInterface } from '@/seeds/creation/CreationInterface' import { ApolloServerTestClient } from 'apollo-server-testing' import { User } from '@entity/User' import { Transaction } from '@entity/Transaction' -import { AdminPendingCreation } from '@entity/AdminPendingCreation' +import { Contribution } from '@entity/Contribution' // import CONFIG from '@/config/index' export const nMonthsBefore = (date: Date, months = 1): string => { @@ -17,7 +17,7 @@ export const nMonthsBefore = (date: Date, months = 1): string => { export const creationFactory = async ( client: ApolloServerTestClient, creation: CreationInterface, -): Promise => { +): Promise => { const { mutate, query } = client await query({ query: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } }) @@ -27,9 +27,9 @@ export const creationFactory = async ( const user = await User.findOneOrFail({ where: { email: creation.email } }) - const pendingCreation = await AdminPendingCreation.findOneOrFail({ + const pendingCreation = await Contribution.findOneOrFail({ where: { userId: user.id, amount: creation.amount }, - order: { created: 'DESC' }, + order: { createdAt: 'DESC' }, }) if (creation.confirmed) { From fa2a05c35ff5d4808b414155dd05e9e23e120405 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 30 May 2022 14:59:51 +0200 Subject: [PATCH 006/119] enable soft delete --- database/entity/0037-contributions_table/Contribution.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/database/entity/0037-contributions_table/Contribution.ts b/database/entity/0037-contributions_table/Contribution.ts index 997bef2c7..61a7550af 100644 --- a/database/entity/0037-contributions_table/Contribution.ts +++ b/database/entity/0037-contributions_table/Contribution.ts @@ -1,5 +1,5 @@ import Decimal from 'decimal.js-light' -import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm' +import { BaseEntity, Column, Entity, PrimaryGeneratedColumn, DeleteDateColumn } from 'typeorm' import { DecimalTransformer } from '../../src/typeorm/DecimalTransformer' @Entity('contributions') @@ -40,6 +40,6 @@ export class Contribution extends BaseEntity { @Column({ nullable: true, name: 'confirmed_at' }) confirmedAt: Date - @Column({ nullable: true, name: 'deleted_at' }) - deletedAt: Date + @DeleteDateColumn({ name: 'deleted_at' }) + deletedAt: Date | null } From 22944bce2871f4ae2b8b0a2649349325717e1c23 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Mon, 30 May 2022 15:00:23 +0200 Subject: [PATCH 007/119] get tests running again --- backend/src/graphql/resolver/AdminResolver.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/graphql/resolver/AdminResolver.test.ts b/backend/src/graphql/resolver/AdminResolver.test.ts index 8d4efd283..61da03dfa 100644 --- a/backend/src/graphql/resolver/AdminResolver.test.ts +++ b/backend/src/graphql/resolver/AdminResolver.test.ts @@ -981,7 +981,7 @@ describe('AdminResolver', () => { }), ).resolves.toEqual( expect.objectContaining({ - errors: [new GraphQLError('No creation found to given id.')], + errors: [new GraphQLError('No contribution found to given id.')], }), ) }) @@ -1004,7 +1004,7 @@ describe('AdminResolver', () => { expect.objectContaining({ errors: [ new GraphQLError( - 'user of the pending creation and send user does not correspond', + 'user of the pending contribution and send user does not correspond', ), ], }), From c5f8534bd896781f64beb6d558b8d7ffd25fd91a Mon Sep 17 00:00:00 2001 From: ogerly Date: Mon, 30 May 2022 15:37:22 +0200 Subject: [PATCH 008/119] add list, json, show, edit, delete and add form --- admin/src/ContributionLinks.json | 8 +++ admin/src/pages/Overview.vue | 107 +++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 admin/src/ContributionLinks.json diff --git a/admin/src/ContributionLinks.json b/admin/src/ContributionLinks.json new file mode 100644 index 000000000..55cac89bf --- /dev/null +++ b/admin/src/ContributionLinks.json @@ -0,0 +1,8 @@ +{ + "fields": ["Name", "Text", "GDD", "startDate", "endDate", "delete", "edit", "show"], + "ContributionLinks":[ + {"Name":"John1", "Text":"Doe1 ", "GDD":"200", "startDate":"", "endDate":""}, + {"Name":"John2", "Text":"Doe2", "GDD":"300", "startDate":"", "endDate":""}, + {"Name":"John3", "Text":"Doe3", "GDD":"400", "startDate":"", "endDate":""} + ] +} \ No newline at end of file diff --git a/admin/src/pages/Overview.vue b/admin/src/pages/Overview.vue index ed7ac8ad7..590089e54 100644 --- a/admin/src/pages/Overview.vue +++ b/admin/src/pages/Overview.vue @@ -28,14 +28,121 @@ +
{{ ContributionLinks }}
+ + + + New Contribution + + + +

New Contribution

+ + + + + + + + + + + + +
+ + + + + + +
+
+ Anlegen + Reset +
+
+
+
+ + + + + + + + +
diff --git a/admin/src/components/AutomaticCreationForm.vue b/admin/src/components/AutomaticCreationForm.vue new file mode 100644 index 000000000..543995ea9 --- /dev/null +++ b/admin/src/components/AutomaticCreationForm.vue @@ -0,0 +1,70 @@ + + diff --git a/admin/src/components/AutomaticCreationList.vue b/admin/src/components/AutomaticCreationList.vue new file mode 100644 index 000000000..7094f1b68 --- /dev/null +++ b/admin/src/components/AutomaticCreationList.vue @@ -0,0 +1,34 @@ + + diff --git a/admin/src/components/ContributionsForm.vue b/admin/src/components/ContributionsForm.vue new file mode 100644 index 000000000..ec59f8a78 --- /dev/null +++ b/admin/src/components/ContributionsForm.vue @@ -0,0 +1,53 @@ + + diff --git a/admin/src/pages/Overview.vue b/admin/src/pages/Overview.vue index 590089e54..edfd12686 100644 --- a/admin/src/pages/Overview.vue +++ b/admin/src/pages/Overview.vue @@ -28,121 +28,28 @@ -
{{ ContributionLinks }}
- - - + New Contribution - - - -

New Contribution

- - - - - - - - - - - - -
- - - - - - -
-
- Anlegen - Reset -
-
-
-
- - - - - - - - -
+ From edcdaa9bd49c34892383510096935842127517b5 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 31 May 2022 09:38:33 +0200 Subject: [PATCH 013/119] formular structur, add props and apollo methods example --- admin/src/components/AutomaticCreation.vue | 18 ++- .../src/components/AutomaticCreationForm.vue | 117 +++++++++++++++--- admin/src/pages/Overview.vue | 23 +++- 3 files changed, 127 insertions(+), 31 deletions(-) diff --git a/admin/src/components/AutomaticCreation.vue b/admin/src/components/AutomaticCreation.vue index 0d087c233..77af1aeb8 100644 --- a/admin/src/components/AutomaticCreation.vue +++ b/admin/src/components/AutomaticCreation.vue @@ -1,24 +1,27 @@ @@ -24,11 +24,11 @@
xxx
- daten + qrCode + link {{ modalData }} + @@ -36,9 +36,13 @@ diff --git a/admin/src/components/AutomaticCreation.vue b/admin/src/components/ContributionLink.vue similarity index 59% rename from admin/src/components/AutomaticCreation.vue rename to admin/src/components/ContributionLink.vue index 04ec752c6..935f7d44c 100644 --- a/admin/src/components/AutomaticCreation.vue +++ b/admin/src/components/ContributionLink.vue @@ -2,28 +2,28 @@
- + New Automatic Creations + + New Contribution Link -

Automatic Creations

- +

Contribution Links

+
-
Es sind keine automatischen Schöpfungen angelegt.
@@ -31,14 +31,14 @@
diff --git a/admin/src/components/AutomaticCreationList.vue b/admin/src/components/ContributionLinkList.vue similarity index 80% rename from admin/src/components/AutomaticCreationList.vue rename to admin/src/components/ContributionLinkList.vue index 1d83beb17..200968e4e 100644 --- a/admin/src/components/AutomaticCreationList.vue +++ b/admin/src/components/ContributionLinkList.vue @@ -2,22 +2,17 @@
@@ -40,11 +35,11 @@
From 98bb217f6e3147f3cc01b8676086c42a5f7a7ef6 Mon Sep 17 00:00:00 2001 From: ogerly Date: Tue, 7 Jun 2022 11:31:55 +0200 Subject: [PATCH 027/119] fixed lint and locales --- admin/.eslintrc.js | 2 +- admin/src/components/ContributionLinkForm.vue | 14 ++++---- admin/src/locales/de.json | 33 +++++++++---------- admin/src/locales/en.json | 28 ++++++++-------- 4 files changed, 38 insertions(+), 39 deletions(-) diff --git a/admin/.eslintrc.js b/admin/.eslintrc.js index 73dce291f..33ab3c0c5 100644 --- a/admin/.eslintrc.js +++ b/admin/.eslintrc.js @@ -39,7 +39,7 @@ module.exports = { { src: './src', extensions: ['.js', '.vue'], - ignores: [], + ignores: ['contributionLink.options.repetition.null'], enableFix: false, }, ], diff --git a/admin/src/components/ContributionLinkForm.vue b/admin/src/components/ContributionLinkForm.vue index a388ab0d7..6e958f125 100644 --- a/admin/src/components/ContributionLinkForm.vue +++ b/admin/src/components/ContributionLinkForm.vue @@ -7,7 +7,7 @@ - + - + - + - + - +
{{ $t('contributionLink.create') }} - {{ $t('contributionLink.clear') }} + + {{ $t('contributionLink.clear') }} +
diff --git a/admin/src/locales/de.json b/admin/src/locales/de.json index 4e871f4a4..d56c9ee3d 100644 --- a/admin/src/locales/de.json +++ b/admin/src/locales/de.json @@ -1,17 +1,17 @@ { "all_emails": "Alle Nutzer", "contributionLink": { - "repetition":"Wiederholung", - "cycle":"Zyclus", - "maximumAmount":"maximaler Betrag", - "create":"Anlegen", - "clear":"Löschen", - "startDate":"Start-Datum", - "endDate":"End-Datum", - "name":"Name", - "memo":"Nachricht", + "repetition": "Wiederholung", + "cycle": "Zyclus", + "maximumAmount": "maximaler Betrag", + "create": "Anlegen", + "clear": "Löschen", + "startDate": "Start-Datum", + "endDate": "End-Datum", + "name": "Name", + "memo": "Nachricht", "amount": "Betrag", - "options" :{ + "options": { "cycle": { "null": "Bitter wähle einen Zyclus", "none": "kein Zyclus", @@ -23,11 +23,10 @@ }, "repetition": { "null": "Bitte wähle eine Wiederholung" - }, - "noStartDate":"Kein Start-Datum gewählt.", - "noEndDate":"Kein End-Datum gewählt." - - } + } + }, + "noStartDate": "Kein Start-Datum gewählt.", + "noEndDate": "Kein End-Datum gewählt." }, "back": "zurück", "creation": "Schöpfung", @@ -103,9 +102,7 @@ "removeNotSelf": "Als Admin / Moderator kannst du dich nicht selber löschen.", "remove_all": "alle Nutzer entfernen", "save": "Speichern", - "selectOptions": { - - }, + "selectOptions": {}, "status": "Status", "success": "Erfolg", "text": "Text", diff --git a/admin/src/locales/en.json b/admin/src/locales/en.json index db86e277d..81ac6a99c 100644 --- a/admin/src/locales/en.json +++ b/admin/src/locales/en.json @@ -1,17 +1,17 @@ { "all_emails": "All users", "contributionLink": { - "repetition":"Repetition", - "cycle":"Cycle", - "maximumAmount":"Maximum amount", - "create":"Create", - "clear":"Clear", - "startDate":"Start-Date", - "endDate":"End-Date", - "name":"Name", - "memo":"Memo", + "repetition": "Repetition", + "cycle": "Cycle", + "maximumAmount": "Maximum amount", + "create": "Create", + "clear": "Clear", + "startDate": "Start-Date", + "endDate": "End-Date", + "name": "Name", + "memo": "Memo", "amount": "Amount", - "options" :{ + "options": { "cycle": { "null": "Please select an cycle", "none": "no cycle", @@ -23,10 +23,10 @@ }, "repetition": { "null": "Please select an repetition" - }, - "noStartDate":"No start Date", - "noEndDate":"No end Date" - } + } + }, + "noStartDate": "No start Date", + "noEndDate": "No end Date" }, "back": "back", "creation": "Creation", From 6a5c72a48db080347c984ebb46f5076189395ce4 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 8 Jun 2022 06:25:30 +0200 Subject: [PATCH 028/119] fixed locales --- admin/src/locales/de.json | 32 ++++++++++++++++---------------- admin/src/locales/en.json | 32 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/admin/src/locales/de.json b/admin/src/locales/de.json index d56c9ee3d..16f38ce60 100644 --- a/admin/src/locales/de.json +++ b/admin/src/locales/de.json @@ -1,34 +1,34 @@ { "all_emails": "Alle Nutzer", + "back": "zurück", "contributionLink": { - "repetition": "Wiederholung", - "cycle": "Zyclus", - "maximumAmount": "maximaler Betrag", - "create": "Anlegen", - "clear": "Löschen", - "startDate": "Start-Datum", - "endDate": "End-Datum", - "name": "Name", - "memo": "Nachricht", "amount": "Betrag", + "clear": "Löschen", + "create": "Anlegen", + "cycle": "Zyclus", + "endDate": "End-Datum", + "maximumAmount": "maximaler Betrag", + "memo": "Nachricht", + "name": "Name", + "noEndDate": "Kein End-Datum gewählt.", + "noStartDate": "Kein Start-Datum gewählt.", "options": { "cycle": { - "null": "Bitter wähle einen Zyclus", - "none": "kein Zyclus", - "hourly": "stündlich", "daily": "täglich", - "weekly": "wöchentlich", + "hourly": "stündlich", "monthly": "monatlich", + "none": "kein Zyclus", + "null": "Bitter wähle einen Zyclus", + "weekly": "wöchentlich", "yearly": "jährlich" }, "repetition": { "null": "Bitte wähle eine Wiederholung" } }, - "noStartDate": "Kein Start-Datum gewählt.", - "noEndDate": "Kein End-Datum gewählt." + "repetition": "Wiederholung", + "startDate": "Start-Datum" }, - "back": "zurück", "creation": "Schöpfung", "creationList": "Schöpfungsliste", "creation_form": { diff --git a/admin/src/locales/en.json b/admin/src/locales/en.json index 81ac6a99c..836f18d02 100644 --- a/admin/src/locales/en.json +++ b/admin/src/locales/en.json @@ -1,34 +1,34 @@ { "all_emails": "All users", + "back": "back", "contributionLink": { - "repetition": "Repetition", - "cycle": "Cycle", - "maximumAmount": "Maximum amount", - "create": "Create", - "clear": "Clear", - "startDate": "Start-Date", - "endDate": "End-Date", - "name": "Name", - "memo": "Memo", "amount": "Amount", + "clear": "Clear", + "create": "Create", + "cycle": "Cycle", + "endDate": "End-Date", + "maximumAmount": "Maximum amount", + "memo": "Memo", + "name": "Name", + "noEndDate": "No end Date", + "noStartDate": "No start Date", "options": { "cycle": { - "null": "Please select an cycle", - "none": "no cycle", - "hourly": "hourly", "daily": "daily", - "weekly": "weekly", + "hourly": "hourly", "monthly": "monthly", + "none": "no cycle", + "null": "Please select an cycle", + "weekly": "weekly", "yearly": "yearly" }, "repetition": { "null": "Please select an repetition" } }, - "noStartDate": "No start Date", - "noEndDate": "No end Date" + "repetition": "Repetition", + "startDate": "Start-Date" }, - "back": "back", "creation": "Creation", "creationList": "Creation list", "creation_form": { From ad61069feea273b16f6ce44a7595d6bf5f90e105 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 8 Jun 2022 06:39:20 +0200 Subject: [PATCH 029/119] fixed locales, stylelint, lint --- admin/src/components/ContributionLink.vue | 8 ++++---- admin/src/components/ContributionLinkList.vue | 2 +- admin/src/locales/de.json | 6 +++++- admin/src/locales/en.json | 6 +++++- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/admin/src/components/ContributionLink.vue b/admin/src/components/ContributionLink.vue index 935f7d44c..cdba4ec02 100644 --- a/admin/src/components/ContributionLink.vue +++ b/admin/src/components/ContributionLink.vue @@ -2,19 +2,19 @@
- + New Contribution Link + {{ $t('math.plus') }} {{ $t('contributionLink.newContributionLink') }} -

Contribution Links

+

{{ $t('contributionLink.contributionLinks') }}

@@ -25,7 +25,7 @@ :items="items" @editContributionLinkData="editContributionLinkData" /> -
Es sind keine automatischen Schöpfungen angelegt.
+
{{ $t('contributionLink.noContributionLinks') }}
diff --git a/admin/src/components/ContributionLinkList.vue b/admin/src/components/ContributionLinkList.vue index 200968e4e..027245ac3 100644 --- a/admin/src/components/ContributionLinkList.vue +++ b/admin/src/components/ContributionLinkList.vue @@ -21,7 +21,7 @@ {{ modalData }} diff --git a/admin/src/locales/de.json b/admin/src/locales/de.json index 16f38ce60..90f1654e9 100644 --- a/admin/src/locales/de.json +++ b/admin/src/locales/de.json @@ -4,12 +4,15 @@ "contributionLink": { "amount": "Betrag", "clear": "Löschen", + "contributionLinks": "Contribution Links", "create": "Anlegen", "cycle": "Zyclus", "endDate": "End-Datum", "maximumAmount": "maximaler Betrag", "memo": "Nachricht", "name": "Name", + "newContributionLink": "Neuer Contribution Link", + "noContributionLinks": "Es sind keine Contribution Links angelegt.", "noEndDate": "Kein End-Datum gewählt.", "noStartDate": "Kein Start-Datum gewählt.", "options": { @@ -72,7 +75,8 @@ "lastname": "Nachname", "math": { "exclaim": "!", - "pipe": "|" + "pipe": "|", + "plus": "+" }, "moderator": "Moderator", "multiple_creation_text": "Bitte wähle ein oder mehrere Mitglieder aus für die du Schöpfen möchtest.", diff --git a/admin/src/locales/en.json b/admin/src/locales/en.json index 836f18d02..67929afaa 100644 --- a/admin/src/locales/en.json +++ b/admin/src/locales/en.json @@ -4,12 +4,15 @@ "contributionLink": { "amount": "Amount", "clear": "Clear", + "contributionLinks": "Contribution Links", "create": "Create", "cycle": "Cycle", "endDate": "End-Date", "maximumAmount": "Maximum amount", "memo": "Memo", "name": "Name", + "newContributionLink": "New Contribution Link", + "noContributionLinks": "No contribution links have been created.", "noEndDate": "No end Date", "noStartDate": "No start Date", "options": { @@ -72,7 +75,8 @@ "lastname": "Lastname", "math": { "exclaim": "!", - "pipe": "|" + "pipe": "|", + "plus": "+" }, "moderator": "Moderator", "multiple_creation_text": "Please select one or more members for which you would like to perform creations.", From 737d2397feefcc7a50a5ec37dc554400f8065622 Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 8 Jun 2022 06:53:08 +0200 Subject: [PATCH 030/119] add FigureQrCode.spec.js --- admin/src/components/FigureQrCode.spec.js | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 admin/src/components/FigureQrCode.spec.js diff --git a/admin/src/components/FigureQrCode.spec.js b/admin/src/components/FigureQrCode.spec.js new file mode 100644 index 000000000..715a5d5d5 --- /dev/null +++ b/admin/src/components/FigureQrCode.spec.js @@ -0,0 +1,30 @@ +import { mount } from '@vue/test-utils' +import FigureQrCode from './FigureQrCode' + +const localVue = global.localVue + +const propsData = { + link: '', +} + +describe('FigureQrCode', () => { + let wrapper + + const Wrapper = () => { + return mount(FigureQrCode, { localVue, propsData }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the Div Element ".figure-qr-code"', () => { + expect(wrapper.find('div.figure-qr-code').exists()).toBeTruthy() + }) + + it('renders the Div Element "q-r-canvas"', () => { + expect(wrapper.find('q-r-canvas')) + }) + }) +}) From bbd0fd64789bee7ed2909fb14723eb8832b630ad Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 8 Jun 2022 07:53:43 +0200 Subject: [PATCH 031/119] test for FigureQrCode --- admin/jest.config.js | 2 +- admin/package.json | 1 + admin/src/components/FigureQrCode.spec.js | 2 +- admin/yarn.lock | 22 +++++++++++++++++++++- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/admin/jest.config.js b/admin/jest.config.js index b7226bd8f..9b9842bad 100644 --- a/admin/jest.config.js +++ b/admin/jest.config.js @@ -22,7 +22,7 @@ module.exports = { '^.+\\.(js|jsx)?$': 'babel-jest', '/node_modules/vee-validate/dist/rules': 'babel-jest', }, - setupFiles: ['/test/testSetup.js'], + setupFiles: ['/test/testSetup.js', 'jest-canvas-mock'], testMatch: ['**/?(*.)+(spec|test).js?(x)'], // snapshotSerializers: ['jest-serializer-vue'], transformIgnorePatterns: ['/node_modules/(?!vee-validate/dist/rules)'], diff --git a/admin/package.json b/admin/package.json index 4c896e6a9..cbbce5a2a 100644 --- a/admin/package.json +++ b/admin/package.json @@ -38,6 +38,7 @@ "graphql": "^15.6.1", "identity-obj-proxy": "^3.0.0", "jest": "26.6.3", + "jest-canvas-mock": "^2.3.1", "portal-vue": "^2.1.7", "qrcanvas-vue": "2.1.1", "regenerator-runtime": "^0.13.9", diff --git a/admin/src/components/FigureQrCode.spec.js b/admin/src/components/FigureQrCode.spec.js index 715a5d5d5..40320aad5 100644 --- a/admin/src/components/FigureQrCode.spec.js +++ b/admin/src/components/FigureQrCode.spec.js @@ -1,5 +1,5 @@ import { mount } from '@vue/test-utils' -import FigureQrCode from './FigureQrCode' +import FigureQrCode from './FigureQrCode.vue' const localVue = global.localVue diff --git a/admin/yarn.lock b/admin/yarn.lock index 232fd06bd..28f577a12 100644 --- a/admin/yarn.lock +++ b/admin/yarn.lock @@ -4404,7 +4404,7 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0, color-name@~1.1.4: +color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== @@ -4852,6 +4852,11 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +cssfontparser@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3" + integrity sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg== + cssnano-preset-default@^4.0.0, cssnano-preset-default@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff" @@ -7828,6 +7833,14 @@ javascript-stringify@^2.0.1: resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== +jest-canvas-mock@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz#947b71442d7719f8e055decaecdb334809465341" + integrity sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ== + dependencies: + cssfontparser "^1.2.1" + moo-color "^1.0.2" + jest-changed-files@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" @@ -9485,6 +9498,13 @@ mkdirp@0.x, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" +moo-color@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/moo-color/-/moo-color-1.0.3.tgz#d56435f8359c8284d83ac58016df7427febece74" + integrity sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ== + dependencies: + color-name "^1.1.4" + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" From 6a91de68084f11424a5e8c5e83476001f306a29f Mon Sep 17 00:00:00 2001 From: ogerly Date: Wed, 8 Jun 2022 08:33:07 +0200 Subject: [PATCH 032/119] test for ContributionLink --- admin/src/components/ContributionLink.spec.js | 32 +++++++++++++++++++ admin/src/components/ContributionLink.vue | 2 +- admin/src/components/ContributionLinkForm.vue | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 admin/src/components/ContributionLink.spec.js diff --git a/admin/src/components/ContributionLink.spec.js b/admin/src/components/ContributionLink.spec.js new file mode 100644 index 000000000..ae5ea4f58 --- /dev/null +++ b/admin/src/components/ContributionLink.spec.js @@ -0,0 +1,32 @@ +import { mount } from '@vue/test-utils' +import ContributionLink from './ContributionLink.vue' + +const localVue = global.localVue + +const mocks = { + $t: jest.fn((t) => t), +} + +describe('ContributionLink', () => { + let wrapper + + const Wrapper = () => { + return mount(ContributionLink, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('renders the Div Element ".contribution-link"', () => { + expect(wrapper.find('div.contribution-link').exists()).toBeTruthy() + }) + + it('emits toggle::collapse new Contribution', async () => { + wrapper.vm.editContributionLinkData() + // expect(wrapper.emitted('bv::toggle::collapse', 'newContribution')).toBeTruthy() + expect(wrapper.vm.$root.$emit('bv::toggle::collapse', 'newContribution')).toBeTruthy() + }) + }) +}) diff --git a/admin/src/components/ContributionLink.vue b/admin/src/components/ContributionLink.vue index cdba4ec02..02b525b44 100644 --- a/admin/src/components/ContributionLink.vue +++ b/admin/src/components/ContributionLink.vue @@ -1,5 +1,5 @@