Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
freekmurze committed Jan 16, 2020
0 parents commit 4ea9c14
Show file tree
Hide file tree
Showing 111 changed files with 6,339 additions and 0 deletions.
22 changes: 22 additions & 0 deletions Actions/ConvertHtmlToTextActionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Spatie\Mailcoach\Tests\Actions;

use Spatie\Mailcoach\Actions\Campaigns\ConvertHtmlToTextAction;
use Spatie\Mailcoach\Tests\TestCase;
use Spatie\Snapshots\MatchesSnapshots;

class ConvertHtmlToTextActionTest extends TestCase
{
use MatchesSnapshots;

/** @test */
public function it_can_convert_html_to_text()
{
$html = file_get_contents(__DIR__ . '/stubs/newsletterHtml.txt');

$text = (new ConvertHtmlToTextAction())->execute($html);

$this->assertMatchesHtmlSnapshotWithoutWhitespace($text);
}
}
67 changes: 67 additions & 0 deletions Actions/PersonalizeHtmlActionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Spatie\Mailcoach\Tests\Actions;

use Spatie\Mailcoach\Actions\Campaigns\PersonalizeHtmlAction;
use Spatie\Mailcoach\Models\Send;
use Spatie\Mailcoach\Tests\TestCase;

class PersonalizeHtmlActionTest extends TestCase
{
/** @var \Spatie\Mailcoach\Models\Send */
private Send $send;

/** @var \Spatie\Mailcoach\Actions\Campaigns\PersonalizeHtmlAction */
private PersonalizeHtmlAction $personalizeHtmlAction;

public function setUp(): void
{
parent::setUp();

$this->send = factory(Send::class)->create();

$subscriber = $this->send->subscriber;
$subscriber->uuid = 'my-uuid';
$subscriber->extra_attributes = ['first_name' => 'John', 'last_name' => 'Doe'];
$subscriber->save();

$this->send->campaign->update(['name' => 'my campaign']);

$this->personalizeHtmlAction = new PersonalizeHtmlAction();
}

/** @test */
public function it_can_replace_an_placeholder_for_a_subscriber_attribute()
{
$this->assertActionResult('::subscriber.uuid::', 'my-uuid');
}

/** @test */
public function it_will_not_replace_a_non_existing_attribute()
{
$this->assertActionResult('::subscriber.non-existing::', '::subscriber.non-existing::');
}

/** @test */
public function it_can_replace_an_placeholder_for_a_subscriber_extra_attribute()
{
$this->assertActionResult('::subscriber.extra_attributes.first_name::', 'John');
}

/** @test */
public function it_will_not_replace_an_placeholder_for_a_non_existing_subscriber_extra_attribute()
{
$this->assertActionResult('::subscriber.extra_attributes.non-existing::', '::subscriber.extra_attributes.non-existing::');
}

protected function assertActionResult(string $inputHtml, $expectedOutputHtml)
{
$actualOutputHtml = (new PersonalizeHtmlAction())->execute($inputHtml, $this->send);
$this->assertEquals($expectedOutputHtml, $actualOutputHtml, "The personalize action did not produce the expected result. Expected: `{$expectedOutputHtml}`, actual: `{$actualOutputHtml}`");

$expectedOutputHtmlWithHtmlTags = "<html>{$expectedOutputHtml}</html>";
$actualOutputHtmlWithHtmlTags = (new PersonalizeHtmlAction())->execute("<html>{$inputHtml}</html>", $this->send);

$this->assertEquals($expectedOutputHtmlWithHtmlTags, $actualOutputHtmlWithHtmlTags, "The personalize action did not produce the expected result when wrapped in html tags. Expected: `{$expectedOutputHtmlWithHtmlTags}`, actual: `{$actualOutputHtmlWithHtmlTags}`");
}
}
47 changes: 47 additions & 0 deletions Actions/PrepareEmailHtmlActionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Spatie\Mailcoach\Tests\Actions;

use Spatie\Mailcoach\Actions\Campaigns\PrepareEmailHtmlAction;
use Spatie\Mailcoach\Models\Campaign;
use Spatie\Mailcoach\Tests\TestCase;
use Spatie\Snapshots\MatchesSnapshots;

class PrepareEmailHtmlActionTest extends TestCase
{
use MatchesSnapshots;

/** @test */
public function it_will_automatically_add_html_tags()
{
$myHtml = '<h1>Hello</h1><p>Hello world</p>';

$campaign = factory(Campaign::class)->create([
'track_clicks' => true,
'html' => $myHtml,
]);

app(PrepareEmailHtmlAction::class)->execute($campaign);

$campaign->refresh();

$this->assertMatchesHtmlSnapshotWithoutWhitespace($campaign->email_html);
}

/** @test */
public function it_will_add_html_tags_if_the_are_already_present()
{
$myHtml = '<html><h1>Hello</h1><p>Hello world</p></html>';

$campaign = factory(Campaign::class)->create([
'track_clicks' => true,
'html' => $myHtml,
]);

app(PrepareEmailHtmlAction::class)->execute($campaign);

$campaign->refresh();

$this->assertMatchesHtmlSnapshotWithoutWhitespace($campaign->email_html);
}
}
35 changes: 35 additions & 0 deletions Actions/SendWelcomeMailActionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Spatie\Mailcoach\Tests\Actions;

use Illuminate\Support\Facades\Mail;
use Spatie\Mailcoach\Actions\Subscribers\SendWelcomeMailAction;
use Spatie\Mailcoach\Mails\WelcomeMail;
use Spatie\Mailcoach\Models\Subscriber;
use Spatie\Mailcoach\Tests\TestCase;

class SendWelcomeMailActionTest extends TestCase
{
private Subscriber $subscriber;

public function setUp(): void
{
parent::setup();

$this->subscriber = factory(Subscriber::class)->create();

$this->subscriber->emailList->update(['send_welcome_mail' => true]);
}

/** @test */
public function it_can_send_a_welcome_mail()
{
Mail::fake();

$action = new SendWelcomeMailAction();

$action->execute($this->subscriber);

Mail::assertQueued(WelcomeMail::class);
}
}
58 changes: 58 additions & 0 deletions Actions/UpdateSubscriberActionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Spatie\Mailcoach\Tests\Actions;

use Spatie\Mailcoach\Actions\Subscribers\UpdateSubscriberAction;
use Spatie\Mailcoach\Models\EmailList;
use Spatie\Mailcoach\Models\Subscriber;
use Spatie\Mailcoach\Support\Config;
use Spatie\Mailcoach\Tests\TestCase;

class UpdateSubscriberActionTest extends TestCase
{
/** @var \Spatie\Mailcoach\Models\Subscriber */
private $subscriber;

/** @var \Spatie\Mailcoach\Models\EmailList */
private $emailList;

/** @var \Spatie\Mailcoach\Models\EmailList */
private $anotherEmailList;

/** @var array */
private $newAttributes;

public function setUp(): void
{
parent::setUp();

$this->subscriber = factory(Subscriber::class)->create();

$this->emailList = factory(EmailList::class)->create();

$this->anotherEmailList = factory(EmailList::class)->create();

$this->newAttributes = [
'email' => '[email protected]',
'first_name' => 'John',
'last_name' => 'Doe',
];
}

/** @test */
public function it_can_update_the_attributes_of_a_subscriber()
{
$updateSubscriberAction = Config::getActionClass('update_subscriber', UpdateSubscriberAction::class);

$updateSubscriberAction->execute(
$this->subscriber,
$this->newAttributes,
);

$this->subscriber->refresh();

$this->assertEquals('[email protected]', $this->subscriber->email);
$this->assertEquals('John', $this->subscriber->first_name);
$this->assertEquals('Doe', $this->subscriber->last_name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>[Viewemailinbrowser](https://sendy.freek.dev/w/gMTJ0B9fBhUbUnImSK1gog)[![freek.dev](https://freek.dev/images/murzicoon.png)](https://freek.dev)FREEK.DEVHi,welcometothe94thfreek.devnewsletter![SendingawelcomenotificationtonewusersofaLaravelapp](https://freek.dev/1500-sending-a-welcome-notification-to-new-users-of-a-laravel-app)Toonboardnewuserscreatedbyotherusers,I'vecreatedanewpackagewhichcansendawelcomenotificationtonewusersthatallowsthemtosetaninitialpassword.[BuildyourownReact](https://pomb.us/build-your-own-react/)Inaverycoolpost,RodrigoPomboexplainstheinternalsofReactbyrewritingit'scorefromscratch.[ClosingModalswiththeBackButtoninaVueSPA](https://jessarcher.com/blog/closing-modals-with-the-back-button-in-a-vue-spa/)JessArcherrecentlygaveanexcellenttalkatLaraconAU.Inanewblogpostsheexplainsoneonetipsgivenduringhertalk:howtoclosemodalsinaVueappbyusingthebackbutton.[Self-hostyournewslettersandemailcampaigns](https://mailcoach.app)MyteamandIarecurrentlybuildingMailcoach,bothastandaloneappandLaravelpackagetosendoutnewsletters.[CreatingcustomrelationsinLaravel](https://stitcher.io/blog/laravel-custom-relation-classes)MycolleagueBrentsolvedaperformancebycreatingacustomrelation.[ImprovingArtisancommands](https://freek.dev/1492-improving-artisan-commands)Inthissmallblogpost,I'dliketogiveyouacoupleoftipstomakeyourArtisancommandsbetter.[WhatIsGarbageCollectioninPHPAndHowDoYouMakeTheMostOfIt?](https://tideways.com/profiler/blog/what-is-garbage-collection-in-php-and-how-do-you-make-the-most-of-it)OntheTidewaysblog,BenjaminEberleiexplainsPHPsgarbagecollectioninternals.[CraftingmaintainableLaravelapplications](https://jasonmccreary.me/articles/crafting-maintainable-laravel-applications/)AtLaraconAU,JasonMcCrearygaveanexcellentalkonhowtocreatemaintainableLaravelapps.Onhisbloghepublishedawrittendownversionofthetalk.MeanwhileonTwitter-[CherrypickthekeysforJSON.stringifytoserialize](https://twitter.com/TejasKumar_/status/1194326690924617728)-[Addquery-constraintswheneagerloadingrelationships](https://twitter.com/_stefanzweifel/status/1194323457477091329)-[Mutatingformrequestdata](https://twitter.com/neilkeena/status/1191410346075901953)Fromthearchives-[BuildingarealtimedashboardpoweredbyLaravel,Vue,PusherandTailwind(2018edition)](https://freek.dev/1212-building-a-realtime-dashboard-powered-by-laravel-vue-pusher-and-tailwind-2018-edition)-[AbetterwaytoregisterroutesinLaravel](https://freek.dev/1210-a-better-way-to-register-routes-in-laravel)-[HowPHPconferencescanbeimproved](https://freek.dev/1209-how-php-conferences-can-be-improved)-[LoadingEloquentrelationshipcounts](https://timacdonald.me/loading-eloquent-relationship-counts/)-[Callinganinvokableinaninstancevariable](https://freek.dev/1208-calling-an-invokable-in-an-instance-variable)-[Usingv-modelonNestedVueComponents](https://zaengle.com/blog/using-v-model-on-nested-vue-components)-[Areyousureyouneedentrustorlaravel-permissiontoimplementyourauthorization?](https://adelf.pro/2018/authorization-packages)-[Otherpeople'ssetup](https://freek.dev/1206-other-peoples-setup)-[FixingImagick's&acirc;&#128;&#156;notauthorized&acirc;&#128;&#157;exception](https://alexvanderbist.com/posts/2018/fixing-imagick-error-unauthorized)-[AutomaticmonitoringofLaravelForgemanagedsites](https://ohdear.app/blog/automatic-monitoring-of-laravel-forge-managed-sites)-[ngrok,lvh.meandnip.io:ATrilogyforLocalDevelopmentandTesting](https://nickjanetakis.com/blog/ngrok-lvhme-nipio-a-trilogy-for-local-development-and-testing)-[Whygeeksshouldspeak](https://justinjackson.ca/speak)-[MakingNovafieldstranslatable](https://freek.dev/1200-making-nova-fields-translatable)-[LaravelTelescope:Datatoolongforcolumn&acirc;&#128;&#152;content&acirc;&#128;&#153;](https://ma.ttias.be/laravel-telescope-data-long-column-content/)Advertisementopportunitiesat[freek.dev/advertising](<https:>).Youarereceivingthismailbecauseyou'vesubscribedat[freek.dev](https://freek.dev).Optoutanytime.[Unsubscribe](https://sendy.freek.dev/unsubscribe-success.php?c=73).</https:></p></body></html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php return ' [View email in browser](https://sendy.freek.dev/w/gMTJ0B9fBhUbUnImSK1gog) [![freek.dev](https://freek.dev/images/murzicoon.png) ](https://freek.dev) FREEK.DEV
Hi, welcome to the 94th freek.dev newsletter!
[Sending a welcome notification to new users of a Laravel app](https://freek.dev/1500-sending-a-welcome-notification-to-new-users-of-a-laravel-app)
To onboard new users created by other users, I\'ve created a new package which can send a welcome notification to new users that allows them to set an initial password.
[Build your own React](https://pomb.us/build-your-own-react/)
In a very cool post, Rodrigo Pombo explains the internals of React by rewriting it\'s core from scratch.
[Closing Modals with the Back Button in a Vue SPA](https://jessarcher.com/blog/closing-modals-with-the-back-button-in-a-vue-spa/)
Jess Archer recently gave an excellent talk at Laracon AU. In a new blogpost she explains one one tips given during her talk: how to close modals in a Vue app by using the back button.
[Self-host your newsletters and email campaigns](https://mailcoach.app)
My team and I are currently building Mailcoach, both a stand alone app and Laravel package to send out newsletters.
[Creating custom relations in Laravel](https://stitcher.io/blog/laravel-custom-relation-classes)
My colleague Brent solved a performance by creating a custom relation.
[Improving Artisan commands](https://freek.dev/1492-improving-artisan-commands)
In this small blog post, I\'d like to give you a couple of tips to make your Artisan commands better.
[What Is Garbage Collection in PHP And How Do You Make The Most Of It?](https://tideways.com/profiler/blog/what-is-garbage-collection-in-php-and-how-do-you-make-the-most-of-it)
On the Tideways blog, Benjamin Eberlei explains PHPs garbage collection internals.
[Crafting maintainable Laravel applications](https://jasonmccreary.me/articles/crafting-maintainable-laravel-applications/)
At Laracon AU, Jason McCreary gave an excellen talk on how to create maintainable Laravel apps. On his blog he published a written down version of the talk.
Meanwhile on Twitter
- [Cherry pick the keys for JSON.stringify to serialize](https://twitter.com/TejasKumar_/status/1194326690924617728)
- [Add query-constraints when eager loading relationships](https://twitter.com/_stefanzweifel/status/1194323457477091329)
- [Mutating form request data](https://twitter.com/neilkeena/status/1191410346075901953)
From the archives
- [Building a realtime dashboard powered by Laravel, Vue, Pusher and Tailwind (2018 edition)](https://freek.dev/1212-building-a-realtime-dashboard-powered-by-laravel-vue-pusher-and-tailwind-2018-edition)
- [A better way to register routes in Laravel](https://freek.dev/1210-a-better-way-to-register-routes-in-laravel)
- [How PHP conferences can be improved](https://freek.dev/1209-how-php-conferences-can-be-improved)
- [Loading Eloquent relationship counts](https://timacdonald.me/loading-eloquent-relationship-counts/)
- [Calling an invokable in an instance variable](https://freek.dev/1208-calling-an-invokable-in-an-instance-variable)
- [Using v-model on Nested Vue Components](https://zaengle.com/blog/using-v-model-on-nested-vue-components)
- [Are you sure you need entrust or laravel-permission to implement your authorization?](https://adelf.pro/2018/authorization-packages)
- [Other people\'s setup](https://freek.dev/1206-other-peoples-setup)
- [Fixing Imagick\'s “not authorized” exception](https://alexvanderbist.com/posts/2018/fixing-imagick-error-unauthorized)
- [Automatic monitoring of Laravel Forge managed sites](https://ohdear.app/blog/automatic-monitoring-of-laravel-forge-managed-sites)
- [ngrok, lvh.me and nip.io: A Trilogy for Local Development and Testing](https://nickjanetakis.com/blog/ngrok-lvhme-nipio-a-trilogy-for-local-development-and-testing)
- [Why geeks should speak](https://justinjackson.ca/speak)
- [Making Nova fields translatable](https://freek.dev/1200-making-nova-fields-translatable)
- [Laravel Telescope: Data too long for column ‘content’](https://ma.ttias.be/laravel-telescope-data-long-column-content/)
Advertisement opportunities at [freek.dev/advertising](< https://freek.dev/advertising>).
You are receiving this mail because you\'ve subscribed at [freek.dev](https://freek.dev). Opt out any time. [Unsubscribe](https://sendy.freek.dev/unsubscribe-success.php?c=73).';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!DOCTYPE htmlPUBLIC>
<html><body>
<p>-//W3C//DTDHTML4.0Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd"&gt;</p>
<h1>Hello</h1>
<p>Helloworld</p>
</body></html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!DOCTYPE htmlPUBLIC>
<html><body>
<p>-//W3C//DTDHTML4.0Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd"&gt;</p>
<h1>Hello</h1>
<p>Helloworld</p>
</body></html>
Loading

0 comments on commit 4ea9c14

Please sign in to comment.