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"); } }