Failed Conditions
Push — master ( ab912b...01f77f )
by Adrien
10:12
created

testHydrateLinesAndFlushMustThrowWithALineWithoutAnyAccount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Repository;
6
7
use Application\Model\Account;
8
use Application\Model\Transaction;
9
use Application\Model\TransactionLine;
10
use Application\Model\User;
11
use Application\Repository\TransactionRepository;
12
use ApplicationTest\Traits\LimitedAccessSubQuery;
13
use Cake\Chronos\Chronos;
14
use Money\Money;
15
16
/**
17
 * @group Repository
18
 */
19
class TransactionRepositoryTest extends AbstractRepositoryTest
20
{
21
    use LimitedAccessSubQuery;
22
23
    /**
24
     * @var TransactionRepository
25
     */
26
    private $repository;
27
28
    protected function setUp(): void
29
    {
30
        parent::setUp();
31
        $this->repository = $this->getEntityManager()->getRepository(Transaction::class);
32
    }
33
34
    public function providerGetAccessibleSubQuery(): array
35
    {
36
        $all = [8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007];
37
38
        $family = [8000, 8002, 8002, 8003, 8004, 8006];
39
40
        return [
41
            ['anonymous', []],
42
            ['bookingonly', []],
43
            ['individual', $family],
44
            ['member', $family],
45
            ['responsible', $all],
46
            ['administrator', $all],
47
        ];
48
    }
49
50
    public function testHydrateLinesAndFlush(): void
51
    {
52
        /** @var User $user */
53
        $user = $this->getEntityManager()->getRepository(User::class)->getOneByLogin('administrator');
54
        User::setCurrent($user);
55
56
        $credit = $user->getAccount();
57
        $debit = $this->getEntityManager()->getRepository(Account::class)->findOneBy(['code' => 1000]);
58
59
        $transaction = new Transaction();
60
        $transaction->setName('foo');
61
        $transaction->setTransactionDate(Chronos::now());
62
        $line = new TransactionLine();
63
        $line->setTransaction($transaction);
64
65
        self::assertTrue($transaction->getTransactionLines()->contains($line));
66
        $lines = [
67
            [
68
                'balance' => Money::CHF(500),
69
                'transactionDate' => Chronos::now(),
70
                'credit' => $credit,
71
                'debit' => $debit,
72
            ],
73
        ];
74
75
        $this->repository->hydrateLinesAndFlush($transaction, $lines);
76
77
        self::assertTrue(Money::CHF(500)->equals($credit->getBalance()), 'credit account balance must have been refreshed from DB');
78
        self::assertTrue(Money::CHF(500)->equals($debit->getBalance()), 'debit account balance must have been refreshed from DB');
79
        self::assertFalse($transaction->getTransactionLines()->contains($line), 'original line must have been deleted');
80
        self::assertCount(1, $transaction->getTransactionLines(), 'one line');
81
82
        $line = $transaction->getTransactionLines()->first();
83
        self::assertTrue(Money::CHF(500)->equals($line->getBalance()));
84
        self::assertSame($credit, $line->getCredit());
85
        self::assertSame($debit, $line->getDebit());
86
    }
87
88
    public function testHydrateLinesAndFlushMustThrowWithoutAnyLines(): void
89
    {
90
        $transaction = new Transaction();
91
92
        $this->expectExceptionMessage('A Transaction must have at least one TransactionLine');
93
        $this->repository->hydrateLinesAndFlush($transaction, []);
94
    }
95
96
    public function testHydrateLinesAndFlushMustThrowWithALineWithoutAnyAccount(): void
97
    {
98
        $transaction = new Transaction();
99
        $this->expectExceptionMessage('Cannot create a TransactionLine without any account');
100
        $this->repository->hydrateLinesAndFlush($transaction, [[]]);
101
    }
102
103
    public function testHydrateLinesAndFlushMustThrowWithUnbalancedLines(): void
104
    {
105
        /** @var User $user */
106
        $user = $this->getEntityManager()->getRepository(User::class)->getOneByLogin('administrator');
107
        User::setCurrent($user);
108
109
        $debit = $this->getEntityManager()->getRepository(Account::class)->findOneBy(['code' => 10201]);
110
        $credit = $this->getEntityManager()->getRepository(Account::class)->findOneBy(['code' => 1000]);
111
112
        $transaction = new Transaction();
113
        $transaction->setName('caisse à poste');
114
        $transaction->setRemarks('montants erronés');
115
        $transaction->setTransactionDate(Chronos::now());
116
        $line = new TransactionLine();
117
        $line->setTransaction($transaction);
118
119
        $lines = [
120
            [
121
                'balance' => Money::CHF(100000),
122
                'transactionDate' => Chronos::now(),
123
                'debit' => $debit,
124
            ],
125
            [
126
                'balance' => Money::CHF(90000),
127
                'credit' => $credit,
128
            ],
129
        ];
130
131
        $this->expectExceptionMessage('Transaction NEW non-équilibrée, débits: 1000.00, crédits: 900.00');
132
        $this->repository->hydrateLinesAndFlush($transaction, $lines);
133
    }
134
135
    public function testTriggers(): void
136
    {
137
        $account1 = 10096;
138
        $account2 = 10037;
139
140
        $this->assertAccountBalance($account1, 5000, 'initial balance');
141
        $this->assertAccountBalance($account2, 10000, 'initial balance');
142
143
        $connection = $this->getEntityManager()->getConnection();
144
        $count = $connection->delete('transaction', ['id' => 8000]);
145
146
        self::assertSame(1, $count);
147
        $this->assertAccountBalance($account1, 15000, 'balance should be increased after deletion');
148
        $this->assertAccountBalance($account2, 0, 'balance should be decreased after deletion');
149
    }
150
}
151