<commit_before><?php
declare(strict_types=1);

namespace Tests\PhpDockerIo\KongCertbot\Certbot;

use PhpDockerIo\KongCertbot\Certbot\Error;
use PhpDockerIo\KongCertbot\Certbot\Exception\CertFileNotFoundException;
use PhpDockerIo\KongCertbot\Certbot\Handler;
use PhpDockerIo\KongCertbot\Certbot\ShellExec;
use PhpDockerIo\KongCertbot\Certificate;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class HandlerTest extends TestCase
{
    /**
     * @var ShellExec|MockObject
     */
    private $shellExec;

    /**
     * @var Handler
     */
    private $handler;

    private $certsBasePath = __DIR__ . '/fixtures';

    private $tmpCertPath = '/tmp/foo.bar';

    public function setUp(): void
    {
        parent::setUp();

        $this->shellExec = $this->getMockBuilder(ShellExec::class)->getMock();

        $this->handler = new Handler($this->shellExec);
        $this->handler->setCertsBasePath($this->certsBasePath);

        \mkdir($this->tmpCertPath);
    }

    public function tearDown(): void
    {
        parent::tearDown();

        $fullChain = $this->tmpCertPath . '/fullchain.pem';
        if (\file_exists($fullChain) === true) {
            unlink($fullChain);
        }

        $privKey = $this->tmpCertPath . '/privkey.pem';
        if (\file_exists($privKey) === true) {
            unlink($privKey);
        }

        if (\file_exists($this->tmpCertPath) === true) {
            \rmdir($this->tmpCertPath);
        }
    }

    /**
     * @test
     */
    public function acquireCertificateHandlesEmptyListOfDomains(): void
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->handler->acquireCertificate([], 'foo', true);
    }

    /**
     * @test
     * @dataProvider booleanDataProvider
     */
    public function acquireCertificateHandlesCerbotError(bool $testCert): void
    {
        $domains = ['foo.bar'];
        $email   = 'foo@bar';

        $execOutput = ['doom'];

        $expectedErrors = [
            new Error($execOutput, 1, $domains),
        ];

        $this->shellExec
            ->expects(self::once())
            ->method('exec')
            ->willReturn(false);

        $this->shellExec
            ->expects(self::once())
            ->method('getOutput')
            ->willReturn($execOutput);

        $exception = null;

        try {
            $this->handler->acquireCertificate($domains, $email, $testCert);
        } catch (\Throwable $ex) {
            $exception = $ex;
        }

        self::assertInstanceOf(\RuntimeException::class, $exception);
        self::assertEquals($expectedErrors, $this->handler->getErrors());
    }

    /**
     * @test
     */
    public function acquireCertificatesHandlesMissingFullChain(): void
    {
        \touch($this->tmpCertPath . '/privkey.pem');

        $domains = ['foo.bar'];
        $email   = 'foo@bar';

        $this->shellExec
            ->expects(self::once())
            ->method('exec')
            ->willReturn(true);

        $this->expectException(CertFileNotFoundException::class);
        $this->expectExceptionMessageRegExp('/fullchain\.pem/');

        $handler = new Handler($this->shellExec);
        $handler
            ->setCertsBasePath('/tmp')
            ->acquireCertificate($domains, $email, false);
    }

    /**
     * @test
     */
    public function acquireCertificatesHandlesMissingPrivKey(): void
    {
        \touch($this->tmpCertPath . '/fullchain.pem');

        $domains = ['foo.bar'];
        $email   = 'foo@bar';

        $this->shellExec
            ->expects(self::once())
            ->method('exec')
            ->willReturn(true);

        $this->expectException(CertFileNotFoundException::class);
        $this->expectExceptionMessageRegExp('/privkey\.pem/');

        $handler = new Handler($this->shellExec);
        $handler
            ->setCertsBasePath('/tmp')
            ->acquireCertificate($domains, $email, false);
    }

    /**
     * @test
     * @dataProvider commandDataProvider
     */<commit_msg>Swap expectExceptionMessageRegExp for expectExceptionMessageMatches as the former is now deprecated<commit_after><?php
declare(strict_types=1);

namespace Tests\PhpDockerIo\KongCertbot\Certbot;

use PhpDockerIo\KongCertbot\Certbot\Error;
use PhpDockerIo\KongCertbot\Certbot\Exception\CertFileNotFoundException;
use PhpDockerIo\KongCertbot\Certbot\Handler;
use PhpDockerIo\KongCertbot\Certbot\ShellExec;
use PhpDockerIo\KongCertbot\Certificate;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class HandlerTest extends TestCase
{
    /**
     * @var ShellExec|MockObject
     */
    private $shellExec;

    /**
     * @var Handler
     */
    private $handler;

    private $certsBasePath = __DIR__ . '/fixtures';

    private $tmpCertPath = '/tmp/foo.bar';

    public function setUp(): void
    {
        parent::setUp();

        $this->shellExec = $this->getMockBuilder(ShellExec::class)->getMock();

        $this->handler = new Handler($this->shellExec);
        $this->handler->setCertsBasePath($this->certsBasePath);

        \mkdir($this->tmpCertPath);
    }

    public function tearDown(): void
    {
        parent::tearDown();

        $fullChain = $this->tmpCertPath . '/fullchain.pem';
        if (\file_exists($fullChain) === true) {
            unlink($fullChain);
        }

        $privKey = $this->tmpCertPath . '/privkey.pem';
        if (\file_exists($privKey) === true) {
            unlink($privKey);
        }

        if (\file_exists($this->tmpCertPath) === true) {
            \rmdir($this->tmpCertPath);
        }
    }

    /**
     * @test
     */
    public function acquireCertificateHandlesEmptyListOfDomains(): void
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->handler->acquireCertificate([], 'foo', true);
    }

    /**
     * @test
     * @dataProvider booleanDataProvider
     */
    public function acquireCertificateHandlesCerbotError(bool $testCert): void
    {
        $domains = ['foo.bar'];
        $email   = 'foo@bar';

        $execOutput = ['doom'];

        $expectedErrors = [
            new Error($execOutput, 1, $domains),
        ];

        $this->shellExec
            ->expects(self::once())
            ->method('exec')
            ->willReturn(false);

        $this->shellExec
            ->expects(self::once())
            ->method('getOutput')
            ->willReturn($execOutput);

        $exception = null;

        try {
            $this->handler->acquireCertificate($domains, $email, $testCert);
        } catch (\Throwable $ex) {
            $exception = $ex;
        }

        self::assertInstanceOf(\RuntimeException::class, $exception);
        self::assertEquals($expectedErrors, $this->handler->getErrors());
    }

    /**
     * @test
     */
    public function acquireCertificatesHandlesMissingFullChain(): void
    {
        \touch($this->tmpCertPath . '/privkey.pem');

        $domains = ['foo.bar'];
        $email   = 'foo@bar';

        $this->shellExec
            ->expects(self::once())
            ->method('exec')
            ->willReturn(true);

        $this->expectException(CertFileNotFoundException::class);
        $this->expectExceptionMessageMatches('/fullchain\.pem/');

        $handler = new Handler($this->shellExec);
        $handler
            ->setCertsBasePath('/tmp')
            ->acquireCertificate($domains, $email, false);
    }

    /**
     * @test
     */
    public function acquireCertificatesHandlesMissingPrivKey(): void
    {
        \touch($this->tmpCertPath . '/fullchain.pem');

        $domains = ['foo.bar'];
        $email   = 'foo@bar';

        $this->shellExec
            ->expects(self::once())
            ->method('exec')
            ->willReturn(true);

        $this->expectException(CertFileNotFoundException::class);
        $this->expectExceptionMessageMatches('/privkey\.pem/');

        $handler = new Handler($this->shellExec);
        $handler
            ->setCertsBasePath('/tmp')
            ->acquireCertificate($domains, $email, false);
    }

    /**
     * @test
     * @dataProvider commandDataProvider
     */
{'fraction_non_alphanumeric': 0.1490713587487781, 'fraction_numerical': 0.0004887585532746823, 'mean_word_length': 2.3030669895076676, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4797879', 'n_tokens_mistral': 2438, 'n_tokens_neox': 2340, 'n_words': 361}