From e5e0e0379949c070ba83ffbebc1f1d1130308ad1 Mon Sep 17 00:00:00 2001 From: Matt Stauffer Date: Fri, 30 Dec 2022 15:07:34 -0500 Subject: [PATCH] Add a bunch more CLI command tests (#1332) * Wip some cli tests * Apply fixes from StyleCI * Test parked command * Test forget command * Update Filesystem::rmDirAndContents to respect symlinks * Wip cli commands * Apply fixes from StyleCI * Test link command, unlink command, and secure command * Apply fixes from StyleCI * Add tests for unsecure, unsecure --all, secured commands Add placeholders for the remaining CLI commands Add nginx::restart to unsecure --all command Co-authored-by: StyleCI Bot --- cli/Valet/Filesystem.php | 6 +- cli/app.php | 6 +- tests/BaseApplicationTestCase.php | 5 + tests/CliTest.php | 348 ++++++++++++++++++ .../Parked/Sites/my-best-site/.gitkeep | 0 5 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/Parked/Sites/my-best-site/.gitkeep diff --git a/cli/Valet/Filesystem.php b/cli/Valet/Filesystem.php index 3fbc7bd..790f9a9 100644 --- a/cli/Valet/Filesystem.php +++ b/cli/Valet/Filesystem.php @@ -257,7 +257,11 @@ public function rmDirAndContents(string $path): void $files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) { - $file->isDir() ? rmdir($file->getRealPath()) : unlink($file->getRealPath()); + if ($file->isLink()) { + unlink($file->getPathname()); + } else { + $file->isDir() ? rmdir($file->getRealPath()) : unlink($file->getRealPath()); + } } rmdir($path); diff --git a/cli/app.php b/cli/app.php index d650e4e..850e036 100644 --- a/cli/app.php +++ b/cli/app.php @@ -66,7 +66,7 @@ function (ConsoleCommandEvent $event) { */ if (is_dir(VALET_HOME_PATH)) { /** - * Upgrade helper: ensure the tld config exists or the loopback config exists. + * Upgrade helper: ensure the tld config exists and the loopback config exists. */ if (empty(Configuration::read()['tld']) || empty(Configuration::read()['loopback'])) { Configuration::writeBaseConfiguration(); @@ -208,6 +208,10 @@ function (ConsoleCommandEvent $event) { if ($all) { Site::unsecureAll(); + Nginx::restart(); + + info('All Valet sites will now serve traffic over HTTP.'); + return; } diff --git a/tests/BaseApplicationTestCase.php b/tests/BaseApplicationTestCase.php index 388319c..744e6e8 100644 --- a/tests/BaseApplicationTestCase.php +++ b/tests/BaseApplicationTestCase.php @@ -12,6 +12,11 @@ public function setUp(): void $this->setNullWriter(); } + public function tearDown(): void + { + Mockery::close(); + } + /** * Prepare a test to run using the full application. * diff --git a/tests/CliTest.php b/tests/CliTest.php index f3bf714..98a6654 100644 --- a/tests/CliTest.php +++ b/tests/CliTest.php @@ -1,10 +1,60 @@ = 8.0 */ class CliTest extends BaseApplicationTestCase { + public function test_tld_command_reads_tld() + { + [$app, $tester] = $this->appAndTester(); + + $tester->run(['command' => 'tld']); + + $tester->assertCommandIsSuccessful(); + + $this->assertEquals('test', trim($tester->getDisplay())); + } + + public function test_tld_command_sets_tld() + { + $this->markTestIncomplete(); + + // [$app, $tester] = $this->appAndTester(); + + // @todo: Mock DnsMasq, Site, PhpFpm, Nginx, Configuration... + // $tester->setInputs(['Y']); + // $tester->run(['command' => 'tld', 'tld' => 'buzz']); + // $tester->assertCommandIsSuccessful(); + } + + public function test_loopback_command_reads_loopback() + { + [$app, $tester] = $this->appAndTester(); + + $tester->run(['command' => 'loopback']); + $tester->assertCommandIsSuccessful(); + + $this->assertEquals('127.0.0.1', trim($tester->getDisplay())); + } + + public function test_loopback_command_sets_loopback() + { + $this->markTestIncomplete(); + + // @todo: Mock everything... + // [$app, $tester] = $this->appAndTester(); + + // $tester->run(['command' => 'loopback', 'loopback' => '127.0.0.9']); + // $tester->assertCommandIsSuccessful(); + } + public function test_park_command() { [$app, $tester] = $this->appAndTester(); @@ -23,4 +73,302 @@ public function test_park_command() $this->assertEquals(1, count($paths)); $this->assertEquals('./tests/output', reset($paths)); } + + public function test_parked_command() + { + [$app, $tester] = $this->appAndTester(); + + $tester->run(['command' => 'parked']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringNotContainsString('test', $tester->getDisplay()); + + Configuration::addPath(__DIR__.'/fixtures/Parked/Sites'); + + $tester->run(['command' => 'parked']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('my-best-site', $tester->getDisplay()); + } + + public function test_forget_command() + { + [$app, $tester] = $this->appAndTester(); + + Configuration::addPath(__DIR__.'/fixtures/Parked/Sites'); + + $tester->run(['command' => 'forget', 'path' => __DIR__.'/fixtures/Parked/Sites']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringNotContainsString('my-best-site', $tester->getDisplay()); + } + + public function test_link_command() + { + [$app, $tester] = $this->appAndTester(); + + $tester->run(['command' => 'link', 'name' => 'tighten']); + $tester->assertCommandIsSuccessful(); + + $this->assertEquals(1, Site::links()->count()); + $this->assertEquals(1, Site::links()->filter(function ($site) { + return $site['site'] === 'tighten'; + })->count()); + } + + public function test_link_command_defaults_to_cwd() + { + [$app, $tester] = $this->appAndTester(); + + $site = Mockery::mock(RealSite::class); + $site->shouldReceive('link')->with(getcwd(), basename(getcwd()))->once(); + swap(RealSite::class, $site); + + $tester->run(['command' => 'link']); + $tester->assertCommandIsSuccessful(); + } + + public function test_link_command_with_secure_flag_secures() + { + [$app, $tester] = $this->appAndTester(); + + $site = Mockery::mock(RealSite::class); + $site->shouldReceive('link')->once(); + $site->shouldReceive('domain')->andReturn('mysite.test'); + $site->shouldReceive('secure')->once(); + swap(RealSite::class, $site); + + $nginx = Mockery::mock(Nginx::class); + $nginx->shouldReceive('restart')->once(); + swap(Nginx::class, $nginx); + + $tester->run(['command' => 'link', '--secure' => true]); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('site has been secured', $tester->getDisplay()); + } + + public function test_links_command() + { + [$app, $tester] = $this->appAndTester(); + + Site::link(__DIR__.'/fixtures/Parked/Sites/my-best-site', 'tighten'); + $tester->run(['command' => 'links']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('tighten', $tester->getDisplay()); + } + + public function test_unlink_command() + { + [$app, $tester] = $this->appAndTester(); + + Site::link(__DIR__.'/fixtures/Parked/Sites/my-best-site', 'tighten'); + + $tester->run(['command' => 'unlink', 'name' => 'tighten']); + $tester->assertCommandIsSuccessful(); + + $this->assertEquals(0, Site::links()->count()); + } + + public function test_secure_command() + { + [$app, $tester] = $this->appAndTester(); + + $site = Mockery::mock(RealSite::class); + $site->shouldReceive('domain')->with('tighten')->andReturn('tighten.test'); + $site->shouldReceive('unsecure')->with('tighten.test')->once(); + swap(RealSite::class, $site); + + $nginx = Mockery::mock(Nginx::class); + $nginx->shouldReceive('restart')->once(); + swap(Nginx::class, $nginx); + + $tester->run(['command' => 'unsecure', 'domain' => 'tighten']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('will now serve traffic over HTTP.', $tester->getDisplay()); + } + + public function test_unsecure_command() + { + [$app, $tester] = $this->appAndTester(); + + $site = Mockery::mock(RealSite::class); + $site->shouldReceive('domain')->andReturn('tighten.test'); + $site->shouldReceive('secure')->with('tighten.test', null, 12345)->once(); + swap(RealSite::class, $site); + + $nginx = Mockery::mock(Nginx::class); + $nginx->shouldReceive('restart')->once(); + swap(Nginx::class, $nginx); + + $tester->run(['command' => 'secure', 'domain' => 'tighten', '--expireIn' => '12345']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('site has been secured', $tester->getDisplay()); + } + + public function test_unsecure_all_command() + { + [$app, $tester] = $this->appAndTester(); + + $site = Mockery::mock(RealSite::class); + $site->shouldReceive('unSecureAll')->once(); + swap(RealSite::class, $site); + + $nginx = Mockery::mock(Nginx::class); + $nginx->shouldReceive('restart')->once(); + swap(Nginx::class, $nginx); + + $tester->run(['command' => 'unsecure', '--all' => true]); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('All Valet sites will now serve traffic over HTTP.', $tester->getDisplay()); + } + + public function test_secured_command() + { + [$app, $tester] = $this->appAndTester(); + + $site = Mockery::mock(RealSite::class); + $site->shouldReceive('secured')->andReturn(['tighten.test']); + swap(RealSite::class, $site); + + $tester->run(['command' => 'secured']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('tighten.test', $tester->getDisplay()); + } + + public function test_proxy_command() + { + $this->markTestIncomplete(); + } + + public function test_unproxy_command() + { + $this->markTestIncomplete(); + } + + public function test_proxies_command() + { + $this->markTestIncomplete(); + } + + public function test_which_command() + { + $this->markTestIncomplete(); + } + + public function test_paths_command() + { + [$app, $tester] = $this->appAndTester(); + + $tester->run(['command' => 'paths']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString('No paths have been registered.', $tester->getDisplay()); + + Configuration::addPath(__DIR__); + + $tester->run(['command' => 'paths']); + $tester->assertCommandIsSuccessful(); + + $this->assertStringContainsString(__DIR__, $tester->getDisplay()); + } + + public function test_open_command() + { + [$app, $tester] = $this->appAndTester(); + + $cli = Mockery::mock(CommandLine::class); + $cli->shouldReceive('runAsUser')->with("open 'http://tighten.test'")->once(); + swap(CommandLine::class, $cli); + + $tester->run(['command' => 'open', 'domain' => 'tighten']); + $tester->assertCommandIsSuccessful(); + } + + public function test_set_ngrok_token_command() + { + [$app, $tester] = $this->appAndTester(); + + $ngrok = Mockery::mock(Ngrok::class); + $ngrok->shouldReceive('setToken')->with('your-token-here')->once()->andReturn('yay'); + swap(Ngrok::class, $ngrok); + + $tester->run(['command' => 'set-ngrok-token', 'token' => 'your-token-here']); + $tester->assertCommandIsSuccessful(); + } + + public function test_start_command() + { + $this->markTestIncomplete(); + } + + public function test_restart_command() + { + $this->markTestIncomplete(); + } + + public function test_stop_command() + { + $this->markTestIncomplete(); + } + + public function test_uninstall_command() + { + $this->markTestIncomplete(); + } + + public function test_trust_command() + { + $this->markTestIncomplete(); + } + + public function test_use_command() + { + $this->markTestIncomplete(); + } + + public function test_isolate_command() + { + $this->markTestIncomplete(); + } + + public function test_unisolate_command() + { + $this->markTestIncomplete(); + } + + public function test_isolated_command() + { + $this->markTestIncomplete(); + } + + public function test_which_php_command() + { + $this->markTestIncomplete(); + } + + public function test_composer_command() + { + $this->markTestIncomplete(); + } + + public function test_log_command() + { + $this->markTestIncomplete(); + } + + public function test_directory_listing_command() + { + $this->markTestIncomplete(); + } + + public function test_diagnose_command() + { + $this->markTestIncomplete(); + } } diff --git a/tests/fixtures/Parked/Sites/my-best-site/.gitkeep b/tests/fixtures/Parked/Sites/my-best-site/.gitkeep new file mode 100644 index 0000000..e69de29