Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.96% covered (success)
97.96%
48 / 49
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
JsonFileUpload
97.96% covered (success)
97.96%
48 / 49
80.00% covered (warning)
80.00%
4 / 5
11
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createRandom
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
3
 validateState
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 toUploadedFile
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 createSchema
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Apie\Core\ValueObjects;
3
4use Apie\Core\Attributes\Description;
5use Apie\Core\Attributes\FakeMethod;
6use Apie\Core\Attributes\Optional;
7use Apie\Core\Attributes\SchemaMethod;
8use Apie\Core\FileStorage\StoredFile;
9use Apie\SchemaGenerator\Builders\ComponentsBuilder;
10use Apie\SchemaGenerator\Enums\SchemaUsages;
11use Faker\Generator;
12
13#[SchemaMethod('createSchema')]
14#[FakeMethod('createRandom')]
15#[Description('Uploads a file with JSON.')]
16final class JsonFileUpload implements CompositeWithOwnValidation
17{
18    use CompositeValueObject;
19
20    public function __construct(
21        private Filename $originalFilename,
22        #[Optional]
23        private BinaryStream $contents,
24        #[Optional]
25        private Base64Stream $base64,
26        #[Optional]
27        private ?StrictMimeType $mime = null
28    ) {
29    }
30
31    public static function createRandom(Generator $generator): JsonFileUpload
32    {
33        $file = Filename::createRandom($generator)->toNative();
34        $contents = null;
35        $base64 = null;
36        $mime = null;
37        if ($generator->boolean()) {
38            $contents = $generator->text();
39        } else {
40            $base64 = Base64Stream::createRandom($generator)->toNative();
41        }
42        if ($generator->boolean()) {
43            $mime = StrictMimeType::createRandom($generator)->toNative();
44        }
45        return JsonFileUpload::fromNative(array_filter([
46            'originalFilename' => $file,
47            'contents' => $contents,
48            'base64' => $base64,
49            'mime' => $mime,
50        ]));
51    }
52
53    protected function validateState(): void
54    {
55        // @phpstan-ignore-next-line isset.initializedProperty
56        if (isset($this->contents) xor isset($this->base64)) {
57            return;
58        }
59        throw new \LogicException(
60            // @phpstan-ignore-next-line isset.initializedProperty
61            isset($this->contents)
62            ? 'You should only provide contents or base64'
63            : 'I need either a "contents" or a "base64" property'
64        );
65    }
66
67    /**
68     * @template T of StoredFile
69     * @param class-string<T> $className
70     * @return T
71     */
72    public function toUploadedFile(string $className = StoredFile::class): StoredFile
73    {
74        // @phpstan-ignore-next-line isset.initializedProperty
75        $contents = isset($this->contents) ? $this->contents->toNative() : $this->base64->decode()->toNative();
76        return $className::createFromString(
77            $contents,
78            isset($this->mime) ? $this->mime->toNative() : null,
79            $this->originalFilename->toNative(),
80        );
81    }
82
83    /**
84     * @return array<string, mixed>
85     */
86    public static function createSchema(SchemaUsages $schemaUsage, ComponentsBuilder $componentsBuilder): array
87    {
88        return [
89            'required' => [
90                'originalFilename',
91            ],
92            'oneOf' => [
93                [
94                    'required' => ['contents', 'originalFilename'],
95                ],
96                [
97                    'required' => ['base64', 'originalFilename'],
98                ],
99            ],
100            'type' => 'object',
101            'properties' => [
102                'contents' => $schemaUsage->toSchema($componentsBuilder, BinaryStream::class),
103                'originalFilename' => $schemaUsage->toSchema($componentsBuilder, Filename::class),
104                'base64' => $schemaUsage->toSchema($componentsBuilder, Base64Stream::class),
105                'mime' => $schemaUsage->toSchema($componentsBuilder, StrictMimeType::class, nullable: true),
106            ]
107        ];
108    }
109}