From 0b67da3d2c74225286cd48f5e90565c3322cfbdb Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 30 Nov 2021 10:08:59 +0100 Subject: [PATCH 01/35] update README --- database/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/database/README.md b/database/README.md index f78eca113..8d490496b 100644 --- a/database/README.md +++ b/database/README.md @@ -39,6 +39,7 @@ yarn seed ## Seeded Users | email | password | admin | +|------------------------|------------|---------| | peter@lustig.de | `Aa12345_` | `true` | | bibi@bloxberg.de | `Aa12345_` | `false` | | raeuber@hotzenplotz.de | `Aa12345_` | `false` | From 43b9f9394bff98329ee8f64049eeb7b56bb78c5d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 30 Nov 2021 10:39:20 +0100 Subject: [PATCH 02/35] add transaction factory --- database/src/factories/transaction.factory.ts | 20 +++++++++++++++++++ database/src/interface/TransactionContext.ts | 12 +++++++++++ 2 files changed, 32 insertions(+) create mode 100644 database/src/factories/transaction.factory.ts create mode 100644 database/src/interface/TransactionContext.ts diff --git a/database/src/factories/transaction.factory.ts b/database/src/factories/transaction.factory.ts new file mode 100644 index 000000000..e9efe1316 --- /dev/null +++ b/database/src/factories/transaction.factory.ts @@ -0,0 +1,20 @@ +import Faker from 'faker' +import { define } from 'typeorm-seeding' +import { Transaction } from '../../entity/Transaction' +import { TransactionContext } from '../interface/TransactionContext' +import { randomBytes } from 'crypto' + +define(Transaction, (faker: typeof Faker, context?: TransactionContext) => { + if (!context) context = {} + + const transaction = new Transaction() + transaction.transactionTypeId = context.transactionTypeId ? context.transactionTypeId : 2 + transaction.txHash = context.txHash ? context.txHash : randomBytes(48) + transaction.memo = context.memo ? context.memo : faker.lorem.sentence() + transaction.received = context.received ? context.received : new Date() + transaction.blockchainTypeId = context.blockchainTypeId ? context.blockchainTypeId : 1 + if (context.transactionSendCoin) transaction.transactionSendCoin = context.transactionSendCoin + if (context.transactionCreation) transaction.transactionCreation = context.transactionCreation + + return transaction +}) diff --git a/database/src/interface/TransactionContext.ts b/database/src/interface/TransactionContext.ts new file mode 100644 index 000000000..f43b57046 --- /dev/null +++ b/database/src/interface/TransactionContext.ts @@ -0,0 +1,12 @@ +import { TransactionSendCoin } from '../../entity/TransactionSendCoin' +import { TransactionCreation } from '../../entity/TransactionCreation' + +export interface TransactionContext { + transactionTypeId?: number + txHash?: Buffer + memo?: string + received?: Date + blockchainTypeId?: number + transactionSendCoin?: TransactionSendCoin + transactionCreation?: TransactionCreation +} From 964b974142056c9e188961dd77ae27c4a81c4684 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 30 Nov 2021 11:14:53 +0100 Subject: [PATCH 03/35] seed decay start block --- database/src/factories/transaction.factory.ts | 2 +- database/src/index.ts | 2 ++ database/src/seeds/decay-start-block.seed.ts | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 database/src/seeds/decay-start-block.seed.ts diff --git a/database/src/factories/transaction.factory.ts b/database/src/factories/transaction.factory.ts index e9efe1316..4880ace5b 100644 --- a/database/src/factories/transaction.factory.ts +++ b/database/src/factories/transaction.factory.ts @@ -10,7 +10,7 @@ define(Transaction, (faker: typeof Faker, context?: TransactionContext) => { const transaction = new Transaction() transaction.transactionTypeId = context.transactionTypeId ? context.transactionTypeId : 2 transaction.txHash = context.txHash ? context.txHash : randomBytes(48) - transaction.memo = context.memo ? context.memo : faker.lorem.sentence() + transaction.memo = context.memo || context.memo === '' ? context.memo : faker.lorem.sentence() transaction.received = context.received ? context.received : new Date() transaction.blockchainTypeId = context.blockchainTypeId ? context.blockchainTypeId : 1 if (context.transactionSendCoin) transaction.transactionSendCoin = context.transactionSendCoin diff --git a/database/src/index.ts b/database/src/index.ts index ec5328a9a..28b54cccc 100644 --- a/database/src/index.ts +++ b/database/src/index.ts @@ -9,6 +9,7 @@ import { CreatePeterLustigSeed } from './seeds/users/peter-lustig.admin.seed' import { CreateBibiBloxbergSeed } from './seeds/users/bibi-bloxberg.seed' import { CreateRaeuberHotzenplotzSeed } from './seeds/users/raeuber-hotzenplotz.seed' import { CreateBobBaumeisterSeed } from './seeds/users/bob-baumeister.seed' +import { DecayStartBlockSeed } from './seeds/decay-start-block.seed' const run = async (command: string) => { // Database actions not supported by our migration library @@ -63,6 +64,7 @@ const run = async (command: string) => { await runSeeder(CreateBibiBloxbergSeed) await runSeeder(CreateRaeuberHotzenplotzSeed) await runSeeder(CreateBobBaumeisterSeed) + await runSeeder(DecayStartBlockSeed) break default: throw new Error(`Unsupported command ${command}`) diff --git a/database/src/seeds/decay-start-block.seed.ts b/database/src/seeds/decay-start-block.seed.ts new file mode 100644 index 000000000..fd62ee333 --- /dev/null +++ b/database/src/seeds/decay-start-block.seed.ts @@ -0,0 +1,17 @@ +import { Factory, Seeder } from 'typeorm-seeding' +import { Transaction } from '../../entity/Transaction' + +export class DecayStartBlockSeed implements Seeder { + public async run(factory: Factory): Promise { + await factory(Transaction)({ + transactionTypeId: 9, + txHash: Buffer.from( + '9c9c4152b8a4cfbac287eee18d2d262e9de756fae726fc0ca36b788564973fff00000000000000000000000000000000', + 'hex', + ), + memo: '', + received: new Date('2021-11-30T09:13:26'), + blockchainTypeId: 1, + }).create() + } +} From 728233052885b2f77d804b53369f3821ca8422ec Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 30 Nov 2021 12:25:05 +0100 Subject: [PATCH 04/35] Balance Interface and OneToOne User -> Balance --- database/entity/0001-init_db/Balance.ts | 7 ++++++- database/entity/0001-init_db/User.ts | 6 +++++- database/src/interface/TransactionContext.ts | 8 ++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/database/entity/0001-init_db/Balance.ts b/database/entity/0001-init_db/Balance.ts index c1ca359f1..e0c1b7bd0 100644 --- a/database/entity/0001-init_db/Balance.ts +++ b/database/entity/0001-init_db/Balance.ts @@ -1,4 +1,5 @@ -import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm' +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, JoinColumn, OneToOne } from 'typeorm' +import { User } from '../User' @Entity('state_balances') export class Balance extends BaseEntity { @@ -16,4 +17,8 @@ export class Balance extends BaseEntity { @Column({ type: 'bigint' }) amount: number + + @OneToOne(() => User, { nullable: false }) + @JoinColumn({ name: 'user_id' }) + user: User } diff --git a/database/entity/0001-init_db/User.ts b/database/entity/0001-init_db/User.ts index 7280dca40..545d4f5c5 100644 --- a/database/entity/0001-init_db/User.ts +++ b/database/entity/0001-init_db/User.ts @@ -1,4 +1,5 @@ -import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm' +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, OneToOne } from 'typeorm' +import { Balance } from '../Balance' // Moriz: I do not like the idea of having two user tables @Entity('state_users') @@ -29,4 +30,7 @@ export class User extends BaseEntity { @Column() disabled: boolean + + @OneToOne(() => Balance, (balance) => balance.user) + balance: Balance } diff --git a/database/src/interface/TransactionContext.ts b/database/src/interface/TransactionContext.ts index f43b57046..4cda149af 100644 --- a/database/src/interface/TransactionContext.ts +++ b/database/src/interface/TransactionContext.ts @@ -1,5 +1,6 @@ import { TransactionSendCoin } from '../../entity/TransactionSendCoin' import { TransactionCreation } from '../../entity/TransactionCreation' +import { User } from '../../entity/User' export interface TransactionContext { transactionTypeId?: number @@ -10,3 +11,10 @@ export interface TransactionContext { transactionSendCoin?: TransactionSendCoin transactionCreation?: TransactionCreation } + +export interface BalanceContext { + modified?: Date + recordDate?: Date + amount?: number + user?: User +} From 4717b0ba4cd983a46dbd76599c7faef7d403f1df Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 30 Nov 2021 13:20:59 +0100 Subject: [PATCH 05/35] Add balance for seeded users --- database/entity/0001-init_db/Balance.ts | 2 +- database/src/factories/balance.factory.ts | 18 +++++++++++++ database/src/index.ts | 2 +- database/src/interface/UserInterface.ts | 6 +++++ database/src/seeds/helpers/user-helpers.ts | 27 ++++++++++++++----- database/src/seeds/users/bibi-bloxberg.ts | 4 +++ database/src/seeds/users/bob-baumeister.ts | 4 +++ .../src/seeds/users/raeuber-hotzenplotz.ts | 4 +++ 8 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 database/src/factories/balance.factory.ts diff --git a/database/entity/0001-init_db/Balance.ts b/database/entity/0001-init_db/Balance.ts index e0c1b7bd0..1a7050daf 100644 --- a/database/entity/0001-init_db/Balance.ts +++ b/database/entity/0001-init_db/Balance.ts @@ -19,6 +19,6 @@ export class Balance extends BaseEntity { amount: number @OneToOne(() => User, { nullable: false }) - @JoinColumn({ name: 'user_id' }) + @JoinColumn({ name: 'state_user_id' }) user: User } diff --git a/database/src/factories/balance.factory.ts b/database/src/factories/balance.factory.ts new file mode 100644 index 000000000..2c344be99 --- /dev/null +++ b/database/src/factories/balance.factory.ts @@ -0,0 +1,18 @@ +import Faker from 'faker' +import { define } from 'typeorm-seeding' +import { Balance } from '../../entity/Balance' +import { BalanceContext } from '../interface/TransactionContext' + +define(Balance, (faker: typeof Faker, context?: BalanceContext) => { + if (!context || !context.user) { + throw new Error('Balance: No user present!') + } + + const balance = new Balance() + balance.modified = context.modified ? context.modified : faker.date.recent() + balance.recordDate = context.recordDate ? context.recordDate : faker.date.recent() + balance.amount = context.amount ? context.amount : 10000000 + balance.user = context.user + + return balance +}) diff --git a/database/src/index.ts b/database/src/index.ts index 28b54cccc..94566c9f5 100644 --- a/database/src/index.ts +++ b/database/src/index.ts @@ -60,11 +60,11 @@ const run = async (command: string) => { root: process.cwd(), configName: 'ormconfig.js', }) + await runSeeder(DecayStartBlockSeed) await runSeeder(CreatePeterLustigSeed) await runSeeder(CreateBibiBloxbergSeed) await runSeeder(CreateRaeuberHotzenplotzSeed) await runSeeder(CreateBobBaumeisterSeed) - await runSeeder(DecayStartBlockSeed) break default: throw new Error(`Unsupported command ${command}`) diff --git a/database/src/interface/UserInterface.ts b/database/src/interface/UserInterface.ts index 942158593..33919fb74 100644 --- a/database/src/interface/UserInterface.ts +++ b/database/src/interface/UserInterface.ts @@ -27,4 +27,10 @@ export interface UserInterface { modified?: Date // flag for admin isAdmin?: boolean + // flag for balance + addBalance?: boolean + // balance + balanceModified?: Date + recordDate?: Date + amount?: number } diff --git a/database/src/seeds/helpers/user-helpers.ts b/database/src/seeds/helpers/user-helpers.ts index 805104519..79068c2ec 100644 --- a/database/src/seeds/helpers/user-helpers.ts +++ b/database/src/seeds/helpers/user-helpers.ts @@ -5,16 +5,18 @@ import { ServerUserContext, LoginUserRolesContext, } from '../../interface/UserContext' +import { BalanceContext } from '../../interface/TransactionContext' import { UserInterface } from '../../interface/UserInterface' import { User } from '../../../entity/User' import { LoginUser } from '../../../entity/LoginUser' import { LoginUserBackup } from '../../../entity/LoginUserBackup' import { ServerUser } from '../../../entity/ServerUser' import { LoginUserRoles } from '../../../entity/LoginUserRoles' +import { Balance } from '../../../entity/Balance' import { Factory } from 'typeorm-seeding' export const userSeeder = async (factory: Factory, userData: UserInterface): Promise => { - await factory(User)(createUserContext(userData)).create() + const user = await factory(User)(createUserContext(userData)).create() const loginUser = await factory(LoginUser)(createLoginUserContext(userData)).create() await factory(LoginUserBackup)(createLoginUserBackupContext(userData, loginUser)).create() @@ -25,9 +27,13 @@ export const userSeeder = async (factory: Factory, userData: UserInterface): Pro // It works with LoginRoles empty!! await factory(LoginUserRoles)(createLoginUserRolesContext(loginUser)).create() } + + if (userData.addBalance) { + await factory(Balance)(createBalanceContext(userData, user)).create() + } } -export const createUserContext = (context: UserInterface): UserContext => { +const createUserContext = (context: UserInterface): UserContext => { return { pubkey: context.pubKey, email: context.email, @@ -38,7 +44,7 @@ export const createUserContext = (context: UserInterface): UserContext => { } } -export const createLoginUserContext = (context: UserInterface): LoginUserContext => { +const createLoginUserContext = (context: UserInterface): LoginUserContext => { return { email: context.email, firstName: context.firstName, @@ -59,7 +65,7 @@ export const createLoginUserContext = (context: UserInterface): LoginUserContext } } -export const createLoginUserBackupContext = ( +const createLoginUserBackupContext = ( context: UserInterface, loginUser: LoginUser, ): LoginUserBackupContext => { @@ -70,7 +76,7 @@ export const createLoginUserBackupContext = ( } } -export const createServerUserContext = (context: UserInterface): ServerUserContext => { +const createServerUserContext = (context: UserInterface): ServerUserContext => { return { role: context.role, username: context.username, @@ -83,9 +89,18 @@ export const createServerUserContext = (context: UserInterface): ServerUserConte } } -export const createLoginUserRolesContext = (loginUser: LoginUser): LoginUserRolesContext => { +const createLoginUserRolesContext = (loginUser: LoginUser): LoginUserRolesContext => { return { userId: loginUser.id, roleId: 1, } } + +const createBalanceContext = (context: UserInterface, user: User): BalanceContext => { + return { + modified: context.balanceModified, + recordDate: context.recordDate, + amount: context.amount, + user, + } +} diff --git a/database/src/seeds/users/bibi-bloxberg.ts b/database/src/seeds/users/bibi-bloxberg.ts index d87e3eb4a..3fc9274b9 100644 --- a/database/src/seeds/users/bibi-bloxberg.ts +++ b/database/src/seeds/users/bibi-bloxberg.ts @@ -22,4 +22,8 @@ export const bibiBloxberg = { 'knife normal level all hurdle crucial color avoid warrior stadium road bachelor affair topple hawk pottery right afford immune two ceiling budget glance hour ', mnemonicType: 2, isAdmin: false, + addBalance: true, + balanceModified: new Date('2021-11-30T10:37:11'), + recordDate: new Date('2021-11-30T10:37:11'), + amount: 10000000, } diff --git a/database/src/seeds/users/bob-baumeister.ts b/database/src/seeds/users/bob-baumeister.ts index 33ce35656..bc9bdbbc1 100644 --- a/database/src/seeds/users/bob-baumeister.ts +++ b/database/src/seeds/users/bob-baumeister.ts @@ -22,4 +22,8 @@ export const bobBaumeister = { 'detail master source effort unable waste tilt flush domain orchard art truck hint barrel response gate impose peanut secret merry three uncle wink resource ', mnemonicType: 2, isAdmin: false, + addBalance: true, + balanceModified: new Date('2021-11-30T10:37:14'), + recordDate: new Date('2021-11-30T10:37:14'), + amount: 10000000, } diff --git a/database/src/seeds/users/raeuber-hotzenplotz.ts b/database/src/seeds/users/raeuber-hotzenplotz.ts index 10fcf8af1..b1a6cc6b0 100644 --- a/database/src/seeds/users/raeuber-hotzenplotz.ts +++ b/database/src/seeds/users/raeuber-hotzenplotz.ts @@ -22,4 +22,8 @@ export const raeuberHotzenplotz = { 'gospel trip tenant mouse spider skill auto curious man video chief response same little over expire drum display fancy clinic keen throw urge basket ', mnemonicType: 2, isAdmin: false, + addBalance: true, + balanceModified: new Date('2021-11-30T10:37:13'), + recordDate: new Date('2021-11-30T10:37:13'), + amount: 10000000, } From 66e629daa2081c3a35b07e99245f7e6d30304e4d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 1 Dec 2021 11:02:00 +0100 Subject: [PATCH 06/35] Interface for TransactionCreateCoin and TransactionSendCoin --- database/src/interface/TransactionContext.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/database/src/interface/TransactionContext.ts b/database/src/interface/TransactionContext.ts index 4cda149af..182a924a3 100644 --- a/database/src/interface/TransactionContext.ts +++ b/database/src/interface/TransactionContext.ts @@ -1,3 +1,4 @@ +import { Transaction } from '../../entity/Transaction' import { TransactionSendCoin } from '../../entity/TransactionSendCoin' import { TransactionCreation } from '../../entity/TransactionCreation' import { User } from '../../entity/User' @@ -18,3 +19,20 @@ export interface BalanceContext { amount?: number user?: User } + +export interface TransactionSendCoinContext { + senderPublic?: Buffer + userId?: number + recipiantPublic?: Buffer + recipiantUserId?: number + amount?: number + senderFinalBalance?: number + transaction?: Transaction +} + +export interface TransactionCreationContext { + userId?: number + amount?: number + targetDate?: Timestamp + transaction?: Transaction +} From 2a5b0e49fe29c18e067031604922d6dc79d6398b Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 1 Dec 2021 13:58:24 +0100 Subject: [PATCH 07/35] add userTransactions, transactionCreation and transaction --- .../factories/transaction-creation.factory.ts | 18 ++++++ .../src/factories/user-transaction.factory.ts | 19 ++++++ database/src/interface/TransactionContext.ts | 8 +++ database/src/interface/UserInterface.ts | 4 +- database/src/seeds/helpers/user-helpers.ts | 60 ++++++++++++++++++- database/src/seeds/users/bibi-bloxberg.ts | 5 ++ database/src/seeds/users/bob-baumeister.ts | 5 ++ .../src/seeds/users/raeuber-hotzenplotz.ts | 5 ++ 8 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 database/src/factories/transaction-creation.factory.ts create mode 100644 database/src/factories/user-transaction.factory.ts diff --git a/database/src/factories/transaction-creation.factory.ts b/database/src/factories/transaction-creation.factory.ts new file mode 100644 index 000000000..ec0b9e8a6 --- /dev/null +++ b/database/src/factories/transaction-creation.factory.ts @@ -0,0 +1,18 @@ +import Faker from 'faker' +import { define } from 'typeorm-seeding' +import { TransactionCreation } from '../../entity/TransactionCreation' +import { TransactionCreationContext } from '../interface/TransactionContext' + +define(TransactionCreation, (faker: typeof Faker, context?: TransactionCreationContext) => { + if (!context || !context.userId || !context.transaction) { + throw new Error('TransactionCreation: No userId and/or transaction present!') + } + + const transactionCreation = new TransactionCreation() + transactionCreation.userId = context.userId + transactionCreation.amount = context.amount ? context.amount : 100000 + transactionCreation.targetDate = context.targetDate ? context.targetDate : new Date() + transactionCreation.transaction = context.transaction + + return transactionCreation +}) diff --git a/database/src/factories/user-transaction.factory.ts b/database/src/factories/user-transaction.factory.ts new file mode 100644 index 000000000..7ea79235b --- /dev/null +++ b/database/src/factories/user-transaction.factory.ts @@ -0,0 +1,19 @@ +import Faker from 'faker' +import { define } from 'typeorm-seeding' +import { UserTransaction } from '../../entity/UserTransaction' +import { UserTransactionContext } from '../interface/TransactionContext' + +define(UserTransaction, (faker: typeof Faker, context?: UserTransactionContext) => { + if (!context || !context.userId || !context.transactionId) { + throw new Error('UserTransaction: No userId and/or transactionId present!') + } + + const userTransaction = new UserTransaction() + userTransaction.userId = context.userId + userTransaction.transactionId = context.transactionId + userTransaction.transactionTypeId = context.transactionTypeId ? context.transactionTypeId : 1 + userTransaction.balance = context.balance ? context.balance : 100000 + userTransaction.balanceDate = context.balanceDate ? context.balanceDate : new Date() + + return userTransaction +}) diff --git a/database/src/interface/TransactionContext.ts b/database/src/interface/TransactionContext.ts index 182a924a3..3a6ceadc0 100644 --- a/database/src/interface/TransactionContext.ts +++ b/database/src/interface/TransactionContext.ts @@ -36,3 +36,11 @@ export interface TransactionCreationContext { targetDate?: Timestamp transaction?: Transaction } + +export interface UserTransactionContext { + userId?: number + transactionId?: number + transactionTypeId?: number + balance?: number + balanceDate?: Date +} diff --git a/database/src/interface/UserInterface.ts b/database/src/interface/UserInterface.ts index 33919fb74..ae8b4ecdb 100644 --- a/database/src/interface/UserInterface.ts +++ b/database/src/interface/UserInterface.ts @@ -27,10 +27,12 @@ export interface UserInterface { modified?: Date // flag for admin isAdmin?: boolean - // flag for balance + // flag for balance (creation of 1000 GDD) addBalance?: boolean // balance balanceModified?: Date recordDate?: Date + targetDate?: Date amount?: number + creationTxHash?: Buffer } diff --git a/database/src/seeds/helpers/user-helpers.ts b/database/src/seeds/helpers/user-helpers.ts index 79068c2ec..54e8c76d1 100644 --- a/database/src/seeds/helpers/user-helpers.ts +++ b/database/src/seeds/helpers/user-helpers.ts @@ -5,7 +5,12 @@ import { ServerUserContext, LoginUserRolesContext, } from '../../interface/UserContext' -import { BalanceContext } from '../../interface/TransactionContext' +import { + BalanceContext, + TransactionContext, + TransactionCreationContext, + UserTransactionContext, +} from '../../interface/TransactionContext' import { UserInterface } from '../../interface/UserInterface' import { User } from '../../../entity/User' import { LoginUser } from '../../../entity/LoginUser' @@ -13,6 +18,9 @@ import { LoginUserBackup } from '../../../entity/LoginUserBackup' import { ServerUser } from '../../../entity/ServerUser' import { LoginUserRoles } from '../../../entity/LoginUserRoles' import { Balance } from '../../../entity/Balance' +import { Transaction } from '../../../entity/Transaction' +import { UserTransaction } from '../../../entity/UserTransaction' +import { TransactionCreation } from '../../../entity/TransactionCreation' import { Factory } from 'typeorm-seeding' export const userSeeder = async (factory: Factory, userData: UserInterface): Promise => { @@ -29,7 +37,17 @@ export const userSeeder = async (factory: Factory, userData: UserInterface): Pro } if (userData.addBalance) { + // create some GDD for the user await factory(Balance)(createBalanceContext(userData, user)).create() + const transaction = await factory(Transaction)( + createTransactionContext(userData, 1, 'Herzlich Willkommen bei Gradido!'), + ).create() + await factory(TransactionCreation)( + createTransactionCreationContext(userData, user, transaction), + ).create() + await factory(UserTransaction)( + createUserTransactionContext(userData, user, transaction), + ).create() } } @@ -104,3 +122,43 @@ const createBalanceContext = (context: UserInterface, user: User): BalanceContex user, } } + +const createTransactionContext = ( + context: UserInterface, + type: number, + memo: string, +): TransactionContext => { + return { + transactionTypeId: type, + txHash: context.creationTxHash, + memo, + received: context.recordDate, + } +} + +const createTransactionCreationContext = ( + context: UserInterface, + user: User, + transaction: Transaction, +): TransactionCreationContext => { + return { + userId: user.id, + amount: context.amount, + targetDate: context.targetDate, + transaction, + } +} + +const createUserTransactionContext = ( + context: UserInterface, + user: User, + transaction: Transaction, +): UserTransactionContext => { + return { + userId: user.id, + transactionId: transaction.id, + transactionTypeId: transaction.transactionTypeId, + balance: context.amount, + balanceDate: context.recordDate, + } +} diff --git a/database/src/seeds/users/bibi-bloxberg.ts b/database/src/seeds/users/bibi-bloxberg.ts index 3fc9274b9..9d5421a9f 100644 --- a/database/src/seeds/users/bibi-bloxberg.ts +++ b/database/src/seeds/users/bibi-bloxberg.ts @@ -25,5 +25,10 @@ export const bibiBloxberg = { addBalance: true, balanceModified: new Date('2021-11-30T10:37:11'), recordDate: new Date('2021-11-30T10:37:11'), + targetDate: new Date('2021-08-01 00:00:00'), amount: 10000000, + creationTxHash: Buffer.from( + '51103dc0fc2ca5d5d75a9557a1e899304e5406cfdb1328d8df6414d527b0118100000000000000000000000000000000', + 'hex', + ), } diff --git a/database/src/seeds/users/bob-baumeister.ts b/database/src/seeds/users/bob-baumeister.ts index bc9bdbbc1..c075361a4 100644 --- a/database/src/seeds/users/bob-baumeister.ts +++ b/database/src/seeds/users/bob-baumeister.ts @@ -25,5 +25,10 @@ export const bobBaumeister = { addBalance: true, balanceModified: new Date('2021-11-30T10:37:14'), recordDate: new Date('2021-11-30T10:37:14'), + targetDate: new Date('2021-08-01 00:00:00'), amount: 10000000, + creationTxHash: Buffer.from( + 'be095dc87acb94987e71168fee8ecbf50ecb43a180b1006e75d573b35725c69c00000000000000000000000000000000', + 'hex', + ), } diff --git a/database/src/seeds/users/raeuber-hotzenplotz.ts b/database/src/seeds/users/raeuber-hotzenplotz.ts index b1a6cc6b0..6380a8beb 100644 --- a/database/src/seeds/users/raeuber-hotzenplotz.ts +++ b/database/src/seeds/users/raeuber-hotzenplotz.ts @@ -25,5 +25,10 @@ export const raeuberHotzenplotz = { addBalance: true, balanceModified: new Date('2021-11-30T10:37:13'), recordDate: new Date('2021-11-30T10:37:13'), + targetDate: new Date('2021-08-01 00:00:00'), amount: 10000000, + creationTxHash: Buffer.from( + '23ba44fd84deb59b9f32969ad0cb18bfa4588be1bdb99c396888506474c16c1900000000000000000000000000000000', + 'hex', + ), } From e99aa0d5adf4809ebea34ed3582b935a77e377fc Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 1 Dec 2021 14:03:56 +0100 Subject: [PATCH 08/35] timestamp to date --- database/src/interface/TransactionContext.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/src/interface/TransactionContext.ts b/database/src/interface/TransactionContext.ts index 3a6ceadc0..e1122bc3e 100644 --- a/database/src/interface/TransactionContext.ts +++ b/database/src/interface/TransactionContext.ts @@ -33,7 +33,7 @@ export interface TransactionSendCoinContext { export interface TransactionCreationContext { userId?: number amount?: number - targetDate?: Timestamp + targetDate?: Date transaction?: Transaction } From e09121d854e98245143cf2025601b158916003ea Mon Sep 17 00:00:00 2001 From: ogerly Date: Thu, 2 Dec 2021 08:17:56 +0100 Subject: [PATCH 09/35] Admin sends confirmPendingCreation to apollo. --- admin/src/components/UserTable.vue | 28 +++++++++++++-------- admin/src/graphql/confirmPendingCreation.js | 7 ++++++ 2 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 admin/src/graphql/confirmPendingCreation.js diff --git a/admin/src/components/UserTable.vue b/admin/src/components/UserTable.vue index e47963159..fd02a08db 100644 --- a/admin/src/components/UserTable.vue +++ b/admin/src/components/UserTable.vue @@ -132,6 +132,7 @@ From 9c0bd490fab39aefe565d10d165badb9e21a0349 Mon Sep 17 00:00:00 2001 From: elweyn Date: Sat, 4 Dec 2021 11:39:00 +0100 Subject: [PATCH 24/35] Moved created method to the end. --- admin/src/components/EditCreationFormular.vue | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/admin/src/components/EditCreationFormular.vue b/admin/src/components/EditCreationFormular.vue index 9154a68fa..c46698b9d 100644 --- a/admin/src/components/EditCreationFormular.vue +++ b/admin/src/components/EditCreationFormular.vue @@ -166,30 +166,6 @@ export default { required: true, }, }, - created() { - this.searchModeratorData() - if (this.pagetype === 'PageCreationConfirm' && this.creationUserData.date) { - switch (this.$moment(this.creationUserData.date).format('MMMM')) { - case this.currentMonth.short: - this.createdIndex = 2 - this.radioSelected = this.currentMonth - break - case this.lastMonth.short: - this.createdIndex = 1 - this.radioSelected = this.lastMonth - break - case this.beforeLastMonth.short: - this.createdIndex = 0 - this.radioSelected = this.beforeLastMonth - break - default: - throw new Error('Something went wrong') - } - this.selectedOpenCreationAmount[this.createdIndex] = - this.creation[this.createdIndex] + this.creationUserData.amount - this.rangeMax = this.selectedOpenCreationAmount[this.createdIndex] - } - }, data() { return { radioSelected: '', @@ -293,5 +269,29 @@ export default { }) }, }, + created() { + this.searchModeratorData() + if (this.pagetype === 'PageCreationConfirm' && this.creationUserData.date) { + switch (this.$moment(this.creationUserData.date).format('MMMM')) { + case this.currentMonth.short: + this.createdIndex = 2 + this.radioSelected = this.currentMonth + break + case this.lastMonth.short: + this.createdIndex = 1 + this.radioSelected = this.lastMonth + break + case this.beforeLastMonth.short: + this.createdIndex = 0 + this.radioSelected = this.beforeLastMonth + break + default: + throw new Error('Something went wrong') + } + this.selectedOpenCreationAmount[this.createdIndex] = + this.creation[this.createdIndex] + this.creationUserData.amount + this.rangeMax = this.selectedOpenCreationAmount[this.createdIndex] + } + }, } From a5406286fe6666e68c37b5455952e2b838ea8790 Mon Sep 17 00:00:00 2001 From: elweyn Date: Sat, 4 Dec 2021 11:43:00 +0100 Subject: [PATCH 25/35] change logic need a if exists or if not exists to up and downgrade easily. --- database/migrations/0002-add_settings.ts | 4 +- .../migrations/0003-login_server_tables.ts | 40 +++++++++---------- database/migrations/0004-login_server_data.ts | 14 +------ database/migrations/0005-admin_tables.ts | 4 +- 4 files changed, 25 insertions(+), 37 deletions(-) diff --git a/database/migrations/0002-add_settings.ts b/database/migrations/0002-add_settings.ts index 1b3b8a1a4..5c1b4fbe7 100644 --- a/database/migrations/0002-add_settings.ts +++ b/database/migrations/0002-add_settings.ts @@ -14,7 +14,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn(` - CREATE TABLE \`user_setting\` ( + CREATE TABLE IF NOT EXISTS \`user_setting\` ( \`id\` int(10) unsigned NOT NULL AUTO_INCREMENT, \`userId\` int(11) NOT NULL, \`key\` varchar(255) NOT NULL, @@ -25,5 +25,5 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { // write downgrade logic as parameter of queryFn - await queryFn(`DROP TABLE \`user_setting\`;`) + await queryFn(`DROP TABLE IF EXISTS \`user_setting\`;`) } diff --git a/database/migrations/0003-login_server_tables.ts b/database/migrations/0003-login_server_tables.ts index 54e7bca54..d3d720c97 100644 --- a/database/migrations/0003-login_server_tables.ts +++ b/database/migrations/0003-login_server_tables.ts @@ -14,7 +14,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn(` - CREATE TABLE \`login_app_access_tokens\` ( + CREATE TABLE IF NOT EXISTS \`login_app_access_tokens\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`user_id\` int NOT NULL, \`access_code\` bigint unsigned NOT NULL, @@ -25,7 +25,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_elopage_buys\` ( + CREATE TABLE IF NOT EXISTS \`login_elopage_buys\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`elopage_user_id\` int DEFAULT NULL, \`affiliate_program_id\` int NOT NULL, @@ -42,7 +42,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_email_opt_in_types\` ( + CREATE TABLE IF NOT EXISTS \`login_email_opt_in_types\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`name\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, @@ -50,7 +50,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_email_opt_in\` ( + CREATE TABLE IF NOT EXISTS \`login_email_opt_in\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`user_id\` int NOT NULL, \`verification_code\` bigint unsigned NOT NULL, @@ -63,7 +63,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_groups\` ( + CREATE TABLE IF NOT EXISTS \`login_groups\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`alias\` varchar(190) NOT NULL, \`name\` varchar(255) NOT NULL, @@ -76,7 +76,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_pending_tasks\` ( + CREATE TABLE IF NOT EXISTS \`login_pending_tasks\` ( \`id\` int UNSIGNED NOT NULL AUTO_INCREMENT, \`user_id\` int UNSIGNED DEFAULT 0, \`request\` varbinary(2048) NOT NULL, @@ -91,7 +91,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_roles\` ( + CREATE TABLE IF NOT EXISTS \`login_roles\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`name\` varchar(255) NOT NULL, \`description\` varchar(255) NOT NULL, @@ -100,7 +100,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_user_backups\` ( + CREATE TABLE IF NOT EXISTS \`login_user_backups\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`user_id\` int NOT NULL, \`passphrase\` text NOT NULL, @@ -109,7 +109,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_user_roles\` ( + CREATE TABLE IF NOT EXISTS \`login_user_roles\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`user_id\` int NOT NULL, \`role_id\` int NOT NULL, @@ -117,7 +117,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; `) await queryFn(` - CREATE TABLE \`login_users\` ( + CREATE TABLE IF NOT EXISTS \`login_users\` ( \`id\` int unsigned NOT NULL AUTO_INCREMENT, \`email\` varchar(191) NOT NULL, \`first_name\` varchar(150) NOT NULL, @@ -143,14 +143,14 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { // write downgrade logic as parameter of queryFn - await queryFn(`DROP TABLE \`login_app_access_tokens\`;`) - await queryFn(`DROP TABLE \`login_elopage_buys\`;`) - await queryFn(`DROP TABLE \`login_email_opt_in_types\`;`) - await queryFn(`DROP TABLE \`login_email_opt_in\`;`) - await queryFn(`DROP TABLE \`login_groups\`;`) - await queryFn(`DROP TABLE \`login_pending_tasks\`;`) - await queryFn(`DROP TABLE \`login_roles\`;`) - await queryFn(`DROP TABLE \`login_user_backups\`;`) - await queryFn(`DROP TABLE \`login_user_roles\`;`) - await queryFn(`DROP TABLE \`login_users\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_app_access_tokens\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_elopage_buys\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_email_opt_in_types\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_email_opt_in\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_groups\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_pending_tasks\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_roles\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_user_backups\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_user_roles\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_users\`;`) } diff --git a/database/migrations/0004-login_server_data.ts b/database/migrations/0004-login_server_data.ts index f319b16ab..b69283ad7 100644 --- a/database/migrations/0004-login_server_data.ts +++ b/database/migrations/0004-login_server_data.ts @@ -62,16 +62,4 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis `) } -export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { - // write downgrade logic as parameter of queryFn - await queryFn(`DELETE FROM \`login_app_access_tokens\`;`) - await queryFn(`DELETE FROM \`login_elopage_buys\`;`) - await queryFn(`DELETE FROM \`login_email_opt_in_types\`;`) - await queryFn(`DELETE FROM \`login_email_opt_in\`;`) - await queryFn(`DELETE FROM \`login_groups\`;`) - await queryFn(`DELETE FROM \`login_pending_tasks\`;`) - await queryFn(`DELETE FROM \`login_roles\`;`) - await queryFn(`DELETE FROM \`login_user_backups\`;`) - await queryFn(`DELETE FROM \`login_user_roles\`;`) - await queryFn(`DELETE FROM \`login_users\`;`) -} +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) {} diff --git a/database/migrations/0005-admin_tables.ts b/database/migrations/0005-admin_tables.ts index 6398b22fc..bd325678f 100644 --- a/database/migrations/0005-admin_tables.ts +++ b/database/migrations/0005-admin_tables.ts @@ -11,7 +11,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn(` - CREATE TABLE \`login_pending_tasks_admin\` ( + CREATE TABLE IF NOT EXISTS \`login_pending_tasks_admin\` ( \`id\` int UNSIGNED NOT NULL AUTO_INCREMENT, \`userId\` int UNSIGNED DEFAULT 0, \`created\` datetime NOT NULL, @@ -25,5 +25,5 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis } export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { - await queryFn(`DROP TABLE \`login_pending_tasks_admin\`;`) + await queryFn(`DROP TABLE IF EXISTS \`login_pending_tasks_admin\`;`) } From c7633bb1eb4047c3a572572f79506a54a787edf4 Mon Sep 17 00:00:00 2001 From: elweyn Date: Sat, 4 Dec 2021 12:22:48 +0100 Subject: [PATCH 26/35] Test submit of EditCreationFormular, remove getCountPendingCreations. --- .../components/EditCreationFormular.spec.js | 38 +++++++++++++++++++ admin/src/components/EditCreationFormular.vue | 1 + admin/src/graphql/getCountPendingCreations.js | 7 ---- 3 files changed, 39 insertions(+), 7 deletions(-) delete mode 100644 admin/src/graphql/getCountPendingCreations.js diff --git a/admin/src/components/EditCreationFormular.spec.js b/admin/src/components/EditCreationFormular.spec.js index 8f8103b06..dd503411a 100644 --- a/admin/src/components/EditCreationFormular.spec.js +++ b/admin/src/components/EditCreationFormular.spec.js @@ -39,6 +39,12 @@ const mocks = { mutate: apolloMutateMock, }, $store: { + state: { + moderator: { + id: 0, + name: 'test moderator', + }, + }, commit: stateCommitMock, }, } @@ -92,6 +98,8 @@ describe('EditCreationFormular', () => { jest.clearAllMocks() await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Test create coins' }) + await wrapper.setData({ value: 90 }) }) describe('first radio button', () => { @@ -106,6 +114,16 @@ describe('EditCreationFormular', () => { it('sets rangeMax to 200', () => { expect(wrapper.vm.rangeMax).toBe(200) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + }) }) describe('second radio button', () => { @@ -120,6 +138,16 @@ describe('EditCreationFormular', () => { it('sets rangeMax to 400', () => { expect(wrapper.vm.rangeMax).toBe(400) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + }) }) describe('third radio button', () => { @@ -134,6 +162,16 @@ describe('EditCreationFormular', () => { it('sets rangeMax to 400', () => { expect(wrapper.vm.rangeMax).toBe(600) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + }) }) }) }) diff --git a/admin/src/components/EditCreationFormular.vue b/admin/src/components/EditCreationFormular.vue index c46698b9d..5e1bf4be1 100644 --- a/admin/src/components/EditCreationFormular.vue +++ b/admin/src/components/EditCreationFormular.vue @@ -106,6 +106,7 @@ diff --git a/admin/src/graphql/getCountPendingCreations.js b/admin/src/graphql/getCountPendingCreations.js deleted file mode 100644 index f8593ee59..000000000 --- a/admin/src/graphql/getCountPendingCreations.js +++ /dev/null @@ -1,7 +0,0 @@ -import gql from 'graphql-tag' - -export const countPendingCreations = gql` - query { - countPendingCreations - } -` From 16fa3de5736ad3c6157c8ec028a1f6b59dcf1fa7 Mon Sep 17 00:00:00 2001 From: elweyn Date: Sat, 4 Dec 2021 12:29:38 +0100 Subject: [PATCH 27/35] click on months in the creation form if index 0, and id set for the label --- admin/src/components/CreationFormular.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/admin/src/components/CreationFormular.vue b/admin/src/components/CreationFormular.vue index dd19ef7ca..41eeef6a3 100644 --- a/admin/src/components/CreationFormular.vue +++ b/admin/src/components/CreationFormular.vue @@ -6,6 +6,7 @@ - +
@@ -92,6 +95,7 @@ v-if="pagetype === 'PageCreationConfirm'" type="button" variant="success" + class="test-submit" @click="submitCreation" :disabled="radioSelected === '' || value <= 0 || text.length < 10" > @@ -183,7 +187,9 @@ export default { methods: { // Auswählen eines Zeitraumes updateRadioSelected(name, index, openCreation) { + console.log('this.createdIndex befor', this.createdIndex) this.createdIndex = index + console.log('this.createdIndex last', this.createdIndex) // Wenn Mehrfachschöpfung if (this.type === 'massCreation') { // An Creation.vue emitten und radioSelectedMass aktualisieren From f5572febee74cffecfbd5a4b31581a5e55dc17c3 Mon Sep 17 00:00:00 2001 From: elweyn Date: Sat, 4 Dec 2021 13:27:10 +0100 Subject: [PATCH 28/35] Testing Creation and EditCreation formulars. --- admin/src/components/CreationFormular.spec.js | 186 ++++++++++++++++++ admin/src/components/CreationFormular.vue | 20 +- admin/src/components/EditCreationFormular.vue | 23 +-- 3 files changed, 192 insertions(+), 37 deletions(-) diff --git a/admin/src/components/CreationFormular.spec.js b/admin/src/components/CreationFormular.spec.js index 01faaed39..f167d48a1 100644 --- a/admin/src/components/CreationFormular.spec.js +++ b/admin/src/components/CreationFormular.spec.js @@ -11,7 +11,14 @@ const apolloMock = jest.fn().mockResolvedValue({ }, }, }) +const apolloMutateMock = jest.fn().mockResolvedValue({ + data: { + createPendingCreation: [0, 0, 0], + }, +}) const stateCommitMock = jest.fn() +const toastedErrorMock = jest.fn() +const toastedSuccessMock = jest.fn() const mocks = { $moment: jest.fn(() => { @@ -26,9 +33,20 @@ const mocks = { }), $apollo: { query: apolloMock, + mutate: apolloMutateMock, }, $store: { commit: stateCommitMock, + state: { + moderator: { + id: 0, + name: 'test moderator', + }, + }, + }, + $toasted: { + error: toastedErrorMock, + success: toastedSuccessMock, }, } @@ -124,6 +142,8 @@ describe('CreationFormular', () => { jest.clearAllMocks() await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Test create coins' }) + await wrapper.setData({ value: 90 }) }) describe('first radio button', () => { @@ -138,6 +158,66 @@ describe('CreationFormular', () => { it('sets rangeMax to 200', () => { expect(wrapper.vm.rangeMax).toBe(200) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + }) + + describe('sendForm', () => { + beforeEach(async () => { + apolloMutateMock.mockRejectedValueOnce({ message: 'Ouch!' }) + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(toastedErrorMock).toBeCalled() + }) + }) + + describe('Negativ value', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ value: -20 }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Empty text', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: '' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Text length less than 10', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Try this' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) }) describe('second radio button', () => { @@ -152,6 +232,55 @@ describe('CreationFormular', () => { it('sets rangeMax to 400', () => { expect(wrapper.vm.rangeMax).toBe(400) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends ... to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + }) + + describe('Negativ value', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ value: -20 }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Empty text', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: '' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Text length less than 10', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Try this' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) }) describe('third radio button', () => { @@ -166,6 +295,63 @@ describe('CreationFormular', () => { it('sets rangeMax to 400', () => { expect(wrapper.vm.rangeMax).toBe(600) }) + + describe('sendForm', () => { + beforeEach(async () => { + await wrapper.find('.test-submit').trigger('click') + }) + + it('sends mutation to apollo', () => { + expect(apolloMutateMock).toBeCalled() + }) + + it('toast success message', () => { + expect(toastedSuccessMock).toBeCalled() + }) + + it('store commit openCreationPlus', () => { + expect(stateCommitMock).toBeCalledWith('openCreationsPlus', 1) + }) + }) + + describe('Negativ value', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ value: -20 }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Empty text', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: '' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) + + describe('Text length less than 10', () => { + beforeEach(async () => { + jest.clearAllMocks() + await wrapper.setProps({ type: 'singleCreation', creation: [200, 400, 600] }) + await wrapper.setData({ rangeMin: 180 }) + await wrapper.setData({ text: 'Try this' }) + }) + + it('has no submit button', async () => { + expect(await wrapper.find('.test-submit').attributes('disabled')).toBe('disabled') + }) + }) }) }) }) diff --git a/admin/src/components/CreationFormular.vue b/admin/src/components/CreationFormular.vue index 41eeef6a3..5b131dca8 100644 --- a/admin/src/components/CreationFormular.vue +++ b/admin/src/components/CreationFormular.vue @@ -106,6 +106,7 @@ v-else type="button" variant="success" + class="test-submit" @click="submitCreation" :disabled="radioSelected === '' || value <= 0 || text.length < 10" > @@ -187,9 +188,7 @@ export default { methods: { // Auswählen eines Zeitraumes updateRadioSelected(name, index, openCreation) { - console.log('this.createdIndex befor', this.createdIndex) this.createdIndex = index - console.log('this.createdIndex last', this.createdIndex) // Wenn Mehrfachschöpfung if (this.type === 'massCreation') { // An Creation.vue emitten und radioSelectedMass aktualisieren @@ -201,23 +200,6 @@ export default { } }, submitCreation() { - // Formular Prüfen ob ein Zeitraum ausgewählt wurde. Ansonsten abbrechen und Hinweis anzeigen - if (this.radioSelected === '') { - return this.$toasted.error('Bitte wähle einen Zeitraum!') - } - // Formular Prüfen ob der GDD Betrag grösser 0 ist. Ansonsten abbrechen und Hinweis anzeigen - if (this.value <= 0) { - return this.$toasted.error('Bitte gib einen GDD Betrag an!') - } - // Formular Prüfen ob der Text vorhanden ist. Ansonsten abbrechen und Hinweis anzeigen - if (this.text === '') { - return this.$toasted.error('Bitte gib einen Text ein!') - } - // Formular Prüfen ob der Text länger als 10 Zeichen hat. Ansonsten abbrechen und Hinweis anzeigen - if (this.text.length < 10) { - return this.$toasted.error('Bitte gib einen Text ein der länger als 10 Zeichen ist!') - } - if (this.type === 'massCreation') { // Die anzahl der Mitglieder aus der Mehrfachschöpfung const i = Object.keys(this.itemsMassCreation).length diff --git a/admin/src/components/EditCreationFormular.vue b/admin/src/components/EditCreationFormular.vue index 5e1bf4be1..bda48569a 100644 --- a/admin/src/components/EditCreationFormular.vue +++ b/admin/src/components/EditCreationFormular.vue @@ -6,6 +6,7 @@ Date: Sat, 4 Dec 2021 13:38:53 +0100 Subject: [PATCH 29/35] test ok for Overview.spec.js --- admin/src/pages/Overview.spec.js | 52 ++++++++++++++++++++++++++++++++ admin/src/pages/Overview.vue | 2 +- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 admin/src/pages/Overview.spec.js diff --git a/admin/src/pages/Overview.spec.js b/admin/src/pages/Overview.spec.js new file mode 100644 index 000000000..7f0a2b3cc --- /dev/null +++ b/admin/src/pages/Overview.spec.js @@ -0,0 +1,52 @@ +import { mount } from '@vue/test-utils' +import Overview from './Overview.vue' + +const localVue = global.localVue + +const apolloQueryMock = jest.fn().mockResolvedValue({ + data: { + searchUsers: [ + { + firstName: 'Bibi', + lastName: 'Bloxberg', + email: 'bibi@bloxberg.de', + creation: [200, 400, 600], + }, + ], + }, +}) + +const toastErrorMock = jest.fn() + +const mocks = { + $store: { + state: { + openCreations: 0, + }, + commit: jest.fn(), + }, + $apollo: { + query: apolloQueryMock, + }, + $toasted: { + error: toastErrorMock, + }, +} + +describe('Overview', () => { + let wrapper + + const Wrapper = () => { + return mount(Overview, { localVue, mocks }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + it('has a DIV element with the class.admin-overview', () => { + expect(wrapper.find('div.admin-overview').exists()).toBeTruthy() + }) + }) +}) diff --git a/admin/src/pages/Overview.vue b/admin/src/pages/Overview.vue index 8d05e03e8..f45f588e5 100644 --- a/admin/src/pages/Overview.vue +++ b/admin/src/pages/Overview.vue @@ -1,5 +1,5 @@