<?php

namespace Tests\Feature;

use App\Models\ToDoList;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class ToDoListsTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function a_user_can_create_a_to_do_list()
    {
        $this->withoutExceptionHandling();
        $this->actingAs($user = factory(User::class)->create(), 'api');

        $response = $this->post('/api/to-do-lists/', [
            'name' => 'Test name to do list'
        ])->assertStatus(201);

        $toDoList = ToDoList::first();

        $this->assertEquals('Test name to do list', $toDoList->name);
        $response->assertJson([
            'data' => [
                'type' => 'to-do-lists',
                'to_do_list_id' => $toDoList->id,
                'attributes' => [
                    'data' => [
                        'name' => $toDoList->name,
                    ]
                ],
            ],
            'links' => [
                'self' => $toDoList->path(),
            ]
        ]);
    }

    /** @test */
    public function to_do_list_name_are_required()
    {
        $this->actingAs($user = factory(\App\User::class)->create(), 'api');
        $response = $this->post('/api/to-do-lists/', ['name' => '']);

        $response->assertSessionHasErrors('name');
        $this->assertCount(0, ToDoList::all());
    }

    /** @test */
    public function a_to_do_list_can_be_retrieved()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');
        $toDoList = factory(ToDoList::class)->create(['user_id' => $user->id]);

        $response = $this->get('/api/to-do-lists/' . $toDoList->id );

        $response->assertJson([
            'data' => [
                'to_do_list_id' => $toDoList->id,
                'attributes' => [
                    'data' => [
                        'name' => $toDoList->name,
                        'last_updated' => $toDoList->updated_at->diffForHumans(),
                    ]
                ],
            ],
            'links' => [
                'self' => $toDoList->path(),
            ]
        ]);
    }

    /** @test */
    public function only_owner_to_do_list_can_retrieved_it()
    {
        $user = factory(User::class)->create();
        $toDoList = factory(ToDoList::class)->create(['user_id' => $user->id]);

        $this->actingAs($userAnother = factory(User::class)->create(), 'api');

        $response = $this->get('/api/to-do-lists/' . $toDoList->id );

        $response->assertStatus(403);
    }

    /** @test */
    public function a_user_can_retrueved_all_this_to_do_lists()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');
        $toDoListOne = factory(ToDoList::class)->create(['user_id' => $user->id]);
        $toDoListTwo = factory(ToDoList::class)->create(['user_id' => $user->id]);

        $response = $this->get('/api/to-do-lists');

        $response->assertJson([
            'data' => [
                [
                    'data' => [
                        'to_do_list_id' => $toDoListOne->id,
                        'attributes' => [
                            'data' => [
                                'name' => $toDoListOne->name,
                                'last_updated' => $toDoListOne->updated_at->diffForHumans(),
                            ]
                        ],
                    ],
                    'links' => [
                        'self' => $toDoListOne->path(),
                    ]
                ],
                [
                    'data' => [
                        'to_do_list_id' => $toDoListTwo->id,
                        'attributes' => [
                            'data' => [
                                'name' => $toDoListTwo->name,
                                'last_updated' => $toDoListTwo->updated_at->diffForHumans(),
                            ]
                        ],
                    ],
                    'links' => [
                        'self' => $toDoListTwo->path(),
                    ]
                ]
            ]

        ]);
    }

    /** @test */
    public function a_to_do_list_can_be_patch()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');

        $toDoList = factory(ToDoList::class)->create(['user_id' => $user->id]);

        $response = $this->patch('/api/to-do-lists/' . $toDoList->id, [
            'name' => 'To Do List Update'
        ]);

        $toDoList = $toDoList->fresh();

        $this->assertEquals('To Do List Update', $toDoList->name);

        $response->assertStatus(200);
        $response->assertJson([
            'data' => [
                'to_do_list_id' => $toDoList->id,
                'attributes' => [
                    'data' => [
                        'name' => 'To Do List Update'
                    ]
                ]
            ],
            'links' => [
                'self' => $toDoList->path(),
            ]
        ]);
    }

    /** @test */
    public function only_the_owner_can_patch_the_to_do_list()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');
        $toDoList = factory(ToDoList::class)->create();

        $anotherUser = factory(User::class)->create();

        $response = $this->patch('/api/to-do-lists/' . $toDoList->id, ['name' => 'Name changed'], ['api_token' => $anotherUser->api_token]);

        $response->assertStatus(403);
    }

    /** @test */
    public function a_to_do_list_can_be_delete()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');

        $toDoList = factory(ToDoList::class)->create(['user_id' => $user->id]);

        $response = $this->delete('/api/to-do-lists/' . $toDoList->id);

        $toDoList = $toDoList->fresh();

        $this->assertCount(0, ToDoList::all());

        $response->assertStatus(204);
    }

    /** @test */
    public function only_the_owner_can_delete_the_to_do_list()
    {
        $user = factory(User::class)->create();
        $toDoList = factory(ToDoList::class)->create();

        $this->actingAs($anotherUser = factory(User::class)->create(), 'api');

        $response = $this->delete('/api/to-do-lists/' . $toDoList->id);

        $response->assertStatus(403);
    }
}
