Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
n/a
0 / 0
n/a
0 / 0
CRAP
n/a
0 / 0
CreatesApieBoundedContext
n/a
0 / 0
n/a
0 / 0
27
n/a
0 / 0
 createPostUserTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createGetUserTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createGetAnimalTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createPostPrimitiveOnlyTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createPostAnimalTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createPostUploadedFileTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createPostOrderTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createPropertyOptionsTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createEntityReferenceTest
n/a
0 / 0
n/a
0 / 0
1
 createUnionObjectTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createObjectWithRestrictionTestRequest
n/a
0 / 0
n/a
0 / 0
1
 getObjectWithRestrictionTestRequest
n/a
0 / 0
n/a
0 / 0
1
 getObjectWithReadAuditLogRequest
n/a
0 / 0
n/a
0 / 0
1
 removeOrderTestRequest
n/a
0 / 0
n/a
0 / 0
1
 getObjectWithRestrictionDeniedTestRequest
n/a
0 / 0
n/a
0 / 0
1
 getObjectWithRestrictionListTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createInvalidPropertyOptionsTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createMethodArgumentOptionsTestRequest
n/a
0 / 0
n/a
0 / 0
1
 createBlockUserFormSubmit
n/a
0 / 0
n/a
0 / 0
1
 createCustomActionRequest
n/a
0 / 0
n/a
0 / 0
1
 createResourceStaticMethodRequest
n/a
0 / 0
n/a
0 / 0
1
 createVariadicActionRequest
n/a
0 / 0
n/a
0 / 0
1
 createSimpleConsoleInteraction
n/a
0 / 0
n/a
0 / 0
1
 createOrderLineInteraction
n/a
0 / 0
n/a
0 / 0
1
 createFileUploadInteraction
n/a
0 / 0
n/a
0 / 0
1
 createPolymorphicObjectInteraction
n/a
0 / 0
n/a
0 / 0
1
 createExampleBoundedContext
n/a
0 / 0
n/a
0 / 0
1
1<?php
2namespace Apie\IntegrationTests\Concerns;
3
4use Apie\Common\ValueObjects\EntityNamespace;
5use Apie\Core\ApieLib;
6use Apie\Core\BoundedContext\BoundedContextId;
7use Apie\Core\Identifiers\Ulid;
8use Apie\CountryAndPhoneNumber\BelgianPhoneNumber;
9use Apie\CountryAndPhoneNumber\DutchPhoneNumber;
10use Apie\IntegrationTests\Apie\TypeDemo\Entities\Human;
11use Apie\IntegrationTests\Apie\TypeDemo\Entities\Ostrich;
12use Apie\IntegrationTests\Apie\TypeDemo\Enums\OrderStatus;
13use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\AnimalIdentifier;
14use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\RestrictedEntityIdentifier;
15use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\UserIdentifier;
16use Apie\IntegrationTests\Apie\TypeDemo\Lists\OrderLineList;
17use Apie\IntegrationTests\Apie\TypeDemo\Resources\Animal;
18use Apie\IntegrationTests\Apie\TypeDemo\Resources\Order;
19use Apie\IntegrationTests\Apie\TypeDemo\Resources\PrimitiveOnly;
20use Apie\IntegrationTests\Apie\TypeDemo\Resources\RestrictedEntity;
21use Apie\IntegrationTests\Apie\TypeDemo\Resources\UnionObject;
22use Apie\IntegrationTests\Apie\TypeDemo\Resources\UploadedFile;
23use Apie\IntegrationTests\Apie\TypeDemo\Resources\User;
24use Apie\IntegrationTests\Config\BoundedContextConfig;
25use Apie\IntegrationTests\Console\InteractiveConsoleCommand;
26use Apie\IntegrationTests\Requests\ActionMethodApiCall;
27use Apie\IntegrationTests\Requests\CmsFormSubmitRequest;
28use Apie\IntegrationTests\Requests\GetResourceApiCall;
29use Apie\IntegrationTests\Requests\GetResourceApiCallDenied;
30use Apie\IntegrationTests\Requests\GetResourceListApiCall;
31use Apie\IntegrationTests\Requests\JsonFields\GetAndSetObjectField;
32use Apie\IntegrationTests\Requests\JsonFields\GetAndSetPrimitiveField;
33use Apie\IntegrationTests\Requests\JsonFields\GetAndSetUploadedFileField;
34use Apie\IntegrationTests\Requests\JsonFields\GetPrimitiveField;
35use Apie\IntegrationTests\Requests\JsonFields\GetUuidField;
36use Apie\IntegrationTests\Requests\JsonFields\SetPrimitiveField;
37use Apie\IntegrationTests\Requests\RemoveResourceApiCall;
38use Apie\IntegrationTests\Requests\TestRequestInterface;
39use Apie\IntegrationTests\Requests\ValidCreateResourceApiCall;
40use Apie\TextValueObjects\CompanyName;
41use Apie\TextValueObjects\FirstName;
42
43/**
44 * @codeCoverageIgnore
45 */
46trait CreatesApieBoundedContext
47{
48    /**
49     * For testing POST /user
50     */
51    public function createPostUserTestRequest(): TestRequestInterface
52    {
53        return new ValidCreateResourceApiCall(
54            new BoundedContextId('types'),
55            User::class,
56            new GetAndSetObjectField(
57                '',
58                new GetAndSetPrimitiveField('id', 'test@example.com'),
59                new GetPrimitiveField('blocked', false),
60                new GetPrimitiveField('blockedReason', null),
61                new GetAndSetPrimitiveField('phoneNumber', ' 0611223344 ', '+31611223344'),
62            ),
63        );
64    }
65
66    /**
67     * For testing GET /user/{id}
68     */
69    public function createGetUserTestRequest(): TestRequestInterface
70    {
71        // @phpstan-ignore-next-line
72        $user = (new User(UserIdentifier::fromNative('test@example.com')))->setPhoneNumber(DutchPhoneNumber::fromNative('0611223344'));
73        return new GetResourceApiCall(
74            new BoundedContextId('types'),
75            User::class,
76            'test@example.com',
77            [$user],
78            new GetAndSetObjectField(
79                '',
80                new GetPrimitiveField('id', 'test@example.com'),
81                new GetPrimitiveField('blocked', false),
82                new GetPrimitiveField('blockedReason', null),
83                new GetPrimitiveField('phoneNumber', '+31611223344'),
84            )
85        );
86    }
87
88    /**
89     * For testing GET /animal/{id}
90     */
91    public function createGetAnimalTestRequest(): TestRequestInterface
92    {
93        // @phpstan-ignore-next-line
94        $animal = new Ostrich(AnimalIdentifier::createRandom(), new FirstName('Albert'));
95        return new GetResourceApiCall(
96            new BoundedContextId('types'),
97            Animal::class,
98            $animal->getId()->toNative(),
99            [$animal],
100            new GetAndSetObjectField(
101                '',
102                new GetPrimitiveField('id', $animal->getId()->toNative()),
103                new GetPrimitiveField('name', 'ostrich'),
104                new GetPrimitiveField('animalName', 'Albert'),
105                new GetPrimitiveField('capableOfFlying', false),
106                new GetPrimitiveField('type', 'bird')
107            )
108        );
109    }
110
111    /**
112     * For testing POST/primitiveOnly
113     */
114    public function createPostPrimitiveOnlyTestRequest(): TestRequestInterface
115    {
116        return new ValidCreateResourceApiCall(
117            new BoundedContextId('types'),
118            PrimitiveOnly::class,
119            new GetAndSetObjectField(
120                '',
121                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
122                new GetAndSetPrimitiveField('stringField', 'test'),
123                new GetAndSetPrimitiveField('integerField', '42', 42),
124                new GetAndSetPrimitiveField('floatingPoint', 1.5, 1.5),
125                new GetPrimitiveField('booleanField', null),
126            ),
127            discardRequestValidation: true, //casting string to int is not documented in OpenAPI spec.
128            expectedAuditLogsAdded: 1
129        );
130    }
131
132    /**
133     * For testing POST /animal
134     */
135    public function createPostAnimalTestRequest(): TestRequestInterface
136    {
137        return new ValidCreateResourceApiCall(
138            new BoundedContextId('types'),
139            Animal::class,
140            new GetAndSetObjectField(
141                '',
142                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
143                new GetAndSetPrimitiveField('animalName', 'George', 'George'),
144                new GetAndSetPrimitiveField('type', 'mammal'),
145                new GetAndSetPrimitiveField('name', 'human'),
146                new GetPrimitiveField('capableOfLayingEggs', false),
147                new GetAndSetPrimitiveField('lastName', 'Pig'),
148            ),
149        );
150    }
151
152    /**
153     * For testing POST /UploadedFile
154     */
155    public function createPostUploadedFileTestRequest(): TestRequestInterface
156    {
157        return new ValidCreateResourceApiCall(
158            new BoundedContextId('types'),
159            UploadedFile::class,
160            new GetAndSetObjectField(
161                '',
162                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
163                new GetAndSetUploadedFileField(
164                    'file',
165                    'first order line',
166                    'test-evil.txt',
167                    '/types/UploadedFile/550e8400-e29b-41d4-a716-446655440000/download/file'
168                ),
169                new GetAndSetUploadedFileField(
170                    'imageFile',
171                    file_get_contents(__DIR__ . '/../../fixtures/apie-logo.svg'),
172                    'apie-logo.svg',
173                    '/types/UploadedFile/550e8400-e29b-41d4-a716-446655440000/download/imageFile'
174                ),
175                new GetPrimitiveField('stream', '/types/UploadedFile/550e8400-e29b-41d4-a716-446655440000/download/stream')
176            ),
177        );
178    }
179
180    /**
181     * For testing POST /Order
182     */
183    public function createPostOrderTestRequest(): TestRequestInterface
184    {
185        return new ValidCreateResourceApiCall(
186            new BoundedContextId('types'),
187            Order::class,
188            new GetAndSetObjectField(
189                '',
190                new GetPrimitiveField('id', 1),
191                new GetPrimitiveField('orderStatus', OrderStatus::DRAFT->value),
192                new GetAndSetObjectField(
193                    'orderLineList',
194                    new GetAndSetObjectField(
195                        '0',
196                        new GetAndSetPrimitiveField('description', 'First order line'),
197                        new GetUuidField('id'),
198                    ),
199                    new GetAndSetObjectField(
200                        '1',
201                        new GetAndSetPrimitiveField('description', 'Second order line'),
202                        new GetUuidField('id'),
203                    )
204                ),
205            ),
206            expectedAuditLogsAdded: 1, // 1: created
207        );
208    }
209
210    /**
211     * Test for dropdown action for comboboxes on entity create
212     *
213     * Url POST /ObjectWithRelation/dropdown-options/userId
214     */
215    public function createPropertyOptionsTestRequest(): TestRequestInterface
216    {
217        $user = new User(UserIdentifier::fromNative('test@example.com'));
218        return new ActionMethodApiCall(
219            new BoundedContextId('types'),
220            'ObjectWithRelation/dropdown-options/userId',
221            new GetAndSetObjectField(
222                '',
223                new SetPrimitiveField('input', 'test@'),
224                new GetAndSetObjectField(
225                    '0',
226                    new GetPrimitiveField('value', 'test@example.com'),
227                    new GetPrimitiveField('displayValue', 'test@example.com'),
228                )
229            ),
230            entities: [$user],
231            discardValidationOnFaker: true
232        );
233    }
234
235    /**
236     * Test for hydrating EntityReference on method call.
237     *
238     * Url POST /indexes/User/{userId}
239     */
240    public function createEntityReferenceTest(): TestRequestInterface
241    {
242        $user = new User(UserIdentifier::fromNative('test@example.com'));
243        return new ActionMethodApiCall(
244            new BoundedContextId('types'),
245            'indexes/User/test@example.com',
246            new GetAndSetObjectField(
247                '',
248                new GetPrimitiveField('0', 'test@example.com'),
249            ),
250            entities: [$user],
251            discardValidationOnFaker: true
252        );
253    }
254
255    /**
256     * Test for entity with union object
257     *
258     * POST /UnionObject
259     */
260    public function createUnionObjectTestRequest(): TestRequestInterface
261    {
262        ApieLib::registerValueObject(DutchPhoneNumber::class);
263        ApieLib::registerValueObject(BelgianPhoneNumber::class);
264        return new ValidCreateResourceApiCall(
265            new BoundedContextId('types'),
266            UnionObject::class,
267            new GetAndSetObjectField(
268                '',
269                new GetAndSetPrimitiveField('id', Ulid::createRandom()->toNative()),
270                new GetAndSetPrimitiveField('value', 'string'),
271                new GetAndSetPrimitiveField('otherValue', true),
272                new GetAndSetPrimitiveField('phoneNumber', ' 0611223344 ', '+31611223344'),
273            ),
274            discardRequestValidation: true,
275            discardResponseValidation: true // Somehow gives a false positive.
276        );
277    }
278
279    /**
280     * Test for entity with permission restrictions.
281     *
282     * POST /RestrictedEntity
283     */
284    public function createObjectWithRestrictionTestRequest(): TestRequestInterface
285    {
286        return new ValidCreateResourceApiCall(
287            new BoundedContextId('types'),
288            RestrictedEntity::class,
289            new GetAndSetObjectField(
290                '',
291                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
292                new GetAndSetPrimitiveField('companyName', 'Company NV'),
293                new GetPrimitiveField('userId', null),
294                new GetPrimitiveField('requiredPermissions', [])
295            ),
296        );
297    }
298
299    /**
300     * Test for entity with permission restrictions.
301     *
302     * GET /RestrictedEntity
303     */
304    public function getObjectWithRestrictionTestRequest(): TestRequestInterface
305    {
306        $object = new RestrictedEntity(
307            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440000'),
308            new CompanyName('Company NV'),
309            null
310        );
311        return new GetResourceApiCall(
312            new BoundedContextId('types'),
313            RestrictedEntity::class,
314            '550e8400-e29b-41d4-a716-446655440000',
315            [$object],
316            new GetAndSetObjectField(
317                '',
318                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
319                new GetAndSetPrimitiveField('companyName', 'Company NV'),
320                new GetPrimitiveField('userId', null),
321                new GetPrimitiveField('requiredPermissions', [])
322            ),
323            discardValidationOnFaker: true
324        );
325    }
326
327    /**
328     * Test for entity with audit log for reading.
329     *
330     * GET /Order/{id}
331     */
332    public function getObjectWithReadAuditLogRequest(): TestRequestInterface
333    {
334        $object = new Order(new OrderLineList());
335        return new GetResourceApiCall(
336            new BoundedContextId('types'),
337            Order::class,
338            '1',
339            [$object],
340            new GetAndSetObjectField(
341                '',
342                new GetPrimitiveField('id', '1'),
343                new GetPrimitiveField('orderStatus', OrderStatus::DRAFT->value),
344                new GetPrimitiveField('orderLineList', [])
345            ),
346            discardValidationOnFaker: true,
347            expectedAuditLogsAdded: 1
348        );
349    }
350
351    public function removeOrderTestRequest(): TestRequestInterface
352    {
353        $order = new Order(new OrderLineList());
354        return new RemoveResourceApiCall(
355            new BoundedContextId('types'),
356            'Order/1',
357            new GetAndSetObjectField(''),
358            entities: [$order],
359            expectedAuditLogsAdded: 2 // 1: created, 1: removed
360        );
361    }
362
363    /**
364     * Test for entity with permission restrictions.
365     *
366     * GET /RestrictedEntity/{id}
367     */
368    public function getObjectWithRestrictionDeniedTestRequest(): TestRequestInterface
369    {
370        $userId = UserIdentifier::fromNative('user@example.com');
371        $user = new User($userId);
372        $object = new RestrictedEntity(
373            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440000'),
374            new CompanyName('Company NV'),
375            $user
376        );
377        return new GetResourceApiCallDenied(
378            new BoundedContextId('types'),
379            RestrictedEntity::class,
380            '550e8400-e29b-41d4-a716-446655440000',
381            [$object, $user],
382            new GetAndSetObjectField(
383                '',
384                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
385                new GetAndSetPrimitiveField('companyName', 'Company NV'),
386                new GetPrimitiveField('userId', 'user@example.com'),
387                new GetPrimitiveField('requiredPermissions', ['useratexampledotcom:read', 'useratexampledotcom:write'])
388            ),
389            discardValidationOnFaker: true
390        );
391    }
392
393    /**
394     * Test for entity list with permission restrictions.
395     *
396     * GET /RestrictedEntity/
397     */
398    public function getObjectWithRestrictionListTestRequest(): TestRequestInterface
399    {
400        $userId = UserIdentifier::fromNative('user@example.com');
401        $user = new User($userId);
402        $object = new RestrictedEntity(
403            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440000'),
404            new CompanyName('Company NV'),
405            $user
406        );
407        $object2 = new RestrictedEntity(
408            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440001'),
409            new CompanyName('Company NV 2'),
410            null
411        );
412        return new GetResourceListApiCall(
413            new BoundedContextId('types'),
414            RestrictedEntity::class,
415            [$object, $object2, $user],
416            new GetAndSetObjectField(
417                '',
418                new GetPrimitiveField('totalCount', 1),
419                new GetPrimitiveField('filteredCount', 1),
420                new GetPrimitiveField('first', '/types/RestrictedEntity'),
421                new GetPrimitiveField('last', '/types/RestrictedEntity'),
422                new GetAndSetObjectField(
423                    'list',
424                    new GetAndSetObjectField(
425                        '0',
426                        new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440001'),
427                        new GetAndSetPrimitiveField('companyName', 'Company NV 2'),
428                        new GetPrimitiveField('requiredPermissions', []),
429                        new GetPrimitiveField('userId', null),
430                    )
431                ),
432            ),
433            discardValidationOnFaker: true
434        );
435    }
436
437    /**
438     * Test for invalid property for comboboxes on entity create
439     *
440     * Url POST /ObjectWithRelation/dropdown-options/unknown
441     */
442    public function createInvalidPropertyOptionsTestRequest(): TestRequestInterface
443    {
444        return new ActionMethodApiCall(
445            new BoundedContextId('types'),
446            'ObjectWithRelation/dropdown-options/unknown',
447            new GetAndSetObjectField(
448                '',
449                new SetPrimitiveField('input', 'test@'),
450            ),
451            entities: [],
452        );
453    }
454
455    /**
456     * Test for dropdown action for comboboxes on action method call.
457     */
458    public function createMethodArgumentOptionsTestRequest(): TestRequestInterface
459    {
460        $user = new User(UserIdentifier::fromNative('test@example.com'));
461        return new ActionMethodApiCall(
462            new BoundedContextId('types'),
463            'action/Authentication/isThisMe/dropdown-options/userId',
464            new GetAndSetObjectField(
465                '',
466                new SetPrimitiveField('input', 'test@'),
467                new GetAndSetObjectField(
468                    '0',
469                    new GetPrimitiveField('value', 'test@example.com'),
470                    new GetPrimitiveField('displayValue', 'test@example.com'),
471                )
472            ),
473            entities: [$user],
474            discardValidationOnFaker: true
475        );
476    }
477
478    /**
479     * For cms action /user/{id}/block
480     */
481    public function createBlockUserFormSubmit(): CmsFormSubmitRequest
482    {
483        return new CmsFormSubmitRequest(
484            new BoundedContextId('types'),
485            User::class,
486            'test@example.com',
487            'block',
488            [
489                new User(new UserIdentifier('test@example.com'))
490            ],
491            [
492                '_csrf' => 'string',
493                'form[blockedReason]' => 'This is a test'
494            ],
495            '/cms/types/resource/User/test@example.com'
496        );
497    }
498
499    /**
500     * For testing /calc/1/plus/12
501     */
502    public function createCustomActionRequest(): TestRequestInterface
503    {
504        return new ActionMethodApiCall(
505            new BoundedContextId('types'),
506            'calc/1/plus/12',
507            new GetPrimitiveField('', 13)
508        );
509    }
510
511    /**
512     * For testing /UploadedFile/createRandomFile (static method on resource)
513     */
514    public function createResourceStaticMethodRequest(): TestRequestInterface
515    {
516        return new ActionMethodApiCall(
517            new BoundedContextId('types'),
518            'UploadedFile/createRandomFile?fields=id,imageFile',
519            new GetAndSetObjectField(
520                '',
521                new GetUuidField('id'),
522                new GetPrimitiveField('imageFile', null),
523            ),
524            discardResponseValidation: true, // disabled because of fields request parameter not following required fields logic
525        );
526    }
527
528    /**
529     * For testing /Calculator/sum for testing variadic request.
530     */
531    public function createVariadicActionRequest(): TestRequestInterface
532    {
533        return new ActionMethodApiCall(
534            new BoundedContextId('types'),
535            'Calculator/sum',
536            new GetAndSetPrimitiveField('', ['numbers' => [1,2,3]], 6)
537        );
538    }
539
540    public function createSimpleConsoleInteraction(): InteractiveConsoleCommand
541    {
542        return new InteractiveConsoleCommand(
543            'apie:types:primitive-only:create',
544            PrimitiveOnly::class,
545            [
546                'stringField' => [0, 'string'],
547                'integerField' => [0, 42],
548                'floatingPoint' => [0, 1.5],
549                'booleanField' => [0, 'yes'],
550                'id' => ['075433c9-ca1f-435c-be81-61bae3009521']
551            ]
552        );
553    }
554
555    public function createOrderLineInteraction(): InteractiveConsoleCommand
556    {
557        return new InteractiveConsoleCommand(
558            'apie:types:order:create',
559            Order::class,
560            [
561                'orderLineList' => ['yes', 'my order line description', 'no'],
562            ]
563        );
564    }
565
566    public function createFileUploadInteraction(): InteractiveConsoleCommand
567    {
568        return new InteractiveConsoleCommand(
569            'apie:types:uploaded-file:create',
570            UploadedFile::class,
571            [
572                'id' => ['075433c9-ca1f-435c-be81-61bae3009521'],
573                'file' => [__FILE__],
574                'imageFile' => ['1'],
575            ]
576        );
577    }
578
579    public function createPolymorphicObjectInteraction(): InteractiveConsoleCommand
580    {
581        return new InteractiveConsoleCommand(
582            'apie:types:animal:create',
583            Animal::class,
584            [
585                'id' => ['075433c9-ca1f-435c-be81-61bae3009521'],
586                'animalName' => ['Donald'],
587                'lastName' => ['Duck'],
588            ],
589            Human::class
590        );
591    }
592
593    public function createExampleBoundedContext(): BoundedContextConfig
594    {
595        $result = new BoundedContextConfig();
596        $result->addEntityNamespace(
597            new BoundedContextId('types'),
598            __DIR__ . '/../Apie/TypeDemo',
599            new EntityNamespace('Apie\\IntegrationTests\\Apie\\TypeDemo\\')
600        );
601
602        return $result;
603    }
604}