Passed
Push — master ( a056d8...a2923e )
by Adrien
10:19
created

TransactionLineRepositoryTest::testTriggers()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 102
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 64
c 1
b 0
f 0
dl 0
loc 102
rs 8.7853
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Repository;
6
7
use Application\Model\Account;
8
use Application\Model\TransactionLine;
9
use Application\Repository\AccountRepository;
10
use Application\Repository\TransactionLineRepository;
11
use ApplicationTest\Traits\LimitedAccessSubQuery;
12
use Cake\Chronos\Chronos;
13
use Cake\Chronos\ChronosDate;
14
use Money\Money;
15
16
class TransactionLineRepositoryTest extends AbstractRepositoryTest
17
{
18
    use LimitedAccessSubQuery;
19
20
    private TransactionLineRepository $repository;
21
22
    protected function setUp(): void
23
    {
24
        parent::setUp();
25
        $this->repository = $this->getEntityManager()->getRepository(TransactionLine::class);
26
    }
27
28
    public function providerGetAccessibleSubQuery(): iterable
29
    {
30
        $all = range(14000, 14011);
31
32
        $family = [14000, 14002, 14003, 14004, 14008, 14011];
33
        yield ['anonymous', []];
34
        yield ['bookingonly', []];
35
        yield ['individual', $family];
36
        yield ['member', $family];
37
        yield ['responsible', $all];
38
        yield ['administrator', $all];
39
    }
40
41
    public function testTriggers(): void
42
    {
43
        $account1 = 10096;
44
        $account2 = 10037;
45
        $account3 = 10085;
46
        $account4 = 10025;
47
48
        $this->assertAccountBalance($account1, 5000, 'initial balance');
49
        $this->assertAccountBalance($account2, 10000, 'initial balance');
50
        $this->assertAccountBalance($account3, 1250, 'initial balance');
51
        $this->assertAccountBalance($account4, 818750, 'initial balance');
52
53
        $connection = $this->getEntityManager()->getConnection();
54
        $connection->insert('transaction_line', [
55
            'transaction_id' => 8000,
56
            'debit_id' => $account1,
57
            'credit_id' => $account2,
58
            'balance' => 500,
59
        ]);
60
61
        $id = $connection->lastInsertId();
62
63
        $this->assertAccountBalance($account1, 4500, 'balance should be reduced when line is inserted');
64
        $this->assertAccountBalance($account2, 10500, 'balance should be increased when line is inserted');
65
66
        $count = $connection->update(
67
            'transaction_line',
68
            [
69
                'balance' => 4000,
70
            ],
71
            [
72
                'id' => $id,
73
            ]
74
        );
75
        self::assertSame(1, $count);
76
        $this->assertAccountBalance($account1, 1000, 'balance should be reduced even more after update');
77
        $this->assertAccountBalance($account2, 14000, 'balance should be increased even more after update');
78
79
        $count = $connection->update(
80
            'transaction_line',
81
            [
82
                'debit_id' => $account2,
83
                'credit_id' => $account1,
84
            ],
85
            [
86
                'id' => $id,
87
            ]
88
        );
89
        self::assertSame(1, $count);
90
        $this->assertAccountBalance($account1, 9000, 'balance should be twice increased after swapping both accounts');
91
        $this->assertAccountBalance($account2, 6000, 'balance should be reduced increased after swapping both accounts');
92
93
        $count = $connection->update(
94
            'transaction_line',
95
            [
96
                'debit_id' => $account2,
97
                'credit_id' => null,
98
            ],
99
            [
100
                'id' => $id,
101
            ]
102
        );
103
        self::assertSame(1, $count);
104
        $this->assertAccountBalance($account1, 5000, 'balance should be restored to its original value after deletion');
105
        $this->assertAccountBalance($account2, 6000, 'balance should be unchanged');
106
107
        $count = $connection->update(
108
            'transaction_line',
109
            [
110
                'debit_id' => null,
111
                'credit_id' => $account2,
112
            ],
113
            [
114
                'id' => $id,
115
            ]
116
        );
117
        self::assertSame(1, $count);
118
        $this->assertAccountBalance($account1, 5000, 'balance should be unchanged');
119
        $this->assertAccountBalance($account2, 14000, 'balance should be twice increased after swapping a single account');
120
121
        $count = $connection->update(
122
            'transaction_line',
123
            [
124
                'debit_id' => $account3,
125
                'credit_id' => $account4,
126
            ],
127
            [
128
                'id' => $id,
129
            ]
130
        );
131
        self::assertSame(1, $count);
132
        $this->assertAccountBalance($account1, 5000, 'balance should be restored to its original value after deletion');
133
        $this->assertAccountBalance($account2, 10000, 'balance should be restored to its original value after deletion');
134
        $this->assertAccountBalance($account3, 5250, 'balance should be increased after swapped account');
135
        $this->assertAccountBalance($account4, 814750, 'balance should be reduced after swapped account');
136
137
        $count = $connection->delete('transaction_line', ['id' => $id]);
138
        self::assertSame(1, $count);
139
        $this->assertAccountBalance($account1, 5000, 'balance should be restored to its original value after deletion');
140
        $this->assertAccountBalance($account2, 10000, 'balance should be restored to its original value after deletion');
141
        $this->assertAccountBalance($account3, 1250, 'balance should be restored to its original value after deletion');
142
        $this->assertAccountBalance($account4, 818750, 'balance should be restored to its original value after deletion');
143
    }
144
145
    public function testTotalBalance(): void
146
    {
147
        /** @var AccountRepository $accountRepository */
148
        $accountRepository = _em()->getRepository(Account::class);
149
150
        /** @var Account $poste */
151
        $poste = $accountRepository->getOneById(10025);
152
153
        $totalDebit = $this->repository->totalBalance($poste, null);
154
        $totalCredit = $this->repository->totalBalance(null, $poste);
155
        self::assertTrue(Money::CHF(1520000)->equals($totalDebit));
156
        self::assertTrue(Money::CHF(701250)->equals($totalCredit));
157
158
        $totalDebitFromDate = $this->repository->totalBalance($poste, null, new ChronosDate('2019-02-01'));
159
        $totalDebitUntilDate = $this->repository->totalBalance($poste, null, null, new ChronosDate('2019-01-01'));
160
        self::assertTrue(Money::CHF(20000)->equals($totalDebitFromDate));
161
        self::assertTrue(Money::CHF(1500000)->equals($totalDebitUntilDate));
162
    }
163
164
    /**
165
     * @dataProvider providerImportedExists
166
     */
167
    public function testImportedExists(string $importedId, string $transactionDate, bool $expected): void
168
    {
169
        self::assertSame($expected, $this->repository->importedExists($importedId, new Chronos($transactionDate)));
170
    }
171
172
    public function providerImportedExists(): iterable
173
    {
174
        yield 'duplicated' => ['my-unique-imported-id', '2019-04-05', true];
175
        yield 'different date' => ['my-unique-imported-id', '2019-02-05', false];
176
        yield 'different id' => ['something-else', '2019-04-05', false];
177
    }
178
179
    public function testHydrateLinesAndFlushMustThrowWithUnbalancedLines(): void
180
    {
181
        $this->setCurrentUser('administrator');
182
183
        /** @var TransactionLine $transactionLine */
184
        $transactionLine = _em()->getReference(TransactionLine::class, 14006);
185
        $transactionLine->setBalance(Money::CHF(99999));
186
187
        $this->expectExceptionMessage('Transaction 8005 non-équilibrée, débits: 10000.00, crédits: 3999.99');
188
        _em()->flush();
189
    }
190
}
191