Passed
Push — master ( dad11e...8233a2 )
by Adrien
07:43
created

BookingTest::tearDown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApplicationTest\Model;
6
7
use Application\Model\Bookable;
8
use Application\Model\Booking;
9
use Application\Model\User;
10
use Money\Money;
11
use PHPUnit\Framework\TestCase;
12
13
class BookingTest extends TestCase
14
{
15
    protected function tearDown(): void
16
    {
17
        User::setCurrent(null);
18
    }
19
20
    public function testOwnerRelation(): void
21
    {
22
        $booking = new Booking();
23
        self::assertNull($booking->getOwner(), 'booking should have no owner');
24
25
        $user = new User();
26
        self::assertCount(0, $user->getBookings(), 'user should have no bookings');
27
28
        $booking->setOwner($user);
29
        self::assertCount(1, $user->getBookings(), 'user should have the added booking');
30
        self::assertSame($booking, $user->getBookings()->first(), 'user should have the same booking');
31
        self::assertSame($user, $booking->getOwner(), 'booking should have owner');
32
    }
33
34
    public function testBookableRelation(): void
35
    {
36
        $booking = new Booking();
37
38
        $bookable = new Bookable();
39
        self::assertCount(0, $bookable->getBookings(), 'bookable should have no bookings');
40
41
        $booking->setBookable($bookable);
42
        self::assertCount(1, $bookable->getBookings(), 'bookable should have the added booking');
43
        self::assertSame($booking, $bookable->getBookings()->first(), 'bookable should have the same booking');
44
        self::assertSame($bookable, $booking->getBookable(), 'booking should be able to retrieve added bookable');
45
46
        $booking->setBookable($bookable);
47
        self::assertCount(1, $bookable->getBookings(), 'bookable should still have exactly 1 booking');
48
        self::assertSame($booking, $bookable->getBookings()->first(), 'bookable should have the same booking');
49
        self::assertSame($bookable, $booking->getBookable(), 'booking should still have the same unique bookable');
50
51
        $bookable2 = new Bookable();
52
        $booking->setBookable($bookable2);
53
        self::assertCount(0, $bookable->getBookings(), 'bookable should not have any booking anymore');
54
        self::assertCount(1, $bookable2->getBookings(), 'bookable2 should have a new booking');
55
        self::assertSame($bookable2, $booking->getBookable(), 'booking should have only the second bookable left');
56
    }
57
58
    public function testGetPeriodicPriceWithoutSharing(): void
59
    {
60
        $booking = new Booking();
61
62
        $bookable = $this->createMock(Bookable::class);
63
        $bookable->expects(self::any())
64
            ->method('getSharedBookings')
65
            ->willReturn([]);
66
67
        $bookable->expects(self::any())
68
            ->method('getPeriodicPrice')
69
            ->willReturn(Money::CHF(500));
70
71
        $booking->setBookable($bookable);
72
        self::assertEquals(Money::CHF(500), $booking->getPeriodicPrice(), 'price should be exactly the bookable price');
73
    }
74
75
    public function testGetPeriodicPriceWithSharing(): void
76
    {
77
        $booking = new Booking();
78
79
        $bookable = $this->createMock(Bookable::class);
80
        $bookable->expects(self::any())
81
            ->method('getPeriodicPriceDividerBookings')
82
            ->willReturn([1, 2, 3]);
83
84
        $bookable->expects(self::any())
85
            ->method('getPeriodicPrice')
86
            ->willReturn(Money::CHF(500));
87
88
        $booking->setBookable($bookable);
89
        self::assertEquals(Money::CHF(167), $booking->getPeriodicPrice(), 'price should be divided by the number of shared booking');
90
    }
91
92
    /**
93
     * @dataProvider providerSetOwner
94
     */
95
    public function testSetOwner(?User $currentUser, ?User $originalOwner, ?User $newOwner, ?string $exception = null): void
96
    {
97
        User::setCurrent($currentUser);
98
99
        $subject = new Booking();
100
        self::assertNull($subject->getOwner());
101
102
        $subject->setOwner($originalOwner);
103
        self::assertSame($originalOwner, $subject->getOwner());
104
105
        if ($exception) {
106
            $this->expectExceptionMessage($exception);
107
        }
108
109
        $subject->setOwner($newOwner);
110
        self::assertSame($newOwner, $subject->getOwner());
111
    }
112
113
    public function providerSetOwner(): array
114
    {
115
        $u1 = new User();
116
        $u1->setLogin('u1');
117
        $u2 = new User();
118
        $u2->setLogin('u2');
119
        $u3 = new User();
120
        $u3->setLogin('u3');
121
        $admin = new User(User::ROLE_ADMINISTRATOR);
122
        $admin->setLogin('admin');
123
124
        return [
125
            'can change nothing to nothing' => [null, null, null],
126
            'can set owner for first time' => [null, null, $u3],
127
            'can set owner for first time to myself' => [$u1, null, $u1],
128
            'can set owner for first time even if it is not myself' => [$u1, null, $u3],
129
            'can donate my stuff' => [$u1, $u1, $u3],
130
            'as a member I cannot donate stuff that are not mine' => [$u1, $u2, $u3, 'u1 is not allowed to change owner to u3 because it belongs to u2'],
131
            'as an admin I can donate stuff that are not mine' => [$admin, $u2, $u3],
132
        ];
133
    }
134
}
135