diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml new file mode 100644 index 0000000..624436f --- /dev/null +++ b/.github/workflows/backend.yml @@ -0,0 +1,11 @@ +name: FoF Discussion Language PHP + +on: [workflow_dispatch, push, pull_request] + +jobs: + run: + uses: flarum/framework/.github/workflows/REUSABLE_backend.yml@main + with: + enable_backend_testing: true + + backend_directory: . diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index a5d4493..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: JavaScript - -on: - push: - branches: - - master - -jobs: - build: - name: JS / Build - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Restore npm cache - uses: actions/cache@v3 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('js/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - # Our action will install npm, cd into `./js`, run `npm run build` and - # `npm run build-typings`, then commit and upload any changes - - name: Build production JS - uses: flarum/action-build@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - build_script: build - package_manager: npm diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml new file mode 100644 index 0000000..6d6cc29 --- /dev/null +++ b/.github/workflows/frontend.yml @@ -0,0 +1,19 @@ +name: FoF Discussion Language JS + +on: [workflow_dispatch, push, pull_request] + +jobs: + run: + uses: flarum/framework/.github/workflows/REUSABLE_frontend.yml@main + with: + enable_bundlewatch: false + enable_prettier: true + enable_typescript: true + + frontend_directory: ./js + backend_directory: . + js_package_manager: npm + main_git_branch: master + + secrets: + bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 04fdede..3b19fb0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ js/dist js/node_modules vendor composer.lock +.phpunit.result.cache diff --git a/composer.json b/composer.json index 5c0dd61..6383e18 100644 --- a/composer.json +++ b/composer.json @@ -1,67 +1,94 @@ { - "name": "fof/discussion-language", - "description": "Specify the language a discussion is written in & sort by language", - "keywords": [ - "flarum" - ], - "type": "flarum-extension", - "license": "MIT", - "support": { - "issues": "https://github.com/FriendsOfFlarum/discussion-language/issues", - "source": "https://github.com/FriendsOfFlarum/discussion-language", - "forum": "https://discuss.flarum.org/d/23702" - }, - "homepage": "https://friendsofflarum.org", - "funding": [ - { - "type": "website", - "url": "https://opencollective.com/fof/donate" - } - ], - "require": { - "flarum/core": "^1.8.1", - "rinvex/countries": "^6.1.2 || ^7.0.1 || ^8.1.0", - "league/csv": "^9.7", - "ianm/iso-639": "^1.0", - "flarum/tags": "*" - }, - "authors": [ - { - "name": "David Sevilla Martin", - "email": "me+fof@datitisev.me", - "role": "Developer" + "name": "fof/discussion-language", + "description": "Specify the language a discussion is written in & sort by language", + "keywords": [ + "flarum" + ], + "type": "flarum-extension", + "license": "MIT", + "support": { + "issues": "https://github.com/FriendsOfFlarum/discussion-language/issues", + "source": "https://github.com/FriendsOfFlarum/discussion-language", + "forum": "https://discuss.flarum.org/d/23702" }, - { - "name": "IanM", - "email": "ian@flarum.org", - "role": "Developer" - } - ], - "autoload": { - "psr-4": { - "FoF\\DiscussionLanguage\\": "src/" - } - }, - "extra": { - "flarum-extension": { - "title": "FoF Discussion Language", - "category": "feature", - "icon": { - "name": "fas fa-language", - "backgroundColor": "#e74c3c", - "color": "#fff" - }, - "optional-dependencies": [ - "fof/byobu", - "fof/follow-tags" - ] + "homepage": "https://friendsofflarum.org", + "funding": [ + { + "type": "website", + "url": "https://opencollective.com/fof/donate" + } + ], + "require": { + "flarum/core": "^1.8.1", + "rinvex/countries": "^6.1.2 || ^7.0.1 || ^8.1.0", + "league/csv": "^9.7", + "ianm/iso-639": "^1.0", + "flarum/tags": "*" + }, + "authors": [ + { + "name": "David Sevilla Martin", + "email": "me+fof@datitisev.me", + "role": "Developer" + }, + { + "name": "IanM", + "email": "ian@flarum.org", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "FoF\\DiscussionLanguage\\": "src/" + } + }, + "extra": { + "flarum-extension": { + "title": "FoF Discussion Language", + "category": "feature", + "icon": { + "name": "fas fa-language", + "backgroundColor": "#e74c3c", + "color": "#fff" + }, + "optional-dependencies": [ + "fof/byobu", + "fof/follow-tags" + ] + }, + "flagrow": { + "discuss": "https://discuss.flarum.org/d/23702" + }, + "flarum-cli": { + "modules": { + "githubActions": true, + "backendTesting": true + } + } + }, + "require-dev": { + "fof/byobu": "*", + "fof/follow-tags": "*", + "flarum/testing": "^1.0.0" + }, + "autoload-dev": { + "psr-4": { + "FoF\\DiscussionLanguage\\Tests\\": "tests/" + } + }, + "scripts": { + "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" }, - "flagrow": { - "discuss": "https://discuss.flarum.org/d/23702" + "scripts-descriptions": { + "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." } - }, - "require-dev": { - "fof/byobu": "*", - "fof/follow-tags": "*" - } } diff --git a/migrations/2023_09_12_000000_add_language_id_to_tag_user_table.php b/migrations/2023_09_12_000000_add_language_id_to_tag_user_table.php index 174d611..e36c7d4 100644 --- a/migrations/2023_09_12_000000_add_language_id_to_tag_user_table.php +++ b/migrations/2023_09_12_000000_add_language_id_to_tag_user_table.php @@ -14,12 +14,14 @@ return [ 'up' => function (Builder $schema) { - $schema->table('tag_user', function (Blueprint $table) { - $table->integer('dl_language_id')->unsigned()->nullable(); + $schema->table('tag_user', function (Blueprint $table) use ($schema) { + if (!$schema->hasColumn('tag_user', 'dl_language_id')) { + $table->integer('dl_language_id')->unsigned()->nullable(); - $table->foreign('dl_language_id')->references('id')->on('discussion_languages')->onDelete('set null'); + $table->foreign('dl_language_id')->references('id')->on('discussion_languages')->onDelete('set null'); + } - $table->index(['user_id', 'subscription', 'dl_language_id']); + $table->index(['user_id', 'dl_language_id']); $table->index(['dl_language_id']); }); }, @@ -29,7 +31,7 @@ $table->dropForeign(['dl_language_id']); $table->dropIndex(['dl_language_id']); - $table->dropIndex(['user_id', 'subscription', 'dl_language_id']); + $table->dropIndex(['user_id', 'dl_language_id']); $table->dropColumn('dl_language_id'); }); diff --git a/tests/fixtures/.gitkeep b/tests/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/api/CreateLanguageTest.php b/tests/integration/api/CreateLanguageTest.php new file mode 100644 index 0000000..625c704 --- /dev/null +++ b/tests/integration/api/CreateLanguageTest.php @@ -0,0 +1,83 @@ +extension('flarum-tags'); + $this->extension('fof-discussion-language'); + + $this->prepareDatabase([ + 'users' => [ + $this->normalUser(), + ], + ]); + } + + /** + * @test + */ + public function non_admin_cannot_create_language() + { + $response = $this->send( + $this->request('POST', '/api/fof/discussion-language', [ + 'json' => [ + 'data' => [ + 'attributes' => [ + 'country' => 'Test Country', + 'code' => 'test', + ], + ], + ], + 'authenticatedAs' => 2, + ]) + ); + + $this->assertEquals(403, $response->getStatusCode()); + } + + /** + * @test + */ + public function admin_can_create_language() + { + $response = $this->send( + $this->request('POST', '/api/fof/discussion-language', [ + 'json' => [ + 'data' => [ + 'attributes' => [ + 'country' => 'Test Country', + 'code' => 'test', + ], + ], + ], + 'authenticatedAs' => 1, + ]) + ); + + $this->assertEquals(201, $response->getStatusCode()); + + $data = json_decode($response->getBody()->getContents(), true); + + $this->assertEquals('Test Country', $data['data']['attributes']['country']); + $this->assertEquals('test', $data['data']['attributes']['code']); + } +} diff --git a/tests/integration/setup.php b/tests/integration/setup.php new file mode 100644 index 0000000..f8bfb54 --- /dev/null +++ b/tests/integration/setup.php @@ -0,0 +1,18 @@ +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