<?php

declare(strict_types=1);

namespace App\Tests\Api\Entity;

use App\Tests\AbstractApiTestCase;

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

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

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

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

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

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains([
            'name' => 'Tension',
            'type' => 'number',
        ]);
    }

    public function testPost(): void
    {
        $machine = $this->createMachine('Machine A');

        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/custom_fields', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'name'    => 'Pression',
                'type'    => 'number',
                'machine' => self::iri('machines', $machine->getId()),
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $this->assertJsonContains(['name' => 'Pression']);
    }

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

        $client = $this->createGestionnaireClient();
        $client->request('PATCH', self::iri('custom_fields', $cf->getId()), [
            'headers' => ['Content-Type' => 'application/merge-patch+json'],
            'json'    => ['required' => true],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['required' => true]);
    }

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

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

        $this->assertResponseStatusCodeSame(204);
    }

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

        $this->assertResponseStatusCodeSame(401);
    }

    public function testViewerCannotWrite(): void
    {
        $client = $this->createViewerClient();
        $client->request('POST', '/api/custom_fields', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'name' => 'Blocked',
                'type' => 'text',
            ],
        ]);

        $this->assertResponseStatusCodeSame(403);
    }
}
