<?php

namespace Tests\Unit;

use App\Models\Role;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Arr;

trait PermissionsTestTrait
{
    public function test_a_page_has_many_permissions()
    {
        $page = $this->getModel();
        $role = Role::factory()->create();

        $page->createPermission('update', $role);

        $this->assertInstanceOf(Collection::class, $page->permissions()->get());
    }

    public function test_a_page_can_grant_access_to_a_role()
    {
        $page = $this->getModel();
        $role = Role::factory()->create();

        $page->createPermission('update', $role);

        $this->assertTrue($role->canPerformAction('update', $page));
    }

    public function test_a_page_can_grant_access_to_a_user()
    {
        $page = $this->getModel();
        $user = User::factory()->create();

        $page->createPermission('update', $user);

        $this->assertTrue($user->can('update', $page));
    }

    public function test_a_page_has_an_actions_attribute()
    {
        $page = $this->getModel();

        $user = User::factory()->create();
        $role = Role::factory()->create();

        $user->addRole($role);

        $user->refresh();

        $this->assertNotNull($page->actions);
        $this->assertFalse($page->actions->has('view'));

        $page->createPermission('view', $user);

        $this->assertFalse($page->actions->has('view'));

        $this->signIn($user);
        $this->assertTrue($page->actions->has('view'));

        $role = Role::factory()->create();
        $user->addRole($role);
        $user->refresh();

        $page->createPermission('update', $role);
        $role->refresh();
        $page->refresh();
        $this->assertTrue($page->actions->has('update'));

        $actions = $page->actions;
        $this->assertInstanceOf(Collection::class, $actions);

        $actions_array = $actions->toArray();

        $this->assertTrue(is_bool(Arr::get($actions_array, 'view')));
        $this->assertEquals(true, Arr::get($actions_array, 'view'));
        $this->assertTrue(is_bool(Arr::get($actions_array, 'update')));
        $this->assertEquals(true, Arr::get($actions_array, 'update'));
    }

    public function test_an_object_with_permissions_has_an_attribute_boolean()
    {
        $object = $this->getModel();
        $user = User::factory()->create();
        $object->createPermission('view', $user);
        $object->refresh();
        $user->refresh();

        $this->assertNotNull($object->has_permissions);

        $data = collect($object->append('has_permissions')->toArray());
        $this->assertTrue($data->contains('has_permissions'));
    }
}
