feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run

- Base: wintercms/winter branch 1.2 (full framework)
- Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS
- Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication
- Partials: hero (offline-first), features, modes (offline/nube toggle),
  screenshots, pricing (3 planes), comparison, FAQ, CTA
- Plugin VivesPOS.Site with ContactForm
- Dockerfile: PHP 8.2 Apache, port 80, healthcheck
- Added winter/wn-pages, blog, sitemap, seo plugins
- Active theme set to vivespos
This commit is contained in:
2026-08-21 19:29:00 -06:00
commit 1f72193a64
3266 changed files with 531480 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use System\Models\File as FileModel;
use Database\Tester\Models\User;
use Model;
class AttachManyModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/User.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testDeleteFlagDestroyRelationship()
{
Model::unguard();
$user = User::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
Model::reguard();
$this->assertEmpty($user->photos);
$user->photos()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']);
$user->reloadRelations();
$this->assertNotEmpty($user->photos);
$photo = $user->photos->first();
$photoId = $photo->id;
$user->photos()->remove($photo);
$this->assertNull(FileModel::find($photoId));
}
public function testDeleteFlagDeleteModel()
{
Model::unguard();
$user = User::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
Model::reguard();
$this->assertEmpty($user->photos);
$user->photos()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']);
$user->reloadRelations();
$this->assertNotEmpty($user->photos);
$photo = $user->photos->first();
$this->assertNotNull($photo);
$photoId = $photo->id;
$user->delete();
$this->assertNull(FileModel::find($photoId));
}
}

View File

@@ -0,0 +1,112 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use System\Models\File as FileModel;
use Database\Tester\Models\User;
use Database\Tester\Models\SoftDeleteUser;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Model;
class AttachOneModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/User.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$user = User::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$user2 = User::create(['name' => 'Joe', 'email' => 'joe@example.com']);
Model::reguard();
// Set by string
$user->avatar = base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png';
// @todo $user->avatar currently sits as a string, not good for validation
// this should really assert as an UploadedFile instead.
// Commit the file and it should snap to a File model
$user->save();
$this->assertNotNull($user->avatar);
$this->assertEquals('avatar.png', $user->avatar->file_name);
// Set by Uploaded file
$sample = $user->avatar;
$upload = new UploadedFile(
base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png',
$sample->file_name,
$sample->content_type,
null,
true
);
$user2->avatar = $upload;
// The file is prepped but not yet commited, this is for validation
$this->assertNotNull($user2->avatar);
$this->assertEquals($upload, $user2->avatar);
// Commit the file and it should snap to a File model
$user2->save();
$this->assertNotNull($user2->avatar);
$this->assertEquals('avatar.png', $user2->avatar->file_name);
}
public function testDeleteFlagDestroyRelationship()
{
Model::unguard();
$user = User::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
Model::reguard();
$this->assertNull($user->avatar);
$user->avatar()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']);
$user->reloadRelations();
$this->assertNotNull($user->avatar);
$avatar = $user->avatar;
$avatarId = $avatar->id;
$user->avatar()->remove($avatar);
$this->assertNull(FileModel::find($avatarId));
}
public function testDeleteFlagDeleteModel()
{
Model::unguard();
$user = User::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
Model::reguard();
$this->assertNull($user->avatar);
$user->avatar()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']);
$user->reloadRelations();
$this->assertNotNull($user->avatar);
$avatarId = $user->avatar->id;
$user->delete();
$this->assertNull(FileModel::find($avatarId));
}
public function testDeleteFlagSoftDeleteModel()
{
Model::unguard();
$user = SoftDeleteUser::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
Model::reguard();
$user->avatar()->create(['data' => base_path() . '/modules/system/tests/fixtures/plugins/database/tester/assets/images/avatar.png']);
$this->assertNotNull($user->avatar);
$avatarId = $user->avatar->id;
$user->delete();
$this->assertNotNull(FileModel::find($avatarId));
}
}

View File

@@ -0,0 +1,218 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Category;
use Database\Tester\Models\Post as PostModel;
use Database\Tester\Models\Role;
use Database\Tester\Models\Author;
use Model;
use DB;
class BelongsToManyModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Role.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Category.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$role1 = Role::create(['name' => "Designer", 'description' => "Quality"]);
$role2 = Role::create(['name' => "Programmer", 'description' => "Speed"]);
$role3 = Role::create(['name' => "Manager", 'description' => "Budget"]);
Model::reguard();
// Add/remove to collection
$this->assertFalse($author->roles->contains($role1->id));
$author->roles()->add($role1);
$author->roles()->add($role2);
$this->assertTrue($author->roles->contains($role1->id));
$this->assertTrue($author->roles->contains($role2->id));
// Set by Model object
$author->roles = $role1;
$this->assertEquals(1, $author->roles->count());
$this->assertEquals('Designer', $author->roles->first()->name);
$author->roles = [$role1, $role2, $role3];
$this->assertEquals(3, $author->roles->count());
// Set by primary key
$author->roles = $role2->id;
$this->assertEquals(1, $author->roles->count());
$this->assertEquals('Programmer', $author->roles->first()->name);
$author->roles = [$role2->id, $role3->id];
$this->assertEquals(2, $author->roles->count());
// Nullify
$author->roles = null;
$this->assertEquals(0, $author->roles->count());
// Extra nullify checks (still exists in DB until saved)
$author->reloadRelations('roles');
$this->assertEquals(2, $author->roles->count());
$author->save();
$author->reloadRelations('roles');
$this->assertEquals(0, $author->roles->count());
// Deferred in memory
$author->roles = [$role2->id, $role3->id];
$this->assertEquals(2, $author->roles->count());
$this->assertEquals('Programmer', $author->roles->first()->name);
}
public function testGetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$role1 = Role::create(['name' => "Designer", 'description' => "Quality"]);
$role2 = Role::create(['name' => "Programmer", 'description' => "Speed"]);
Model::reguard();
$author->roles()->add($role1);
$author->roles()->add($role2);
$this->assertEquals([$role1->id, $role2->id], $author->getRelationValue('roles'));
}
public function testDeferredBinding()
{
$sessionKey = uniqid('session_key', true);
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$role1 = Role::create(['name' => "Designer", 'description' => "Quality"]);
$role2 = Role::create(['name' => "Programmer", 'description' => "Speed"]);
$category = Category::create(['name' => 'News']);
$post1 = PostModel::create(['title' => 'First post']);
$post2 = PostModel::create(['title' => 'Second post']);
Model::reguard();
// Deferred add
$author->roles()->add($role1, $sessionKey);
$author->roles()->add($role2, $sessionKey);
$category->posts()->add($post1, $sessionKey, [
'category_name' => $category->name . ' in pivot',
'post_name' => $post1->title . ' in pivot',
]);
$category->posts()->add($post2, $sessionKey, [
'category_name' => $category->name . ' in pivot',
'post_name' => $post2->title . ' in pivot',
]);
$this->assertEmpty($author->roles);
$this->assertEmpty($category->posts);
$this->assertEquals(0, $author->roles()->count());
$this->assertEquals(2, $author->roles()->withDeferred($sessionKey)->count());
$this->assertEquals(0, $category->posts()->count());
$this->assertEquals(2, $category->posts()->withDeferred($sessionKey)->count());
// Get simple value (implicit)
$author->reloadRelations();
$author->sessionKey = $sessionKey;
$this->assertEquals([$role1->id, $role2->id], $author->getRelationValue('roles'));
$category->reloadRelations();
$category->sessionKey = $sessionKey;
$this->assertEquals([$post1->id, $post2->id], $category->getRelationValue('posts'));
// Get simple value (explicit)
$relatedIds = $author->roles()->allRelatedIds($sessionKey)->all();
$this->assertEquals([$role1->id, $role2->id], $relatedIds);
$relatedIds = $category->posts()->allRelatedIds($sessionKey)->all();
$this->assertEquals([$post1->id, $post2->id], $relatedIds);
// Commit deferred
$author->save(null, $sessionKey);
$category->save(null, $sessionKey);
$this->assertEquals(2, $author->roles()->count());
$this->assertEquals('Designer', $author->roles->first()->name);
$this->assertEquals(2, $category->posts()->count());
$this->assertEquals('First post', $category->posts->first()->title);
$this->assertEquals('Second post', $category->posts->last()->title);
$this->assertEquals('First post in pivot', $category->posts->first()->pivot->post_name);
$this->assertEquals('Second post in pivot', $category->posts->last()->pivot->post_name);
$this->assertEquals('News in pivot', $category->posts->first()->pivot->category_name);
$this->assertEquals('News in pivot', $category->posts->last()->pivot->category_name);
// New session
$sessionKey = uniqid('session_key', true);
// Deferred remove
$author->roles()->remove($role1, $sessionKey);
$author->roles()->remove($role2, $sessionKey);
$category->posts()->remove($post1, $sessionKey);
$category->posts()->remove($post2, $sessionKey);
$this->assertEquals(2, $author->roles()->count());
$this->assertEquals(0, $author->roles()->withDeferred($sessionKey)->count());
$this->assertEquals(2, $category->posts()->count());
$this->assertEquals(0, $category->posts()->withDeferred($sessionKey)->count());
$this->assertEquals('Designer', $author->roles->first()->name);
$this->assertEquals('First post', $category->posts->first()->title);
$this->assertEquals('Second post', $category->posts->last()->title);
$this->assertEquals('First post in pivot', $category->posts->first()->pivot->post_name);
$this->assertEquals('Second post in pivot', $category->posts->last()->pivot->post_name);
$this->assertEquals('News in pivot', $category->posts->first()->pivot->category_name);
$this->assertEquals('News in pivot', $category->posts->last()->pivot->category_name);
// Commit deferred
$author->save(null, $sessionKey);
$category->save(null, $sessionKey);
$this->assertEquals(0, $author->roles()->count());
$this->assertEquals(0, $author->roles->count());
$this->assertEquals(0, $category->posts()->count());
$this->assertEquals(0, $category->posts->count());
}
public function testDetachAfterDelete()
{
// Needed for other "delete" events
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/User.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/EventLog.php';
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$role1 = Role::create(['name' => "Designer", 'description' => "Quality"]);
$role2 = Role::create(['name' => "Programmer", 'description' => "Speed"]);
$role3 = Role::create(['name' => "Manager", 'description' => "Budget"]);
Model::reguard();
$author->roles()->add($role1);
$author->roles()->add($role2);
$author->roles()->add($role3);
$this->assertEquals(3, DB::table('database_tester_authors_roles')->where('author_id', $author->id)->count());
$author->delete();
$this->assertEquals(0, DB::table('database_tester_authors_roles')->where('author_id', $author->id)->count());
}
public function testConditionsWithPivotAttributes()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$role1 = Role::create(['name' => "Designer", 'description' => "Quality"]);
$role2 = Role::create(['name' => "Programmer", 'description' => "Speed"]);
$role3 = Role::create(['name' => "Manager", 'description' => "Budget"]);
Model::reguard();
$author->roles()->add($role1, null, ['is_executive' => 1]);
$author->roles()->add($role2, null, ['is_executive' => 1]);
$author->roles()->add($role3, null, ['is_executive' => 0]);
$this->assertEquals([1, 2], $author->executive_authors->lists('id'));
$this->assertEquals([1, 2], $author->executive_authors()->lists('id'));
$this->assertEquals([1, 2], $author->executive_authors()->get()->lists('id'));
}
}

View File

@@ -0,0 +1,103 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Post;
use Database\Tester\Models\Author;
use Model;
class BelongsToModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$post = Post::create(['title' => "First post", 'description' => "Yay!!"]);
$author1 = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$author2 = Author::create(['name' => 'Louie', 'email' => 'louie@example.com']);
$author3 = Author::make(['name' => 'Charlie', 'email' => 'charlie@example.com']);
Model::reguard();
// Set by Model object
$post->author = $author1;
$this->assertEquals($author1->id, $post->author_id);
$this->assertEquals('Stevie', $post->author->name);
// Set by primary key
$post->author = $author2->id;
$this->assertEquals($author2->id, $post->author_id);
$this->assertEquals('Louie', $post->author->name);
// Nullify
$post->author = null;
$this->assertNull($post->author_id);
$this->assertNull($post->author);
// Deferred in memory
$post->author = $author3;
$this->assertEquals('Charlie', $post->author->name);
$this->assertNull($post->author_id);
$author3->save();
$this->assertEquals($author3->id, $post->author_id);
}
public function testGetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$post = Post::make(['title' => "First post", 'author_id' => $author->id]);
Model::reguard();
$this->assertEquals($author->id, $post->getRelationValue('author'));
}
public function testDeferredBinding()
{
$sessionKey = uniqid('session_key', true);
Model::unguard();
$post = Post::make(['title' => "First post"]);
$author = Author::create(['name' => 'Stevie']);
Model::reguard();
// Deferred add
$post->author()->add($author, $sessionKey);
$this->assertNull($post->author_id);
$this->assertNull($post->author);
$this->assertEquals(0, $post->author()->count());
$this->assertEquals(1, $post->author()->withDeferred($sessionKey)->count());
// Commit deferred
$post->save(null, $sessionKey);
$this->assertEquals(1, $post->author()->count());
$this->assertEquals($author->id, $post->author_id);
$this->assertEquals('Stevie', $post->author->name);
// New session
$sessionKey = uniqid('session_key', true);
// Deferred remove
$post->author()->remove($author, $sessionKey);
$this->assertEquals(1, $post->author()->count());
$this->assertEquals(0, $post->author()->withDeferred($sessionKey)->count());
$this->assertEquals($author->id, $post->author_id);
$this->assertEquals('Stevie', $post->author->name);
// Commit deferred
$post->save(null, $sessionKey);
$this->assertEquals(0, $post->author()->count());
$this->assertNull($post->author_id);
$this->assertNull($post->author);
}
}

View File

@@ -0,0 +1,112 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Post;
use Database\Tester\Models\Author;
use Winter\Storm\Database\Models\DeferredBinding;
use Model;
class DeferredBindingTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testNegatedBinding()
{
$sessionKey = uniqid('session_key', true);
DeferredBinding::truncate();
Model::unguard();
$author = Author::make(['name' => 'Stevie']);
$post = Post::create(['title' => "First post"]);
$post2 = Post::create(['title' => "Second post"]);
Model::reguard();
$author->posts()->add($post, $sessionKey);
$this->assertEquals(1, DeferredBinding::count());
// Skip repeat bindings
$author->posts()->add($post, $sessionKey);
$this->assertEquals(1, DeferredBinding::count());
// Remove add-delete pairs
$author->posts()->remove($post, $sessionKey);
$this->assertEquals(0, DeferredBinding::count());
// Multi ball
$sessionKey = uniqid('session_key', true);
$author->posts()->add($post, $sessionKey);
$author->posts()->add($post, $sessionKey);
$author->posts()->add($post, $sessionKey);
$author->posts()->add($post, $sessionKey);
$author->posts()->add($post2, $sessionKey);
$author->posts()->add($post2, $sessionKey);
$author->posts()->add($post2, $sessionKey);
$author->posts()->add($post2, $sessionKey);
$author->posts()->add($post2, $sessionKey);
$this->assertEquals(2, DeferredBinding::count());
// Clean up add-delete pairs
$author->posts()->remove($post, $sessionKey);
$author->posts()->remove($post2, $sessionKey);
$this->assertEquals(0, DeferredBinding::count());
// Double negative
$author->posts()->remove($post, $sessionKey);
$author->posts()->remove($post2, $sessionKey);
$this->assertEquals(2, DeferredBinding::count());
// Skip repeat bindings
$author->posts()->remove($post, $sessionKey);
$author->posts()->remove($post2, $sessionKey);
$this->assertEquals(2, DeferredBinding::count());
// Clean up add-delete pairs again
$author->posts()->add($post, $sessionKey);
$author->posts()->add($post2, $sessionKey);
$this->assertEquals(0, DeferredBinding::count());
}
public function testCancelBinding()
{
$sessionKey = uniqid('session_key', true);
DeferredBinding::truncate();
Model::unguard();
$author = Author::make(['name' => 'Stevie']);
$post = Post::create(['title' => "First post"]);
Model::reguard();
$author->posts()->add($post, $sessionKey);
$this->assertEquals(1, DeferredBinding::count());
$author->cancelDeferred($sessionKey);
$this->assertEquals(0, DeferredBinding::count());
}
public function testCommitBinding()
{
$sessionKey = uniqid('session_key', true);
DeferredBinding::truncate();
Model::unguard();
$author = Author::make(['name' => 'Stevie']);
$post = Post::create(['title' => "First post"]);
Model::reguard();
$author->posts()->add($post, $sessionKey);
$this->assertEquals(1, DeferredBinding::count());
$author->commitDeferred($sessionKey);
$this->assertEquals(0, DeferredBinding::count());
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Author;
use Database\Tester\Models\Post;
use Winter\Storm\Database\Collection;
use Model;
class HasManyModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$post1 = Post::create(['title' => "First post", 'description' => "Yay!!"]);
$post2 = Post::create(['title' => "Second post", 'description' => "Woohoo!!"]);
$post3 = Post::create(['title' => "Third post", 'description' => "Yipiee!!"]);
$post4 = Post::make(['title' => "Fourth post", 'description' => "Hooray!!"]);
Model::reguard();
// Set by Model object
$author->posts = new Collection([$post1, $post2]);
$author->save();
$this->assertEquals($author->id, $post1->author_id);
$this->assertEquals($author->id, $post2->author_id);
$this->assertEquals([
'First post',
'Second post'
], $author->posts->lists('title'));
// Set by primary key
$postId = $post3->id;
$author->posts = $postId;
$author->save();
$post3 = Post::find($postId);
$this->assertEquals($author->id, $post3->author_id);
$this->assertEquals([
'Third post'
], $author->posts->lists('title'));
// Nullify
$author->posts = null;
$author->save();
$post3 = Post::find($postId);
$this->assertNull($post3->author_id);
$this->assertNull($post3->author);
// Deferred in memory
$author->posts = $post4;
$this->assertEquals($author->id, $post4->author_id);
$this->assertEquals([
'Fourth post'
], $author->posts->lists('title'));
}
public function testGetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$post1 = Post::create(['title' => "First post", 'author_id' => $author->id]);
$post2 = Post::create(['title' => "Second post", 'author_id' => $author->id]);
Model::reguard();
$this->assertEquals([$post1->id, $post2->id], $author->getRelationValue('posts'));
}
public function testDeferredBinding()
{
$sessionKey = uniqid('session_key', true);
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$post = Post::create(['title' => "First post", 'description' => "Yay!!"]);
Model::reguard();
$postId = $post->id;
// Deferred add
$author->posts()->add($post, $sessionKey);
$this->assertNull($post->author_id);
$this->assertEmpty($author->posts);
$this->assertEquals(0, $author->posts()->count());
$this->assertEquals(1, $author->posts()->withDeferred($sessionKey)->count());
// Commit deferred
$author->save(null, $sessionKey);
$post = Post::find($postId);
$this->assertEquals(1, $author->posts()->count());
$this->assertEquals($author->id, $post->author_id);
$this->assertEquals([
'First post'
], $author->posts->lists('title'));
// New session
$sessionKey = uniqid('session_key', true);
// Deferred remove
$author->posts()->remove($post, $sessionKey);
$this->assertEquals(1, $author->posts()->count());
$this->assertEquals(0, $author->posts()->withDeferred($sessionKey)->count());
$this->assertEquals($author->id, $post->author_id);
$this->assertEquals([
'First post'
], $author->posts->lists('title'));
// Commit deferred
$author->save(null, $sessionKey);
$post = Post::find($postId);
$this->assertEquals(0, $author->posts()->count());
$this->assertNull($post->author_id);
$this->assertEmpty($author->posts);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Author;
use Database\Tester\Models\Country;
use Database\Tester\Models\Post;
use Winter\Storm\Database\Collection;
use Model;
class HasManyThroughModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Country.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testGet()
{
Model::unguard();
$country = Country::create(['name' => 'Australia']);
$author1 = Author::create(['name' => 'Stevie', 'email' => 'stevie@email.tld']);
$author2 = Author::create(['name' => 'Louie', 'email' => 'louie@email.tld']);
$post1 = Post::create(['title' => "First post", 'description' => "Yay!!"]);
$post2 = Post::create(['title' => "Second post", 'description' => "Woohoo!!"]);
$post3 = Post::create(['title' => "Third post", 'description' => "Yipiee!!"]);
$post4 = Post::make(['title' => "Fourth post", 'description' => "Hooray!!"]);
Model::reguard();
// Set data
$author1->country = $country;
$author2->country = $country;
$author1->posts = new Collection([$post1, $post2]);
$author2->posts = new Collection([$post3, $post4]);
$author1->save();
$author2->save();
$country = Country::with([
'posts'
])->find($country->id);
$this->assertEquals([
$post1->id,
$post2->id,
$post3->id,
$post4->id
], $country->posts->pluck('id')->toArray());
}
}

View File

@@ -0,0 +1,138 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Author;
use Database\Tester\Models\Phone;
use Model;
class HasOneModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Phone.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$phone1 = Phone::create(['number' => '0404040404']);
$phone2 = Phone::create(['number' => '0505050505']);
$phone3 = Phone::make(['number' => '0606060606']);
Model::reguard();
// Set by Model object
$author->phone = $phone1;
$author->save();
$this->assertEquals($author->id, $phone1->author_id);
$this->assertEquals('0404040404', $author->phone->number);
// Double check
$phone1 = Phone::find($phone1->id);
$this->assertEquals($author->id, $phone1->author_id);
// Set by primary key
$phoneId = $phone2->id;
$author->phone = $phoneId;
$author->save();
$phone2 = Phone::find($phoneId);
$this->assertEquals($author->id, $phone2->author_id);
$this->assertEquals('0505050505', $author->phone->number);
// Ensure relationship is "stolen" from first model
$phone1 = Phone::find($phone1->id);
$this->assertNotEquals($author->id, $phone1->author_id);
// Nullify
$author->phone = null;
$author->save();
$phone2 = Phone::find($phoneId);
$this->assertNull($phone2->author_id);
$this->assertNull($phone2->author);
// Deferred in memory
$author->phone = $phone3;
$this->assertEquals('0606060606', $author->phone->number);
$this->assertEquals($author->id, $phone3->author_id);
}
public function testSetRelationValueTwice()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$phone = Phone::create(['number' => '0505050505']);
Model::reguard();
$phoneId = $phone->id;
$author->phone = $phoneId;
$author->save();
$author->phone = $phoneId;
$author->save();
$phone = Phone::find($phoneId);
$this->assertEquals($author->id, $phone->author_id);
$this->assertEquals('0505050505', $author->phone->number);
}
public function testGetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$phone = Phone::create(['number' => '0404040404', 'author_id' => $author->id]);
Model::reguard();
$this->assertEquals($phone->id, $author->getRelationValue('phone'));
}
public function testDeferredBinding()
{
$sessionKey = uniqid('session_key', true);
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$phone = Phone::create(['number' => '0404040404']);
Model::reguard();
$phoneId = $phone->id;
// Deferred add
$author->phone()->add($phone, $sessionKey);
$this->assertNull($phone->author_id);
$this->assertNull($author->phone);
$this->assertEquals(0, $author->phone()->count());
$this->assertEquals(1, $author->phone()->withDeferred($sessionKey)->count());
// Commit deferred
$author->save(null, $sessionKey);
$phone = Phone::find($phoneId);
$this->assertEquals(1, $author->phone()->count());
$this->assertEquals($author->id, $phone->author_id);
$this->assertEquals('0404040404', $author->phone->number);
// New session
$sessionKey = uniqid('session_key', true);
// Deferred remove
$author->phone()->remove($phone, $sessionKey);
$this->assertEquals(1, $author->phone()->count());
$this->assertEquals(0, $author->phone()->withDeferred($sessionKey)->count());
$this->assertEquals($author->id, $phone->author_id);
$this->assertEquals('0404040404', $author->phone->number);
// Commit deferred
$author->save(null, $sessionKey);
$phone = Phone::find($phoneId);
$this->assertEquals(0, $author->phone()->count());
$this->assertNull($phone->author_id);
$this->assertNull($author->phone);
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Author;
use Database\Tester\Models\Phone;
use Database\Tester\Models\User;
use Model;
class HasOneThroughModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/User.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Phone.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testGet()
{
Model::unguard();
$phone = Phone::create(['number' => '08 1234 5678']);
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@email.tld']);
$user = User::create(['name' => 'Stevie', 'email' => 'stevie@email.tld']);
Model::reguard();
// Set data
$author->phone = $phone;
$author->user = $user;
$author->save();
$user = User::with([
'phone'
])->find($user->id);
$this->assertEquals($phone->id, $user->phone->id);
}
}

View File

@@ -0,0 +1,174 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Author;
use Database\Tester\Models\Tag;
use Database\Tester\Models\Post;
use Database\Tester\Models\EventLog;
use Winter\Storm\Database\Collection;
use Model;
class MorphManyModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/EventLog.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Tag.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$event1 = EventLog::create(['action' => "user-created"]);
$event2 = EventLog::create(['action' => "user-updated"]);
$event3 = EventLog::create(['action' => "user-deleted"]);
$event4 = EventLog::make(['action' => "user-restored"]);
Model::reguard();
// Set by Model object
$author->event_log = new Collection([$event1, $event2]);
$author->save();
$this->assertEquals($author->id, $event1->related_id);
$this->assertEquals($author->id, $event2->related_id);
$this->assertEquals('Database\Tester\Models\Author', $event1->related_type);
$this->assertEquals('Database\Tester\Models\Author', $event2->related_type);
$this->assertEquals([
'user-created',
'user-updated'
], $author->event_log->lists('action'));
// Set by primary key
$eventId = $event3->id;
$author->event_log = $eventId;
$author->save();
$event3 = EventLog::find($eventId);
$this->assertEquals($author->id, $event3->related_id);
$this->assertEquals('Database\Tester\Models\Author', $event3->related_type);
$this->assertEquals([
'user-deleted'
], $author->event_log->lists('action'));
// Nullify
$author->event_log = null;
$author->save();
$event3 = EventLog::find($eventId);
$this->assertNull($event3->related_type);
$this->assertNull($event3->related_id);
$this->assertNull($event3->related);
// Deferred in memory
$author->event_log = $event4;
$this->assertEquals($author->id, $event4->related_id);
$this->assertEquals('Database\Tester\Models\Author', $event4->related_type);
$this->assertEquals([
'user-restored'
], $author->event_log->lists('action'));
}
public function testGetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$event1 = EventLog::create(['action' => "user-created", 'related_id' => $author->id, 'related_type' => 'Database\Tester\Models\Author']);
$event2 = EventLog::create(['action' => "user-updated", 'related_id' => $author->id, 'related_type' => 'Database\Tester\Models\Author']);
Model::reguard();
$this->assertEquals([$event1->id, $event2->id], $author->getRelationValue('event_log'));
}
public function testDeferredBinding()
{
$sessionKey = uniqid('session_key', true);
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$event = EventLog::create(['action' => "user-created"]);
$post = Post::create(['title' => 'Hello world!']);
$tagForAuthor = Tag::create(['name' => 'ForAuthor']);
$tagForPost = Tag::create(['name' => 'ForPost']);
Model::reguard();
$eventId = $event->id;
// Deferred add
$author->event_log()->add($event, $sessionKey);
$this->assertNull($event->related_id);
$this->assertEmpty($author->event_log);
$this->assertEquals(0, $author->event_log()->count());
$this->assertEquals(1, $author->event_log()->withDeferred($sessionKey)->count());
$author->tags()->add($tagForAuthor, $sessionKey, ['added_by' => 99]);
$this->assertEmpty($author->tags);
$this->assertEquals(0, $author->tags()->count());
$this->assertEquals(1, $author->tags()->withDeferred($sessionKey)->count());
$tagForPost->posts()->add($post, $sessionKey, ['added_by' => 88]);
$this->assertEmpty($tagForPost->posts);
$this->assertEquals(0, $tagForPost->posts()->count());
$this->assertEquals(1, $tagForPost->posts()->withDeferred($sessionKey)->count());
// Commit deferred
$author->save(null, $sessionKey);
$event = EventLog::find($eventId);
$this->assertEquals(1, $author->event_log()->count());
$this->assertEquals($author->id, $event->related_id);
$this->assertEquals([
'user-created'
], $author->event_log->lists('action'));
$this->assertEquals(1, $author->tags()->count());
$this->assertEquals([$tagForAuthor->id], $author->tags->lists('id'));
$this->assertEquals(99, $author->tags->first()->pivot->added_by);
$tagForPost->save(null, $sessionKey);
$this->assertEquals(1, $tagForPost->posts()->count());
$this->assertEquals([$post->id], $tagForPost->posts->lists('id'));
$this->assertEquals(88, $tagForPost->posts->first()->pivot->added_by);
// New session
$sessionKey = uniqid('session_key', true);
// Deferred remove
$author->event_log()->remove($event, $sessionKey);
$this->assertEquals(1, $author->event_log()->count());
$this->assertEquals(0, $author->event_log()->withDeferred($sessionKey)->count());
$this->assertEquals($author->id, $event->related_id);
$this->assertEquals([
'user-created'
], $author->event_log->lists('action'));
$author->tags()->remove($tagForAuthor, $sessionKey);
$this->assertEquals(1, $author->tags()->count());
$this->assertEquals(0, $author->tags()->withDeferred($sessionKey)->count());
$this->assertEquals([$tagForAuthor->id], $author->tags->lists('id'));
$this->assertEquals(99, $author->tags->first()->pivot->added_by);
$tagForPost->posts()->remove($post, $sessionKey);
$this->assertEquals(1, $tagForPost->posts()->count());
$this->assertEquals(0, $tagForPost->posts()->withDeferred($sessionKey)->count());
$this->assertEquals([$post->id], $tagForPost->posts->lists('id'));
$this->assertEquals(88, $tagForPost->posts->first()->pivot->added_by);
// Commit deferred (model is deleted as per definition)
$author->save(null, $sessionKey);
$event = EventLog::find($eventId);
$this->assertEquals(0, $author->event_log()->count());
$this->assertNull($event);
$this->assertEmpty($author->event_log);
$this->assertEmpty(0, $author->tags);
$this->assertEmpty(0, $tagForPost->posts);
}
}

View File

@@ -0,0 +1,192 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Author;
use Database\Tester\Models\Post;
use Database\Tester\Models\Meta;
use Model;
class MorphOneModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Phone.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Meta.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$post = Post::create(['title' => "First post", 'description' => "Yay!!"]);
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$meta1 = Meta::create([
'meta_title' => 'Question',
'meta_description' => 'Industry',
'meta_keywords' => 'major',
'canonical_url' => 'http://google.com/search/jobs',
'redirect_url' => 'http://google.com',
'robot_index' => 'index',
'robot_follow' => 'follow',
]);
$meta2 = Meta::create([
'meta_title' => 'Comment',
'meta_description' => 'Social',
'meta_keywords' => 'startup',
'canonical_url' => 'http://facebook.com/search/users',
'redirect_url' => 'http://facebook.com',
'robot_index' => 'index',
'robot_follow' => 'follow',
]);
$meta3 = Meta::make([
'meta_title' => 'Answer',
'meta_description' => 'Employment',
'meta_keywords' => 'minor',
'canonical_url' => 'http://yahoo.com/search/stats',
'redirect_url' => 'http://yahoo.com',
'robot_index' => 'index',
'robot_follow' => 'follow',
]);
Model::reguard();
// Set by Model object
$post->meta = $meta1;
$post->save();
$this->assertEquals($post->id, $meta1->taggable_id);
$this->assertEquals(get_class($post), $meta1->taggable_type);
$this->assertEquals('Question', $post->meta->meta_title);
// Double check
$meta1 = Meta::find($meta1->id);
$this->assertEquals($post->id, $meta1->taggable_id);
$this->assertEquals(get_class($post), $meta1->taggable_type);
// Set by primary key
$metaId = $meta2->id;
$author->meta = $metaId;
$author->save();
$meta2 = Meta::find($metaId);
$this->assertEquals($author->id, $meta2->taggable_id);
$this->assertEquals(get_class($author), $meta2->taggable_type);
$this->assertEquals('Comment', $author->meta->meta_title);
// Nullify
$author->meta = null;
$author->save();
$meta = Meta::find($metaId);
$this->assertNull($meta->taggable_type);
$this->assertNull($meta->taggable_id);
$this->assertNull($meta->taggable);
// Deferred in memory
$author->meta = $meta3;
$this->assertEquals('Answer', $author->meta->meta_title);
$this->assertEquals($author->id, $meta3->taggable_id);
}
public function testSetRelationValueTwice()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$meta = Meta::create([
'meta_title' => 'Question',
'meta_description' => 'Industry',
'meta_keywords' => 'major',
'canonical_url' => 'http://google.com/search/jobs',
'redirect_url' => 'http://google.com',
'robot_index' => 'index',
'robot_follow' => 'follow',
]);
Model::reguard();
$metaId = $meta->id;
$author->meta = $metaId;
$author->save();
$author->meta = $metaId;
$author->save();
$meta = Meta::find($metaId);
$this->assertEquals($author->id, $meta->taggable_id);
$this->assertEquals(get_class($author), $meta->taggable_type);
}
public function testGetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$meta = Meta::create([
'taggable_id' => $author->id,
'taggable_type' => get_class($author),
'meta_title' => 'Question',
'meta_description' => 'Industry',
'meta_keywords' => 'major',
'canonical_url' => 'http://google.com/search/jobs',
'redirect_url' => 'http://google.com',
'robot_index' => 'index',
'robot_follow' => 'follow',
]);
Model::reguard();
$this->assertEquals($meta->id, $author->getRelationValue('meta'));
}
public function testDeferredBinding()
{
$sessionKey = uniqid('session_key', true);
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$meta = Meta::create([
'meta_title' => 'Comment',
'meta_description' => 'Social',
'meta_keywords' => 'startup',
'canonical_url' => 'http://facebook.com/search/users',
'redirect_url' => 'http://facebook.com',
'robot_index' => 'index',
'robot_follow' => 'follow',
]);
Model::reguard();
$metaId = $meta->id;
// Deferred add
$author->meta()->add($meta, $sessionKey);
$this->assertNull($meta->taggable_id);
$this->assertNull($author->meta);
$this->assertEquals(0, $author->meta()->count());
$this->assertEquals(1, $author->meta()->withDeferred($sessionKey)->count());
// Commit deferred
$author->save(null, $sessionKey);
$meta = Meta::find($metaId);
$this->assertEquals(1, $author->meta()->count());
$this->assertEquals($author->id, $meta->taggable_id);
$this->assertEquals('Comment', $author->meta->meta_title);
// New session
$sessionKey = uniqid('session_key', true);
// Deferred remove
$author->meta()->remove($meta, $sessionKey);
$this->assertEquals(1, $author->meta()->count());
$this->assertEquals(0, $author->meta()->withDeferred($sessionKey)->count());
$this->assertEquals($author->id, $meta->taggable_id);
$this->assertEquals('Comment', $author->meta->meta_title);
// Commit deferred
$author->save(null, $sessionKey);
$meta = Meta::find($metaId);
$this->assertEquals(0, $author->meta()->count());
$this->assertNull($meta->taggable_id);
$this->assertNull($author->meta);
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Post;
use Database\Tester\Models\Author;
use Database\Tester\Models\EventLog;
use Model;
class MorphToModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/EventLog.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testSetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$post1 = Post::create(['title' => "First post", 'description' => "Yay!!"]);
$post2 = Post::make(['title' => "Second post", 'description' => "Woohoo!!"]);
$event = EventLog::create(['action' => "user-created"]);
Model::reguard();
// Set by Model object
$event->related = $author;
$event->save();
$this->assertEquals($author->id, $event->related_id);
$this->assertEquals('Stevie', $event->related->name);
// Set by primary key
$event->related = [$post1->id, get_class($post1)];
$this->assertEquals($post1->id, $event->related_id);
$this->assertEquals('First post', $event->related->title);
// Nullify
$event->related = null;
$this->assertNull($event->related_id);
$this->assertNull($event->related);
// Deferred in memory
$event->related = $post2;
$this->assertEquals('Second post', $event->related->title);
$this->assertNull($event->related_id);
$event->save();
$this->assertEquals($post2->id, $event->related_id);
}
public function testGetRelationValue()
{
Model::unguard();
$author = Author::create(['name' => 'Stevie']);
$event = EventLog::make(['action' => "user-created", 'related_id' => $author->id, 'related_type' => get_class($author)]);
Model::reguard();
$this->assertEquals([$author->id, get_class($author)], $event->getRelationValue('related'));
}
}

View File

@@ -0,0 +1,158 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\CategoryNested;
use Model;
class NestedTreeModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Category.php';
$this->runPluginRefreshCommand('Database.Tester');
$this->seedSampleTree();
}
public function testGetNested()
{
$items = CategoryNested::getNested();
// Eager loaded
$items->each(function ($item) {
$this->assertTrue($item->relationLoaded('children'));
});
$this->assertEquals(2, $items->count());
}
public function testGetAllRoot()
{
$items = CategoryNested::getAllRoot();
// Not eager loaded
$items->each(function ($item) {
$this->assertFalse($item->relationLoaded('children'));
});
$this->assertEquals(2, $items->count());
}
public function testListsNested()
{
$array = CategoryNested::listsNested('name', 'id');
$this->assertEquals([
1 => 'Category Orange',
2 => '&nbsp;&nbsp;&nbsp;Autumn Leaves',
3 => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;September',
4 => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;October',
5 => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;November',
6 => '&nbsp;&nbsp;&nbsp;Summer Breeze',
7 => 'Category Green',
8 => '&nbsp;&nbsp;&nbsp;Winter Snow',
9 => '&nbsp;&nbsp;&nbsp;Spring Trees'
], $array);
CategoryNested::flushDuplicateCache();
$array = CategoryNested::listsNested('name', 'id', '--');
$this->assertEquals([
1 => 'Category Orange',
2 => '--Autumn Leaves',
3 => '----September',
4 => '----October',
5 => '----November',
6 => '--Summer Breeze',
7 => 'Category Green',
8 => '--Winter Snow',
9 => '--Spring Trees'
], $array);
CategoryNested::flushDuplicateCache();
$array = CategoryNested::listsNested('description', 'name', '**');
$this->assertEquals([
'Category Orange' => 'A root level test category',
'Autumn Leaves' => '**Disccusion about the season of falling leaves.',
'September' => '****The start of the fall season.',
'October' => '****The middle of the fall season.',
'November' => '****The end of the fall season.',
'Summer Breeze' => '**Disccusion about the wind at the ocean.',
'Category Green' => 'A root level test category',
'Winter Snow' => '**Disccusion about the frosty snow flakes.',
'Spring Trees' => '**Disccusion about the blooming gardens.'
], $array);
}
public function testListsNestedFromCollection()
{
$array = CategoryNested::get()->listsNested('custom_name', 'id', '...');
$this->assertEquals([
1 => 'Category Orange (#1)',
2 => '...Autumn Leaves (#2)',
3 => '......September (#3)',
4 => '......October (#4)',
5 => '......November (#5)',
6 => '...Summer Breeze (#6)',
7 => 'Category Green (#7)',
8 => '...Winter Snow (#8)',
9 => '...Spring Trees (#9)'
], $array);
}
public function seedSampleTree()
{
Model::unguard();
$orange = CategoryNested::create([
'name' => 'Category Orange',
'description' => 'A root level test category',
]);
$autumn = $orange->children()->create([
'name' => 'Autumn Leaves',
'description' => 'Disccusion about the season of falling leaves.'
]);
$autumn->children()->create([
'name' => 'September',
'description' => 'The start of the fall season.'
]);
$autumn->children()->create([
'name' => 'October',
'description' => 'The middle of the fall season.'
]);
$autumn->children()->create([
'name' => 'November',
'description' => 'The end of the fall season.'
]);
$orange->children()->create([
'name' => 'Summer Breeze',
'description' => 'Disccusion about the wind at the ocean.'
]);
$green = CategoryNested::create([
'name' => 'Category Green',
'description' => 'A root level test category',
]);
$green->children()->create([
'name' => 'Winter Snow',
'description' => 'Disccusion about the frosty snow flakes.'
]);
$green->children()->create([
'name' => 'Spring Trees',
'description' => 'Disccusion about the blooming gardens.'
]);
Model::reguard();
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\NullablePost;
class NullableModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testNullifyingFields()
{
// Save as SQL default
$post = NullablePost::create(['author_nickname' => ''])->reload();
$this->assertEquals('Winter', $post->author_nickname);
// Save as empty string
$post->author_nickname = '';
$post->save();
$this->assertNull($post->author_nickname);
}
public function testNonEmptyValuesAreIgnored()
{
// Save as value
$post = NullablePost::create(['author_nickname' => 'Joe']);
$this->assertEquals('Joe', $post->author_nickname);
// Save as zero integer
$post->author_nickname = 0;
$post->save();
$this->assertNotNull($post->author_nickname);
$this->assertEquals(0, $post->author_nickname);
// Save as zero float
$post->author_nickname = 0.0;
$post->save();
$this->assertNotNull($post->author_nickname);
$this->assertEquals(0.0, $post->author_nickname);
// Save as zero string
$post->author_nickname = '0';
$post->save();
$this->assertNotNull($post->author_nickname);
$this->assertEquals('0', $post->author_nickname);
// Save as false
$post->author_nickname = false;
$post->save();
$this->assertNotNull($post->author_nickname);
$this->assertEquals(false, $post->author_nickname);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\Post;
class PluginModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testCreateFirstPost()
{
Post::truncate();
$post = new Post;
$post->title = "First post";
$post->description = "Yay!!";
$post->save();
$this->assertEquals(1, $post->id);
}
public function testGuardedAttribute()
{
$this->expectException(\Illuminate\Database\Eloquent\MassAssignmentException::class);
$this->expectExceptionMessageMatches('/title/');
Post::create(['title' => 'Hi!', 'slug' => 'authenticity']);
}
}

View File

@@ -0,0 +1,145 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Carbon\Carbon;
use Database\Tester\Models\RevisionablePost;
use DateTime;
class RevisionableModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testUpdateNothing()
{
$post = RevisionablePost::create(['title' => 'Hello World!']);
$this->assertEquals('Hello World!', $post->title);
$this->assertEquals(0, $post->revision_history()->count());
$post->revisionsEnabled = false;
$post->title = 'Helloooooooooooo!';
$post->save();
$this->assertEquals(0, $post->revision_history()->count());
}
public function testUpdateSingleField()
{
$post = RevisionablePost::create(['title' => 'Hello World!']);
$this->assertEquals('Hello World!', $post->title);
$this->assertEquals(0, $post->revision_history()->count());
$post->title = 'Helloooooooooooo!';
$post->save();
$this->assertEquals(1, $post->revision_history()->count());
$item = $post->revision_history()->first();
$this->assertEquals('title', $item->field);
$this->assertEquals('Hello World!', $item->old_value);
$this->assertEquals('Helloooooooooooo!', $item->new_value);
$this->assertEquals(7, $item->user_id);
}
public function testUpdateMultipleFields()
{
$post = RevisionablePost::create([
'title' => 'Hello World!',
'slug' => 'hello-world',
'description' => 'Good day, Commander',
'is_published' => true,
'published_at' => new DateTime
]);
$this->assertEquals(0, $post->revision_history()->count());
$post->title = "Gday mate";
$post->slug = "gday-mate";
$post->description = 'Wazzaaaaaaaaaaaaap';
$post->is_published = false;
$post->published_at = Carbon::now()->addDays(1);
$post->save();
$history = $post->revision_history;
$this->assertEquals(5, $history->count());
$this->assertEquals([
'title',
'slug',
'description',
'is_published',
'published_at'
], $history->lists('field'));
}
public function testExceedingRevisionLimit()
{
$post = RevisionablePost::create([
'title' => 'Hello World!',
'slug' => 'hello-world',
'description' => 'Good day, Commander',
'is_published' => true,
'published_at' => new DateTime
]);
$this->assertEquals(0, $post->revision_history()->count());
$post->title = "Gday mate";
$post->slug = "gday-mate";
$post->description = 'Wazzaaaaaaaaaaaaap';
$post->is_published = false;
$post->published_at = Carbon::now()->addDays(1);
$post->save();
$post->title = 'The Boss';
$post->slug = 'the-boss';
$post->description = 'Paid the cost to be the boss';
$post->is_published = true;
$post->published_at = Carbon::now()->addDays(10);
$post->save();
// Count 10 changes above, limit is 8
$this->assertEquals(8, $post->revision_history()->count());
}
public function testSoftDeletes()
{
$post = RevisionablePost::create(['title' => 'Hello World!']);
$this->assertEquals('Hello World!', $post->title);
$this->assertEquals(0, $post->revision_history()->count());
$post->title = 'Helloooooooooooo!';
$post->save();
$this->assertEquals(1, $post->revision_history()->count());
$post->delete();
$this->assertEquals(2, $post->revision_history()->count());
}
public function testRevisionDateCast()
{
$post = RevisionablePost::create([
'title' => 'Hello World!',
'published_at' => Carbon::now()
]);
$this->assertEquals(0, $post->revision_history()->count());
$post->published_at = Carbon::now()->addDays(1);
$post->save();
$this->assertEquals(1, $post->revision_history()->count());
$item = $post->revision_history()->first();
$this->assertEquals('published_at', $item->field);
$this->assertEquals('date', $item->cast);
$this->assertInstanceOf('Carbon\Carbon', $item->old_value);
$this->assertInstanceOf('Carbon\Carbon', $item->new_value);
}
}

View File

@@ -0,0 +1,245 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Carbon\Carbon;
use Database\Tester\Models\CategorySimple;
use Model;
class SimpleTreeModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Category.php';
$this->runPluginRefreshCommand('Database.Tester');
$this->seedSampleTree();
}
public function testGetNested()
{
$items = CategorySimple::getNested();
// Eager loaded
$items->each(function ($item) {
$this->assertTrue($item->relationLoaded('children'));
});
$this->assertEquals(3, $items->count());
}
public function testGetAllRoot()
{
$items = CategorySimple::getAllRoot();
// Not eager loaded
$items->each(function ($item) {
$this->assertFalse($item->relationLoaded('children'));
});
$this->assertEquals(3, $items->count());
}
public function testGetChildren()
{
// Not eager loaded
$item = CategorySimple::first();
$this->assertFalse($item->relationLoaded('children'));
$this->assertEquals(6, $item->getChildren()->count());
// Not eager loaded
$item = CategorySimple::getAllRoot()->first();
$this->assertFalse($item->relationLoaded('children'));
$this->assertEquals(6, $item->getChildren()->count());
// Eager loaded
$item = CategorySimple::getNested()->first();
$this->assertTrue($item->relationLoaded('children'));
$this->assertEquals(6, $item->getChildren()->count());
}
public function testGetChildCount()
{
// Not eager loaded
$item = CategorySimple::first();
$this->assertFalse($item->relationLoaded('children'));
$this->assertEquals(9, $item->getChildCount());
// Not eager loaded
$item = CategorySimple::getAllRoot()->first();
$this->assertFalse($item->relationLoaded('children'));
$this->assertEquals(9, $item->getChildCount());
// Eager loaded
$item = CategorySimple::getNested()->first();
$this->assertTrue($item->relationLoaded('children'));
$this->assertEquals(9, $item->getChildCount());
}
public function testGetAllChildren()
{
// Not eager loaded
$item = CategorySimple::first();
$this->assertFalse($item->relationLoaded('children'));
$this->assertEquals(9, $item->getAllChildren()->count());
// Not eager loaded
$item = CategorySimple::getAllRoot()->first();
$this->assertFalse($item->relationLoaded('children'));
$this->assertEquals(9, $item->getAllChildren()->count());
// Eager loaded
$item = CategorySimple::getNested()->first();
$this->assertTrue($item->relationLoaded('children'));
$this->assertEquals(9, $item->getAllChildren()->count());
}
public function testListsNested()
{
$array = CategorySimple::listsNested('name', 'id');
$this->assertEquals([
1 => 'Web development',
2 => '&nbsp;&nbsp;&nbsp;HTML5',
3 => '&nbsp;&nbsp;&nbsp;CSS3',
4 => '&nbsp;&nbsp;&nbsp;jQuery',
5 => '&nbsp;&nbsp;&nbsp;Bootstrap',
6 => '&nbsp;&nbsp;&nbsp;Laravel',
7 => '&nbsp;&nbsp;&nbsp;Winter CMS',
8 => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;September',
9 => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;October',
10 => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;November',
11 => 'Mobile development',
12 => '&nbsp;&nbsp;&nbsp;iOS',
13 => '&nbsp;&nbsp;&nbsp;iPhone',
14 => '&nbsp;&nbsp;&nbsp;iPad',
15 => '&nbsp;&nbsp;&nbsp;Android',
16 => 'Graphic design',
17 => '&nbsp;&nbsp;&nbsp;Photoshop',
18 => '&nbsp;&nbsp;&nbsp;Illustrator',
19 => '&nbsp;&nbsp;&nbsp;Fireworks'
], $array);
$array = CategorySimple::listsNested('name', 'id', '--');
$this->assertEquals([
1 => 'Web development',
2 => '--HTML5',
3 => '--CSS3',
4 => '--jQuery',
5 => '--Bootstrap',
6 => '--Laravel',
7 => '--Winter CMS',
8 => '----September',
9 => '----October',
10 => '----November',
11 => 'Mobile development',
12 => '--iOS',
13 => '--iPhone',
14 => '--iPad',
15 => '--Android',
16 => 'Graphic design',
17 => '--Photoshop',
18 => '--Illustrator',
19 => '--Fireworks'
], $array);
$array = CategorySimple::listsNested('id', 'name', '**');
$this->assertEquals([
'Web development' => '1',
'HTML5' => '**2',
'CSS3' => '**3',
'jQuery' => '**4',
'Bootstrap' => '**5',
'Laravel' => '**6',
'Winter CMS' => '**7',
'September' => '****8',
'October' => '****9',
'November' => '****10',
'Mobile development' => '11',
'iOS' => '**12',
'iPhone' => '**13',
'iPad' => '**14',
'Android' => '**15',
'Graphic design' => '16',
'Photoshop' => '**17',
'Illustrator' => '**18',
'Fireworks' => '**19'
], $array);
}
public function testListsNestedUnknownColumn()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage('Column mismatch in listsNested method');
CategorySimple::listsNested('custom_name', 'id');
}
public function testListsNestedFromCollection()
{
$array = CategorySimple::get()->listsNested('custom_name', 'id', '...');
$this->assertEquals([
1 => 'Web development (#1)',
2 => '...HTML5 (#2)',
3 => '...CSS3 (#3)',
4 => '...jQuery (#4)',
5 => '...Bootstrap (#5)',
6 => '...Laravel (#6)',
7 => '...Winter CMS (#7)',
8 => '......September (#8)',
9 => '......October (#9)',
10 => '......November (#10)',
11 => 'Mobile development (#11)',
12 => '...iOS (#12)',
13 => '...iPhone (#13)',
14 => '...iPad (#14)',
15 => '...Android (#15)',
16 => 'Graphic design (#16)',
17 => '...Photoshop (#17)',
18 => '...Illustrator (#18)',
19 => '...Fireworks (#19)'
], $array);
}
public function seedSampleTree()
{
Model::unguard();
$webdev = CategorySimple::create([
'name' => 'Web development'
]);
$webdev->children()->create(['name' => 'HTML5']);
$webdev->children()->create(['name' => 'CSS3']);
$webdev->children()->create(['name' => 'jQuery']);
$webdev->children()->create(['name' => 'Bootstrap']);
$webdev->children()->create(['name' => 'Laravel']);
$winter = $webdev->children()->create(['name' => 'Winter CMS']);
$winter->children()->create(['name' => 'September']);
$winter->children()->create(['name' => 'October']);
$winter->children()->create(['name' => 'November']);
$mobdev = CategorySimple::create([
'name' => 'Mobile development'
]);
$mobdev->children()->create(['name' => 'iOS']);
$mobdev->children()->create(['name' => 'iPhone']);
$mobdev->children()->create(['name' => 'iPad']);
$mobdev->children()->create(['name' => 'Android']);
$design = CategorySimple::create([
'name' => 'Graphic design'
]);
$design->children()->create(['name' => 'Photoshop']);
$design->children()->create(['name' => 'Illustrator']);
$design->children()->create(['name' => 'Fireworks']);
Model::reguard();
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\SluggablePost;
class SluggableModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testFillPost()
{
$post = SluggablePost::create(['title' => 'Hello World!']);
$this->assertEquals('hello-world', $post->slug);
}
public function testSetAttributeOnPost()
{
$post = new SluggablePost;
$post->title = "Let's go, rock show!";
$post->save();
$this->assertEquals('lets-go-rock-show', $post->slug);
}
public function testSetSlugAttributeManually()
{
$post = new SluggablePost;
$post->title = 'We parked in a comfortable spot';
$post->slug = 'war-is-pain';
$post->save();
$this->assertEquals('war-is-pain', $post->slug);
}
public function testConcatenatedSlug()
{
$post = new SluggablePost;
$post->title = 'Sweetness and Light';
$post->description = 'Itchee and Scratchee';
$post->save();
$this->assertEquals('sweetness-and-light-itchee-and-scratchee', $post->long_slug);
}
public function testDuplicateSlug()
{
$post1 = SluggablePost::create(['title' => 'Pace yourself']);
$post2 = SluggablePost::create(['title' => 'Pace yourself']);
$post3 = SluggablePost::create(['title' => 'Pace yourself']);
$this->assertEquals('pace-yourself', $post1->slug);
$this->assertEquals('pace-yourself-2', $post2->slug);
$this->assertEquals('pace-yourself-3', $post3->slug);
}
public function testCollisionWithSelf()
{
$post1 = SluggablePost::create(['title' => 'Watch yourself']);
$post2 = SluggablePost::create(['title' => 'Watch yourself']);
$post3 = SluggablePost::create(['title' => 'Watch yourself']);
$this->assertEquals('watch-yourself', $post1->slug);
$this->assertEquals('watch-yourself-2', $post2->slug);
$this->assertEquals('watch-yourself-3', $post3->slug);
$post3->slugAttributes();
$post3->save();
$post2->slugAttributes();
$post2->save();
$post1->slugAttributes();
$post1->save();
$this->assertEquals('watch-yourself', $post1->slug);
$this->assertEquals('watch-yourself-2', $post2->slug);
$this->assertEquals('watch-yourself-3', $post3->slug);
}
public function testSuffixCollision()
{
$post1 = SluggablePost::create(['title' => 'Type 1']);
$post2 = SluggablePost::create(['title' => 'Type 2']);
$post3 = SluggablePost::create(['title' => 'Type 3']);
$post4 = SluggablePost::create(['title' => 'Type 3']);
$post5 = SluggablePost::create(['title' => 'Type 3']);
$this->assertEquals('type-1', $post1->slug);
$this->assertEquals('type-2', $post2->slug);
$this->assertEquals('type-3', $post3->slug);
$this->assertEquals('type-3-2', $post4->slug);
$this->assertEquals('type-3-3', $post5->slug);
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\User;
use Database\Tester\Models\Author;
use Database\Tester\Models\UserWithAuthor;
use Database\Tester\Models\SoftDeleteAuthor;
use Database\Tester\Models\UserWithSoftAuthor;
use Database\Tester\Models\UserWithAuthorAndSoftDelete;
use Database\Tester\Models\UserWithSoftAuthorAndSoftDelete;
use Model;
class SoftDeleteModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/User.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Author.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testDeleteOptionOnHardModel()
{
Model::unguard();
$user = UserWithAuthor::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$author = Author::create(['name' => 'Louie', 'email' => 'louie@example.com', 'user_id' => $user->id]);
Model::reguard();
$authorId = $author->id;
$user->delete(); // Hard
$this->assertNull(Author::find($authorId));
}
public function testSoftDeleteOptionOnHardModel()
{
Model::unguard();
$user = UserWithSoftAuthor::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$author = Author::create(['name' => 'Louie', 'email' => 'louie@example.com', 'user_id' => $user->id]);
Model::reguard();
$authorId = $author->id;
$user->delete(); // Hard
$this->assertNotNull(Author::find($authorId)); // Do nothing
}
public function testSoftDeleteOptionOnSoftModel()
{
Model::unguard();
$user = UserWithSoftAuthorAndSoftDelete::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$author = SoftDeleteAuthor::create(['name' => 'Louie', 'email' => 'louie@example.com', 'user_id' => $user->id]);
Model::reguard();
$authorId = $author->id;
$user->delete(); // Soft
$this->assertNull(SoftDeleteAuthor::find($authorId));
$this->assertNotNull(SoftDeleteAuthor::withTrashed()->find($authorId));
}
public function testDeleteOptionOnSoftModel()
{
Model::unguard();
$user = UserWithAuthorAndSoftDelete::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$author = Author::create(['name' => 'Louie', 'email' => 'louie@example.com', 'user_id' => $user->id]);
Model::reguard();
$authorId = $author->id;
$user->delete(); // Soft
$this->assertNotNull(Author::find($authorId)); // Do nothing
$userId = $user->id;
$user = UserWithAuthorAndSoftDelete::withTrashed()->find($userId);
$user->restore();
$user->forceDelete(); // Hard
$this->assertNull(Author::find($authorId));
}
public function testRestoreSoftDeleteRelation()
{
Model::unguard();
$user = UserWithSoftAuthorAndSoftDelete::create(['name' => 'Stevie', 'email' => 'stevie@example.com']);
$author = SoftDeleteAuthor::create(['name' => 'Louie', 'email' => 'louie@example.com', 'user_id' => $user->id]);
Model::reguard();
$authorId = $author->id;
$user->delete(); // Soft
$this->assertNull(SoftDeleteAuthor::find($authorId));
$this->assertNotNull(SoftDeleteAuthor::withTrashed()->find($authorId));
$userId = $user->id;
$user = UserWithSoftAuthorAndSoftDelete::withTrashed()->find($userId);
$user->restore();
$this->assertNotNull(SoftDeleteAuthor::find($authorId));
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace System\Tests\Plugins\Database;
use System\Tests\Bootstrap\PluginTestCase;
use Database\Tester\Models\ValidationPost;
class ValidationModelTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/database/tester/models/Post.php';
$this->runPluginRefreshCommand('Database.Tester');
}
public function testUniqueTableValidation()
{
$this->expectException(\Winter\Storm\Database\ModelException::class);
$post = ValidationPost::create([
'title' => 'This is a new post',
'slug' => 'post-1',
'description' => 'Testing...'
]);
$this->assertNotFalse($post);
$post2 = ValidationPost::create([
'title' => 'this is another post with the same slug',
'slug' => 'post-1',
'description' => 'testing....'
]);
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace System\Tests\Plugins\System;
use System\Tests\Bootstrap\PluginTestCase;
use Validator;
class CustomValidatorRulesTest extends PluginTestCase
{
public function setUp() : void
{
parent::setUp();
include_once base_path() . '/modules/system/tests/fixtures/plugins/winter/tester/rules/BeLikeBobRule.php';
include_once base_path() . '/modules/system/tests/fixtures/plugins/winter/tester/Plugin.php';
$this->runPluginRefreshCommand('Winter.Tester');
}
public function testValidationUsingClosure()
{
$validData = [
'company' => 'ACME'
];
$invalidData = [
'company' => 'Acme'
];
$rules = [
'company' => 'uppercase'
];
$validationWithValidData = Validator::make($validData, $rules);
$validationWithInvalidData = Validator::make($invalidData, $rules);
$this->assertFalse($validationWithValidData->fails());
$this->assertTrue($validationWithInvalidData->fails());
}
public function testValidationUsingRuleObject()
{
$validData = [
'name' => 'bob'
];
$invalidData = [
'name' => 'karen'
];
$rules = [
'name' => 'be_like_bob'
];
$validationWithValidData = Validator::make($validData, $rules);
$validationWithInvalidData = Validator::make($invalidData, $rules);
$this->assertFalse($validationWithValidData->fails());
$this->assertTrue($validationWithInvalidData->fails());
$this->assertEquals($validationWithInvalidData->errors()->first(), 'You must be like bob');
}
}