diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml
index 793bebb..ea60fea 100644
--- a/.github/workflows/backend.yml
+++ b/.github/workflows/backend.yml
@@ -6,7 +6,7 @@ jobs:
run:
uses: flarum/framework/.github/workflows/REUSABLE_backend.yml@2.x
with:
- enable_backend_testing: false
+ enable_backend_testing: true
enable_phpstan: true
backend_directory: .
diff --git a/composer.json b/composer.json
index 686e3fb..8388fc7 100644
--- a/composer.json
+++ b/composer.json
@@ -54,17 +54,35 @@
}
},
"require-dev": {
+ "flarum/audit": "2.x-dev",
"flarum/phpstan": "^2.0.0",
"flarum/testing": "^2.0.0",
"flarum/tags": "*",
- "flarum/flags": "*"
+ "flarum/flags": "*",
+ "flarum/realtime": "*"
},
"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\\Split\\Tests\\": "tests/"
+ }
},
"minimum-stability": "beta",
"prefer-stable": true
diff --git a/extend.php b/extend.php
index f32da34..eff943f 100644
--- a/extend.php
+++ b/extend.php
@@ -15,6 +15,8 @@
use Flarum\Api\Context;
use Flarum\Api\Resource;
use Flarum\Api\Schema;
+use Flarum\Audit\AuditLogger;
+use Flarum\Audit\Extend\Audit;
use Flarum\Discussion\Discussion;
use Flarum\Discussion\Event\Renamed;
use Flarum\Extend;
@@ -46,4 +48,25 @@
Schema\Boolean::make('canSplit')
->get(fn (Discussion $discussion, Context $context) => $context->getActor()->can('split', $discussion)),
]),
+
+ (new Extend\Conditional())
+ ->whenExtensionEnabled('flarum-audit', fn () => [
+ (new Audit())
+ ->group('fof-split')
+ ->register('discussion.split_away', 'discussion.split_into')
+ ->using(function () {
+ resolve('events')->listen(DiscussionWasSplit::class, function (DiscussionWasSplit $event) {
+ AuditLogger::log('discussion.split_away', [
+ 'discussion_id' => $event->originalDiscussion->id,
+ 'new_discussion_id' => $event->newDiscussion->id,
+ 'post_count' => $event->posts->count(),
+ ]);
+ AuditLogger::log('discussion.split_into', [
+ 'discussion_id' => $event->newDiscussion->id,
+ 'original_discussion_id' => $event->originalDiscussion->id,
+ 'post_count' => $event->posts->count(),
+ ]);
+ });
+ }),
+ ]),
];
diff --git a/locale/en.yml b/locale/en.yml
index b19bb6c..1731917 100644
--- a/locale/en.yml
+++ b/locale/en.yml
@@ -14,3 +14,13 @@ fof-split:
title: Split discussion
new_discussion_label: Specify the title for the new discussion
submit_button: Split
+
+# Labels for the audit log entries this extension produces, rendered by the (optional)
+# flarum/audit browser. Defined under the flarum-audit namespace so the audit frontend
+# resolves them, but shipped here so they travel with the extension that owns the actions.
+flarum-audit:
+ lib:
+ browser:
+ discussion:
+ split_away: Split {post_count} posts from {discussion} into {new_discussion}
+ split_into: Split {post_count} posts into new discussion {discussion}
diff --git a/tests/fixtures/.gitkeep b/tests/fixtures/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/integration/AuditTest.php b/tests/integration/AuditTest.php
new file mode 100644
index 0000000..bfb6dd9
--- /dev/null
+++ b/tests/integration/AuditTest.php
@@ -0,0 +1,92 @@
+extension('flarum-audit', 'fof-split');
+
+ $date = Carbon::parse('2021-01-01T12:00:00+00:00');
+
+ $this->prepareDatabase([
+ 'audit_log' => [],
+ Discussion::class => [
+ ['id' => 10, 'title' => 'A', 'created_at' => $date, 'last_posted_at' => $date, 'first_post_id' => 1, 'comment_count' => 4],
+ ],
+ Post::class => [
+ ['id' => 1, 'number' => 1, 'discussion_id' => 10, 'created_at' => $date, 'type' => 'comment', 'content' => 'A
'],
+ ['id' => 2, 'number' => 2, 'discussion_id' => 10, 'created_at' => $date, 'type' => 'comment', 'content' => 'B
', 'user_id' => 1],
+ ['id' => 3, 'number' => 3, 'discussion_id' => 10, 'created_at' => $date, 'type' => 'comment', 'content' => 'C
'],
+ ['id' => 4, 'number' => 4, 'discussion_id' => 10, 'created_at' => $date, 'type' => 'comment', 'content' => 'D
'],
+ ],
+ ]);
+ }
+
+ #[Test]
+ public function split()
+ {
+ $response = $this->send($this->request('POST', '/api/split', [
+ 'authenticatedAs' => 1,
+ 'json' => [
+ 'title' => 'Split',
+ 'start_post_id' => 2,
+ 'end_post_number' => 3,
+ ],
+ ]));
+
+ $body = $response->getBody()->getContents();
+
+ $this->assertEquals(200, $response->getStatusCode(), $body);
+
+ $newDiscussionId = Arr::get(json_decode($body, true), 'data.id');
+
+ $log = AuditLog::query()->where('action', 'discussion.split_away')->first();
+ $this->assertNotNull($log);
+ $this->assertEquals(1, $log->actor_id);
+ $this->assertEquals([
+ 'discussion_id' => 10,
+ 'new_discussion_id' => $newDiscussionId,
+ 'post_count' => 2,
+ ], $log->payload);
+ $this->assertEquals('127.0.0.1', $log->ip_address);
+
+ $log = AuditLog::query()->where('action', 'discussion.split_into')->first();
+ $this->assertNotNull($log);
+ $this->assertEquals(1, $log->actor_id);
+ $this->assertEquals([
+ 'discussion_id' => $newDiscussionId,
+ 'original_discussion_id' => 10,
+ 'post_count' => 2,
+ ], $log->payload);
+ $this->assertEquals('127.0.0.1', $log->ip_address);
+ }
+}
diff --git a/tests/integration/setup.php b/tests/integration/setup.php
new file mode 100644
index 0000000..3281430
--- /dev/null
+++ b/tests/integration/setup.php
@@ -0,0 +1,19 @@
+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