From 77bb82bda495fd740417c98220638b8328e4b4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Tue, 17 Apr 2018 11:15:28 +0200 Subject: [PATCH 1/5] Improved foundational backend unit tests (#1405) * part one of adding tests, updating core * Apply fixes from StyleCI [ci skip] [skip ci] * we need xdebug for code coverage, and hhvm was already removed * forgot about the sidecar for mysql completely :facepalm: * gitignore removed this installed json we need to fake that we have extensions * using reguarded closure --- framework/core/.editorconfig | 2 +- framework/core/.gitignore | 2 +- framework/core/.travis.yml | 9 +- framework/core/phpunit.xml | 5 +- .../Install/Console/DataProviderInterface.php | 2 + .../Install/Console/DefaultsDataProvider.php | 12 ++ .../src/Install/Console/FileDataProvider.php | 13 +- .../src/Install/Console/InstallCommand.php | 3 +- .../src/Install/Console/UserDataProvider.php | 5 + .../DefaultInstallationCommandTest.php | 51 ++++++ .../core/tests/Test/Concerns/CreatesForum.php | 150 ++++++++++++++++++ .../tests/Test/Concerns/MakesApiRequests.php | 31 ++++ .../Concerns/RetrievesAuthorizedUsers.php | 37 +++++ framework/core/tests/Test/TestCase.php | 9 +- .../core/tests/tmp/public/assets/.gitkeep | 0 framework/core/tests/tmp/storage/.gitkeep | 0 .../tests/tmp/vendor/composer/installed.json | 1 + 17 files changed, 319 insertions(+), 13 deletions(-) create mode 100644 framework/core/tests/Install/DefaultInstallationCommandTest.php create mode 100644 framework/core/tests/Test/Concerns/CreatesForum.php create mode 100644 framework/core/tests/Test/Concerns/MakesApiRequests.php create mode 100644 framework/core/tests/Test/Concerns/RetrievesAuthorizedUsers.php create mode 100644 framework/core/tests/tmp/public/assets/.gitkeep create mode 100644 framework/core/tests/tmp/storage/.gitkeep create mode 100644 framework/core/tests/tmp/vendor/composer/installed.json diff --git a/framework/core/.editorconfig b/framework/core/.editorconfig index 87694ddab..658a43499 100644 --- a/framework/core/.editorconfig +++ b/framework/core/.editorconfig @@ -15,5 +15,5 @@ indent_size = 2 [*.{diff,md}] trim_trailing_whitespace = false -[*.php] +[*.{php,xml}] indent_size = 4 diff --git a/framework/core/.gitignore b/framework/core/.gitignore index dea5121b7..afb97426c 100644 --- a/framework/core/.gitignore +++ b/framework/core/.gitignore @@ -3,6 +3,6 @@ composer.lock composer.phar .DS_Store Thumbs.db -tests/_output/* +/tests/tmp .vagrant .idea/* diff --git a/framework/core/.travis.yml b/framework/core/.travis.yml index 7d99d4e9e..3a288f4c7 100644 --- a/framework/core/.travis.yml +++ b/framework/core/.travis.yml @@ -1,5 +1,10 @@ language: php +env: + - DB_USERNAME=travis +services: + - mysql + php: - 7.0 - 7.1 @@ -7,9 +12,9 @@ php: matrix: fast_finish: true - +before_install: + - mysql -e 'CREATE DATABASE flarum;' before_script: - - if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then phpenv config-rm xdebug.ini; fi; - composer self-update - composer install diff --git a/framework/core/phpunit.xml b/framework/core/phpunit.xml index c16f17554..6bdd4b7c7 100644 --- a/framework/core/phpunit.xml +++ b/framework/core/phpunit.xml @@ -11,9 +11,12 @@ syntaxCheck="false"> + + ./tests/Install + ./tests + ./tests/Install - diff --git a/framework/core/src/Install/Console/DataProviderInterface.php b/framework/core/src/Install/Console/DataProviderInterface.php index 11fc191c1..9976598e2 100644 --- a/framework/core/src/Install/Console/DataProviderInterface.php +++ b/framework/core/src/Install/Console/DataProviderInterface.php @@ -20,4 +20,6 @@ interface DataProviderInterface public function getAdminUser(); public function getSettings(); + + public function isDebugMode(): bool; } diff --git a/framework/core/src/Install/Console/DefaultsDataProvider.php b/framework/core/src/Install/Console/DefaultsDataProvider.php index c14d3aabd..70f300071 100644 --- a/framework/core/src/Install/Console/DefaultsDataProvider.php +++ b/framework/core/src/Install/Console/DefaultsDataProvider.php @@ -23,6 +23,8 @@ class DefaultsDataProvider implements DataProviderInterface 'port' => '3306', ]; + protected $debug = false; + protected $baseUrl = 'http://flarum.local'; protected $adminUser = [ @@ -96,4 +98,14 @@ class DefaultsDataProvider implements DataProviderInterface { $this->settings[$key] = $value; } + + public function isDebugMode(): bool + { + return $this->debug; + } + + public function setDebugMode(bool $debug = true) + { + $this->debug = $debug; + } } diff --git a/framework/core/src/Install/Console/FileDataProvider.php b/framework/core/src/Install/Console/FileDataProvider.php index 17bb9c5e9..0eb8886f0 100644 --- a/framework/core/src/Install/Console/FileDataProvider.php +++ b/framework/core/src/Install/Console/FileDataProvider.php @@ -18,6 +18,7 @@ use Symfony\Component\Yaml\Yaml; class FileDataProvider implements DataProviderInterface { protected $default; + protected $debug = false; protected $baseUrl = null; protected $databaseConfiguration = []; protected $adminUser = []; @@ -44,10 +45,11 @@ class FileDataProvider implements DataProviderInterface } // Define configuration variables + $this->debug = $configuration['debug'] ?? false; $this->baseUrl = isset($configuration['baseUrl']) ? rtrim($configuration['baseUrl'], '/') : null; - $this->databaseConfiguration = isset($configuration['databaseConfiguration']) ? $configuration['databaseConfiguration'] : []; - $this->adminUser = isset($configuration['adminUser']) ? $configuration['adminUser'] : []; - $this->settings = isset($configuration['settings']) ? $configuration['settings'] : []; + $this->databaseConfiguration = $configuration['databaseConfiguration'] ?? []; + $this->adminUser = $configuration['adminUser'] ?? []; + $this->settings = $configuration['settings'] ?? []; } else { throw new Exception('Configuration file does not exist.'); } @@ -72,4 +74,9 @@ class FileDataProvider implements DataProviderInterface { return $this->settings + $this->default->getSettings(); } + + public function isDebugMode(): bool + { + return $this->debug; + } } diff --git a/framework/core/src/Install/Console/InstallCommand.php b/framework/core/src/Install/Console/InstallCommand.php index 1ce1a2c0a..f3137454e 100644 --- a/framework/core/src/Install/Console/InstallCommand.php +++ b/framework/core/src/Install/Console/InstallCommand.php @@ -138,6 +138,7 @@ class InstallCommand extends AbstractCommand protected function install() { try { + $this->debug = $this->dataSource->isDebugMode(); $this->dbConfig = $this->dataSource->getDatabaseConfiguration(); $validation = $this->getValidator()->make( @@ -214,7 +215,7 @@ class InstallCommand extends AbstractCommand $dbConfig = $this->dbConfig; $config = [ - 'debug' => false, + 'debug' => $this->debug, 'database' => [ 'driver' => $dbConfig['driver'], 'host' => $dbConfig['host'], diff --git a/framework/core/src/Install/Console/UserDataProvider.php b/framework/core/src/Install/Console/UserDataProvider.php index 529e9d8e8..a84df2050 100644 --- a/framework/core/src/Install/Console/UserDataProvider.php +++ b/framework/core/src/Install/Console/UserDataProvider.php @@ -109,4 +109,9 @@ class UserDataProvider implements DataProviderInterface return $this->questionHelper->ask($this->input, $this->output, $question); } + + public function isDebugMode(): bool + { + return false; + } } diff --git a/framework/core/tests/Install/DefaultInstallationCommandTest.php b/framework/core/tests/Install/DefaultInstallationCommandTest.php new file mode 100644 index 000000000..7a8014fc0 --- /dev/null +++ b/framework/core/tests/Install/DefaultInstallationCommandTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tests\Install; + +use Flarum\Install\Console\InstallCommand; +use Flarum\Install\InstallServiceProvider; +use Flarum\Tests\Test\TestCase; +use Flarum\User\User; +use Symfony\Component\Console\Input\StringInput; +use Symfony\Component\Console\Output\StreamOutput; + +class DefaultInstallationCommandTest extends TestCase +{ + protected $isInstalled = false; + + /** + * @test + */ + public function allows_forum_installation() + { + if (file_exists($this->app->basePath().DIRECTORY_SEPARATOR.'config.php')) { + unlink($this->app->basePath().DIRECTORY_SEPARATOR.'config.php'); + } + + $this->app->register(InstallServiceProvider::class); + /** @var InstallCommand $command */ + $command = $this->app->make(InstallCommand::class); + $command->setDataSource($this->configuration); + + $body = fopen('php://temp', 'wb+'); + $input = new StringInput(''); + $output = new StreamOutput($body); + + $command->run($input, $output); + + $this->assertFileExists($this->app->basePath().DIRECTORY_SEPARATOR.'config.php'); + + $admin = $this->configuration->getAdminUser(); + + $this->assertEquals(User::find(1)->username, $admin['username']); + } +} diff --git a/framework/core/tests/Test/Concerns/CreatesForum.php b/framework/core/tests/Test/Concerns/CreatesForum.php new file mode 100644 index 000000000..6be88436d --- /dev/null +++ b/framework/core/tests/Test/Concerns/CreatesForum.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tests\Test\Concerns; + +use Flarum\Database\Migrator; +use Flarum\Foundation\Application; +use Flarum\Foundation\Site; +use Flarum\Http\Server; +use Flarum\Install\Console\DataProviderInterface; +use Flarum\Install\Console\DefaultsDataProvider; +use Illuminate\Database\ConnectionInterface; +use Illuminate\Database\Schema\Builder; + +trait CreatesForum +{ + /** + * @var Server + */ + protected $http; + + /** + * @var Site + */ + protected $site; + + /** + * @var Application + */ + protected $app; + + /** + * @var DataProviderInterface + */ + protected $configuration; + + /** + * Make the test set up Flarum as an installed app. + * + * @var bool + */ + protected $isInstalled = true; + + protected function createsSite() + { + $this->site = (new Site) + ->setBasePath(__DIR__.'/../../tmp') + ->setPublicPath(__DIR__.'/../../tmp/public'); + } + + protected function createsHttpForum() + { + $this->http = Server::fromSite( + $this->site + ); + + $this->app = $this->http->app; + } + + protected function refreshApplication() + { + $this->createsSite(); + + $data = new DefaultsDataProvider(); + + $data->setDebugMode(); + $data->setSetting('mail_driver', 'log'); + + $database = $data->getDatabaseConfiguration(); + $database['database'] = env('DB_DATABASE', 'flarum'); + $database['username'] = env('DB_USERNAME', 'root'); + $database['password'] = env('DB_PASSWORD', ''); + $data->setDatabaseConfiguration($database); + + $this->configuration = $data; + + $this->setsApplicationConfiguration($data); + + $this->seedsApplication(); + + $this->createsHttpForum(); + } + + protected function teardownApplication() + { + /** @var ConnectionInterface $connection */ + $connection = $this->app->make(ConnectionInterface::class); + $connection->rollBack(); + } + + protected function setsApplicationConfiguration(DataProviderInterface $data) + { + if ($this->isInstalled) { + $dbConfig = $data->getDatabaseConfiguration(); + $this->site->setConfig( + $config = [ + 'debug' => $data->isDebugMode(), + 'database' => [ + 'driver' => $dbConfig['driver'], + 'host' => $dbConfig['host'], + 'database' => $dbConfig['database'], + 'username' => $dbConfig['username'], + 'password' => $dbConfig['password'], + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => $dbConfig['prefix'], + 'port' => $dbConfig['port'], + 'strict' => false + ], + 'url' => $data->getBaseUrl(), + 'paths' => [ + 'api' => 'api', + 'admin' => 'admin', + ], + ] + ); + } + } + + protected function seedsApplication() + { + if ($this->isInstalled) { + $app = app(\Illuminate\Contracts\Foundation\Application::class); + + $app->bind(Builder::class, function ($container) { + return $container->make(ConnectionInterface::class)->getSchemaBuilder(); + }); + + /** @var Migrator $migrator */ + $migrator = $app->make(Migrator::class); + if (! $migrator->getRepository()->repositoryExists()) { + $migrator->getRepository()->createRepository(); + } + + $migrator->run(__DIR__.'/../../../migrations'); + + /** @var ConnectionInterface $connection */ + $connection = $app->make(\Illuminate\Database\ConnectionInterface::class); + $connection->beginTransaction(); + } + } +} diff --git a/framework/core/tests/Test/Concerns/MakesApiRequests.php b/framework/core/tests/Test/Concerns/MakesApiRequests.php new file mode 100644 index 000000000..270e501fb --- /dev/null +++ b/framework/core/tests/Test/Concerns/MakesApiRequests.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tests\Test\Concerns; + +use Flarum\Api\ApiServiceProvider; +use Flarum\Api\Client; +use Flarum\User\Guest; +use Flarum\User\User; +use Psr\Http\Message\ResponseInterface; + +trait MakesApiRequests +{ + public function call(string $controller, User $actor = null, array $queryParams = [], array $body = []): ResponseInterface + { + $this->app->register(ApiServiceProvider::class); + $this->app->make('flarum.api.middleware'); + /** @var Client $api */ + $api = $this->app->make(Client::class); + + return $api->send($controller, $actor ?? new Guest, $queryParams, $body); + } +} diff --git a/framework/core/tests/Test/Concerns/RetrievesAuthorizedUsers.php b/framework/core/tests/Test/Concerns/RetrievesAuthorizedUsers.php new file mode 100644 index 000000000..ca4bf581c --- /dev/null +++ b/framework/core/tests/Test/Concerns/RetrievesAuthorizedUsers.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Tests\Test\Concerns; + +use Flarum\User\User; + +trait RetrievesAuthorizedUsers +{ + protected $userAttributes = [ + 'username' => 'normal', + 'password' => 'too-obscure', + 'email' => 'normal@machine.local' + ]; + + public function getAdminUser() + { + return User::find(1); + } + + public function getNormalUser() + { + User::unguarded(function () { + return User::firstOrCreate([ + 'username' => $this->userAttributes['username'] + ], $this->userAttributes); + }); + } +} diff --git a/framework/core/tests/Test/TestCase.php b/framework/core/tests/Test/TestCase.php index b9f2459e2..21dbfff7b 100644 --- a/framework/core/tests/Test/TestCase.php +++ b/framework/core/tests/Test/TestCase.php @@ -11,20 +11,21 @@ namespace Flarum\Tests\Test; -use Mockery; use PHPUnit\Framework\TestCase as Test; abstract class TestCase extends Test { + use Concerns\CreatesForum, + Concerns\MakesApiRequests; + public function setUp() { - Mockery::close(); - + $this->refreshApplication(); $this->init(); } protected function init() { - // To be overloaded by children - saves having to do setUp/mockery::close every time + // .. allows implementation by children without the need to call the parent. } } diff --git a/framework/core/tests/tmp/public/assets/.gitkeep b/framework/core/tests/tmp/public/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/framework/core/tests/tmp/storage/.gitkeep b/framework/core/tests/tmp/storage/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/framework/core/tests/tmp/vendor/composer/installed.json b/framework/core/tests/tmp/vendor/composer/installed.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/framework/core/tests/tmp/vendor/composer/installed.json @@ -0,0 +1 @@ +{} From 4df36063c05a74a11b3f4a2bc1e207ff5ba40a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Klabbers?= Date: Tue, 8 May 2018 10:32:28 +0200 Subject: [PATCH 2/5] fixes session during installation (#1418) * fixes session during installation * Apply fixes from StyleCI [ci skip] [skip ci] * styling of commented code, removed unnecessary import --- framework/core/src/Foundation/Application.php | 8 +++----- framework/core/src/Http/Server.php | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/framework/core/src/Foundation/Application.php b/framework/core/src/Foundation/Application.php index 2753291b5..61c8fd798 100644 --- a/framework/core/src/Foundation/Application.php +++ b/framework/core/src/Foundation/Application.php @@ -119,22 +119,20 @@ class Application extends Container implements ApplicationContract * * @return bool */ - public function isInstalled() + public function isInstalled(): bool { return $this->bound('flarum.config'); } - public function isUpToDate() + public function isUpToDate(): bool { $settings = $this->make(SettingsRepositoryInterface::class); try { $version = $settings->get('version'); } finally { - $isUpToDate = isset($version) && $version === $this->version(); + return isset($version) && $version === $this->version(); } - - return $isUpToDate; } /** diff --git a/framework/core/src/Http/Server.php b/framework/core/src/Http/Server.php index 9c5c1af7c..222d177fe 100644 --- a/framework/core/src/Http/Server.php +++ b/framework/core/src/Http/Server.php @@ -118,7 +118,7 @@ class Server // (Right now it tries to resolve a database connection because of the injected settings repo instance) // We could register a different settings repo when Flarum is not installed //$pipe->pipe($this->app->make(HandleErrors::class, ['debug' => true])); - $pipe->pipe($this->app->make(StartSession::class)); + //$pipe->pipe($this->app->make(StartSession::class)); $pipe->pipe($this->app->make(DispatchRoute::class, ['routes' => $this->app->make('flarum.install.routes')])); return $pipe; From f6398fc2456582b7e76f836988ff9e8dc1aacfa9 Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 8 May 2018 23:56:30 -0700 Subject: [PATCH 3/5] Update icons to "fas" (#1426) * Update icons to "fas" * Install icon change --- .../core/js/admin/src/components/AdminNav.js | 10 +++---- .../js/admin/src/components/ExtensionsPage.js | 6 ++--- .../src/components/PermissionDropdown.js | 16 ++++++------ .../js/admin/src/components/PermissionGrid.js | 26 +++++++++---------- .../admin/src/components/PermissionsPage.js | 2 +- .../admin/src/components/SessionDropdown.js | 2 +- .../admin/src/components/SettingDropdown.js | 4 +-- .../js/admin/src/components/StatusWidget.js | 2 +- .../js/forum/src/components/AvatarEditor.js | 6 ++--- .../js/forum/src/components/CommentPost.js | 2 +- .../core/js/forum/src/components/Composer.js | 8 +++--- .../src/components/DiscussionListItem.js | 4 +-- .../js/forum/src/components/DiscussionPage.js | 2 +- .../DiscussionRenamedNotification.js | 2 +- .../src/components/DiscussionRenamedPost.js | 2 +- .../src/components/DiscussionsSearchSource.js | 2 +- .../forum/src/components/EditPostComposer.js | 2 +- .../forum/src/components/HeaderSecondary.js | 2 +- .../core/js/forum/src/components/IndexPage.js | 8 +++--- .../forum/src/components/NotificationGrid.js | 4 +-- .../forum/src/components/NotificationList.js | 2 +- .../src/components/NotificationsDropdown.js | 2 +- .../core/js/forum/src/components/Post.js | 2 +- .../src/components/PostStreamScrubber.js | 6 ++--- .../js/forum/src/components/ReplyComposer.js | 2 +- .../core/js/forum/src/components/Search.js | 2 +- .../forum/src/components/SessionDropdown.js | 8 +++--- .../js/forum/src/components/TerminalPost.js | 2 +- .../js/forum/src/components/TextEditor.js | 4 +-- .../core/js/forum/src/components/UserCard.js | 4 +-- .../core/js/forum/src/components/UserPage.js | 4 +-- .../js/forum/src/components/WelcomeHero.js | 2 +- .../initializers/alertEmailConfirmation.js | 2 +- .../js/forum/src/utils/DiscussionControls.js | 10 +++---- .../core/js/forum/src/utils/PostControls.js | 6 ++--- .../core/js/forum/src/utils/UserControls.js | 4 +-- framework/core/js/lib/components/Alert.js | 2 +- framework/core/js/lib/components/Checkbox.js | 2 +- framework/core/js/lib/components/Dropdown.js | 2 +- framework/core/js/lib/components/Modal.js | 2 +- .../core/js/lib/components/Navigation.js | 6 ++--- framework/core/js/lib/components/Select.js | 2 +- .../core/js/lib/components/SelectDropdown.js | 2 +- .../core/js/lib/components/SplitDropdown.js | 2 +- framework/core/js/lib/helpers/userOnline.js | 2 +- framework/core/js/lib/models/Discussion.js | 2 +- .../src/Install/Console/InstallCommand.php | 4 +-- 47 files changed, 101 insertions(+), 101 deletions(-) diff --git a/framework/core/js/admin/src/components/AdminNav.js b/framework/core/js/admin/src/components/AdminNav.js index 697a2f440..3e0e82f90 100644 --- a/framework/core/js/admin/src/components/AdminNav.js +++ b/framework/core/js/admin/src/components/AdminNav.js @@ -41,35 +41,35 @@ export default class AdminNav extends Component { items.add('basics', AdminLinkButton.component({ href: app.route('basics'), - icon: 'fa fa-pencil-alt', + icon: 'fas fa-pencil-alt', children: app.translator.trans('core.admin.nav.basics_button'), description: app.translator.trans('core.admin.nav.basics_text') })); items.add('mail', AdminLinkButton.component({ href: app.route('mail'), - icon: 'fa fa-envelope', + icon: 'fas fa-envelope', children: app.translator.trans('core.admin.nav.email_button'), description: app.translator.trans('core.admin.nav.email_text') })); items.add('permissions', AdminLinkButton.component({ href: app.route('permissions'), - icon: 'fa fa-key', + icon: 'fas fa-key', children: app.translator.trans('core.admin.nav.permissions_button'), description: app.translator.trans('core.admin.nav.permissions_text') })); items.add('appearance', AdminLinkButton.component({ href: app.route('appearance'), - icon: 'fa fa-paint-brush', + icon: 'fas fa-paint-brush', children: app.translator.trans('core.admin.nav.appearance_button'), description: app.translator.trans('core.admin.nav.appearance_text') })); items.add('extensions', AdminLinkButton.component({ href: app.route('extensions'), - icon: 'fa fa-puzzle-piece', + icon: 'fas fa-puzzle-piece', children: app.translator.trans('core.admin.nav.extensions_button'), description: app.translator.trans('core.admin.nav.extensions_text') })); diff --git a/framework/core/js/admin/src/components/ExtensionsPage.js b/framework/core/js/admin/src/components/ExtensionsPage.js index dce9fec38..352046771 100644 --- a/framework/core/js/admin/src/components/ExtensionsPage.js +++ b/framework/core/js/admin/src/components/ExtensionsPage.js @@ -17,7 +17,7 @@ export default class ExtensionsPage extends Page {
{Button.component({ children: app.translator.trans('core.admin.extensions.add_button'), - icon: 'fa fa-plus', + icon: 'fas fa-plus', className: 'Button Button--primary', onclick: () => app.modal.show(new AddExtensionModal()) })} @@ -42,7 +42,7 @@ export default class ExtensionsPage extends Page { className="ExtensionListItem-controls" buttonClassName="Button Button--icon Button--flat" menuClassName="Dropdown-menu--right" - icon="fa fa-ellipsis-h"> + icon="fas fa-ellipsis-h"> {controls} ) : ''} @@ -67,7 +67,7 @@ export default class ExtensionsPage extends Page { if (app.extensionSettings[name]) { items.add('settings', Button.component({ - icon: 'fa fa-cog', + icon: 'fas fa-cog', children: app.translator.trans('core.admin.extensions.settings_button'), onclick: app.extensionSettings[name] })); diff --git a/framework/core/js/admin/src/components/PermissionDropdown.js b/framework/core/js/admin/src/components/PermissionDropdown.js index 8e1402e7c..a579cc969 100644 --- a/framework/core/js/admin/src/components/PermissionDropdown.js +++ b/framework/core/js/admin/src/components/PermissionDropdown.js @@ -52,9 +52,9 @@ export default class PermissionDropdown extends Dropdown { const adminGroup = app.store.getById('groups', Group.ADMINISTRATOR_ID); if (everyone) { - this.props.label = Badge.component({icon: 'fa fa-globe'}); + this.props.label = Badge.component({icon: 'fas fa-globe'}); } else if (members) { - this.props.label = Badge.component({icon: 'fa fa-user'}); + this.props.label = Badge.component({icon: 'fas fa-user'}); } else { this.props.label = [ badgeForId(Group.ADMINISTRATOR_ID), @@ -66,8 +66,8 @@ export default class PermissionDropdown extends Dropdown { if (this.props.allowGuest) { this.props.children.push( Button.component({ - children: [Badge.component({icon: 'fa fa-globe'}), ' ', app.translator.trans('core.admin.permissions_controls.everyone_button')], - icon: everyone ? 'fa fa-check' : true, + children: [Badge.component({icon: 'fas fa-globe'}), ' ', app.translator.trans('core.admin.permissions_controls.everyone_button')], + icon: everyone ? 'fas fa-check' : true, onclick: () => this.save([Group.GUEST_ID]), disabled: this.isGroupDisabled(Group.GUEST_ID) }) @@ -76,8 +76,8 @@ export default class PermissionDropdown extends Dropdown { this.props.children.push( Button.component({ - children: [Badge.component({icon: 'fa fa-user'}), ' ', app.translator.trans('core.admin.permissions_controls.members_button')], - icon: members ? 'fa fa-check' : true, + children: [Badge.component({icon: 'fas fa-user'}), ' ', app.translator.trans('core.admin.permissions_controls.members_button')], + icon: members ? 'fas fa-check' : true, onclick: () => this.save([Group.MEMBER_ID]), disabled: this.isGroupDisabled(Group.MEMBER_ID) }), @@ -86,7 +86,7 @@ export default class PermissionDropdown extends Dropdown { Button.component({ children: [badgeForId(adminGroup.id()), ' ', adminGroup.namePlural()], - icon: !everyone && !members ? 'fa fa-check' : true, + icon: !everyone && !members ? 'fas fa-check' : true, disabled: !everyone && !members, onclick: e => { if (e.shiftKey) e.stopPropagation(); @@ -101,7 +101,7 @@ export default class PermissionDropdown extends Dropdown { .filter(group => [Group.ADMINISTRATOR_ID, Group.GUEST_ID, Group.MEMBER_ID].indexOf(group.id()) === -1) .map(group => Button.component({ children: [badgeForId(group.id()), ' ', group.namePlural()], - icon: groupIds.indexOf(group.id()) !== -1 ? 'fa fa-check' : true, + icon: groupIds.indexOf(group.id()) !== -1 ? 'fas fa-check' : true, onclick: (e) => { if (e.shiftKey) e.stopPropagation(); this.toggle(group.id()); diff --git a/framework/core/js/admin/src/components/PermissionGrid.js b/framework/core/js/admin/src/components/PermissionGrid.js index 466bbf501..0eacd4d0a 100644 --- a/framework/core/js/admin/src/components/PermissionGrid.js +++ b/framework/core/js/admin/src/components/PermissionGrid.js @@ -29,7 +29,7 @@ export default class PermissionGrid extends Component { {scopes.map(scope => ( {scope.label}{' '} - {scope.onremove ? Button.component({icon: 'fa fa-times', className: 'Button Button--text PermissionGrid-removeScope', onclick: scope.onremove}) : ''} + {scope.onremove ? Button.component({icon: 'fas fa-times', className: 'Button Button--text PermissionGrid-removeScope', onclick: scope.onremove}) : ''} ))} {this.scopeControlItems().toArray()} @@ -85,21 +85,21 @@ export default class PermissionGrid extends Component { const items = new ItemList(); items.add('viewDiscussions', { - icon: 'fa fa-eye', + icon: 'fas fa-eye', label: app.translator.trans('core.admin.permissions.view_discussions_label'), permission: 'viewDiscussions', allowGuest: true }, 100); items.add('viewUserList', { - icon: 'fa fa-users', + icon: 'fas fa-users', label: app.translator.trans('core.admin.permissions.view_user_list_label'), permission: 'viewUserList', allowGuest: true }, 100); items.add('signUp', { - icon: 'fa fa-user-plus', + icon: 'fas fa-user-plus', label: app.translator.trans('core.admin.permissions.sign_up_label'), setting: () => SettingDropdown.component({ key: 'allow_sign_up', @@ -117,13 +117,13 @@ export default class PermissionGrid extends Component { const items = new ItemList(); items.add('start', { - icon: 'fa fa-edit', + icon: 'fas fa-edit', label: app.translator.trans('core.admin.permissions.start_discussions_label'), permission: 'startDiscussion' }, 100); items.add('allowRenaming', { - icon: 'fa fa-i-cursor', + icon: 'fas fa-i-cursor', label: app.translator.trans('core.admin.permissions.allow_renaming_label'), setting: () => { const minutes = parseInt(app.data.settings.allow_renaming, 10); @@ -149,13 +149,13 @@ export default class PermissionGrid extends Component { const items = new ItemList(); items.add('reply', { - icon: 'fa fa-reply', + icon: 'fas fa-reply', label: app.translator.trans('core.admin.permissions.reply_to_discussions_label'), permission: 'discussion.reply' }, 100); items.add('allowPostEditing', { - icon: 'fa fa-pencil-alt', + icon: 'fas fa-pencil-alt', label: app.translator.trans('core.admin.permissions.allow_post_editing_label'), setting: () => { const minutes = parseInt(app.data.settings.allow_post_editing, 10); @@ -181,13 +181,13 @@ export default class PermissionGrid extends Component { const items = new ItemList(); items.add('viewIpsPosts', { - icon: 'fa fa-bullseye', + icon: 'fas fa-bullseye', label: app.translator.trans('core.admin.permissions.view_post_ips_label'), permission: 'discussion.viewIpsPosts' }, 110); items.add('renameDiscussions', { - icon: 'fa fa-i-cursor', + icon: 'fas fa-i-cursor', label: app.translator.trans('core.admin.permissions.rename_discussions_label'), permission: 'discussion.rename' }, 100); @@ -199,19 +199,19 @@ export default class PermissionGrid extends Component { }, 90); items.add('deleteDiscussions', { - icon: 'fa fa-times', + icon: 'fas fa-times', label: app.translator.trans('core.admin.permissions.delete_discussions_forever_label'), permission: 'discussion.delete' }, 80); items.add('editPosts', { - icon: 'fa fa-pencil-alt', + icon: 'fas fa-pencil-alt', label: app.translator.trans('core.admin.permissions.edit_and_delete_posts_label'), permission: 'discussion.editPosts' }, 70); items.add('deletePosts', { - icon: 'fa fa-times', + icon: 'fas fa-times', label: app.translator.trans('core.admin.permissions.delete_posts_forever_label'), permission: 'discussion.deletePosts' }, 60); diff --git a/framework/core/js/admin/src/components/PermissionsPage.js b/framework/core/js/admin/src/components/PermissionsPage.js index 9896566f9..0484bd08c 100644 --- a/framework/core/js/admin/src/components/PermissionsPage.js +++ b/framework/core/js/admin/src/components/PermissionsPage.js @@ -24,7 +24,7 @@ export default class PermissionsPage extends Page { ))}
diff --git a/framework/core/js/admin/src/components/SessionDropdown.js b/framework/core/js/admin/src/components/SessionDropdown.js index 5d34f683b..7ef99f3f4 100644 --- a/framework/core/js/admin/src/components/SessionDropdown.js +++ b/framework/core/js/admin/src/components/SessionDropdown.js @@ -42,7 +42,7 @@ export default class SessionDropdown extends Dropdown { items.add('logOut', Button.component({ - icon: 'fa fa-sign-out-alt', + icon: 'fas fa-sign-out-alt', children: app.translator.trans('core.admin.header.log_out_button'), onclick: app.session.logout.bind(app.session) }), diff --git a/framework/core/js/admin/src/components/SettingDropdown.js b/framework/core/js/admin/src/components/SettingDropdown.js index f85159372..d404f62a4 100644 --- a/framework/core/js/admin/src/components/SettingDropdown.js +++ b/framework/core/js/admin/src/components/SettingDropdown.js @@ -8,7 +8,7 @@ export default class SettingDropdown extends SelectDropdown { props.className = 'SettingDropdown'; props.buttonClassName = 'Button Button--text'; - props.caretIcon = 'fa fa-caret-down'; + props.caretIcon = 'fas fa-caret-down'; props.defaultLabel = 'Custom'; props.children = props.options.map(({value, label}) => { @@ -16,7 +16,7 @@ export default class SettingDropdown extends SelectDropdown { return Button.component({ children: label, - icon: active ? 'fa fa-check' : true, + icon: active ? 'fas fa-check' : true, onclick: saveSettings.bind(this, {[props.key]: value}), active }); diff --git a/framework/core/js/admin/src/components/StatusWidget.js b/framework/core/js/admin/src/components/StatusWidget.js index ac177af67..8d7a979a0 100644 --- a/framework/core/js/admin/src/components/StatusWidget.js +++ b/framework/core/js/admin/src/components/StatusWidget.js @@ -28,7 +28,7 @@ export default class StatusWidget extends DashboardWidget { items.add('help', ( - {icon('fa fa-question-circle')} {app.translator.trans('core.admin.dashboard.help_link')} + {icon('fas fa-question-circle')} {app.translator.trans('core.admin.dashboard.help_link')} )); diff --git a/framework/core/js/forum/src/components/AvatarEditor.js b/framework/core/js/forum/src/components/AvatarEditor.js index adafcfbae..f9691d93f 100644 --- a/framework/core/js/forum/src/components/AvatarEditor.js +++ b/framework/core/js/forum/src/components/AvatarEditor.js @@ -53,7 +53,7 @@ export default class AvatarEditor extends Component { ondragleave={this.disableDragover.bind(this)} ondragend={this.disableDragover.bind(this)} ondrop={this.dropUpload.bind(this)}> - {this.loading ? LoadingIndicator.component() : (user.avatarUrl() ? icon('fa fa-pencil-alt') : icon('fa fa-plus-circle'))} + {this.loading ? LoadingIndicator.component() : (user.avatarUrl() ? icon('fas fa-pencil-alt') : icon('fas fa-plus-circle'))}
    {listItems(this.controlItems().toArray())} @@ -72,7 +72,7 @@ export default class AvatarEditor extends Component { items.add('upload', Button.component({ - icon: 'fa fa-upload', + icon: 'fas fa-upload', children: app.translator.trans('core.forum.user.avatar_upload_button'), onclick: this.openPicker.bind(this) }) @@ -80,7 +80,7 @@ export default class AvatarEditor extends Component { items.add('remove', Button.component({ - icon: 'fa fa-times', + icon: 'fas fa-times', children: app.translator.trans('core.forum.user.avatar_remove_button'), onclick: this.remove.bind(this) }) diff --git a/framework/core/js/forum/src/components/CommentPost.js b/framework/core/js/forum/src/components/CommentPost.js index 9751936f2..1ee1952cd 100644 --- a/framework/core/js/forum/src/components/CommentPost.js +++ b/framework/core/js/forum/src/components/CommentPost.js @@ -142,7 +142,7 @@ export default class CommentPost extends Post { items.add('toggle', ( Button.component({ className: 'Button Button--default Button--more', - icon: 'fa fa-ellipsis-h', + icon: 'fas fa-ellipsis-h', onclick: this.toggleContent.bind(this) }) )); diff --git a/framework/core/js/forum/src/components/Composer.js b/framework/core/js/forum/src/components/Composer.js index a9ddad421..c6a01b446 100644 --- a/framework/core/js/forum/src/components/Composer.js +++ b/framework/core/js/forum/src/components/Composer.js @@ -422,28 +422,28 @@ class Composer extends Component { if (this.position === Composer.PositionEnum.FULLSCREEN) { items.add('exitFullScreen', ComposerButton.component({ - icon: 'fa fa-compress', + icon: 'fas fa-compress', title: app.translator.trans('core.forum.composer.exit_full_screen_tooltip'), onclick: this.exitFullScreen.bind(this) })); } else { if (this.position !== Composer.PositionEnum.MINIMIZED) { items.add('minimize', ComposerButton.component({ - icon: 'fa fa-minus minimize', + icon: 'fas fa-minus minimize', title: app.translator.trans('core.forum.composer.minimize_tooltip'), onclick: this.minimize.bind(this), itemClassName: 'App-backControl' })); items.add('fullScreen', ComposerButton.component({ - icon: 'fa fa-expand', + icon: 'fas fa-expand', title: app.translator.trans('core.forum.composer.full_screen_tooltip'), onclick: this.fullScreen.bind(this) })); } items.add('close', ComposerButton.component({ - icon: 'fa fa-times', + icon: 'fas fa-times', title: app.translator.trans('core.forum.composer.close_tooltip'), onclick: this.close.bind(this) })); diff --git a/framework/core/js/forum/src/components/DiscussionListItem.js b/framework/core/js/forum/src/components/DiscussionListItem.js index 2b8418c2a..f1e82840e 100644 --- a/framework/core/js/forum/src/components/DiscussionListItem.js +++ b/framework/core/js/forum/src/components/DiscussionListItem.js @@ -81,7 +81,7 @@ export default class DiscussionListItem extends Component { return (
    {controls.length ? Dropdown.component({ - icon: 'fa fa-ellipsis-v', + icon: 'fas fa-ellipsis-v', children: controls, className: 'DiscussionListItem-controls', buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right' @@ -89,7 +89,7 @@ export default class DiscussionListItem extends Component { - {icon('fa fa-check')} + {icon('fas fa-check')}
    diff --git a/framework/core/js/forum/src/components/DiscussionPage.js b/framework/core/js/forum/src/components/DiscussionPage.js index fdb71dbce..bc73a8a46 100644 --- a/framework/core/js/forum/src/components/DiscussionPage.js +++ b/framework/core/js/forum/src/components/DiscussionPage.js @@ -240,7 +240,7 @@ export default class DiscussionPage extends Page { items.add('controls', SplitDropdown.component({ children: DiscussionControls.controls(this.discussion, this).toArray(), - icon: 'fa fa-ellipsis-v', + icon: 'fas fa-ellipsis-v', className: 'App-primaryControl', buttonClassName: 'Button--primary' }) diff --git a/framework/core/js/forum/src/components/DiscussionRenamedNotification.js b/framework/core/js/forum/src/components/DiscussionRenamedNotification.js index 409e55d53..cbaba1d9e 100644 --- a/framework/core/js/forum/src/components/DiscussionRenamedNotification.js +++ b/framework/core/js/forum/src/components/DiscussionRenamedNotification.js @@ -10,7 +10,7 @@ import Notification from 'flarum/components/Notification'; */ export default class DiscussionRenamedNotification extends Notification { icon() { - return 'fa fa-pencil-alt'; + return 'fas fa-pencil-alt'; } href() { diff --git a/framework/core/js/forum/src/components/DiscussionRenamedPost.js b/framework/core/js/forum/src/components/DiscussionRenamedPost.js index 0d0b609f8..d5aa76994 100644 --- a/framework/core/js/forum/src/components/DiscussionRenamedPost.js +++ b/framework/core/js/forum/src/components/DiscussionRenamedPost.js @@ -11,7 +11,7 @@ import extractText from 'flarum/utils/extractText'; */ export default class DiscussionRenamedPost extends EventPost { icon() { - return 'fa fa-pencil-alt'; + return 'fas fa-pencil-alt'; } description(data) { diff --git a/framework/core/js/forum/src/components/DiscussionsSearchSource.js b/framework/core/js/forum/src/components/DiscussionsSearchSource.js index 632c47af0..60c4f4aca 100644 --- a/framework/core/js/forum/src/components/DiscussionsSearchSource.js +++ b/framework/core/js/forum/src/components/DiscussionsSearchSource.js @@ -35,7 +35,7 @@ export default class DiscussionsSearchSource {
  • {app.translator.trans('core.forum.search.discussions_heading')}
  • ,
  • {LinkButton.component({ - icon: 'fa fa-search', + icon: 'fas fa-search', children: app.translator.trans('core.forum.search.all_discussions_button', {query}), href: app.route('index', {q: query}) })} diff --git a/framework/core/js/forum/src/components/EditPostComposer.js b/framework/core/js/forum/src/components/EditPostComposer.js index 9a060b078..8d2460a46 100644 --- a/framework/core/js/forum/src/components/EditPostComposer.js +++ b/framework/core/js/forum/src/components/EditPostComposer.js @@ -52,7 +52,7 @@ export default class EditPostComposer extends ComposerBody { items.add('title', (

    - {icon('fa fa-pencil-alt')} {' '} + {icon('fas fa-pencil-alt')} {' '} {app.translator.trans('core.forum.composer_edit.post_link', {number: post.number(), discussion: post.discussion().title()})} diff --git a/framework/core/js/forum/src/components/HeaderSecondary.js b/framework/core/js/forum/src/components/HeaderSecondary.js index 140179a86..a719b09d8 100644 --- a/framework/core/js/forum/src/components/HeaderSecondary.js +++ b/framework/core/js/forum/src/components/HeaderSecondary.js @@ -46,7 +46,7 @@ export default class HeaderSecondary extends Component { locales.push(Button.component({ active: app.data.locale === locale, children: app.data.locales[locale], - icon: app.data.locale === locale ? 'fa fa-check' : true, + icon: app.data.locale === locale ? 'fas fa-check' : true, onclick: () => { if (app.session.user) { app.session.user.savePreferences({locale}).then(() => window.location.reload()); diff --git a/framework/core/js/forum/src/components/IndexPage.js b/framework/core/js/forum/src/components/IndexPage.js index 51dd89dd0..d1a5401c6 100644 --- a/framework/core/js/forum/src/components/IndexPage.js +++ b/framework/core/js/forum/src/components/IndexPage.js @@ -154,7 +154,7 @@ export default class IndexPage extends Page { items.add('newDiscussion', Button.component({ children: app.translator.trans(canStartDiscussion ? 'core.forum.index.start_discussion_button' : 'core.forum.index.cannot_start_discussion_button'), - icon: 'fa fa-edit', + icon: 'fas fa-edit', className: 'Button Button--primary IndexPage-newDiscussion', itemClassName: 'App-primaryControl', onclick: this.newDiscussion.bind(this), @@ -221,7 +221,7 @@ export default class IndexPage extends Page { return Button.component({ children: label, - icon: active ? 'fa fa-check' : true, + icon: active ? 'fas fa-check' : true, onclick: this.changeSort.bind(this, value), active: active, }) @@ -244,7 +244,7 @@ export default class IndexPage extends Page { items.add('refresh', Button.component({ title: app.translator.trans('core.forum.index.refresh_tooltip'), - icon: 'fa fa-sync', + icon: 'fas fa-sync', className: 'Button Button--icon', onclick: () => { app.cache.discussionList.refresh(); @@ -260,7 +260,7 @@ export default class IndexPage extends Page { items.add('markAllAsRead', Button.component({ title: app.translator.trans('core.forum.index.mark_all_as_read_tooltip'), - icon: 'fa fa-check', + icon: 'fas fa-check', className: 'Button Button--icon', onclick: this.markAllAsRead.bind(this) }) diff --git a/framework/core/js/forum/src/components/NotificationGrid.js b/framework/core/js/forum/src/components/NotificationGrid.js index 5d1b2ad48..3b39f2bfd 100644 --- a/framework/core/js/forum/src/components/NotificationGrid.js +++ b/framework/core/js/forum/src/components/NotificationGrid.js @@ -177,7 +177,7 @@ export default class NotificationGrid extends Component { items.add('alert', { name: 'alert', - icon: 'fa fa-bell', + icon: 'fas fa-bell', label: app.translator.trans('core.forum.settings.notify_by_web_heading'), }); @@ -206,7 +206,7 @@ export default class NotificationGrid extends Component { items.add('discussionRenamed', { name: 'discussionRenamed', - icon: 'fa fa-pencil-alt', + icon: 'fas fa-pencil-alt', label: app.translator.trans('core.forum.settings.notify_discussion_renamed_label') }); diff --git a/framework/core/js/forum/src/components/NotificationList.js b/framework/core/js/forum/src/components/NotificationList.js index c90e38898..bbba4302c 100644 --- a/framework/core/js/forum/src/components/NotificationList.js +++ b/framework/core/js/forum/src/components/NotificationList.js @@ -34,7 +34,7 @@ export default class NotificationList extends Component {
    {Button.component({ className: 'Button Button--icon Button--link', - icon: 'fa fa-check', + icon: 'fas fa-check', title: app.translator.trans('core.forum.notifications.mark_all_as_read_tooltip'), onclick: this.markAllAsRead.bind(this) })} diff --git a/framework/core/js/forum/src/components/NotificationsDropdown.js b/framework/core/js/forum/src/components/NotificationsDropdown.js index 04579a78e..be22a79cf 100644 --- a/framework/core/js/forum/src/components/NotificationsDropdown.js +++ b/framework/core/js/forum/src/components/NotificationsDropdown.js @@ -8,7 +8,7 @@ export default class NotificationsDropdown extends Dropdown { props.buttonClassName = props.buttonClassName || 'Button Button--flat'; props.menuClassName = props.menuClassName || 'Dropdown-menu--right'; props.label = props.label || app.translator.trans('core.forum.notifications.tooltip'); - props.icon = props.icon || 'fa fa-bell'; + props.icon = props.icon || 'fas fa-bell'; super.initProps(props); } diff --git a/framework/core/js/forum/src/components/Post.js b/framework/core/js/forum/src/components/Post.js index b1841afa3..a8050e323 100644 --- a/framework/core/js/forum/src/components/Post.js +++ b/framework/core/js/forum/src/components/Post.js @@ -57,7 +57,7 @@ export default class Post extends Component { className="Post-controls" buttonClassName="Button Button--icon Button--flat" menuClassName="Dropdown-menu--right" - icon="fa fa-ellipsis-h" + icon="fas fa-ellipsis-h" onshow={() => this.$('.Post-actions').addClass('open')} onhide={() => this.$('.Post-actions').removeClass('open')}> {controls} diff --git a/framework/core/js/forum/src/components/PostStreamScrubber.js b/framework/core/js/forum/src/components/PostStreamScrubber.js index c47316e49..8ed1d1c21 100644 --- a/framework/core/js/forum/src/components/PostStreamScrubber.js +++ b/framework/core/js/forum/src/components/PostStreamScrubber.js @@ -84,13 +84,13 @@ export default class PostStreamScrubber extends Component { return (
    diff --git a/framework/core/js/forum/src/components/ReplyComposer.js b/framework/core/js/forum/src/components/ReplyComposer.js index d03dccc84..d33c63b2d 100644 --- a/framework/core/js/forum/src/components/ReplyComposer.js +++ b/framework/core/js/forum/src/components/ReplyComposer.js @@ -51,7 +51,7 @@ export default class ReplyComposer extends ComposerBody { items.add('title', (

    - {icon('fa fa-reply')} {' '} + {icon('fas fa-reply')} {' '} {discussion.title()}

    )); diff --git a/framework/core/js/forum/src/components/Search.js b/framework/core/js/forum/src/components/Search.js index 43ab20597..93512d4ff 100644 --- a/framework/core/js/forum/src/components/Search.js +++ b/framework/core/js/forum/src/components/Search.js @@ -92,7 +92,7 @@ export default class Search extends Component { {this.loadingSources ? LoadingIndicator.component({size: 'tiny', className: 'Button Button--icon Button--link'}) : currentSearch - ? + ? : ''}