Skip to content
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
46 changes: 46 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Run Tests

on:
push:
pull_request:

jobs:
php-tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
php: [8.3, 8.4]
laravel: [11.*, 12.*]
dependency-version: [prefer-stable]
exclude:
- php: 8.1
laravel: 11.*
- php: 8.1
laravel: 12.*
- php: 8.4
laravel: 10.*
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} - ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.composer/cache/files
key: dependencies-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick
coverage: none

- name: Install dependencies
run: |
composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction

- name: Execute tests
run: vendor/bin/pest
13 changes: 7 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
"name": "transformstudios/front",
"require": {
"php": "^8.3",
"laravel/framework": "^11.0",
"illuminate/contracts": "^11.0 || ^12.0",
"pixelfear/composer-dist-plugin": "^0.1.4",
"statamic/cms": "^5.0"
"statamic/cms": "^5.0 || ^6.0"
},
"require-dev": {
"mockery/mockery": "^1.3.1",
"nunomaduro/collision": "^8.1",
"phpunit/phpunit": "^11.0",
"orchestra/testbench": "^9.0",
"spatie/laravel-ray": "^1.24"
"orchestra/testbench": "^9.0 || ^10",
"spatie/laravel-ray": "^1.24",
"pestphp/pest": "^4.1"
},
"autoload": {
"psr-4": {
Expand Down Expand Up @@ -43,7 +43,8 @@
},
"config": {
"allow-plugins": {
"pixelfear/composer-dist-plugin": true
"pixelfear/composer-dist-plugin": true,
"pestphp/pest-plugin": true
}
}
}
54 changes: 19 additions & 35 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
printerClass="NunoMaduro\Collision\Adapters\Phpunit\Printer"
stopOnFailure="false"
verbose="true">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">tests/Unit/</directory>
</testsuite>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_KEY" value="base64:xRIcDp1ReW8Y8rd9V9D7hOVV4TI7ThCF3FKxRg01Rm8="/>
<env name="APP_URL" value="http://front.test"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="MAIL_DRIVER" value="array"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
</php>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<coverage/>
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_KEY" value="base64:xRIcDp1ReW8Y8rd9V9D7hOVV4TI7ThCF3FKxRg01Rm8="/>
<env name="APP_URL" value="http://front.test"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="MAIL_DRIVER" value="array"/>
</php>
<source/>
</phpunit>
29 changes: 13 additions & 16 deletions src/Logging/LogHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Support\Collection;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Level;
use Monolog\Logger as Monolog;
use Monolog\LogRecord;
use Statamic\Support\Arr;
Expand All @@ -15,7 +16,7 @@ class LogHandler extends AbstractProcessingHandler
/** @throws \Illuminate\Contracts\Container\BindingResolutionException */
public function __construct(array $channelConfig)
{
parent::__construct(Monolog::toMonologLevel($channelConfig['level'] ?? Monolog::DEBUG));
parent::__construct(Monolog::toMonologLevel($channelConfig['level'] ?? Level::Debug));
}

public function write(array|LogRecord $record): void
Expand All @@ -29,13 +30,11 @@ public function write(array|LogRecord $record): void
}

if (! Arr::get($record, 'context.exception')) {
$errors = collect(
[
'Request URL: '.request()->fullUrl(),
'Request data: '.json_encode(request()->input()),
'Error: '.json_encode($record),
]
);
$errors = collect([
'Request URL: '.request()->fullUrl(),
'Request data: '.json_encode(request()->input()),
'Error: '.json_encode($record),
]);

front()
->post(
Expand All @@ -60,14 +59,12 @@ private function convertErrorToFrontMessage(Throwable $error): array

private function formatErrorLines(Throwable $error): Collection
{
return collect(
[
'Request URL: '.request()->fullUrl(),
'Request data: '.json_encode(request()->input()),
'**'.$error->getMessage().'**',
'* '.$error->getFile().' ('.$error->getLine().')',
]
)->merge($this->formatStackTrace($error));
return collect([
'Request URL: '.request()->fullUrl(),
'Request data: '.json_encode(request()->input()),
'**'.$error->getMessage().'**',
'* '.$error->getFile().' ('.$error->getLine().')',
])->merge($this->formatStackTrace($error));
}

private function formatStackTrace(Throwable $error): Collection
Expand Down
5 changes: 1 addition & 4 deletions src/Logging/Logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ class Logger
/** @throws \Illuminate\Contracts\Container\BindingResolutionException */
public function __invoke(array $config)
{
return new Monolog(
config('app.name'),
[new LogHandler($config)]
);
return new Monolog(config('app.name'), [new LogHandler($config)]);
}
}
5 changes: 2 additions & 3 deletions src/Notifications/BaseNotification.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ public function __construct(
public string $key,
public string $subject,
public string $renderedView,
public Collection $users)
{
}
public Collection $users
) {}

public function via($notifiable)
{
Expand Down
9 changes: 2 additions & 7 deletions src/Notifications/Channel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Illuminate\Http\Client\Response;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Statamic\Auth\User;

class Channel
Expand Down Expand Up @@ -39,17 +38,13 @@ private function data(BaseNotification $notification): array

private function post(string $segment, string $id, array $data): Response
{
return Http::withToken(config('front.api_token'))
->baseUrl('https://api2.frontapp.com')
return front()
->post("/$segment/$id/messages", $data)
->throw();
}

private function getConversationId(Response $response): string
{
return last(explode(
'/',
Arr::get($response, '_links.related.conversation')
));
return last(explode('/', Arr::get($response, '_links.related.conversation')));
}
}
5 changes: 2 additions & 3 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

function front(): PendingRequest
{
return Http::withToken(config('front.api_token'))->baseUrl(
'https://api2.frontapp.com'
);
return Http::withToken(config('front.api_token'))
->baseUrl('https://api2.frontapp.com');
}
60 changes: 60 additions & 0 deletions tests/Notifications/ChannelTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Statamic\Facades\User;
use TransformStudios\Front\Notifications\BaseNotification;
use TransformStudios\Front\Notifications\Channel;

beforeEach(function () {
config()->set('front.notifications.channel', 'test-channel');
Http::preventStrayRequests();
Http::fake([
'https://api2.frontapp.com/channels/test-channel/messages' => Http::response([
'_links' => [
'related' => [
'conversation' => 'https://transform-studios.api.frontapp.com/conversations/cnv_id',
],
],
], 200),
'https://api2.frontapp.com/conversations/cnv_id/messages' => Http::response([], 200),
]);
});

test('can send front message', function () {
$users = collect([makeUser('erin@transformstudios.com'), makeUser('erin@silentz.co')]);
$notification = new TestNotification('some-key', 'Monitor Alert: Error Detected', '', $users);

expect((new Channel)->send(new AnonymousNotifiable, $notification))->toBeTrue();
});

it('stores the conversation id', function () {
$notification = new TestNotification('some-key', 'Monitor Alert: Error Detected', '', collect([makeUser('foo@bar.com')]));

expect(Cache::get('some-key'))->toBeNull();
expect((new Channel)->send(new AnonymousNotifiable, $notification))->toBeTrue();
expect(Cache::get('some-key'))->toEqual('cnv_id');
});

it('removes the conversation id when alert cleared', function () {
$notification = new TestNotification('some-key', 'Monitor Alert: Error Cleared', '', collect([makeUser('foo@bar.com')]));

Cache::put('some-key', 'cnv_id');
expect(Cache::get('some-key'))->not->toBeNull();
expect((new Channel)->send(new AnonymousNotifiable, $notification))->toBeTrue();
expect(Cache::get('some-key'))->toBeNull();
});

it('adds to the conversation when conversation id exists', function () {
$user = makeUser('foo@bar.com');
$notification = new TestNotification('some-key', 'Monitor Alert: Error Detected', '', collect([$user]));
$anotherNotification = new TestNotification('some-key', 'Monitor Alert: Error Cleared', '', collect([$user]));
$channel = new Channel;

expect($channel->send(new AnonymousNotifiable, $notification))->toBeTrue();
expect($channel->send(new AnonymousNotifiable, $anotherNotification))->toBeTrue();
});

class TestNotification extends BaseNotification {}
47 changes: 47 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

use Statamic\Auth\User;

/*
|--------------------------------------------------------------------------
| Test Case
|--------------------------------------------------------------------------
|
| The closure you provide to your test functions is always bound to a specific PHPUnit test
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
| need to change it using the "pest()" function to bind a different classes or traits.
|
*/

pest()->extend(TransformStudios\Front\Tests\TestCase::class)->in(__DIR__);

/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| When you're writing tests, you often need to check that values meet certain conditions. The
| "expect()" function gives you access to a set of "expectations" methods that you can use
| to assert different things. Of course, you may extend the Expectation API at any time.
|
*/

expect()->extend('toBeOne', function () {
return $this->toBe(1);
});

/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/

function makeUser(string $email): User
{
return tap(User::make()->email($email))->save();
}
30 changes: 0 additions & 30 deletions tests/PreventSavingStacheItemsToDisk.php

This file was deleted.

Loading