<?php

declare(strict_types=1);
namespace Tests\Adawolfa\Retrofit;
use Adawolfa\Retrofit\Executor;
use Adawolfa\Retrofit\Factory;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Utils;
use Http\Mock\Client;
use PHPUnit\Framework\TestCase as TC;

final class ConverterServiceTest extends TC
{

	private Service $service;
	private Client  $client;

	public function testRoot(): void
	{
		$this->client->addResponse(new Response(body: 'hello'));
		$this->assertSame('HELLO', $this->service->root());
		$this->assertSame('root', (string) $this->client->getLastRequest()->getUri());
	}

	public function testReturnsMixed(): void
	{
		$this->client->addResponse(new Response(body: 'hello'));
		$this->assertSame('HELLO', $this->service->returnMixed());
	}

	public function testHeaderArgument(): void
	{
		$this->client->addResponse(new Response);
		$this->service->header('a', 'b');
		$request = $this->client->getLastRequest();
		$this->assertSame([
			'A' => ['B'],
		], $request->getHeaders());
	}

	public function testQuery(): void
	{
		$this->client->addResponse(new Response);
		$this->service->query('b');
		$request = $this->client->getLastRequest();
		$this->assertSame('a=a&b=B&c=C&x=D&e=E', $request->getUri()->getQuery());
	}

	public function testBodyString(): void
	{
		$this->client->addResponse(new Response);
		$this->service->body('hello');
		$this->assertSame('BODY', $this->client->getLastRequest()->getBody()->getContents());
	}

	public function testBodyStream(): void
	{
		$this->client->addResponse(new Response);
		$this->service->body(Utils::streamFor('hello'));
		$this->assertSame('BODY', $this->client->getLastRequest()->getBody()->getContents());
	}

	public function testURLEncodedBody(): void
	{
		$this->client->addResponse(new Response);
		$this->service->urlEncodedBody('foo');
		$request = $this->client->getLastRequest();
		parse_str($request->getBody()->getContents(), $post);
		$this->assertSame(['a' => 'A'], $post);
	}

	protected function setUp(): void
	{
		$this->service = (new Factory())
			->withExecutor(new Executor($this->client = new Client))
			->withConverter(new Converter)
			->create(Service::class);
	}

}