<?php

declare(strict_types=1);

namespace Drupal\Tests\flowdrop\Unit\DTO\JsApi;

use Drupal\Tests\UnitTestCase;
use Drupal\flowdrop\DTO\JsApi\Edge;
use Drupal\flowdrop\DTO\JsApi\Node;
use Drupal\flowdrop\DTO\JsApi\Workflow;

/**
 * Tests the JsApi transport Workflow envelope.
 *
 * @coversDefaultClass \Drupal\flowdrop\DTO\JsApi\Workflow
 * @group flowdrop
 */
class WorkflowTest extends UnitTestCase {

  /**
   * @covers ::fromArray
   * @covers ::getId
   * @covers ::getName
   * @covers ::getDescription
   * @covers ::getNodes
   * @covers ::getEdges
   * @covers ::getMetadata
   */
  public function testReadsEnvelope(): void {
    $workflow = Workflow::fromArray([
      'id' => 'wf1',
      'name' => 'My Flow',
      'description' => 'desc',
      'metadata' => ['version' => 2],
      'nodes' => [['id' => 'a.1'], ['id' => 'b.1']],
      'edges' => [['id' => 'e1', 'source' => 'a.1', 'target' => 'b.1']],
    ]);

    $this->assertSame('wf1', $workflow->getId());
    $this->assertSame('My Flow', $workflow->getName());
    $this->assertSame('desc', $workflow->getDescription());
    $this->assertSame(['version' => 2], $workflow->getMetadata());
    $this->assertContainsOnlyInstancesOf(Node::class, $workflow->getNodes());
    $this->assertContainsOnlyInstancesOf(Edge::class, $workflow->getEdges());
    $this->assertCount(2, $workflow->getNodes());
    $this->assertCount(1, $workflow->getEdges());
  }

  /**
   * The editor sometimes posts the full API response wrapped in `data`.
   *
   * @covers ::fromArray
   */
  public function testUnwrapsDataEnvelope(): void {
    $workflow = Workflow::fromArray([
      'data' => ['id' => 'wf1', 'nodes' => [['id' => 'a.1']]],
    ]);
    $this->assertSame('wf1', $workflow->getId());
    $this->assertCount(1, $workflow->getNodes());
  }

  /**
   * Edges may arrive under the legacy `connections` key.
   *
   * @covers ::fromArray
   */
  public function testConnectionsAliasForEdges(): void {
    $workflow = Workflow::fromArray([
      'id' => 'wf1',
      'connections' => [['id' => 'e1', 'source' => 'a.1', 'target' => 'b.1']],
    ]);
    $this->assertCount(1, $workflow->getEdges());
  }

  /**
   * @covers ::getName
   * @covers ::getLabel
   */
  public function testNameAndLabelNullWhenAbsent(): void {
    $workflow = Workflow::fromArray(['id' => 'wf1']);
    $this->assertNull($workflow->getName());
    $this->assertNull($workflow->getLabel());
  }

}
