<?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\User;
use Dvivier\Smarticops\Role;
use Dvivier\Smarticops\Permission;

class UsersControllerTest extends TestCase
{
    
    // uses migrations to to rollback after each test, and migrate before each test.
    use DatabaseMigrations;
    
    /**
     * 
     * Setup
     */
    public function setup() {
        
        parent::setup();
        $this->seed();
        $admin = User::find(1);
        Auth::login($admin);
        Auth::user()->loadPermissions();
        //var_dump(Auth::user()->hasPermission('sa'));
        $this->userKubrick = factory(User::class)->create([
                                            'first_name' => 'Stanley',
                                            'last_name'  => 'Kubrick',
                                            'email'      => 's.kubrick@example.com',
                                            ]);
                                            
        $this->userBowman = factory(User::class)->create([
                                                    'first_name' => 'Dave',
                                                    'last_name'  => 'Bowman',
                                                    'email'      => 'd.bowman@example.com'
                                                    ]);
        
        $this->roleStudent = factory(Role::class)->create([
                                                'name' => 'Student',
                                                        ]);
        
        $this->roleTeacher = factory(Role::class)->create([
                                                'name' => 'Teacher',
                                                        ]);
                                                        
        $this->roleTeacher = factory(Role::class)->create([
                                                'name' => 'Admin',
                                                        ]);
        
        
        $perm1 = new Permission();
        $perm1->code = 'world.create';
        $perm1->description = 'Create the world';
        $perm1->save();
        
        $perm2 = new Permission();
        $perm2->code = 'world.dominate';
        $perm2->description = 'Dominate the world';
        $perm2->save();
        
        $perm3 = new Permission();
        $perm3->code = 'world.destroy';
        $perm3->description = 'Destroy the world';
        $perm3->save();
        

        //var_dump(Auth::user()->hasPermission('admin'));
        //Auth::user()->loadPermissions();
        //return Session::all();
    }
    
    
    
    public function testIndex() {
        //Session::set('func', 'testIndex()');
        $this->visit('users')
                ->see('List of Users')
                ->see('Stanley Kubrick')
                ->see('Dave Bowman');   
        
        $this->assertResponseOk();
        
        User::withTrashed()->delete();
        
        $this->visit('users')
            ->see('No users found.');
        
    }
    
    
    public function testCreate() {
        //var_dump(Auth::user()->hasPermission('admin'));
        $this->roleStudent->givePermission('world.dominate');
        //Session::set('func', 'testCreate()');
        Auth::user()->loadPermissions();
        $this->visit('users/create')
                ->type('Hal', 'first_name')
                ->type('9000', 'last_name')
                ->type('hal.9000@example.com', 'email')
                
                // roles
                ->check('roles[0]')  // Student
                ->check('roles[1]')  // Teacher
                
                // permissions
                ->check('codes[0]')  // world.create
                ->check('codes[1]')  // world.dominate

                ->press('Create')
                ->seePageIs('users')
                ->see('The user Hal 9000 has been created.');
        //foreach(User::all() as $user) var_dump($user->first_name);
        $user = User::find(4);
        $this->assertEquals('Hal 9000', $user->fullName());
        
        $this->assertTrue($user->is('Student'));
        $this->assertTrue($user->is('Teacher'));
        $this->assertFalse($user->is('Admin'));
        
        //$user->loadPermissions();
        //foreach($user->fresh()->permissions as $p) var_dump($p->code);
        $this->assertTrue($user->hasPermission('world.create', true));   
        $this->assertTrue($user->hasPermission('world.dominate', true)); 
        $this->assertFalse($user->hasPermission('world.destroy', true)); 
        
        
        //Session::set('func', 'testCreate()-2');
        Auth::user()->loadPermissions();
        // creation of a user with the same email address
        $this->visit('users/create')
                ->type('Dave', 'first_name')
                ->type('Bowman', 'last_name')
                ->type('hal.9000@example.com', 'email')
                ->press('Create')
                ->seePageIs('users/create')
                ->see('This email address is already used by another user.');
        
        // not filling fields
        $this->visit('users/create')
                ->press('Create')
                ->seePageIs('users/create')
                ->see('The "First Name" field is required.')
                ->see('The "Last Name" field is required.')
                ->see('The "Email" field is required.');
        
    }
    
    
    public function testEdit() {
        //Session::set('func', 'testEdit()');
        $this->visit('users/edit/2')
            ->see('Edit a User')
            // field already filled by existing record
            ->see('Stanley')
            ->see('Kubrick')
            ->see('s.kubrick@example.com')
            
            // typing new valid data
            ->type('Hal', 'first_name')
            ->type('9000', 'last_name')
            ->type('hal9000@example.com', 'email')
            ->press('Save')
            ->seePageIs('users')
            ->see('The user Hal 9000 has been updated.')
            ->see('Hal')
            ->dontSee('Stanley');
        
        // typing invalid email
        $this->visit('users/edit/2')
            ->type('invalid.email', 'email')
            ->press('Save')
            ->seePageIs('users/edit/2')
            ->see('The Email must be a valid email address.');
            
        
    }
    
    public function testDelete() {
        //Session::set('func', 'testDelete()');
        $this->visit('users/delete/2')
            ->seePageIs('users')
            ->see('The user Stanley Kubrick has been deleted.');
        
        $this->seeInDatabase(       'users', [
                                                'last_name' => 'Kubrick',
                                                ])
                ->notSeeInDatabase( 'users', [
                                                'last_name' => 'Kubrick',
                                                'deleted_at' => null 
                                                ]);
        
    }
    
    
    
}

