]> BookStack Code Mirror - system-cli/commitdiff
Developed base testing and environment further
authorDan Brown <redacted>
Mon, 3 Apr 2023 14:46:01 +0000 (15:46 +0100)
committerDan Brown <redacted>
Mon, 3 Apr 2023 14:46:01 +0000 (15:46 +0100)
Dockerfile
docker-compose.yml
readme.md
src/app.php
tests/CommandResult.php [new file with mode: 0644]
tests/Commands/InitCommandTest.php
tests/TestCase.php

index cd441d3adfd05aec9029d4bfcb08252b1062945c..b257de4c37a6b7ce74dd0693036c66e50f6a008c 100644 (file)
@@ -8,7 +8,20 @@ RUN set -xe && \
                          php8.1-xml php8.1-zip php8.1-gd php8.1-bcmath php8.1-mysql php8.1-xdebug
 
 # Install composer to a custom location
-RUN mkdir /scripts && \
-    curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
+RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
+
+# Clone down a BookStack instance for us to play with
+RUN mkdir -p /var/www/bookstack && \
+    cd /var/www/bookstack && \
+    git clone https://github.com/BookStackApp/BookStack.git --branch release --single-branch ./ && \
+    composer install --no-dev && \
+    cp .env.example .env && \
+    php artisan key:generate
+
+# Update env options
+RUN sed -i 's/^DB_HOST=.*/DB_HOST=db/' /var/www/bookstack/.env && \
+    sed -i 's/^DB_DATABASE=.*/DB_DATABASE=bookstack/' /var/www/bookstack/.env && \
+    sed -i 's/^DB_USERNAME=.*/DB_USERNAME=bookstack/' /var/www/bookstack/.env && \
+    sed -i 's/^DB_PASSWORD=.*/DB_PASSWORD=bookstack/' /var/www/bookstack/.env
 
 CMD ["/bin/bash"]
\ No newline at end of file
index a2054b515716d7a273618864b882ef1d9f533a57..9499d982ca09f4c6c207005b987ece0e939722c2 100644 (file)
@@ -3,6 +3,7 @@ version: "3.8"
 services:
   app:
     build: .
+    working_dir: /cli
     volumes:
       - ./:/cli
     depends_on:
index 186222f167c3564cc9a18f1572d7d1535849e036..22bd0c37e3052f74e9cefcc65d8a8ff0d2be2ee5 100644 (file)
--- a/readme.md
+++ b/readme.md
@@ -25,14 +25,19 @@ This can be done by running the compile file:
 php compile.php
 ```
 
+Tests can be ran via PHPUnit within the docker environment as described below. **It is not advised** to run tests outside of this docker environment since tests are written to an expected pre-configured system environment.
+
 #### Docker Environment
 
 A docker-compose setup exists to create a clean, contained environment, which is important for this project since the
 CLI checks and interacts with many system-level elements.
 
 ```bash
+# Build the environment container
+docker compose build
+
 # Enter the environment
-docker compose run -w /cli app
+docker compose run app
 
 # From there you'll be dropped into a bash shell within the project directory.
 # You could proceed to install dependencies via composer via:
@@ -40,8 +45,13 @@ composer install
 
 # Then you can run tests via:
 vendor/bin/phpunit
+
+# To clean-up and delete the environment:
+docker compose rm -fsv
 ```
 
+Within the environment a pre-existing BookStack instance can be found at `/var/www/bookstack` for testing.
+
 ### Contributing
 
 I welcome issues and PRs but keep in mind that I'd like to keep the feature-set narrow to limit support/maintenance burden.
index 2a6a8b833a98b5ed0361d8517f8dbae18671ed54..0ff90cd2a1c7f5ba504e41a48649ffbcee0ca52f 100644 (file)
@@ -15,4 +15,5 @@ $app->add(new UpdateCommand());
 $app->add(new InitCommand());
 $app->add(new RestoreCommand());
 
+
 return $app;
\ No newline at end of file
diff --git a/tests/CommandResult.php b/tests/CommandResult.php
new file mode 100644 (file)
index 0000000..b8ee3b0
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+namespace Tests;
+
+use PHPUnit\Framework\Assert;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class CommandResult
+{
+
+    public function __construct(
+        protected CommandTester $tester,
+        protected ?\Exception $error
+    ) { }
+
+    public function assertSuccessfulExit(): void
+    {
+        Assert::assertEquals(0, $this->tester->getStatusCode());
+    }
+
+    public function assertErrorExit(): void
+    {
+        Assert::assertTrue($this->error !== null);
+    }
+
+    public function assertStdoutContains(string $needle): void
+    {
+        Assert::assertStringContainsString($needle, $this->tester->getDisplay());
+    }
+
+    public function assertStderrContains(string $needle): void
+    {
+        Assert::assertStringContainsString($needle, $this->error->getMessage() ?? '');
+    }
+
+
+}
\ No newline at end of file
index 294521b222cb90488d03e916c37f42ccf97817c7..42908a88656441a80b0aff5643789e064ed40a95 100644 (file)
@@ -11,8 +11,8 @@ class InitCommandTest extends TestCase
         $dir = $this->getEmptyTestDir();
         chdir($dir);
 
-        $commandTester = $this->runCommand('init');
-        $commandTester->assertCommandIsSuccessful();
+        $result = $this->runCommand('init');
+        $result->assertSuccessfulExit();
 
         $this->assertFileExists($dir . '/vendor/autoload.php');
         $this->assertFileExists($dir . '/.env');
@@ -20,8 +20,28 @@ class InitCommandTest extends TestCase
         $envData = file_get_contents($dir . '/.env');
         $this->assertMatchesRegularExpression('/^APP_KEY=base64:.{30,60}$/m', $envData);
 
-        $output = $commandTester->getDisplay();
-        $this->assertStringContainsString("A BookStack install has been initialized at: " . $dir, $output);
+        $result->assertStdoutContains("A BookStack install has been initialized at: " . $dir);
+
+        $this->deleteDirectory($dir);
+    }
+
+    public function test_command_custom_path_validation()
+    {
+        $dir = $this->getEmptyTestDir();
+        $file = $dir . '/out.txt';
+        file_put_contents($file, 'hello');
+
+        $result = $this->runCommand('init', ['target-directory' => $file]);
+        $result->assertErrorExit();
+        $result->assertStderrContains("Was provided [{$file}] as an install path but existing file provided.");
+
+        $result = $this->runCommand('init', ['target-directory' => $dir]);
+        $result->assertErrorExit();
+        $result->assertStderrContains("Expected install directory to be empty but existing files found in [{$dir}] target location.");
+
+        $result = $this->runCommand('init', ['target-directory' => '/my/duck/says/hello']);
+        $result->assertErrorExit();
+        $result->assertStderrContains("Could not resolve provided [/my/duck/says/hello] path to an existing folder.");
 
         $this->deleteDirectory($dir);
     }
index 4cd1bcd842e7079adbcf91da5cecfa0615b70741..92cc2b6b49e504a37347742eb3fe21f7e96752ac 100644 (file)
@@ -40,14 +40,20 @@ class TestCase extends \PHPUnit\Framework\TestCase
         return require dirname(__DIR__) . '/src/app.php';
     }
 
-    protected function runCommand(string $command, array $args = []): CommandTester
+    protected function runCommand(string $command, array $args = []): CommandResult
     {
         $app = $this->getApp();
         $command = $app->find($command);
 
+        $err = null;
         $commandTester = new CommandTester($command);
-        $commandTester->execute($args);
 
-        return $commandTester;
+        try {
+            $commandTester->execute($args);
+        } catch (\Exception $exception) {
+            $err = $exception;
+        }
+
+        return new CommandResult($commandTester, $err);
     }
 }
\ No newline at end of file