Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Laravel 10 #14

Merged
merged 1 commit into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 14 additions & 31 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,19 @@ name: CI(PhpStan -> PhpUnit)

on:
pull_request:
branches:
- "*"
schedule:
- cron: '0 0 * * *'

jobs:
phpstan:
runs-on: ubuntu-latest
if: (!contains(github.event.head_commit.message, '[skip ci]'))
steps:
- uses: actions/checkout@v2
- uses: php-actions/composer@v6
- uses: php-actions/phpstan@v3
with:
memory_limit: 512M
configuration: ./phpstan.neon

php-tests:
if: (!contains(github.event.head_commit.message, '[skip ci]'))
needs: [phpstan]
strategy:
matrix:
os: [ubuntu-latest]
php: [8.1, 8.0, 7.4]
laravel: [7.*, 8.*, 9.*]
php: [8.1, 8.2, 8.3]
laravel: [10.*]
dependency-version: [prefer-lowest, prefer-stable]
include:
- laravel: 9.*
testbench: 7.*
- laravel: 8.*
testbench: 6.23
- laravel: 7.*
testbench: 5.*
exclude:
- laravel: 9.*
php: 7.4
# https://bytexd.com/fix-laravel-return-type-of-illuminatesupportcollectionoffsetexistskey/
- laravel: 7.*
php: 8.1
- laravel: 10.*
testbench: 8.*

runs-on: ${{ matrix.os }}

Expand All @@ -55,4 +29,13 @@ jobs:
coverage: none
- run: composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update --dev
- run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction
- run: vendor/bin/phpunit
- run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

- name: Static analysis
run: vendor/bin/phpstan --memory-limit=512M analyze

- name: Migrate phpunit schema
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running dependency-version: [prefer-lowest, prefer-stable], the versions don't use the same schema so need to migrate it before running

run: vendor/bin/phpunit --migrate-configuration

- name: Unit testing
run: vendor/bin/phpunit
13 changes: 9 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@
}
},
"require-dev": {
"orchestra/testbench": "^6.0"
"orchestra/testbench": "^8.0",
"phpstan/phpstan": "^1.8",
"phpunit/phpunit": "^10.0",
"spatie/temporary-directory": "^2.2"
},
"require": {
"php": "^7.3|^8.0",
"guzzlehttp/guzzle": "^7.0"
"php": "^8.1|^8.2|^8.3",
"guzzlehttp/guzzle": "^7.0",
"illuminate/contracts": "^10.0",
"symfony/mailer": "^6.2"
}
}
}
25 changes: 25 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
services:
php:
image: php:8.3-fpm # Or any other version you want
volumes:
- ./:/var/www/html # Mount the current directory to the container
working_dir: /var/www/html
ports:
- "8088:80"
depends_on:
- composer
networks:
- newsletter-driver-network

composer:
image: composer:latest
volumes:
- ./:/var/www/html # Same mount so composer can install dependencies
working_dir: /var/www/html
networks:
- newsletter-driver-network
entrypoint: ['composer']

networks:
newsletter-driver-network:
driver: bridge
80 changes: 46 additions & 34 deletions src/Transport/NewsletterTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,25 @@

use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Mail\Transport\Transport;
use Symfony\Component\Mailer\Envelope;
use Symfony\Component\Mailer\Exception\TransportException;
use Symfony\Component\Mailer\Transport\AbstractTransport;
use Lundalogik\NewsletterDriver\Newsletter\AttachmentModel;
use Lundalogik\NewsletterDriver\Newsletter\SendingDomain;
use Lundalogik\NewsletterDriver\Newsletter\SendTransactionMailArgs;
use Lundalogik\NewsletterDriver\Newsletter\SendTransactionMailBatchArgs;
use Lundalogik\NewsletterDriver\Newsletter\TransactionMail;
use Swift_Mime_Attachment;
use Swift_Mime_SimpleMessage;
use Swift_TransportException;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mailer\SentMessage;

class NewsletterTransport extends Transport
class NewsletterTransport extends AbstractTransport
{
/**
* TransactionMail instance.
*
* @var TransactionMail
*/
protected $api;
protected TransactionMail $api;

/**
* Create a new NewsletterTransport instance.
Expand All @@ -32,53 +33,56 @@ class NewsletterTransport extends Transport
public function __construct(TransactionMail $api)
{
$this->api = $api;

parent::__construct();
}

/**
* {@inheritdoc}
* Send the given message.
* Triggered by parent::send()
*
* @param SentMessage $message
* @return void
*/
public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null)
protected function doSend(SentMessage $message): void
{
$this->beforeSendPerformed($message);

try {
$this->api->sendBatch(
$this->getSendTransactionMailBatchArgs($message)
);
$originalMessage = $message->getOriginalMessage();
if ($originalMessage instanceof Email) {
$this->api->sendBatch(
$this->getSendTransactionMailBatchArgs($message->getEnvelope(), $originalMessage)
);
}
} catch (GuzzleException $e) {
throw new Swift_TransportException(
throw new TransportException(
'Request to Newsletter API failed.',
$e->getCode(),
new Exception($e)
);
}

$this->sendPerformed($message);

return $this->numberOfRecipients($message);
}


/**
* Get the SendTransactionMailBatchArgs from the message
*
* @param Swift_Mime_SimpleMessage $message
* @param Envelope $envelope
* @param Email $message
* @return SendTransactionMailBatchArgs
*/
protected function getSendTransactionMailBatchArgs(Swift_Mime_SimpleMessage $message)
protected function getSendTransactionMailBatchArgs(Envelope $envelope, Email $message): SendTransactionMailBatchArgs
{
$sendTransactionMailArgs = [];

$from = $message->getFrom();

[$fromEmail] = array_keys($from);
[$fromName] = array_values($from);
$fromEmail = $envelope->getSender()->getAddress();
$fromName = $envelope->getSender()->getName();

foreach ($message->getTo() as $toEmail => $toName) {
foreach ($envelope->getRecipients() as $index => $to) {
$sendTransactionMailArgs[] = (new SendTransactionMailArgs())
->to($toEmail, $toName)
->to($to->getAddress(), $to->getName())
->from($fromEmail, $fromName)
->subject($message->getSubject())
->htmlContent($message->getBody());
->htmlContent($message->getHtmlBody());
}

return new SendTransactionMailBatchArgs(
Expand All @@ -90,21 +94,29 @@ protected function getSendTransactionMailBatchArgs(Swift_Mime_SimpleMessage $mes
/**
* Get an array of AttachmentModel from the message
*
* @param Swift_Mime_SimpleMessage $message
* @param Email $message
* @return AttachmentModel[]
*/
protected function buildAttachmentModels(Swift_Mime_SimpleMessage $message)
protected function buildAttachmentModels(Email $message): array
{
return collect($message->getChildren())
->filter(function ($child) {
return $child->getHeaders()->get('content-disposition') !== null;
return collect($message->getAttachments())
->filter(function (DataPart $child) {
return $child->getPreparedHeaders()->get('Content-Disposition') !== null;
})
->map(function (Swift_Mime_Attachment $attachment) {
->map(function (DataPart $attachment) {
return (new AttachmentModel())
->fileData($attachment->getBody())
->fileNameWithExtension($attachment->getFilename())
->mimeType($attachment->getContentType());
})
->toArray();
}

/**
* @return string
*/
public function __toString(): string
{
return "newsletter";
}
}
65 changes: 65 additions & 0 deletions tests/Unit/NewsletterTransportTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Lundalogik\NewsletterDriver\Tests\Unit;

use Lundalogik\NewsletterDriver\Newsletter\SendTransactionMailBatchArgs;
use Lundalogik\NewsletterDriver\Newsletter\TransactionMail;
use PHPUnit\Framework\TestCase;
use Lundalogik\NewsletterDriver\Transport\NewsletterTransport;
use Mockery;
use Spatie\TemporaryDirectory\Exceptions\PathAlreadyExists;
use Spatie\TemporaryDirectory\TemporaryDirectory;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mime\Email;

class NewsletterTransportTest extends TestCase
{

/**
* @throws PathAlreadyExists
* @throws TransportExceptionInterface
*/
public function test_it_can_send_full_email_with_attachments(): void
{
$tempDir = (new TemporaryDirectory())
->deleteWhenDestroyed()
->create();

$tmpPath = $tempDir->path('test.txt');
file_put_contents($tmpPath, 'this is a test');

$message = new Email();
$message->from('noreply@lime-forms.com')
->to('albin.hallen@lime.tech')
->subject('Test from laravel-newsletter-driver')
->html("<p>This is a test email from laravel-newsletter-driver</p>")
->attachFromPath($tmpPath, 'test.txt');

$api = Mockery::mock(TransactionMail::class);

/** @phpstan-ignore-next-line */
$api->shouldReceive('sendBatch')
->once()
->with(Mockery::on(function ($args) use ($message) {
$this->assertInstanceOf(SendTransactionMailBatchArgs::class, $args);

$batchArgs = $args->toArray();
$firstBatch = (object) $batchArgs['SendTransactionMailArgs'][0];

$this->assertEquals($firstBatch->RecipientEmail, $message->getTo()[0]->getAddress());
$this->assertEquals($firstBatch->RecipientName, $message->getTo()[0]->getName());
$this->assertEquals($firstBatch->FromEmail, $message->getFrom()[0]->getAddress());
$this->assertEquals($firstBatch->FromName, $message->getFrom()[0]->getName());
$this->assertEquals($firstBatch->Subject, $message->getSubject());
$this->assertNotEmpty($firstBatch->HtmlContent);

$firstBatchAttachments = $batchArgs['BatchAttachments'];
$this->assertEquals('test.txt', $firstBatchAttachments[0]['FileNameWithExtension']);

return 1 === count($batchArgs['SendTransactionMailArgs']);
}))->andReturn();

/** @phpstan-ignore-next-line */
(new NewsletterTransport($api))->send($message);
}
}
Loading