CommentsIT::shouldBaselineNonExistentPost()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 12
rs 10
1
<?php
2
3
namespace App\Tests\Modules\Comments\Integration;
4
5
use App\Modules\Comments\Api\Command\BaselineCommentsCommand;
6
use App\Modules\Comments\Api\Command\CreateCommentCommand;
7
use App\Modules\Comments\Api\CommentsApiInterface;
8
use App\Modules\Comments\Api\Event\Inbound\PostBaselinedCommentsIEvent;
9
use App\Modules\Comments\Api\Event\Inbound\PostCreatedCommentsIEvent;
10
use App\Modules\Comments\Api\Event\Inbound\PostDeletedCommentsIEvent;
11
use App\Modules\Comments\Api\Event\Inbound\PostUpdatedCommentsIEvent;
12
use App\Modules\Comments\Api\Query\FindCommentsByPostIdQuery;
13
use App\Modules\Comments\Api\Query\FindLatestCommentsQuery;
14
use App\Modules\Comments\Api\Query\Response\FindLatestCommentsQueryResponse;
15
use App\Modules\Comments\Domain\Event\Outbound\CommentsBaselinedOEvent;
16
use App\Tests\Modules\Comments\Integration\Http\CommentsHttpTrait;
17
use App\Tests\TestUtils\Contracts\ApplicationEventContractLoader;
18
use App\Tests\TestUtils\Events\InMemoryEventPublisher;
19
use App\Tests\TestUtils\IntegrationTest;
20
use Symfony\Bundle\FrameworkBundle\Console\Application;
21
use Symfony\Component\Console\Tester\CommandTester;
22
use Symfony\Component\Uid\Ulid;
23
24
class CommentsIT extends IntegrationTest
25
{
26
    use CommentsHttpTrait;
27
    use ApplicationEventContractLoader;
28
29
    /**
30
     * @test
31
     */
32
    public function shouldCreateFetchAndDeleteCommentsForPost()
33
    {
34
        //given: there was a Post Created
35
        $postId = $this->createAndUpdatePost();
36
37
        //and: someone authored a Comment for that Post
38
        $command = new CreateCommentCommand($postId, 'Parent Author', 'Parent Body', null);
39
40
        //and: comment is Created
41
        $parentCommentId = $this->createComment($command)->getId();
42
43
        //and: someone authored a Child Comment for that Post and Parent Comment
44
        $command = new CreateCommentCommand($postId, 'Author', 'Body', $parentCommentId);
45
46
        //and: Child Comment is Created
47
        $commentId = $this->createComment($command)->getId();
48
49
        //when: list of Comments for that Post is fetched
50
        $comments = $this->findCommentsForPost(new FindCommentsByPostIdQuery($postId));
51
52
        //then: the Post Comments are fetched correctly
53
        self::assertNotNull($comments);
54
        self::assertCount(2, $comments);
55
        self::assertTrue(isset($comments[0]));
56
        self::assertTrue(isset($comments[1]));
57
58
        self::assertEquals($parentCommentId, $comments[0]->getId());
59
        self::assertEquals('Parent Author', $comments[0]->getAuthor());
60
        self::assertEquals('Parent Body', $comments[0]->getBody());
61
        self::assertNotNull($comments[0]->getCreatedAt());
62
        self::assertNull($comments[0]->getParentId());
63
64
        self::assertEquals($commentId, $comments[1]->getId());
65
        self::assertEquals('Author', $comments[1]->getAuthor());
66
        self::assertEquals('Body', $comments[1]->getBody());
67
        self::assertNotNull($comments[1]->getCreatedAt());
68
        self::assertEquals($parentCommentId, $comments[1]->getParentId());
69
70
        //when: list of Comments for that Post is fetched
71
        $comments = $this->findLatestComments(new FindLatestCommentsQuery(1));
72
73
        //then: the Post Comments are fetched correctly
74
        self::assertNotNull($comments);
75
        self::assertCount(2, $comments->getData());
76
        self::assertEquals(2, $comments->getCount());
77
        self::assertTrue(isset($comments->getData()[0]));
78
        self::assertTrue(isset($comments->getData()[1]));
79
80
        $parentComment = $this->convert($comments->getData()[1], FindLatestCommentsQueryResponse::class);
81
        $comment = $this->convert($comments->getData()[0], FindLatestCommentsQueryResponse::class);
82
83
        self::assertEquals($parentCommentId, $parentComment->getId());
84
        self::assertEquals('Parent Author', $parentComment->getAuthor());
85
        self::assertEquals('Parent Body', $parentComment->getBody());
86
        self::assertNotNull($parentComment->getCreatedAt());
87
        self::assertNull($parentComment->getParentId());
88
89
        self::assertEquals($commentId, $comment->getId());
90
        self::assertEquals('Author', $comment->getAuthor());
91
        self::assertEquals('Body', $comment->getBody());
92
        self::assertNotNull($comment->getCreatedAt());
93
        self::assertEquals($parentCommentId, $comment->getParentId());
94
95
        //when: the Post was Deleted
96
        $this->deletePost($postId);
97
98
        //and: the list of Comments was fetched
99
        $comments = $this->findLatestComments(new FindLatestCommentsQuery(1));
100
101
        //then: there were no Comments left
102
        self::assertNotNull($comments);
103
        self::assertCount(0, $comments->getData());
104
        self::assertEquals(0, $comments->getCount());
105
    }
106
107
    /**
108
     * @test
109
     */
110
    public function shouldBaselineNonExistentPost()
111
    {
112
        //given: there was a PostCreatedIEvent to be published
113
        $event = new PostBaselinedCommentsIEvent($this->getInboundEvent("Comments/PostBaselinedCommentsIEvent"));
114
115
        //when: the Event was already published
116
        $this->getCommentsApi()->onPostBaselined($event);
117
118
        //then: Non-existent post was Baselined
119
        $posts = $this->getCommentsApi()->findPostHeaders();
120
        self::assertCount(1, $posts);
121
        self::assertEquals(3, $posts[0]->getVersion());
122
123
    }
124
125
    /**
126
     * @test
127
     */
128
    public function shouldBaselineAlreadyExistentPost()
129
    {
130
        //given: there was a Post Created
131
        $postId = $this->createAndUpdatePost();
132
133
        //given: there was a PostCreatedIEvent to be published
134
        $data = $this->getInboundEvent("Comments/PostBaselinedCommentsIEvent");
135
        $data['id'] = $postId;
136
        $event = new PostBaselinedCommentsIEvent($data);
137
138
        //when: the Event was already published
139
        $this->getCommentsApi()->onPostBaselined($event);
140
141
        //then: Non-existent post was Baselined
142
        $posts = $this->getCommentsApi()->findPostHeaders();
143
        self::assertCount(1, $posts);
144
        self::assertEquals(3, $posts[0]->getVersion());
145
146
    }
147
148
    /**
149
     * @test
150
     */
151
    public function shouldBaselineCommentsForPost()
152
    {
153
        //given: there was a Post Created
154
        $postId = $this->createAndUpdatePost();
155
156
        //and: someone authored a Comment for that Post
157
        $command = new CreateCommentCommand($postId, 'Parent Author', 'Parent Body', null);
158
159
        //and: comment is Created
160
        $parentCommentId = $this->createComment($command)->getId();
161
162
        //and: someone authored a Child Comment for that Post and Parent Comment
163
        $command = new CreateCommentCommand($postId, 'Author', 'Body', $parentCommentId);
164
165
        //and: Child Comment is Created
166
        $this->createComment($command)->getId();
167
168
        //when: Comments are baselined
169
        $application = $this->setupKernel();
170
        $command = $application->find('app:comments:baseline');
171
        $commandTester = new CommandTester($command);
172
        $commandTester->execute([]);
173
        $output = $commandTester->getDisplay();
174
175
        //then: Comments were baselined correctly
176
        self::assertStringStartsWith('Successfully base-lined all Comments', $output);
177
        $events = InMemoryEventPublisher::get(CommentsBaselinedOEvent::class);
178
        self::assertCount(1, $events);
179
        self::assertEquals($postId, $events[0]->getData()['postId']);
180
        self::assertCount(2, json_decode($events[0]->getData()['comments']));
181
    }
182
183
184
    private function createAndUpdatePost(): Ulid
185
    {
186
        //given: there was a PostCreatedIEvent to be published
187
        $event = new PostCreatedCommentsIEvent($this->getInboundEvent("Comments/PostCreatedCommentsIEvent"));
188
189
        //and: the Event was already published
190
        $this->getCommentsApi()->onPostCreated($event);
191
192
        //and: the Header was to be updated
193
        $event = new PostUpdatedCommentsIEvent($this->getInboundEvent("Comments/PostUpdatedCommentsIEvent"));
194
195
        //and: the Event was published
196
        $this->getCommentsApi()->onPostUpdated($event);
197
198
        return $event->getId();
199
    }
200
201
    private function deletePost(Ulid $postId): void
202
    {
203
        //and: the Header was to be updated
204
        $data = $this->getInboundEvent("Comments/PostDeletedCommentsIEvent");
205
        $data["postId"] = $postId;
206
        $event = new PostDeletedCommentsIEvent($data);
207
208
209
        //and: the Event was published
210
        $this->getCommentsApi()->onPostDeleted($event);
211
    }
212
213
    private function getCommentsApi(): CommentsApiInterface
214
    {
215
        return $this->getContainer()->get(CommentsApiInterface::class);
216
    }
217
218
    /**
219
     * @return Application
220
     */
221
    protected function setupKernel(): Application
222
    {
223
        $kernel = static::createKernel();
224
        $kernel->boot();
225
        $application = new Application($kernel);
226
        $application->add(new BaselineCommentsCommand(
227
            $this->getContainer()->get(CommentsApiInterface::class)
228
        ));
229
        return $application;
230
    }
231
}