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
37
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
 createAuditLogFor
n/a
0 / 0
n/a
0 / 0
1
 getAuditLogTestRequest
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
 createAcceptLocaleRequestWithoutLanguageHeader
n/a
0 / 0
n/a
0 / 0
1
 createAcceptLocaleRequestWithLanguageHeader
n/a
0 / 0
n/a
0 / 0
1
 createLocaleRequestWithoutLanguageHeader
n/a
0 / 0
n/a
0 / 0
1
 createLocaleRequestWithLanguageHeader
n/a
0 / 0
n/a
0 / 0
1
 createDataLocaleRequestWithoutLanguageHeader
n/a
0 / 0
n/a
0 / 0
1
 createDataLocaleRequestWithLanguageHeader
n/a
0 / 0
n/a
0 / 0
1
 createLocaleObjectRequestWithoutLanguageHeader
n/a
0 / 0
n/a
0 / 0
1
 createLocaleObjectRequestWithLanguageHeader
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\Other\Audit\AuditCreate;
5use Apie\Common\Other\AuditLog;
6use Apie\Common\Other\AuditOrigin;
7use Apie\Common\ValueObjects\EntityNamespace;
8use Apie\Core\ApieLib;
9use Apie\Core\BoundedContext\BoundedContextId;
10use Apie\Core\Entities\EntityInterface;
11use Apie\Core\Identifiers\Ulid;
12use Apie\Core\IdentifierUtils;
13use Apie\Core\ValueObjects\IdFriendlyEntityReference;
14use Apie\Core\ValueObjects\NonEmptyString;
15use Apie\CountryAndPhoneNumber\BelgianPhoneNumber;
16use Apie\CountryAndPhoneNumber\DutchPhoneNumber;
17use Apie\IntegrationTests\Apie\TypeDemo\Entities\Human;
18use Apie\IntegrationTests\Apie\TypeDemo\Entities\Ostrich;
19use Apie\IntegrationTests\Apie\TypeDemo\Enums\OrderStatus;
20use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\AnimalIdentifier;
21use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\OrderIdentifier;
22use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\RestrictedEntityIdentifier;
23use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\UserIdentifier;
24use Apie\IntegrationTests\Apie\TypeDemo\Lists\OrderLineList;
25use Apie\IntegrationTests\Apie\TypeDemo\Resources\Animal;
26use Apie\IntegrationTests\Apie\TypeDemo\Resources\Order;
27use Apie\IntegrationTests\Apie\TypeDemo\Resources\PrimitiveOnly;
28use Apie\IntegrationTests\Apie\TypeDemo\Resources\RestrictedEntity;
29use Apie\IntegrationTests\Apie\TypeDemo\Resources\UnionObject;
30use Apie\IntegrationTests\Apie\TypeDemo\Resources\UploadedFile;
31use Apie\IntegrationTests\Apie\TypeDemo\Resources\User;
32use Apie\IntegrationTests\Config\BoundedContextConfig;
33use Apie\IntegrationTests\Console\InteractiveConsoleCommand;
34use Apie\IntegrationTests\Requests\ActionMethodApiCall;
35use Apie\IntegrationTests\Requests\CmsFormSubmitRequest;
36use Apie\IntegrationTests\Requests\GetResourceApiCall;
37use Apie\IntegrationTests\Requests\GetResourceApiCallDenied;
38use Apie\IntegrationTests\Requests\GetResourceListApiCall;
39use Apie\IntegrationTests\Requests\JsonFields\GetAndSetObjectField;
40use Apie\IntegrationTests\Requests\JsonFields\GetAndSetPrimitiveField;
41use Apie\IntegrationTests\Requests\JsonFields\GetAndSetUploadedFileField;
42use Apie\IntegrationTests\Requests\JsonFields\GetPrimitiveField;
43use Apie\IntegrationTests\Requests\JsonFields\GetUuidField;
44use Apie\IntegrationTests\Requests\JsonFields\SetPrimitiveField;
45use Apie\IntegrationTests\Requests\RemoveResourceApiCall;
46use Apie\IntegrationTests\Requests\TestRequestInterface;
47use Apie\IntegrationTests\Requests\ValidCreateResourceApiCall;
48use Apie\Serializer\ValueObjects\SerializedPhpObject;
49use Apie\TextValueObjects\CompanyName;
50use Apie\TextValueObjects\FirstName;
51use Beste\Clock\FrozenClock;
52use Beste\Clock\SystemClock;
53use DateTimeImmutable;
54use ReflectionClass;
55
56/**
57 * @codeCoverageIgnore
58 */
59trait CreatesApieBoundedContext
60{
61    /**
62     * For testing POST /user
63     */
64    public function createPostUserTestRequest(): TestRequestInterface
65    {
66        return new ValidCreateResourceApiCall(
67            new BoundedContextId('types'),
68            User::class,
69            new GetAndSetObjectField(
70                '',
71                new GetAndSetPrimitiveField('id', 'test@example.com'),
72                new GetPrimitiveField('blocked', false),
73                new GetPrimitiveField('blockedReason', null),
74                new GetAndSetPrimitiveField('phoneNumber', ' 0611223344 ', '+31611223344'),
75            ),
76        );
77    }
78
79    /**
80     * For testing GET /user/{id}
81     */
82    public function createGetUserTestRequest(): TestRequestInterface
83    {
84        // @phpstan-ignore-next-line
85        $user = (new User(UserIdentifier::fromNative('test@example.com')))->setPhoneNumber(DutchPhoneNumber::fromNative('0611223344'));
86        return new GetResourceApiCall(
87            new BoundedContextId('types'),
88            User::class,
89            'test@example.com',
90            [$user],
91            new GetAndSetObjectField(
92                '',
93                new GetPrimitiveField('id', 'test@example.com'),
94                new GetPrimitiveField('blocked', false),
95                new GetPrimitiveField('blockedReason', null),
96                new GetPrimitiveField('phoneNumber', '+31611223344'),
97            )
98        );
99    }
100
101    /**
102     * For testing GET /animal/{id}
103     */
104    public function createGetAnimalTestRequest(): TestRequestInterface
105    {
106        // @phpstan-ignore-next-line
107        $animal = new Ostrich(AnimalIdentifier::createRandom(), new FirstName('Albert'));
108        return new GetResourceApiCall(
109            new BoundedContextId('types'),
110            Animal::class,
111            $animal->getId()->toNative(),
112            [$animal],
113            new GetAndSetObjectField(
114                '',
115                new GetPrimitiveField('id', $animal->getId()->toNative()),
116                new GetPrimitiveField('name', 'ostrich'),
117                new GetPrimitiveField('animalName', 'Albert'),
118                new GetPrimitiveField('capableOfFlying', false),
119                new GetPrimitiveField('type', 'bird')
120            )
121        );
122    }
123
124    /**
125     * For testing POST/primitiveOnly
126     */
127    public function createPostPrimitiveOnlyTestRequest(): TestRequestInterface
128    {
129        return new ValidCreateResourceApiCall(
130            new BoundedContextId('types'),
131            PrimitiveOnly::class,
132            new GetAndSetObjectField(
133                '',
134                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
135                new GetAndSetPrimitiveField('stringField', 'test'),
136                new GetAndSetPrimitiveField('integerField', '42', 42),
137                new GetAndSetPrimitiveField('floatingPoint', 1.5, 1.5),
138                new GetPrimitiveField('booleanField', null),
139            ),
140            discardRequestValidation: true, //casting string to int is not documented in OpenAPI spec.
141            expectedAuditLogsAdded: 1
142        );
143    }
144
145    /**
146     * For testing POST /animal
147     */
148    public function createPostAnimalTestRequest(): TestRequestInterface
149    {
150        return new ValidCreateResourceApiCall(
151            new BoundedContextId('types'),
152            Animal::class,
153            new GetAndSetObjectField(
154                '',
155                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
156                new GetAndSetPrimitiveField('animalName', 'George', 'George'),
157                new GetAndSetPrimitiveField('type', 'mammal'),
158                new GetAndSetPrimitiveField('name', 'human'),
159                new GetPrimitiveField('capableOfLayingEggs', false),
160                new GetAndSetPrimitiveField('lastName', 'Pig'),
161            ),
162        );
163    }
164
165    /**
166     * For testing POST /UploadedFile
167     */
168    public function createPostUploadedFileTestRequest(): TestRequestInterface
169    {
170        return new ValidCreateResourceApiCall(
171            new BoundedContextId('types'),
172            UploadedFile::class,
173            new GetAndSetObjectField(
174                '',
175                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
176                new GetAndSetUploadedFileField(
177                    'file',
178                    'first order line',
179                    'test-evil.txt',
180                    '/types/UploadedFile/550e8400-e29b-41d4-a716-446655440000/download/file'
181                ),
182                new GetAndSetUploadedFileField(
183                    'imageFile',
184                    file_get_contents(__DIR__ . '/../../fixtures/apie-logo.svg'),
185                    'apie-logo.svg',
186                    '/types/UploadedFile/550e8400-e29b-41d4-a716-446655440000/download/imageFile'
187                ),
188                new GetPrimitiveField('stream', '/types/UploadedFile/550e8400-e29b-41d4-a716-446655440000/download/stream')
189            ),
190        );
191    }
192
193    /**
194     * For testing POST /Order
195     */
196    public function createPostOrderTestRequest(): TestRequestInterface
197    {
198        return new ValidCreateResourceApiCall(
199            new BoundedContextId('types'),
200            Order::class,
201            new GetAndSetObjectField(
202                '',
203                new GetPrimitiveField('id', 1),
204                new GetPrimitiveField('orderStatus', OrderStatus::DRAFT->value),
205                new GetAndSetObjectField(
206                    'orderLineList',
207                    new GetAndSetObjectField(
208                        '0',
209                        new GetAndSetPrimitiveField('description', 'First order line'),
210                        new GetUuidField('id'),
211                    ),
212                    new GetAndSetObjectField(
213                        '1',
214                        new GetAndSetPrimitiveField('description', 'Second order line'),
215                        new GetUuidField('id'),
216                    )
217                ),
218            ),
219            expectedAuditLogsAdded: 1, // 1: created
220        );
221    }
222
223    /**
224     * Test for dropdown action for comboboxes on entity create
225     *
226     * Url POST /ObjectWithRelation/dropdown-options/userId
227     */
228    public function createPropertyOptionsTestRequest(): TestRequestInterface
229    {
230        $user = new User(UserIdentifier::fromNative('test@example.com'));
231        return new ActionMethodApiCall(
232            new BoundedContextId('types'),
233            'ObjectWithRelation/dropdown-options/userId',
234            new GetAndSetObjectField(
235                '',
236                new SetPrimitiveField('input', 'test@'),
237                new GetAndSetObjectField(
238                    '0',
239                    new GetPrimitiveField('value', 'test@example.com'),
240                    new GetPrimitiveField('displayValue', 'test@example.com'),
241                )
242            ),
243            entities: [$user],
244            discardValidationOnFaker: true
245        );
246    }
247
248    /**
249     * Test for hydrating EntityReference on method call.
250     *
251     * Url POST /indexes/User/{userId}
252     */
253    public function createEntityReferenceTest(): TestRequestInterface
254    {
255        $user = new User(UserIdentifier::fromNative('test@example.com'));
256        return new ActionMethodApiCall(
257            new BoundedContextId('types'),
258            'indexes/User/test@example.com',
259            new GetAndSetObjectField(
260                '',
261                new GetPrimitiveField('0', 'test@example.com'),
262            ),
263            entities: [$user],
264            discardValidationOnFaker: true
265        );
266    }
267
268    /**
269     * Test for entity with union object
270     *
271     * POST /UnionObject
272     */
273    public function createUnionObjectTestRequest(): TestRequestInterface
274    {
275        ApieLib::registerValueObject(DutchPhoneNumber::class);
276        ApieLib::registerValueObject(BelgianPhoneNumber::class);
277        return new ValidCreateResourceApiCall(
278            new BoundedContextId('types'),
279            UnionObject::class,
280            new GetAndSetObjectField(
281                '',
282                new GetAndSetPrimitiveField('id', Ulid::createRandom()->toNative()),
283                new GetAndSetPrimitiveField('value', 'string'),
284                new GetAndSetPrimitiveField('otherValue', true),
285                new GetAndSetPrimitiveField('phoneNumber', ' 0611223344 ', '+31611223344'),
286            ),
287            discardRequestValidation: true,
288            discardResponseValidation: true // Somehow gives a false positive.
289        );
290    }
291
292    /**
293     * Test for entity with permission restrictions.
294     *
295     * POST /RestrictedEntity
296     */
297    public function createObjectWithRestrictionTestRequest(): TestRequestInterface
298    {
299        return new ValidCreateResourceApiCall(
300            new BoundedContextId('types'),
301            RestrictedEntity::class,
302            new GetAndSetObjectField(
303                '',
304                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
305                new GetAndSetPrimitiveField('companyName', 'Company NV'),
306                new GetPrimitiveField('userId', null),
307                new GetPrimitiveField('requiredPermissions', [])
308            ),
309        );
310    }
311
312    /**
313     * Test for entity with permission restrictions.
314     *
315     * GET /RestrictedEntity
316     */
317    public function getObjectWithRestrictionTestRequest(): TestRequestInterface
318    {
319        $object = new RestrictedEntity(
320            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440000'),
321            new CompanyName('Company NV'),
322            null
323        );
324        return new GetResourceApiCall(
325            new BoundedContextId('types'),
326            RestrictedEntity::class,
327            '550e8400-e29b-41d4-a716-446655440000',
328            [$object],
329            new GetAndSetObjectField(
330                '',
331                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
332                new GetAndSetPrimitiveField('companyName', 'Company NV'),
333                new GetPrimitiveField('userId', null),
334                new GetPrimitiveField('requiredPermissions', [])
335            ),
336            discardValidationOnFaker: true
337        );
338    }
339
340    /**
341     * Test for entity with audit log for reading.
342     *
343     * GET /Order/{id}
344     */
345    public function getObjectWithReadAuditLogRequest(): TestRequestInterface
346    {
347        $object = new Order(new OrderLineList());
348        return new GetResourceApiCall(
349            new BoundedContextId('types'),
350            Order::class,
351            '1',
352            [$object],
353            new GetAndSetObjectField(
354                '',
355                new GetPrimitiveField('id', '1'),
356                new GetPrimitiveField('orderStatus', OrderStatus::DRAFT->value),
357                new GetPrimitiveField('orderLineList', [])
358            ),
359            discardValidationOnFaker: true,
360            expectedAuditLogsAdded: 1
361        );
362    }
363
364    public function removeOrderTestRequest(): TestRequestInterface
365    {
366        $order = new Order(new OrderLineList());
367        return new RemoveResourceApiCall(
368            new BoundedContextId('types'),
369            'Order/1',
370            new GetAndSetObjectField(''),
371            entities: [$order],
372            expectedAuditLogsAdded: 2 // 1: created, 1: removed
373        );
374    }
375
376    /**
377     * Test for entity with permission restrictions.
378     *
379     * GET /RestrictedEntity/{id}
380     */
381    public function getObjectWithRestrictionDeniedTestRequest(): TestRequestInterface
382    {
383        $userId = UserIdentifier::fromNative('user@example.com');
384        $user = new User($userId);
385        $object = new RestrictedEntity(
386            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440000'),
387            new CompanyName('Company NV'),
388            $user
389        );
390        return new GetResourceApiCallDenied(
391            new BoundedContextId('types'),
392            RestrictedEntity::class,
393            '550e8400-e29b-41d4-a716-446655440000',
394            [$object, $user],
395            new GetAndSetObjectField(
396                '',
397                new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440000'),
398                new GetAndSetPrimitiveField('companyName', 'Company NV'),
399                new GetPrimitiveField('userId', 'user@example.com'),
400                new GetPrimitiveField('requiredPermissions', ['useratexampledotcom:read', 'useratexampledotcom:write'])
401            ),
402            discardValidationOnFaker: true
403        );
404    }
405
406    private function createAuditLogFor(BoundedContextId $boundedContextId, EntityInterface $entity, ?object $createdBy = null): AuditLog
407    {
408        return new AuditLog(
409            new IdFriendlyEntityReference(
410                $boundedContextId,
411                NonEmptyString::fromNative(
412                    IdentifierUtils::entityClassToIdentifier($entity)
413                        ->getMethod('getReferenceFor')
414                        ->invoke(null)
415                        ->name
416                ),
417                NonEmptyString::fromNative($entity->getId())
418            ),
419            SerializedPhpObject::createFromPhpObject($entity),
420            new AuditCreate(false),
421            new AuditOrigin('1.2.3.4', 'Apienternet Explorer', 'testserver', 'phpunit'),
422            SerializedPhpObject::createFromPhpObject($createdBy)
423        );
424    }
425
426    /**
427     * Test for reading audit logs.
428     *
429     * GET /AuditLog/
430     */
431    public function getAuditLogTestRequest(): TestRequestInterface
432    {
433        $userId = UserIdentifier::fromNative('user@example.com');
434        $user = new User($userId);
435        $boundedContextId = new BoundedContextId('types');
436        ApieLib::setPsrClock(FrozenClock::at(new DateTimeImmutable('1970-01-01')));
437
438        $object = new RestrictedEntity(
439            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440000'),
440            new CompanyName('Company NV'),
441            $user
442        );
443        $auditLog1 = $this->createAuditLogFor(
444            $boundedContextId,
445            $object,
446            $userId
447        );
448        ApieLib::setPsrClock(FrozenClock::at(new DateTimeImmutable('1970-01-02')));
449        $object2 = new RestrictedEntity(
450            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440001'),
451            new CompanyName('Company NV 2'),
452            null
453        );
454        $auditLog2 = $this->createAuditLogFor(
455            $boundedContextId,
456            $object2,
457            $userId
458        );
459        ApieLib::setPsrClock(FrozenClock::at(new DateTimeImmutable('1970-01-03')));
460        $object3 = new RestrictedEntity(
461            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440002'),
462            new CompanyName('Company NV 3'),
463            null
464        );
465        $auditLog3 = $this->createAuditLogFor(
466            $boundedContextId,
467            $object3
468        );
469
470        ApieLib::setPsrClock(FrozenClock::at(new DateTimeImmutable('1970-01-04')));
471        $object4 = new Order(new OrderLineList());
472        $refl = new ReflectionClass($object4);
473        $refl->getProperty('id')->setValue($object4, new OrderIdentifier(1));
474        $auditLog4 = $this->createAuditLogFor(
475            $boundedContextId,
476            $object4
477        );
478
479
480        return new GetResourceListApiCall(
481            new BoundedContextId('types'),
482            AuditLog::class,
483            [$object, $auditLog1, $object2, $auditLog2, $object3, $auditLog3, $object4, $auditLog4, $user],
484            new GetAndSetObjectField(
485                '',
486                new GetPrimitiveField('totalCount', 3),
487                new GetPrimitiveField('filteredCount', 3),
488                new GetPrimitiveField('first', '/types/AuditLog'),
489                new GetPrimitiveField('last', '/types/AuditLog'),
490                new GetAndSetObjectField(
491                    'list',
492                    new GetAndSetObjectField(
493                        '0',
494                        new GetAndSetPrimitiveField('id', $auditLog4->getId()->toNative()),
495                    ),
496                    new GetAndSetObjectField(
497                        '1',
498                        new GetAndSetPrimitiveField('id', $auditLog3->getId()->toNative()),
499                    ),
500                    new GetAndSetObjectField(
501                        '2',
502                        new GetAndSetPrimitiveField('id', $auditLog2->getId()->toNative()),
503                    ),
504                ),
505            ),
506            discardValidationOnFaker: true,
507        );
508    }
509
510    /**
511     * Test for entity list with permission restrictions.
512     *
513     * GET /RestrictedEntity/
514     */
515    public function getObjectWithRestrictionListTestRequest(): TestRequestInterface
516    {
517        $userId = UserIdentifier::fromNative('user@example.com');
518        $user = new User($userId);
519        ApieLib::setPsrClock(SystemClock::create());
520        $object = new RestrictedEntity(
521            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440000'),
522            new CompanyName('Company NV'),
523            $user
524        );
525        $object2 = new RestrictedEntity(
526            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440001'),
527            new CompanyName('Company NV 2'),
528            null
529        );
530        $object3 = new RestrictedEntity(
531            RestrictedEntityIdentifier::fromNative('550e8400-e29b-41d4-a716-446655440002'),
532            new CompanyName('Company NV 3'),
533            null
534        );
535        return new GetResourceListApiCall(
536            new BoundedContextId('types'),
537            RestrictedEntity::class,
538            [$object, $object2, $object3, $user],
539            new GetAndSetObjectField(
540                '',
541                new GetPrimitiveField('totalCount', 2),
542                new GetPrimitiveField('filteredCount', 2),
543                new GetPrimitiveField('first', '/types/RestrictedEntity'),
544                new GetPrimitiveField('last', '/types/RestrictedEntity'),
545                new GetAndSetObjectField(
546                    'list',
547                    new GetAndSetObjectField(
548                        '1',
549                        new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440002'),
550                        new GetAndSetPrimitiveField('companyName', 'Company NV 3'),
551                        new GetPrimitiveField('requiredPermissions', []),
552                        new GetPrimitiveField('userId', null),
553                    ),
554                    new GetAndSetObjectField(
555                        '0',
556                        new GetAndSetPrimitiveField('id', '550e8400-e29b-41d4-a716-446655440001'),
557                        new GetAndSetPrimitiveField('companyName', 'Company NV 2'),
558                        new GetPrimitiveField('requiredPermissions', []),
559                        new GetPrimitiveField('userId', null),
560                    ),
561                ),
562            ),
563            discardValidationOnFaker: true,
564            expectedAuditLogsAdded: 2 // 2: created for object2 + 3, object1 is not returned because of permissions
565        );
566    }
567
568    /**
569     * Test for invalid property for comboboxes on entity create
570     *
571     * Url POST /ObjectWithRelation/dropdown-options/unknown
572     */
573    public function createInvalidPropertyOptionsTestRequest(): TestRequestInterface
574    {
575        return new ActionMethodApiCall(
576            new BoundedContextId('types'),
577            'ObjectWithRelation/dropdown-options/unknown',
578            new GetAndSetObjectField(
579                '',
580                new SetPrimitiveField('input', 'test@'),
581            ),
582            entities: [],
583        );
584    }
585
586    /**
587     * Test for dropdown action for comboboxes on action method call.
588     *
589     * Url POST /Authentication/isThisMe/dropdown-options/userId
590     */
591    public function createMethodArgumentOptionsTestRequest(): TestRequestInterface
592    {
593        $user = new User(UserIdentifier::fromNative('test@example.com'));
594        return new ActionMethodApiCall(
595            new BoundedContextId('types'),
596            'action/Authentication/isThisMe/dropdown-options/userId',
597            new GetAndSetObjectField(
598                '',
599                new SetPrimitiveField('input', 'test@'),
600                new GetAndSetObjectField(
601                    '0',
602                    new GetPrimitiveField('value', 'test@example.com'),
603                    new GetPrimitiveField('displayValue', 'test@example.com'),
604                )
605            ),
606            entities: [$user],
607            discardValidationOnFaker: true
608        );
609    }
610
611    /**
612     * test POST /Authentication/acceptLocale
613     *
614     * Only works if application default locale is 'en'.
615     */
616    public function createAcceptLocaleRequestWithoutLanguageHeader(): TestRequestInterface
617    {
618        return new ActionMethodApiCall(
619            new BoundedContextId('types'),
620            'Authentication/acceptLocale',
621            new GetPrimitiveField('', 'en')
622        );
623    }
624
625    public function createAcceptLocaleRequestWithLanguageHeader(): TestRequestInterface
626    {
627        return (new ActionMethodApiCall(
628            new BoundedContextId('types'),
629            'Authentication/acceptLocale',
630            new GetPrimitiveField('', 'nl-NL')
631        ))
632        ->withAdditionalHeaders([
633            'accept-language' => 'nl-NL',
634            'content-language' => 'en-US',
635        ]);
636    }
637
638    /**
639     * test POST /Authentication/locale
640     *
641     * Only works if application default locale is 'en'.
642     */
643    public function createLocaleRequestWithoutLanguageHeader(): TestRequestInterface
644    {
645        return new ActionMethodApiCall(
646            new BoundedContextId('types'),
647            'Authentication/locale',
648            new GetPrimitiveField('', 'en')
649        );
650    }
651
652    public function createLocaleRequestWithLanguageHeader(): TestRequestInterface
653    {
654        return (new ActionMethodApiCall(
655            new BoundedContextId('types'),
656            'Authentication/locale',
657            new GetPrimitiveField('', 'en-US')
658        ))->withAdditionalHeaders([
659            'accept-language' => 'nl-NL',
660            'content-language' => 'en-US',
661        ]);
662    }
663
664    /**
665     * test POST /Authentication/dataLocale
666     *
667     * Only works if application default locale is 'en'.
668     */
669    public function createDataLocaleRequestWithoutLanguageHeader(): TestRequestInterface
670    {
671        return new ActionMethodApiCall(
672            new BoundedContextId('types'),
673            'Authentication/dataLocale',
674            new GetPrimitiveField('', 'en')
675        );
676    }
677
678    public function createDataLocaleRequestWithLanguageHeader(): TestRequestInterface
679    {
680        return (new ActionMethodApiCall(
681            new BoundedContextId('types'),
682            'Authentication/dataLocale',
683            new GetPrimitiveField('', 'en-US')
684        ))->withAdditionalHeaders([
685            'accept-language' => 'nl-NL',
686            'content-language' => 'en-US',
687        ]);
688    }
689
690    /**
691     * test POST /Authentication/localeObject
692     *
693     * Only works if application default locale is 'en'.
694     *
695     * It still results in null as the picked locale object class does not allow 'en' as a proper value.
696     */
697    public function createLocaleObjectRequestWithoutLanguageHeader(): TestRequestInterface
698    {
699        return new ActionMethodApiCall(
700            new BoundedContextId('types'),
701            'Authentication/localeObject',
702            new GetPrimitiveField('', null)
703        );
704    }
705
706    public function createLocaleObjectRequestWithLanguageHeader(): TestRequestInterface
707    {
708        return (new ActionMethodApiCall(
709            new BoundedContextId('types'),
710            'Authentication/localeObject',
711            new GetPrimitiveField('', 'en-US')
712        ))->withAdditionalHeaders([
713            'accept-language' => 'nl-nl',
714            'content-language' => 'en-us',
715        ]);
716    }
717
718    /**
719     * For cms action /user/{id}/block
720     */
721    public function createBlockUserFormSubmit(): CmsFormSubmitRequest
722    {
723        return new CmsFormSubmitRequest(
724            new BoundedContextId('types'),
725            User::class,
726            'test@example.com',
727            'block',
728            [
729                new User(new UserIdentifier('test@example.com'))
730            ],
731            [
732                '_csrf' => 'string',
733                'form[blockedReason]' => 'This is a test'
734            ],
735            '/cms/types/resource/User/test@example.com'
736        );
737    }
738
739    /**
740     * For testing /calc/1/plus/12
741     */
742    public function createCustomActionRequest(): TestRequestInterface
743    {
744        return new ActionMethodApiCall(
745            new BoundedContextId('types'),
746            'calc/1/plus/12',
747            new GetPrimitiveField('', 13)
748        );
749    }
750
751    /**
752     * For testing /UploadedFile/createRandomFile (static method on resource)
753     */
754    public function createResourceStaticMethodRequest(): TestRequestInterface
755    {
756        return new ActionMethodApiCall(
757            new BoundedContextId('types'),
758            'UploadedFile/createRandomFile?fields=id,imageFile',
759            new GetAndSetObjectField(
760                '',
761                new GetUuidField('id'),
762                new GetPrimitiveField('imageFile', null),
763            ),
764            discardResponseValidation: true, // disabled because of fields request parameter not following required fields logic
765        );
766    }
767
768    /**
769     * For testing /Calculator/sum for testing variadic request.
770     */
771    public function createVariadicActionRequest(): TestRequestInterface
772    {
773        return new ActionMethodApiCall(
774            new BoundedContextId('types'),
775            'Calculator/sum',
776            new GetAndSetPrimitiveField('', ['numbers' => [1,2,3]], 6)
777        );
778    }
779
780    public function createSimpleConsoleInteraction(): InteractiveConsoleCommand
781    {
782        return new InteractiveConsoleCommand(
783            'apie:types:primitive-only:create',
784            PrimitiveOnly::class,
785            [
786                'stringField' => [0, 'string'],
787                'integerField' => [0, 42],
788                'floatingPoint' => [0, 1.5],
789                'booleanField' => [0, 'yes'],
790                'id' => ['075433c9-ca1f-435c-be81-61bae3009521']
791            ]
792        );
793    }
794
795    public function createOrderLineInteraction(): InteractiveConsoleCommand
796    {
797        return new InteractiveConsoleCommand(
798            'apie:types:order:create',
799            Order::class,
800            [
801                'orderLineList' => ['yes', 'my order line description', 'no'],
802            ]
803        );
804    }
805
806    public function createFileUploadInteraction(): InteractiveConsoleCommand
807    {
808        return new InteractiveConsoleCommand(
809            'apie:types:uploaded-file:create',
810            UploadedFile::class,
811            [
812                'id' => ['075433c9-ca1f-435c-be81-61bae3009521'],
813                'file' => [__FILE__],
814                'imageFile' => ['1'],
815            ]
816        );
817    }
818
819    public function createPolymorphicObjectInteraction(): InteractiveConsoleCommand
820    {
821        return new InteractiveConsoleCommand(
822            'apie:types:animal:create',
823            Animal::class,
824            [
825                'id' => ['075433c9-ca1f-435c-be81-61bae3009521'],
826                'animalName' => ['Donald'],
827                'lastName' => ['Duck'],
828            ],
829            Human::class
830        );
831    }
832
833    public function createExampleBoundedContext(): BoundedContextConfig
834    {
835        $result = new BoundedContextConfig();
836        $result->addEntityNamespace(
837            new BoundedContextId('types'),
838            __DIR__ . '/../Apie/TypeDemo',
839            new EntityNamespace('Apie\\IntegrationTests\\Apie\\TypeDemo\\')
840        );
841
842        return $result;
843    }
844}