| @@ -6,6 +6,7 @@ | |||||
| /config/secrets/prod/prod.decrypt.private.php | /config/secrets/prod/prod.decrypt.private.php | ||||
| /public/bundles/ | /public/bundles/ | ||||
| /public/media/ | /public/media/ | ||||
| /public/document/ | |||||
| /var/ | /var/ | ||||
| /vendor/ | /vendor/ | ||||
| ###< symfony/framework-bundle ### | ###< symfony/framework-bundle ### | ||||
| @@ -11,8 +11,8 @@ vich_uploader: | |||||
| inject_on_load: false | inject_on_load: false | ||||
| delete_on_update: true | delete_on_update: true | ||||
| delete_on_remove: true | delete_on_remove: true | ||||
| download: | |||||
| uri_prefix: /download | |||||
| upload_destination: '%kernel.project_dir%/public/download' | |||||
| document_object: | |||||
| uri_prefix: /document | |||||
| upload_destination: '%kernel.project_dir%/public/document' | |||||
| # Will rename uploaded files using a uniqueid as a prefix. | # Will rename uploaded files using a uniqueid as a prefix. | ||||
| namer: Vich\UploaderBundle\Naming\SmartUniqueNamer | namer: Vich\UploaderBundle\Naming\SmartUniqueNamer | ||||
| @@ -0,0 +1,35 @@ | |||||
| <?php | |||||
| declare(strict_types=1); | |||||
| namespace DoctrineMigrations; | |||||
| use Doctrine\DBAL\Schema\Schema; | |||||
| use Doctrine\Migrations\AbstractMigration; | |||||
| /** | |||||
| * Auto-generated Migration: Please modify to your needs! | |||||
| */ | |||||
| final class Version20240321094704 extends AbstractMigration | |||||
| { | |||||
| public function getDescription(): string | |||||
| { | |||||
| return ''; | |||||
| } | |||||
| public function up(Schema $schema): void | |||||
| { | |||||
| // this up() migration is auto-generated, please modify it to your needs | |||||
| $this->addSql('CREATE TABLE document_object (id INT AUTO_INCREMENT NOT NULL, partner_id INT DEFAULT NULL, product_id INT DEFAULT NULL, file_path VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', INDEX IDX_16CF1A8A9393F8FE (partner_id), INDEX IDX_16CF1A8A4584665A (product_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); | |||||
| $this->addSql('ALTER TABLE document_object ADD CONSTRAINT FK_16CF1A8A9393F8FE FOREIGN KEY (partner_id) REFERENCES partner (id)'); | |||||
| $this->addSql('ALTER TABLE document_object ADD CONSTRAINT FK_16CF1A8A4584665A FOREIGN KEY (product_id) REFERENCES product (id)'); | |||||
| } | |||||
| public function down(Schema $schema): void | |||||
| { | |||||
| // this down() migration is auto-generated, please modify it to your needs | |||||
| $this->addSql('ALTER TABLE document_object DROP FOREIGN KEY FK_16CF1A8A9393F8FE'); | |||||
| $this->addSql('ALTER TABLE document_object DROP FOREIGN KEY FK_16CF1A8A4584665A'); | |||||
| $this->addSql('DROP TABLE document_object'); | |||||
| } | |||||
| } | |||||
| @@ -90,6 +90,7 @@ class PostingApi implements OwnerInterface | |||||
| * @var $comments array<int, CommentApi> | * @var $comments array<int, CommentApi> | ||||
| */ | */ | ||||
| #[ApiProperty( | #[ApiProperty( | ||||
| writable: false, | |||||
| readableLink: true, | readableLink: true, | ||||
| writableLink: true, | writableLink: true, | ||||
| builtinTypes: [ | builtinTypes: [ | ||||
| @@ -101,6 +101,7 @@ class TaskApi | |||||
| * @var $taskNotes array<int, TaskNoteApi> | * @var $taskNotes array<int, TaskNoteApi> | ||||
| */ | */ | ||||
| #[ApiProperty( | #[ApiProperty( | ||||
| writable: false, | |||||
| readableLink: true, | readableLink: true, | ||||
| writableLink: true, | writableLink: true, | ||||
| builtinTypes: [ | builtinTypes: [ | ||||
| @@ -0,0 +1,59 @@ | |||||
| <?php | |||||
| /** | |||||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||||
| * @date 25.01.24 | |||||
| */ | |||||
| namespace App\Controller; | |||||
| use ApiPlatform\Api\IriConverterInterface; | |||||
| use App\Entity\DocumentObject; | |||||
| use App\Entity\Partner; | |||||
| use App\Entity\Product; | |||||
| use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | |||||
| use Symfony\Component\HttpFoundation\Request; | |||||
| use Symfony\Component\HttpKernel\Attribute\AsController; | |||||
| use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; | |||||
| use Symfonycasts\MicroMapper\MicroMapperInterface; | |||||
| #[AsController] | |||||
| final class CreateDocumentObjectAction extends AbstractController | |||||
| { | |||||
| public function __invoke( | |||||
| Request $request, | |||||
| IriConverterInterface $iriConverter, | |||||
| MicroMapperInterface $microMapper | |||||
| ): DocumentObject { | |||||
| $uploadedFile = $request->files->get('file'); | |||||
| if (!$uploadedFile) { | |||||
| throw new BadRequestHttpException('"file" is required'); | |||||
| } | |||||
| $documentObject = new DocumentObject(); | |||||
| $documentObject->file = $uploadedFile; | |||||
| $partnerIri = $request->request->get('partner'); | |||||
| if ($partnerIri !== null) { | |||||
| try { | |||||
| $partnerApi = $iriConverter->getResourceFromIri($partnerIri); | |||||
| } catch (\Exception $exception) { | |||||
| throw new BadRequestHttpException('invalid partner iri'); | |||||
| } | |||||
| $documentObject->setPartner($microMapper->map($partnerApi, Partner::class)); | |||||
| } | |||||
| $productIri = $request->request->get('product'); | |||||
| if ($productIri !== null) { | |||||
| try { | |||||
| $productApi = $iriConverter->getResourceFromIri($productIri); | |||||
| } catch (\Exception $exception) { | |||||
| throw new BadRequestHttpException('invalid product iri'); | |||||
| } | |||||
| $documentObject->setProduct($microMapper->map($productApi, Product::class)); | |||||
| } | |||||
| return $documentObject; | |||||
| } | |||||
| } | |||||
| @@ -4,6 +4,7 @@ namespace App\DataFixtures; | |||||
| use App\Factory\CommentFactory; | use App\Factory\CommentFactory; | ||||
| use App\Factory\ContactFactory; | use App\Factory\ContactFactory; | ||||
| use App\Factory\DocumentObjectFactory; | |||||
| use App\Factory\MediaObjectLogoFactory; | use App\Factory\MediaObjectLogoFactory; | ||||
| use App\Factory\MediaObjectProductFactory; | use App\Factory\MediaObjectProductFactory; | ||||
| use App\Factory\MediaObjectContactFactory; | use App\Factory\MediaObjectContactFactory; | ||||
| @@ -73,5 +74,6 @@ class AppFixtures extends Fixture | |||||
| MediaObjectProductFactory::createMany(50); | MediaObjectProductFactory::createMany(50); | ||||
| TaskFactory::createMany(50); | TaskFactory::createMany(50); | ||||
| TaskNoteFactory::createMany(100); | TaskNoteFactory::createMany(100); | ||||
| DocumentObjectFactory::createMany(50); | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,149 @@ | |||||
| <?php | |||||
| /** | |||||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||||
| * @date 25.01.24 | |||||
| */ | |||||
| namespace App\Entity; | |||||
| use ApiPlatform\Metadata\ApiProperty; | |||||
| use ApiPlatform\Metadata\ApiResource; | |||||
| use ApiPlatform\Metadata\Delete; | |||||
| use ApiPlatform\Metadata\Get; | |||||
| use ApiPlatform\Metadata\GetCollection; | |||||
| use ApiPlatform\Metadata\Post; | |||||
| use ApiPlatform\OpenApi\Model; | |||||
| use App\Controller\CreateDocumentObjectAction; | |||||
| use Doctrine\ORM\Mapping as ORM; | |||||
| use Symfony\Component\HttpFoundation\File\File; | |||||
| use Symfony\Component\Serializer\Annotation\Groups; | |||||
| use Symfony\Component\Validator\Constraints as Assert; | |||||
| use Vich\UploaderBundle\Mapping\Annotation as Vich; | |||||
| #[Vich\Uploadable] | |||||
| #[ORM\Entity] | |||||
| #[ApiResource( | |||||
| shortName: 'Document', | |||||
| types: ['https://schema.org/MediaObject'], | |||||
| operations: [ | |||||
| new Get(), | |||||
| new GetCollection(), | |||||
| new Post( | |||||
| controller: CreateDocumentObjectAction::class, | |||||
| openapi: new Model\Operation( | |||||
| requestBody: new Model\RequestBody( | |||||
| content: new \ArrayObject([ | |||||
| 'multipart/form-data' => [ | |||||
| 'schema' => [ | |||||
| 'type' => 'object', | |||||
| 'properties' => [ | |||||
| 'file' => [ | |||||
| 'type' => 'string', | |||||
| 'format' => 'binary' | |||||
| ], | |||||
| 'partner' => [ | |||||
| 'type' => 'string', | |||||
| 'format' => 'iri_reference', | |||||
| 'example' => 'https://example.com/' | |||||
| ], | |||||
| 'product' => [ | |||||
| 'type' => 'string', | |||||
| 'format' => 'iri_reference', | |||||
| 'example' => 'https://example.com/' | |||||
| ] | |||||
| ], | |||||
| ], | |||||
| ], | |||||
| ]) | |||||
| ) | |||||
| ), | |||||
| validationContext: ['groups' => ['Default', 'document_object_create']], | |||||
| deserialize: false | |||||
| ), | |||||
| new Delete( | |||||
| // controller: DeleteMediaObjectAction::class | |||||
| ), | |||||
| ], | |||||
| normalizationContext: ['groups' => ['document_object:read']], | |||||
| security: 'is_granted("ROLE_USER")', | |||||
| )] | |||||
| class DocumentObject | |||||
| { | |||||
| #[ORM\Id, ORM\Column, ORM\GeneratedValue] | |||||
| private ?int $id = null; | |||||
| #[ApiProperty(types: ['https://schema.org/contentUrl'])] | |||||
| #[Groups(['document_object:read'])] | |||||
| public ?string $contentUrl = null; | |||||
| #[Vich\UploadableField(mapping: 'document_object', fileNameProperty: 'filePath')] | |||||
| #[Assert\NotNull(groups: ['document_object_create'])] | |||||
| public ?File $file = null; | |||||
| #[ORM\Column(nullable: true)] | |||||
| public ?string $filePath = null; | |||||
| #[ORM\Column] | |||||
| private ?\DateTimeImmutable $createdAt = null; | |||||
| #[ORM\ManyToOne(inversedBy: 'documentObjects')] | |||||
| private ?Partner $partner = null; | |||||
| #[ORM\ManyToOne(inversedBy: 'documentObjects')] | |||||
| private ?Product $product = null; | |||||
| public function __construct() | |||||
| { | |||||
| $this->createdAt = new \DateTimeImmutable(); | |||||
| } | |||||
| public function getId(): ?int | |||||
| { | |||||
| return $this->id; | |||||
| } | |||||
| public function getContentUrl(): ?string | |||||
| { | |||||
| return $this->contentUrl; | |||||
| } | |||||
| public function getFile(): ?File | |||||
| { | |||||
| return $this->file; | |||||
| } | |||||
| public function getFilePath(): ?string | |||||
| { | |||||
| return $this->filePath; | |||||
| } | |||||
| public function getCreatedAt(): ?\DateTimeImmutable | |||||
| { | |||||
| return $this->createdAt; | |||||
| } | |||||
| public function getPartner(): ?Partner | |||||
| { | |||||
| return $this->partner; | |||||
| } | |||||
| public function setPartner(?Partner $partner): static | |||||
| { | |||||
| $this->partner = $partner; | |||||
| return $this; | |||||
| } | |||||
| public function getProduct(): ?Product | |||||
| { | |||||
| return $this->product; | |||||
| } | |||||
| public function setProduct(?Product $product): static | |||||
| { | |||||
| $this->product = $product; | |||||
| return $this; | |||||
| } | |||||
| } | |||||
| @@ -57,12 +57,16 @@ class Partner | |||||
| #[ORM\OneToMany(mappedBy: 'partner', targetEntity: Sale::class)] | #[ORM\OneToMany(mappedBy: 'partner', targetEntity: Sale::class)] | ||||
| private Collection $sales; | private Collection $sales; | ||||
| #[ORM\OneToMany(mappedBy: 'partner', targetEntity: DocumentObject::class)] | |||||
| private Collection $documentObjects; | |||||
| public function __construct() | public function __construct() | ||||
| { | { | ||||
| $this->createdAt = new \DateTimeImmutable(); | $this->createdAt = new \DateTimeImmutable(); | ||||
| $this->contacts = new ArrayCollection(); | $this->contacts = new ArrayCollection(); | ||||
| $this->postings = new ArrayCollection(); | $this->postings = new ArrayCollection(); | ||||
| $this->sales = new ArrayCollection(); | $this->sales = new ArrayCollection(); | ||||
| $this->documentObjects = new ArrayCollection(); | |||||
| } | } | ||||
| public function getId(): ?int | public function getId(): ?int | ||||
| @@ -240,4 +244,34 @@ class Partner | |||||
| return $this; | return $this; | ||||
| } | } | ||||
| /** | |||||
| * @return Collection<int, DocumentObject> | |||||
| */ | |||||
| public function getDocumentObjects(): Collection | |||||
| { | |||||
| return $this->documentObjects; | |||||
| } | |||||
| public function addDocumentObject(DocumentObject $documentObject): static | |||||
| { | |||||
| if (!$this->documentObjects->contains($documentObject)) { | |||||
| $this->documentObjects->add($documentObject); | |||||
| $documentObject->setPartner($this); | |||||
| } | |||||
| return $this; | |||||
| } | |||||
| public function removeDocumentObject(DocumentObject $documentObject): static | |||||
| { | |||||
| if ($this->documentObjects->removeElement($documentObject)) { | |||||
| // set the owning side to null (unless already changed) | |||||
| if ($documentObject->getPartner() === $this) { | |||||
| $documentObject->setPartner(null); | |||||
| } | |||||
| } | |||||
| return $this; | |||||
| } | |||||
| } | } | ||||
| @@ -32,10 +32,14 @@ class Product | |||||
| #[ORM\OneToMany(mappedBy: 'product', targetEntity: Sale::class)] | #[ORM\OneToMany(mappedBy: 'product', targetEntity: Sale::class)] | ||||
| private Collection $sales; | private Collection $sales; | ||||
| #[ORM\OneToMany(mappedBy: 'product', targetEntity: DocumentObject::class)] | |||||
| private Collection $documentObjects; | |||||
| public function __construct() | public function __construct() | ||||
| { | { | ||||
| $this->createdAt = new \DateTimeImmutable(); | $this->createdAt = new \DateTimeImmutable(); | ||||
| $this->sales = new ArrayCollection(); | $this->sales = new ArrayCollection(); | ||||
| $this->documentObjects = new ArrayCollection(); | |||||
| } | } | ||||
| public function getId(): ?int | public function getId(): ?int | ||||
| @@ -113,4 +117,34 @@ class Product | |||||
| return $this; | return $this; | ||||
| } | } | ||||
| /** | |||||
| * @return Collection<int, DocumentObject> | |||||
| */ | |||||
| public function getDocumentObjects(): Collection | |||||
| { | |||||
| return $this->documentObjects; | |||||
| } | |||||
| public function addDocumentObject(DocumentObject $documentObject): static | |||||
| { | |||||
| if (!$this->documentObjects->contains($documentObject)) { | |||||
| $this->documentObjects->add($documentObject); | |||||
| $documentObject->setProduct($this); | |||||
| } | |||||
| return $this; | |||||
| } | |||||
| public function removeDocumentObject(DocumentObject $documentObject): static | |||||
| { | |||||
| if ($this->documentObjects->removeElement($documentObject)) { | |||||
| // set the owning side to null (unless already changed) | |||||
| if ($documentObject->getProduct() === $this) { | |||||
| $documentObject->setProduct(null); | |||||
| } | |||||
| } | |||||
| return $this; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,84 @@ | |||||
| <?php | |||||
| namespace App\Factory; | |||||
| use App\Entity\DocumentObject; | |||||
| use Doctrine\ORM\EntityRepository; | |||||
| use Symfony\Component\HttpKernel\KernelInterface; | |||||
| use Vich\UploaderBundle\FileAbstraction\ReplacingFile; | |||||
| use Zenstruck\Foundry\ModelFactory; | |||||
| use Zenstruck\Foundry\Proxy; | |||||
| use Zenstruck\Foundry\RepositoryProxy; | |||||
| /** | |||||
| * @extends ModelFactory<DocumentObject> | |||||
| * | |||||
| * @method DocumentObject|Proxy create(array|callable $attributes = []) | |||||
| * @method static DocumentObject|Proxy createOne(array $attributes = []) | |||||
| * @method static DocumentObject|Proxy find(object|array|mixed $criteria) | |||||
| * @method static DocumentObject|Proxy findOrCreate(array $attributes) | |||||
| * @method static DocumentObject|Proxy first(string $sortedField = 'id') | |||||
| * @method static DocumentObject|Proxy last(string $sortedField = 'id') | |||||
| * @method static DocumentObject|Proxy random(array $attributes = []) | |||||
| * @method static DocumentObject|Proxy randomOrCreate(array $attributes = []) | |||||
| * @method static EntityRepository|RepositoryProxy repository() | |||||
| * @method static DocumentObject[]|Proxy[] all() | |||||
| * @method static DocumentObject[]|Proxy[] createMany(int $number, array|callable $attributes = []) | |||||
| * @method static DocumentObject[]|Proxy[] createSequence(iterable|callable $sequence) | |||||
| * @method static DocumentObject[]|Proxy[] findBy(array $attributes) | |||||
| * @method static DocumentObject[]|Proxy[] randomRange(int $min, int $max, array $attributes = []) | |||||
| * @method static DocumentObject[]|Proxy[] randomSet(int $number, array $attributes = []) | |||||
| */ | |||||
| final class DocumentObjectFactory extends ModelFactory | |||||
| { | |||||
| /** | |||||
| * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#factories-as-services | |||||
| * | |||||
| * @todo inject services if required | |||||
| */ | |||||
| public function __construct( | |||||
| private KernelInterface $appKernel | |||||
| ) | |||||
| { | |||||
| parent::__construct(); | |||||
| } | |||||
| /** | |||||
| * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#model-factories | |||||
| * | |||||
| * @todo add your default values here | |||||
| */ | |||||
| protected function getDefaults(): array | |||||
| { | |||||
| $projectRoot = $this->appKernel->getProjectDir(); | |||||
| $folderPath = $projectRoot . '/src/DataFixtures/documents/'; | |||||
| $files = glob($folderPath . '*.*'); | |||||
| $randomFile = null; | |||||
| if ($files !== false && count($files) > 0) { | |||||
| $randomFile = $files[array_rand($files)]; | |||||
| } | |||||
| $randBool = (bool)random_int(0, 1); | |||||
| return [ | |||||
| 'file' => new ReplacingFile($randomFile), | |||||
| 'partner' => $randBool ? PartnerFactory::random() : null, | |||||
| 'product' => !$randBool ? ProductFactory::random() : null | |||||
| ]; | |||||
| } | |||||
| /** | |||||
| * @see https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#initialization | |||||
| */ | |||||
| protected function initialize(): self | |||||
| { | |||||
| return $this | |||||
| // ->afterInstantiate(function(DocumentObject $documentObject): void {}) | |||||
| ; | |||||
| } | |||||
| protected static function getClass(): string | |||||
| { | |||||
| return DocumentObject::class; | |||||
| } | |||||
| } | |||||
| @@ -8,6 +8,7 @@ | |||||
| namespace App\Serializer; | namespace App\Serializer; | ||||
| use App\Entity\DocumentObject; | |||||
| use App\Entity\MediaObject; | use App\Entity\MediaObject; | ||||
| use Symfony\Component\DependencyInjection\Attribute\AsDecorator; | use Symfony\Component\DependencyInjection\Attribute\AsDecorator; | ||||
| use Symfony\Component\Serializer\Normalizer\NormalizerInterface; | use Symfony\Component\Serializer\Normalizer\NormalizerInterface; | ||||
| @@ -31,7 +32,7 @@ final class MediaObjectNormalizer implements NormalizerInterface, SerializerAwar | |||||
| { | { | ||||
| $context[self::ALREADY_CALLED] = true; | $context[self::ALREADY_CALLED] = true; | ||||
| if ($object instanceof MediaObject) { | |||||
| if ($object instanceof MediaObject || $object instanceof DocumentObject) { | |||||
| // Nur für MediaObject die URI generieren | // Nur für MediaObject die URI generieren | ||||
| $object->contentUrl = $this->storage->resolveUri($object, 'file'); | $object->contentUrl = $this->storage->resolveUri($object, 'file'); | ||||
| } | } | ||||
| @@ -0,0 +1,121 @@ | |||||
| <?php | |||||
| /** | |||||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||||
| * @date 01.03.24 | |||||
| */ | |||||
| namespace App\Tests\Functional; | |||||
| use App\Factory\DocumentObjectFactory; | |||||
| use App\Factory\MediaObjectLogoFactory; | |||||
| use App\Factory\MediaObjectProductFactory; | |||||
| use App\Factory\PartnerFactory; | |||||
| use App\Factory\ProductFactory; | |||||
| use App\Factory\UserFactory; | |||||
| use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface; | |||||
| use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; | |||||
| use Symfony\Component\HttpFoundation\File\UploadedFile; | |||||
| use Zenstruck\Browser\Test\HasBrowser; | |||||
| use Zenstruck\Foundry\Test\Factories; | |||||
| use Zenstruck\Foundry\Test\ResetDatabase; | |||||
| class DocumentObjectResourceTest extends KernelTestCase | |||||
| { | |||||
| use HasBrowser; | |||||
| use ResetDatabase; | |||||
| use Factories; | |||||
| private JWTTokenManagerInterface $JWTManager; | |||||
| private string $projectDir; | |||||
| protected function setUp(): void | |||||
| { | |||||
| parent::setUp(); | |||||
| $this->JWTManager = self::getContainer()->get('lexik_jwt_authentication.jwt_manager'); | |||||
| $this->projectDir = self::getContainer()->get('kernel')->getProjectDir(); | |||||
| } | |||||
| public function testCreateDocumentObject(): void | |||||
| { | |||||
| $path = $this->projectDir . '/tests/fixtures/'; | |||||
| $srcFile = $path . '1176.png'; | |||||
| $dstFile = $path . '1176_upload.png'; | |||||
| copy($srcFile, $dstFile); | |||||
| $file = new UploadedFile($dstFile, 'image.png'); | |||||
| $user = UserFactory::createOne( | |||||
| [ | |||||
| 'firstName' => 'Peter', | |||||
| 'lastName' => 'Test', | |||||
| 'password' => 'test', | |||||
| 'email' => 'peter@test.de', | |||||
| ] | |||||
| ); | |||||
| MediaObjectProductFactory::createOne(); | |||||
| $partner = PartnerFactory::createOne(); | |||||
| $product = ProductFactory::createOne(); | |||||
| $token = $this->JWTManager->create($user->object()); | |||||
| $this->browser() | |||||
| ->get('/api/documents', [ | |||||
| 'headers' => [ | |||||
| 'Authorization' => 'Bearer ' . $token, | |||||
| ], | |||||
| ]) | |||||
| ->assertSuccessful() | |||||
| ; | |||||
| $this->browser() | |||||
| ->post('/api/documents', [ | |||||
| 'headers' => [ | |||||
| 'Authorization' => 'Bearer ' . $token, | |||||
| 'Content-Type' => 'multipart/form-data' | |||||
| ], | |||||
| 'files' => [ | |||||
| 'file' => $file, | |||||
| ], | |||||
| 'partner' => '/api/partners/' . $partner->getId(), | |||||
| 'product' => '/api/products/' . $product->getId(), | |||||
| ]) | |||||
| ->assertSuccessful() | |||||
| ; | |||||
| $this->browser() | |||||
| ->delete('/api/documents/1', | |||||
| [ | |||||
| 'headers' => [ | |||||
| 'Authorization' => 'Bearer ' . $token, | |||||
| ], | |||||
| ]) | |||||
| ->assertSuccessful() | |||||
| ; | |||||
| } | |||||
| public function testDeleteDocumentObject() | |||||
| { | |||||
| MediaObjectProductFactory::createOne(); | |||||
| $partner = PartnerFactory::createOne(); | |||||
| $product = ProductFactory::createOne(); | |||||
| $documentsObject = DocumentObjectFactory::createOne(); | |||||
| $user = UserFactory::createOne( | |||||
| [ | |||||
| 'firstName' => 'Peter', | |||||
| 'lastName' => 'Test', | |||||
| 'password' => 'test', | |||||
| 'email' => 'peter@test.de', | |||||
| ] | |||||
| ); | |||||
| $token = $this->JWTManager->create($user->object()); | |||||
| $this->browser() | |||||
| ->delete('/api/documents/' . $documentsObject->getId(), [ | |||||
| 'headers' => [ | |||||
| 'Authorization' => 'Bearer ' . $token, | |||||
| ], | |||||
| ]) | |||||
| ->assertSuccessful() | |||||
| ; | |||||
| } | |||||
| } | |||||
| @@ -33,7 +33,7 @@ class MediaObjectResourceTest extends KernelTestCase | |||||
| $this->projectDir = self::getContainer()->get('kernel')->getProjectDir(); | $this->projectDir = self::getContainer()->get('kernel')->getProjectDir(); | ||||
| } | } | ||||
| public function testCreateAMediaObject(): void | |||||
| public function testCreateMediaObject(): void | |||||
| { | { | ||||
| $path = $this->projectDir . '/tests/fixtures/'; | $path = $this->projectDir . '/tests/fixtures/'; | ||||
| $srcFile = $path . '1176.png'; | $srcFile = $path . '1176.png'; | ||||