Passed
Push — master ( 34423e...8c40d4 )
by Adrien
06:57
created

AccountRepositoryTest::testGetOrCreateForTheFirstTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Repository;
6
7
use Application\DBAL\Types\AccountTypeType;
8
use Application\Model\Account;
9
use Application\Model\User;
10
use Application\Repository\AccountRepository;
11
use ApplicationTest\Traits\LimitedAccessSubQuery;
12
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
13
use Money\Money;
14
15
/**
16
 * @group Repository
17
 */
18
class AccountRepositoryTest extends AbstractRepositoryTest
19
{
20
    use LimitedAccessSubQuery;
21
22
    /**
23
     * @var AccountRepository
24
     */
25
    private $repository;
26
27
    public function setUp(): void
28
    {
29
        parent::setUp();
30
        $this->repository = $this->getEntityManager()->getRepository(Account::class);
31
    }
32
33
    public function providerGetAccessibleSubQuery(): array
34
    {
35
        $all = range(10000, 10106);
36
37
        return [
38
            ['anonymous', []],
39
            ['bookingonly', []],
40
            ['individual', [10097]],
41
            ['member', [10096]],
42
            ['responsible', $all],
43
            ['administrator', $all],
44
        ];
45
    }
46
47
    public function testOneUserCanHaveOnlyOneAccount(): void
48
    {
49
        $this->expectException(UniqueConstraintViolationException::class);
50
        $this->getEntityManager()->getConnection()->insert('account', ['owner_id' => 1000, 'iban' => uniqid()]);
51
    }
52
53
    public function testGetOrCreate(): void
54
    {
55
        $user = new User();
56
        $user->setFirstName('Foo');
57
        $user->setLastName('Bar');
58
59
        $account = $this->repository->getOrCreate($user);
60
61
        self::assertSame($user, $account->getOwner());
62
        self::assertSame('Foo Bar', $account->getName());
63
        self::assertSame(AccountTypeType::LIABILITY, $account->getType());
64
        self::assertSame(20300009, $account->getCode());
65
        self::assertSame('Acomptes de clients', $account->getParent()->getName());
66
        self::assertSame($account, $user->getAccount());
67
68
        $account2 = $this->repository->getOrCreate($user);
69
        self::assertSame($account, $account2, 'should return the same account if called more than once for same user');
70
71
        $user2 = new User();
72
        $user2->setFirstName('Alice');
73
        $user2->setLastName('Stark');
74
75
        $account3 = $this->repository->getOrCreate($user2);
76
        self::assertNotSame($account, $account3, 'creating a second account for a second user should not give same code');
77
        self::assertNotSame($account->getCode(), $account3->getCode(), 'creating a second account for a second user should not give same code');
78
        self::assertSame(20300010, $account3->getCode(), 'should have been incremented from maxCode in memory');
79
    }
80
81
    public function testGetOrCreateForTheFirstTime(): void
82
    {
83
        $this->getEntityManager()->getConnection()->executeQuery('DELETE FROM transaction');
84
        $this->getEntityManager()->getConnection()->executeQuery('DELETE FROM account WHERE code LIKE "20300%"');
85
        $user = new User();
86
87
        $account = $this->repository->getOrCreate($user);
88
        self::assertSame(20300001, $account->getCode());
89
    }
90
91
    public function testGetOrCreateInMemory(): void
92
    {
93
        $user = new User();
94
        $account = new Account();
95
        $account->setOwner($user);
96
97
        $actualAccount = $this->repository->getOrCreate($user);
98
99
        self::assertSame($account, $actualAccount, 'should return the in-memory account if existing');
100
    }
101
102
    public function testTotalBalance(): void
103
    {
104
        $totalAssets = $this->repository->totalBalanceByType(AccountTypeType::ASSET);
105
        $totalLiabilities = $this->repository->totalBalanceByType(AccountTypeType::LIABILITY);
106
        $totalRevenue = $this->repository->totalBalanceByType(AccountTypeType::REVENUE);
107
        $totalExpense = $this->repository->totalBalanceByType(AccountTypeType::EXPENSE);
108
        $totalEquity = $this->repository->totalBalanceByType(AccountTypeType::EQUITY);
109
110
        self::assertTrue(Money::CHF(3518750)->equals($totalAssets));
111
        self::assertTrue(Money::CHF(6000)->equals($totalLiabilities));
112
        self::assertTrue(Money::CHF(24000)->equals($totalRevenue));
113
        self::assertTrue(Money::CHF(11250)->equals($totalExpense));
114
        self::assertTrue(Money::CHF(3500000)->equals($totalEquity));
115
116
        $groupAccount = $this->repository->getOneById(10001); // 2. Passifs
117
        self::assertSame(AccountTypeType::GROUP, $groupAccount->getType(), 'is a group');
118
        self::assertTrue(Money::CHF(0)->equals($groupAccount->getBalance()), 'balance for group account is always 0');
119
        self::assertTrue(Money::CHF(3506000)->equals($groupAccount->getTotalBalance()), 'total balance for group account should have been computed via DB triggers');
120
121
        $otherAccount = $this->repository->getOneById(10025); // 10201. PostFinance
122
        self::assertNotSame(AccountTypeType::GROUP, $otherAccount->getType(), 'not a group');
123
        self::assertTrue(Money::CHF(818750)->equals($otherAccount->getBalance()), 'balance for non-group should have been computed via DB triggers');
124
        self::assertTrue($otherAccount->getBalance()->equals($otherAccount->getTotalBalance()), 'total balance for non-group should be equal to balance');
125
    }
126
127
    public function testGetOneById(): void
128
    {
129
        $account = $this->repository->getOneById(10025); // Poste
130
        self::assertNotNull($account);
131
        self::assertSame(10025, $account->getId());
132
        $this->expectExceptionMessage('Account #-9999 not found');
133
        $this->repository->getOneById(-9999);
134
    }
135
}
136