<?php

declare(strict_types=1);

namespace App\Tests\Api\Entity;

use App\Tests\AbstractApiTestCase;

/**
 * @internal
 */
class MachineComponentLinkTest extends AbstractApiTestCase
{
    public function testGetCollection(): void
    {
        $machine   = $this->createMachine('Machine A');
        $composant = $this->createComposant('Pompe A');
        $this->createMachineComponentLink($machine, $composant);

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

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

    public function testGetItem(): void
    {
        $machine   = $this->createMachine('Machine A');
        $composant = $this->createComposant('Pompe A');
        $link      = $this->createMachineComponentLink($machine, $composant);

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

        $this->assertResponseIsSuccessful();
    }

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

        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/machine_component_links', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'machine'   => self::iri('machines', $machine->getId()),
                'composant' => self::iri('composants', $composant->getId()),
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
    }

    public function testPostWithOverrides(): void
    {
        $machine   = $this->createMachine('Machine A');
        $composant = $this->createComposant('Pompe A');

        $client = $this->createGestionnaireClient();
        $client->request('POST', '/api/machine_component_links', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'machine'           => self::iri('machines', $machine->getId()),
                'composant'         => self::iri('composants', $composant->getId()),
                'nameOverride'      => 'Pompe spéciale',
                'referenceOverride' => 'REF-OVERRIDE',
                'prixOverride'      => '500.00',
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $this->assertJsonContains([
            'nameOverride'      => 'Pompe spéciale',
            'referenceOverride' => 'REF-OVERRIDE',
            'prixOverride'      => '500.00',
        ]);
    }

    public function testPatch(): void
    {
        $machine   = $this->createMachine('Machine A');
        $composant = $this->createComposant('Pompe A');
        $link      = $this->createMachineComponentLink($machine, $composant);

        $client = $this->createGestionnaireClient();
        $client->request('PATCH', self::iri('machine_component_links', $link->getId()), [
            'headers' => ['Content-Type' => 'application/merge-patch+json'],
            'json'    => ['nameOverride' => 'Overridden'],
        ]);

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['nameOverride' => 'Overridden']);
    }

    public function testDelete(): void
    {
        $machine   = $this->createMachine('Machine A');
        $composant = $this->createComposant('Pompe A');
        $link      = $this->createMachineComponentLink($machine, $composant);

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

        $this->assertResponseStatusCodeSame(204);
    }

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

        $this->assertResponseStatusCodeSame(401);
    }

    public function testViewerCannotWrite(): void
    {
        $machine   = $this->createMachine('Machine A');
        $composant = $this->createComposant('Pompe A');

        $client = $this->createViewerClient();
        $client->request('POST', '/api/machine_component_links', [
            'headers' => ['Content-Type' => 'application/ld+json'],
            'json'    => [
                'machine'   => self::iri('machines', $machine->getId()),
                'composant' => self::iri('composants', $composant->getId()),
            ],
        ]);

        $this->assertResponseStatusCodeSame(403);
    }
}
