Skip to content

Commit

Permalink
Adds: tests
Browse files Browse the repository at this point in the history
  • Loading branch information
DaltonMcCleery committed Jul 9, 2024
1 parent a8a7ccc commit 37f2dce
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 0 deletions.
22 changes: 22 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
colors="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
<php>
<env name="APP_KEY" value="abcdefghijklmnopqrstuvwxyz1234567890"/>
<env name="DB_CONNECTION" value="testing"/>
<env name="SESSION_DRIVER" value="array"/>
</php>
</phpunit>
60 changes: 60 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Tests;

use Illuminate\Support\Facades\Http;

/*
|--------------------------------------------------------------------------
| 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 "uses()" function to bind a different classes or traits.
|
*/

uses(TestCase::class)->in('./');

/*
|--------------------------------------------------------------------------
| 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.
|
*/

//

/*
|--------------------------------------------------------------------------
| 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 mockDefaultHttpResponse(): array
{
return [
'yourdomain.com/api/celebrities*' => Http::response([
'total' => 1,
'per_page' => 15,
'current_page' => 1,
'last_page' => 1,
'data' => [
[
'id' => 999,
'name' => 'Dwayne Johnson',
]
]
]),
];
}
151 changes: 151 additions & 0 deletions tests/RemoteModelTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php
namespace Tests;

use RemoteModels\RemoteModel;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;

it('loads data via pagination', function () {
Http::fake([
'yourdomain.com/api/celebrities*' => Http::sequence()
// Initial schema call.
->push([
'total' => 2,
'per_page' => 1,
'current_page' => 1,
'last_page' => 2,
'data' => [
[
'id' => 888,
'name' => 'The Rock',
]
]
])
// Loading data API calls.
->push([
'total' => 2,
'per_page' => 1,
'current_page' => 1,
'last_page' => 2,
'data' => [
[
'id' => 888,
'name' => 'The Rock',
]
]
])
->push([
'total' => 2,
'per_page' => 1,
'current_page' => 2,
'last_page' => 2,
'data' => [
[
'id' => 999,
'name' => 'Dwayne Johnson',
]
]
]),
]);

expect(Celebrity::where('name', 'Dwayne Johnson')->first()->id)->toBe(999)
->and(Celebrity::where('name', 'The Rock')->first()->id)->toBe(888);
});

it('loads user from where query', function () {
Http::fake(mockDefaultHttpResponse());

expect(Celebrity::where('name', 'Dwayne Johnson')->first()->id)->toBe(999)
->and(Celebrity::where('name', 'The Rock')->first())->toBeNull();
});

it('adds domain to config', function () {
Config::set('remote-models.domain', 'https://yourdomain.com/');

Http::fake(mockDefaultHttpResponse());

expect(WithDomain::where('name', 'Dwayne Johnson')->first()->id)->toBe(999);
});

it('loads user from plain API', function () {
Http::fake([
'yourdomain.com/api/celebrities*' => Http::response([
[
'id' => 999,
'name' => 'Dwayne Johnson',
]
]),
]);

expect(Celebrity::where('name', 'Dwayne Johnson')->first()->id)->toBe(999)
->and(Celebrity::where('name', 'The Rock')->first())->toBeNull();
});

it('fails with no endpoint', function () {
expect(NoEndpoint::where('name', 'Dwayne Johnson')->first())->toBeNull();
})->throws(\Exception::class, 'Remote Model property `$endpoint` cannot be empty.');

it('fails on API call', function () {
Http::fake([
'yourdomain.com/api/celebrities*' => Http::response(status: 500),
]);

expect(Celebrity::where('name', 'Dwayne Johnson')->first())->toBeNull();
})->throws(\Exception::class, 'Access to Remote Model `$endpoint` failed.');

it('fails on empty API data', function () {
Http::fake([
'yourdomain.com/api/celebrities*' => Http::response([
'total' => 0,
'per_page' => 15,
'current_page' => 1,
'last_page' => 1,
'data' => []
]),
]);

expect(Celebrity::where('name', 'Dwayne Johnson')->first())->toBeNull();
})->throws(\Exception::class, 'No data returned from Remote Model `$endpoint`.');

it('uses memory if the cache directory is not writeable or not found', function () {
Http::fake(mockDefaultHttpResponse());

config(['remote-models.cache-path' => $path = __DIR__ . '/non-existant-path']);

$count = Celebrity::count();

expect(\file_exists($path))->toBeFalse()
->and($count)->toBe(1)
->and((new Celebrity)->getConnection()->getDatabaseName())->toBe(':memory:');
});

it('caches sqlite file if storage cache folder is available', function () {
Http::fake(mockDefaultHttpResponse());

$count = Celebrity::count();

expect(\file_exists(__DIR__ . '/cache'))->toBeTrue()
->and($count)->toBe(1);
});

it('uses same cache between requests', function () {
// TODO
})->skip();


class Celebrity extends Model {
use RemoteModel;

protected $endpoint = 'https://yourdomain.com/api/celebrities';
}

class WithDomain extends Model {
use RemoteModel;

protected $endpoint = '/api/celebrities';
}

class NoEndpoint extends Model {
use RemoteModel;
}
54 changes: 54 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Tests;

use RemoteModels\RemoteModelServiceProvider;
use Illuminate\Support\Facades\File;
use Orchestra\Testbench\TestCase as OrchestraTestCase;

abstract class TestCase extends OrchestraTestCase
{
public string $cachePath;

protected function getEnvironmentSetUp($app): void
{
$app['config']->set('database.default', 'testbench');
$app['config']->set('database.connections.testbench', [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
]);
}

protected function defineDatabaseMigrations(): void
{
$this->loadLaravelMigrations(['--database' => 'testbench']);
}

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

config(['remote-models.cache-path' => $this->cachePath = __DIR__ . '/cache']);

if (! file_exists($this->cachePath)) {
mkdir($this->cachePath, 0777, true);
}

File::cleanDirectory($this->cachePath);
}

protected function tearDown(): void
{
File::cleanDirectory($this->cachePath);

parent::tearDown();
}

protected function getPackageProviders($app): array
{
return [
RemoteModelServiceProvider::class,
];
}
}

0 comments on commit 37f2dce

Please sign in to comment.