<?php
/**
 * Copyright 2016 David Vivier on behalf of Smartic.ca
 * 
 * This file is part of the Smarticops Package
 * 
 * License : MIT
 * 
 * @author David Vivier
 */

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

use Dvivier\Smarticops\Role;
use Dvivier\Smarticops\User;
use Dvivier\Smarticops\Permission;

class RolesControllerTest extends TestCase
{
    use DatabaseMigrations;
    
    public function setup() {
        
        
        parent::setup();
        
        $this->seed();
        $admin = User::find(1);
        Auth::login($admin);
        Auth::user()->loadPermissions();
        
        $this->roleStudent = factory(Role::class)->create([
                                                'name' => 'Student',
                                                        ]);
        
        $this->roleTeacher = factory(Role::class)->create([
                                                'name' => 'Teacher',
                                                        ]);
        
        $this->permission = new Permission();
        $this->permission->code = 'world.destroy';
        $this->permission->description = 'Destroy World';
        $this->permission->save();
        
        $this->permission = new Permission();
        $this->permission->code = 'world.dominate';
        $this->permission->save();
        
        $this->permission = new Permission();
        $this->permission->code = 'world.create';
        $this->permission->save();
        
    }
    
    public function testIndex() {
        
        $this->visit('/roles')
              ->see('Student')
              ->see('Teacher');
        $this->assertResponseOk();
        
        Role::withTrashed()->delete();
        $this->visit('/roles')
              ->see('No roles found.')
              ->dontSee('Teacher')
              ->dontSee('Student');
        
    }
    
    public function testCreate() {
        
    /// test with valid data : a role is created
        $this->visit('/roles/create')
              ->see('Create Role')
              ->type('Master', 'name')
              ->type('Master of the Universe', 'description')
              ->check('codes[0]')
              ->check('codes[1]')
              ->press('Create')
              ->seePageIs('roles')
              ->see('Master')
              ->see('The role Master has been created.');
              
              
        $role = Role::byName('Master');
        
        $this->assertTrue($role->hasPermission('world.destroy'));
        $this->assertTrue($role->hasPermission('world.dominate'));
        $this->assertFalse($role->hasPermission('world.create'));
        
        $this->assertEquals('Master of the Universe', $role->description);
                
        
    /// tests with invalid data
    
        // name already exists 
        $this->visit('roles/create')
             ->see('Create Role')
             ->type('Master', 'name')
             ->type('Another master of the Universe', 'description')
             ->press('Create')
             ->seePageIs('roles/create')  // we see the same page, because the name is not valid
             ->see('This name is already used.');

        // data not provided
        $this->visit('roles/create')
              ->see('Create Role')
              ->press('Create')
              ->seePageIs('roles/create')
              ->see('The "name" field is required.');
              //->see('The "description" field is required.');
    }
    
    public function testEdit() {
        // similar to create
        
    /// test normal procedure
        $roleStudent = $this->roleStudent;
        // permission which will be unchecked for the test
        $roleStudent->givePermission('world.dominate');
        $this->assertFalse($roleStudent->hasPermission('world.destroy'));
        $this->assertTrue($roleStudent->hasPermission('world.dominate'));
        
        $this->visit('roles/edit/1')
              ->see('Edit Role')
              ->see('Student') // existing value
              ->type('another description', 'description')
              ->check('codes[0]') // world.destroy
              ->uncheck('codes[1]') // world.dominate
              ->press('Save')
              ->seePageIs('roles')
              ->see('another description');
        
        $roleStudent = Role::byName('Student');
        
        $this->assertTrue($roleStudent->hasPermission('world.destroy'));
        $this->assertFalse($roleStudent->hasPermission('world.dominate'));
        $this->assertEquals('another description', $roleStudent->description);
        
    // test with duplicate name
        $this->visit('roles/edit/2')
              ->see('Edit Role')
              ->see('Teacher')
              // "Student" is the name of role #1
              ->type('Student', 'name')
              ->press('Save')
              ->seePageIs('roles/edit/2')
              ->see('This name is already used.');
    }
    
    public function testDelete() {
        
        $this->visit('roles/delete/1')
              ->see('The role Student has been deleted.')
              // check soft delete
              ->seeInDatabase( 'roles', [
                                        'name' => 'Student',
                                        ])
              ->notSeeInDatabase( 'roles', [
                                    'name' => 'Student',
                                    'deleted_at' => null,
                                    ]);
    }
}

