Skip to content

Commit

Permalink
standalone craft-pest-core tests and a sequence method
Browse files Browse the repository at this point in the history
  • Loading branch information
markhuot committed Oct 27, 2023
1 parent 3c6f764 commit 3aae66c
Show file tree
Hide file tree
Showing 51 changed files with 1,505 additions and 3 deletions.
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/vendor
.DS_Store
.idea
composer.lock
cpresources
/src/bin/index.php
.phpunit.result.cache
Expand All @@ -15,3 +14,13 @@ src/bin/cpresources
!/storage/.gitkeep
node_modules
/docs/.vitepress/dist
/composer.lock
/composer-local.lock
/storage
/web
/bootstrap.php
/.env
/cpresources
/templates
/node_modules

32 changes: 32 additions & 0 deletions bin/create-default-fs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

// Load shared bootstrap
require __DIR__.'/../bootstrap.php';

// Load and run Craft
/** @var craft\console\Application $app */
$app = require CRAFT_VENDOR_PATH.'/craftcms/cms/bootstrap/console.php';

$fs = $app->fs->getFilesystemByHandle('local');
if (! $fs) {
$fs = $app->fs->createFilesystem([
'type' => \craft\fs\Local::class,
'name' => 'Local',
'handle' => 'local',
'hasUrls' => true,
'url' => 'http://localhost:8080/volumes/local/',
'settings' => ['path' => CRAFT_BASE_PATH.'/web/volumes/local'],
]);
$result = $app->fs->saveFilesystem($fs);
}

$volume = $app->volumes->getVolumeByHandle('local');
if (! $volume) {
$volume = new \craft\models\Volume();
$volume->name = 'Local';
$volume->handle = 'local';
$volume->fs = $fs;
$app->volumes->saveVolume($volume);
}

$app->run();
47 changes: 47 additions & 0 deletions bin/post-clone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

if [ ! -d "storage" ]; then
mkdir -p storage
fi

if [ ! -f ".env" ]; then
cp vendor/craftcms/craft/.env.example.dev ./.env.example
fi

if ! grep -q "CRAFT_RUN_QUEUE_AUTOMATICALLY=false" .env.example; then
echo "" >> .env
echo "CRAFT_RUN_QUEUE_AUTOMATICALLY=false" >> .env.example
echo "" >> .env
fi

if [ ! -f "config/app.php" ]; then
mkdir -p config
echo "<?php return [
'components' => [
'queue' => [
'class' => \yii\queue\sync\Queue::class,
'handle' => true, // if tasks should be executed immediately
],
],
'bootstrap' => [
function (\$app) {
(new \\markhuot\\craftpest\\Pest)->bootstrap(\$app);
},
]
];" > config/app.php
fi

if [ ! -d "web" ]; then
cp -r vendor/craftcms/craft/web ./
fi

if [ ! -f "craft" ]; then
cp vendor/craftcms/craft/craft ./
chmod +x ./craft
fi

if [ ! -f "bootstrap.php" ]; then
cp vendor/craftcms/craft/bootstrap.php ./
fi

php craft setup/security-key
4 changes: 4 additions & 0 deletions bin/post-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

php craft plugin/install keystone
php ./bin/create-default-fs.php > /dev/null 2>&1
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"symfony/process": "^5.3|^6.0",
"illuminate/collections": "^8.23|^9.1|^10.0",
"pestphp/pest": "^2.8",
"vlucas/phpdotenv": "^2.4|^3.4|^5.4"
"vlucas/phpdotenv": "^2.4|^3.4|^5.4",
"craftcms/cms": "^4.5"
},
"autoload": {
"psr-4": {
Expand Down Expand Up @@ -50,6 +51,7 @@
"prefer-stable": true,
"require-dev": {
"craftcms/phpstan": "dev-main",
"symfony/var-dumper": "^5.0|^6.0"
"symfony/var-dumper": "^5.0|^6.0",
"craftcms/craft": "^2.0"
}
}
16 changes: 16 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" cacheDirectory=".phpunit.cache">
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<coverage/>
<source>
<include>
<directory suffix=".php">./src</directory>
<!-- <directory suffix=".php">./src</directory> -->
<directory suffix=".php">./storage/runtime/compiled_templates</directory>
</include>
</source>
</phpunit>
55 changes: 55 additions & 0 deletions tests/ActingAsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

use markhuot\craftpest\factories\User;

it('logs in users by factory', function () {
$userFactory = User::factory();

$this->actingAs($userFactory);

expect(\Craft::$app->user->identity->email)
->toBe($userFactory->getMadeModels()->first()->email);
});

it('logs in users by email address', function () {
$user = \markhuot\craftpest\factories\User::factory()->create();

$this->actingAs($user->email);

expect(\Craft::$app->user->identity->email)->toBe($user->email);
});

it('logs in user objects', function () {
$user = \markhuot\craftpest\factories\User::factory()->create();

$this->actingAs($user);

expect(\Craft::$app->user->identity->email)->toBe($user->email);
});

it('logs in admins via shorthand')
->actingAsAdmin()
->get('/admin/settings')
->assertOk();

it('throws on missing users', function () {
$this->expectException(\Exception::class);
$this->actingAs('foobar');
});

it('should not be logged in on subsequent tests', function () {
expect(\Craft::$app->user->id)->toBeEmpty();
});

it('acts as a user on get requests', function () {
$user = \markhuot\craftpest\factories\User::factory()->create();

$this->expectException(\yii\web\ForbiddenHttpException::class);
$this->actingAs($user)->withoutExceptionHandling()->get('admin/settings');
});

it('creates admin users', function () {
$user = \markhuot\craftpest\factories\User::factory()->admin(true)->create();

$this->actingAs($user)->get('admin/settings')->assertOk();
});
32 changes: 32 additions & 0 deletions tests/BenchmarkTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use markhuot\craftpest\factories\Entry;
use markhuot\craftpest\factories\Section;

it('benchmarks duplicate queries')
->beginBenchmark()
->get('/')
->assertOk()
->endBenchmark()
->assertNoDuplicateQueries();

it('benchmarks query speed')
->beginBenchmark()
->get('/')
->assertOk()
->endBenchmark()
->assertAllQueriesFasterThan(2);

it('benchmarks load time')
->beginBenchmark()
->get('/')
->assertOk()
->endBenchmark()
->assertLoadTimeLessThan(10);

it('benchmarks memory usage')
->beginBenchmark()
->get('/')
->assertOk()
->endBenchmark()
->assertMemoryLoadLessThan(256);
5 changes: 5 additions & 0 deletions tests/BootstrapTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

it('can bootstrap craft', function () {
expect(\Craft::$app)->toBeTruthy();
});
37 changes: 37 additions & 0 deletions tests/CookieTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

use markhuot\craftpest\factories\User;

it('receives cookies')
->get('response-test')
->assertCookie('cookieName');

it('sends cookies', function () {
$content = $this->http('get', 'responses/cookies')
->addCookie('theName', 'theValue')
->send()
->content;

expect(trim($content))->toBe(json_encode(['theName' => 'theValue']));
});

it('retains cookies', function () {
$this->get('response-test')
->assertOk()
->assertCookie('cookieName');

$this->get('responses/cookies')
->assertOk()
->expect()
->jsonContent->toBe(['cookieName' => 'cookieValue']);

$this->get('responses/cookies')
->assertOk()
->expect()
->jsonContent->toBe(['cookieName' => 'cookieValue']);
});

it('doesn\'t have any cookies from previous tests', function () {
$response = $this->get('responses/cookies');
expect($response->jsonContent)->toHaveCount(0);
});
14 changes: 14 additions & 0 deletions tests/CoverageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use function markhuot\craftpest\helpers\http\get;

it ('does not run a conditional', function () {
get('/')->assertOk()->assertDontSee('getParam');
});

it ('runs a conditional via a query var', function () {
get('/?foo=1')->assertOk()->assertSee('getParam');
});

get('/loop-test')
->assertOk();
29 changes: 29 additions & 0 deletions tests/DatabaseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use markhuot\craftpest\factories\Entry;

it('asserts database content', function () {
$count = (new \craft\db\Query)->from(\craft\db\Table::SITES)->count();
$this->assertDatabaseCount(\craft\db\Table::SITES, $count);
});

it('asserts database content on condition', function () {
$section = \markhuot\craftpest\factories\Section::factory()->create();
$entry = \markhuot\craftpest\factories\Entry::factory()->section($section)->create();

$this->assertDatabaseHas(\craft\db\Table::CONTENT, [
'title' => $entry->title,
]);
});

it('asserts database content is missing')
->assertDatabaseMissing(\craft\db\Table::CONTENT, ['title' => 'fooz baz']);

it('asserts trashed', function () {
$entry = Entry::factory()
->create()
->assertNotTrashed();

\Craft::$app->elements->deleteElement($entry);
$entry->assertTrashed();
});
14 changes: 14 additions & 0 deletions tests/ElementTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use markhuot\craftpest\factories\Entry;

it('asserts valid')
->factory(Entry::class)
->create()
->assertValid();

it('asserts invalid')
->factory(Entry::class)
->muteValidationErrors()
->create(['title' => null])
->assertInvalid();
13 changes: 13 additions & 0 deletions tests/EntryQueryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

use markhuot\craftpest\factories\Section;
use markhuot\craftpest\factories\Entry;

it('counts entries', function() {
Entry::factory()
->section($section = Section::factory()->create())
->count(10)
->create();

\craft\elements\Entry::find()->section($section)->assertCount(10);
});
Loading

0 comments on commit 3aae66c

Please sign in to comment.