-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #192 from buggregator/feature/185
Adds embeddings support
- Loading branch information
Showing
9 changed files
with
172 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,4 +37,3 @@ public function __invoke(EnvironmentInterface $env, string|int $project): Respon | |
); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
app/modules/Smtp/Interfaces/Http/Controllers/Attachments/PreviewAction.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Modules\Smtp\Interfaces\Http\Controllers\Attachments; | ||
|
||
use App\Application\Commands\FindEventByUuid; | ||
use App\Application\Commands\FindSmtpAttachmentByUuid; | ||
use App\Application\Domain\ValueObjects\Uuid; | ||
use App\Application\HTTP\Response\ErrorResource; | ||
use Modules\Smtp\Domain\AttachmentStorageInterface; | ||
use Nyholm\Psr7\Stream; | ||
use Psr\Http\Message\ResponseInterface; | ||
use Spiral\Cqrs\QueryBusInterface; | ||
use Spiral\Http\Exception\ClientException\ForbiddenException; | ||
use Spiral\Http\ResponseWrapper; | ||
use Spiral\Router\Annotation\Route; | ||
use OpenApi\Attributes as OA; | ||
|
||
#[OA\Get( | ||
path: '/api/smtp/{eventUuid}/attachments/preview/{uuid}', | ||
description: 'Preview an attachment by UUID', | ||
tags: ['Smtp'], | ||
parameters: [ | ||
new OA\PathParameter( | ||
name: 'eventUuid', | ||
description: 'Event UUID', | ||
required: true, | ||
schema: new OA\Schema(type: 'string', format: 'uuid'), | ||
), | ||
new OA\PathParameter( | ||
name: 'uuid', | ||
description: 'Attachment UUID', | ||
required: true, | ||
schema: new OA\Schema(type: 'string', format: 'uuid'), | ||
), | ||
], | ||
responses: [ | ||
new OA\Response( | ||
response: 200, | ||
description: 'Success', | ||
headers: [ | ||
new OA\Header(header: 'Content-Type', schema: new OA\Schema(type: 'string', format: 'binary')), | ||
], | ||
), | ||
new OA\Response( | ||
response: 404, | ||
description: 'Not found', | ||
content: new OA\JsonContent( | ||
ref: ErrorResource::class, | ||
), | ||
), | ||
new OA\Response( | ||
response: 403, | ||
description: 'Access denied.', | ||
content: new OA\JsonContent( | ||
ref: ErrorResource::class, | ||
), | ||
), | ||
], | ||
)] | ||
final readonly class PreviewAction | ||
{ | ||
public function __construct( | ||
private AttachmentStorageInterface $storage, | ||
) {} | ||
|
||
#[Route(route: 'smtp/<eventUuid>/attachments/preview/<uuid>', name: 'smtp.attachments.preview', group: 'api_guest')] | ||
public function __invoke( | ||
QueryBusInterface $bus, | ||
ResponseWrapper $responseWrapper, | ||
Uuid $eventUuid, | ||
Uuid $uuid, | ||
): ResponseInterface { | ||
$event = $bus->ask(new FindEventByUuid($eventUuid)); | ||
$attachment = $bus->ask(new FindSmtpAttachmentByUuid($uuid)); | ||
|
||
if (!$attachment->getEventUuid()->equals($event->getUuid())) { | ||
throw new ForbiddenException('Access denied.'); | ||
} | ||
|
||
$stream = Stream::create($this->storage->getContent($attachment->getPath())); | ||
|
||
return $responseWrapper->create(200) | ||
->withHeader('Content-Type', $attachment->getMime()) | ||
->withBody($stream); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,19 +14,21 @@ | |
use Spiral\RoadRunnerBridge\Tcp\Response\CloseConnection; | ||
use Symfony\Component\Mime\Address; | ||
use Symfony\Component\Mime\Email; | ||
use Symfony\Component\Mime\Part\DataPart; | ||
use Symfony\Component\Mime\Part\File; | ||
use Tests\Feature\Interfaces\TCP\TCPTestCase; | ||
|
||
final class EmailTest extends TCPTestCase | ||
{ | ||
private \Spiral\Storage\BucketInterface $bucket; | ||
private \Mockery\MockInterface|AttachmentRepositoryInterface $accounts; | ||
private \Mockery\MockInterface|AttachmentRepositoryInterface $attachments; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
|
||
$this->bucket = $this->fakeStorage()->bucket('smtp'); | ||
$this->accounts = $this->mockContainer(AttachmentRepositoryInterface::class); | ||
$this->attachments = $this->mockContainer(AttachmentRepositoryInterface::class); | ||
} | ||
|
||
public function testSendEmail(): void | ||
|
@@ -41,8 +43,23 @@ public function testSendEmail(): void | |
uuid: $connectionUuid = Uuid::uuid7(), | ||
); | ||
|
||
// Assert logo-embeddable is persisted to a database | ||
$this->attachments->shouldReceive('store') | ||
->once() | ||
->with( | ||
\Mockery::on(function (Attachment $attachment) { | ||
$this->assertSame('logo-embeddable', $attachment->getFilename()); | ||
$this->assertSame(1206, $attachment->getSize()); | ||
$this->assertSame('image/svg+xml', $attachment->getMime()); | ||
|
||
// Check attachments storage | ||
$this->bucket->assertCreated($attachment->getPath()); | ||
return true; | ||
}), | ||
); | ||
|
||
// Assert hello.txt is persisted to a database | ||
$this->accounts->shouldReceive('store') | ||
$this->attachments->shouldReceive('store') | ||
->once() | ||
->with( | ||
\Mockery::on(function (Attachment $attachment) { | ||
|
@@ -56,17 +73,17 @@ public function testSendEmail(): void | |
}), | ||
); | ||
|
||
|
||
// Assert world.txt is persisted to a database | ||
$this->accounts->shouldReceive('store') | ||
// Assert hello.txt is persisted to a database | ||
$this->attachments->shouldReceive('store') | ||
->once() | ||
->with( | ||
\Mockery::on(function (Attachment $attachment) { | ||
$this->assertSame('logo.svg', $attachment->getFilename()); | ||
$this->assertSame('image/svg+xml', $attachment->getMime()); | ||
$this->assertSame(1206, $attachment->getSize()); | ||
$this->bucket->assertCreated($attachment->getPath()); | ||
$this->assertSame('image/svg+xml', $attachment->getMime()); | ||
|
||
// Check attachments storage | ||
$this->bucket->assertCreated($attachment->getPath()); | ||
return true; | ||
}), | ||
); | ||
|
@@ -141,12 +158,15 @@ private function validateMessage(string $messageId, string $uuid): void | |
|
||
$this->assertSame([], $parsedMessage->getBccs()); | ||
|
||
$this->assertSame( | ||
'Hello Alice.<br>This is a test message with 5 header fields and 4 lines in the message body.', | ||
$parsedMessage->textBody, | ||
$this->assertStringEqualsStringIgnoringLineEndings( | ||
<<<'HTML' | ||
<img src="cid:test-cid@buggregator"> | ||
Hello Alice.<br>This is a test message with 5 header fields and 4 lines in the message body. | ||
HTML | ||
, | ||
$parsedMessage->htmlBody, | ||
); | ||
|
||
$this->assertSame('', $parsedMessage->htmlBody); | ||
$this->assertStringContainsString( | ||
"Subject: Test message\r | ||
Date: Thu, 02 May 2024 16:01:33 +0000\r | ||
|
@@ -213,9 +233,18 @@ public function buildEmail(): Email | |
) | ||
->addFrom(new Address('[email protected]', 'Bob Example'),) | ||
->attachFromPath(path: __DIR__ . '/hello.txt',) | ||
->attachFromPath(path: __DIR__ . '/logo.svg',) | ||
->text( | ||
body: 'Hello Alice.<br>This is a test message with 5 header fields and 4 lines in the message body.', | ||
->attachFromPath(path: __DIR__ . '/logo.svg') | ||
->addPart( | ||
(new DataPart(new File(__DIR__ . '/logo.svg'), 'logo-embeddable'))->asInline()->setContentId( | ||
'test-cid@buggregator', | ||
), | ||
) | ||
->html( | ||
body: <<<'TEXT' | ||
<img src="cid:logo-embeddable"> | ||
Hello Alice.<br>This is a test message with 5 header fields and 4 lines in the message body. | ||
TEXT | ||
, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters