mirror of
https://github.com/IT4Change/gradido.git
synced 2026-02-06 09:56:05 +00:00
324 lines
12 KiB
TypeScript
324 lines
12 KiB
TypeScript
import { Community } from '@entity/Community'
|
|
import { Transaction } from '@entity/Transaction'
|
|
import { Decimal } from 'decimal.js-light'
|
|
|
|
import { logger } from '@/logging/logger'
|
|
|
|
import { CommunityRoot } from './proto/3_3/CommunityRoot'
|
|
import { CrossGroupType } from './proto/3_3/enum/CrossGroupType'
|
|
import { GradidoCreation } from './proto/3_3/GradidoCreation'
|
|
import { GradidoDeferredTransfer } from './proto/3_3/GradidoDeferredTransfer'
|
|
import { GradidoTransfer } from './proto/3_3/GradidoTransfer'
|
|
import { RegisterAddress } from './proto/3_3/RegisterAddress'
|
|
import { TransactionBody } from './proto/3_3/TransactionBody'
|
|
import { TransactionLogic } from './Transaction.logic'
|
|
|
|
let a: Transaction
|
|
let b: Transaction
|
|
|
|
describe('data/transaction.logic', () => {
|
|
describe('isBelongTogether', () => {
|
|
beforeEach(() => {
|
|
const now = new Date()
|
|
let body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
body.transfer = new GradidoTransfer()
|
|
body.otherGroup = 'recipient group'
|
|
|
|
a = new Transaction()
|
|
a.community = new Community()
|
|
a.communityId = 1
|
|
a.otherCommunityId = 2
|
|
a.id = 1
|
|
a.signingAccountId = 1
|
|
a.recipientAccountId = 2
|
|
a.createdAt = now
|
|
a.amount = new Decimal('100')
|
|
a.signature = Buffer.alloc(64)
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
|
|
body = new TransactionBody()
|
|
body.type = CrossGroupType.INBOUND
|
|
body.transfer = new GradidoTransfer()
|
|
body.otherGroup = 'sending group'
|
|
|
|
b = new Transaction()
|
|
b.community = new Community()
|
|
b.communityId = 2
|
|
b.otherCommunityId = 1
|
|
b.id = 2
|
|
b.signingAccountId = 1
|
|
b.recipientAccountId = 2
|
|
b.createdAt = now
|
|
b.amount = new Decimal('100')
|
|
b.signature = Buffer.alloc(64)
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
})
|
|
|
|
const spy = jest.spyOn(logger, 'info')
|
|
|
|
it('true', () => {
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(true)
|
|
})
|
|
|
|
it('false because of same id', () => {
|
|
b.id = 1
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith('id is the same, it is the same transaction!')
|
|
})
|
|
|
|
it('false because of different signing accounts', () => {
|
|
b.signingAccountId = 17
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
'transaction a and b are not pairs',
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('false because of different recipient accounts', () => {
|
|
b.recipientAccountId = 21
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
'transaction a and b are not pairs',
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('false because of different community ids', () => {
|
|
b.communityId = 6
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
'transaction a and b are not pairs',
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('false because of different other community ids', () => {
|
|
b.otherCommunityId = 3
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
'transaction a and b are not pairs',
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('false because of different createdAt', () => {
|
|
b.createdAt = new Date('2021-01-01T17:12')
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
'transaction a and b are not pairs',
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
describe('false because of mismatching cross group type', () => {
|
|
const body = new TransactionBody()
|
|
it('a is LOCAL', () => {
|
|
body.type = CrossGroupType.LOCAL
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenNthCalledWith(7, 'no one can be LOCAL')
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"cross group types don't match",
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('b is LOCAL', () => {
|
|
body.type = CrossGroupType.LOCAL
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenNthCalledWith(9, 'no one can be LOCAL')
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"cross group types don't match",
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('both are INBOUND', () => {
|
|
body.type = CrossGroupType.INBOUND
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"cross group types don't match",
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('both are OUTBOUND', () => {
|
|
body.type = CrossGroupType.OUTBOUND
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"cross group types don't match",
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('a is CROSS', () => {
|
|
body.type = CrossGroupType.CROSS
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"cross group types don't match",
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('b is CROSS', () => {
|
|
body.type = CrossGroupType.CROSS
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"cross group types don't match",
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('true with a as INBOUND and b as OUTBOUND', () => {
|
|
let body = TransactionBody.fromBodyBytes(a.bodyBytes)
|
|
body.type = CrossGroupType.INBOUND
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
body = TransactionBody.fromBodyBytes(b.bodyBytes)
|
|
body.type = CrossGroupType.OUTBOUND
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('false because of transaction type not suitable for cross group transactions', () => {
|
|
const body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
it('without transaction type (broken TransactionBody)', () => {
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(() => logic.isBelongTogether(b)).toThrowError("couldn't determine transaction type")
|
|
})
|
|
|
|
it('not the same transaction types', () => {
|
|
const body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
body.registerAddress = new RegisterAddress()
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"transaction types don't match",
|
|
expect.objectContaining({}),
|
|
)
|
|
})
|
|
|
|
it('community root cannot be a cross group transaction', () => {
|
|
let body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
body.communityRoot = new CommunityRoot()
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
body = new TransactionBody()
|
|
body.type = CrossGroupType.INBOUND
|
|
body.communityRoot = new CommunityRoot()
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"TransactionType COMMUNITY_ROOT couldn't be a CrossGroup Transaction",
|
|
)
|
|
})
|
|
|
|
it('Gradido Creation cannot be a cross group transaction', () => {
|
|
let body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
body.creation = new GradidoCreation()
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
body = new TransactionBody()
|
|
body.type = CrossGroupType.INBOUND
|
|
body.creation = new GradidoCreation()
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"TransactionType GRADIDO_CREATION couldn't be a CrossGroup Transaction",
|
|
)
|
|
})
|
|
|
|
it('Deferred Transfer cannot be a cross group transaction', () => {
|
|
let body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
body.deferredTransfer = new GradidoDeferredTransfer()
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
body = new TransactionBody()
|
|
body.type = CrossGroupType.INBOUND
|
|
body.deferredTransfer = new GradidoDeferredTransfer()
|
|
b.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith(
|
|
"TransactionType GRADIDO_DEFERRED_TRANSFER couldn't be a CrossGroup Transaction",
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('false because of wrong amount', () => {
|
|
it('amount missing on a', () => {
|
|
a.amount = undefined
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith('missing amount')
|
|
})
|
|
|
|
it('amount missing on b', () => {
|
|
b.amount = undefined
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith('missing amount')
|
|
})
|
|
|
|
it('amount not the same', () => {
|
|
a.amount = new Decimal('101')
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith('amounts mismatch', expect.objectContaining({}))
|
|
})
|
|
})
|
|
|
|
it('false because otherGroup are the same', () => {
|
|
const body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
body.transfer = new GradidoTransfer()
|
|
body.otherGroup = 'sending group'
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith('otherGroups are the same', expect.objectContaining({}))
|
|
})
|
|
|
|
it('false because of different memos', () => {
|
|
const body = new TransactionBody()
|
|
body.type = CrossGroupType.OUTBOUND
|
|
body.transfer = new GradidoTransfer()
|
|
body.otherGroup = 'recipient group'
|
|
body.memo = 'changed memo'
|
|
a.bodyBytes = Buffer.from(TransactionBody.encode(body).finish())
|
|
const logic = new TransactionLogic(a)
|
|
expect(logic.isBelongTogether(b)).toBe(false)
|
|
expect(spy).toHaveBeenLastCalledWith('memo differ', expect.objectContaining({}))
|
|
})
|
|
})
|
|
})
|