UseCaseTest.php 6.44 KB
Newer Older
Jacob Priddy's avatar
Jacob Priddy committed
1
2
3
4
5
<?php


namespace Tests\Unit\Source\UseCases\Users\UpdateUser;

Jacob Priddy's avatar
Jacob Priddy committed
6
use Carbon\Carbon;
Jacob Priddy's avatar
Jacob Priddy committed
7
use Source\Entities\User;
Jacob Priddy's avatar
Jacob Priddy committed
8
9
use Source\Entities\Doorcode;
use Source\Entities\Password;
Jacob Priddy's avatar
Jacob Priddy committed
10
use PHPUnit\Framework\TestCase;
Jacob Priddy's avatar
Jacob Priddy committed
11
use Tests\Doubles\AuthorizerStub;
Jacob Priddy's avatar
Jacob Priddy committed
12
use Source\Exceptions\EntityNotFoundException;
Jacob Priddy's avatar
Jacob Priddy committed
13
use Tests\Doubles\InMemoryUsersRepositoryStub;
Jacob Priddy's avatar
Jacob Priddy committed
14
15
16
17
use Source\UseCases\Users\UpdateUser\UpdateUser;
use Source\Gateways\Users\InMemoryUsersRepository;
use Source\UseCases\Users\UpdateUser\ResponseModel;

Jacob Priddy's avatar
Jacob Priddy committed
18
19
class UseCaseTest extends TestCase
{
Jacob Priddy's avatar
Jacob Priddy committed
20
21
22
23
24
25
26
27
    protected InMemoryUsersRepository $usersRepository;

    protected UpdateUser $useCase;

    protected ResponseModel $response;

    protected PresenterStub $presenter;

Jacob Priddy's avatar
Jacob Priddy committed
28
29
    protected AuthorizerStub $authorizer;

Jacob Priddy's avatar
Jacob Priddy committed
30
31
    public function setUp(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
32
33
        parent::setUp();

Jacob Priddy's avatar
Jacob Priddy committed
34
        $this->authorizer = new AuthorizerStub();
Jacob Priddy's avatar
Jacob Priddy committed
35
        $this->usersRepository = new InMemoryUsersRepository();
Jacob Priddy's avatar
Jacob Priddy committed
36
        $this->useCase = new UpdateUser($this->authorizer, $this->usersRepository);
Jacob Priddy's avatar
Jacob Priddy committed
37
38
39
        $this->presenter = new PresenterStub();
    }

Jacob Priddy's avatar
Jacob Priddy committed
40
    protected function createUserAttributes(User $user, ?string $password = null, ?string $doorcode = null): array
Jacob Priddy's avatar
Jacob Priddy committed
41
    {
Jacob Priddy's avatar
Jacob Priddy committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
        $expires = $user->getExpiresAt();
        if ($expires) {
            $expires = $expires->toString();
        }

        return [
            'first_name'   => $user->getFirstName(),
            'last_name'    => $user->getLastName(),
            'display_name' => $user->getDisplayName(),
            'emplid'       => $user->getEmplid(),
            'email'        => $user->getEmail(),
            'password'     => $password,
            'doorcode'     => $doorcode,
            'expires_at'   => $expires,
Jacob Priddy's avatar
Jacob Priddy committed
56
            'salt'         => '',
Jacob Priddy's avatar
Jacob Priddy committed
57
58
59
60
61
62
63
64
        ];
    }

    /**
     * @param string $userId
     * @param array  $attributes
     * @throws EntityNotFoundException
     */
Jacob Priddy's avatar
Jacob Priddy committed
65
66
    public function handleTest(string $userId, array $attributes): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
67
68
69
70
71
72
73
74
75
        $this->useCase->update($userId, $attributes, $this->presenter);

        $this->response = $this->presenter->response;
    }

    /**
     * @test
     * @throws EntityNotFoundException
     */
Jacob Priddy's avatar
Jacob Priddy committed
76
77
    public function presenter_was_called(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
78
        $user = new User(69, 'special name', '', '', '');
Jacob Priddy's avatar
Jacob Priddy committed
79
80
81
82
83
84
85
86
87
88
89
        $this->usersRepository->create($user);

        $this->handleTest('69', $this->createUserAttributes($user));

        $this->assertTrue($this->presenter->wasPresenterCalled());
    }

    /**
     * @test
     * @throws EntityNotFoundException
     */
Jacob Priddy's avatar
Jacob Priddy committed
90
91
    public function it_updates_a_user(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
92
93
        $user = new User(69, 'camdiddle beerbong', '', '', '');
        $updatedUser = new User(69, 'updated name', '', '', '');
Jacob Priddy's avatar
Jacob Priddy committed
94
95
96
97
98
99
100
        $this->usersRepository->create($user);

        $this->handleTest('69', $this->createUserAttributes($updatedUser));

        $this->assertFalse($this->response->hasError());
        $this->assertEquals('updated name', $this->usersRepository->get('69')->getFirstName());
        $this->assertEquals($updatedUser, $this->response->getUser());
Jacob Priddy's avatar
Jacob Priddy committed
101
        $this->assertTrue($this->authorizer->adminRightsWereProtected());
Jacob Priddy's avatar
Jacob Priddy committed
102
103
104
105
106
107
    }

    /**
     * @test
     * @throws EntityNotFoundException
     */
Jacob Priddy's avatar
Jacob Priddy committed
108
109
    public function it_cannot_update_non_existent_user(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
110
        $this->expectException(EntityNotFoundException::class);
Jacob Priddy's avatar
Jacob Priddy committed
111
        $updatedUser = new User(69, 'updated name', '', '', '');
Jacob Priddy's avatar
Jacob Priddy committed
112
113
114
115
116
117
118
119

        $this->handleTest('420', $this->createUserAttributes($updatedUser));
    }

    /**
     * @test
     * @throws EntityNotFoundException
     */
Jacob Priddy's avatar
Jacob Priddy committed
120
121
    public function it_sets_error_on_fail(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
122
        $updatedUser = new User(420, 'updated name', '', '', '');
Jacob Priddy's avatar
Jacob Priddy committed
123
124
125

        $stub = new InMemoryUsersRepositoryStub();
        $stub->setUserToReturnOnGet($updatedUser);
Jacob Priddy's avatar
Jacob Priddy committed
126
        $this->useCase = new UpdateUser($this->authorizer, $stub);
Jacob Priddy's avatar
Jacob Priddy committed
127
128
129
130
131
132

        $this->handleTest('420', $this->createUserAttributes($updatedUser));

        $this->assertTrue($this->response->hasError());
        $this->assertEquals('Unable to update user.', $this->response->getError());
    }
133
134
135
136
137

    /**
     * @test
     * @throws EntityNotFoundException
     */
Jacob Priddy's avatar
Jacob Priddy committed
138
139
    public function it_doesnt_need_doorcode_or_password(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
140
141
        $user = new User(69, '', '', '', '', null, new Password('pass'), new Doorcode('door'));
        $updatedUser = new User(0, '', '', '', '');
142
143
144
145
146

        $this->usersRepository->create($user);

        $this->handleTest('69', $this->createUserAttributes($updatedUser, null, null));

Jacob Priddy's avatar
Jacob Priddy committed
147
148
        $this->assertEquals('pass', $this->response->getUser()->getPassword()->getHash());
        $this->assertEquals('door', $this->response->getUser()->getDoorcode()->getHash());
149
150
151
152
153
154
    }

    /**
     * @test
     * @throws EntityNotFoundException
     */
Jacob Priddy's avatar
Jacob Priddy committed
155
156
    public function it_will_overwrite_pass_and_door_code(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
157
158
        $user = new User(69, '', '', '', '');
        $updatedUser = new User(0, '', '', '', '');
159
160
161
162
163

        $this->usersRepository->create($user);

        $this->handleTest('69', $this->createUserAttributes($updatedUser, 'pass', 'door'));

Jacob Priddy's avatar
Jacob Priddy committed
164
165
166
167
168
        $this->assertTrue($this->response->getUser()->getPassword()->matches('pass'));
        $this->assertEquals(
            Doorcode::hash('', 'door')->getHash(),
            $this->response->getUser()->getDoorcode()->getHash()
        );
169
    }
Jacob Priddy's avatar
Jacob Priddy committed
170
171
172
173
174
175
176

    /**
     * @test
     * @throws \Source\Exceptions\EntityNotFoundException
     */
    public function it_will_set_expires_at(): void
    {
Jacob Priddy's avatar
Jacob Priddy committed
177
178
        $user = new User(69, '', '', '', '');
        $updatedUser = new User(0, '', '', '', '', null, null, null, new Carbon('2020-03-07 20:58:50'), null, null);
Jacob Priddy's avatar
Jacob Priddy committed
179
180
181
182
183
184
185

        $this->usersRepository->create($user);

        $this->handleTest('69', $this->createUserAttributes($updatedUser));

        $this->assertEquals('2020-03-07T20:58:50+00:00', $this->response->getUser()->getExpiresAt()->format('c'));
    }
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

    /**
     * @test
     * @throws \Source\Exceptions\EntityNotFoundException
     */
    public function it_will_update_nothing_if_no_changes_are_required(): void
    {
        $user = new User(
            69,
            'scat',
            'man',
            'IM THE SCAT MAN',
            'do biddle be bahhhh',
            'hes the scat man',
            new Password('hash'),
            new Doorcode('hash')
        );

        $this->usersRepository->create($user);

        $this->handleTest('69', ['salt' => '']);

        $this->assertFalse($this->response->hasError());
        $this->assertEquals($user, $this->response->getUser());
        $this->assertTrue($this->authorizer->adminRightsWereProtected());
    }
Jacob Priddy's avatar
Jacob Priddy committed
212
}