orbit/tests/src/Orbit/CertTest.php
2020-09-06 02:32:56 -05:00

189 lines
6.3 KiB
PHP

<?php declare(strict_types=1);
namespace Orbit\Tests;
use PHPUnit\Framework\TestCase;
use Orbit\Cert;
use Orbit\Config;
use Monolog\Logger;
final class CertTest extends TestCase
{
public function makeTestLogger(): Logger
{
$logger = new Logger('test-orbit');
$logger->pushHandler(new \Monolog\Handler\TestHandler());
return $logger;
}
public function getTestLogRecords($logger): array
{
return $logger->getHandlers()[0]->getRecords();
}
public function getTestLogMessages($logger): array
{
$messages = [];
foreach ($this->getTestLogRecords($logger) as $message) {
$messages[] = $message['level_name'] . ": " . $message['message'];
}
return $messages;
}
public function testConstructDev(): void
{
$config = new Config(true);
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertEquals(3, count($messages));
$this->assertStringContainsString('development mode', $messages[0]);
$this->assertStringContainsString('Generating new cert file', $messages[1]);
$this->assertStringContainsString('Generating new key file', $messages[2]);
}
public function testConstructDevExistingCertFile(): void
{
$config = new Config(true);
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('development mode', $messages[0]);
$this->assertStringContainsString('Generating new cert file', $messages[1]);
$this->assertStringContainsString('Generating new key file', $messages[2]);
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('Using existing cert file', $messages[1]);
$this->assertStringContainsString('Using existing key file', $messages[2]);
}
public function testConstructDevOverwriteCertWarning(): void
{
$config = new Config(true);
$logger = $this->makeTestLogger();
@mkdir('certs');
file_put_contents('certs/localhost.cert.pem', '####');
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('May overwrite existing cert file', $messages[3]);
}
public function testConstructDevSetCertFile(): void
{
$config = new Config(true);
$config->tls_certfile = 'certs/subd/wahoo.cert.pem';
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('certs/subd/wahoo.cert.pem', $messages[1]);
@unlink("certs/subd/wahoo.cert.pem");
}
public function testConstructDevSetKeyFile(): void
{
$config = new Config(true);
$config->tls_keyfile = 'certs/wahoo.key.pem';
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('certs/wahoo.key.pem', $messages[2]);
@unlink("certs/wahoo.key.pem");
}
public function testConstructDevFilesUsingHostname(): void
{
$config = new Config(true);
$config->hostname = 'particle';
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('certs/particle.cert.pem', $messages[1]);
$this->assertStringContainsString('certs/particle.key.pem', $messages[2]);
@unlink("certs/particle.cert.pem");
@unlink("certs/particle.key.pem");
}
public function testConstructDevOverwriteKeyWarning(): void
{
$config = new Config(true);
$logger = $this->makeTestLogger();
@mkdir('certs');
file_put_contents('certs/localhost.key.pem', '####');
$cert = new Cert($config, $logger);
$this->assertInstanceOf(Cert::class, $cert);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('May overwrite existing key file', $messages[3]);
}
public function testConstructProd(): void
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage("Missing required cert file");
$config = new Config();
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
}
public function testConstructProdDefinedButMissingFiles(): void
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage("does not exist or is not readable");
$config = new Config();
$config->tls_certfile = 'localhost.cert.pem';
$config->tls_keyfile = 'localhost.key.pem';
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
}
public function testConstructProdDefinedFiles(): void
{
// first run in development mode to auto-generate certs
$config = new Config(true);
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
// now run in prod mode to use those cert files
$config = new Config();
$config->tls_certfile = 'certs/localhost.cert.pem';
$config->tls_keyfile = 'certs/localhost.key.pem';
$logger = $this->makeTestLogger();
$cert = new Cert($config, $logger);
$messages = $this->getTestLogMessages($logger);
$this->assertStringContainsString('Using cert file', $messages[1]);
$this->assertStringContainsString('Using key file', $messages[2]);
}
public function tearDown(): void
{
@unlink("certs/localhost.cert.pem");
@unlink("certs/localhost.key.pem");
@rmdir("certs/subd");
}
}