<?php
require_once __DIR__ . '/helper/TestResultsManager.php';


use PHPUnit\Framework\TestCase;

class FormEmailTest extends TestCase
{

    private $testResultsManager;

    protected function setUp(): void
    {
        $this->testResultsManager = new TestResultsManager();
    }

    public function testVariableUndefined()
    {
        try {
            $testCase = get_class($this) . '.' . __FUNCTION__;

            $_GET['error'] = 'variable_undefined';

            ob_start();
            include './apps/formEmail.php';

            $output = ob_get_clean();
            $dom = new DOMDocument();
            $dom->loadHTML($output);
            $errorMessage = $dom->getElementsByTagName('div')->item(0)->textContent;
            $expectedMessage = "Sorry, you must access this page from formEmail.php";
            $this->assertStringContainsString($expectedMessage, $errorMessage, 'The error message for the condition $_GET["error"] == "variable_undefined" is out of specification');

            $this->verifyFormAttributes($dom);
            $this->testResultsManager->showTestResult($testCase);
        } catch (\Throwable $e) {
            $this->testResultsManager->showTestResult($testCase, $e);
            throw $e;
        }
    }

    public function testEmptyName()
    {
        try {
            $testCase = get_class($this) . '.' . __FUNCTION__;

            $_GET['error'] = 'empty_name';

            ob_start();
            include './apps/formEmail.php';

            $output = ob_get_clean();
            $dom = new DOMDocument();
            $dom->loadHTML($output);
            $errorMessage = $dom->getElementsByTagName('div')->item(0)->textContent;
            $expectedMessage = "Sorry, name field required";
            $this->assertStringContainsString($expectedMessage, $errorMessage, 'The error message for the condition $_GET["error"] == "empty_name" is out of specification');

            $this->verifyFormAttributes($dom);
            $this->testResultsManager->showTestResult($testCase);
        } catch (\Throwable $e) {
            $this->testResultsManager->showTestResult($testCase, $e);
            throw $e;
        }
    }

    public function testInvalidName()
    {
        try {
            $testCase = get_class($this) . '.' . __FUNCTION__;

            $_GET['error'] = 'invalid_name';

            ob_start();
            include './apps/formEmail.php';

            $output = ob_get_clean();
            $dom = new DOMDocument();
            $dom->loadHTML($output);
            $errorMessage = $dom->getElementsByTagName('div')->item(0)->textContent;
            $expectedMessage = "Sorry, name must contains letter";
            $this->assertStringContainsString($expectedMessage, $errorMessage, 'The error message for the condition $_GET["error"] == "empty_name" is out of specification');

            $this->verifyFormAttributes($dom);
            $this->testResultsManager->showTestResult($testCase);
        } catch (\Throwable $e) {
            $this->testResultsManager->showTestResult($testCase, $e);
            throw $e;
        }
    }

    public function testEmptyEmail()
    {
        try {
            $testCase = get_class($this) . '.' . __FUNCTION__;

            $_GET['error'] = 'empty_email';

            ob_start();
            include './apps/formEmail.php';

            $output = ob_get_clean();
            $dom = new DOMDocument();
            $dom->loadHTML($output);
            $errorMessage = $dom->getElementsByTagName('div')->item(0)->textContent;
            $expectedMessage = "Sorry, email field required";
            $this->assertStringContainsString($expectedMessage, $errorMessage, 'The error message for the condition $_GET["error"] == "empty_email" is out of specification');

            $this->verifyFormAttributes($dom);
            $this->testResultsManager->showTestResult($testCase);
        } catch (\Throwable $e) {
            $this->testResultsManager->showTestResult($testCase, $e);
            throw $e;
        }
    }

    public function testInvalidEmail()
    {
        try {
            $testCase = get_class($this) . '.' . __FUNCTION__;

            $_GET['error'] = 'invalid_email';

            ob_start();
            include './apps/formEmail.php';

            $output = ob_get_clean();
            $dom = new DOMDocument();
            $dom->loadHTML($output);
            $errorMessage = $dom->getElementsByTagName('div')->item(0)->textContent;
            $expectedMessage = "Sorry, invalid email";
            $this->assertStringContainsString($expectedMessage, $errorMessage, 'The error message for the condition $_GET["error"] == "empty_email" is out of specification');

            $this->verifyFormAttributes($dom);
            $this->testResultsManager->showTestResult($testCase);
        } catch (\Throwable $e) {
            $this->testResultsManager->showTestResult($testCase, $e);
            throw $e;
        }
    }

    private function verifyFormAttributes(DOMDocument $dom)
    {
        try {
            $testCase = get_class($this) . '.' . __FUNCTION__;

            $form = $dom->getElementsByTagName('form')->item(0);
            $this->assertEquals('prosesFormEmail.php', $form->attributes->getNamedItem('action')->nodeValue, "The value of the action attribute on the form doesn't match the specifications");
            $this->assertEqualsIgnoringCase('GET', $form->attributes->getNamedItem('method')->nodeValue, "The value of the action attribute on the form doesn't match the specifications");

            $labelName = $dom->getElementsByTagName('label')->item(0);
            $this->assertEquals('Your Name:', $labelName->textContent, "The text content of the first label element in the form doesn't match");

            $inputName = $dom->getElementsByTagName('input')->item(0);
            $this->assertEquals('text', $inputName->attributes->getNamedItem('type')->nodeValue, "The value of the type attribute on the first input element in the form != text");
            $this->assertEquals('yourname', $inputName->attributes->getNamedItem('name')->nodeValue, "The value of the name attribute on the first input element in the form != yourname");
            $this->assertEquals('', $inputName->attributes->getNamedItem('value')->nodeValue);


            $labelName = $dom->getElementsByTagName('label')->item(1);
            $this->assertEquals('Your Email:', $labelName->textContent, "The text content of the third label element in the form does not match");

            $inputAddress = $dom->getElementsByTagName('input')->item(1);
            $this->assertEquals('email', $inputAddress->attributes->getNamedItem('type')->nodeValue, "The value of the type attribute on the second input element in the form != email");
            $this->assertEquals('youremail', $inputAddress->attributes->getNamedItem('name')->nodeValue, "The value of the name attribute in the second input element in the form != youremail");
            $this->assertEquals('', $inputAddress->attributes->getNamedItem('value')->nodeValue);

            $inputSubmit = $dom->getElementsByTagName('input')->item(2);
            $this->assertEquals('submit', $inputSubmit->attributes->getNamedItem('type')->nodeValue, "The value of the type attribute on the third input element in the form != submit");
            $this->assertEquals('submit', $inputSubmit->attributes->getNamedItem('name')->nodeValue, "The value of the name attribute in the third input element in the form != submit");
            $this->assertEquals('Submit', $inputSubmit->attributes->getNamedItem('value')->nodeValue, "The value attribute value in the third input element in the form != Submit");
            $this->testResultsManager->showTestResult($testCase);
        } catch (\Throwable $e) {
            $this->testResultsManager->showTestResult($testCase, $e);
            throw $e;
        }
    }
}
