<?php

declare(strict_types=1);

namespace App\Tests\Api\Entity;

use App\Tests\AbstractApiTestCase;

/**
 * @internal
 */
class CustomFieldValueTest extends AbstractApiTestCase
{
    public function testGetCollection(): void
    {
        $machine = $this->createMachine('Machine A');
        $cf      = $this->createCustomField('Tension', 'number', $machine);
        $this->createCustomFieldValue($cf, '220', $machine);

        $client = $this->createViewerClient();
        $client->request('GET', '/api/custom_field_values');

        $this->assertResponseIsSuccessful();
        $this->assertJsonContainsHydraCollection();
        $this->assertJsonContains(['totalItems' => 1]);
    }

    public function testGetItem(): void
    {
        $machine = $this->createMachine('Machine A');
        $cf      = $this->createCustomField('Tension', 'number', $machine);
        $cfv     = $this->createCustomFieldValue($cf, '220', $machine);

        $client = $this->createViewerClient();
        $client->request('GET', self::iri('custom_field_values', $cfv->getId()));

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['value' => '220']);
    }

    public function testPost(): void
    {
        $machine = $this->createMachine('Machine A');
        $cf      = $this->createCustomField('Tension', 'number', $machine);

        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/custom_field_values', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'value'       => '380',
                'customField' => self::iri('custom_fields', $cf->getId()),
                'machine'     => self::iri('machines', $machine->getId()),
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $this->assertJsonContains(['value' => '380']);
    }

    public function testPatch(): void
    {
        $machine = $this->createMachine('Machine A');
        $cf      = $this->createCustomField('Tension', 'number', $machine);
        $cfv     = $this->createCustomFieldValue($cf, '220', $machine);

        $client = $this->createGestionnaireClient();
        $client->request('PATCH', self::iri('custom_field_values', $cfv->getId()), [
            'headers' => ['Content-Type' => 'application/merge-patch+json'],
            'json'    => ['value' => '400'],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['value' => '400']);
    }

    public function testDelete(): void
    {
        $machine = $this->createMachine('Machine A');
        $cf      = $this->createCustomField('ToDelete', 'text', $machine);
        $cfv     = $this->createCustomFieldValue($cf, 'val', $machine);

        $client = $this->createGestionnaireClient();
        $client->request('DELETE', self::iri('custom_field_values', $cfv->getId()));

        $this->assertResponseStatusCodeSame(204);
    }

    public function testUnauthenticatedAccess(): void
    {
        $client = $this->createUnauthenticatedClient();
        $client->request('GET', '/api/custom_field_values');

        $this->assertResponseStatusCodeSame(401);
    }

    public function testViewerCannotWrite(): void
    {
        $machine = $this->createMachine('Machine A');
        $cf      = $this->createCustomField('Blocked', 'text', $machine);

        $client = $this->createViewerClient();
        $client->request('POST', '/api/custom_field_values', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'value'       => 'nope',
                'customField' => self::iri('custom_fields', $cf->getId()),
            ],
        ]);

        $this->assertResponseStatusCodeSame(403);
    }
}
