diff --git a/.gitignore b/.gitignore index b576366..b9ca4e9 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ node_modules bower_components js/dist composer.lock +.phpunit.result.cache diff --git a/composer.json b/composer.json index 01922d3..a73a2ac 100644 --- a/composer.json +++ b/composer.json @@ -53,18 +53,36 @@ }, "flarum-cli": { "modules": { - "githubActions": true + "githubActions": true, + "backendTesting": true } } }, "require-dev": { - "flarum/phpstan": "*" + "flarum/phpstan": "*", + "flarum/testing": "^1.0.0" }, "scripts": { "analyse:phpstan": "phpstan analyse", - "clear-cache:phpstan": "phpstan clear-result-cache" + "clear-cache:phpstan": "phpstan clear-result-cache", + "test": [ + "@test:unit", + "@test:integration" + ], + "test:unit": "phpunit -c tests/phpunit.unit.xml", + "test:integration": "phpunit -c tests/phpunit.integration.xml", + "test:setup": "@php tests/integration/setup.php" }, "scripts-descriptions": { - "analyse:phpstan": "Run static analysis" + "analyse:phpstan": "Run static analysis", + "test": "Runs all tests.", + "test:unit": "Runs all unit tests.", + "test:integration": "Runs all integration tests.", + "test:setup": "Sets up a database for use with integration tests. Execute this only once." + }, + "autoload-dev": { + "psr-4": { + "FoF\\Filter\\Tests\\": "tests/" + } } } diff --git a/tests/fixtures/.gitkeep b/tests/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/api/CreatePostTest.php b/tests/integration/api/CreatePostTest.php new file mode 100644 index 0000000..ba913d3 --- /dev/null +++ b/tests/integration/api/CreatePostTest.php @@ -0,0 +1,105 @@ +extension('flarum-flags', 'flarum-approval', 'fof-filter'); + + $this->prepareDatabase([ + 'users' => [ + $this->normalUser(), + ], + 'settings' => [ + ['key' => 'fof-filter.words', 'value' => 'wibble'.PHP_EOL.'wobble'.PHP_EOL], + ['key' => 'fof-filter.censors', 'value' => '["\/(w|w\\.|w\\-|\u03c9|\u03c8|\u03a8)(i|i\\.|i\\-|!|\\||\\]\\[|]|1|\u222b|\u00cc|\u00cd|\u00ce|\u00cf|\u00ec|\u00ed|\u00ee|\u00ef)(b|b\\.|b\\-|8|\\|3|\u00df|\u0392|\u03b2)(b|b\\.|b\\-|8|\\|3|\u00df|\u0392|\u03b2)(l|1\\.|l\\-|!|\\||\\]\\[|]|\u00a3|\u222b|\u00cc|\u00cd|\u00ce|\u00cf)(e|e\\.|e\\-|3|\u20ac|\u00c8|\u00e8|\u00c9|\u00e9|\u00ca|\u00ea|\u2211)\/i","\/(w|w\\.|w\\-|\u03c9|\u03c8|\u03a8)(o|o\\.|o\\-|0|\u039f|\u03bf|\u03a6|\u00a4|\u00b0|\u00f8)(b|b\\.|b\\-|8|\\|3|\u00df|\u0392|\u03b2)(b|b\\.|b\\-|8|\\|3|\u00df|\u0392|\u03b2)(l|1\\.|l\\-|!|\\||\\]\\[|]|\u00a3|\u222b|\u00cc|\u00cd|\u00ce|\u00cf)(e|e\\.|e\\-|3|\u20ac|\u00c8|\u00e8|\u00c9|\u00e9|\u00ca|\u00ea|\u2211)\/i"]'] + ] + ]); + + parent::setUp(); + + } + + /** + * @test + */ + public function create_discussion_without_any_bad_words() + { + $response = $this->send( + $this->request('POST', '/api/discussions', [ + 'authenticatedAs' => 2, + 'json' => [ + 'data' => [ + 'attributes' => [ + 'title' => 'test - too-obscure', + 'content' => 'predetermined content for automated testing - too-obscure', + ], + ] + ], + ]) + ); + + $this->assertEquals(201, $response->getStatusCode()); + + /** @var Discussion $discussion */ + $discussion = Discussion::firstOrFail(); + $data = json_decode($response->getBody()->getContents(), true); + + $this->assertEquals('test - too-obscure', $discussion->title); + $this->assertEquals('test - too-obscure', Arr::get($data, 'data.attributes.title')); + + $post = $discussion->firstPost; + + $this->assertNotNull($post); + $this->assertEquals('predetermined content for automated testing - too-obscure', $post->content); + + $this->assertTrue($post->is_approved); + $this->assertTrue($discussion->is_approved); + } + + /** + * @test + */ + public function create_discussion_with_bad_words() + { + $response = $this->send( + $this->request('POST', '/api/discussions', [ + 'authenticatedAs' => 2, + 'json' => [ + 'data' => [ + 'attributes' => [ + 'title' => 'test - wibble', + 'content' => 'predetermined content for automated testing - wibble', + ], + ] + ], + ]) + ); + + $this->assertEquals(201, $response->getStatusCode()); + + /** @var Discussion $discussion */ + $discussion = Discussion::firstOrFail(); + $data = json_decode($response->getBody()->getContents(), true); + + $this->assertEquals('test - wibble', $discussion->title); + $this->assertEquals('test - wibble', Arr::get($data, 'data.attributes.title')); + + $post = $discussion->firstPost; + + $this->assertNotNull($post); + $this->assertEquals('predetermined content for automated testing - wibble', $post->content); + + $this->assertFalse($post->is_approved); + $this->assertFalse($discussion->is_approved); + } +} diff --git a/tests/integration/setup.php b/tests/integration/setup.php new file mode 100644 index 0000000..67039c0 --- /dev/null +++ b/tests/integration/setup.php @@ -0,0 +1,16 @@ +run(); diff --git a/tests/phpunit.integration.xml b/tests/phpunit.integration.xml new file mode 100644 index 0000000..90fbbff --- /dev/null +++ b/tests/phpunit.integration.xml @@ -0,0 +1,25 @@ + + + + + ../src/ + + + + + ./integration + ./integration/tmp + + + diff --git a/tests/phpunit.unit.xml b/tests/phpunit.unit.xml new file mode 100644 index 0000000..d3a4a3e --- /dev/null +++ b/tests/phpunit.unit.xml @@ -0,0 +1,27 @@ + + + + + ../src/ + + + + + ./unit + + + + + + diff --git a/tests/unit/.gitkeep b/tests/unit/.gitkeep new file mode 100644 index 0000000..e69de29