diff --git a/.github/workflows/composer.test.yml b/.github/workflows/composer.test.yml index 976b0c205..e6d2f61b2 100644 --- a/.github/workflows/composer.test.yml +++ b/.github/workflows/composer.test.yml @@ -50,6 +50,8 @@ jobs: run: docker compose exec -e APP_ENV=testing -T api vendor/bin/phpunit - name: Psalm run: docker compose exec -T api vendor/bin/psalm + - name: Linting + run: docker compose exec api vendor/bin/pint --test -v - name: Run elasticsearch index deletion integration test run: docker compose exec -e RUN_PHPUNIT_INTEGRATION_TEST=1 -e ELASTICSEARCH_HOST=elasticsearch.svc:9200 -T api vendor/bin/phpunit tests/Jobs/Integration/ElasticSearchIndexDeleteTest.php diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 2a595343c..000000000 --- a/.php_cs +++ /dev/null @@ -1,19 +0,0 @@ -setFinder( - PhpCsFixer\Finder::create() - ->in(app_path()) - ->in(config_path()) - ->in(database_path()) - ->notPath(database_path('migrations')) - ->in(resource_path('lang')) - ->in(base_path('routes')) - ->in(base_path('tests')) - ) - ->setRules([ - '@Laravel' => true, - ]); diff --git a/README.md b/README.md index 0c62c5677..d8f06d8cb 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,12 @@ Currently most of the tests require the DB connection to exist. docker compose exec api vendor/bin/phpunit ``` +### Linting + +```sh +docker compose exec api vendor/bin/pint --test -v +``` + #### Debugging If you get a CORS error from an API when testing, it might be due to an exception internally, resulting in a 500 response with no CORS. diff --git a/app/ComplaintRecord.php b/app/ComplaintRecord.php index 7dc435ab2..50cc4c77b 100644 --- a/app/ComplaintRecord.php +++ b/app/ComplaintRecord.php @@ -17,10 +17,10 @@ * @property \Illuminate\Support\Carbon|null $dispatched_at * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at + * * @mixin \Eloquent */ -class ComplaintRecord extends Model -{ +class ComplaintRecord extends Model { use HasFactory; protected $fillable = [ @@ -30,8 +30,7 @@ class ComplaintRecord extends Model 'offending_urls', ]; - public function markAsDispatched() - { + public function markAsDispatched() { $this->dispatched_at = Carbon::now(); } } diff --git a/app/Console/Commands/Invitation/All.php b/app/Console/Commands/Invitation/All.php index 302fef414..f9abe7b93 100644 --- a/app/Console/Commands/Invitation/All.php +++ b/app/Console/Commands/Invitation/All.php @@ -5,8 +5,7 @@ use App\Invitation; use Illuminate\Console\Command; -class All extends Command -{ +class All extends Command { protected $signature = 'wbs-invitation:all'; protected $description = 'List all current invitations'; @@ -16,8 +15,7 @@ class All extends Command * * @return mixed */ - public function handle() - { + public function handle() { foreach (Invitation::all() as $invitation) { $this->line($invitation->code); } diff --git a/app/Console/Commands/Invitation/Create.php b/app/Console/Commands/Invitation/Create.php index 1dcfaf29d..cc09c2da6 100644 --- a/app/Console/Commands/Invitation/Create.php +++ b/app/Console/Commands/Invitation/Create.php @@ -5,8 +5,7 @@ use App\Jobs\InvitationCreateJob; use Illuminate\Console\Command; -class Create extends Command -{ +class Create extends Command { protected $signature = 'wbs-invitation:create {code}'; protected $description = 'Create an invitation'; @@ -16,15 +15,14 @@ class Create extends Command * * @return mixed */ - public function handle() - { + public function handle() { $code = trim($this->argument('code')); $jobResult = (new InvitationCreateJob($code))->handle(); if ($jobResult) { - $this->line('Successfully created invitation: '.$code); + $this->line('Successfully created invitation: ' . $code); } else { - $this->line('Failed to create invitation: '.$code); + $this->line('Failed to create invitation: ' . $code); } return 0; diff --git a/app/Console/Commands/Invitation/CreateBulk.php b/app/Console/Commands/Invitation/CreateBulk.php index 8a53051b5..294241c47 100644 --- a/app/Console/Commands/Invitation/CreateBulk.php +++ b/app/Console/Commands/Invitation/CreateBulk.php @@ -2,12 +2,11 @@ namespace App\Console\Commands\Invitation; +use App\Helper\InviteHelper; use App\Jobs\InvitationCreateJob; use Illuminate\Console\Command; -use App\Helper\InviteHelper; -class CreateBulk extends Command -{ +class CreateBulk extends Command { protected $signature = 'wbs-invitation:create-bulk {numCodes}'; protected $description = 'Create an bulk invitations'; @@ -17,20 +16,19 @@ class CreateBulk extends Command * * @return mixed */ - public function handle() - { + public function handle() { $numCodes = trim($this->argument('numCodes')); - $helper = new InviteHelper(); + $helper = new InviteHelper; - for($i = 0; $i < $numCodes; $i++) { + for ($i = 0; $i < $numCodes; $i++) { $code = $helper->generate(); $jobResult = (new InvitationCreateJob($code))->handle(); if ($jobResult) { - $this->line('Successfully created invitation: '.$code); - } else { - $this->line('Failed to create invitation: '.$code); - } + $this->line('Successfully created invitation: ' . $code); + } else { + $this->line('Failed to create invitation: ' . $code); + } } return 0; diff --git a/app/Console/Commands/Invitation/Delete.php b/app/Console/Commands/Invitation/Delete.php index 753f7821c..a115846dc 100644 --- a/app/Console/Commands/Invitation/Delete.php +++ b/app/Console/Commands/Invitation/Delete.php @@ -5,8 +5,7 @@ use App\Jobs\InvitationDeleteJob; use Illuminate\Console\Command; -class Delete extends Command -{ +class Delete extends Command { protected $signature = 'wbs-invitation:delete {code}'; protected $description = 'Delete an invitation'; @@ -16,8 +15,7 @@ class Delete extends Command * * @return mixed */ - public function handle() - { + public function handle() { $code = trim($this->argument('code')); (new InvitationDeleteJob($code))->handle(); diff --git a/app/Console/Commands/RebuildQueryserviceData.php b/app/Console/Commands/RebuildQueryserviceData.php index 2525cab59..fde73123b 100644 --- a/app/Console/Commands/RebuildQueryserviceData.php +++ b/app/Console/Commands/RebuildQueryserviceData.php @@ -3,18 +3,16 @@ namespace App\Console\Commands; use App\Constants\MediawikiNamespace; +use App\Jobs\SpawnQueryserviceUpdaterJob; +use App\QueryserviceNamespace; use App\Traits; +use App\Wiki; +use App\WikiSetting; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Queue; -use App\Wiki; -use App\WikiSetting; -use App\QueryserviceNamespace; -use App\Jobs\SpawnQueryserviceUpdaterJob; -class RebuildQueryserviceData extends Command -{ +class RebuildQueryserviceData extends Command { use Traits\PageFetcher; protected $signature = 'wbs-qs:rebuild {--domain=*} {--chunkSize=50} {--queueName=manual-intervention} {--sparqlUrlFormat=http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/%s/sparql}'; @@ -22,15 +20,16 @@ class RebuildQueryserviceData extends Command protected $description = 'Rebuild the queryservice data for a certain wiki or all wikis'; protected int $chunkSize; + protected string $sparqlUrlFormat; + protected string $queueName; - public function handle() - { + public function handle() { $this->chunkSize = intval($this->option('chunkSize')); $this->sparqlUrlFormat = $this->option('sparqlUrlFormat'); $this->queueName = $this->option('queueName'); - $this->apiUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php'; + $this->apiUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php'; $wikiDomains = $this->option('domain'); $exitCode = 0; @@ -48,7 +47,7 @@ public function handle() $sparqlUrl = $this->getSparqlUrl($wiki); } catch (\Exception $ex) { Log::error( - 'Failed to get prerequisites for enqueuing wiki '.$wiki->domain.', will not dispatch jobs.', + 'Failed to get prerequisites for enqueuing wiki ' . $wiki->domain . ', will not dispatch jobs.', [$ex], ); $exitCode = 1; @@ -66,24 +65,24 @@ public function handle() } $jobTotal += count($entityChunks); $processedWikis += 1; - Log::info('Dispatched '.count($entityChunks).' job(s) for wiki '.$wiki->domain.'.'); + Log::info('Dispatched ' . count($entityChunks) . ' job(s) for wiki ' . $wiki->domain . '.'); } Log::info( - 'Done. Jobs dispatched: '.$jobTotal.' Wikis processed: '.$processedWikis.' Wikis skipped: '.$skippedWikis + 'Done. Jobs dispatched: ' . $jobTotal . ' Wikis processed: ' . $processedWikis . ' Wikis skipped: ' . $skippedWikis ); + return $exitCode; } - private function getEntitiesForWiki (Wiki $wiki): array - { + private function getEntitiesForWiki(Wiki $wiki): array { $items = $this->fetchPagesInNamespace($wiki->domain, MediawikiNamespace::item); $properties = $this->fetchPagesInNamespace($wiki->domain, MediawikiNamespace::property); $lexemesSetting = WikiSetting::where( [ 'wiki_id' => $wiki->id, - 'name' => WikiSetting::wwExtEnableWikibaseLexeme + 'name' => WikiSetting::wwExtEnableWikibaseLexeme, ], )->first(); $hasLexemesEnabled = $lexemesSetting !== null && $lexemesSetting->value === '1'; @@ -93,22 +92,22 @@ private function getEntitiesForWiki (Wiki $wiki): array $merged = array_merge($items, $properties, $lexemes); $this->stripPrefixes($merged); + return $merged; } - private function getSparqlUrl (Wiki $wiki): string - { + private function getSparqlUrl(Wiki $wiki): string { $match = QueryserviceNamespace::where(['wiki_id' => $wiki->id])->first(); if (!$match) { throw new \Exception( - 'Unable to find queryservice namespace record for wiki '.$wiki->domain + 'Unable to find queryservice namespace record for wiki ' . $wiki->domain ); } + return sprintf($this->sparqlUrlFormat, $match->namespace); } - private static function stripPrefixes (array &$items): void - { + private static function stripPrefixes(array &$items): void { foreach ($items as &$item) { $e = explode(':', $item); $item = end($e); diff --git a/app/Console/Commands/ScheduleStatsUpdates.php b/app/Console/Commands/ScheduleStatsUpdates.php index b74625a91..d0cd65da0 100644 --- a/app/Console/Commands/ScheduleStatsUpdates.php +++ b/app/Console/Commands/ScheduleStatsUpdates.php @@ -2,17 +2,17 @@ namespace App\Console\Commands; -use Illuminate\Console\Command; +use App\Jobs\PlatformStatsSummaryJob; use App\Jobs\SiteStatsUpdateJob; use App\Wiki; -use App\Jobs\PlatformStatsSummaryJob; +use Illuminate\Console\Command; use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Log; + /** * Schedules jobs for updating site_stats per wiki then platformsummaryjob */ -class ScheduleStatsUpdates extends Command -{ +class ScheduleStatsUpdates extends Command { /** * The name and signature of the console command. * @@ -32,8 +32,7 @@ class ScheduleStatsUpdates extends Command * * @return void */ - public function __construct() - { + public function __construct() { parent::__construct(); } @@ -42,20 +41,20 @@ public function __construct() * * @return int */ - public function handle() - { + public function handle() { $siteStatsUpdateJobs = []; foreach (Wiki::all() as $wiki) { $siteStatsUpdateJobs[] = new SiteStatsUpdateJob($wiki->id); } - Log::info(__METHOD__ . ": Scheduling updates for " . count($siteStatsUpdateJobs) . " wikis."); + Log::info(__METHOD__ . ': Scheduling updates for ' . count($siteStatsUpdateJobs) . ' wikis.'); Bus::batch($siteStatsUpdateJobs) ->allowFailures() ->finally(function () { - dispatch(new PlatformStatsSummaryJob()); + dispatch(new PlatformStatsSummaryJob); })->dispatch(); + return 0; } } diff --git a/app/Console/Commands/User/ChangeEmail.php b/app/Console/Commands/User/ChangeEmail.php index 7a2df03a0..78ed2f016 100644 --- a/app/Console/Commands/User/ChangeEmail.php +++ b/app/Console/Commands/User/ChangeEmail.php @@ -2,18 +2,16 @@ namespace App\Console\Commands\User; +use App\Jobs\UserVerificationCreateTokenAndSendJob; use App\User; use Illuminate\Console\Command; -use App\Jobs\UserVerificationCreateTokenAndSendJob; -class ChangeEmail extends Command -{ +class ChangeEmail extends Command { protected $signature = 'wbs-user:change-email {--from=} {--to=}'; protected $description = 'Change e-mail address for user'; - public function handle(): int - { + public function handle(): int { $emailOld = $this->option('from'); $emailNew = $this->option('to'); @@ -21,11 +19,13 @@ public function handle(): int if (!$user) { $this->error("Error: Could not find a user for '$emailOld'."); + return 1; } if ($emailNew == $emailOld) { - $this->error("Error: New email matches current email."); + $this->error('Error: New email matches current email.'); + return 2; } @@ -40,7 +40,8 @@ public function handle(): int return 0; } else { - $this->error("Error: Failed to save changes to the database."); + $this->error('Error: Failed to save changes to the database.'); + return 3; } } diff --git a/app/Console/Commands/User/Verify.php b/app/Console/Commands/User/Verify.php index 94b11d053..d38b44852 100644 --- a/app/Console/Commands/User/Verify.php +++ b/app/Console/Commands/User/Verify.php @@ -5,19 +5,17 @@ use App\User; use Illuminate\Console\Command; -class Verify extends Command -{ +class Verify extends Command { protected $signature = 'wbs-user:verify {email} {verificationState}'; protected $description = 'Set verification state for user'; - public function handle(): int - { + public function handle(): int { $email = $this->argument('email'); $state = (int) $this->argument('verificationState'); $user = User::whereEmail($email)->first(); - if (! $user) { + if (!$user) { $this->error("User not found for $email"); return 1; @@ -25,7 +23,7 @@ public function handle(): int $user->verified = $state; if ($user->save()) { - $this->line("Marked $email as ".($state ? 'verified' : 'not verified')); + $this->line("Marked $email as " . ($state ? 'verified' : 'not verified')); } else { $this->error("Failed to update $email"); } diff --git a/app/Console/Commands/Wiki/Delete.php b/app/Console/Commands/Wiki/Delete.php index 6099ca9b1..78c1be772 100644 --- a/app/Console/Commands/Wiki/Delete.php +++ b/app/Console/Commands/Wiki/Delete.php @@ -5,17 +5,18 @@ use App\Wiki; use Illuminate\Console\Command; -class Delete extends Command -{ +class Delete extends Command { public const SUCCESS = 'Success!'; + public const ERR_WIKI_DOES_NOT_EXIST = 'No wiki was found matching the given key and value.'; + public const ERR_AMBIGUOUS_KEY_VALUE = 'Wiki deletion failed. Multiple wikis match the given key and value.'; protected $signature = 'wbs-wiki:delete {key} {value}'; + protected $description = 'Soft deletes the Wiki matching the given key and value.'; - public function handle(): int - { + public function handle(): int { $key = trim($this->argument('key')); $value = trim($this->argument('value')); @@ -34,6 +35,7 @@ public function handle(): int $wikis->delete(); $this->info(self::SUCCESS); + return 0; } } diff --git a/app/Console/Commands/Wiki/Get.php b/app/Console/Commands/Wiki/Get.php index d242dfc3e..be36d6922 100644 --- a/app/Console/Commands/Wiki/Get.php +++ b/app/Console/Commands/Wiki/Get.php @@ -5,8 +5,7 @@ use App\Wiki; use Illuminate\Console\Command; -class Get extends Command -{ +class Get extends Command { protected $signature = 'wbs-wiki:get {key} {value?}'; protected $description = 'Get Wiki data by key and value.'; @@ -16,8 +15,7 @@ class Get extends Command * * @return mixed */ - public function handle() - { + public function handle() { $key = trim($this->argument('key')); $value = trim($this->argument('value')); // TODO don't select the timestamps and redundant info for the settings? diff --git a/app/Console/Commands/Wiki/SetSetting.php b/app/Console/Commands/Wiki/SetSetting.php index 0d8d907a8..5a0dd6198 100644 --- a/app/Console/Commands/Wiki/SetSetting.php +++ b/app/Console/Commands/Wiki/SetSetting.php @@ -6,8 +6,7 @@ use App\WikiSetting; use Illuminate\Console\Command; -class SetSetting extends Command -{ +class SetSetting extends Command { protected $signature = 'wbs-wiki:setSetting {wikiKey} {wikiValue} {settingKey} {settingValue?}'; protected $description = 'Set a single setting for a wiki.'; @@ -17,31 +16,31 @@ class SetSetting extends Command * * @return mixed */ - public function handle() - { + public function handle() { $wikiKey = trim($this->argument('wikiKey')); $wikiValue = trim($this->argument('wikiValue')); $settingKey = trim($this->argument('settingKey')); $settingValue = $this->argument('settingValue'); - if(is_string($settingValue)) { + if (is_string($settingValue)) { $settingValue = trim($settingValue); } // TODO don't select the timestamps and redundant info for the settings? $wiki = Wiki::where($wikiKey, $wikiValue)->first(); - if (! $wiki) { + if (!$wiki) { $this->error('Wiki not found'); return 1; } $wikiId = $wiki->id; - if($settingValue === null) { + if ($settingValue === null) { WikiSetting::where([ 'wiki_id' => $wiki->id, 'name' => $settingKey, ])->delete(); $this->line("Deleted setting {$settingKey} for wiki id {$wikiId}"); + return; } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index cb3e62f22..b4330d6ac 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,33 +2,29 @@ namespace App\Console; +use App\Jobs\CreateQueryserviceBatchesJob; use App\Jobs\ExpireOldUserVerificationTokensJob; +use App\Jobs\FailStalledEntityImportsJob; +use App\Jobs\PollForMediaWikiJobsJob; use App\Jobs\ProvisionQueryserviceNamespaceJob; use App\Jobs\ProvisionWikiDbJob; use App\Jobs\PruneEventPageUpdatesTable; use App\Jobs\PruneQueryserviceBatchesTable; use App\Jobs\RequeuePendingQsBatchesJob; use App\Jobs\SandboxCleanupJob; -use App\Jobs\PollForMediaWikiJobsJob; -use App\Jobs\UpdateWikiDailyMetricJob; -use App\Jobs\UpdateWikiSiteStatsJob; use App\Jobs\SendEmptyWikiNotificationsJob; -use App\Jobs\CreateQueryserviceBatchesJob; -use App\Jobs\FailStalledEntityImportsJob; use App\Jobs\UpdateQueryserviceAllowList; +use App\Jobs\UpdateWikiDailyMetricJob; +use App\Jobs\UpdateWikiSiteStatsJob; use App\Wiki; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; -class Kernel extends ConsoleKernel -{ +class Kernel extends ConsoleKernel { /** * Define the application's command schedule. - * - * @param \Illuminate\Console\Scheduling\Schedule $schedule */ - protected function schedule(Schedule $schedule): void - { + protected function schedule(Schedule $schedule): void { // Make sure that the DB and QS pools are always populated somewhat. // This will create at most 1 new entry for each per minute... // There are also jobs currently scheduled in Controllers that use up resources from these pools @@ -70,13 +66,12 @@ protected function schedule(Schedule $schedule): void /** * Register the commands for the application. */ - protected function commands(): void - { - $this->load(__DIR__.'/Commands'); - $this->load(__DIR__.'/Commands/User'); - $this->load(__DIR__.'/Commands/Job'); - $this->load(__DIR__.'/Commands/Wiki'); - $this->load(__DIR__.'/Commands/Invitation'); + protected function commands(): void { + $this->load(__DIR__ . '/Commands'); + $this->load(__DIR__ . '/Commands/User'); + $this->load(__DIR__ . '/Commands/Job'); + $this->load(__DIR__ . '/Commands/Wiki'); + $this->load(__DIR__ . '/Commands/Invitation'); require base_path('routes/console.php'); } diff --git a/app/EventPageUpdate.php b/app/EventPageUpdate.php index 39f6d7b64..83882a5e6 100644 --- a/app/EventPageUpdate.php +++ b/app/EventPageUpdate.php @@ -15,6 +15,7 @@ * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\Wiki $wiki + * * @method static \Illuminate\Database\Eloquent\Builder|\App\EventPageUpdate newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\EventPageUpdate newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\EventPageUpdate query() @@ -24,10 +25,10 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\EventPageUpdate whereTitle($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\EventPageUpdate whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\EventPageUpdate whereWikiId($value) + * * @mixin \Eloquent */ -class EventPageUpdate extends Model -{ +class EventPageUpdate extends Model { use HasFactory; protected $fillable = [ @@ -37,12 +38,9 @@ class EventPageUpdate extends Model ]; /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Wiki::class); } } diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index a6ec12f04..27ab98a43 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -5,8 +5,7 @@ use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Throwable; -class Handler extends ExceptionHandler -{ +class Handler extends ExceptionHandler { /** * The list of the inputs that are never flashed to the session on validation exceptions. * @@ -20,11 +19,9 @@ class Handler extends ExceptionHandler /** * Register the exception handling callbacks for the application. */ - public function register(): void - { + public function register(): void { $this->reportable(function (Throwable $e) { (new \Absszero\ErrorReporting)->report($e); }); } } - diff --git a/app/Helper/DomainHelper.php b/app/Helper/DomainHelper.php index 35fd459a4..24305a52a 100644 --- a/app/Helper/DomainHelper.php +++ b/app/Helper/DomainHelper.php @@ -2,25 +2,25 @@ /* The purpose of this class to offer helper functions for safely * encoding/decoding domain names that contain non-ASCII characters. - * + * * Currently this just wraps around the PHP IDN functions: * https://www.php.net/manual/en/ref.intl.idn.php - * + * * The difference is that this wrapper returns a string in any case, * either encoded or decoded. The native functions can return * boolean `false` on failure. - * + * */ namespace App\Helper; class DomainHelper { // @return string - the domain name encoded in ASCII-compatible form - static public function encode($string) { + public static function encode($string) { $result = idn_to_ascii($string); // return the original input if encoding failed - if (false === $result) { + if ($result === false) { $result = $string; } @@ -28,11 +28,11 @@ static public function encode($string) { } // @return string - the domain name in Unicode, encoded in UTF-8 - static public function decode($string) { + public static function decode($string) { $result = idn_to_utf8($string); // return the original input if decoding failed - if (false === $result) { + if ($result === false) { $result = $string; } diff --git a/app/Helper/DomainValidator.php b/app/Helper/DomainValidator.php index 5963c3ab8..9aa30079e 100644 --- a/app/Helper/DomainValidator.php +++ b/app/Helper/DomainValidator.php @@ -1,26 +1,23 @@ subDomainSuffix = $subDomainSuffix; $this->subdomainRules = $subdomainRules; } - public function validate( $domain ): \Illuminate\Validation\Validator { + public function validate($domain): \Illuminate\Validation\Validator { - $isSubdomain = WikiController::isSubDomain( $domain, $this->subDomainSuffix ); + $isSubdomain = WikiController::isSubDomain($domain, $this->subDomainSuffix); if ($isSubdomain) { $subDomainSuffixLength = strlen($this->subDomainSuffix); @@ -29,12 +26,12 @@ public function validate( $domain ): \Illuminate\Validation\Validator { // This also stops things like mail. www. pop. ETC... $requiredLength = $requiredSubdomainPrefixChars + $subDomainSuffixLength; $domainRequirements = array_merge( - [ - 'required', - 'unique:wikis', - 'unique:wiki_domains', - 'min:' . $requiredLength, - 'regex:/^[a-z0-9-]+' . preg_quote( $this->subDomainSuffix ) . '$/', + [ + 'required', + 'unique:wikis', + 'unique:wiki_domains', + 'min:' . $requiredLength, + 'regex:/^[a-z0-9-]+' . preg_quote($this->subDomainSuffix) . '$/', ], $this->subdomainRules ); @@ -42,9 +39,8 @@ public function validate( $domain ): \Illuminate\Validation\Validator { $domainRequirements = 'required|unique:wikis|unique:wiki_domains|min:4|regex:/[a-z0-9-]+\.[a-z]+$/'; } - return Validator::make(['domain' => $domain ], [ + return Validator::make(['domain' => $domain], [ 'domain' => $domainRequirements, ]); } - } diff --git a/app/Helper/ElasticSearchHelper.php b/app/Helper/ElasticSearchHelper.php index 16d5a9663..983ab8c3c 100644 --- a/app/Helper/ElasticSearchHelper.php +++ b/app/Helper/ElasticSearchHelper.php @@ -1,25 +1,26 @@ elasticSearchHost = $elasticSearchHost; $this->elasticSearchBaseName = $elasticSearchBaseName; } - public function hasIndices( HttpRequest $request ): bool { - + public function hasIndices(HttpRequest $request): bool { + $hasIndices = true; // Make an initial request to see if there is anything - $url = $this->elasticSearchHost."/_cat/indices/{$this->elasticSearchBaseName}*?v&s=index&h=index"; - $request->setOptions( + $url = $this->elasticSearchHost . "/_cat/indices/{$this->elasticSearchBaseName}*?v&s=index&h=index"; + $request->setOptions( [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, @@ -33,20 +34,20 @@ public function hasIndices( HttpRequest $request ): bool { $rawResponse = $request->execute(); $err = $request->error(); $request->close(); - - if ( $err ) { - throw new \RuntimeException('curl error for '.$this->elasticSearchBaseName.': '.$err); + + if ($err) { + throw new \RuntimeException('curl error for ' . $this->elasticSearchBaseName . ': ' . $err); } // Example response: - // + // // index\n // site1.localhost_content_blabla\n // site1.localhost_general_bla\n $wikiIndices = array_filter(explode("\n", $rawResponse)); // no indices to delete only index header - if( count($wikiIndices) <= 1 ) { + if (count($wikiIndices) <= 1) { $hasIndices = false; } diff --git a/app/Helper/InviteHelper.php b/app/Helper/InviteHelper.php index 6a573da8f..618bed4f8 100644 --- a/app/Helper/InviteHelper.php +++ b/app/Helper/InviteHelper.php @@ -1,31 +1,31 @@ prefix = "wbcloud-"; + public function __construct(int $numSegments = 2, int $segmentLength = 4) { + $this->prefix = 'wbcloud-'; $this->segments = $numSegments; $this->segmentLength = $segmentLength; } - private function generateSegment( int &$counter ): string { - $segment = ""; + private function generateSegment(int &$counter): string { + $segment = ''; - for($i = 0; $i < $this->segmentLength; $i++) { - $segment .= rand(0, 9); + for ($i = 0; $i < $this->segmentLength; $i++) { + $segment .= rand(0, 9); } $counter++; - - if($counter < $this->segments) { - return $segment . '-' . $this->generateSegment( $counter ); + + if ($counter < $this->segments) { + return $segment . '-' . $this->generateSegment($counter); } return $segment; @@ -33,8 +33,7 @@ private function generateSegment( int &$counter ): string { public function generate(): string { $counter = 0; - return $this->prefix . $this->generateSegment( $counter ); - } - + return $this->prefix . $this->generateSegment($counter); + } } diff --git a/app/Helper/MWTimestampHelper.php b/app/Helper/MWTimestampHelper.php index 17a3bbc5f..0d781a1a5 100644 --- a/app/Helper/MWTimestampHelper.php +++ b/app/Helper/MWTimestampHelper.php @@ -7,21 +7,22 @@ */ namespace App\Helper; + use Carbon\CarbonImmutable; class MWTimestampHelper { - private const MWTimestampFormat = 'YmdHis'; - static public function getCarbonFromMWTimestamp( string $MWTimestamp ): CarbonImmutable { - $carbon = CarbonImmutable::createFromFormat( self::MWTimestampFormat, $MWTimestamp ); + public static function getCarbonFromMWTimestamp(string $MWTimestamp): CarbonImmutable { + $carbon = CarbonImmutable::createFromFormat(self::MWTimestampFormat, $MWTimestamp); if ($carbon === false) { throw new \Exception('Unable to create Carbon object'); } + return $carbon; } - static public function getMWTimestampFromCarbon(CarbonImmutable $carbonImmutable): string { + public static function getMWTimestampFromCarbon(CarbonImmutable $carbonImmutable): string { return $carbonImmutable->format(self::MWTimestampFormat); } -} \ No newline at end of file +} diff --git a/app/Helper/ProfileValidator.php b/app/Helper/ProfileValidator.php index 71f848d49..5d8036b88 100644 --- a/app/Helper/ProfileValidator.php +++ b/app/Helper/ProfileValidator.php @@ -1,12 +1,11 @@ 'in:data_hub,data_lab,tool_lab,test_drive,decide_later,other', @@ -17,5 +16,4 @@ public function validate( $profile ): \Illuminate\Validation\Validator { 'temporality_other' => 'string|required_if:temporality,other|missing_unless:temporality,other', ]); } - -} \ No newline at end of file +} diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 2bf87cd61..4d230679a 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -5,8 +5,7 @@ use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\SendsPasswordResetEmails; -class ForgotPasswordController extends Controller -{ +class ForgotPasswordController extends Controller { /* |-------------------------------------------------------------------------- | Password Reset Controller @@ -25,18 +24,15 @@ class ForgotPasswordController extends Controller * * @return void */ - public function __construct() - { + public function __construct() { $this->middleware('guest'); } - protected function sendResetLinkResponse(): \Illuminate\Http\JsonResponse - { + protected function sendResetLinkResponse(): \Illuminate\Http\JsonResponse { return response()->json('Success', 200); } - protected function sendResetLinkFailedResponse(): \Illuminate\Http\JsonResponse - { + protected function sendResetLinkFailedResponse(): \Illuminate\Http\JsonResponse { return response()->json('Success', 200); } } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 5e0b25048..d2b1431cf 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -7,21 +7,18 @@ use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Cookie; use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Cookie; -class LoginController extends Controller -{ +class LoginController extends Controller { use ThrottlesLogins; // Used by ThrottlesLogins - protected function username(): string - { + protected function username(): string { return 'email'; } - private static function getCookie(string $token): \Symfony\Component\HttpFoundation\Cookie - { + private static function getCookie(string $token): \Symfony\Component\HttpFoundation\Cookie { return Cookie::make( Config::get('auth.cookies.key'), $token, @@ -35,37 +32,33 @@ private static function getCookie(string $token): \Symfony\Component\HttpFoundat ); } - private static function deleteCookie(): \Symfony\Component\HttpFoundation\Cookie - { + private static function deleteCookie(): \Symfony\Component\HttpFoundation\Cookie { return Cookie::forget( Config::get('auth.cookies.key'), Config::get('auth.cookies.path'), ); } - public function getLogin(Request $request) - { + public function getLogin(Request $request) { return response()->json([ 'user' => $request->user(), ]); } - public function deleteLogin(Request $request) - { + public function deleteLogin(Request $request) { return response() ->json() ->setStatusCode(204) ->withCookie($this->deleteCookie()); } - public function postLogin(Request $request): ?\Illuminate\Http\JsonResponse - { + public function postLogin(Request $request): ?\Illuminate\Http\JsonResponse { // Validation $rules = [ - // Do not specify that the email is required to exist, as this exposes that a user is registered... - 'email' => 'required', - 'password' => 'required', - ]; + // Do not specify that the email is required to exist, as this exposes that a user is registered... + 'email' => 'required', + 'password' => 'required', + ]; $request->validate($rules); // Throttle @@ -77,8 +70,8 @@ public function postLogin(Request $request): ?\Illuminate\Http\JsonResponse // Try login $data = [ - 'email' => $request->get('email'), - 'password' => $request->get('password'), + 'email' => $request->get('email'), + 'password' => $request->get('password'), ]; if (Auth::attempt($data)) { @@ -88,12 +81,13 @@ public function postLogin(Request $request): ?\Illuminate\Http\JsonResponse $user = Auth::user(); return response()->json([ - 'user' => $user, // <- we're sending the user info for frontend usage + 'user' => $user, // <- we're sending the user info for frontend usage ])->withCookie( $this->getCookie($user->createToken('yourAppName')->accessToken) ); } else { $this->incrementLoginAttempts($request); + return response()->json('Unauthorized', 401); } } diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 2d3c5b9d4..d2861a841 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -3,7 +3,6 @@ namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; -use App\Jobs\InvitationDeleteJob; use App\Jobs\UserCreateJob; use App\Jobs\UserVerificationCreateTokenAndSendJob; use App\Rules\ReCaptchaValidation; @@ -13,8 +12,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; -class RegisterController extends Controller -{ +class RegisterController extends Controller { /** * @var \App\Rules\ReCaptchaValidation */ @@ -27,19 +25,17 @@ public function __construct(ReCaptchaValidation $recaptchaValidation) { /** * Handle a registration request for the application. * - * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ - public function register(Request $request) - { + public function register(Request $request) { $this->validator($request->all())->validate(); $user = null; DB::transaction(function () use (&$user, $request) { - $user = ( new UserCreateJob( - $request->input('email'), - $request->input('password') - ))->handle(); + $user = (new UserCreateJob( + $request->input('email'), + $request->input('password') + ))->handle(); (UserVerificationCreateTokenAndSendJob::newForAccountCreation($user))->handle(); }); @@ -66,16 +62,15 @@ public function register(Request $request) /** * Get a validator for an incoming registration request. * - * @param array $data * @return \Illuminate\Contracts\Validation\Validator */ - protected function validator(array $data) - { + protected function validator(array $data) { $validation = [ 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], - 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], - 'password' => ['required', 'string', 'min:8'], + 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], + 'password' => ['required', 'string', 'min:8'], ]; + return Validator::make($data, $validation); } } diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index 9f93896d4..9d71f0564 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -5,8 +5,7 @@ use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; -class ResetPasswordController extends Controller -{ +class ResetPasswordController extends Controller { /* |-------------------------------------------------------------------------- | Password Reset Controller @@ -32,18 +31,15 @@ class ResetPasswordController extends Controller * * @return void */ - public function __construct() - { + public function __construct() { $this->middleware('guest'); } - protected function sendResetResponse(): \Illuminate\Http\JsonResponse - { + protected function sendResetResponse(): \Illuminate\Http\JsonResponse { return response()->json('Success', 200); } - protected function sendResetFailedResponse(): \Illuminate\Http\JsonResponse - { + protected function sendResetFailedResponse(): \Illuminate\Http\JsonResponse { return response()->json('Unauthorized', 401); } } diff --git a/app/Http/Controllers/Auth/VerificationController.php b/app/Http/Controllers/Auth/VerificationController.php index c9480f107..88f75042e 100644 --- a/app/Http/Controllers/Auth/VerificationController.php +++ b/app/Http/Controllers/Auth/VerificationController.php @@ -5,8 +5,7 @@ use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\VerifiesEmails; -class VerificationController extends Controller -{ +class VerificationController extends Controller { /* |-------------------------------------------------------------------------- | Email Verification Controller @@ -32,12 +31,11 @@ class VerificationController extends Controller * * @return void */ - public function __construct() - { + public function __construct() { // TODO don't use this controller, use my own! $this->middleware('auth'); // https://laravel-news.com/signed-routes - //$this->middleware('signed')->only('verify'); + // $this->middleware('signed')->only('verify'); $this->middleware('throttle:6,1')->only('verify', 'resend'); } } diff --git a/app/Http/Controllers/Backend/EventController.php b/app/Http/Controllers/Backend/EventController.php index 6ac2b1289..c549d2b17 100644 --- a/app/Http/Controllers/Backend/EventController.php +++ b/app/Http/Controllers/Backend/EventController.php @@ -5,15 +5,12 @@ use App\Http\Controllers\Controller; use Illuminate\Http\Request; -class EventController extends Controller -{ - public function pageUpdate(Request $request): void - { +class EventController extends Controller { + public function pageUpdate(Request $request): void { \App\EventPageUpdate::create(json_decode($request->getContent(), true)); } - public function pageUpdateBatch(Request $request): void - { + public function pageUpdateBatch(Request $request): void { \App\EventPageUpdate::insert(json_decode($request->getContent(), true)); } } diff --git a/app/Http/Controllers/Backend/IngressController.php b/app/Http/Controllers/Backend/IngressController.php index 54c026e37..fd95f1e60 100644 --- a/app/Http/Controllers/Backend/IngressController.php +++ b/app/Http/Controllers/Backend/IngressController.php @@ -6,10 +6,8 @@ use App\Wiki; use Illuminate\Http\Request; -class IngressController extends Controller -{ - public function getWikiVersionForDomain(Request $request): \Illuminate\Http\Response - { +class IngressController extends Controller { + public function getWikiVersionForDomain(Request $request): \Illuminate\Http\Response { $domain = $request->query('domain'); $version = Wiki::where('domain', $domain) ->whereNull('deleted_at') @@ -20,6 +18,7 @@ public function getWikiVersionForDomain(Request $request): \Illuminate\Http\Resp if (is_null($version)) { abort(401); } + return response('1')->header('x-version', $version); } } diff --git a/app/Http/Controllers/Backend/QsController.php b/app/Http/Controllers/Backend/QsController.php index a7ee0e364..126182316 100644 --- a/app/Http/Controllers/Backend/QsController.php +++ b/app/Http/Controllers/Backend/QsController.php @@ -8,16 +8,14 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; -class QsController extends Controller -{ - public function getBatches(Request $request): \Illuminate\Http\Response - { +class QsController extends Controller { + public function getBatches(Request $request): \Illuminate\Http\Response { return DB::transaction(function () { $oldestBatch = QsBatch::has('wiki') ->where([ ['done', '=', 0], ['pending_since', '=', null], - ['failed', '=', false] + ['failed', '=', false], ]) ->orderBy('id') ->lockForUpdate() @@ -29,28 +27,29 @@ public function getBatches(Request $request): \Illuminate\Http\Response $oldestBatch->update(['pending_since' => Carbon::now()]); $oldestBatch->load(['wiki', 'wiki.wikiQueryserviceNamespace']); + return response([$oldestBatch]); }, 3); } - public function markBatchesDone(Request $request): \Illuminate\Http\Response - { + public function markBatchesDone(Request $request): \Illuminate\Http\Response { $batches = (array) $request->json()->all('batches'); QsBatch::whereIn('id', $batches)->increment( 'processing_attempts', 1, ['done' => 1, 'pending_since' => null] ); + return response('1'); } - public function markBatchesNotDone(Request $request): \Illuminate\Http\Response - { + public function markBatchesNotDone(Request $request): \Illuminate\Http\Response { $batches = (array) $request->json()->all('batches'); QsBatch::whereIn('id', $batches)->increment( 'processing_attempts', 1, ['done' => 0, 'pending_since' => null] ); + return response('1'); } } diff --git a/app/Http/Controllers/Backend/WikiController.php b/app/Http/Controllers/Backend/WikiController.php index 2343cd32d..8fccf7781 100644 --- a/app/Http/Controllers/Backend/WikiController.php +++ b/app/Http/Controllers/Backend/WikiController.php @@ -6,12 +6,10 @@ use App\Wiki; use Illuminate\Http\Request; -class WikiController extends Controller -{ +class WikiController extends Controller { private static $with = ['wikiDb', 'wikiQueryserviceNamespace', 'settings']; - public function getWikiForDomain(Request $request): \Illuminate\Http\JsonResponse - { + public function getWikiForDomain(Request $request): \Illuminate\Http\JsonResponse { $domain = $request->input('domain'); // XXX: this same logic is in quickstatements.php and platform api WikiController backend diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index d59941c15..2088fcd0a 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -2,18 +2,16 @@ namespace App\Http\Controllers; -use App\Notifications\ComplaintNotificationExternal; +use App\ComplaintRecord; use App\Notifications\ComplaintNotification; +use App\Notifications\ComplaintNotificationExternal; use App\Rules\ReCaptchaValidation; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; -use App\ComplaintRecord; -use Illuminate\Support\Facades\Log; -class ComplaintController extends Controller -{ +class ComplaintController extends Controller { /** * @var \App\Rules\ReCaptchaValidation */ @@ -25,11 +23,8 @@ public function __construct(ReCaptchaValidation $recaptchaValidation) { /** * Handle a complaint report page request for the application. - * - * @param \Illuminate\Http\Request $request */ - public function sendMessage(Request $request): \Illuminate\Http\JsonResponse - { + public function sendMessage(Request $request): \Illuminate\Http\JsonResponse { $validator = $this->validator($request->all()); if ($validator->fails()) { @@ -51,9 +46,9 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse $complaintRecord->offending_urls = $validated['url']; $complaintRecord->save(); - if (! empty($complaintRecord->mail_address)) { + if (!empty($complaintRecord->mail_address)) { Notification::route('mail', [ - $complaintRecord->mail_address, + $complaintRecord->mail_address, ])->notify( new ComplaintNotificationExternal( $complaintRecord->offending_urls, @@ -67,11 +62,11 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse Notification::route('mail', [ config('app.complaint-mail-recipient'), ])->notify( - new ComplaintNotification( - $complaintRecord->offending_urls, - $complaintRecord->reason, - $complaintRecord->name, - $complaintRecord->mail_address, + new ComplaintNotification( + $complaintRecord->offending_urls, + $complaintRecord->reason, + $complaintRecord->name, + $complaintRecord->mail_address, ) ); @@ -84,18 +79,17 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse /** * Get a validator for an incoming complaint report page request. */ - protected function validator(array $data): \Illuminate\Validation\Validator - { + protected function validator(array $data): \Illuminate\Validation\Validator { $data['name'] = $data['name'] ?? ''; $data['email'] = $data['email'] ?? ''; $validation = [ - 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], - 'name' => ['nullable', 'string', 'max:300'], - 'message' => ['required', 'string', 'max:1000'], - 'url' => ['required', 'string', 'max:1000'], + 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], + 'name' => ['nullable', 'string', 'max:300'], + 'message' => ['required', 'string', 'max:1000'], + 'url' => ['required', 'string', 'max:1000'], - 'email' => [ + 'email' => [ 'nullable', 'max:300', Rule::when( diff --git a/app/Http/Controllers/ContactController.php b/app/Http/Controllers/ContactController.php index 7e7c91a35..37f5734ea 100644 --- a/app/Http/Controllers/ContactController.php +++ b/app/Http/Controllers/ContactController.php @@ -5,12 +5,11 @@ use App\Notifications\ContactNotification; use App\Rules\ReCaptchaValidation; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; -class ContactController extends Controller -{ +class ContactController extends Controller { /** * @var \App\Rules\ReCaptchaValidation */ @@ -22,11 +21,8 @@ public function __construct(ReCaptchaValidation $recaptchaValidation) { /** * Handle a contact page request for the application. - * - * @param \Illuminate\Http\Request $request */ - public function sendMessage(Request $request): \Illuminate\Http\JsonResponse - { + public function sendMessage(Request $request): \Illuminate\Http\JsonResponse { $validator = $this->validator($request->all()); if ($validator->fails()) { @@ -58,9 +54,8 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse /** * Get a validator for an incoming contact page request. */ - protected function validator(array $data): \Illuminate\Validation\Validator - { - if (! isset($data['contactDetails'])) { + protected function validator(array $data): \Illuminate\Validation\Validator { + if (!isset($data['contactDetails'])) { $data['contactDetails'] = ''; // could we skip this using some feature of the validator? } @@ -73,10 +68,10 @@ protected function validator(array $data): \Illuminate\Validation\Validator ]; $validation = [ - 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], - 'subject' => ['required', 'string', 'max:300', Rule::in($validSubjects)], - 'name' => ['required', 'string', 'max:300'], - 'message' => ['required', 'string', 'max:10000'], + 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], + 'subject' => ['required', 'string', 'max:300', Rule::in($validSubjects)], + 'name' => ['required', 'string', 'max:300'], + 'message' => ['required', 'string', 'max:10000'], 'contactDetails' => ['string', 'nullable', 'max:300'], ]; diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 77ec359ab..3074b9c9e 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -6,7 +6,6 @@ use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; -class Controller extends BaseController -{ +class Controller extends BaseController { use AuthorizesRequests, ValidatesRequests; } diff --git a/app/Http/Controllers/ConversionMetricController.php b/app/Http/Controllers/ConversionMetricController.php index acdf0bd31..aab72ffa9 100644 --- a/app/Http/Controllers/ConversionMetricController.php +++ b/app/Http/Controllers/ConversionMetricController.php @@ -4,29 +4,24 @@ use App\Wiki; use Carbon\CarbonImmutable; -use Illuminate\Http\Response; use Illuminate\Http\Request; -class ConversionMetricController extends Controller -{ - - private string $fileName="conversion_metric_for_all_wikis.csv"; +class ConversionMetricController extends Controller { + private string $fileName = 'conversion_metric_for_all_wikis.csv'; /** * Produce a downloadable csv file with conversion metrics for all wikis. */ - public function index(Request $request) - { + public function index(Request $request) { $allWikis = Wiki::all(); $current_date = CarbonImmutable::now(); $output = []; - foreach ($allWikis as $wiki) { $lifecycleEvents = $wiki->wikiLifecycleEvents()->orderBy('id', 'desc')->first(); $wikiLastEditedTime = null; $wikiFirstEditedTime = null; - if (!empty($lifecycleEvents) ) { + if (!empty($lifecycleEvents)) { if ($lifecycleEvents['last_edited']) { $wikiLastEditedTime = CarbonImmutable::parse($lifecycleEvents['last_edited']); } @@ -52,30 +47,31 @@ public function index(Request $request) 'number_of_active_editors' => $wiki_number_of_editors, 'wiki_creation_time' => $wiki->created_at, 'first_edited_time' => $wikiFirstEditedTime, - 'last_edited_time' => $wikiLastEditedTime + 'last_edited_time' => $wikiLastEditedTime, ]; } - if ( $request->wantsJson() ) { - return response()->json( $output ); + if ($request->wantsJson()) { + return response()->json($output); } return $this->returnCsv($output); } - private function returnCsv( $output ) { + private function returnCsv($output) { ob_start(); - $handle = fopen('php://output', 'r+'); + $handle = fopen('php://output', 'r+'); fputcsv($handle, ['domain_name', 'time_to_engage_days', 'time_before_wiki_abandoned_days', 'number_of_active_editors', 'wiki_creation_time', 'first_edited_time', 'last_edited_time']); foreach ($output as $wikiMetrics) { fputcsv($handle, array_values($wikiMetrics)); } $csv = ob_get_clean(); + return response($csv, 200, [ - 'Content-Type' => 'text/csv', - 'Content-Disposition' => 'attachment;filename='.CarbonImmutable::now()->toIso8601String().'-'.$this->fileName - ]);; + 'Content-Type' => 'text/csv', + 'Content-Disposition' => 'attachment;filename=' . CarbonImmutable::now()->toIso8601String() . '-' . $this->fileName, + ]); } } diff --git a/app/Http/Controllers/DeletedWikiMetricsController.php b/app/Http/Controllers/DeletedWikiMetricsController.php index 390ae56b0..5992ac4e4 100644 --- a/app/Http/Controllers/DeletedWikiMetricsController.php +++ b/app/Http/Controllers/DeletedWikiMetricsController.php @@ -6,22 +6,20 @@ use Carbon\CarbonImmutable; use Illuminate\Http\Request; -class DeletedWikiMetricsController extends Controller -{ - - private string $fileName="deleted_wiki_metric.csv"; +class DeletedWikiMetricsController extends Controller { + private string $fileName = 'deleted_wiki_metric.csv'; /** * Produce a downloadable csv file with deleted wiki metrics. */ - public function index(Request $request) - { + public function index(Request $request) { $allDeletedWikis = Wiki::onlyTrashed()->get(); $output = $this->createOutput($allDeletedWikis); + return $this->returnCsv($output); } - private function returnCsv( $output ) { + private function returnCsv($output) { ob_start(); $handle = fopen('php://output', 'r+'); fputcsv($handle, [ @@ -37,13 +35,13 @@ private function returnCsv( $output ) { fputcsv($handle, array_values($deletedWikiMetrics)); } $csv = ob_get_clean(); + return response($csv, 200, [ 'Content-Type' => 'text/csv', - 'Content-Disposition' => 'attachment;filename='.CarbonImmutable::now()->toIso8601String().'-'.$this->fileName ]); + 'Content-Disposition' => 'attachment;filename=' . CarbonImmutable::now()->toIso8601String() . '-' . $this->fileName]); } - private function createOutput($wikis): array - { + private function createOutput($wikis): array { $output = []; foreach ($wikis as $wiki) { $output[] = [ @@ -53,9 +51,10 @@ private function createOutput($wikis): array 'number_of_wiki_pages_for_wiki' => $wiki->wikiSiteStats()->first()->pages ?? null, 'number_of_users_for_wiki' => $wiki->wikiSiteStats()->first()->users ?? null, 'wiki_creation_time' => $wiki->created_at, - 'wiki_deletion_time' => $wiki->deleted_at + 'wiki_deletion_time' => $wiki->deleted_at, ]; } + return $output; } } diff --git a/app/Http/Controllers/PublicWikiController.php b/app/Http/Controllers/PublicWikiController.php index 554186044..ca4d3e7da 100644 --- a/app/Http/Controllers/PublicWikiController.php +++ b/app/Http/Controllers/PublicWikiController.php @@ -2,16 +2,15 @@ namespace App\Http\Controllers; +use App\Http\Resources\PublicWikiResource; +use App\Wiki; use App\WikiSiteStats; use Illuminate\Http\Request; -use App\Wiki; -use App\Http\Resources\PublicWikiResource; -class PublicWikiController extends Controller -{ +class PublicWikiController extends Controller { private static $defaultParams = [ 'sort' => 'sitename', - 'direction' => 'asc' + 'direction' => 'asc', ]; private static $activeThresholdPageCount = 2; @@ -19,15 +18,14 @@ class PublicWikiController extends Controller /** * Display a listing of the resource. */ - public function index(Request $request) - { + public function index(Request $request) { $request->validate([ 'sort' => 'in:sitename,pages', 'direction' => 'in:desc,asc', 'is_featured' => 'boolean', 'is_active' => 'boolean', 'per_page' => 'numeric', - 'page' => 'numeric' + 'page' => 'numeric', ]); $params = array_merge(self::$defaultParams, $request->input()); @@ -35,7 +33,7 @@ public function index(Request $request) if (array_key_exists('is_featured', $params)) { $query = $query->where([ - 'is_featured' => boolval($params['is_featured']) + 'is_featured' => boolval($params['is_featured']), ]); } @@ -46,20 +44,20 @@ public function index(Request $request) } switch ($params['sort']) { - case 'sitename': - $query = $query->orderBy( - 'sitename', - $params['direction'] - ); - break; - case 'pages': - $query = $query->orderBy( - WikiSiteStats::query() - ->select('pages') - ->whereColumn('wiki_site_stats.wiki_id', 'wikis.id'), - $params['direction'] - ); - break; + case 'sitename': + $query = $query->orderBy( + 'sitename', + $params['direction'] + ); + break; + case 'pages': + $query = $query->orderBy( + WikiSiteStats::query() + ->select('pages') + ->whereColumn('wiki_site_stats.wiki_id', 'wikis.id'), + $params['direction'] + ); + break; } $perPage = null; @@ -73,8 +71,7 @@ public function index(Request $request) /** * Display the specified resource. */ - public function show($id) - { + public function show($id) { return new PublicWikiResource(Wiki::findOrFail($id)); } } diff --git a/app/Http/Controllers/Sandbox/SandboxController.php b/app/Http/Controllers/Sandbox/SandboxController.php index 6d3340f83..37d8e5971 100644 --- a/app/Http/Controllers/Sandbox/SandboxController.php +++ b/app/Http/Controllers/Sandbox/SandboxController.php @@ -17,14 +17,14 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Support\Str; -class SandboxController extends Controller -{ +class SandboxController extends Controller { const WIKIBASE_DOMAIN = 'wikibase.cloud'; + const MW_VERSION = 'mw1.35-wbs1'; + const DOT = '.'; - public function create(Request $request): \Illuminate\Http\Response - { + public function create(Request $request): \Illuminate\Http\Response { $validation = [ 'recaptcha' => 'required|captcha', // TODO validate dataSet param @@ -37,7 +37,7 @@ public function create(Request $request): \Illuminate\Http\Response $wiki = null; DB::transaction(function () use (&$wiki, $domain) { - $wikiDbCondition = ['wiki_id'=>null, 'version'=> self::MW_VERSION]; + $wikiDbCondition = ['wiki_id' => null, 'version' => self::MW_VERSION]; // Fail if there is not enough storage ready if (WikiDb::where($wikiDbCondition)->count() == 0) { @@ -54,11 +54,11 @@ public function create(Request $request): \Illuminate\Http\Response // Assign storage $dbAssignment = DB::table('wiki_dbs')->where($wikiDbCondition)->limit(1)->update(['wiki_id' => $wiki->id]); - if (! $dbAssignment) { + if (!$dbAssignment) { abort(503, 'Database ready, but failed to assign'); } - $nsAssignment = DB::table('queryservice_namespaces')->where(['wiki_id'=>null])->limit(1)->update(['wiki_id' => $wiki->id]); - if (! $nsAssignment) { + $nsAssignment = DB::table('queryservice_namespaces')->where(['wiki_id' => null])->limit(1)->update(['wiki_id' => $wiki->id]); + if (!$nsAssignment) { abort(503, 'QS Namespace ready, but failed to assign'); } @@ -103,27 +103,25 @@ public function create(Request $request): \Illuminate\Http\Response return response($res); } - private function generateUnusedDomain() - { + private function generateUnusedDomain() { $domain = $this->generateDomain(); - if (! WikiDomain::whereDomain($domain)->first()) { + if (!WikiDomain::whereDomain($domain)->first()) { return $domain; } return $this->generateUnusedDomain(); } - private function generateDomain(): string - { - $generator = new HumanPasswordGenerator(); + private function generateDomain(): string { + $generator = new HumanPasswordGenerator; $generator - ->setWordList(__DIR__.'/words') - ->setWordCount(3) - ->setWordSeparator('-'); + ->setWordList(__DIR__ . '/words') + ->setWordCount(3) + ->setWordSeparator('-'); $password = $generator->generatePassword(); - return $password.self::DOT.self::WIKIBASE_DOMAIN; + return $password . self::DOT . self::WIKIBASE_DOMAIN; } } diff --git a/app/Http/Controllers/UserVerificationTokenController.php b/app/Http/Controllers/UserVerificationTokenController.php index 45e936a6e..97d017cce 100644 --- a/app/Http/Controllers/UserVerificationTokenController.php +++ b/app/Http/Controllers/UserVerificationTokenController.php @@ -10,10 +10,8 @@ /** * Verification of user emails. */ -class UserVerificationTokenController extends Controller -{ - public function verify(Request $request): \Illuminate\Http\Response - { +class UserVerificationTokenController extends Controller { + public function verify(Request $request): \Illuminate\Http\Response { $request->validate([ 'token' => 'required|exists:user_verification_tokens,token', ]); @@ -39,8 +37,7 @@ public function verify(Request $request): \Illuminate\Http\Response return response($res); } - public function createAndSendForUser(Request $request): \Illuminate\Http\Response - { + public function createAndSendForUser(Request $request): \Illuminate\Http\Response { $user = $request->user(); if ($user->verified) { diff --git a/app/Http/Controllers/WikiController.php b/app/Http/Controllers/WikiController.php index f4516bfe4..b54eed5d8 100644 --- a/app/Http/Controllers/WikiController.php +++ b/app/Http/Controllers/WikiController.php @@ -2,13 +2,15 @@ namespace App\Http\Controllers; +use App\Helper\DomainHelper; +use App\Helper\DomainValidator; use App\Helper\ProfileValidator; +use App\Jobs\CirrusSearch\ElasticSearchIndexInit; +use App\Jobs\ElasticSearchAliasInit; use App\Jobs\KubernetesIngressCreate; use App\Jobs\MediawikiInit; use App\Jobs\ProvisionQueryserviceNamespaceJob; use App\Jobs\ProvisionWikiDbJob; -use App\Jobs\CirrusSearch\ElasticSearchIndexInit; -use App\Jobs\ElasticSearchAliasInit; use App\QueryserviceNamespace; use App\Wiki; use App\WikiDb; @@ -17,25 +19,21 @@ use App\WikiProfile; use App\WikiSetting; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; -use Illuminate\Support\Facades\Config; -use App\Helper\DomainValidator; -use App\Helper\DomainHelper; -class WikiController extends Controller -{ +class WikiController extends Controller { private $domainValidator; + private $profileValidator; - public function __construct( DomainValidator $domainValidator, ProfileValidator $profileValidator ) - { + public function __construct(DomainValidator $domainValidator, ProfileValidator $profileValidator) { $this->profileValidator = $profileValidator; $this->domainValidator = $domainValidator; } - public function create(Request $request): \Illuminate\Http\Response - { + public function create(Request $request): \Illuminate\Http\Response { $clusterWithoutSharedIndex = Config::get('wbstack.elasticsearch_cluster_without_shared_index'); $sharedIndexHost = Config::get('wbstack.elasticsearch_shared_index_host'); $sharedIndexPrefix = Config::get('wbstack.elasticsearch_shared_index_prefix'); @@ -50,7 +48,7 @@ public function create(Request $request): \Illuminate\Http\Response $submittedDomain = strtolower($request->input('domain')); $submittedDomain = DomainHelper::encode($submittedDomain); - $domainValidator = $this->domainValidator->validate( $submittedDomain ); + $domainValidator = $this->domainValidator->validate($submittedDomain); $isSubdomain = $this->isSubDomain($submittedDomain); $domainValidator->validateWithBag('post'); @@ -63,7 +61,7 @@ public function create(Request $request): \Illuminate\Http\Response ]); $rawProfile = false; - if ($request->filled('profile') ) { + if ($request->filled('profile')) { $rawProfile = json_decode($request->input('profile'), true); $profileValidator = $this->profileValidator->validate($rawProfile); $profileValidator->validateWithBag('post'); @@ -75,7 +73,7 @@ public function create(Request $request): \Illuminate\Http\Response // TODO create with some sort of owner etc? DB::transaction(function () use ($user, $request, &$wiki, &$dbAssignment, $isSubdomain, $submittedDomain, $rawProfile) { $dbVersion = Config::get('wbstack.wiki_db_use_version'); - $wikiDbCondition = ['wiki_id'=>null, 'version'=>$dbVersion]; + $wikiDbCondition = ['wiki_id' => null, 'version' => $dbVersion]; // Fail if there is not enough storage ready if (WikiDb::where($wikiDbCondition)->count() == 0) { @@ -88,22 +86,22 @@ public function create(Request $request): \Illuminate\Http\Response $numWikis = $user->managesWikis()->count() + 1; $maxWikis = config('wbstack.wiki_max_per_user'); - if ( config('wbstack.wiki_max_per_user') !== false && $numWikis > config('wbstack.wiki_max_per_user')) { + if (config('wbstack.wiki_max_per_user') !== false && $numWikis > config('wbstack.wiki_max_per_user')) { abort(403, "Too many wikis. Your new total of {$numWikis} would exceed the limit of {$maxWikis} per user."); } $wiki = Wiki::create([ 'sitename' => $request->input('sitename'), - 'domain' => $submittedDomain, + 'domain' => $submittedDomain, ]); // Assign storage $dbAssignment = DB::table('wiki_dbs')->where($wikiDbCondition)->limit(1)->update(['wiki_id' => $wiki->id]); - if (! $dbAssignment) { + if (!$dbAssignment) { abort(503, 'Database ready, but failed to assign'); } - $nsAssignment = DB::table('queryservice_namespaces')->where(['wiki_id'=>null])->limit(1)->update(['wiki_id' => $wiki->id]); - if (! $nsAssignment) { + $nsAssignment = DB::table('queryservice_namespaces')->where(['wiki_id' => null])->limit(1)->update(['wiki_id' => $wiki->id]); + if (!$nsAssignment) { abort(503, 'QS Namespace ready, but failed to assign'); } @@ -155,20 +153,19 @@ public function create(Request $request): \Illuminate\Http\Response ]); $ownerAssignment = WikiManager::create([ - 'user_id' => $user->id, - 'wiki_id' => $wiki->id, + 'user_id' => $user->id, + 'wiki_id' => $wiki->id, ]); // Create WikiProfile if ($rawProfile) { - WikiProfile::create([ 'wiki_id' => $wiki->id, ...$rawProfile ] ); + WikiProfile::create(['wiki_id' => $wiki->id, ...$rawProfile]); } - // TODO maybe always make these run in a certain order..? dispatch(new MediawikiInit($wiki->domain, $request->input('username'), $user->email)); // Only dispatch a job to add a k8s ingress IF we are using a custom domain... - if (! $isSubdomain) { + if (!$isSubdomain) { dispatch(new KubernetesIngressCreate($wiki->id, $wiki->domain)); } }); @@ -198,25 +195,23 @@ public function create(Request $request): \Illuminate\Http\Response return response($res); } - public function delete(Request $request): \Illuminate\Http\JsonResponse - { + public function delete(Request $request): \Illuminate\Http\JsonResponse { $wikiDeletionReason = $request->input('deletionReasons'); $wiki = $request->attributes->get('wiki'); - if(isset($wikiDeletionReason)){ - //Save the wiki deletion reason + if (isset($wikiDeletionReason)) { + // Save the wiki deletion reason $wiki->update(['wiki_deletion_reason' => $wikiDeletionReason]); } // Delete the wiki $wiki->delete(); // Return a success - return response()->json("Success", 200); + return response()->json('Success', 200); } // TODO should this just be get wiki? - public function getWikiDetailsForIdForOwner(Request $request): \Illuminate\Http\Response - { + public function getWikiDetailsForIdForOwner(Request $request): \Illuminate\Http\Response { $wiki = $request->attributes->get('wiki') ->load('wikiManagers') ->load('wikiDbVersion') @@ -225,14 +220,15 @@ public function getWikiDetailsForIdForOwner(Request $request): \Illuminate\Http\ $res = [ 'success' => true, - 'data' => $wiki, + 'data' => $wiki, ]; return response($res); } - public static function isSubDomain( string $domain, string $subDomainSuffix = null ): bool { + public static function isSubDomain(string $domain, ?string $subDomainSuffix = null): bool { $subDomainSuffix = $subDomainSuffix ?? Config::get('wbstack.subdomain_suffix'); - return preg_match('/' . preg_quote( $subDomainSuffix ) . '$/', $domain) === 1; + + return preg_match('/' . preg_quote($subDomainSuffix) . '$/', $domain) === 1; } } diff --git a/app/Http/Controllers/WikiEntityImportController.php b/app/Http/Controllers/WikiEntityImportController.php index 595323655..08afe2ada 100644 --- a/app/Http/Controllers/WikiEntityImportController.php +++ b/app/Http/Controllers/WikiEntityImportController.php @@ -2,22 +2,21 @@ namespace App\Http\Controllers; +use App\Jobs\WikiEntityImportJob; +use App\WikiEntityImport; use App\WikiEntityImportStatus; +use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Validation\Rule; -use App\WikiEntityImport; -use App\Jobs\WikiEntityImportJob; -use Carbon\Carbon; use Prometheus\CollectorRegistry; use Prometheus\Counter; -class WikiEntityImportController extends Controller -{ +class WikiEntityImportController extends Controller { private Counter $successfulCounter; + private Counter $failedCounter; - public function __construct(CollectorRegistry $registry) - { + public function __construct(CollectorRegistry $registry) { $this->successfulCounter = $registry->getOrRegisterCounter( config('horizon-exporter.namespace'), 'wiki_entity_imports_successful', @@ -29,15 +28,15 @@ public function __construct(CollectorRegistry $registry) 'The number of failed Entity import records.', ); } - public function get(Request $request): \Illuminate\Http\JsonResponse - { + + public function get(Request $request): \Illuminate\Http\JsonResponse { $wiki = $request->attributes->get('wiki'); $imports = $wiki->wikiEntityImports()->get(); + return response()->json(['data' => $imports]); } - public function create(Request $request): \Illuminate\Http\JsonResponse - { + public function create(Request $request): \Illuminate\Http\JsonResponse { $validatedInput = $request->validate([ 'source_wiki_url' => ['required', 'url'], 'entity_ids' => ['required', 'string', function (string $attr, mixed $value, \Closure $fail) { @@ -55,12 +54,12 @@ public function create(Request $request): \Illuminate\Http\JsonResponse foreach ($imports as $import) { if ($import->status === WikiEntityImportStatus::Success) { return response() - ->json(['error' => 'Wiki "'.$wiki->domain.'" already has performed a successful entity import']) + ->json(['error' => 'Wiki "' . $wiki->domain . '" already has performed a successful entity import']) ->setStatusCode(400); } if ($import->status === WikiEntityImportStatus::Pending) { return response() - ->json(['error' => 'Wiki "'.$wiki->domain.'" currently has a pending entity import']) + ->json(['error' => 'Wiki "' . $wiki->domain . '" currently has a pending entity import']) ->setStatusCode(400); } } @@ -81,8 +80,7 @@ public function create(Request $request): \Illuminate\Http\JsonResponse return response()->json(['data' => $import]); } - public function update(Request $request): \Illuminate\Http\JsonResponse - { + public function update(Request $request): \Illuminate\Http\JsonResponse { // This route is not supposed have ACL middlewares in front as it is expected // to be called from backend services that are implicitly allowed // access right. diff --git a/app/Http/Controllers/WikiLogoController.php b/app/Http/Controllers/WikiLogoController.php index eb595aba0..8228d5b9a 100644 --- a/app/Http/Controllers/WikiLogoController.php +++ b/app/Http/Controllers/WikiLogoController.php @@ -6,8 +6,7 @@ use App\WikiSetting; use Illuminate\Http\Request; -class WikiLogoController extends Controller -{ +class WikiLogoController extends Controller { /** * It would be beneficial to have a bit of atomicness here? * Right now WgLogo is always the same path when set, so if we start writing new files but die we still end up updating the site. @@ -15,8 +14,7 @@ class WikiLogoController extends Controller * * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response */ - public function update(Request $request) - { + public function update(Request $request) { $request->validate([ 'logo' => 'required|mimes:png', ]); @@ -24,7 +22,7 @@ public function update(Request $request) $wiki = $request->attributes->get('wiki'); // run the job to set the wiki logo - ( new SetWikiLogo('id', $wiki->id, $request->file('logo')->getRealPath()) )->handle(); + (new SetWikiLogo('id', $wiki->id, $request->file('logo')->getRealPath()))->handle(); // get the logo URL from the settings $wgLogoSetting = $wiki->settings()->firstWhere(['name' => WikiSetting::wgLogo])->value; diff --git a/app/Http/Controllers/WikiProfileController.php b/app/Http/Controllers/WikiProfileController.php index 2cb0c7f4e..e50734268 100644 --- a/app/Http/Controllers/WikiProfileController.php +++ b/app/Http/Controllers/WikiProfileController.php @@ -7,20 +7,17 @@ use App\WikiProfile; use Illuminate\Http\Request; -class WikiProfileController extends Controller -{ +class WikiProfileController extends Controller { private $profileValidator; - public function __construct(ProfileValidator $profileValidator) - { + public function __construct(ProfileValidator $profileValidator) { $this->profileValidator = $profileValidator; } - public function create(Request $request): \Illuminate\Http\JsonResponse - { + public function create(Request $request): \Illuminate\Http\JsonResponse { $wiki = $request->attributes->get('wiki'); $validatedInput = $request->validate([ - 'profile' => ['required', 'json', new NonEmptyJsonRule] + 'profile' => ['required', 'json', new NonEmptyJsonRule], ]); $rawProfile = json_decode($validatedInput['profile'], true); @@ -28,6 +25,7 @@ public function create(Request $request): \Illuminate\Http\JsonResponse $profileValidator->validateWithBag('post'); $profile = WikiProfile::create(['wiki_id' => $wiki->id, ...$rawProfile]); + return response()->json(['data' => $profile]); } } diff --git a/app/Http/Controllers/WikiSettingController.php b/app/Http/Controllers/WikiSettingController.php index 01295adf5..3bae96f0e 100644 --- a/app/Http/Controllers/WikiSettingController.php +++ b/app/Http/Controllers/WikiSettingController.php @@ -7,15 +7,13 @@ use App\WikiSetting; use Illuminate\Http\Request; -class WikiSettingController extends Controller -{ +class WikiSettingController extends Controller { /** * @return (SettingWikibaseManifestEquivEntities|string)[][] * * @psalm-return array{wgDefaultSkin: array{0: 'required', 1: 'string', 2: 'in:vector,modern,timeless'}, wwExtEnableConfirmAccount: array{0: 'required', 1: 'boolean'}, wwExtEnableWikibaseLexeme: array{0: 'required', 1: 'boolean'}, wwWikibaseStringLengthString: array{0: 'required', 1: 'integer', 2: 'between:400,2500'}, wwWikibaseStringLengthMonolingualText: array{0: 'required', 1: 'integer', 2: 'between:400,2500'}, wwWikibaseStringLengthMultilang: array{0: 'required', 1: 'integer', 2: 'between:250,2500'}, wikibaseFedPropsEnable: array{0: 'required', 1: 'boolean'}, wikibaseManifestEquivEntities: array{0: 'required', 1: 'json', 2: SettingWikibaseManifestEquivEntities}, wwUseQuestyCaptcha: array{0: 'required, 1: 'boolean}, wwCaptchaQuestions: array:{0: 'required', 1: 'json', 2: SettingCaptchaQuestions}} */ - private function getSettingValidations(): array - { + private function getSettingValidations(): array { // FIXME: this list is evil and should be kept in sync with the model in Wiki.php?! (mostly) return [ 'wgDefaultSkin' => ['required', 'string', 'in:vector,modern,timeless'], @@ -25,22 +23,21 @@ private function getSettingValidations(): array 'wwWikibaseStringLengthMonolingualText' => ['required', 'integer', 'between:400,2500'], 'wwWikibaseStringLengthMultilang' => ['required', 'integer', 'between:250,2500'], 'wikibaseFedPropsEnable' => ['required', 'boolean'], - 'wikibaseManifestEquivEntities' => ['required', 'json', new SettingWikibaseManifestEquivEntities()], + 'wikibaseManifestEquivEntities' => ['required', 'json', new SettingWikibaseManifestEquivEntities], 'wwUseQuestyCaptcha' => ['required', 'boolean'], - 'wwCaptchaQuestions' => [ 'required', 'json', new SettingCaptchaQuestions()] + 'wwCaptchaQuestions' => ['required', 'json', new SettingCaptchaQuestions], ]; } /** * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response */ - public function update($setting, Request $request) - { + public function update($setting, Request $request) { $settingValidations = $this->getSettingValidations(); $request->validate([ // Allow both internal and external setting names, see normalizeSetting - 'setting' => 'required|string|in:'.implode(',', array_keys($settingValidations)), + 'setting' => 'required|string|in:' . implode(',', array_keys($settingValidations)), ]); $settingName = $request->input('setting'); diff --git a/app/Http/Controllers/WikisController.php b/app/Http/Controllers/WikisController.php index 8eb15578d..b7533ab60 100644 --- a/app/Http/Controllers/WikisController.php +++ b/app/Http/Controllers/WikisController.php @@ -2,21 +2,18 @@ namespace App\Http\Controllers; -use App\Wiki; use Illuminate\Http\Request; -class WikisController extends Controller -{ - public function getWikisOwnedByCurrentUser(Request $request): \Illuminate\Http\Response - { - $wikis = $request->user()->managesWikis()->get(); +class WikisController extends Controller { + public function getWikisOwnedByCurrentUser(Request $request): \Illuminate\Http\Response { + $wikis = $request->user()->managesWikis()->get(); - return response( - [ - "wikis" => $wikis, - "count" => count($wikis), - "limit" => config('wbstack.wiki_max_per_user') - ] - ); + return response( + [ + 'wikis' => $wikis, + 'count' => count($wikis), + 'limit' => config('wbstack.wiki_max_per_user'), + ] + ); } } diff --git a/app/Http/Curl/CurlRequest.php b/app/Http/Curl/CurlRequest.php index 5ae4a0c6a..523720709 100644 --- a/app/Http/Curl/CurlRequest.php +++ b/app/Http/Curl/CurlRequest.php @@ -1,8 +1,8 @@ handle, $options ); + public function setOptions(array $options) { + curl_setopt_array($this->handle, $options); } /** @@ -38,7 +38,7 @@ public function getInfo($name) { * @return void */ public function close() { - if( $this->handle ) { + if ($this->handle) { curl_close($this->handle); $this->handle = null; } @@ -48,7 +48,7 @@ public function close() { * @return void */ public function reset() { - if( $this->handle ) { + if ($this->handle) { $this->close(); } diff --git a/app/Http/Curl/HttpRequest.php b/app/Http/Curl/HttpRequest.php index d81882aab..85da2fed3 100644 --- a/app/Http/Curl/HttpRequest.php +++ b/app/Http/Curl/HttpRequest.php @@ -2,13 +2,16 @@ namespace App\Http\Curl; -interface HttpRequest -{ +interface HttpRequest { public function setOptions(array $options); + public function execute(); + public function getInfo($name); + public function close(); + public function error(); - public function reset(); -} \ No newline at end of file + public function reset(); +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 90dfa2517..a92fd7149 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -4,8 +4,7 @@ use Illuminate\Foundation\Http\Kernel as HttpKernel; -class Kernel extends HttpKernel -{ +class Kernel extends HttpKernel { /** * The application's global HTTP middleware stack. * @@ -40,12 +39,12 @@ class Kernel extends HttpKernel 'limit_wiki_access' => \App\Http\Middleware\LimitWikiAccess::class, // https://laravel-news.com/signed-routes - //'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, + // 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'backend.auth' => \App\Http\Middleware\BackendAuth::class, 'throttle.signup' => \App\Http\Middleware\ThrottleSignup::class, 'throttle' => \App\Http\Middleware\Throttle::class, - //'auth' => App\Http\Middleware\Authenticate::class, + // 'auth' => App\Http\Middleware\Authenticate::class, ]; /** diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 6ace0108b..61917e206 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -7,10 +7,8 @@ use Illuminate\Auth\Middleware\Authenticate as Middleware; use Illuminate\Support\Facades\Config; -class Authenticate extends Middleware -{ - public function handle($request, Closure $next, ...$guards) - { +class Authenticate extends Middleware { + public function handle($request, Closure $next, ...$guards) { try { // Passport wants to read tokens from Authorization headers, so // we'll pass on a value if set in a cookie. This means the @@ -18,7 +16,7 @@ public function handle($request, Closure $next, ...$guards) // are set. $token = $request->cookie(Config::get('auth.cookies.key')); if ($token) { - $request->headers->set('Authorization', 'Bearer '.$token); + $request->headers->set('Authorization', 'Bearer ' . $token); } $this->authenticate($request, $guards); } catch (AuthenticationException $e) { diff --git a/app/Http/Middleware/AuthorisedUsersForDeletedWikiMetricsMiddleware.php b/app/Http/Middleware/AuthorisedUsersForDeletedWikiMetricsMiddleware.php index 7ef228859..fc0a76cda 100644 --- a/app/Http/Middleware/AuthorisedUsersForDeletedWikiMetricsMiddleware.php +++ b/app/Http/Middleware/AuthorisedUsersForDeletedWikiMetricsMiddleware.php @@ -6,19 +6,18 @@ use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; -class AuthorisedUsersForDeletedWikiMetricsMiddleware -{ +class AuthorisedUsersForDeletedWikiMetricsMiddleware { /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ - public function handle(Request $request, Closure $next): Response - { + public function handle(Request $request, Closure $next): Response { $user = $request->user(); - if(!is_null($user) && $user->is_admin === 1) { + if (!is_null($user) && $user->is_admin === 1) { return $next($request); } + return redirect()->route('login'); } } diff --git a/app/Http/Middleware/BackendAuth.php b/app/Http/Middleware/BackendAuth.php index 497b83d90..cd1cf286c 100644 --- a/app/Http/Middleware/BackendAuth.php +++ b/app/Http/Middleware/BackendAuth.php @@ -5,8 +5,7 @@ use Closure; use Illuminate\Contracts\Auth\Factory as Auth; -class BackendAuth -{ +class BackendAuth { /** * The authentication guard factory instance. * @@ -17,11 +16,9 @@ class BackendAuth /** * Create a new middleware instance. * - * @param \Illuminate\Contracts\Auth\Factory $auth * @return void */ - public function __construct(Auth $auth) - { + public function __construct(Auth $auth) { $this->auth = $auth; } @@ -29,12 +26,10 @@ public function __construct(Auth $auth) * Handle an incoming request. * * @param \Illuminate\Http\Request $request - * @param \Closure $next * @param string|null $guard * @return mixed */ - public function handle($request, Closure $next, $guard = null) - { + public function handle($request, Closure $next, $guard = null) { $token = $request->header('X-Backend-Token'); $service = $request->header('X-Backend-Service'); @@ -46,7 +41,7 @@ public function handle($request, Closure $next, $guard = null) $tokenOk = $token === 'backend-token'; $serviceOk = $service === 'backend-service'; - if (! $tokenOk || ! $serviceOk) { + if (!$tokenOk || !$serviceOk) { // TODO log failures return response()->json([ 'error' => 'Unauthorized.', diff --git a/app/Http/Middleware/CheckForMaintenanceMode.php b/app/Http/Middleware/CheckForMaintenanceMode.php index 35b9824ba..86fa3eb97 100644 --- a/app/Http/Middleware/CheckForMaintenanceMode.php +++ b/app/Http/Middleware/CheckForMaintenanceMode.php @@ -4,8 +4,7 @@ use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware; -class CheckForMaintenanceMode extends Middleware -{ +class CheckForMaintenanceMode extends Middleware { /** * The URIs that should be reachable while maintenance mode is enabled. * diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php index 033136ad1..61dc55764 100644 --- a/app/Http/Middleware/EncryptCookies.php +++ b/app/Http/Middleware/EncryptCookies.php @@ -4,8 +4,7 @@ use Illuminate\Cookie\Middleware\EncryptCookies as Middleware; -class EncryptCookies extends Middleware -{ +class EncryptCookies extends Middleware { /** * The names of the cookies that should not be encrypted. * diff --git a/app/Http/Middleware/LimitWikiAccess.php b/app/Http/Middleware/LimitWikiAccess.php index ba70f89a9..51fa94081 100644 --- a/app/Http/Middleware/LimitWikiAccess.php +++ b/app/Http/Middleware/LimitWikiAccess.php @@ -2,22 +2,20 @@ namespace App\Http\Middleware; +use App\Wiki; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; -use App\Wiki; -class LimitWikiAccess -{ +class LimitWikiAccess { /** * Reject any incoming request unless the user is a manager of the * requested wiki. If the user is authorized, inject the wiki * object into the request context. */ - public function handle(Request $request, Closure $next): Response - { + public function handle(Request $request, Closure $next): Response { $validatedInput = $request->validate([ - 'wiki' => ['required', 'integer'] + 'wiki' => ['required', 'integer'], ]); $wiki = Wiki::find($validatedInput['wiki']); @@ -35,6 +33,7 @@ public function handle(Request $request, Closure $next): Response } $request->attributes->set('wiki', $wiki); + return $next($request); } } diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 2d0b724e1..775a94717 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -11,17 +11,13 @@ * The purpose of RedirectIfAuthenticated is to keep an already authenticated user * from reaching the login or registration routes/views since they're already logged in. */ -class RedirectIfAuthenticated -{ +class RedirectIfAuthenticated { /** * Handle an incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next * @param string|null $guard */ - public function handle(Request $request, Closure $next, string ...$guards): Response - { + public function handle(Request $request, Closure $next, string ...$guards): Response { $guards = empty($guards) ? [null] : $guards; foreach ($guards as $guard) { @@ -29,6 +25,7 @@ public function handle(Request $request, Closure $next, string ...$guards): Resp return response()->json('Endpoint not needed', 400); } } + return $next($request); } } diff --git a/app/Http/Middleware/Throttle.php b/app/Http/Middleware/Throttle.php index 6e0aec4e0..6de380c30 100644 --- a/app/Http/Middleware/Throttle.php +++ b/app/Http/Middleware/Throttle.php @@ -6,12 +6,10 @@ use Illuminate\Routing\Middleware\ThrottleRequests; class Throttle extends ThrottleRequests { - /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request - * @param \Closure $next * @param int|string $maxAttempts * @param float|int $decayMinutes * @param string $prefix @@ -23,6 +21,7 @@ public function handle($request, Closure $next, $maxAttempts = 60, $decayMinutes if (config('app.env') === 'local') { return $next($request); } + return parent::handle($request, $next, $maxAttempts, $decayMinutes, $prefix); } } diff --git a/app/Http/Middleware/ThrottleSignup.php b/app/Http/Middleware/ThrottleSignup.php index a121c1f4a..433ce9b57 100644 --- a/app/Http/Middleware/ThrottleSignup.php +++ b/app/Http/Middleware/ThrottleSignup.php @@ -2,15 +2,13 @@ namespace App\Http\Middleware; -use Closure; -use Carbon\Carbon; use App\User; +use Carbon\Carbon; +use Closure; use Illuminate\Http\Request; -class ThrottleSignup -{ - public function handle(Request $request, Closure $next, string $limit, string $range) - { +class ThrottleSignup { + public function handle(Request $request, Closure $next, string $limit, string $range) { if (!$limit || !$range) { return $next($request); } @@ -18,9 +16,10 @@ public function handle(Request $request, Closure $next, string $limit, string $r $lookback = Carbon::now()->sub(new \DateInterval($range)); $recentSignups = User::where('created_at', '>=', $lookback)->count(); if ($recentSignups >= intval($limit)) { - report("Attempted account creation was blocked because given limits were exceeded."); + report('Attempted account creation was blocked because given limits were exceeded.'); + return response()->json( - ["errors" => "Due to high load, we're currently not able to create an account for you. Please try again tomorrow or reach out through our contact page."], + ['errors' => "Due to high load, we're currently not able to create an account for you. Please try again tomorrow or reach out through our contact page."], 503 ); } diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php index 5a50e7b5c..da8416469 100644 --- a/app/Http/Middleware/TrimStrings.php +++ b/app/Http/Middleware/TrimStrings.php @@ -4,8 +4,7 @@ use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware; -class TrimStrings extends Middleware -{ +class TrimStrings extends Middleware { /** * The names of the attributes that should not be trimmed. * diff --git a/app/Http/Resources/ConversionMetricResource.php b/app/Http/Resources/ConversionMetricResource.php index 027d8a60b..c015c92f6 100644 --- a/app/Http/Resources/ConversionMetricResource.php +++ b/app/Http/Resources/ConversionMetricResource.php @@ -1,12 +1,11 @@ $this->id, 'description' => $this->description, diff --git a/app/Http/Resources/PublicWikiResource.php b/app/Http/Resources/PublicWikiResource.php index 62ff9e8f0..37e1e92ef 100644 --- a/app/Http/Resources/PublicWikiResource.php +++ b/app/Http/Resources/PublicWikiResource.php @@ -3,13 +3,11 @@ namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; -use App\WikiDomain; -class PublicWikiResource extends JsonResource -{ - public function toArray($request): array - { +class PublicWikiResource extends JsonResource { + public function toArray($request): array { $logoSetting = $this->settings()->where('name', 'wgLogo')->first(); + return [ 'id' => $this->id, 'description' => $this->description, @@ -17,7 +15,7 @@ public function toArray($request): array 'domain_decoded' => $this->domain_decoded, 'sitename' => $this->sitename, 'wiki_site_stats' => $this->wikiSiteStats, - 'logo_url' => $logoSetting ? $logoSetting->value : null + 'logo_url' => $logoSetting ? $logoSetting->value : null, ]; } } diff --git a/app/Invitation.php b/app/Invitation.php index d636a39a1..0c8c10f90 100644 --- a/app/Invitation.php +++ b/app/Invitation.php @@ -2,8 +2,8 @@ namespace App; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; /** * App\Invitation. @@ -12,6 +12,7 @@ * @property string $code * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at + * * @method static \Database\Factories\InvitationFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|\App\Invitation newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\Invitation newQuery() @@ -20,10 +21,10 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\Invitation whereCreatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Invitation whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Invitation whereUpdatedAt($value) + * * @mixin \Eloquent */ -class Invitation extends Model -{ +class Invitation extends Model { use HasFactory; /** diff --git a/app/Jobs/CirrusSearch/CirrusSearchJob.php b/app/Jobs/CirrusSearch/CirrusSearchJob.php index 0c280321b..8e86dabac 100644 --- a/app/Jobs/CirrusSearch/CirrusSearchJob.php +++ b/app/Jobs/CirrusSearch/CirrusSearchJob.php @@ -2,23 +2,26 @@ namespace App\Jobs\CirrusSearch; -use Illuminate\Contracts\Queue\ShouldBeUnique; -use App\WikiSetting; use App\Http\Curl\HttpRequest; -use App\Wiki; use App\Jobs\Job; +use App\Wiki; +use App\WikiSetting; +use Illuminate\Contracts\Queue\ShouldBeUnique; -abstract class CirrusSearchJob extends Job implements ShouldBeUnique -{ +abstract class CirrusSearchJob extends Job implements ShouldBeUnique { protected $wikiId; + protected $setting; + protected $wiki; + protected $wikiDB; - abstract function apiModule(): string; - abstract function handleResponse( string $rawResponse, $error ): void; + abstract public function apiModule(): string; + + abstract public function handleResponse(string $rawResponse, $error): void; - public function __construct( $wikiId ) { + public function __construct($wikiId) { $this->wikiId = $wikiId; } @@ -28,7 +31,7 @@ public function __construct( $wikiId ) { * @return string */ public function uniqueId() { - return strval( $this->wikiId ); + return strval($this->wikiId); } public function wikiId(): int { @@ -38,33 +41,35 @@ public function wikiId(): int { /** * @return void */ - public function handle( HttpRequest $request ) - { - $this->wiki = Wiki::whereId( $this->wikiId )->with('settings')->with('wikiDb')->first(); + public function handle(HttpRequest $request) { + $this->wiki = Wiki::whereId($this->wikiId)->with('settings')->with('wikiDb')->first(); // job got triggered but no wiki - if ( !$this->wiki ) { - $this->fail( new \RuntimeException( $this->apiModule() . ' call for '.$this->wikiId.' was triggered but not wiki available.') ); + if (!$this->wiki) { + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was triggered but not wiki available.')); + return; } - $this->setting = $this->wiki->settings()->where([ 'name' => WikiSetting::wwExtEnableElasticSearch, ])->first(); + $this->setting = $this->wiki->settings()->where(['name' => WikiSetting::wwExtEnableElasticSearch])->first(); // job got triggered but no setting - if ( !$this->setting ) { - $this->fail( new \RuntimeException( $this->apiModule() . ' call for '.$this->wikiId.' was triggered but not setting available') ); + if (!$this->setting) { + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was triggered but not setting available')); + return; } $this->wikiDB = $this->wiki->wikiDb()->first(); // no wikiDB around - if ( !$this->wikiDB ) { - $this->fail( new \RuntimeException($this->apiModule() . ' call for '.$this->wikiId.' was triggered but not WikiDb available') ); + if (!$this->wikiDB) { + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was triggered but not WikiDb available')); + return; } $request->setOptions( [ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action='. $this->apiModule() . $this->getQueryParams(), + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=' . $this->apiModule() . $this->getQueryParams(), CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => $this->getRequestTimeout(), @@ -72,8 +77,8 @@ public function handle( HttpRequest $request ) CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wiki->domain, - ] + 'host: ' . $this->wiki->domain, + ], ] ); @@ -81,30 +86,35 @@ public function handle( HttpRequest $request ) $err = $request->error(); $request->close(); - $this->handleResponse( $rawResponse, $err ); + $this->handleResponse($rawResponse, $err); } - protected function validateOrFailRequest( ?array $response, string $rawResponse, $error ): bool { - if ( $error ) { - $this->fail( new \RuntimeException( $this->apiModule() . ' curl error for '.$this->wikiId.': '.$error) ); + protected function validateOrFailRequest(?array $response, string $rawResponse, $error): bool { + if ($error) { + $this->fail(new \RuntimeException($this->apiModule() . ' curl error for ' . $this->wikiId . ': ' . $error)); + return false; } - if( $this->hasApiError( $response ) ) { - $this->fail( new \RuntimeException( $this->apiModule() . ' call failed with api error: '. $response['error']['info'] ) ); + if ($this->hasApiError($response)) { + $this->fail(new \RuntimeException($this->apiModule() . ' call failed with api error: ' . $response['error']['info'])); + return false; } - if ( !$this->isValid( $response ) ) { - $this->fail( new \RuntimeException( $this->apiModule() . ' call for '.$this->wikiId.'. No ' . $this->apiModule() . ' key in response: '.$rawResponse) ); + if (!$this->isValid($response)) { + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . '. No ' . $this->apiModule() . ' key in response: ' . $rawResponse)); + return false; } return true; } - protected function validateSuccess( array $response, string $rawResponse, $error ): bool { - if ( !$this->isSuccessful($response)) { - $this->fail( new \RuntimeException( $this->apiModule() . ' call for '.$this->wikiId.' was not successful:'.$rawResponse) ); + + protected function validateSuccess(array $response, string $rawResponse, $error): bool { + if (!$this->isSuccessful($response)) { + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was not successful:' . $rawResponse)); + return false; } @@ -117,15 +127,15 @@ protected function getRequestTimeout(): int { // TODO Migrate this to some other baseclass for all internal api classes // This and some other stuff would be usedful there too - protected function hasApiError( ?array $response ): bool { - return is_array($response) && array_key_exists( 'error', $response); + protected function hasApiError(?array $response): bool { + return is_array($response) && array_key_exists('error', $response); } - protected function isValid( ?array $response ): bool { - return is_array($response) && array_key_exists( $this->apiModule(), $response); + protected function isValid(?array $response): bool { + return is_array($response) && array_key_exists($this->apiModule(), $response); } - protected function isSuccessful( array $response ): bool { + protected function isSuccessful(array $response): bool { return array_key_exists('return', $response[$this->apiModule()]) && $response[$this->apiModule()]['return'] == 0; } @@ -135,5 +145,4 @@ protected function isSuccessful( array $response ): bool { protected function getQueryParams() { return '&format=json'; } - } diff --git a/app/Jobs/CirrusSearch/ElasticSearchIndexInit.php b/app/Jobs/CirrusSearch/ElasticSearchIndexInit.php index 9e60f0e4b..dfa2aaf46 100644 --- a/app/Jobs/CirrusSearch/ElasticSearchIndexInit.php +++ b/app/Jobs/CirrusSearch/ElasticSearchIndexInit.php @@ -4,52 +4,52 @@ use Illuminate\Support\Facades\Log; -class ElasticSearchIndexInit extends CirrusSearchJob -{ +class ElasticSearchIndexInit extends CirrusSearchJob { private $cluster; - public function __construct( int $wikiId, string $cluster = 'all' ) { + public function __construct(int $wikiId, string $cluster = 'all') { $this->cluster = $cluster; - parent::__construct( $wikiId ); + parent::__construct($wikiId); } public function cluster(): string { return $this->cluster; } - function apiModule(): string { + public function apiModule(): string { return 'wbstackElasticSearchInit'; } private function logFailure(): void { - Log::error( __METHOD__ . ": Failed initializing elasticsearch." ); + Log::error(__METHOD__ . ': Failed initializing elasticsearch.'); } - public function handleResponse( string $rawResponse, $error ): void - { - $response = json_decode( $rawResponse, true ); + public function handleResponse(string $rawResponse, $error): void { + $response = json_decode($rawResponse, true); - if( !$this->validateOrFailRequest($response, $rawResponse, $error) ) { + if (!$this->validateOrFailRequest($response, $rawResponse, $error)) { $this->logFailure(); + return; } if (!$this->validateSuccess($response, $rawResponse, $error)) { $this->logFailure(); + return; } $output = $response[$this->apiModule()]['output']; // if newly created index failed, script ran and update was unsuccessful, then log error. - if ( !( - in_array( "\tCreating index...ok", $output ) || - in_array( "\t\tValidating {$this->wikiDB->name}_general alias...ok", $output ) - ) ) { + if (!( + in_array("\tCreating index...ok", $output) || + in_array("\t\tValidating {$this->wikiDB->name}_general alias...ok", $output) + )) { Log::error(__METHOD__ . ": Job finished but didn't create or update, something is weird"); $this->logFailure(); - $this->fail( new \RuntimeException($this->apiModule() . ' call for '.$this->wikiId.' was not successful:' . $rawResponse ) ); + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was not successful:' . $rawResponse)); } } diff --git a/app/Jobs/CirrusSearch/ForceSearchIndex.php b/app/Jobs/CirrusSearch/ForceSearchIndex.php index 6967d2724..7377d888d 100644 --- a/app/Jobs/CirrusSearch/ForceSearchIndex.php +++ b/app/Jobs/CirrusSearch/ForceSearchIndex.php @@ -2,23 +2,22 @@ namespace App\Jobs\CirrusSearch; -use Illuminate\Support\Facades\Log; use App\Wiki; +use Illuminate\Support\Facades\Log; /** - * * Job for running CirrusSearch/ForceSearchIndex.php on a wiki - * + * * Example: - * + * * php artisan job:dispatch CirrusSearch\\ForceSearchIndex id 1 0 1000 */ -class ForceSearchIndex extends CirrusSearchJob -{ +class ForceSearchIndex extends CirrusSearchJob { private $fromId; + private $toId; - public function __construct( string $selectCol, $selectValue, int $fromId, int $toId ) { + public function __construct(string $selectCol, $selectValue, int $fromId, int $toId) { $wiki = Wiki::where($selectCol, $selectValue)->firstOrFail(); $this->fromId = $fromId; @@ -35,11 +34,12 @@ public function uniqueId() { public function fromId(): int { return $this->fromId; } + public function toId(): int { return $this->toId; } - function apiModule(): string { + public function apiModule(): string { return 'wbstackForceSearchIndex'; } @@ -47,14 +47,14 @@ protected function getRequestTimeout(): int { return 1000; } - public function handleResponse( string $rawResponse, $error ) : void { + public function handleResponse(string $rawResponse, $error): void { $response = json_decode($rawResponse, true); - if( !$this->validateOrFailRequest($response, $rawResponse, $error) ) { + if (!$this->validateOrFailRequest($response, $rawResponse, $error)) { return; } - if( !$this->validateSuccess($response, $rawResponse, $error) ) { + if (!$this->validateSuccess($response, $rawResponse, $error)) { return; } @@ -64,13 +64,13 @@ public function handleResponse( string $rawResponse, $error ) : void { $lastElement = end($output); preg_match('/Indexed a total of (\d+) pages/', $lastElement, $successMatches, PREG_OFFSET_CAPTURE); - if ( count($successMatches) === 2 && is_numeric($successMatches[1][0]) ) { - $numIndexedPages = intVal($successMatches[1][0]); + if (count($successMatches) === 2 && is_numeric($successMatches[1][0])) { + $numIndexedPages = intval($successMatches[1][0]); Log::info(__METHOD__ . ": Finished batch! Indexed {$numIndexedPages} pages. From id {$this->fromId} to {$this->toId}"); } else { dd($successMatches); - Log::error(__METHOD__ . ": Job finished but did not contain the expected output."); - $this->fail( new \RuntimeException($this->apiModule() . ' call for '.$this->wikiId.' was not successful:' . $rawResponse ) ); + Log::error(__METHOD__ . ': Job finished but did not contain the expected output.'); + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was not successful:' . $rawResponse)); } } diff --git a/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php b/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php index 264e349a6..2ef3c9ea7 100644 --- a/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php +++ b/app/Jobs/CirrusSearch/QueueSearchIndexBatches.php @@ -2,23 +2,20 @@ namespace App\Jobs\CirrusSearch; - -use Illuminate\Support\Facades\Log; use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Support\Facades\Log; /** - * - * Job for queuing batched runs of CirrusSearch ForceSearchIndex.php by using the --buildChunks parameter - * + * Job for queuing batched runs of CirrusSearch ForceSearchIndex.php by using the --buildChunks parameter + * * Example: - * + * * php artisan job:dispatch CirrusSearch\\QueueSearchIndexBatches 1 */ -class QueueSearchIndexBatches extends CirrusSearchJob -{ +class QueueSearchIndexBatches extends CirrusSearchJob { use DispatchesJobs; - function apiModule(): string { + public function apiModule(): string { return 'wbstackQueueSearchIndexBatches'; } @@ -26,7 +23,7 @@ protected function getRequestTimeout(): int { return 1000; } - public function convertToBatch( $output ): array { + public function convertToBatch($output): array { $batches = []; @@ -34,54 +31,56 @@ public function convertToBatch( $output ): array { $matches = []; preg_match('/--fromId (\d+) --toId (\d+)/', $command, $matches, PREG_OFFSET_CAPTURE); - if ( count($matches) !== 3 ) { + if (count($matches) !== 3) { throw new \RuntimeException('Got some weird output from the script: ' . $command); } $fromId = $matches[1][0]; $toId = $matches[2][0]; - if( (!is_numeric($fromId) || !is_numeric($toId)) && intVal($fromId) <= intVal($toId) ) { + if ((!is_numeric($fromId) || !is_numeric($toId)) && intval($fromId) <= intval($toId)) { throw new \RuntimeException('Batch parameters from command looks weird! fromId: ' . $fromId . ' toId: ' . $toId); } - $batches[] = new ForceSearchIndex( 'id', $this->wikiId, $fromId, $toId ); + $batches[] = new ForceSearchIndex('id', $this->wikiId, $fromId, $toId); } - + return $batches; } - public function handleResponse( string $rawResponse, $error ) : void { + public function handleResponse(string $rawResponse, $error): void { $response = json_decode($rawResponse, true); - if( !$this->validateOrFailRequest($response, $rawResponse, $error) ) { + if (!$this->validateOrFailRequest($response, $rawResponse, $error)) { return; } $output = $response[$this->apiModule()]['output']; // if there are no pages to index, just exit now. - if( !$this->isSuccessful($response) && - is_array($output) && count($output) == 1 && $output[0] == "Couldn't find any pages to index. fromId = = = toId." ) { - Log::warning(__METHOD__ . ": ForceSearchIndex could not find any pages to index. " . $rawResponse); + if (!$this->isSuccessful($response) && + is_array($output) && count($output) == 1 && $output[0] == "Couldn't find any pages to index. fromId = = = toId.") { + Log::warning(__METHOD__ . ': ForceSearchIndex could not find any pages to index. ' . $rawResponse); + return; } - if( !$this->validateSuccess($response, $rawResponse, $error) ) { + if (!$this->validateSuccess($response, $rawResponse, $error)) { return; } $batches = []; try { - $batches = $this->convertToBatch( $output ); + $batches = $this->convertToBatch($output); } catch (\RuntimeException $e) { - Log::error(__METHOD__ . ": Failed to convert command output into batched commands: " . $rawResponse); + Log::error(__METHOD__ . ': Failed to convert command output into batched commands: ' . $rawResponse); $this->fail($e); + return; } - if ( !empty($batches) ) { + if (!empty($batches)) { // todo rewrite as batch foreach ($batches as $job) { dispatch($job); @@ -90,7 +89,7 @@ public function handleResponse( string $rawResponse, $error ) : void { } else { Log::error(__METHOD__ . ": Job finished but didn't create any batches, something is weird"); - $this->fail( new \RuntimeException($this->apiModule() . ' call for '.$this->wikiId.' was not successful:' . $rawResponse ) ); + $this->fail(new \RuntimeException($this->apiModule() . ' call for ' . $this->wikiId . ' was not successful:' . $rawResponse)); } } diff --git a/app/Jobs/CreateQueryserviceBatchesJob.php b/app/Jobs/CreateQueryserviceBatchesJob.php index c1597e995..e22157f6f 100644 --- a/app/Jobs/CreateQueryserviceBatchesJob.php +++ b/app/Jobs/CreateQueryserviceBatchesJob.php @@ -6,24 +6,21 @@ use App\EventPageUpdate; use App\QsBatch; use App\QsCheckpoint; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Config; -use Illuminate\Support\Collection; -class CreateQueryserviceBatchesJob extends Job -{ +class CreateQueryserviceBatchesJob extends Job { private int $entityLimit; public $timeout = 3600; - public function __construct() - { + public function __construct() { $this->entityLimit = Config::get('wbstack.qs_batch_entity_limit'); } - public function handle(): void - { + public function handle(): void { DB::transaction(function () { $latestCheckpoint = QsCheckpoint::get(); @@ -37,7 +34,7 @@ public function handle(): void $this->createNewBatches($entityIdsFromEvents, $wikiId); } catch (\Exception $ex) { Log::error( - 'Failed to process entities '.implode(',', $entityIdsFromEvents).' for wiki with id '.$wikiId.': '.$ex->getMessage() + 'Failed to process entities ' . implode(',', $entityIdsFromEvents) . ' for wiki with id ' . $wikiId . ': ' . $ex->getMessage() ); $this->fail($ex); } @@ -47,8 +44,7 @@ public function handle(): void }, 3); } - private function getNewEntities(int $latestCheckpoint): array - { + private function getNewEntities(int $latestCheckpoint): array { $newEntitiesFromEvents = []; $latestEventId = $latestCheckpoint; @@ -67,8 +63,7 @@ private function getNewEntities(int $latestCheckpoint): array return [$newEntitiesFromEvents, $latestEventId]; } - private function tryToAppendEntitesToExistingBatches(array $entityIdsFromEvents, int $wikiId): bool - { + private function tryToAppendEntitesToExistingBatches(array $entityIdsFromEvents, int $wikiId): bool { if (DB::transactionLevel() < 1) { throw new \Exception( 'This method can only be run within the context of a transaction.' @@ -95,13 +90,14 @@ private function tryToAppendEntitesToExistingBatches(array $entityIdsFromEvents, $qsBatch->update([ 'entityIds' => implode(',', $tentativeMerge), ]); + return true; } + return false; } - private function createNewBatches(array $entityIdsFromEvents, int $wikiId): void - { + private function createNewBatches(array $entityIdsFromEvents, int $wikiId): void { $chunks = array_chunk( array_unique($entityIdsFromEvents), $this->entityLimit, ); diff --git a/app/Jobs/DeleteQueryserviceNamespaceJob.php b/app/Jobs/DeleteQueryserviceNamespaceJob.php index 964f0b084..ebf0297ab 100644 --- a/app/Jobs/DeleteQueryserviceNamespaceJob.php +++ b/app/Jobs/DeleteQueryserviceNamespaceJob.php @@ -2,21 +2,18 @@ namespace App\Jobs; -use App\QueryserviceNamespace; -use App\Http\Curl\CurlRequest; use App\Http\Curl\HttpRequest; -use Illuminate\Contracts\Queue\ShouldBeUnique; +use App\QueryserviceNamespace; use App\Wiki; +use Illuminate\Contracts\Queue\ShouldBeUnique; -class DeleteQueryserviceNamespaceJob extends Job implements ShouldBeUnique -{ +class DeleteQueryserviceNamespaceJob extends Job implements ShouldBeUnique { private $wikiId; /** * @return void */ - public function __construct( $wikiId ) - { + public function __construct($wikiId) { $this->wikiId = $wikiId; } @@ -25,32 +22,33 @@ public function __construct( $wikiId ) * * @return string */ - public function uniqueId() - { + public function uniqueId() { return strval($this->wikiId); } /** * @return void */ - public function handle( HttpRequest $request ) - { + public function handle(HttpRequest $request) { $wiki = Wiki::withTrashed()->where(['id' => $this->wikiId])->first(); - if( !$wiki ) { + if (!$wiki) { $this->fail(new \RuntimeException("Wiki not found for {$this->wikiId}")); + return; } - if( !$wiki->deleted_at ) { + if (!$wiki->deleted_at) { $this->fail(new \RuntimeException("Wiki {$this->wikiId} is not marked for deletion.")); + return; } - + $qsNamespace = QueryserviceNamespace::whereWikiId($this->wikiId)->first(); - if( !$qsNamespace ) { - $this->fail( new \RuntimeException("Namespace for wiki {$this->wikiId} not found.") ); + if (!$qsNamespace) { + $this->fail(new \RuntimeException("Namespace for wiki {$this->wikiId} not found.")); + return; } @@ -76,15 +74,17 @@ public function handle( HttpRequest $request ) $request->close(); if ($err) { - $this->fail( new \RuntimeException('cURL Error #:'.$err) ); + $this->fail(new \RuntimeException('cURL Error #:' . $err)); + return; } else { - if ($response === 'DELETED: '.$qsNamespace->namespace) { + if ($response === 'DELETED: ' . $qsNamespace->namespace) { $qsNamespace->delete(); } else { - $this->fail( new \RuntimeException('Valid response, but couldn\'t find "DELETED: " in: '.$response) ); + $this->fail(new \RuntimeException('Valid response, but couldn\'t find "DELETED: " in: ' . $response)); + return; } } diff --git a/app/Jobs/DeleteWikiDbJob.php b/app/Jobs/DeleteWikiDbJob.php index a6ff09952..7d0c5b915 100644 --- a/app/Jobs/DeleteWikiDbJob.php +++ b/app/Jobs/DeleteWikiDbJob.php @@ -2,24 +2,22 @@ namespace App\Jobs; -use App\WikiDb; -use Illuminate\Contracts\Queue\ShouldBeUnique; use App\Wiki; +use App\WikiDb; use Carbon\Carbon; +use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Database\DatabaseManager; /** * Prepends the MW Database, User with `deleted_` prefix and deletes WikiDB relation for a wiki */ -class DeleteWikiDbJob extends Job implements ShouldBeUnique -{ +class DeleteWikiDbJob extends Job implements ShouldBeUnique { private $wikiId; /** * @return void */ - public function __construct( int $wikiId ) - { + public function __construct(int $wikiId) { $this->wikiId = $wikiId; } @@ -28,32 +26,33 @@ public function __construct( int $wikiId ) * * @return string */ - public function uniqueId() - { + public function uniqueId() { return strval($this->wikiId); } /** * @return void */ - public function handle( DatabaseManager $manager ) - { + public function handle(DatabaseManager $manager) { $wiki = Wiki::withTrashed()->where(['id' => $this->wikiId])->first(); - if( !$wiki ) { + if (!$wiki) { $this->fail(new \RuntimeException("Wiki not found for {$this->wikiId}")); + return; } - if( !$wiki->deleted_at ) { + if (!$wiki->deleted_at) { $this->fail(new \RuntimeException("Wiki {$this->wikiId} is not marked for deletion.")); + return; } - $wikiDB = WikiDb::whereWikiId( $this->wikiId )->first(); + $wikiDB = WikiDb::whereWikiId($this->wikiId)->first(); - if( !$wikiDB ) { + if (!$wikiDB) { $this->fail(new \RuntimeException("WikiDb not found for {$this->wikiId}")); + return; } @@ -62,19 +61,18 @@ public function handle( DatabaseManager $manager ) $manager->purge('mw'); $conn = $manager->connection('mw'); - if (! $conn instanceof \Illuminate\Database\Connection) { - throw new \RuntimeException('Must be run on a PDO based DB connection'); + if (!$conn instanceof \Illuminate\Database\Connection) { + throw new \RuntimeException('Must be run on a PDO based DB connection'); } $pdo = $conn->getPdo(); $timestamp = Carbon::now()->timestamp; $deletedDatabaseName = "mwdb_deleted_{$timestamp}_{$this->wikiId}"; - if ($pdo->exec('USE '.$wikiDB->name) === false) { - throw new \RuntimeException('Failed to use database with dbname: '.$wikiDB->name); + if ($pdo->exec('USE ' . $wikiDB->name) === false) { + throw new \RuntimeException('Failed to use database with dbname: ' . $wikiDB->name); } - $tables = []; $result = $pdo->query('SHOW TABLES')->fetchAll(); /* @@ -83,29 +81,28 @@ public function handle( DatabaseManager $manager ) 0 => "" ] */ - foreach($result as $table) { + foreach ($result as $table) { $values = array_unique(array_values($table)); - if(count($values) !== 1) { + if (count($values) !== 1) { throw new \RuntimeException("Tried getting table names for wikiDB {$wikiDB->name} but failed"); } $tables[] = $values[0]; } - if( empty($tables) ) { + if (empty($tables)) { throw new \RuntimeException("Tried getting table names for wikiDB {$wikiDB->name} but did not find any"); } - // Create the new database $pdo->exec(sprintf('CREATE DATABASE %s', $deletedDatabaseName)); // iterate over each table and replace the prefix // and move it to the deleted database by using RENAME TABLE - foreach($tables as $table) { + foreach ($tables as $table) { $replacedCount = 0; - $tableWithoutPrefix = str_replace($wikiDB->prefix . '_', '', $table, $replacedCount ); + $tableWithoutPrefix = str_replace($wikiDB->prefix . '_', '', $table, $replacedCount); if ($replacedCount !== 1) { /** * @psalm-suppress InvalidCast @@ -115,10 +112,11 @@ public function handle( DatabaseManager $manager ) $pdo->exec(sprintf('RENAME TABLE %s.%s TO %s.%s', $wikiDB->name, $table, $deletedDatabaseName, $tableWithoutPrefix)); } - $pdo->exec(sprintf('DROP USER %s', $wikiDB->user )); + $pdo->exec(sprintf('DROP USER %s', $wikiDB->user)); } catch (\Throwable $e) { $manager->purge('mw'); - $this->fail( new \RuntimeException('Failed to soft-soft delete '.$wikiDB->name . ': ' . $e->getMessage()) ); + $this->fail(new \RuntimeException('Failed to soft-soft delete ' . $wikiDB->name . ': ' . $e->getMessage())); + return; } diff --git a/app/Jobs/DeleteWikiDispatcherJob.php b/app/Jobs/DeleteWikiDispatcherJob.php index 9a35cc375..18aab8e7d 100644 --- a/app/Jobs/DeleteWikiDispatcherJob.php +++ b/app/Jobs/DeleteWikiDispatcherJob.php @@ -1,79 +1,79 @@ subDays( Config::get('wbstack.wiki_hard_delete_threshold') ); - $wikis = Wiki::withTrashed()->whereDate( 'deleted_at', '<=', $deleteCutoff )->get(); + $wikis = Wiki::withTrashed()->whereDate('deleted_at', '<=', $deleteCutoff)->get(); + + if (!$wikis->count()) { + Log::info(__METHOD__ . ': Found no soft deleted wikis over threshold. exiting.'); - if( !$wikis->count() ) { - Log::info( __METHOD__ . ": Found no soft deleted wikis over threshold. exiting."); return; } - foreach($wikis as $wiki) { - Log::info( __METHOD__ . ": Starting hard-delete chain for id: {$wiki->id}, domain: {$wiki->domain}."); + foreach ($wikis as $wiki) { + Log::info(__METHOD__ . ": Starting hard-delete chain for id: {$wiki->id}, domain: {$wiki->domain}."); $jobs = []; $namespace = QueryserviceNamespace::whereWikiId($wiki->id)->first(); // if there is a namespace add the job for that - if( $namespace ) { - $jobs[] = new DeleteQueryserviceNamespaceJob( $wiki->id ); + if ($namespace) { + $jobs[] = new DeleteQueryserviceNamespaceJob($wiki->id); } $elasticSearchSetting = WikiSetting::where([ 'wiki_id' => $wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, - 'value' => true + 'value' => true, ])->first(); // if elasticsearch is enabled, add the job for that - if( $elasticSearchSetting ) { - $jobs[] = new ElasticSearchIndexDelete( $wiki->id ); + if ($elasticSearchSetting) { + $jobs[] = new ElasticSearchIndexDelete($wiki->id); } // if domain is not subdomain remove kubernetes ingress if any - if ( !WikiController::isSubDomain( $wiki->domain ) ) { - $jobs[] = new KubernetesIngressDeleteJob( $wiki->id ); + if (!WikiController::isSubDomain($wiki->domain)) { + $jobs[] = new KubernetesIngressDeleteJob($wiki->id); } - $wikiDB = WikiDb::whereWikiId( $wiki->id )->first(); + $wikiDB = WikiDb::whereWikiId($wiki->id)->first(); // soft-deletes the mediawiki database and removes WikiDB entry - if ( $wikiDB ) { - $jobs[] = new DeleteWikiDbJob( $wiki->id ); + if ($wikiDB) { + $jobs[] = new DeleteWikiDbJob($wiki->id); } // deletes any settings, managers and the wiki itself - $jobs[] = new DeleteWikiFinalizeJob( $wiki->id ); + $jobs[] = new DeleteWikiFinalizeJob($wiki->id); - $logMessage = implode(',', array_map("get_class", $jobs)); - Log::info( __METHOD__ . ": Dispatching hard delete job chain for id: {$wiki->id}, jobs: {$logMessage}."); + $logMessage = implode(',', array_map('get_class', $jobs)); + Log::info(__METHOD__ . ": Dispatching hard delete job chain for id: {$wiki->id}, jobs: {$logMessage}."); Bus::chain([ - ...$jobs - ])->catch(function (Throwable $e ) use ( $wiki ) { - Log::error( __METHOD__ . "An error occured when deleting {$wiki->id}: " . $e->getMessage()); + ...$jobs, + ])->catch(function (Throwable $e) use ($wiki) { + Log::error(__METHOD__ . "An error occured when deleting {$wiki->id}: " . $e->getMessage()); })->dispatch(); } diff --git a/app/Jobs/DeleteWikiFinalizeJob.php b/app/Jobs/DeleteWikiFinalizeJob.php index 26b3e0f82..38358204d 100644 --- a/app/Jobs/DeleteWikiFinalizeJob.php +++ b/app/Jobs/DeleteWikiFinalizeJob.php @@ -1,25 +1,24 @@ wikiId = $wikiId; } @@ -28,48 +27,49 @@ public function __construct( $wikiId ) * * @return string */ - public function uniqueId() - { + public function uniqueId() { return strval($this->wikiId); } /** * @return void */ - public function handle( HttpRequest $request ) - { - $wiki = Wiki::withTrashed()->where('id', $this->wikiId )->first(); - + public function handle(HttpRequest $request) { + $wiki = Wiki::withTrashed()->where('id', $this->wikiId)->first(); - if( !$wiki ) { + if (!$wiki) { $this->fail(new \RuntimeException("Wiki not found for {$this->wikiId}")); + return; } - if( !$wiki->deleted_at ) { + if (!$wiki->deleted_at) { $this->fail(new \RuntimeException("Wiki {$this->wikiId} is not deleted, but job got dispatched.")); + return; } $wikiDB = $wiki->wikiDb()->first(); - if( $wikiDB ) { + if ($wikiDB) { $elasticSearchHosts = Config::get('wbstack.elasticsearch_hosts'); foreach ($elasticSearchHosts as $elasticSearchHost) { try { $elasticSearchBaseName = $wikiDB->name; $elasticSearchHelper = new ElasticSearchHelper($elasticSearchHost, $elasticSearchBaseName); $request->reset(); - if( $elasticSearchHelper->hasIndices( $request ) ) { + if ($elasticSearchHelper->hasIndices($request)) { throw new \RuntimeException("Elasticsearch indices with basename {$elasticSearchBaseName} still exists in {$elasticSearchHost}"); } } catch (\RuntimeException $exception) { $this->fail($exception); + continue; } $this->fail(new \RuntimeException("WikiDb for {$wiki->id} still exists")); } + return; } @@ -78,13 +78,15 @@ public function handle( HttpRequest $request ) $qsNamespace = $wiki->wikiQueryserviceNamespace()->first(); - if( $qsNamespace ) { + if ($qsNamespace) { $this->fail(new \RuntimeException("Queryservice namespace for {$wiki->id} still exists")); + return; } - if ( !$this->deleteSiteDirectory( $wiki->id) ) { - $this->fail(new \RuntimeException("Failed deleting site directory.")); + if (!$this->deleteSiteDirectory($wiki->id)) { + $this->fail(new \RuntimeException('Failed deleting site directory.')); + return; } @@ -95,23 +97,25 @@ public function handle( HttpRequest $request ) $wiki->forceDelete(); } - public function deleteSiteDirectory( int $wiki_id ): bool { + public function deleteSiteDirectory(int $wiki_id): bool { try { $disk = Storage::disk('static-assets'); - if (! $disk instanceof Cloud) { - $this->fail(new \RuntimeException("Invalid storage (not cloud).")); + if (!$disk instanceof Cloud) { + $this->fail(new \RuntimeException('Invalid storage (not cloud).')); + return false; } - $directory = Wiki::getSiteDirectory( $wiki_id ); - if ( $disk->exists($directory) ) { + $directory = Wiki::getSiteDirectory($wiki_id); + if ($disk->exists($directory)) { return $disk->deleteDirectory($directory); } else { return true; } - } catch ( \Exception $ex ) { + } catch (\Exception $ex) { $this->fail($ex); + return false; } diff --git a/app/Jobs/ElasticSearchAliasInit.php b/app/Jobs/ElasticSearchAliasInit.php index 5a139a9f3..9eb266309 100644 --- a/app/Jobs/ElasticSearchAliasInit.php +++ b/app/Jobs/ElasticSearchAliasInit.php @@ -2,105 +2,104 @@ namespace App\Jobs; -use Illuminate\Support\Facades\Log; use App\Http\Curl\HttpRequest; use App\WikiDb; +use Illuminate\Support\Facades\Log; -class ElasticSearchAliasInit extends Job -{ +class ElasticSearchAliasInit extends Job { private $wikiId; + private $dbName; + private $sharedPrefix; /** - * @param int $wikiId - * @param string $dbName + * @param string $dbName */ - public function __construct( int $wikiId, string $sharedPrefix = null ) - { + public function __construct(int $wikiId, ?string $sharedPrefix = null) { $this->wikiId = $wikiId; - $this->sharedPrefix = $sharedPrefix ?? getenv( 'ELASTICSEARCH_SHARED_INDEX_PREFIX' ); + $this->sharedPrefix = $sharedPrefix ?? getenv('ELASTICSEARCH_SHARED_INDEX_PREFIX'); } - /** - * @param HttpRequest $request - */ - public function handle( HttpRequest $request ) - { - Log::info( __METHOD__ . ": Updating Elasticsearch aliases for $this->wikiId" ); + public function handle(HttpRequest $request) { + Log::info(__METHOD__ . ": Updating Elasticsearch aliases for $this->wikiId"); - if ( !$this->sharedPrefix ) { - Log::error( __METHOD__ . ": Missing shared index prefix for $this->wikiId" ); + if (!$this->sharedPrefix) { + Log::error(__METHOD__ . ": Missing shared index prefix for $this->wikiId"); $this->fail( - new \RuntimeException( "Missing shared index prefix for $this->wikiId" ) + new \RuntimeException("Missing shared index prefix for $this->wikiId") ); + return; } - Log::info( __METHOD__ . ": Using '$this->sharedPrefix' as the shared prefix for $this->wikiId" ); + Log::info(__METHOD__ . ": Using '$this->sharedPrefix' as the shared prefix for $this->wikiId"); - $this->dbName = WikiDb::where( 'wiki_id', $this->wikiId )->pluck( 'name' )->first(); - if ( !$this->dbName ) { - Log::error( __METHOD__ . ": Failed to get database name for $this->wikiId" ); + $this->dbName = WikiDb::where('wiki_id', $this->wikiId)->pluck('name')->first(); + if (!$this->dbName) { + Log::error(__METHOD__ . ": Failed to get database name for $this->wikiId"); $this->fail( - new \RuntimeException( "Failed to get database name for $this->wikiId" ) + new \RuntimeException("Failed to get database name for $this->wikiId") ); + return; } $actions = []; - foreach ( [ 'content', 'general' ] as $index ) { + foreach (['content', 'general'] as $index) { $notAliasedIndex = $this->sharedPrefix . '_' . $index . '_first'; $filter = $this->dbName . '-'; $aliases = [ $this->dbName, $this->dbName . '_' . $index, - $this->dbName . '_' . $index . '_first' + $this->dbName . '_' . $index . '_first', ]; - foreach ( $aliases as $alias ) { - array_push( $actions, [ + foreach ($aliases as $alias) { + array_push($actions, [ 'add' => [ 'index' => $notAliasedIndex, 'alias' => $alias, 'routing' => $alias, - 'filter' => [ 'prefix' => [ 'wiki' => $filter ] ] - ] - ] ); + 'filter' => ['prefix' => ['wiki' => $filter]], + ], + ]); } } - $request->setOptions( [ - CURLOPT_URL => getenv( 'ELASTICSEARCH_SHARED_INDEX_HOST' ) . '/_aliases', + $request->setOptions([ + CURLOPT_URL => getenv('ELASTICSEARCH_SHARED_INDEX_HOST') . '/_aliases', CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60 * 15, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_HTTPHEADER => [ 'Content-Type: application/json' ], - CURLOPT_POSTFIELDS => json_encode( [ 'actions' => $actions ] ) - ] ); + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], + CURLOPT_POSTFIELDS => json_encode(['actions' => $actions]), + ]); $rawResponse = $request->execute(); $error = $request->error(); $request->close(); - if ( $error ) { - Log::error( __METHOD__ . ": Updating Elasticsearch aliases failed for $this->wikiId with $rawResponse" ); + if ($error) { + Log::error(__METHOD__ . ": Updating Elasticsearch aliases failed for $this->wikiId with $rawResponse"); $this->fail( - new \RuntimeException( "cURL errored for $this->wikiId with $error" ) + new \RuntimeException("cURL errored for $this->wikiId with $error") ); + return; } - $json = json_decode( $rawResponse, true ); - if ( $json[ 'acknowledged' ] !== true ) { - Log::error( __METHOD__ . ": Updating Elasticsearch aliases failed for $this->wikiId with $rawResponse" ); + $json = json_decode($rawResponse, true); + if ($json['acknowledged'] !== true) { + Log::error(__METHOD__ . ": Updating Elasticsearch aliases failed for $this->wikiId with $rawResponse"); $this->fail( - new \RuntimeException( "Updating Elasticsearch aliases failed for $this->wikiId with $rawResponse" ) + new \RuntimeException("Updating Elasticsearch aliases failed for $this->wikiId with $rawResponse") ); + return; } - Log::info( __METHOD__ . ": Updating Elasticsearch aliases finished for $this->wikiId" ); + Log::info(__METHOD__ . ": Updating Elasticsearch aliases finished for $this->wikiId"); } } diff --git a/app/Jobs/ElasticSearchIndexDelete.php b/app/Jobs/ElasticSearchIndexDelete.php index ceda24702..2b69ca081 100644 --- a/app/Jobs/ElasticSearchIndexDelete.php +++ b/app/Jobs/ElasticSearchIndexDelete.php @@ -1,23 +1,21 @@ wikiId = $wikiId; } @@ -26,38 +24,40 @@ public function __construct( int $wikiId) * * @return string */ - public function uniqueId() - { + public function uniqueId() { return strval($this->wikiId); } /** * @return void */ - public function handle( HttpRequest $request ) - { - $wiki = Wiki::withTrashed()->where( [ 'id' => $this->wikiId ] )->with('settings')->with('wikiDb')->first(); + public function handle(HttpRequest $request) { + $wiki = Wiki::withTrashed()->where(['id' => $this->wikiId])->with('settings')->with('wikiDb')->first(); + + if (!$wiki) { + $this->fail(new \RuntimeException('ElasticSearchIndexDelete job for ' . $this->wikiId . ' was triggered but no wiki available.')); - if ( !$wiki ) { - $this->fail( new \RuntimeException('ElasticSearchIndexDelete job for '.$this->wikiId.' was triggered but no wiki available.') ); return; } - if ( !$wiki->deleted_at ) { - $this->fail( new \RuntimeException('ElasticSearchIndexDelete job for '.$this->wikiId.' but that wiki is not marked as deleted.') ); + if (!$wiki->deleted_at) { + $this->fail(new \RuntimeException('ElasticSearchIndexDelete job for ' . $this->wikiId . ' but that wiki is not marked as deleted.')); + return; } - $setting = $wiki->settings()->where([ 'name' => WikiSetting::wwExtEnableElasticSearch, ])->first(); - if ( !$setting ) { - $this->fail( new \RuntimeException('ElasticSearchIndexDelete job for '.$this->wikiId.' was triggered but no setting available') ); + $setting = $wiki->settings()->where(['name' => WikiSetting::wwExtEnableElasticSearch])->first(); + if (!$setting) { + $this->fail(new \RuntimeException('ElasticSearchIndexDelete job for ' . $this->wikiId . ' was triggered but no setting available')); + return; } $wikiDB = $wiki->wikiDb()->first(); - if ( !$wikiDB ) { - $this->fail( new \RuntimeException('ElasticSearchIndexDelete job for '.$this->wikiId.' was triggered but no WikiDb available') ); - $setting->update( [ 'value' => false ] ); + if (!$wikiDB) { + $this->fail(new \RuntimeException('ElasticSearchIndexDelete job for ' . $this->wikiId . ' was triggered but no WikiDb available')); + $setting->update(['value' => false]); + return; } @@ -65,7 +65,8 @@ public function handle( HttpRequest $request ) $elasticSearchHosts = Config::get('wbstack.elasticsearch_hosts'); if (empty($elasticSearchHosts)) { - $this->fail( new \RuntimeException('No ElasticSearch hosts were configured, cannot continue.') ); + $this->fail(new \RuntimeException('No ElasticSearch hosts were configured, cannot continue.')); + return; } @@ -74,21 +75,22 @@ public function handle( HttpRequest $request ) $elasticSearchHelper = new ElasticSearchHelper($elasticSearchHost, $elasticSearchBaseName); // Not having any indices to remove should not fail the job - if( !$elasticSearchHelper->hasIndices($request) ) { - $setting->update( [ 'value' => false ] ); + if (!$elasticSearchHelper->hasIndices($request)) { + $setting->update(['value' => false]); + continue; } } catch (\RuntimeException $exception) { $this->fail($exception); + continue; } - // So there are some indices to delete for the wiki // // make a request to the elasticsearch cluster using DELETE // use cirrusSearch baseName to delete indices - $url = $elasticSearchHost."/{$elasticSearchBaseName}*"; + $url = $elasticSearchHost . "/{$elasticSearchBaseName}*"; $request->reset(); @@ -108,18 +110,20 @@ public function handle( HttpRequest $request ) $request->close(); if ($err) { - $this->fail( new \RuntimeException('curl error for '.$this->wikiId.': '.$err) ); + $this->fail(new \RuntimeException('curl error for ' . $this->wikiId . ': ' . $err)); + continue; } $response = json_decode($rawResponse, true); - if ( !is_array($response) || !array_key_exists('acknowledged', $response) || $response['acknowledged'] !== true) { - $this->fail( new \RuntimeException('ElasticSearchIndexDelete job for '.$this->wikiId.' was not successful: '.$rawResponse) ); + if (!is_array($response) || !array_key_exists('acknowledged', $response) || $response['acknowledged'] !== true) { + $this->fail(new \RuntimeException('ElasticSearchIndexDelete job for ' . $this->wikiId . ' was not successful: ' . $rawResponse)); + continue; } - $setting->update( [ 'value' => false ] ); + $setting->update(['value' => false]); } } } diff --git a/app/Jobs/ExpireOldUserVerificationTokensJob.php b/app/Jobs/ExpireOldUserVerificationTokensJob.php index 7361507a9..665cae75e 100644 --- a/app/Jobs/ExpireOldUserVerificationTokensJob.php +++ b/app/Jobs/ExpireOldUserVerificationTokensJob.php @@ -4,13 +4,11 @@ use App\UserVerificationToken; -class ExpireOldUserVerificationTokensJob extends Job -{ +class ExpireOldUserVerificationTokensJob extends Job { /** * @return void */ - public function handle() - { + public function handle() { $oldTokens = UserVerificationToken::whereDate('created_at', '<=', \Carbon\Carbon::now()->subDays(1)->toDateTimeString()); $oldTokens->delete(); } diff --git a/app/Jobs/FailJob.php b/app/Jobs/FailJob.php index ee97901d4..f0ffe03e3 100644 --- a/app/Jobs/FailJob.php +++ b/app/Jobs/FailJob.php @@ -2,11 +2,8 @@ namespace App\Jobs; -class FailJob extends Job -{ - public function handle(): void - { - $this->fail(self::class.': The job failed successfully (this is intended, as this is a test Job). Have a nice day.'); - } +class FailJob extends Job { + public function handle(): void { + $this->fail(self::class . ': The job failed successfully (this is intended, as this is a test Job). Have a nice day.'); + } } - diff --git a/app/Jobs/FailStalledEntityImportsJob.php b/app/Jobs/FailStalledEntityImportsJob.php index b10229156..934bcdef1 100644 --- a/app/Jobs/FailStalledEntityImportsJob.php +++ b/app/Jobs/FailStalledEntityImportsJob.php @@ -2,6 +2,7 @@ namespace App\Jobs; +use App\WikiEntityImport; use App\WikiEntityImportStatus; use Carbon\Carbon; use Illuminate\Bus\Queueable; @@ -10,13 +11,11 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Log; -use App\WikiEntityImport; -class FailStalledEntityImportsJob implements ShouldQueue -{ +class FailStalledEntityImportsJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public function handle(): void - { + + public function handle(): void { $deadline = Carbon::now()->subHours(24); $now = Carbon::now(); @@ -31,7 +30,7 @@ public function handle(): void if ($stalledImports->count() > 0) { Log::info( - "Marked ".$stalledImports->count()." WikiEntityImports as failed as they seem to be stalled." + 'Marked ' . $stalledImports->count() . ' WikiEntityImports as failed as they seem to be stalled.' ); } } diff --git a/app/Jobs/GenerateOAuth2KeysJob.php b/app/Jobs/GenerateOAuth2KeysJob.php index 8c80cbae2..471d27e2c 100644 --- a/app/Jobs/GenerateOAuth2KeysJob.php +++ b/app/Jobs/GenerateOAuth2KeysJob.php @@ -5,25 +5,23 @@ use App\Wiki; use App\WikiSetting; use Illuminate\Bus\Queueable; -use Illuminate\Support\Facades\Log; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Log; -class GenerateOAuth2KeysJob extends Job implements ShouldQueue -{ +class GenerateOAuth2KeysJob extends Job implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public function handle() - { + public function handle() { $allWikis = Wiki::all(); foreach ($allWikis as $wiki) { try { $hasPrivateKey = WikiSetting::where('wiki_id', $wiki->id) - ->where('name', 'wgOAuth2PrivateKey') - ->exists(); + ->where('name', 'wgOAuth2PrivateKey') + ->exists(); if (!$hasPrivateKey) { $keyPair = openssl_pkey_new([ @@ -51,7 +49,7 @@ public function handle() } catch (\Exception $ex) { $this->job->markAsFailed(); Log::error( - 'Failure generating keys for '.$wiki->getAttribute('domain').' for sitestats: '.$ex->getMessage() + 'Failure generating keys for ' . $wiki->getAttribute('domain') . ' for sitestats: ' . $ex->getMessage() ); } } diff --git a/app/Jobs/InvitationCreateJob.php b/app/Jobs/InvitationCreateJob.php index 07053e8f3..5ab4acc38 100644 --- a/app/Jobs/InvitationCreateJob.php +++ b/app/Jobs/InvitationCreateJob.php @@ -4,31 +4,28 @@ use App\Invitation; -class InvitationCreateJob extends Job -{ +class InvitationCreateJob extends Job { private $code; - public function __construct(string $code) - { + public function __construct(string $code) { $this->code = strtolower($code); } /** * @return Invitation|null */ - public function handle() - { + public function handle() { $test = Invitation::where('code', $this->code)->first(); if ($test) { $this->fail( new \RuntimeException('Invitation code already existed') ); - return; //safegaurd + return; // safegaurd } return Invitation::create([ - 'code' => $this->code, - ]); + 'code' => $this->code, + ]); } } diff --git a/app/Jobs/InvitationDeleteJob.php b/app/Jobs/InvitationDeleteJob.php index f952b01cc..81619679f 100644 --- a/app/Jobs/InvitationDeleteJob.php +++ b/app/Jobs/InvitationDeleteJob.php @@ -4,23 +4,20 @@ use App\Invitation; -class InvitationDeleteJob extends Job -{ +class InvitationDeleteJob extends Job { private $code; /** * @return void */ - public function __construct(string $code) - { + public function __construct(string $code) { $this->code = strtolower($code); } /** * @return void */ - public function handle() - { + public function handle() { $invite = Invitation::where('code', $this->code)->first(); if ($invite) { $invite->delete(); @@ -29,7 +26,7 @@ public function handle() new \RuntimeException('Invitation not found, so can\'t delete') ); - return; //safegaurd + return; // safegaurd } } } diff --git a/app/Jobs/Job.php b/app/Jobs/Job.php index 1969c9930..869ae1aa7 100644 --- a/app/Jobs/Job.php +++ b/app/Jobs/Job.php @@ -8,8 +8,7 @@ use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Config; -abstract class Job implements ShouldQueue -{ +abstract class Job implements ShouldQueue { /* |-------------------------------------------------------------------------- | Queueable Jobs @@ -24,8 +23,7 @@ abstract class Job implements ShouldQueue public $timeout = 60; - public function backoff(): array - { + public function backoff(): array { return Config::get('queue.backoff'); } } diff --git a/app/Jobs/KubernetesIngressCreate.php b/app/Jobs/KubernetesIngressCreate.php index c566af145..41e6a6799 100644 --- a/app/Jobs/KubernetesIngressCreate.php +++ b/app/Jobs/KubernetesIngressCreate.php @@ -2,9 +2,9 @@ namespace App\Jobs; +use Illuminate\Support\Facades\Log; use Maclof\Kubernetes\Client; use Maclof\Kubernetes\Models\Ingress; -use Illuminate\Support\Facades\Log; /** * This can be run with for example: @@ -12,34 +12,32 @@ * * If you need to cleanup a test run of this you need to remove the ingress and the related secret */ -class KubernetesIngressCreate extends Job -{ +class KubernetesIngressCreate extends Job { private $id; + private $wikiDomain; /** - * @param int|string $wikiId - * @param string $wikiDomain + * @param int|string $wikiId + * @param string $wikiDomain */ - public function __construct($wikiId, $wikiDomain) - { + public function __construct($wikiId, $wikiDomain) { $this->id = $wikiId; $this->wikiDomain = $wikiDomain; } - public static function getKubernetesIngressName( $wikiId ): string { + public static function getKubernetesIngressName($wikiId): string { return 'mediawiki-site-' . $wikiId; } /** * @return void */ - public function handle( Client $client ) - { + public function handle(Client $client) { // Docs for the client https://github.com/maclof/kubernetes-client // Connection example from: https://github.com/maclof/kubernetes-client#using-a-service-account - Log::info( 'Creating k8s client' ); + Log::info('Creating k8s client'); $ingress = new Ingress([ 'metadata' => [ @@ -73,7 +71,7 @@ public function handle( Client $client ) 'hosts' => [ $this->wikiDomain, ], - 'secretName' => 'mediawiki-site-tls-'.$this->id, + 'secretName' => 'mediawiki-site-tls-' . $this->id, ], ], 'rules' => [ @@ -103,14 +101,14 @@ public function handle( Client $client ) Log::info('Getting ingress resources'); $ingresses = $client->ingresses(); - Log::info('Checking if resource exists: '.$ingress->getMetadata('name')); + Log::info('Checking if resource exists: ' . $ingress->getMetadata('name')); $exists = $ingresses->exists($ingress->getMetadata('name')); if ($exists) { $this->fail( new \RuntimeException('Ingress already exists, but it should not') ); - return; //safegaurd + return; // safegaurd } Log::info('Creating ingress resource'); diff --git a/app/Jobs/KubernetesIngressDeleteJob.php b/app/Jobs/KubernetesIngressDeleteJob.php index f30744efa..51fe9e1d1 100644 --- a/app/Jobs/KubernetesIngressDeleteJob.php +++ b/app/Jobs/KubernetesIngressDeleteJob.php @@ -2,51 +2,51 @@ namespace App\Jobs; -use Maclof\Kubernetes\Client; use App\Wiki; +use Maclof\Kubernetes\Client; /** * Job for deleting a wikis kubernetes ingress */ -class KubernetesIngressDeleteJob extends Job -{ +class KubernetesIngressDeleteJob extends Job { private $id; + private $wikiDomain; /** - * @param int|string $wikiId + * @param int|string $wikiId */ - public function __construct( $wikiId ) - { + public function __construct($wikiId) { $this->id = $wikiId; } /** * @return void */ - public function handle( Client $client ) - { - $wiki = Wiki::withTrashed()->where('id', $this->id )->first(); + public function handle(Client $client) { + $wiki = Wiki::withTrashed()->where('id', $this->id)->first(); + + if (!$wiki) { + $this->fail(new \RuntimeException("Could not find wiki with id {$this->id}")); - if ( !$wiki) { - $this->fail( new \RuntimeException("Could not find wiki with id {$this->id}") ); return; } - if ( !$wiki->deleted_at) { - $this->fail( new \RuntimeException("Wiki {$this->id} is not deleted, but it's ingress got called to be deleted.") ); + if (!$wiki->deleted_at) { + $this->fail(new \RuntimeException("Wiki {$this->id} is not deleted, but it's ingress got called to be deleted.")); + return; } - $exists = $client->ingresses()->exists( KubernetesIngressCreate::getKubernetesIngressName($this->id) ); - + $exists = $client->ingresses()->exists(KubernetesIngressCreate::getKubernetesIngressName($this->id)); + // just exit if there is nothing no need to fail - if ( !$exists ) { + if (!$exists) { return; } // TODO how to test any of this? - $result = $client->ingresses()->deleteByName( KubernetesIngressCreate::getKubernetesIngressName($this->id) ); + $result = $client->ingresses()->deleteByName(KubernetesIngressCreate::getKubernetesIngressName($this->id)); } } diff --git a/app/Jobs/MediawikiInit.php b/app/Jobs/MediawikiInit.php index 1036bb825..9fd6b5123 100644 --- a/app/Jobs/MediawikiInit.php +++ b/app/Jobs/MediawikiInit.php @@ -1,19 +1,20 @@ wikiDomain = $wikiDomain; $this->username = $username; $this->email = $email; @@ -22,15 +23,14 @@ public function __construct($wikiDomain, $username, $email) /** * @return void */ - public function handle( HttpRequest $request ) - { + public function handle(HttpRequest $request) { $data = [ 'username' => $this->username, 'email' => $this->email, ]; $request->setOptions([ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackInit&format=json', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackInit&format=json', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 60, @@ -39,26 +39,26 @@ public function handle( HttpRequest $request ) CURLOPT_POSTFIELDS => http_build_query($data), CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wikiDomain, + 'host: ' . $this->wikiDomain, ], ]); - $rawResponse = $request->execute(); + $rawResponse = $request->execute(); $err = $request->error(); $request->close(); if ($err) { - throw new \RuntimeException('curl error for '.$this->wikiDomain.': '.$err); + throw new \RuntimeException('curl error for ' . $this->wikiDomain . ': ' . $err); } $response = json_decode($rawResponse, true); - if ( !is_array($response) || !array_key_exists('wbstackInit', $response) ) { - throw new \RuntimeException('wbstackInit call for '.$this->wikiDomain.'. No wbstackInit key in response: '.$rawResponse); + if (!is_array($response) || !array_key_exists('wbstackInit', $response)) { + throw new \RuntimeException('wbstackInit call for ' . $this->wikiDomain . '. No wbstackInit key in response: ' . $rawResponse); } if ($response['wbstackInit']['success'] == 0) { - throw new \RuntimeException('wbstackInit call for '.$this->wikiDomain.' was not successful:'.$rawResponse); + throw new \RuntimeException('wbstackInit call for ' . $this->wikiDomain . ' was not successful:' . $rawResponse); } // Otherwise there was success (and we could get the userId if we wanted... } diff --git a/app/Jobs/MediawikiSandboxLoadData.php b/app/Jobs/MediawikiSandboxLoadData.php index feacff528..ace75498b 100644 --- a/app/Jobs/MediawikiSandboxLoadData.php +++ b/app/Jobs/MediawikiSandboxLoadData.php @@ -2,16 +2,15 @@ namespace App\Jobs; -class MediawikiSandboxLoadData extends Job -{ +class MediawikiSandboxLoadData extends Job { private $wikiDomain; + private $dataSet; /** * @return void */ - public function __construct($wikiDomain, $dataSet) - { + public function __construct($wikiDomain, $dataSet) { $this->wikiDomain = $wikiDomain; $this->dataSet = $dataSet; } @@ -19,15 +18,14 @@ public function __construct($wikiDomain, $dataSet) /** * @return void */ - public function handle() - { + public function handle() { $data = [ 'dataSet' => $this->dataSet, ]; $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/rest.php/wikibase-exampledata/v0/load', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/rest.php/wikibase-exampledata/v0/load', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 10 * 60, // TODO Long 10 mins (probably shouldn't keep the request open...) @@ -36,7 +34,7 @@ public function handle() CURLOPT_POSTFIELDS => http_build_query($data), CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wikiDomain, + 'host: ' . $this->wikiDomain, ], ]); @@ -44,20 +42,20 @@ public function handle() $err = curl_error($curl); if ($err) { $this->fail( - new \RuntimeException('wikibase-exampledata/v0/load curl error for '.$this->wikiDomain.': '.$err) + new \RuntimeException('wikibase-exampledata/v0/load curl error for ' . $this->wikiDomain . ': ' . $err) ); - return; //safegaurd + return; // safegaurd } curl_close($curl); - if (! strstr($rawResponse, 'Done!')) { + if (!strstr($rawResponse, 'Done!')) { $this->fail( - new \RuntimeException('wikibase-exampledata/v0/load call for '.$this->wikiDomain.' was not successful:'.$rawResponse) + new \RuntimeException('wikibase-exampledata/v0/load call for ' . $this->wikiDomain . ' was not successful:' . $rawResponse) ); - return; //safegaurd + return; // safegaurd } } } diff --git a/app/Jobs/MediawikiUpdate.php b/app/Jobs/MediawikiUpdate.php index 914665893..ff708d348 100644 --- a/app/Jobs/MediawikiUpdate.php +++ b/app/Jobs/MediawikiUpdate.php @@ -23,25 +23,25 @@ * And loop them (10 at a time) * for i in {1..10}; do php artisan job:dispatchNow MediawikiUpdate wiki_dbs.version mw1.34-wbs1 mw1.34-wbs1 mw1.35-wbs1 mediawiki-135; done */ -class MediawikiUpdate extends Job -{ +class MediawikiUpdate extends Job { private $selectCol; + private $selectValue; private $targetBackendHost; private $from; + private $to; /** - * @param string $selectCol Selection field in the wiki_dbs table e.g. "wiki_id" - * @param string $selectValue Selection value in the wiki_dbs table e.g. "38" - * @param string $from The version of schema to update from - * @param string $to The version of schema to say we updated to - * @param string $targetBackendHost the backend API hosts to hit (as they are versioned) + * @param string $selectCol Selection field in the wiki_dbs table e.g. "wiki_id" + * @param string $selectValue Selection value in the wiki_dbs table e.g. "38" + * @param string $from The version of schema to update from + * @param string $to The version of schema to say we updated to + * @param string $targetBackendHost the backend API hosts to hit (as they are versioned) */ - public function __construct($selectCol, $selectValue, $from, $to, $targetBackendHost) - { + public function __construct($selectCol, $selectValue, $from, $to, $targetBackendHost) { $this->selectCol = $selectCol; $this->selectValue = $selectValue; $this->from = $from; @@ -53,8 +53,7 @@ public function __construct($selectCol, $selectValue, $from, $to, $targetBackend /** * @return void */ - public function handle() - { + public function handle() { // Get the Wikidb and Wiki we are operating on, where the wiki is NOT deleted $wikidb = WikiDb::where($this->selectCol, $this->selectValue) ->select('wiki_dbs.*') // Needed to avoid confusing the update later?! =o https://stackoverflow.com/a/56141702/4746236 @@ -66,12 +65,12 @@ public function handle() if ($wikidb->version !== $this->from) { $this->fail( new \RuntimeException( - 'Wiki Db selected is at different version than expected. '. - 'At: '.$wikidb->version.' Expected: '.$this->from + 'Wiki Db selected is at different version than expected. ' . + 'At: ' . $wikidb->version . ' Expected: ' . $this->from ) ); - return; //safegaurd + return; // safegaurd } $wiki = $wikidb->wiki; @@ -80,7 +79,7 @@ public function handle() // Make a request to the backend MW API to perform the update. $curl = curl_init(); curl_setopt_array($curl, [ - CURLOPT_URL => 'http://'.$this->targetBackendHost.'-app-backend/w/api.php?action=wbstackUpdate&format=json', + CURLOPT_URL => 'http://' . $this->targetBackendHost . '-app-backend/w/api.php?action=wbstackUpdate&format=json', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 60 * 60, // Longish timeout for such things? @@ -88,7 +87,7 @@ public function handle() CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$wikiDomain, + 'host: ' . $wikiDomain, ], ]); @@ -96,10 +95,10 @@ public function handle() $err = curl_error($curl); if ($err) { $this->fail( - new \RuntimeException('curl error for '.$wikiDomain.': '.$err) + new \RuntimeException('curl error for ' . $wikiDomain . ': ' . $err) ); - return; //safegaurd + return; // safegaurd } curl_close($curl); @@ -121,19 +120,19 @@ public function handle() } // Output stuff (output is an array) - echo json_encode($response['output']).PHP_EOL; - echo json_encode($response['script']).PHP_EOL; - echo json_encode($response['return']).PHP_EOL; - echo json_encode($wikiDomain).PHP_EOL; - echo json_encode('success: '.$success).PHP_EOL; + echo json_encode($response['output']) . PHP_EOL; + echo json_encode($response['script']) . PHP_EOL; + echo json_encode($response['return']) . PHP_EOL; + echo json_encode($wikiDomain) . PHP_EOL; + echo json_encode('success: ' . $success) . PHP_EOL; // Exception if really bad - if (! $success) { + if (!$success) { $this->fail( - new \RuntimeException('wbstackUpdate call for '.$wikiDomain.' was not successful:'.$rawResponse) + new \RuntimeException('wbstackUpdate call for ' . $wikiDomain . ' was not successful:' . $rawResponse) ); - return; //safegaurd + return; // safegaurd } } } diff --git a/app/Jobs/PlatformStatsSummaryJob.php b/app/Jobs/PlatformStatsSummaryJob.php index a59ae7c7a..d882e6159 100644 --- a/app/Jobs/PlatformStatsSummaryJob.php +++ b/app/Jobs/PlatformStatsSummaryJob.php @@ -3,16 +3,16 @@ namespace App\Jobs; use App\Constants\MediawikiNamespace; -use App\Traits; use App\Helper\MWTimestampHelper; -use App\Wiki; +use App\Traits; use App\User; -use Illuminate\Database\DatabaseManager; -use PDO; +use App\Wiki; use Carbon\CarbonImmutable; -use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Config; +use Illuminate\Database\DatabaseManager; use Illuminate\Support\Facades\App; +use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Log; +use PDO; /* * @@ -28,25 +28,25 @@ * * Example: php artisan job:dispatch PlatformStatsSummaryJob */ -class PlatformStatsSummaryJob extends Job -{ +class PlatformStatsSummaryJob extends Job { use Traits\PageFetcher; public $timeout = 3600; private $inactiveThreshold; + private $creationRateRanges; - private $platformSummaryStatsVersion = "v1"; + private $platformSummaryStatsVersion = 'v1'; public function __construct() { $this->inactiveThreshold = Config::get('wbstack.platform_summary_inactive_threshold'); $this->creationRateRanges = Config::get('wbstack.platform_summary_creation_rate_ranges'); - $this->apiUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php'; + $this->apiUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php'; } - private function isNullOrEmpty( $value ): bool { - return is_null($value) || intVal($value) === 0; + private function isNullOrEmpty($value): bool { + return is_null($value) || intval($value) === 0; } @@ -56,14 +56,15 @@ public function getCreationStats(): array { foreach ($this->creationRateRanges as $range) { $limit = $now->clone()->sub(new \DateInterval($range)); $wikis = Wiki::where('created_at', '>=', $limit)->count(); - $result['wikis_created_'.$range] = $wikis; + $result['wikis_created_' . $range] = $wikis; $users = User::where('created_at', '>=', $limit)->count(); - $result['users_created_'.$range] = $users; + $result['users_created_' . $range] = $users; } + return $result; } - public function prepareStats( array $allStats, $wikis): array { + public function prepareStats(array $allStats, $wikis): array { $deletedWikis = []; $editedLast90DaysWikis = []; @@ -75,58 +76,63 @@ public function prepareStats( array $allStats, $wikis): array { $currentTime = CarbonImmutable::now(); - foreach( $wikis as $wiki ) { + foreach ($wikis as $wiki) { - if( !is_null($wiki->deleted_at) ) { + if (!is_null($wiki->deleted_at)) { $deletedWikis[] = $wiki; + continue; } - //add items and properties counts of the wiki to the corresponded arrays + // add items and properties counts of the wiki to the corresponded arrays try { $nextItemCount = count($this->fetchPagesInNamespace($wiki->domain, MediawikiNamespace::item)); array_push($itemsCount, $nextItemCount); } catch (\Exception $ex) { - Log::warning("Failed to fetch item count for wiki ".$wiki->domain.", will use 0 instead."); + Log::warning('Failed to fetch item count for wiki ' . $wiki->domain . ', will use 0 instead.'); } try { $nextPropertyCount = count($this->fetchPagesInNamespace($wiki->domain, MediawikiNamespace::property)); array_push($propertiesCount, $nextPropertyCount); } catch (\Exception $ex) { - Log::warning("Failed to fetch property count for wiki ".$wiki->domain.", will use 0 instead."); + Log::warning('Failed to fetch property count for wiki ' . $wiki->domain . ', will use 0 instead.'); } $wikiDb = $wiki->wikiDb()->first(); - if( !$wikiDb ) { + if (!$wikiDb) { Log::error(__METHOD__ . ": Could not find WikiDB for {$wiki->domain}"); + continue; } $found_key = array_search($wiki->domain, array_column($allStats, 'wiki')); - if($found_key === false) { + if ($found_key === false) { Log::warning(__METHOD__ . ": Could not find stats for {$wiki->domain}"); + continue; } $stats = $allStats[$found_key]; // is it empty? - if( $this->isNullOrEmpty($stats['edits']) && $this->isNullOrEmpty($stats['pages']) && $this->isNullOrEmpty($stats['lastEdit'])) { + if ($this->isNullOrEmpty($stats['edits']) && $this->isNullOrEmpty($stats['pages']) && $this->isNullOrEmpty($stats['lastEdit'])) { $emptyWikis[] = $wiki; + continue; } $nonDeletedStats[] = $stats; // is it edited in the last 90 days? - if(!is_null($stats['lastEdit'])){ - $lastTimestamp = MWTimestampHelper::getCarbonFromMWTimestamp(intVal($stats['lastEdit'])); + if (!is_null($stats['lastEdit'])) { + $lastTimestamp = MWTimestampHelper::getCarbonFromMWTimestamp(intval($stats['lastEdit'])); $diff = $lastTimestamp->diffInSeconds($currentTime); if ($diff <= $this->inactiveThreshold) { $editedLast90DaysWikis[] = $wiki; + continue; } } @@ -154,19 +160,18 @@ public function prepareStats( array $allStats, $wikis): array { 'total_non_deleted_pages' => $totalNonDeletedPages, 'total_non_deleted_edits' => $totalNonDeletedEdits, 'total_items_count' => $totalItemsCount, - 'total_properties_count' => $totalPropertiesCount + 'total_properties_count' => $totalPropertiesCount, ]; } - public function handle( DatabaseManager $manager ): void - { + public function handle(DatabaseManager $manager): void { $wikis = Wiki::withTrashed()->with('wikidb')->get(); $conn = $manager->connection('mysql'); $mwConn = $manager->connection('mw'); - if (!$conn instanceof \Illuminate\Database\Connection || !$mwConn instanceof \Illuminate\Database\Connection ) { - throw new \RuntimeException('Must be run on a PDO based DB connection'); + if (!$conn instanceof \Illuminate\Database\Connection || !$mwConn instanceof \Illuminate\Database\Connection) { + throw new \RuntimeException('Must be run on a PDO based DB connection'); } $pdo = $conn->getPdo(); @@ -187,18 +192,18 @@ public function handle( DatabaseManager $manager ): void // Execute the second query using the mw // PDO to talk to mediawiki dbs $allStats = $mediawikiPdo->query($query)->fetchAll(PDO::FETCH_ASSOC); - $summary = $this->prepareStats( $allStats, $wikis ); + $summary = $this->prepareStats($allStats, $wikis); $creationStats = $this->getCreationStats(); $summary = array_merge($summary, $creationStats); // Output to be scraped from logs - if( !App::runningUnitTests() ) { - print( json_encode($summary) . PHP_EOL ); + if (!App::runningUnitTests()) { + echo json_encode($summary) . PHP_EOL; } } - private $wikiStatsQuery = <<pluck('domain'); foreach ($allWikiDomains as $wikiDomain) { if ($this->hasPendingJobs($wikiDomain)) { @@ -21,28 +20,28 @@ public function handle (): void } } - private function hasPendingJobs (string $wikiDomain): bool - { + private function hasPendingJobs(string $wikiDomain): bool { $response = Http::withHeaders([ - 'host' => $wikiDomain + 'host' => $wikiDomain, ])->get( - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' ); if ($response->failed()) { $this->job->markAsFailed(); Log::error( - 'Failure polling wiki '.$wikiDomain.' for pending MediaWiki jobs: '.$response->clientError() + 'Failure polling wiki ' . $wikiDomain . ' for pending MediaWiki jobs: ' . $response->clientError() ); + return false; } $pendingJobsCount = data_get($response->json(), 'query.statistics.jobs', 0); + return $pendingJobsCount > 0; } - private function enqueueWiki (string $wikiDomain): void - { + private function enqueueWiki(string $wikiDomain): void { dispatch(new ProcessMediaWikiJobsJob($wikiDomain)); } } diff --git a/app/Jobs/ProcessMediaWikiJobsJob.php b/app/Jobs/ProcessMediaWikiJobsJob.php index e9b357266..298c3ee79 100644 --- a/app/Jobs/ProcessMediaWikiJobsJob.php +++ b/app/Jobs/ProcessMediaWikiJobsJob.php @@ -3,49 +3,47 @@ namespace App\Jobs; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldBeUnique; +use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Log; use Maclof\Kubernetes\Client; use Maclof\Kubernetes\Models\Job as KubernetesJob; -class ProcessMediaWikiJobsJob implements ShouldQueue, ShouldBeUnique -{ +class ProcessMediaWikiJobsJob implements ShouldBeUnique, ShouldQueue { use InteractsWithQueue, Queueable; private string $wikiDomain; + private string $jobsKubernetesNamespace; - public function __construct (string $wikiDomain) - { + public function __construct(string $wikiDomain) { $this->wikiDomain = $wikiDomain; $this->jobsKubernetesNamespace = Config::get('wbstack.api_job_namespace'); } - public function uniqueId(): string - { + public function uniqueId(): string { return $this->wikiDomain; } - public function handle (Client $kubernetesClient): void - { + public function handle(Client $kubernetesClient): void { $kubernetesClient->setNamespace('default'); $mediawikiPod = $kubernetesClient->pods()->setFieldSelector([ - 'status.phase' => 'Running' + 'status.phase' => 'Running', ])->setLabelSelector([ 'app.kubernetes.io/name' => 'mediawiki', - 'app.kubernetes.io/component' => 'app-backend' + 'app.kubernetes.io/component' => 'app-backend', ])->first(); if ($mediawikiPod === null) { $this->fail( new \RuntimeException( - 'Unable to find a running MediaWiki pod in the cluster, '. + 'Unable to find a running MediaWiki pod in the cluster, ' . 'cannot continue.' ) ); + return; } $mediawikiPod = $mediawikiPod->toArray(); @@ -53,18 +51,18 @@ public function handle (Client $kubernetesClient): void $kubernetesClient->setNamespace($this->jobsKubernetesNamespace); $jobSpec = new KubernetesJob([ 'metadata' => [ - 'name' => 'run-all-mw-jobs-'.hash('sha1', $this->wikiDomain), + 'name' => 'run-all-mw-jobs-' . hash('sha1', $this->wikiDomain), 'namespace' => $this->jobsKubernetesNamespace, 'labels' => [ 'app.kubernetes.io/instance' => $this->wikiDomain, - 'app.kubernetes.io/name' => 'run-all-mw-jobs' - ] + 'app.kubernetes.io/name' => 'run-all-mw-jobs', + ], ], 'spec' => [ 'ttlSecondsAfterFinished' => 0, 'template' => [ 'metadata' => [ - 'name' => 'run-all-mw-jobs' + 'name' => 'run-all-mw-jobs', ], 'spec' => [ 'containers' => [ @@ -91,12 +89,12 @@ public function handle (Client $kubernetesClient): void done CMD ], - ] + ], ], - 'restartPolicy' => 'Never' - ] - ] - ] + 'restartPolicy' => 'Never', + ], + ], + ], ]); $job = $kubernetesClient->jobs()->apply($jobSpec); @@ -105,15 +103,14 @@ public function handle (Client $kubernetesClient): void // The k8s client does not fail reliably on 4xx responses, so checking the name // currently serves as poor man's error handling. $this->fail( - new \RuntimeException('Job creation for wiki "'.$this->wikiDomain.'" failed with message: '.data_get($job, 'message', 'n/a')) + new \RuntimeException('Job creation for wiki "' . $this->wikiDomain . '" failed with message: ' . data_get($job, 'message', 'n/a')) ); + return; } Log::info( - 'MediaWiki Job for wiki "'.$this->wikiDomain.'" exists or was created with name "'.$jobName.'".' + 'MediaWiki Job for wiki "' . $this->wikiDomain . '" exists or was created with name "' . $jobName . '".' ); - return; } - } diff --git a/app/Jobs/ProvisionQueryserviceNamespaceJob.php b/app/Jobs/ProvisionQueryserviceNamespaceJob.php index 1826118c5..3da47ed13 100644 --- a/app/Jobs/ProvisionQueryserviceNamespaceJob.php +++ b/app/Jobs/ProvisionQueryserviceNamespaceJob.php @@ -2,41 +2,38 @@ namespace App\Jobs; -use App\QueryserviceNamespace; -use App\Http\Curl\CurlRequest; use App\Http\Curl\HttpRequest; +use App\QueryserviceNamespace; use Illuminate\Support\Facades\Log; /** * Example usage * php artisan job:dispatch ProvisionQueryserviceNamespaceJob */ -class ProvisionQueryserviceNamespaceJob extends Job -{ +class ProvisionQueryserviceNamespaceJob extends Job { private $namespace; + private $maxFree; /** * @return void */ - public function __construct($namespace = null, $maxFree = null) - { + public function __construct($namespace = null, $maxFree = null) { if ($namespace !== null && preg_match('/[^A-Za-z0-9]/', $namespace)) { - throw new \InvalidArgumentException('$namespace must only contain [^A-Za-z0-9] or null, got '.$namespace); + throw new \InvalidArgumentException('$namespace must only contain [^A-Za-z0-9] or null, got ' . $namespace); } // Auto generation and corrections // TODO this stuff could come from the model? if ($namespace === 'null' || $namespace === null) { - $namespace = 'qsns_'.substr(bin2hex(random_bytes(24)), 0, 10); + $namespace = 'qsns_' . substr(bin2hex(random_bytes(24)), 0, 10); } $this->namespace = $namespace; $this->maxFree = $maxFree; } - private function doesMaxFreeSayWeShouldStop(): bool - { + private function doesMaxFreeSayWeShouldStop(): bool { $unassignedQueryserviceNamespaces = QueryserviceNamespace::where('wiki_id', null)->count(); $toCreate = $this->maxFree - $unassignedQueryserviceNamespaces; @@ -46,21 +43,20 @@ private function doesMaxFreeSayWeShouldStop(): bool /** * @return void */ - public function handle( HttpRequest $request ) - { + public function handle(HttpRequest $request) { // If the job is only meant to create so many DBs, then make sure we don't create too many. if ($this->maxFree && $this->doesMaxFreeSayWeShouldStop()) { return; } - $properties = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'../data/RWStore.properties'); + $properties = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . '../data/RWStore.properties'); // Currently only one, but will change at some point... $queryServiceHost = config('app.queryservice_host'); // Replace the namespace in the properties file $properties = str_replace('REPLACE_NAMESPACE', $this->namespace, $properties); - $url = $queryServiceHost.'/bigdata/namespace'; + $url = $queryServiceHost . '/bigdata/namespace'; $request->setOptions([ // TODO when there are multiple hosts, this will need to be different? @@ -84,24 +80,26 @@ public function handle( HttpRequest $request ) $request->close(); if ($err) { - $this->fail( new \RuntimeException('cURL Error #:'.$err) ); + $this->fail(new \RuntimeException('cURL Error #:' . $err)); + return; } else { - if ($response === 'CREATED: '.$this->namespace) { + if ($response === 'CREATED: ' . $this->namespace) { $qsns = QueryserviceNamespace::create([ 'namespace' => $this->namespace, 'backend' => $queryServiceHost, ]); - // TODO error if $qsns is not actually created... - } else if( $response === 'EXISTS: ' .$this->namespace ) { + // TODO error if $qsns is not actually created... + } elseif ($response === 'EXISTS: ' . $this->namespace) { Log::error(__METHOD__ . ": The namespace: {$this->namespace} already exists"); $this->fail( new \RuntimeException("The namespace: {$this->namespace} already exists. response: " . $response) ); - return; + + return; } else { $this->fail( - new \RuntimeException('Valid response, but couldn\'t find "CREATED: " in: '.$response) + new \RuntimeException('Valid response, but couldn\'t find "CREATED: " in: ' . $response) ); return; diff --git a/app/Jobs/ProvisionWikiDbJob.php b/app/Jobs/ProvisionWikiDbJob.php index b16eb48ee..c8d3da4e3 100644 --- a/app/Jobs/ProvisionWikiDbJob.php +++ b/app/Jobs/ProvisionWikiDbJob.php @@ -3,24 +3,23 @@ namespace App\Jobs; use App\WikiDb; -use Illuminate\Support\Facades\DB; use Illuminate\Database\DatabaseManager; +use Illuminate\Support\Facades\DB; /** * Example usage that will always provision a new DB: * php artisan job:dispatch ProvisionWikiDbJob */ -class ProvisionWikiDbJob extends Job -{ +class ProvisionWikiDbJob extends Job { private $prefix; private $newSqlFile; /** * @var string|null|false - * null results in the default database being used - * false results in an auto generated name being used - * string results in that string being used + * null results in the default database being used + * false results in an auto generated name being used + * string results in that string being used */ private $dbName; @@ -33,14 +32,13 @@ class ProvisionWikiDbJob extends Job /** * @return void */ - public function __construct($prefix = null, $dbName = false, $maxFree = null) - { + public function __construct($prefix = null, $dbName = false, $maxFree = null) { if (preg_match('/[^A-Za-z0-9\-_]/', $prefix)) { - throw new \InvalidArgumentException('Prefix must only contain [^A-Za-z0-9\-_], got '.$prefix); + throw new \InvalidArgumentException('Prefix must only contain [^A-Za-z0-9\-_], got ' . $prefix); } if ($dbName !== null && preg_match('/[^A-Za-z0-9\-_]/', $dbName)) { - throw new \InvalidArgumentException('dbName must only contain [^A-Za-z0-9\-_] or null, got '.$dbName); + throw new \InvalidArgumentException('dbName must only contain [^A-Za-z0-9\-_] or null, got ' . $dbName); } // Auto generation and corrections @@ -49,13 +47,13 @@ public function __construct($prefix = null, $dbName = false, $maxFree = null) $dbName = env('MW_DB_DATABASE'); } if ($dbName === 'null' || $dbName === null) { - $dbName = 'mwdb_'.substr(bin2hex(random_bytes(48)), 0, 10); + $dbName = 'mwdb_' . substr(bin2hex(random_bytes(48)), 0, 10); } if ($prefix === 'null' || $prefix === null) { - $prefix = 'mwt_'.substr(bin2hex(random_bytes(48)), 0, 10); + $prefix = 'mwt_' . substr(bin2hex(random_bytes(48)), 0, 10); } - $this->dbUser = 'mwu_'.substr(bin2hex(random_bytes(48)), 0, 10); + $this->dbUser = 'mwu_' . substr(bin2hex(random_bytes(48)), 0, 10); $this->dbPassword = substr(bin2hex(random_bytes(48)), 0, 14); $this->prefix = $prefix; @@ -64,8 +62,7 @@ public function __construct($prefix = null, $dbName = false, $maxFree = null) $this->newSqlFile = config('wbstack.wiki_db_provision_version'); } - private function doesMaxFreeSayWeShouldStop(): bool - { + private function doesMaxFreeSayWeShouldStop(): bool { $wikiDbCondition = ['wiki_id' => null, 'version' => $this->newSqlFile]; $unassignedDbs = WikiDb::where($wikiDbCondition)->count(); $toCreate = $this->maxFree - $unassignedDbs; @@ -76,8 +73,7 @@ private function doesMaxFreeSayWeShouldStop(): bool /** * @return void */ - public function handle( DatabaseManager $manager ) - { + public function handle(DatabaseManager $manager) { // If the job is only meant to create so many DBs, then make sure we don't create too many. if ($this->maxFree && $this->doesMaxFreeSayWeShouldStop()) { return; @@ -85,10 +81,10 @@ public function handle( DatabaseManager $manager ) $manager->purge('mw'); $conn = $manager->connection('mw'); - if (! $conn instanceof \Illuminate\Database\Connection) { + if (!$conn instanceof \Illuminate\Database\Connection) { $this->fail(new \RuntimeException('Must be run on a PDO based DB connection')); - return; //safegaurd + return; // safegaurd } $pdo = $conn->getPdo(); @@ -102,76 +98,76 @@ public function handle( DatabaseManager $manager ) // PDOException: SQLSTATE[HY000]: General error: 1396 Operation CREATE USER failed for 'mwu_0985131dfa'@'%' // So, catch this exception and check the error state ourselves, and allow us to continue past this? try { - $conn->statement("CREATE USER '".$this->dbUser."'@'%' IDENTIFIED BY '".$this->dbPassword."'"); + $conn->statement("CREATE USER '" . $this->dbUser . "'@'%' IDENTIFIED BY '" . $this->dbPassword . "'"); } catch (\Illuminate\Database\QueryException $e) { // Probably fine, and if not fine then the ALTER will fail below? :) - $conn->statement("ALTER USER '".$this->dbUser."'@'%' IDENTIFIED BY '".$this->dbPassword."'"); + $conn->statement("ALTER USER '" . $this->dbUser . "'@'%' IDENTIFIED BY '" . $this->dbPassword . "'"); } // CREATE (maybe) AND USE DB if ($this->dbName) { - if ($pdo->exec('CREATE DATABASE IF NOT EXISTS '.$this->dbName) === false) { + if ($pdo->exec('CREATE DATABASE IF NOT EXISTS ' . $this->dbName) === false) { $this->fail( - new \RuntimeException('Failed to create database with dbname: '.$this->dbName) + new \RuntimeException('Failed to create database with dbname: ' . $this->dbName) ); - return; //safegaurd + return; // safegaurd } } else { // Default to mediawiki $this->dbName = 'mediawiki'; } - if ($pdo->exec('USE '.$this->dbName) === false) { + if ($pdo->exec('USE ' . $this->dbName) === false) { $this->fail( - new \RuntimeException('Failed to use database with dbname: '.$this->dbName) + new \RuntimeException('Failed to use database with dbname: ' . $this->dbName) ); - return; //safegaurd + return; // safegaurd } // GRANT THE USER ACCESS TO THE DB // TODO more limited GRANTS... // TODO cant grant based on table prefix, so maybe do have seperate dbs...? - if ($pdo->exec('GRANT ALL ON '.$this->dbName.'.* TO \''.$this->dbUser.'\'@\'%\'') === false) { + if ($pdo->exec('GRANT ALL ON ' . $this->dbName . '.* TO \'' . $this->dbUser . '\'@\'%\'') === false) { $this->fail( - new \RuntimeException('Failed to grant user: '.$this->dbUser) + new \RuntimeException('Failed to grant user: ' . $this->dbUser) ); - return; //safegaurd + return; // safegaurd } // Figure out the SQL version - $stmt = $pdo->query("SELECT version() AS version"); + $stmt = $pdo->query('SELECT version() AS version'); $fullVersion = $stmt->fetch()['version']; // "10.5.12-MariaDB-log" preg_match('/^(\d+\.\d+\.\d+)(?!\d).*?$/', $fullVersion, $versionMatches); // [ 0 => '10.5.12-MariaDB-log', 1 => '10.5.12' ] $sqlVersion = $versionMatches[1]; // '10.5.12' - $aboveMariaDb1059 = version_compare($sqlVersion,'10.5.9'); // 1 = higher, 0 = same, -1 = lower - $aboveMariaDb1052 = version_compare($sqlVersion,'10.5.2'); // 1 = higher, 0 = same, -1 = lower + $aboveMariaDb1059 = version_compare($sqlVersion, '10.5.9'); // 1 = higher, 0 = same, -1 = lower + $aboveMariaDb1052 = version_compare($sqlVersion, '10.5.2'); // 1 = higher, 0 = same, -1 = lower - if($aboveMariaDb1052 >= 0 && $aboveMariaDb1059 == -1) { + if ($aboveMariaDb1052 >= 0 && $aboveMariaDb1059 == -1) { $this->fail( new \RuntimeException('Can not succeed on MariaDB versions between 10.5.2 and 10.5.9') ); } - if($aboveMariaDb1059 == -1) { + if ($aboveMariaDb1059 == -1) { // GRANT the user access to see slave status // GRANT REPLICATION CLIENT ON *.* TO 'mwu_36be7164b0'@'%' - if ($pdo->exec('GRANT REPLICATION CLIENT ON *.* TO \''.$this->dbUser.'\'@\'%\'') === false) { + if ($pdo->exec('GRANT REPLICATION CLIENT ON *.* TO \'' . $this->dbUser . '\'@\'%\'') === false) { $this->fail( - new \RuntimeException('Failed to grant user: '.$this->dbUser) + new \RuntimeException('Failed to grant user: ' . $this->dbUser) ); return; } } - if($aboveMariaDb1059 >= 0) { - // GRANT the user access to see slave status + if ($aboveMariaDb1059 >= 0) { + // GRANT the user access to see slave status // Mariadb versions > 10.5.9 https://mariadb.com/kb/en/grant/#replica-monitor // https://mariadb.com/docs/reference/mdb/privileges/BINLOG_MONITOR/ required to query "SHOW MASTER STATUS" // GRANT REPLICA MONITOR, BINLOG MONITOR ON *.* TO 'mwu_36be7164b0'@'%' - if ($pdo->exec('GRANT REPLICA MONITOR, BINLOG MONITOR ON *.* TO \''.$this->dbUser.'\'@\'%\'') === false) { + if ($pdo->exec('GRANT REPLICA MONITOR, BINLOG MONITOR ON *.* TO \'' . $this->dbUser . '\'@\'%\'') === false) { $this->fail( - new \RuntimeException('Failed to grant REPLICA MONITOR to user: '.$this->dbUser) + new \RuntimeException('Failed to grant REPLICA MONITOR to user: ' . $this->dbUser) ); return; @@ -180,7 +176,7 @@ public function handle( DatabaseManager $manager ) // ADD THE TABLES // Get SQL statements to run - $rawSql = file_get_contents(__DIR__.'/../../database/mw/new/'.$this->newSqlFile.'.sql'); + $rawSql = file_get_contents(__DIR__ . '/../../database/mw/new/' . $this->newSqlFile . '.sql'); $prefixedSql = str_replace('<>', $this->prefix, $rawSql); $sqlParts = explode("\n\n", $prefixedSql); @@ -193,10 +189,10 @@ public function handle( DatabaseManager $manager ) // Execute each chunk of SQL... if ($pdo->exec($part) === false) { $this->fail( - new \RuntimeException('SQL execution failed for prefix '.$this->prefix.' SQL part: '.$part) + new \RuntimeException('SQL execution failed for prefix ' . $this->prefix . ' SQL part: ' . $part) ); - return; //safegaurd + return; // safegaurd } } @@ -208,13 +204,13 @@ public function handle( DatabaseManager $manager ) // // This way, if this wikiDb create fails, there is still a record of the DB that has been / is being created? WikiDb::create([ - 'name' => $this->dbName, - 'user' => $this->dbUser, - 'password' => $this->dbPassword, - 'version' => $this->newSqlFile, - 'prefix' => $this->prefix, - ]); - - $manager->purge('mw'); + 'name' => $this->dbName, + 'user' => $this->dbUser, + 'password' => $this->dbPassword, + 'version' => $this->newSqlFile, + 'prefix' => $this->prefix, + ]); + + $manager->purge('mw'); } } diff --git a/app/Jobs/PruneEventPageUpdatesTable.php b/app/Jobs/PruneEventPageUpdatesTable.php index 73d5c2fcd..bb5116c64 100644 --- a/app/Jobs/PruneEventPageUpdatesTable.php +++ b/app/Jobs/PruneEventPageUpdatesTable.php @@ -5,10 +5,8 @@ use App\EventPageUpdate; use Illuminate\Support\Facades\DB; -class PruneEventPageUpdatesTable extends Job -{ - public function handle(): void - { +class PruneEventPageUpdatesTable extends Job { + public function handle(): void { // Assume that we only need the latest 100k page update events // and delete 500 if there are too many EventPageUpdate::where('id', '<', DB::table('event_page_updates')->max('id') - 100000) diff --git a/app/Jobs/PruneQueryserviceBatchesTable.php b/app/Jobs/PruneQueryserviceBatchesTable.php index e22267d21..dfbbabf48 100644 --- a/app/Jobs/PruneQueryserviceBatchesTable.php +++ b/app/Jobs/PruneQueryserviceBatchesTable.php @@ -5,10 +5,8 @@ use App\QsBatch; use Carbon\Carbon; -class PruneQueryserviceBatchesTable extends Job -{ - public function handle(): void - { +class PruneQueryserviceBatchesTable extends Job { + public function handle(): void { QsBatch::where([ ['done', '=', 1], ['pending_since', '=', null], diff --git a/app/Jobs/RequeuePendingQsBatchesJob.php b/app/Jobs/RequeuePendingQsBatchesJob.php index 5e837a530..1f063c122 100644 --- a/app/Jobs/RequeuePendingQsBatchesJob.php +++ b/app/Jobs/RequeuePendingQsBatchesJob.php @@ -2,37 +2,36 @@ namespace App\Jobs; -use Illuminate\Support\Facades\Config; -use Illuminate\Support\Facades\DB; use App\QsBatch; use Carbon\Carbon; +use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\DB; -class RequeuePendingQsBatchesJob extends Job -{ +class RequeuePendingQsBatchesJob extends Job { private $pendingTimeout; + private $markFailedAfter; + public function __construct() { $this->pendingTimeout = Config::get('wbstack.qs_batch_pending_timeout'); $this->markFailedAfter = Config::get('wbstack.qs_batch_mark_failed_after'); } - public function handle(): void - { + public function handle(): void { $failedBatches = $this->markBatchesFailed(); foreach ($failedBatches as $batchId) { - report("QsBatch with ID ".$batchId." was marked as failed."); + report('QsBatch with ID ' . $batchId . ' was marked as failed.'); } $this->requeueStalledBatches(); } - private function markBatchesFailed(): array - { + private function markBatchesFailed(): array { return DB::transaction(function () { $failedBatches = QsBatch::where([ ['processing_attempts', '>=', $this->markFailedAfter], ['failed', '=', false], - ['done', '=', false] + ['done', '=', false], ]) ->select('id') ->lockForUpdate() @@ -43,12 +42,12 @@ private function markBatchesFailed(): array 'failed' => true, 'pending_since' => null, ]); + return $failedBatches; }, 3); } - private function requeueStalledBatches(): void - { + private function requeueStalledBatches(): void { $threshold = Carbon::now()->subtract(new \DateInterval($this->pendingTimeout)); QsBatch::where([ ['pending_since', '<>', null], diff --git a/app/Jobs/SandboxCleanupJob.php b/app/Jobs/SandboxCleanupJob.php index c1cd565cc..d45b7e9b0 100644 --- a/app/Jobs/SandboxCleanupJob.php +++ b/app/Jobs/SandboxCleanupJob.php @@ -5,10 +5,8 @@ use App\Wiki; use App\WikiSetting; -class SandboxCleanupJob extends Job -{ - public function handle(): void - { +class SandboxCleanupJob extends Job { + public function handle(): void { Wiki::whereIn('id', WikiSetting::whereName('wwSandboxAutoUserLogin')->pluck('wiki_id')->toArray()) ->where('created_at', '<', date('Y-m-d', strtotime('-1 week')))->delete(); } diff --git a/app/Jobs/SendEmptyWikiNotificationsJob.php b/app/Jobs/SendEmptyWikiNotificationsJob.php index 312ee69a0..56bdaa4ad 100644 --- a/app/Jobs/SendEmptyWikiNotificationsJob.php +++ b/app/Jobs/SendEmptyWikiNotificationsJob.php @@ -9,10 +9,8 @@ use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Support\Facades\Log; -class SendEmptyWikiNotificationsJob extends Job implements ShouldBeUnique -{ - public function handle (): void - { +class SendEmptyWikiNotificationsJob extends Job implements ShouldBeUnique { + public function handle(): void { $wikis = Wiki::with(['wikiLifecycleEvents']) ->has('wikiLifecycleEvents') ->get(); @@ -24,15 +22,14 @@ public function handle (): void } } catch (\Exception $exception) { Log::error( - 'Failure processing wiki '.$wiki->getAttribute('domain').' for EmptyWikiNotification check: '.$exception->getMessage() + 'Failure processing wiki ' . $wiki->getAttribute('domain') . ' for EmptyWikiNotification check: ' . $exception->getMessage() ); $this->fail(); } } } - public function checkIfWikiIsOldAndEmpty(Wiki $wiki) - { + public function checkIfWikiIsOldAndEmpty(Wiki $wiki) { // Calculate how many days has passed since the wiki instance was first created $emptyDaysThreshold = config('wbstack.wiki_empty_notification_threshold'); $createdAt = $wiki->created_at; @@ -43,7 +40,7 @@ public function checkIfWikiIsOldAndEmpty(Wiki $wiki) $emptyWikiNotificationCount = WikiNotificationSentRecord::where([ 'wiki_id' => $wiki->id, - 'notification_type' => EmptyWikiNotification::TYPE + 'notification_type' => EmptyWikiNotification::TYPE, ])->count(); if ( @@ -57,18 +54,17 @@ public function checkIfWikiIsOldAndEmpty(Wiki $wiki) } } - public function sendEmptyWikiNotification (Wiki $wiki): void - { + public function sendEmptyWikiNotification(Wiki $wiki): void { $wikiManagers = $wiki->wikiManagersWithEmail()->get(); - foreach($wikiManagers as $wikiManager) { + foreach ($wikiManagers as $wikiManager) { // we think the order here matters, so that people do not get spammed in case creating a record fails // discussed here https://github.com/wbstack/api/pull/656#discussion_r1392443739 $wiki->wikiNotificationSentRecords()->create([ 'notification_type' => EmptyWikiNotification::TYPE, 'user_id' => $wikiManager->pivot->user_id, ]); - $wikiManager->notify(new EmptyWikiNotification($wiki->sitename)); + $wikiManager->notify(new EmptyWikiNotification($wiki->sitename)); } } } diff --git a/app/Jobs/SetWikiLogo.php b/app/Jobs/SetWikiLogo.php index cb9816964..2aa4b0295 100644 --- a/app/Jobs/SetWikiLogo.php +++ b/app/Jobs/SetWikiLogo.php @@ -5,10 +5,10 @@ use App\Wiki; use App\WikiSetting; use Illuminate\Database\QueryException; +use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Http\File; -use Intervention\Image\Facades\Image; use Illuminate\Support\Facades\Storage; -use Illuminate\Filesystem\FilesystemAdapter; +use Intervention\Image\Facades\Image; /** * This can be run with the artisan job command, for example: @@ -17,39 +17,41 @@ * * NOTE: This job needs to be run as the correct user if run via artisan (instead of via the UI) */ -class SetWikiLogo extends Job -{ +class SetWikiLogo extends Job { private $wikiKey; + private $wikiValue; + private $logoPath; - public function __construct(string $wikiKey, string $wikiValue, string $logoPath) - { + public function __construct(string $wikiKey, string $wikiValue, string $logoPath) { $this->wikiKey = $wikiKey; $this->wikiValue = $wikiValue; $this->logoPath = $logoPath; } - public function handle(): void - { + public function handle(): void { if (!file_exists($this->logoPath)) { $this->fail(new \InvalidArgumentException("Logo not found at '{$this->logoPath}'")); - return; //safeguard + + return; // safeguard } try { $wikis = Wiki::where($this->wikiKey, $this->wikiValue); if ($wikis->count() === 0) { $this->fail(new \InvalidArgumentException("Wiki not found for key={$this->wikiKey} and value={$this->wikiValue}")); - return; //safeguard - } - elseif ($wikis->count() > 1) { + + return; // safeguard + } elseif ($wikis->count() > 1) { $this->fail(new \InvalidArgumentException("Multiple Wikis matched for key={$this->wikiKey} and value={$this->wikiValue}")); - return; //safeguard + + return; // safeguard } - } catch(QueryException $e) { + } catch (QueryException $e) { $this->fail(new \InvalidArgumentException("Invalid key ({$this->wikiKey}) or value ({$this->wikiValue})")); - return; //safeguard + + return; // safeguard } $wiki = $wikis->first(); @@ -57,16 +59,17 @@ public function handle(): void // Get the cloud disk we use to store logos $storage = Storage::disk('static-assets'); if (!$storage instanceof FilesystemAdapter) { - # TODO: Use a more specific exception? - $this->fail(new \RuntimeException("Invalid storage (not cloud)")); - return; //safeguard + // TODO: Use a more specific exception? + $this->fail(new \RuntimeException('Invalid storage (not cloud)')); + + return; // safeguard } // Get the directory for storing this site's logos $logosDir = Wiki::getLogosDirectory($wiki->id); // Upload the local image to the cloud storage - $storage->putFileAs($logosDir, new File($this->logoPath), "raw.png", ['visibility' => 'public']); + $storage->putFileAs($logosDir, new File($this->logoPath), 'raw.png', ['visibility' => 'public']); // Store a conversion for the actual site logo $reducedPath = $logosDir . '/135.png'; diff --git a/app/Jobs/SiteStatsUpdateJob.php b/app/Jobs/SiteStatsUpdateJob.php index 537e8bf15..118e35d32 100644 --- a/app/Jobs/SiteStatsUpdateJob.php +++ b/app/Jobs/SiteStatsUpdateJob.php @@ -2,11 +2,10 @@ namespace App\Jobs; -use App\Wiki; -use Illuminate\Support\Facades\Log; use App\Http\Curl\HttpRequest; +use App\Wiki; use Illuminate\Bus\Batchable; - +use Illuminate\Support\Facades\Log; /* * @@ -14,29 +13,27 @@ * * Example: php artisan job:dispatch SiteStatsUpdateJob */ -class SiteStatsUpdateJob extends Job -{ +class SiteStatsUpdateJob extends Job { use Batchable; private $wiki_id; - public function __construct( $wiki_id ) { + public function __construct($wiki_id) { $this->wiki_id = $wiki_id; } - public function handle( HttpRequest $request ): void - { + public function handle(HttpRequest $request): void { $timeStart = microtime(true); $wiki = Wiki::where('id', $this->wiki_id)->first(); - if( !$wiki ) { - $this->fail( new \RuntimeException(" Could not find wiki with id: $this->wiki_id" ) ); + if (!$wiki) { + $this->fail(new \RuntimeException(" Could not find wiki with id: $this->wiki_id")); } Log::info(__METHOD__ . ": Updating stats for or $wiki->domain"); $request->setOptions([ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackSiteStatsUpdate&format=json', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackSiteStatsUpdate&format=json', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 60 * 5, @@ -44,7 +41,7 @@ public function handle( HttpRequest $request ): void CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$wiki->domain, + 'host: ' . $wiki->domain, ], ]); @@ -55,28 +52,28 @@ public function handle( HttpRequest $request ): void if ($err) { Log::error(__METHOD__ . ": wbstackSiteStatsUpdate failed: $rawResponse"); $this->fail( - new \RuntimeException('curl error for '.$wiki->domain.': '.$err) + new \RuntimeException('curl error for ' . $wiki->domain . ': ' . $err) ); - return; //safegaurd + return; // safegaurd } $response = json_decode($rawResponse, true); - if ( !is_array($response) || !array_key_exists('wbstackSiteStatsUpdate', $response) ) { + if (!is_array($response) || !array_key_exists('wbstackSiteStatsUpdate', $response)) { $this->fail( - new \RuntimeException('wbstackSiteStatsUpdate call for '.$wiki->domain.'. No wbstackSiteStatsUpdate key in response: '.$rawResponse) + new \RuntimeException('wbstackSiteStatsUpdate call for ' . $wiki->domain . '. No wbstackSiteStatsUpdate key in response: ' . $rawResponse) ); - return; //safegaurd + return; // safegaurd } if ($response['wbstackSiteStatsUpdate']['return'] !== 0) { $this->fail( - new \RuntimeException('wbstackSiteStatsUpdate call for '.$wiki->domain.' was not successful: '.$rawResponse) + new \RuntimeException('wbstackSiteStatsUpdate call for ' . $wiki->domain . ' was not successful: ' . $rawResponse) ); - return; //safegaurd + return; // safegaurd } $timeEnd = microtime(true); @@ -84,6 +81,5 @@ public function handle( HttpRequest $request ): void Log::info(__METHOD__ . ": Finished in: $executionTime s"); - } } diff --git a/app/Jobs/SpawnQueryserviceUpdaterJob.php b/app/Jobs/SpawnQueryserviceUpdaterJob.php index 2e2bf2e2a..d71f28a50 100644 --- a/app/Jobs/SpawnQueryserviceUpdaterJob.php +++ b/app/Jobs/SpawnQueryserviceUpdaterJob.php @@ -3,25 +3,26 @@ namespace App\Jobs; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldBeUnique; +use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Log; use Maclof\Kubernetes\Client; use Maclof\Kubernetes\Models\Job as KubernetesJob; -class SpawnQueryserviceUpdaterJob implements ShouldQueue, ShouldBeUnique -{ +class SpawnQueryserviceUpdaterJob implements ShouldBeUnique, ShouldQueue { use InteractsWithQueue, Queueable; public string $wikiDomain; + public string $entities; + public string $sparqlUrl; + public string $qsKubernetesNamespace; - public function __construct (string $wikiDomain, string $entities, string $sparqlUrl) - { + public function __construct(string $wikiDomain, string $entities, string $sparqlUrl) { $sortedEntities = explode(',', $entities); asort($sortedEntities); @@ -31,16 +32,14 @@ public function __construct (string $wikiDomain, string $entities, string $sparq $this->qsKubernetesNamespace = Config::get('wbstack.qs_job_namespace'); } - public function uniqueId(): string - { - return $this->wikiDomain.$this->entities; + public function uniqueId(): string { + return $this->wikiDomain . $this->entities; } - public function handle (Client $kubernetesClient): void - { + public function handle(Client $kubernetesClient): void { $kubernetesClient->setNamespace('default'); $qsUpdaterPod = $kubernetesClient->pods()->setFieldSelector([ - 'status.phase' => 'Running' + 'status.phase' => 'Running', ])->setLabelSelector([ 'app.kubernetes.io/name' => 'queryservice-updater', ])->first(); @@ -48,10 +47,11 @@ public function handle (Client $kubernetesClient): void if ($qsUpdaterPod === null) { $this->fail( new \RuntimeException( - 'Unable to find a running queryservice-updater pod in the cluster, '. + 'Unable to find a running queryservice-updater pod in the cluster, ' . 'cannot continue.' ) ); + return; } $qsUpdaterPod = $qsUpdaterPod->toArray(); @@ -59,18 +59,18 @@ public function handle (Client $kubernetesClient): void $kubernetesClient->setNamespace($this->qsKubernetesNamespace); $jobSpec = new KubernetesJob([ 'metadata' => [ - 'name' => 'run-qs-updater-'.hash('sha1', $this->uniqueId()), + 'name' => 'run-qs-updater-' . hash('sha1', $this->uniqueId()), 'namespace' => $this->qsKubernetesNamespace, 'labels' => [ 'app.kubernetes.io/instance' => $this->wikiDomain, 'app.kubernetes.io/name' => 'run-qs-updater', - ] + ], ], 'spec' => [ 'ttlSecondsAfterFinished' => 14 * 24 * 60 * 60, // 2 weeks 'template' => [ 'metadata' => [ - 'name' => 'run-qs-updater' + 'name' => 'run-qs-updater', ], 'spec' => [ 'containers' => [ @@ -91,12 +91,12 @@ public function handle (Client $kubernetesClient): void --conceptUri https://{$this->wikiDomain} CMD ], - ] + ], ], - 'restartPolicy' => 'Never' - ] - ] - ] + 'restartPolicy' => 'Never', + ], + ], + ], ]); $job = $kubernetesClient->jobs()->apply($jobSpec); @@ -105,15 +105,14 @@ public function handle (Client $kubernetesClient): void // The k8s client does not fail reliably on 4xx responses, so checking the name // currently serves as poor man's error handling. $this->fail( - new \RuntimeException('Queryservice Updater creation for wiki "'.$this->wikiDomain.'" failed with message: '.data_get($job, 'message', 'n/a')) + new \RuntimeException('Queryservice Updater creation for wiki "' . $this->wikiDomain . '" failed with message: ' . data_get($job, 'message', 'n/a')) ); + return; } Log::info( - 'Queryservice Updater for wiki "'.$this->wikiDomain.'" and entities "'.$this->entities.'" exists or was created with name "'.$jobName.'".' + 'Queryservice Updater for wiki "' . $this->wikiDomain . '" and entities "' . $this->entities . '" exists or was created with name "' . $jobName . '".' ); - return; } - } diff --git a/app/Jobs/UpdateQueryserviceAllowList.php b/app/Jobs/UpdateQueryserviceAllowList.php index 961eceecc..c5f47d48c 100644 --- a/app/Jobs/UpdateQueryserviceAllowList.php +++ b/app/Jobs/UpdateQueryserviceAllowList.php @@ -6,14 +6,12 @@ use Maclof\Kubernetes\Client; use Maclof\Kubernetes\Models\ConfigMap; -class UpdateQueryserviceAllowList extends Job -{ - public function handle(Client $k8s) - { +class UpdateQueryserviceAllowList extends Job { + public function handle(Client $k8s) { $allowList = implode( PHP_EOL, array_map( - fn($domain) => "https://{$domain}/query/sparql", + fn ($domain) => "https://{$domain}/query/sparql", Wiki::all()->pluck('domain')->toArray() ) ); @@ -21,7 +19,7 @@ public function handle(Client $k8s) $k8s->setNamespace('default'); $configName = 'queryservice-allowlist'; $config = $k8s->configMaps()->setFieldSelector([ - 'metadata.name' => $configName + 'metadata.name' => $configName, ])->first(); if ($config === null) { @@ -30,6 +28,7 @@ public function handle(Client $k8s) "Queryservice config map '{$configName}' does not exist." ) ); + return; } diff --git a/app/Jobs/UpdateWikiDailyMetricJob.php b/app/Jobs/UpdateWikiDailyMetricJob.php index fe8b8c5b5..2d1460b78 100755 --- a/app/Jobs/UpdateWikiDailyMetricJob.php +++ b/app/Jobs/UpdateWikiDailyMetricJob.php @@ -2,27 +2,25 @@ namespace App\Jobs; +use App\Metrics\App\WikiMetrics; use App\Wiki; -use \App\Metrics\App\WikiMetrics; use Illuminate\Contracts\Queue\ShouldBeUnique; -use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; -//This job is for the daily measurements of metrics per wikibases. -//This is to help in understanding the purpose of active wikis. -class UpdateWikiDailyMetricJob extends Job implements ShouldBeUnique -{ +// This job is for the daily measurements of metrics per wikibases. +// This is to help in understanding the purpose of active wikis. +class UpdateWikiDailyMetricJob extends Job implements ShouldBeUnique { use Dispatchable; + public $timeout = 3600; /** * Execute the job. */ - public function handle(): void - { - $wikis= Wiki::withTrashed()->get(); - foreach ( $wikis as $wiki ) { - (new WikiMetrics())->saveMetrics($wiki); + public function handle(): void { + $wikis = Wiki::withTrashed()->get(); + foreach ($wikis as $wiki) { + (new WikiMetrics)->saveMetrics($wiki); } } } diff --git a/app/Jobs/UpdateWikiSiteStatsJob.php b/app/Jobs/UpdateWikiSiteStatsJob.php index 1ea77c24c..04e5368b1 100644 --- a/app/Jobs/UpdateWikiSiteStatsJob.php +++ b/app/Jobs/UpdateWikiSiteStatsJob.php @@ -4,21 +4,20 @@ use App\Wiki; use App\WikiSiteStats; +use Carbon\Carbon; use Carbon\CarbonInterface; +use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\DB; -use Illuminate\Http\Client\Pool; -use Illuminate\Contracts\Queue\ShouldBeUnique; -use Carbon\Carbon; -class UpdateWikiSiteStatsJob extends Job implements ShouldBeUnique -{ +class UpdateWikiSiteStatsJob extends Job implements ShouldBeUnique { use Dispatchable; + public $timeout = 3600; - public function handle (): void - { + + public function handle(): void { $allWikis = Wiki::all(); foreach ($allWikis as $wiki) { try { @@ -27,13 +26,13 @@ public function handle (): void } catch (\Exception $ex) { $this->job->markAsFailed(); Log::error( - 'Failure polling wiki '.$wiki->getAttribute('domain').' for sitestats: '.$ex->getMessage() + 'Failure polling wiki ' . $wiki->getAttribute('domain') . ' for sitestats: ' . $ex->getMessage() ); } } } - private function updateLifecycleEvents (Wiki $wiki): void { + private function updateLifecycleEvents(Wiki $wiki): void { $update = []; $firstEdited = $this->getFirstEditedDate($wiki); @@ -51,22 +50,21 @@ private function updateLifecycleEvents (Wiki $wiki): void { }); } - private function updateSiteStats (Wiki $wiki): void - { + private function updateSiteStats(Wiki $wiki): void { $response = Http::withHeaders([ - 'host' => $wiki->getAttribute('domain') + 'host' => $wiki->getAttribute('domain'), ])->get( - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' ); if ($response->failed()) { - throw new \Exception('Request failed with reason '.$response->body()); + throw new \Exception('Request failed with reason ' . $response->body()); } $responseBody = $response->json(); $update = []; foreach (WikiSiteStats::FIELDS as $field) { - $value = data_get($responseBody, 'query.statistics.'.$field, null); + $value = data_get($responseBody, 'query.statistics.' . $field, null); if ($value !== null) { $update[$field] = $value; } @@ -76,10 +74,9 @@ private function updateSiteStats (Wiki $wiki): void }); } - private function getFirstEditedDate (Wiki $wiki): ?CarbonInterface - { + private function getFirstEditedDate(Wiki $wiki): ?CarbonInterface { $allRevisions = Http::withHeaders(['host' => $wiki->getAttribute('domain')])->get( - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php', + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php', [ 'action' => 'query', 'format' => 'json', @@ -97,7 +94,7 @@ private function getFirstEditedDate (Wiki $wiki): ?CarbonInterface } $revisionInfo = Http::withHeaders(['host' => $wiki->getAttribute('domain')])->get( - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php', + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php', [ 'action' => 'query', 'format' => 'json', @@ -111,13 +108,13 @@ private function getFirstEditedDate (Wiki $wiki): ?CarbonInterface if (!$result) { return null; } + return Carbon::parse($result); } - private function getLastEditedDate (Wiki $wiki): ?CarbonInterface - { + private function getLastEditedDate(Wiki $wiki): ?CarbonInterface { $allRevisions = Http::withHeaders(['host' => $wiki->getAttribute('domain')])->get( - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php', + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php', [ 'action' => 'query', 'format' => 'json', @@ -135,7 +132,7 @@ private function getLastEditedDate (Wiki $wiki): ?CarbonInterface } $revisionInfo = Http::withHeaders(['host' => $wiki->getAttribute('domain')])->get( - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php', + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php', [ 'action' => 'query', 'format' => 'json', @@ -149,6 +146,7 @@ private function getLastEditedDate (Wiki $wiki): ?CarbonInterface if (!$result) { return null; } + return Carbon::parse($result); } } diff --git a/app/Jobs/UserCreateJob.php b/app/Jobs/UserCreateJob.php index a43abb98f..e2a54f51a 100644 --- a/app/Jobs/UserCreateJob.php +++ b/app/Jobs/UserCreateJob.php @@ -5,16 +5,14 @@ use App\User; use Illuminate\Support\Facades\Hash; -class UserCreateJob extends Job -{ +class UserCreateJob extends Job { private $email; private $password; private $verified; - public function __construct($email, $password, $verified = false) - { + public function __construct($email, $password, $verified = false) { // TODO maybe pass in an unsaved eloquent model? // // but that would make CLI job creation hard $this->email = $email; @@ -25,13 +23,12 @@ public function __construct($email, $password, $verified = false) /** * @return User */ - public function handle() - { + public function handle() { $user = User::create([ - 'email' => $this->email, - 'password' => Hash::make($this->password), - 'verified' => $this->verified, - ]); + 'email' => $this->email, + 'password' => Hash::make($this->password), + 'verified' => $this->verified, + ]); return $user; } diff --git a/app/Jobs/UserVerificationCreateTokenAndSendJob.php b/app/Jobs/UserVerificationCreateTokenAndSendJob.php index 6f46c4dd6..8b3505229 100644 --- a/app/Jobs/UserVerificationCreateTokenAndSendJob.php +++ b/app/Jobs/UserVerificationCreateTokenAndSendJob.php @@ -7,8 +7,7 @@ use App\User; use App\UserVerificationToken; -class UserVerificationCreateTokenAndSendJob extends Job -{ +class UserVerificationCreateTokenAndSendJob extends Job { /** * @var User */ @@ -19,24 +18,21 @@ class UserVerificationCreateTokenAndSendJob extends Job */ private $notificationClass; - public static function newForAccountCreation(User $user): self - { + public static function newForAccountCreation(User $user): self { return new self($user, UserCreationNotification::class); } - public static function newForReverification(User $user): self - { + public static function newForReverification(User $user): self { return new self($user, EmailReverificationNotification::class); } /** * @return void */ - public function __construct(User $user, string $notificationClass) - { + public function __construct(User $user, string $notificationClass) { $this->user = $user; $this->notificationClass = $notificationClass; - if (! class_exists($notificationClass)) { + if (!class_exists($notificationClass)) { throw new \InvalidArgumentException("$notificationClass not found for notification"); } } @@ -44,8 +40,7 @@ public function __construct(User $user, string $notificationClass) /** * @return void */ - public function handle() - { + public function handle() { $emailToken = bin2hex(random_bytes(24)); UserVerificationToken::create([ 'user_id' => $this->user->id, diff --git a/app/Jobs/WikiEntityImportJob.php b/app/Jobs/WikiEntityImportJob.php index 5322d3927..6b0af4736 100644 --- a/app/Jobs/WikiEntityImportJob.php +++ b/app/Jobs/WikiEntityImportJob.php @@ -2,23 +2,22 @@ namespace App\Jobs; +use App\Wiki; +use App\WikiEntityImport; use App\WikiEntityImportStatus; +use Carbon\Carbon; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Config; -use App\Wiki; -use App\WikiEntityImport; -use Carbon\Carbon; use Maclof\Kubernetes\Client; use Maclof\Kubernetes\Models\Job as KubernetesJob; -class WikiEntityImportJob implements ShouldQueue -{ +class WikiEntityImportJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** @@ -29,16 +28,14 @@ public function __construct( public string $sourceWikiUrl, public array $entityIds, public int $importId, - ) - {} + ) {} private string $targetWikiUrl; /** * Execute the job. */ - public function handle(Client $kubernetesClient): void - { + public function handle(Client $kubernetesClient): void { $import = null; try { $wiki = Wiki::findOrFail($this->wikiId); @@ -58,32 +55,31 @@ public function handle(Client $kubernetesClient): void ); $jobName = $kubernetesJob->spawn(); Log::info( - 'transferbot job for wiki "'.$wiki->domain.'" was created with name "'.$jobName.'".' + 'transferbot job for wiki "' . $wiki->domain . '" was created with name "' . $jobName . '".' ); } catch (\Exception $ex) { - Log::error('Entity import job failed with error: '.$ex->getMessage()); + Log::error('Entity import job failed with error: ' . $ex->getMessage()); $import?->update([ 'status' => WikiEntityImportStatus::Failed, 'finished_at' => Carbon::now(), ]); $this->fail( - new \Exception('Error spawning transferbot for wiki '.$this->wikiId.': '.$ex->getMessage()), + new \Exception('Error spawning transferbot for wiki ' . $this->wikiId . ': ' . $ex->getMessage()), ); } } - private static function domainToOrigin(string $domain): string - { + private static function domainToOrigin(string $domain): string { $tld = last(explode('.', $domain)); + return $tld === 'localhost' - ? "http://".$domain - : "https://".$domain; + ? 'http://' . $domain + : 'https://' . $domain; } - private static function acquireCredentials(string $wikiDomain): OAuthCredentials - { + private static function acquireCredentials(string $wikiDomain): OAuthCredentials { $response = Http::withHeaders(['host' => $wikiDomain])->asForm()->post( - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackPlatformOauthGet&format=json', + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackPlatformOauthGet&format=json', [ 'consumerName' => 'WikiEntityImportJob', 'ownerOnly' => '1', @@ -94,20 +90,19 @@ private static function acquireCredentials(string $wikiDomain): OAuthCredentials ); if ($response->status() > 399) { - throw new \Exception('Unexpected status code '.$response->status().' from Mediawiki'); + throw new \Exception('Unexpected status code ' . $response->status() . ' from Mediawiki'); } $body = $response->json(); if (!$body || $body['wbstackPlatformOauthGet']['success'] !== '1') { - throw new \ErrorException('Unexpected error acquiring oauth credentials for wiki '.$wikiDomain); + throw new \ErrorException('Unexpected error acquiring oauth credentials for wiki ' . $wikiDomain); } return OAuthCredentials::unmarshalMediaWikiResponse($body); } } -class TransferBotKubernetesJob -{ +class TransferBotKubernetesJob { public function __construct( public Client $kubernetesClient, public Wiki $wiki, @@ -116,18 +111,19 @@ public function __construct( public string $sourceWikiUrl, public string $targetWikiUrl, public int $importId, - ){ + ) { $this->kubernetesNamespace = Config::get('wbstack.api_job_namespace'); $this->transferbotImageRepo = Config::get('wbstack.transferbot_image_repo'); $this->transferbotImageVersion = Config::get('wbstack.transferbot_image_version'); } private string $kubernetesNamespace; + private string $transferbotImageRepo; + private string $transferbotImageVersion; - public function spawn(): string - { + public function spawn(): string { $spec = $this->constructSpec(); $jobSpec = new KubernetesJob($spec); @@ -138,14 +134,14 @@ public function spawn(): string // The k8s client does not fail reliably on 4xx responses, so checking the name // currently serves as poor man's error handling. throw new \RuntimeException( - 'transferbot creation for wiki "'.$this->wiki->domain.'" failed with message: '.data_get($jobObject, 'message', 'n/a') + 'transferbot creation for wiki "' . $this->wiki->domain . '" failed with message: ' . data_get($jobObject, 'message', 'n/a') ); } + return $jobName; } - private function constructSpec(): array - { + private function constructSpec(): array { return [ 'metadata' => [ 'generateName' => 'run-transferbot-', @@ -153,30 +149,30 @@ private function constructSpec(): array 'labels' => [ 'app.kubernetes.io/instance' => $this->wiki->domain, 'app.kubernetes.io/name' => 'run-transferbot', - ] + ], ], 'spec' => [ 'ttlSecondsAfterFinished' => 0, 'backoffLimit' => 0, 'template' => [ 'metadata' => [ - 'name' => 'run-entity-import' + 'name' => 'run-entity-import', ], 'spec' => [ 'containers' => [ 0 => [ 'hostNetwork' => true, 'name' => 'run-entity-import', - 'image' => $this->transferbotImageRepo.':'.$this->transferbotImageVersion, + 'image' => $this->transferbotImageRepo . ':' . $this->transferbotImageVersion, 'env' => [ ...$this->creds->marshalEnv(), [ 'name' => 'CALLBACK_ON_FAILURE', - 'value' => 'curl -sS -H "Accept: application/json" -H "Content-Type: application/json" --data \'{"wiki_entity_import":'.$this->importId.',"status":"failed"}\' -XPATCH http://api-app-backend.default.svc.cluster.local/backend/wiki/updateEntityImport' + 'value' => 'curl -sS -H "Accept: application/json" -H "Content-Type: application/json" --data \'{"wiki_entity_import":' . $this->importId . ',"status":"failed"}\' -XPATCH http://api-app-backend.default.svc.cluster.local/backend/wiki/updateEntityImport', ], [ 'name' => 'CALLBACK_ON_SUCCESS', - 'value' => 'curl -sS -H "Accept: application/json" -H "Content-Type: application/json" --data \'{"wiki_entity_import":'.$this->importId.',"status":"success"}\' -XPATCH http://api-app-backend.default.svc.cluster.local/backend/wiki/updateEntityImport' + 'value' => 'curl -sS -H "Accept: application/json" -H "Content-Type: application/json" --data \'{"wiki_entity_import":' . $this->importId . ',"status":"success"}\' -XPATCH http://api-app-backend.default.svc.cluster.local/backend/wiki/updateEntityImport', ], ], 'command' => [ @@ -195,29 +191,27 @@ private function constructSpec(): array 'memory' => '500Mi', ], ], - ] + ], ], - 'restartPolicy' => 'Never' - ] - ] - ] + 'restartPolicy' => 'Never', + ], + ], + ], ]; } } -class OAuthCredentials -{ +class OAuthCredentials { public function __construct( public string $consumerToken, public string $consumerSecret, public string $accessToken, public string $accessSecret, - ) - {} + ) {} - public static function unmarshalMediaWikiResponse(array $response): OAuthCredentials - { + public static function unmarshalMediaWikiResponse(array $response): OAuthCredentials { $data = $response['wbstackPlatformOauthGet']['data']; + return new OAuthCredentials( consumerToken: $data['consumerKey'], consumerSecret: $data['consumerSecret'], @@ -226,23 +220,22 @@ public static function unmarshalMediaWikiResponse(array $response): OAuthCredent ); } - public function marshalEnv(string $prefix = 'TARGET_WIKI_OAUTH'): array - { + public function marshalEnv(string $prefix = 'TARGET_WIKI_OAUTH'): array { return [ [ - 'name' => $prefix.'_CONSUMER_TOKEN', + 'name' => $prefix . '_CONSUMER_TOKEN', 'value' => $this->consumerToken, ], [ - 'name' => $prefix.'_CONSUMER_SECRET', + 'name' => $prefix . '_CONSUMER_SECRET', 'value' => $this->consumerSecret, ], [ - 'name' => $prefix.'_ACCESS_TOKEN', + 'name' => $prefix . '_ACCESS_TOKEN', 'value' => $this->accessToken, ], [ - 'name' => $prefix.'_ACCESS_SECRET', + 'name' => $prefix . '_ACCESS_SECRET', 'value' => $this->accessSecret, ], ]; diff --git a/app/Metrics/App/WikiMetrics.php b/app/Metrics/App/WikiMetrics.php index 5609782a4..af3564fdb 100644 --- a/app/Metrics/App/WikiMetrics.php +++ b/app/Metrics/App/WikiMetrics.php @@ -9,24 +9,25 @@ use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; -class WikiMetrics -{ +class WikiMetrics { const INTERVAL_DAILY = 'INTERVAL 1 DAY'; + const INTERVAL_WEEKLY = ' INTERVAL 1 WEEK'; + const INTERVAL_MONTHLY = 'INTERVAL 1 MONTH'; + const INTERVAL_QUARTERLY = 'INTERVAL 3 MONTH'; protected $wiki; - public function saveMetrics(Wiki $wiki): void - { + public function saveMetrics(Wiki $wiki): void { $this->wiki = $wiki; $today = now()->format('Y-m-d'); $oldRecord = WikiDailyMetrics::where('wiki_id', $wiki->id)->latest('date')->first(); $tripleCount = $this->getNumOfTriples(); $todayPageCount = $wiki->wikiSiteStats()->first()->pages ?? 0; - $isDeleted = (bool)$wiki->deleted_at; + $isDeleted = (bool) $wiki->deleted_at; $dailyActions = $this->getNumberOfActions(self::INTERVAL_DAILY); $weeklyActions = $this->getNumberOfActions(self::INTERVAL_WEEKLY); @@ -54,11 +55,13 @@ public function saveMetrics(Wiki $wiki): void if ($oldRecord) { if ($oldRecord->is_deleted) { Log::info("Wiki is deleted, no new record for Wiki ID {$wiki->id}."); + return; } if (!$isDeleted) { if ($oldRecord->areMetricsEqual($dailyMetrics)) { Log::info("Record unchanged for Wiki ID {$wiki->id}, no new record added."); + return; } } @@ -68,44 +71,48 @@ public function saveMetrics(Wiki $wiki): void Log::info("New metric recorded for Wiki ID {$wiki->id}"); } - protected function getNumOfTriples(): ?int - { + + protected function getNumOfTriples(): ?int { $qsNamespace = QueryserviceNamespace::whereWikiId($this->wiki->id)->first(); - if( !$qsNamespace ) { - Log::info( new \RuntimeException("Namespace for wiki {$this->wiki->id} not found.") ); + if (!$qsNamespace) { + Log::info(new \RuntimeException("Namespace for wiki {$this->wiki->id} not found.")); + return null; } - $endpoint = $qsNamespace->backend . '/bigdata/namespace/' . $qsNamespace->namespace. '/sparql'; + $endpoint = $qsNamespace->backend . '/bigdata/namespace/' . $qsNamespace->namespace . '/sparql'; $query = 'SELECT (COUNT(*) AS ?triples) WHERE { ?s ?p ?o }'; $response = Http::withHeaders([ - 'Accept' => 'application/sparql-results+json' + 'Accept' => 'application/sparql-results+json', ])->get($endpoint, [ - 'query' => $query + 'query' => $query, ]); if ($response->successful()) { $data = $response->json(); + return $data['results']['bindings'][0]['triples']['value']; } + return null; } - protected function getNumberOfActions(string $interval): null|int - { + protected function getNumberOfActions(string $interval): ?int { $actions = null; // safeguard - if (false === in_array($interval, - [ + if (in_array($interval, + [ self::INTERVAL_DAILY, self::INTERVAL_WEEKLY, self::INTERVAL_MONTHLY, - self::INTERVAL_QUARTERLY - ] - )) { return null; } + self::INTERVAL_QUARTERLY, + ] + ) === false) { + return null; + } $wikiDb = $this->wiki->wikiDb; $tableRecentChanges = $wikiDb->name . '.' . $wikiDb->prefix . '_recentchanges'; @@ -135,8 +142,7 @@ protected function getNumberOfActions(string $interval): null|int return $actions; } - private function getNumberOfUsersPerActivityType() : array - { + private function getNumberOfUsersPerActivityType(): array { $wikiDb = $this->wiki->wikiDb; $tableRecentChanges = $wikiDb->name . '.' . $wikiDb->prefix . '_recentchanges'; $tableActor = $wikiDb->name . '.' . $wikiDb->prefix . '_actor'; @@ -168,7 +174,7 @@ private function getNumberOfUsersPerActivityType() : array return [ Arr::get($result, 'monthly_casual_users', null), - Arr::get($result, 'monthly_active_users',null) + Arr::get($result, 'monthly_active_users', null), ]; } } diff --git a/app/Metrics/FailedQsBatches.php b/app/Metrics/FailedQsBatches.php index fa5f11e8c..f65f2149c 100644 --- a/app/Metrics/FailedQsBatches.php +++ b/app/Metrics/FailedQsBatches.php @@ -1,18 +1,15 @@ gauge = $collectorRegistry->getOrRegisterGauge( config('horizon-exporter.namespace'), 'qs_batches_failed_batches', @@ -20,8 +17,7 @@ public function metrics(CollectorRegistry $collectorRegistry) ); } - public function collect() - { + public function collect() { $numBatches = QsBatch::has('wiki')->where([ 'failed' => 1, ])->count(); diff --git a/app/Metrics/PendingQsBatches.php b/app/Metrics/PendingQsBatches.php index 42fa0bd01..584ab32d8 100644 --- a/app/Metrics/PendingQsBatches.php +++ b/app/Metrics/PendingQsBatches.php @@ -1,18 +1,15 @@ gauge = $collectorRegistry->getOrRegisterGauge( config('horizon-exporter.namespace'), 'qs_batches_pending_batches', @@ -20,8 +17,7 @@ public function metrics(CollectorRegistry $collectorRegistry) ); } - public function collect() - { + public function collect() { $numBatches = QsBatch::has('wiki')->where([ 'done' => 0, 'failed' => 0, diff --git a/app/Metrics/WikiEntityImports.php b/app/Metrics/WikiEntityImports.php index 60a60aa35..70d756e52 100644 --- a/app/Metrics/WikiEntityImports.php +++ b/app/Metrics/WikiEntityImports.php @@ -1,18 +1,16 @@ pending = $collectorRegistry->getOrRegisterGauge( config('horizon-exporter.namespace'), 'wiki_entity_imports_pending', @@ -20,9 +18,7 @@ public function metrics(CollectorRegistry $collectorRegistry) ); } - - public function collect() - { + public function collect() { // counters for failed / success are incremented in the HTTP controller $this->pending->set( WikiEntityImport::where(['status' => WikiEntityImportStatus::Pending])->count() diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php index 98ff38141..17bce6c01 100644 --- a/app/Notifications/ComplaintNotification.php +++ b/app/Notifications/ComplaintNotification.php @@ -10,11 +10,13 @@ /** * A notification to be sent when the legal complaint form is being used. */ -class ComplaintNotification extends Notification -{ +class ComplaintNotification extends Notification { public $offendingUrls; + public $reason; + public $name; + public $mailAddress; /** @@ -26,8 +28,7 @@ class ComplaintNotification extends Notification * @param string $mailAddress * @return void */ - public function __construct($offendingUrls, $reason, $name=null, $mailAddress=null) - { + public function __construct($offendingUrls, $reason, $name = null, $mailAddress = null) { $this->offendingUrls = $offendingUrls; $this->reason = $reason; $this->name = $name; @@ -40,8 +41,7 @@ public function __construct($offendingUrls, $reason, $name=null, $mailAddress=nu * @param mixed $notifiable * @return array|string */ - public function via($notifiable) - { + public function via($notifiable) { return ['database', 'mail']; } @@ -51,8 +51,7 @@ public function via($notifiable) * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ - public function toMail($notifiable) - { + public function toMail($notifiable) { $name = $this->name; $mailAddress = $this->mailAddress; @@ -83,6 +82,6 @@ public function toMail($notifiable) public function toDatabase($notifiable) { $mail = $this->toMail($notifiable); - return (new DatabaseMessage($mail->toArray())); + return new DatabaseMessage($mail->toArray()); } } diff --git a/app/Notifications/ComplaintNotificationExternal.php b/app/Notifications/ComplaintNotificationExternal.php index fb01370df..b38609d7f 100644 --- a/app/Notifications/ComplaintNotificationExternal.php +++ b/app/Notifications/ComplaintNotificationExternal.php @@ -2,23 +2,20 @@ namespace App\Notifications; -use App\Notifications\ComplaintNotification; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Support\Facades\Lang; /** * A notification to be sent when the legal complaint form is being used. */ -class ComplaintNotificationExternal extends ComplaintNotification -{ +class ComplaintNotificationExternal extends ComplaintNotification { /** * Build the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ - public function toMail($notifiable) - { + public function toMail($notifiable) { $name = $this->name; if (empty($name)) { diff --git a/app/Notifications/ContactNotification.php b/app/Notifications/ContactNotification.php index d4a82175b..9a8d2e7fd 100644 --- a/app/Notifications/ContactNotification.php +++ b/app/Notifications/ContactNotification.php @@ -9,11 +9,13 @@ /** * A notification to be sent when the contact form is being used. */ -class ContactNotification extends Notification -{ +class ContactNotification extends Notification { public $name; + public $subject; + public $message; + public $contactDetails; /** @@ -25,8 +27,7 @@ class ContactNotification extends Notification * @param string $contactDetails * @return void */ - public function __construct($name, $subject, $message, $contactDetails='') - { + public function __construct($name, $subject, $message, $contactDetails = '') { $this->name = $name; $this->message = $message; $this->subject = $subject; @@ -39,8 +40,7 @@ public function __construct($name, $subject, $message, $contactDetails='') * @param mixed $notifiable * @return array|string */ - public function via($notifiable) - { + public function via($notifiable) { return ['mail']; } @@ -50,10 +50,9 @@ public function via($notifiable) * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ - public function toMail($notifiable) - { + public function toMail($notifiable) { $subject = Lang::get('contact.' . $this->subject); - $contactDetails = $this->contactDetails ? $this->contactDetails:'None'; + $contactDetails = $this->contactDetails ? $this->contactDetails : 'None'; $mailFrom = str_replace('', $this->subject, config('app.contact-mail-sender')); $mailSubject = config('app.name') . Lang::get(' contact form message: ') . $subject; diff --git a/app/Notifications/EmailReverificationNotification.php b/app/Notifications/EmailReverificationNotification.php index 1495ec872..60b9d715e 100644 --- a/app/Notifications/EmailReverificationNotification.php +++ b/app/Notifications/EmailReverificationNotification.php @@ -10,8 +10,7 @@ * A notification to be sent when an account has already been created, but the verification link has been lost, or has expired * and a new link is needed by the user. */ -class EmailReverificationNotification extends Notification -{ +class EmailReverificationNotification extends Notification { /** * The email verification token. * @@ -32,8 +31,7 @@ class EmailReverificationNotification extends Notification * @param string $token * @return void */ - public function __construct($token) - { + public function __construct($token) { $this->token = $token; } @@ -43,8 +41,7 @@ public function __construct($token) * @param mixed $notifiable * @return array|string */ - public function via($notifiable) - { + public function via($notifiable) { return ['mail']; } @@ -54,13 +51,12 @@ public function via($notifiable) * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ - public function toMail($notifiable) - { + public function toMail($notifiable) { if (static::$toMailCallback) { return call_user_func(static::$toMailCallback, $notifiable, $this->token); } - $verifyEmailLink = config('wbstack.ui_url') . '/emailVerification/'.$this->token; + $verifyEmailLink = config('wbstack.ui_url') . '/emailVerification/' . $this->token; return (new MailMessage) ->subject(Lang::get('Please verify your email')) @@ -75,8 +71,7 @@ public function toMail($notifiable) * @param \Closure $callback * @return void */ - public static function toMailUsing($callback) - { + public static function toMailUsing($callback) { static::$toMailCallback = $callback; } } diff --git a/app/Notifications/EmptyWikiNotification.php b/app/Notifications/EmptyWikiNotification.php index a2329da1d..93cbc01eb 100644 --- a/app/Notifications/EmptyWikiNotification.php +++ b/app/Notifications/EmptyWikiNotification.php @@ -3,7 +3,6 @@ namespace App\Notifications; use App\Wiki; -use Closure; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; use Illuminate\Support\Facades\Lang; @@ -12,9 +11,7 @@ /** * Notification to be sent to empty Wikibase owner if the wiki stay empty longer than 30 days */ - -class EmptyWikiNotification extends Notification -{ +class EmptyWikiNotification extends Notification { const TYPE = 'empty_wiki_notification'; private string $sitename; @@ -22,11 +19,9 @@ class EmptyWikiNotification extends Notification /** * Create a notification instance. * - * @param string $sitename * @return void */ - public function __construct(string $sitename) - { + public function __construct(string $sitename) { $this->sitename = $sitename; } @@ -36,8 +31,7 @@ public function __construct(string $sitename) * @param mixed $notifiable * @return array */ - public function via($notifiable) - { + public function via($notifiable) { return ['mail']; } @@ -47,14 +41,13 @@ public function via($notifiable) * @param mixed $notifiable * @return MailMessage */ - public function toMail($notifiable) - { + public function toMail($notifiable) { $days = intval(config('wbstack.wiki_empty_notification_threshold')); return (new MailMessage) ->from('noreply@wikibase.cloud', 'Wikibase Cloud') ->subject(Lang::get('Need some help with your Wikibase?')) - ->line(Lang::get('Thanks for creating a Wikibase instance on Wikibase Cloud! That was at least '.$days.' days ago. We couldn’t help but notice that your Wikibase instance `'.$this->sitename.'` remains empty, so we’re checking in to see if we can help.')) + ->line(Lang::get('Thanks for creating a Wikibase instance on Wikibase Cloud! That was at least ' . $days . ' days ago. We couldn’t help but notice that your Wikibase instance `' . $this->sitename . '` remains empty, so we’re checking in to see if we can help.')) ->line(Lang::get('If you’re still planning to use Wikibase for your project but just haven’t gotten around to doing so, no worries -- feel free to ignore this email.')) ->line(Lang::get('Are you having trouble getting started? We have some resources that might help:')) ->line(new HtmlString('
    ')) diff --git a/app/Notifications/ResetPasswordNotification.php b/app/Notifications/ResetPasswordNotification.php index 605175bf3..55f76b7d5 100644 --- a/app/Notifications/ResetPasswordNotification.php +++ b/app/Notifications/ResetPasswordNotification.php @@ -7,9 +7,8 @@ use Illuminate\Notifications\Notification; use Illuminate\Support\Facades\Lang; -class ResetPasswordNotification extends Notification -{ - use HasFactory; +class ResetPasswordNotification extends Notification { + use HasFactory; /** * The password reset token. @@ -31,8 +30,7 @@ class ResetPasswordNotification extends Notification * @param string $token * @return void */ - public function __construct($token) - { + public function __construct($token) { $this->token = $token; } @@ -42,8 +40,7 @@ public function __construct($token) * @param mixed $notifiable * @return array|string */ - public function via($notifiable) - { + public function via($notifiable) { return ['mail']; } @@ -53,21 +50,20 @@ public function via($notifiable) * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ - public function toMail($notifiable) - { + public function toMail($notifiable) { if (static::$toMailCallback) { return call_user_func(static::$toMailCallback, $notifiable, $this->token); } $encodedEmail = urlencode($notifiable->getEmailForPasswordReset()); $queryPart = "?token=$this->token&email={$encodedEmail}"; - $resetPasswordLink = config('wbstack.ui_url').'/reset-password'.$queryPart; + $resetPasswordLink = config('wbstack.ui_url') . '/reset-password' . $queryPart; return (new MailMessage) ->subject(Lang::get('Please reset your password')) ->line(Lang::get('You are receiving this email because we received a password reset request for your account.')) ->action(Lang::get('Reset Password'), $resetPasswordLink) - ->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')])) + ->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.' . config('auth.defaults.passwords') . '.expire')])) ->line(Lang::get('If you did not make this request, you can simply disregard this email.')); } @@ -77,8 +73,7 @@ public function toMail($notifiable) * @param \Closure $callback * @return void */ - public static function toMailUsing($callback) - { + public static function toMailUsing($callback) { static::$toMailCallback = $callback; } } diff --git a/app/Notifications/UserCreationNotification.php b/app/Notifications/UserCreationNotification.php index 774b8bb3a..adde64ca2 100644 --- a/app/Notifications/UserCreationNotification.php +++ b/app/Notifications/UserCreationNotification.php @@ -9,8 +9,7 @@ /** * Notification to be sent after account creation that includes a verification link. */ -class UserCreationNotification extends Notification -{ +class UserCreationNotification extends Notification { /** * The email verification token. * @@ -31,8 +30,7 @@ class UserCreationNotification extends Notification * @param string $token * @return void */ - public function __construct($token) - { + public function __construct($token) { $this->token = $token; } @@ -42,8 +40,7 @@ public function __construct($token) * @param mixed $notifiable * @return array|string */ - public function via($notifiable) - { + public function via($notifiable) { return ['mail']; } @@ -53,13 +50,12 @@ public function via($notifiable) * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ - public function toMail($notifiable) - { + public function toMail($notifiable) { if (static::$toMailCallback) { return call_user_func(static::$toMailCallback, $notifiable, $this->token); } - $verifyEmailLink = config('wbstack.ui_url') . '/emailVerification/'.$this->token; + $verifyEmailLink = config('wbstack.ui_url') . '/emailVerification/' . $this->token; return (new MailMessage) ->subject(Lang::get('Action Needed: Please verify your email')) @@ -74,8 +70,7 @@ public function toMail($notifiable) * @param \Closure $callback * @return void */ - public static function toMailUsing($callback) - { + public static function toMailUsing($callback) { static::$toMailCallback = $callback; } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 7816cecac..1101227dd 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,27 +2,24 @@ namespace App\Providers; -use Illuminate\Support\ServiceProvider; -use Illuminate\Support\Facades\Queue; -use Illuminate\Queue\Events\JobFailed; use App\Http\Curl\CurlRequest; use App\Http\Curl\HttpRequest; +use Illuminate\Queue\Events\JobFailed; +use Illuminate\Support\Facades\Queue; +use Illuminate\Support\ServiceProvider; -class AppServiceProvider extends ServiceProvider -{ +class AppServiceProvider extends ServiceProvider { /** * Register any application services. */ - public function register(): void - { + public function register(): void { $this->app->bind(HttpRequest::class, CurlRequest::class); } /** * Bootstrap any application services. */ - public function boot(): void - { + public function boot(): void { Queue::failing(function (JobFailed $event) { $name = data_get($event->job->payload(), 'data.commandName'); $wrappedException = new \Exception("Executing Job '$name' failed.", 1, $event->exception); diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index c846f56cf..219867b49 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -5,8 +5,7 @@ use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Laravel\Passport\Passport; -class AuthServiceProvider extends ServiceProvider -{ +class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * @@ -17,8 +16,7 @@ class AuthServiceProvider extends ServiceProvider /** * Register any authentication / authorization services. */ - public function boot(): void - { + public function boot(): void { Passport::personalAccessTokensExpireIn(now()->addDays(30)); } } diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php index 2be04f5d9..5e024b6b7 100644 --- a/app/Providers/BroadcastServiceProvider.php +++ b/app/Providers/BroadcastServiceProvider.php @@ -5,13 +5,11 @@ use Illuminate\Support\Facades\Broadcast; use Illuminate\Support\ServiceProvider; -class BroadcastServiceProvider extends ServiceProvider -{ +class BroadcastServiceProvider extends ServiceProvider { /** * Bootstrap any application services. */ - public function boot(): void - { + public function boot(): void { Broadcast::routes(); require base_path('routes/channels.php'); diff --git a/app/Providers/CollectorRegistryProvider.php b/app/Providers/CollectorRegistryProvider.php index 2fde053cd..ebc36f6e9 100644 --- a/app/Providers/CollectorRegistryProvider.php +++ b/app/Providers/CollectorRegistryProvider.php @@ -2,21 +2,18 @@ namespace App\Providers; -use Illuminate\Support\ServiceProvider; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Facades\Config; +use Illuminate\Support\ServiceProvider; +use LKDevelopment\HorizonPrometheusExporter\Repository\ExporterRepository; use Prometheus\CollectorRegistry; use Prometheus\Storage\Redis; -use Illuminate\Contracts\Foundation\Application; -use LKDevelopment\HorizonPrometheusExporter\Repository\ExporterRepository; - -class CollectorRegistryProvider extends ServiceProvider -{ +class CollectorRegistryProvider extends ServiceProvider { /** * Register services. */ - public function register(): void - { + public function register(): void { $this->app->bind(CollectorRegistry::class, function (Application $app) { return new CollectorRegistry(new Redis([ 'host' => Config::get('database.redis.metrics.host'), @@ -24,7 +21,7 @@ public function register(): void 'password' => Config::get('database.redis.metrics.password'), 'timeout' => 0.1, // in seconds 'read_timeout' => '10', // in seconds - 'persistent_connections' => false + 'persistent_connections' => false, ])); }, true); } @@ -32,8 +29,7 @@ public function register(): void /** * Bootstrap services. */ - public function boot(): void - { + public function boot(): void { ExporterRepository::setRegistry( $this->app->make(CollectorRegistry::class), ); diff --git a/app/Providers/DomainValidatorServiceProvider.php b/app/Providers/DomainValidatorServiceProvider.php index ecf4c7a20..4af0c0124 100644 --- a/app/Providers/DomainValidatorServiceProvider.php +++ b/app/Providers/DomainValidatorServiceProvider.php @@ -2,29 +2,28 @@ namespace App\Providers; -use Illuminate\Support\ServiceProvider; -use Illuminate\Support\Facades\Config; use App\Helper\DomainValidator; use App\Rules\ForbiddenSubdomainRule; +use Illuminate\Support\Facades\Config; +use Illuminate\Support\ServiceProvider; -class DomainValidatorServiceProvider extends ServiceProvider -{ +class DomainValidatorServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ - public function register() - { - $this->app->singleton(DomainValidator::class , function ($app) { + public function register() { + $this->app->singleton(DomainValidator::class, function ($app) { $suffix = Config::get('wbstack.subdomain_suffix'); + return new DomainValidator( $suffix, [ - new ForbiddenSubdomainRule( - require __DIR__ . '/../Rules/ForbiddenSubdomains.php', - $suffix - ) + new ForbiddenSubdomainRule( + require __DIR__ . '/../Rules/ForbiddenSubdomains.php', + $suffix + ), ] ); }); diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index fbfb66bd2..a14d3f96b 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -6,8 +6,7 @@ use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; -class EventServiceProvider extends ServiceProvider -{ +class EventServiceProvider extends ServiceProvider { /** * The event listener mappings for the application. * @@ -22,8 +21,7 @@ class EventServiceProvider extends ServiceProvider /** * Register any events for your application. */ - public function boot(): void - { + public function boot(): void { parent::boot(); // @@ -32,8 +30,7 @@ public function boot(): void /** * Determine if events and listeners should be automatically discovered. */ - public function shouldDiscoverEvents(): bool - { + public function shouldDiscoverEvents(): bool { return false; } } diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php index 9811982b6..e185692ef 100644 --- a/app/Providers/HorizonServiceProvider.php +++ b/app/Providers/HorizonServiceProvider.php @@ -6,13 +6,11 @@ use Laravel\Horizon\Horizon; use Laravel\Horizon\HorizonApplicationServiceProvider; -class HorizonServiceProvider extends HorizonApplicationServiceProvider -{ +class HorizonServiceProvider extends HorizonApplicationServiceProvider { /** * Bootstrap any application services. */ - public function boot(): void - { + public function boot(): void { parent::boot(); // Horizon::routeSmsNotificationsTo('15556667777'); @@ -25,8 +23,7 @@ public function boot(): void * * This gate determines who can access Horizon in non-local environments. */ - protected function gate(): void - { + protected function gate(): void { Gate::define('viewHorizon', function ($user) { return in_array($user->email, [ // diff --git a/app/Providers/KubernetesClientServiceProvider.php b/app/Providers/KubernetesClientServiceProvider.php index 016ad0a15..73723e6d0 100644 --- a/app/Providers/KubernetesClientServiceProvider.php +++ b/app/Providers/KubernetesClientServiceProvider.php @@ -2,27 +2,25 @@ namespace App\Providers; +use Http\Adapter\Guzzle7\Client as GuzzleClient; use Illuminate\Support\ServiceProvider; use Maclof\Kubernetes\Client; -use Http\Adapter\Guzzle7\Client as GuzzleClient; -class KubernetesClientServiceProvider extends ServiceProvider -{ +class KubernetesClientServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ - public function register() - { - $this->app->bind(Client::class , function ($app) { + public function register() { + $this->app->bind(Client::class, function ($app) { $httpClient = GuzzleClient::createWithConfig([ 'verify' => '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', ]); return new Client([ - 'master' => 'https://kubernetes.default.svc', - 'token' => '/var/run/secrets/kubernetes.io/serviceaccount/token', + 'master' => 'https://kubernetes.default.svc', + 'token' => '/var/run/secrets/kubernetes.io/serviceaccount/token', ], null, $httpClient); }); } diff --git a/app/Providers/ReCaptchaServiceProvider.php b/app/Providers/ReCaptchaServiceProvider.php index 72e0e02de..84215414c 100644 --- a/app/Providers/ReCaptchaServiceProvider.php +++ b/app/Providers/ReCaptchaServiceProvider.php @@ -2,20 +2,18 @@ namespace App\Providers; -use Illuminate\Support\ServiceProvider; use App\Rules\ReCaptchaValidation; -use \ReCaptcha\ReCaptcha; +use Illuminate\Support\ServiceProvider; +use ReCaptcha\ReCaptcha; -class ReCaptchaServiceProvider extends ServiceProvider -{ - /** +class ReCaptchaServiceProvider extends ServiceProvider { + /** * Register any application services. * * @return void */ - public function register() - { - $this->app->bind(ReCaptchaValidation::class, function($app) { + public function register() { + $this->app->bind(ReCaptchaValidation::class, function ($app) { $recaptcha = new ReCaptcha( config('recaptcha.secret_key') ); @@ -33,8 +31,7 @@ public function register() * * @return array */ - public function provides() - { + public function provides() { return [ReCaptchaValidation::class]; } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 4b89e9a99..fa8d9f433 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -5,8 +5,7 @@ use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Route; -class RouteServiceProvider extends ServiceProvider -{ +class RouteServiceProvider extends ServiceProvider { /** * This namespace is applied to your controller routes. * @@ -19,8 +18,7 @@ class RouteServiceProvider extends ServiceProvider /** * Define your route model bindings, pattern filters, etc. */ - public function boot(): void - { + public function boot(): void { // parent::boot(); @@ -30,8 +28,7 @@ public function boot(): void * Define the routes for the application. * These are optionally loaded based on environment variables. */ - public function map(): void - { + public function map(): void { $this->mapGeneralRoutes(); if (getenv('ROUTES_LOAD_WEB') == 1) { $this->mapApiRoutes(); @@ -44,28 +41,24 @@ public function map(): void } } - protected function mapGeneralRoutes(): void - { + protected function mapGeneralRoutes(): void { Route::namespace($this->namespace) - ->group(base_path('routes/general.php')); + ->group(base_path('routes/general.php')); } - protected function mapApiRoutes(): void - { + protected function mapApiRoutes(): void { Route::namespace($this->namespace) - ->group(base_path('routes/api.php')); + ->group(base_path('routes/api.php')); } - protected function mapSandboxRoutes(): void - { + protected function mapSandboxRoutes(): void { Route::namespace($this->namespace) - ->group(base_path('routes/sandbox.php')); + ->group(base_path('routes/sandbox.php')); } - protected function mapBackendRoutes(): void - { + protected function mapBackendRoutes(): void { Route::prefix('backend') - ->namespace($this->namespace.'\Backend') - ->group(base_path('routes/backend.php')); + ->namespace($this->namespace . '\Backend') + ->group(base_path('routes/backend.php')); } } diff --git a/app/QsBatch.php b/app/QsBatch.php index 8ff1aca03..4b12a1aa9 100644 --- a/app/QsBatch.php +++ b/app/QsBatch.php @@ -16,6 +16,7 @@ * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\Wiki $wiki + * * @method static \Illuminate\Database\Eloquent\Builder|\App\QsBatch newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\QsBatch newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\QsBatch query() @@ -26,10 +27,10 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\QsBatch whereIn($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\QsBatch whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\QsBatch whereWikiId($value) + * * @mixin \Eloquent */ -class QsBatch extends Model -{ +class QsBatch extends Model { use HasFactory; protected $fillable = [ @@ -42,16 +43,13 @@ class QsBatch extends Model ]; protected $casts = [ - 'pending_since'=> 'datetime', + 'pending_since' => 'datetime', ]; /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Wiki::class); } } diff --git a/app/QsCheckpoint.php b/app/QsCheckpoint.php index 75e5a32bc..977bd1f17 100644 --- a/app/QsCheckpoint.php +++ b/app/QsCheckpoint.php @@ -5,8 +5,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\ModelNotFoundException; -class QsCheckpoint extends Model -{ +class QsCheckpoint extends Model { public const CHECKPOINT_ID = 0; const FIELDS = [ @@ -18,27 +17,25 @@ class QsCheckpoint extends Model protected $visible = self::FIELDS; - public static function init(int $value = 0): void - { + public static function init(int $value = 0): void { self::create([ 'id' => self::CHECKPOINT_ID, 'checkpoint' => $value, ]); } - public static function get(): int - { + public static function get(): int { $match = self::where(['id' => self::CHECKPOINT_ID])->first(); if (!$match) { throw new ModelNotFoundException( 'No QsCheckpoint found. Is your table properly initialized?' ); } + return $match->checkpoint; } - public static function set(int $val): void - { + public static function set(int $val): void { $match = self::where(['id' => self::CHECKPOINT_ID])->first(); if (!$match) { throw new ModelNotFoundException( diff --git a/app/QueryserviceNamespace.php b/app/QueryserviceNamespace.php index d2bac71c7..142abee62 100644 --- a/app/QueryserviceNamespace.php +++ b/app/QueryserviceNamespace.php @@ -2,8 +2,8 @@ namespace App; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; /** * App\QueryserviceNamespace. @@ -15,6 +15,7 @@ * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\Wiki|null $wiki + * * @method static \Illuminate\Database\Eloquent\Builder|\App\QueryserviceNamespace newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\QueryserviceNamespace newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\QueryserviceNamespace query() @@ -24,11 +25,12 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\QueryserviceNamespace whereNamespace($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\QueryserviceNamespace whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\QueryserviceNamespace whereWikiId($value) + * * @mixin \Eloquent */ -class QueryserviceNamespace extends Model -{ +class QueryserviceNamespace extends Model { use HasFactory; + /** * The attributes that are mass assignable. * @@ -36,17 +38,14 @@ class QueryserviceNamespace extends Model */ protected $fillable = [ 'namespace', - //'internalHost', + // 'internalHost', 'backend', ]; /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Wiki::class); } } diff --git a/app/Rules/ForbiddenSubdomainRule.php b/app/Rules/ForbiddenSubdomainRule.php index b8cc70e26..c7df427f5 100644 --- a/app/Rules/ForbiddenSubdomainRule.php +++ b/app/Rules/ForbiddenSubdomainRule.php @@ -3,12 +3,12 @@ namespace App\Rules; use Illuminate\Contracts\Validation\Rule; -use App\Helper\DomainValidator; -class ForbiddenSubdomainRule implements Rule -{ +class ForbiddenSubdomainRule implements Rule { private $badWords; + private $subdomainSuffix; + const ERROR_MESSAGE = 'The subdomain contains a forbidden word.'; /** @@ -16,8 +16,7 @@ class ForbiddenSubdomainRule implements Rule * * @return void */ - public function __construct( array $badWords, string $subdomainSuffix ) - { + public function __construct(array $badWords, string $subdomainSuffix) { $this->badWords = $badWords; $this->subdomainSuffix = $subdomainSuffix; } @@ -29,18 +28,18 @@ public function __construct( array $badWords, string $subdomainSuffix ) * @param mixed $value * @return bool */ - public function passes( $attribute, $value ) - { + public function passes($attribute, $value) { $matches = []; - $regexp = '/^([a-z0-9-]+)' . preg_quote( $this->subdomainSuffix ) . '$/'; + $regexp = '/^([a-z0-9-]+)' . preg_quote($this->subdomainSuffix) . '$/'; preg_match($regexp, $value, $matches, PREG_OFFSET_CAPTURE); - if( count($matches) !== 2 ) { + if (count($matches) !== 2) { return false; } $subdomain = $matches[1][0]; - return $value !== null && !in_array( $subdomain, $this->badWords ); + + return $value !== null && !in_array($subdomain, $this->badWords); } /** @@ -48,8 +47,7 @@ public function passes( $attribute, $value ) * * @return string */ - public function message() - { + public function message() { return self::ERROR_MESSAGE; } } diff --git a/app/Rules/ForbiddenSubdomains.php b/app/Rules/ForbiddenSubdomains.php index 4b09b2693..6e4139cb4 100644 --- a/app/Rules/ForbiddenSubdomains.php +++ b/app/Rules/ForbiddenSubdomains.php @@ -202,5 +202,5 @@ 'www1', 'www2', 'wwww', - 'zuul' + 'zuul', ]; diff --git a/app/Rules/NonEmptyJsonRule.php b/app/Rules/NonEmptyJsonRule.php index 5a9ff9b1f..bc341a80f 100644 --- a/app/Rules/NonEmptyJsonRule.php +++ b/app/Rules/NonEmptyJsonRule.php @@ -5,10 +5,8 @@ use Closure; use Illuminate\Contracts\Validation\ValidationRule; -class NonEmptyJsonRule implements ValidationRule -{ - public function validate(string $attribute, mixed $value, Closure $fail): void - { +class NonEmptyJsonRule implements ValidationRule { + public function validate(string $attribute, mixed $value, Closure $fail): void { $json = json_decode($value, true); if (!is_array($json) || empty($json)) { $fail("The {$attribute} field must be a non-empty JSON object."); diff --git a/app/Rules/ReCaptchaValidation.php b/app/Rules/ReCaptchaValidation.php index e7f71a4d4..1fbfdeff0 100644 --- a/app/Rules/ReCaptchaValidation.php +++ b/app/Rules/ReCaptchaValidation.php @@ -5,22 +5,21 @@ use Illuminate\Contracts\Validation\ImplicitRule; use Illuminate\Support\Arr; use Illuminate\Support\Str; -use \ReCaptcha\ReCaptcha; +use ReCaptcha\ReCaptcha; -class ReCaptchaValidation implements ImplicitRule -{ +class ReCaptchaValidation implements ImplicitRule { /** - * @var \ReCaptcha\ReCaptcha $recaptcha instance + * @var \ReCaptcha\ReCaptcha instance */ protected $recaptcha; /** - * @var string $minScore Lowest score to pass (0.0 - 1.0) + * @var string Lowest score to pass (0.0 - 1.0) */ protected $minScore; /** - * @var string $appUrl App URL of client request + * @var string App URL of client request */ protected $appUrl; @@ -32,17 +31,16 @@ public function __construct(ReCaptcha $recaptcha, $minScore, $appUrl) { /** * Comparison against expected hostname. - * - * @param string $hostname - * @return bool + * + * @param string $hostname + * @return bool */ - private function verifyHostname($hostname) - { + private function verifyHostname($hostname) { $parsedUrl = parse_url($this->appUrl); $expectedHostname = Arr::get($parsedUrl, 'host', null); if (filled($expectedHostname)) { - if (false === Str::of($expectedHostname)->exactly($hostname)) { + if (Str::of($expectedHostname)->exactly($hostname) === false) { return false; } } else { @@ -56,28 +54,27 @@ private function verifyHostname($hostname) /** * Verifies the ReCaptcha Request with the official ReCaptcha service library - * - * @param string $secretKey - * @return \ReCaptcha\Response + * + * @param string $secretKey + * @return \ReCaptcha\Response */ - private function verify($token) - { + private function verify($token) { $recaptchaResponse = new \ReCaptcha\Response(false); try { $recaptchaResponse = $this->recaptcha - ->verify( - $token, - request()->getClientIp() - ); + ->verify( + $token, + request()->getClientIp() + ); logger()->debug('ReCaptcha response', [ - 'class' => self::class, - 'response' => $recaptchaResponse->toArray() + 'class' => self::class, + 'response' => $recaptchaResponse->toArray(), ]); - } catch(\Exception $e) { + } catch (\Exception $e) { logger()->error('Exception thrown by \Recaptcha\ReCaptcha::verify', [ - 'class' => self::class, + 'class' => self::class, 'exception' => $e, ]); } @@ -92,23 +89,22 @@ private function verify($token) * @param mixed $value * @return bool */ - public function passes($attribute, $value) - { + public function passes($attribute, $value) { $recaptchaResponse = $this->verify($value); - if (false === $this->verifyHostname($recaptchaResponse->getHostname())) { + if ($this->verifyHostname($recaptchaResponse->getHostname()) === false) { return false; } - if (false === $recaptchaResponse->isSuccess()) { + if ($recaptchaResponse->isSuccess() === false) { return false; } if ($recaptchaResponse->getScore() < $this->minScore) { logger()->debug('ReCaptcha response below minScore', [ - 'class' => self::class, + 'class' => self::class, 'minScore' => $this->minScore, - 'score' => $recaptchaResponse->getScore() + 'score' => $recaptchaResponse->getScore(), ]); return false; @@ -122,8 +118,7 @@ public function passes($attribute, $value) * * @return string */ - public function message() - { + public function message() { return 'ReCaptcha validation failed.'; } } diff --git a/app/Rules/SettingCaptchaQuestions.php b/app/Rules/SettingCaptchaQuestions.php index 493de9928..c41eb2b0f 100644 --- a/app/Rules/SettingCaptchaQuestions.php +++ b/app/Rules/SettingCaptchaQuestions.php @@ -4,8 +4,7 @@ use Illuminate\Contracts\Validation\Rule; -class SettingCaptchaQuestions implements Rule -{ +class SettingCaptchaQuestions implements Rule { /** * Determine if the validation rule passes. * @@ -13,8 +12,7 @@ class SettingCaptchaQuestions implements Rule * @param mixed $value * @return bool */ - public function passes($attribute, $value) - { + public function passes($attribute, $value) { $value = json_decode($value, true); if ($value === null) { @@ -49,14 +47,14 @@ public function passes($attribute, $value) } } } + return true; } /** * Get the validation error message. */ - public function message(): string - { + public function message(): string { return 'Value must be JSON mapping of questions to an array of answers and neither question nor answers may be longer than 200 chars'; } } diff --git a/app/Rules/SettingWikibaseManifestEquivEntities.php b/app/Rules/SettingWikibaseManifestEquivEntities.php index 11f9b7446..3508ba1d0 100644 --- a/app/Rules/SettingWikibaseManifestEquivEntities.php +++ b/app/Rules/SettingWikibaseManifestEquivEntities.php @@ -4,9 +4,9 @@ use Illuminate\Contracts\Validation\Rule; -class SettingWikibaseManifestEquivEntities implements Rule -{ +class SettingWikibaseManifestEquivEntities implements Rule { public static $entityTypes = ['properties', 'items']; + public static $entityTypeValidation = [ 'properties' => '/^(P)\d+$/', 'items' => '/^(Q)\d+$/', @@ -19,8 +19,7 @@ class SettingWikibaseManifestEquivEntities implements Rule * @param mixed $value * @return bool */ - public function passes($attribute, $value) - { + public function passes($attribute, $value) { $value = json_decode($value, true); if ($value === null) { @@ -28,7 +27,7 @@ public function passes($attribute, $value) } foreach (self::$entityTypes as $entityType) { - if (! array_key_exists($entityType, $value)) { + if (!array_key_exists($entityType, $value)) { return false; } @@ -36,7 +35,7 @@ public function passes($attribute, $value) foreach ($value[$entityType] as $local => $wikidata) { // Make sure that we have a single array mapping some property to some value - if (! preg_match($validationRule, $local) || ! is_string($wikidata) || ! preg_match($validationRule, $wikidata)) { + if (!preg_match($validationRule, $local) || !is_string($wikidata) || !preg_match($validationRule, $wikidata)) { return false; } } @@ -50,8 +49,7 @@ public function passes($attribute, $value) * * @return string */ - public function message() - { + public function message() { return 'Value must be a JSON string mapping Wikidata Item or Property Ids to local Item or Property Ids'; } } diff --git a/app/Traits/PageFetcher.php b/app/Traits/PageFetcher.php index e05f690bc..09bc04e97 100644 --- a/app/Traits/PageFetcher.php +++ b/app/Traits/PageFetcher.php @@ -5,13 +5,11 @@ use App\Constants\MediawikiNamespace; use Illuminate\Support\Facades\Http; -trait PageFetcher -{ +trait PageFetcher { private string $apiUrl; - //this function is used to fetch pages on namespace - function fetchPagesInNamespace(string $wikiDomain, MediawikiNamespace $namespace): array - { + // this function is used to fetch pages on namespace + public function fetchPagesInNamespace(string $wikiDomain, MediawikiNamespace $namespace): array { if (empty($this->apiUrl)) { throw new \RuntimeException('API URL has not been set.'); } @@ -20,7 +18,7 @@ function fetchPagesInNamespace(string $wikiDomain, MediawikiNamespace $namespace $cursor = ''; while (true) { $response = Http::withHeaders([ - 'host' => $wikiDomain + 'host' => $wikiDomain, ])->get( $this->apiUrl, [ @@ -35,7 +33,7 @@ function fetchPagesInNamespace(string $wikiDomain, MediawikiNamespace $namespace if ($response->failed()) { throw new \Exception( - 'Failed to fetch allpages for wiki '.$wikiDomain + 'Failed to fetch allpages for wiki ' . $wikiDomain ); } @@ -43,7 +41,7 @@ function fetchPagesInNamespace(string $wikiDomain, MediawikiNamespace $namespace $error = data_get($jsonResponse, 'error'); if ($error !== null) { throw new \Exception( - 'Error response fetching allpages for wiki '.$wikiDomain.': '.$error + 'Error response fetching allpages for wiki ' . $wikiDomain . ': ' . $error ); } diff --git a/app/User.php b/app/User.php index ed3ae63c7..3c15b1e38 100644 --- a/app/User.php +++ b/app/User.php @@ -5,10 +5,10 @@ use App\Notifications\ResetPasswordNotification; use http\Exception\RuntimeException; use Illuminate\Contracts\Auth\MustVerifyEmail; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Passport\HasApiTokens; -use Illuminate\Database\Eloquent\Factories\HasFactory; /** * App\User. @@ -32,7 +32,8 @@ * @property-read int|null $notifications_count * @property-read \Illuminate\Database\Eloquent\Collection|\Laravel\Passport\Token[] $tokens * @property-read int|null $tokens_count - * @method static \Database\Factories\UserFactory factory(...$parameters) + * + * @method static \Database\Factories\UserFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|\App\User newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\User newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\User query() @@ -47,11 +48,11 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereTrialEndsAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\User whereVerified($value) + * * @mixin \Eloquent */ -class User extends Authenticatable implements MustVerifyEmail -{ - use HasApiTokens, Notifiable, HasFactory; +class User extends Authenticatable implements MustVerifyEmail { + use HasApiTokens, HasFactory, Notifiable; /** * The attributes that are mass assignable. @@ -86,45 +87,37 @@ class User extends Authenticatable implements MustVerifyEmail 'password' => 'hashed', ]; - public function sendPasswordResetNotification($token) - { + public function sendPasswordResetNotification($token) { $this->notify(new ResetPasswordNotification($token)); } /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ - public function managesWikis(): \Illuminate\Database\Eloquent\Relations\BelongsToMany - { + public function managesWikis(): \Illuminate\Database\Eloquent\Relations\BelongsToMany { return $this->belongsToMany(Wiki::class, 'wiki_managers'); } - public function hasVerifiedEmail() - { + public function hasVerifiedEmail() { return (bool) $this->verified; } - public function markEmailAsVerified() - { + public function markEmailAsVerified() { $this->verified = 1; return true; } - public function sendEmailVerificationNotification() - { + public function sendEmailVerificationNotification() { // This is required by the MustVerifyEmail interface that we use for middle ware. // But we currently send our emails via a different means, so we havn't implemented this.. // We can not throw an exception here as this is still called! (even if we don't use it) // https://github.com/addshore/wbstack/issues/120 - //throw new RuntimeException('Not yet implemented'); + // throw new RuntimeException('Not yet implemented'); } - public function getEmailForVerification() - { + public function getEmailForVerification() { return $this->email; } } diff --git a/app/UserVerificationToken.php b/app/UserVerificationToken.php index f3d65119c..1d02e3e77 100644 --- a/app/UserVerificationToken.php +++ b/app/UserVerificationToken.php @@ -13,6 +13,7 @@ * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\User $user + * * @method static \Illuminate\Database\Eloquent\Builder|\App\UserVerificationToken newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\UserVerificationToken newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\UserVerificationToken query() @@ -21,10 +22,10 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\UserVerificationToken whereToken($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\UserVerificationToken whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\UserVerificationToken whereUserId($value) + * * @mixin \Eloquent */ -class UserVerificationToken extends Model -{ +class UserVerificationToken extends Model { /** * The attributes that are mass assignable. * @@ -36,12 +37,9 @@ class UserVerificationToken extends Model ]; /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class); } } diff --git a/app/Wiki.php b/app/Wiki.php index 8fcafb05f..e51e48af7 100644 --- a/app/Wiki.php +++ b/app/Wiki.php @@ -2,10 +2,10 @@ namespace App; +use App\Helper\DomainHelper; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; -use Illuminate\Database\Eloquent\Factories\HasFactory; -use App\Helper\DomainHelper; /** * App\Wiki. @@ -23,6 +23,7 @@ * @property-read \Illuminate\Database\Eloquent\Collection|\App\User[] $wikiManagers * @property-read int|null $wiki_managers_count * @property-read \App\QueryserviceNamespace|null $wikiQueryserviceNamespace + * * @method static \Database\Factories\WikiFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|\App\Wiki newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\Wiki newQuery() @@ -36,11 +37,11 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\Wiki whereUpdatedAt($value) * @method static \Illuminate\Database\Query\Builder|\App\Wiki withTrashed() * @method static \Illuminate\Database\Query\Builder|\App\Wiki withoutTrashed() + * * @mixin \Eloquent */ -class Wiki extends Model -{ - use SoftDeletes, HasFactory; +class Wiki extends Model { + use HasFactory, SoftDeletes; /** * The attributes that are mass assignable. @@ -68,8 +69,7 @@ class Wiki extends Model 'deleted_at' => 'datetime', ]; - public function wikiDbVersion() - { + public function wikiDbVersion() { /** * @psalm-suppress InvalidArgument */ @@ -79,32 +79,25 @@ public function wikiDbVersion() // TODO these should just be on the backend model? =] Or marked as a private relationship or something? // OR some sort of access control needs to be done.. /** - * @return \Illuminate\Database\Eloquent\Relations\HasOne - * * @psalm-return \Illuminate\Database\Eloquent\Relations\HasOne */ - public function wikiDb(): \Illuminate\Database\Eloquent\Relations\HasOne - { + public function wikiDb(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(WikiDb::class); } - public function wikiSiteStats(): \Illuminate\Database\Eloquent\Relations\HasOne - { + public function wikiSiteStats(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(WikiSiteStats::class); } - public function wikiLifecycleEvents(): \Illuminate\Database\Eloquent\Relations\HasOne - { + public function wikiLifecycleEvents(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(WikiLifecycleEvents::class); } - public function wikiNotificationSentRecords(): \Illuminate\Database\Eloquent\Relations\HasMany - { + public function wikiNotificationSentRecords(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(WikiNotificationSentRecord::class); } - public function wikiEntityImports(): \Illuminate\Database\Eloquent\Relations\HasMany - { + public function wikiEntityImports(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(WikiEntityImport::class); } @@ -113,49 +106,41 @@ public function wikiManagers(): \Illuminate\Database\Eloquent\Relations\HasMany } /** - * @return \Illuminate\Database\Eloquent\Relations\HasOne - * * @psalm-return \Illuminate\Database\Eloquent\Relations\HasOne */ - public function wikiQueryserviceNamespace(): \Illuminate\Database\Eloquent\Relations\HasOne - { + public function wikiQueryserviceNamespace(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(QueryserviceNamespace::class); } // FIXME: rename to privateSettings / allSettings for clarity? /** - * @return \Illuminate\Database\Eloquent\Relations\HasMany - * * @psalm-return \Illuminate\Database\Eloquent\Relations\HasMany */ - public function settings(): \Illuminate\Database\Eloquent\Relations\HasMany - { + public function settings(): \Illuminate\Database\Eloquent\Relations\HasMany { return $this->hasMany(WikiSetting::class); } - public function publicSettings() - { + public function publicSettings() { return $this->settings()->whereIn('name', - [ - 'wgLogo', - 'wgReadOnly', - // FIXME: this list is evil and should be kept in sync with WikiSettingController?! - 'wgDefaultSkin', - 'wwExtEnableConfirmAccount', - 'wwExtEnableWikibaseLexeme', - 'wwWikibaseStringLengthString', - 'wwWikibaseStringLengthMonolingualText', - 'wwWikibaseStringLengthMultilang', - 'wikibaseFedPropsEnable', - 'wikibaseManifestEquivEntities', - 'wwUseQuestyCaptcha', - 'wwCaptchaQuestions', - ] - ); + [ + 'wgLogo', + 'wgReadOnly', + // FIXME: this list is evil and should be kept in sync with WikiSettingController?! + 'wgDefaultSkin', + 'wwExtEnableConfirmAccount', + 'wwExtEnableWikibaseLexeme', + 'wwWikibaseStringLengthString', + 'wwWikibaseStringLengthMonolingualText', + 'wwWikibaseStringLengthMultilang', + 'wikibaseFedPropsEnable', + 'wikibaseManifestEquivEntities', + 'wwUseQuestyCaptcha', + 'wwCaptchaQuestions', + ] + ); } - public function wikiManagersWithEmail() - { + public function wikiManagersWithEmail() { // TODO should this be hasMany ? /** * @psalm-suppress InvalidArgument @@ -166,22 +151,21 @@ public function wikiManagersWithEmail() /** * Get logo directory path */ - public static function getLogosDirectory( int $wiki_id ): string { - return self::getSiteDirectory( $wiki_id ) . '/logos'; + public static function getLogosDirectory(int $wiki_id): string { + return self::getSiteDirectory($wiki_id) . '/logos'; } /** * Get site directory path */ - public static function getSiteDirectory( int $wiki_id ): string { - $siteDir = md5($wiki_id.md5($wiki_id)); - return 'sites/'.$siteDir; + public static function getSiteDirectory(int $wiki_id): string { + $siteDir = md5($wiki_id . md5($wiki_id)); + + return 'sites/' . $siteDir; } /** * Convert the IDN formatted domain name to it's Unicode representation. - * - * @return string */ public function getDomainDecodedAttribute(): string { return DomainHelper::decode($this->domain); diff --git a/app/WikiDailyMetrics.php b/app/WikiDailyMetrics.php index d0114842d..330cad359 100644 --- a/app/WikiDailyMetrics.php +++ b/app/WikiDailyMetrics.php @@ -5,8 +5,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class WikiDailyMetrics extends Model -{ +class WikiDailyMetrics extends Model { use HasFactory; protected $table = 'wiki_daily_metrics'; @@ -46,9 +45,8 @@ class WikiDailyMetrics extends Model 'monthly_active_users', ]; - public function areMetricsEqual(WikiDailyMetrics $wikiDailyMetrics): bool - { - foreach(self::$metricNames as $field) { + public function areMetricsEqual(WikiDailyMetrics $wikiDailyMetrics): bool { + foreach (self::$metricNames as $field) { if ($this->$field != $wikiDailyMetrics->$field) { return false; } diff --git a/app/WikiDb.php b/app/WikiDb.php index 28d8787ea..705e34b9b 100644 --- a/app/WikiDb.php +++ b/app/WikiDb.php @@ -2,8 +2,8 @@ namespace App; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; /** * App\WikiDb. @@ -18,6 +18,7 @@ * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\Wiki|null $wiki + * * @method static \Database\Factories\WikiDbFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDb newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDb newQuery() @@ -31,10 +32,10 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDb whereUser($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDb whereVersion($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDb whereWikiId($value) + * * @mixin \Eloquent */ -class WikiDb extends Model -{ +class WikiDb extends Model { use HasFactory; /** @@ -52,12 +53,9 @@ class WikiDb extends Model ]; /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Wiki::class); } } diff --git a/app/WikiDomain.php b/app/WikiDomain.php index cdc9fc37d..d5727e81d 100644 --- a/app/WikiDomain.php +++ b/app/WikiDomain.php @@ -13,6 +13,7 @@ * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\Wiki|null $wiki + * * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDomain newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDomain newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDomain query() @@ -21,22 +22,19 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDomain whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDomain whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiDomain whereWikiId($value) + * * @mixin \Eloquent */ -class WikiDomain extends Model -{ +class WikiDomain extends Model { protected $fillable = [ 'domain', 'wiki_id', ]; /** - * @return \Illuminate\Database\Eloquent\Relations\HasOne - * * @psalm-return \Illuminate\Database\Eloquent\Relations\HasOne */ - public function wiki(): \Illuminate\Database\Eloquent\Relations\HasOne - { + public function wiki(): \Illuminate\Database\Eloquent\Relations\HasOne { return $this->hasOne(Wiki::class); } } diff --git a/app/WikiEntityImport.php b/app/WikiEntityImport.php index 13d11d42b..eaad4554c 100644 --- a/app/WikiEntityImport.php +++ b/app/WikiEntityImport.php @@ -5,9 +5,9 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class WikiEntityImport extends Model -{ +class WikiEntityImport extends Model { use HasFactory; + const FIELDS = [ 'status', 'started_at', diff --git a/app/WikiEntityImportStatus.php b/app/WikiEntityImportStatus.php index 9678ee9d3..99e1dd518 100644 --- a/app/WikiEntityImportStatus.php +++ b/app/WikiEntityImportStatus.php @@ -2,9 +2,8 @@ namespace App; -enum WikiEntityImportStatus: string -{ - case Pending = "pending"; - case Success = "success"; - case Failed = "failed"; +enum WikiEntityImportStatus: string { + case Pending = 'pending'; + case Success = 'success'; + case Failed = 'failed'; } diff --git a/app/WikiLifecycleEvents.php b/app/WikiLifecycleEvents.php index 114bf8a7a..4ce640508 100644 --- a/app/WikiLifecycleEvents.php +++ b/app/WikiLifecycleEvents.php @@ -8,8 +8,7 @@ // This class is supposed to contain information about certain events // in a wiki's lifecycle, e.g. the time of the last edit. Sources for these // points in time can be chosen as needed. -class WikiLifecycleEvents extends Model -{ +class WikiLifecycleEvents extends Model { use HasFactory; const FIELDS = [ diff --git a/app/WikiManager.php b/app/WikiManager.php index d102111d2..70acf7b42 100644 --- a/app/WikiManager.php +++ b/app/WikiManager.php @@ -2,8 +2,8 @@ namespace App; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; /** * App\WikiManager. @@ -15,6 +15,7 @@ * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\User $user * @property-read \App\Wiki $wiki + * * @method static \Database\Factories\WikiManagerFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiManager newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiManager newQuery() @@ -24,10 +25,10 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiManager whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiManager whereUserId($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiManager whereWikiId($value) + * * @mixin \Eloquent */ -class WikiManager extends Model -{ +class WikiManager extends Model { use HasFactory; /** @@ -42,27 +43,20 @@ class WikiManager extends Model // TODO remove these relationships if they are not used... /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Wiki::class); } /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class); } - public function email(): void - { + public function email(): void { $this->user()->get(['email'])->first(); } } diff --git a/app/WikiNotificationSentRecord.php b/app/WikiNotificationSentRecord.php index b0af024ac..08eebe985 100644 --- a/app/WikiNotificationSentRecord.php +++ b/app/WikiNotificationSentRecord.php @@ -5,13 +5,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class WikiNotificationSentRecord extends Model -{ +class WikiNotificationSentRecord extends Model { use HasFactory; const FIELDS = [ 'notification_type', - 'user_id' + 'user_id', ]; protected $fillable = self::FIELDS; diff --git a/app/WikiProfile.php b/app/WikiProfile.php index b4d4b2243..e3e045313 100644 --- a/app/WikiProfile.php +++ b/app/WikiProfile.php @@ -2,13 +2,11 @@ namespace App; -use App\Wiki; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; -class WikiProfile extends Model -{ +class WikiProfile extends Model { use HasFactory; protected $fillable = [ @@ -21,9 +19,7 @@ class WikiProfile extends Model 'temporality_other', ]; - public function wiki(): BelongsTo - { + public function wiki(): BelongsTo { return $this->belongsTo(Wiki::class); } - -} \ No newline at end of file +} diff --git a/app/WikiSetting.php b/app/WikiSetting.php index 344a185d5..71113e65f 100644 --- a/app/WikiSetting.php +++ b/app/WikiSetting.php @@ -2,8 +2,8 @@ namespace App; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Model; /** * App\WikiSetting. @@ -15,6 +15,7 @@ * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\Wiki|null $wiki + * * @method static \Database\Factories\WikiSettingFactory factory(...$parameters) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiSetting newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiSetting newQuery() @@ -25,18 +26,24 @@ * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiSetting whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiSetting whereValue($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\WikiSetting whereWikiId($value) + * * @mixin \Eloquent */ -class WikiSetting extends Model -{ +class WikiSetting extends Model { use HasFactory; public const wwExtEnableElasticSearch = 'wwExtEnableElasticSearch'; + public const wwExtEnableWikibaseLexeme = 'wwExtEnableWikibaseLexeme'; + public const wgSecretKey = 'wgSecretKey'; + public const wgLogo = 'wgLogo'; + public const wgFavicon = 'wgFavicon'; + public const wgOAuth2PrivateKey = 'wgOAuth2PrivateKey'; + public const wgOAuth2PublicKey = 'wgOAuth2PublicKey'; /** @@ -51,12 +58,9 @@ class WikiSetting extends Model ]; /** - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo - * * @psalm-return \Illuminate\Database\Eloquent\Relations\BelongsTo */ - public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo - { + public function wiki(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Wiki::class); } } diff --git a/app/WikiSiteStats.php b/app/WikiSiteStats.php index 52519f4d9..b303447ca 100644 --- a/app/WikiSiteStats.php +++ b/app/WikiSiteStats.php @@ -10,8 +10,7 @@ // `?action=query&meta=siteinfo&siprop=statistics` // When adding additional data about a wiki that comes from a different // source, consider storing it elsewhere. -class WikiSiteStats extends Model -{ +class WikiSiteStats extends Model { use HasFactory; const FIELDS = [ @@ -23,7 +22,7 @@ class WikiSiteStats extends Model 'activeusers', 'admins', 'jobs', - 'cirrussearch-article-words' + 'cirrussearch-article-words', ]; protected $fillable = self::FIELDS; diff --git a/composer.json b/composer.json index 3489c70d1..236e84a54 100644 --- a/composer.json +++ b/composer.json @@ -36,6 +36,7 @@ "require-dev": { "barryvdh/laravel-ide-helper": "2.13", "fakerphp/faker": "^1.17", + "laravel/pint": "^1.22", "mockery/mockery": "^1.4", "phpunit/phpunit": "^10.5", "psalm/plugin-laravel": "^2.8", @@ -68,8 +69,7 @@ ], "psalm": "vendor/bin/psalm", "phpunit": "vendor/bin/phpunit", - "check-style": "php-cs-fixer fix --dry-run --diff", - "fix-style": "php-cs-fixer fix" + "pint": "vendor/bin/pint" }, "config": { "platform": { diff --git a/composer.lock b/composer.lock index 31357111c..61e79f186 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "99faca32e4d564eff6f67af58a1c98a3", + "content-hash": "3796991d1c1ef562d82fcbe7583cc82d", "packages": [ { "name": "absszero/laravel-stackdriver-error-reporting", @@ -11057,6 +11057,72 @@ }, "time": "2020-07-09T08:09:16+00:00" }, + { + "name": "laravel/pint", + "version": "v1.22.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "941d1927c5ca420c22710e98420287169c7bcaf7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/941d1927c5ca420c22710e98420287169c7bcaf7", + "reference": "941d1927c5ca420c22710e98420287169c7bcaf7", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.75.0", + "illuminate/view": "^11.44.7", + "larastan/larastan": "^3.4.0", + "laravel-zero/framework": "^11.36.1", + "mockery/mockery": "^1.6.12", + "nunomaduro/termwind": "^2.3.1", + "pestphp/pest": "^2.36.0" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2025-05-08T08:38:12+00:00" + }, { "name": "mockery/mockery", "version": "1.6.7", @@ -14508,13 +14574,13 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, - "platform": [], - "platform-dev": [], + "platform": {}, + "platform-dev": {}, "platform-overrides": { "php": "8.2" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/config/auth.php b/config/auth.php index 2fccf9977..7742032c6 100644 --- a/config/auth.php +++ b/config/auth.php @@ -105,6 +105,6 @@ 'path' => '/api', 'ttl_minutes' => 60 * 24 * 30, 'same_site' => 'strict', - ] + ], ]; diff --git a/config/broadcasting.php b/config/broadcasting.php index 4eb4ce49a..0e086f2d0 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -37,7 +37,7 @@ 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), - 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', + 'host' => env('PUSHER_HOST') ?: 'api-' . env('PUSHER_APP_CLUSTER', 'mt1') . '.pusher.com', 'port' => env('PUSHER_PORT', 443), 'scheme' => env('PUSHER_SCHEME', 'https'), 'encrypted' => true, diff --git a/config/cache.php b/config/cache.php index a41651ff0..18cedef1a 100644 --- a/config/cache.php +++ b/config/cache.php @@ -97,5 +97,5 @@ | that reason, you may prefix every cache key to avoid collisions. | */ - 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache_'), ]; diff --git a/config/database.php b/config/database.php index 409620ff9..8ca6fdd92 100644 --- a/config/database.php +++ b/config/database.php @@ -54,8 +54,8 @@ // If the sticky option is enabled and a "write" operation has been performed // against the database during the current request cycle, // any further "read" operations will use the "write" connection. - 'sticky' => true, - 'driver' => 'mysql', + 'sticky' => true, + 'driver' => 'mysql', 'url' => env('DATABASE_URL'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE'), @@ -88,7 +88,7 @@ // If the sticky option is enabled and a "write" operation has been performed // against the database during the current request cycle, // any further "read" operations will use the "write" connection. - 'sticky' => true, + 'sticky' => true, 'driver' => 'mysql', 'url' => env('MW_DATABASE_URL'), 'port' => env('MW_DB_PORT', '3306'), @@ -140,7 +140,7 @@ 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'predis'), - 'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_', + 'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_', ], 'default' => [ diff --git a/config/dev-booter.php b/config/dev-booter.php index 0bbbffa36..f2b4cb4af 100644 --- a/config/dev-booter.php +++ b/config/dev-booter.php @@ -30,8 +30,8 @@ */ 'dev_providers_config_keys' => [ - 'dev' => 'app.dev_providers', - 'local' => 'app.local_providers', + 'dev' => 'app.dev_providers', + 'local' => 'app.local_providers', 'testing' => 'app.testing_providers', ], @@ -46,8 +46,8 @@ */ 'dev_aliases_config_keys' => [ - 'dev' => 'app.dev_aliases', - 'local' => 'app.local_aliases', + 'dev' => 'app.dev_aliases', + 'local' => 'app.local_aliases', 'testing' => 'app.testing_aliases', ], ]; diff --git a/config/error_reporting.php b/config/error_reporting.php index d14cb3f4e..5a8c9701b 100644 --- a/config/error_reporting.php +++ b/config/error_reporting.php @@ -19,7 +19,7 @@ // The transport type used for requests. // May be either `grpc` or `rest`. // **Defaults to** `grpc` if gRPC support is detected on the system. - 'transport' => null + 'transport' => null, ], 'PsrLogger' => [ // Determines whether or not to use background batching. @@ -32,5 +32,5 @@ 'callPeriod' => 2.0, 'workerNum' => 1, ], - ] + ], ]; diff --git a/config/filesystems.php b/config/filesystems.php index 8e494ca20..1753400d5 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -52,7 +52,7 @@ 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), - 'url' => env('APP_URL').'/storage', + 'url' => env('APP_URL') . '/storage', 'visibility' => 'public', 'throw' => false, ], diff --git a/config/horizon-exporter.php b/config/horizon-exporter.php index dc5ab76b7..9bb5fa2f7 100644 --- a/config/horizon-exporter.php +++ b/config/horizon-exporter.php @@ -1,19 +1,20 @@ getenv('ROUTES_LOAD_BACKEND') == 1, - "namespace" => 'platform_api', + 'enabled' => getenv('ROUTES_LOAD_BACKEND') == 1, + 'namespace' => 'platform_api', /** * You can change the default endpoint to something other than metrics. * Keep in mind that the change needs to be reflected in your Prometheus configuration as well. */ - "url" => 'metrics', + 'url' => 'metrics', /** * You can enable or disable or even create own exporters by simply implementing the LKDevelopment\HorizonPrometheusExporter\Contracts\Exporter Contract. * If you want to disable oder enable a Exporter just comment the specific line out. * If you want to add your own Exporter just add the Class Name to this array */ - "exporters" => [ + 'exporters' => [ \LKDevelopment\HorizonPrometheusExporter\Exporter\CurrentMasterSupervisors::class, \LKDevelopment\HorizonPrometheusExporter\Exporter\JobsPerMinute::class, \LKDevelopment\HorizonPrometheusExporter\Exporter\CurrentWorkload::class, @@ -29,17 +30,17 @@ /** * IP Whitelisting, you may don't want to expose your metrics on the internet so you can add the IP addresses of your Prometheus Server here. */ - "ip_whitelist" => [ + 'ip_whitelist' => [ // Keep empty to allow all IP addresses ], /** * You can change the Middleware which is used for the IP whitelisting. You can add your own, like a token based authentication. */ - "middleware" => \LKDevelopment\HorizonPrometheusExporter\Http\Middleware\IPWhitelistingMiddleware::class, + 'middleware' => \LKDevelopment\HorizonPrometheusExporter\Http\Middleware\IPWhitelistingMiddleware::class, /** * Allow storage to be wiped after a render of data in metrics controller */ - "wipe_storage_after_render" => false, + 'wipe_storage_after_render' => false, ]; diff --git a/config/horizon.php b/config/horizon.php index b439c11ad..c08e12a01 100644 --- a/config/horizon.php +++ b/config/horizon.php @@ -56,7 +56,7 @@ 'prefix' => env( 'HORIZON_PREFIX', - Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:' + Str::slug(env('APP_NAME', 'laravel'), '_') . '_horizon:' ), /* diff --git a/config/ide-helper.php b/config/ide-helper.php index fc188ce2a..93bd0270c 100644 --- a/config/ide-helper.php +++ b/config/ide-helper.php @@ -11,8 +11,8 @@ | */ - 'filename' => '_ide_helper', - 'format' => 'php', + 'filename' => '_ide_helper', + 'format' => 'php', 'meta_filename' => '.phpstorm.meta.php', @@ -78,7 +78,7 @@ 'include_helpers' => false, 'helper_files' => [ - base_path().'/vendor/laravel/framework/src/Illuminate/Support/helpers.php', + base_path() . '/vendor/laravel/framework/src/Illuminate/Support/helpers.php', ], /* diff --git a/config/mail.php b/config/mail.php index c7960ef83..ae8270d55 100644 --- a/config/mail.php +++ b/config/mail.php @@ -69,7 +69,7 @@ 'array' => [ 'transport' => 'array', ], - + 'failover' => [ 'transport' => 'failover', 'mailers' => [ diff --git a/config/recaptcha.php b/config/recaptcha.php index 0c1e6476b..b7ba8ecdb 100644 --- a/config/recaptcha.php +++ b/config/recaptcha.php @@ -2,5 +2,5 @@ return [ 'secret_key' => env('RECAPTCHA_V3_SECRET_KEY', 'config/recaptcha.php: no-secret-key-set!'), - 'min_score' => env('RECAPTCHA_V3_MIN_SCORE', 0.5), + 'min_score' => env('RECAPTCHA_V3_MIN_SCORE', 0.5), ]; diff --git a/config/session.php b/config/session.php index 0a7158b0f..b139c4fc4 100644 --- a/config/session.php +++ b/config/session.php @@ -128,7 +128,7 @@ 'cookie' => env( 'SESSION_COOKIE', - Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + Str::slug(env('APP_NAME', 'laravel'), '_') . '_session' ), /* diff --git a/config/trustedproxy.php b/config/trustedproxy.php index 907830e31..b32778be9 100644 --- a/config/trustedproxy.php +++ b/config/trustedproxy.php @@ -6,12 +6,12 @@ explode(',', env('TRUSTED_PROXY_PROXIES', '')) ); switch (count($split)) { - case 0: - return null; - case 1: - return $split[0]; - default: - return $split; + case 0: + return null; + case 1: + return $split[0]; + default: + return $split; } })(), ]; diff --git a/database/factories/ComplaintRecordFactory.php b/database/factories/ComplaintRecordFactory.php index 90d8de135..c76f761f6 100644 --- a/database/factories/ComplaintRecordFactory.php +++ b/database/factories/ComplaintRecordFactory.php @@ -10,8 +10,7 @@ * * @extends \Illuminate\Database\Eloquent\Factories\Factory */ -class ComplaintRecordFactory extends Factory -{ +class ComplaintRecordFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -24,8 +23,7 @@ class ComplaintRecordFactory extends Factory * * @return array */ - public function definition(): array - { + public function definition(): array { return [ 'dispatched' => null, ]; diff --git a/database/factories/EventPageUpdateFactory.php b/database/factories/EventPageUpdateFactory.php index 8541338d2..948160547 100644 --- a/database/factories/EventPageUpdateFactory.php +++ b/database/factories/EventPageUpdateFactory.php @@ -5,8 +5,7 @@ use App\EventPageUpdate; use Illuminate\Database\Eloquent\Factories\Factory; -class EventPageUpdateFactory extends Factory -{ +class EventPageUpdateFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class EventPageUpdateFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/factories/InvitationFactory.php b/database/factories/InvitationFactory.php index 043499979..4928f0ebf 100644 --- a/database/factories/InvitationFactory.php +++ b/database/factories/InvitationFactory.php @@ -5,8 +5,7 @@ use App\Invitation; use Illuminate\Database\Eloquent\Factories\Factory; -class InvitationFactory extends Factory -{ +class InvitationFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,10 +18,9 @@ class InvitationFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return [ - 'code' => $this->faker->unique()->text(20) + 'code' => $this->faker->unique()->text(20), ]; } } diff --git a/database/factories/QsBatchFactory.php b/database/factories/QsBatchFactory.php index b1e2d2fe8..a05bc9630 100644 --- a/database/factories/QsBatchFactory.php +++ b/database/factories/QsBatchFactory.php @@ -5,8 +5,7 @@ use App\QsBatch; use Illuminate\Database\Eloquent\Factories\Factory; -class QsBatchFactory extends Factory -{ +class QsBatchFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class QsBatchFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/factories/QueryserviceNamespaceFactory.php b/database/factories/QueryserviceNamespaceFactory.php index 5eea64404..25bac17b6 100644 --- a/database/factories/QueryserviceNamespaceFactory.php +++ b/database/factories/QueryserviceNamespaceFactory.php @@ -5,8 +5,7 @@ use App\QueryserviceNamespace; use Illuminate\Database\Eloquent\Factories\Factory; -class QueryserviceNamespaceFactory extends Factory -{ +class QueryserviceNamespaceFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class QueryserviceNamespaceFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 8d2ef515c..b535d4b46 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -5,8 +5,7 @@ use App\User; use Illuminate\Database\Eloquent\Factories\Factory; -class UserFactory extends Factory -{ +class UserFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class UserFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return [ 'password' => $this->faker->password(), 'email' => $this->faker->unique()->safeEmail(), diff --git a/database/factories/WikSiteStatsFactory.php b/database/factories/WikSiteStatsFactory.php index 9e07a8d63..54462d5b0 100644 --- a/database/factories/WikSiteStatsFactory.php +++ b/database/factories/WikSiteStatsFactory.php @@ -5,8 +5,7 @@ use App\WikiSiteStats; use Illuminate\Database\Eloquent\Factories\Factory; -class WikiSiteStatsFactory extends Factory -{ +class WikiSiteStatsFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class WikiSiteStatsFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/factories/WikiDbFactory.php b/database/factories/WikiDbFactory.php index 5c6dc0b66..95344ba46 100644 --- a/database/factories/WikiDbFactory.php +++ b/database/factories/WikiDbFactory.php @@ -2,11 +2,10 @@ namespace Database\Factories; -use Illuminate\Database\Eloquent\Factories\Factory; use App\WikiDb; +use Illuminate\Database\Eloquent\Factories\Factory; -class WikiDbFactory extends Factory -{ +class WikiDbFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,14 +18,13 @@ class WikiDbFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return [ 'name' => $this->faker->unique()->text(5), 'prefix' => $this->faker->unique()->text(5), 'user' => 'root', 'password' => 'toor', - 'version' => 'seeded' + 'version' => 'seeded', ]; } } diff --git a/database/factories/WikiEntityImportFactory.php b/database/factories/WikiEntityImportFactory.php index 4809dc204..124b02b53 100644 --- a/database/factories/WikiEntityImportFactory.php +++ b/database/factories/WikiEntityImportFactory.php @@ -5,8 +5,7 @@ use App\WikiEntityImport; use Illuminate\Database\Eloquent\Factories\Factory; -class WikiEntityImportFactory extends Factory -{ +class WikiEntityImportFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class WikiEntityImportFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/factories/WikiFactory.php b/database/factories/WikiFactory.php index 212700076..09367f0a6 100644 --- a/database/factories/WikiFactory.php +++ b/database/factories/WikiFactory.php @@ -5,8 +5,7 @@ use App\Wiki; use Illuminate\Database\Eloquent\Factories\Factory; -class WikiFactory extends Factory -{ +class WikiFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class WikiFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { $sitename = $this->faker->unique()->text(30); $sitename = strtolower($sitename); $sitename = str_replace(' ', '_', $sitename); diff --git a/database/factories/WikiLifecycleEventsFactory.php b/database/factories/WikiLifecycleEventsFactory.php index 84c604782..8301e4d82 100644 --- a/database/factories/WikiLifecycleEventsFactory.php +++ b/database/factories/WikiLifecycleEventsFactory.php @@ -5,8 +5,7 @@ use App\WikiLifecycleEvents; use Illuminate\Database\Eloquent\Factories\Factory; -class WikiLifecycleEventsFactory extends Factory -{ +class WikiLifecycleEventsFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class WikiLifecycleEventsFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/factories/WikiManagerFactory.php b/database/factories/WikiManagerFactory.php index fe023645f..7a1f984a7 100644 --- a/database/factories/WikiManagerFactory.php +++ b/database/factories/WikiManagerFactory.php @@ -5,8 +5,7 @@ use App\WikiManager; use Illuminate\Database\Eloquent\Factories\Factory; -class WikiManagerFactory extends Factory -{ +class WikiManagerFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,11 +18,10 @@ class WikiManagerFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return [ 'user_id' => $this->faker->unique()->randomNumber(), - 'wiki_id' => $this->faker->unique()->randomNumber() + 'wiki_id' => $this->faker->unique()->randomNumber(), ]; } } diff --git a/database/factories/WikiNotificationSentRecordFactory.php b/database/factories/WikiNotificationSentRecordFactory.php index ab17d1988..b1efd6311 100644 --- a/database/factories/WikiNotificationSentRecordFactory.php +++ b/database/factories/WikiNotificationSentRecordFactory.php @@ -2,12 +2,10 @@ namespace Database\Factories; -use App\Notifications\EmptyWikiNotification; use App\WikiNotificationSentRecord; use Illuminate\Database\Eloquent\Factories\Factory; -class WikiNotificationSentRecordFactory extends Factory -{ +class WikiNotificationSentRecordFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -20,8 +18,7 @@ class WikiNotificationSentRecordFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/factories/WikiSettingFactory.php b/database/factories/WikiSettingFactory.php index f13615a62..6322b1163 100644 --- a/database/factories/WikiSettingFactory.php +++ b/database/factories/WikiSettingFactory.php @@ -5,8 +5,7 @@ use App\WikiSetting; use Illuminate\Database\Eloquent\Factories\Factory; -class WikiSettingFactory extends Factory -{ +class WikiSettingFactory extends Factory { /** * The name of the factory's corresponding model. * @@ -19,8 +18,7 @@ class WikiSettingFactory extends Factory * * @return array */ - public function definition() - { + public function definition() { return []; } } diff --git a/database/migrations/2018_11_17_124956_create_users_table.php b/database/migrations/2018_11_17_124956_create_users_table.php index 92eb73432..05c0d827f 100644 --- a/database/migrations/2018_11_17_124956_create_users_table.php +++ b/database/migrations/2018_11_17_124956_create_users_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateUsersTable extends Migration -{ +class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('email')->unique(); @@ -29,8 +27,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('users'); } } diff --git a/database/migrations/2018_11_17_133622_create_wiki_dbs_table.php b/database/migrations/2018_11_17_133622_create_wiki_dbs_table.php index 5802c8a0c..dcc5218bb 100644 --- a/database/migrations/2018_11_17_133622_create_wiki_dbs_table.php +++ b/database/migrations/2018_11_17_133622_create_wiki_dbs_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateWikidbsTable extends Migration -{ +class CreateWikidbsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('wiki_dbs', function (Blueprint $table) { $table->increments('id'); @@ -39,8 +37,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wiki_dbs'); } } diff --git a/database/migrations/2018_11_17_133627_create_wikis_table.php b/database/migrations/2018_11_17_133627_create_wikis_table.php index 3f98d48fb..f10d8f299 100644 --- a/database/migrations/2018_11_17_133627_create_wikis_table.php +++ b/database/migrations/2018_11_17_133627_create_wikis_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateWikisTable extends Migration -{ +class CreateWikisTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('wikis', function (Blueprint $table) { $table->increments('id'); @@ -29,8 +27,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wikis'); } } diff --git a/database/migrations/2019_08_14_111000_create_invitations_table.php b/database/migrations/2019_08_14_111000_create_invitations_table.php index ca912c7bf..8cd54d833 100644 --- a/database/migrations/2019_08_14_111000_create_invitations_table.php +++ b/database/migrations/2019_08_14_111000_create_invitations_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateInvitationsTable extends Migration -{ +class CreateInvitationsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('invitations', function (Blueprint $table) { $table->increments('id'); $table->string('code')->unique(); @@ -25,8 +23,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('invitations'); } } diff --git a/database/migrations/2019_08_14_155900_create_wiki_managers_table.php b/database/migrations/2019_08_14_155900_create_wiki_managers_table.php index b4fb938d4..ccd862889 100644 --- a/database/migrations/2019_08_14_155900_create_wiki_managers_table.php +++ b/database/migrations/2019_08_14_155900_create_wiki_managers_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateWikiManagersTable extends Migration -{ +class CreateWikiManagersTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('wiki_managers', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); @@ -27,8 +25,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wiki_managers'); } } diff --git a/database/migrations/2019_08_19_225500_create_user_verification_tokens_table.php b/database/migrations/2019_08_19_225500_create_user_verification_tokens_table.php index dc9dbfc78..00e35526e 100644 --- a/database/migrations/2019_08_19_225500_create_user_verification_tokens_table.php +++ b/database/migrations/2019_08_19_225500_create_user_verification_tokens_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateUserVerificationTokensTable extends Migration -{ +class CreateUserVerificationTokensTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('user_verification_tokens', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); @@ -26,8 +24,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('user_verification_tokens'); } } diff --git a/database/migrations/2019_08_31_163057_create_failed_jobs_table.php b/database/migrations/2019_08_31_163057_create_failed_jobs_table.php index 389bdf768..a33022953 100644 --- a/database/migrations/2019_08_31_163057_create_failed_jobs_table.php +++ b/database/migrations/2019_08_31_163057_create_failed_jobs_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateFailedJobsTable extends Migration -{ +class CreateFailedJobsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('failed_jobs', function (Blueprint $table) { $table->bigIncrements('id'); $table->text('connection'); @@ -28,8 +26,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('failed_jobs'); } } diff --git a/database/migrations/2019_09_02_000000_create_wiki_domains_table.php b/database/migrations/2019_09_02_000000_create_wiki_domains_table.php index 9a2501c7b..874b4117d 100644 --- a/database/migrations/2019_09_02_000000_create_wiki_domains_table.php +++ b/database/migrations/2019_09_02_000000_create_wiki_domains_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateWikiDomainsTable extends Migration -{ +class CreateWikiDomainsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('wiki_domains', function (Blueprint $table) { $table->increments('id'); @@ -30,8 +28,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wiki_domains'); } } diff --git a/database/migrations/2019_10_18_170700_create_queryservice_namespaces_table.php b/database/migrations/2019_10_18_170700_create_queryservice_namespaces_table.php index c5cca3dae..2b5ac78bd 100644 --- a/database/migrations/2019_10_18_170700_create_queryservice_namespaces_table.php +++ b/database/migrations/2019_10_18_170700_create_queryservice_namespaces_table.php @@ -4,20 +4,18 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateQueryservicenamespacesTable extends Migration -{ +class CreateQueryservicenamespacesTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('queryservice_namespaces', function (Blueprint $table) { $table->increments('id'); $table->string('namespace', 100)->unique(); - //$table->string('internalHost', 100)->unique(); + // $table->string('internalHost', 100)->unique(); $table->string('backend', 100); $table->integer('wiki_id')->nullable()->unsigned()->unique(); @@ -31,8 +29,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('queryservice_namespaces'); } } diff --git a/database/migrations/2019_10_19_164400_create_wiki_settings_table.php b/database/migrations/2019_10_19_164400_create_wiki_settings_table.php index 8b4d583d0..2807f4f8b 100644 --- a/database/migrations/2019_10_19_164400_create_wiki_settings_table.php +++ b/database/migrations/2019_10_19_164400_create_wiki_settings_table.php @@ -4,10 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateWikiSettingsTable extends Migration -{ - public function up() - { +class CreateWikiSettingsTable extends Migration { + public function up() { Schema::create('wiki_settings', function (Blueprint $table) { $table->increments('id'); $table->string('name', 100); @@ -26,8 +24,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wiki_settings'); } } diff --git a/database/migrations/2019_10_20_004100_create_event_page_updates_table.php b/database/migrations/2019_10_20_004100_create_event_page_updates_table.php index 70c29cc62..65813872e 100644 --- a/database/migrations/2019_10_20_004100_create_event_page_updates_table.php +++ b/database/migrations/2019_10_20_004100_create_event_page_updates_table.php @@ -4,10 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateEventPageUpdatesTable extends Migration -{ - public function up() - { +class CreateEventPageUpdatesTable extends Migration { + public function up() { Schema::create('event_page_updates', function (Blueprint $table) { $table->increments('id'); $table->integer('wiki_id'); @@ -24,8 +22,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('event_page_updates'); } } diff --git a/database/migrations/2019_10_20_101600_create_qs_batches_table.php b/database/migrations/2019_10_20_101600_create_qs_batches_table.php index 49ae5be3a..e3c8918e6 100644 --- a/database/migrations/2019_10_20_101600_create_qs_batches_table.php +++ b/database/migrations/2019_10_20_101600_create_qs_batches_table.php @@ -4,10 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateQsBatchesTable extends Migration -{ - public function up() - { +class CreateQsBatchesTable extends Migration { + public function up() { Schema::create('qs_batches', function (Blueprint $table) { $table->increments('id'); $table->integer('eventFrom'); @@ -22,8 +20,7 @@ public function up() }); } - public function down() - { + public function down() { Schema::dropIfExists('qs_batches'); } } diff --git a/database/migrations/2020_04_06_173300_create_password_resets_table.php b/database/migrations/2020_04_06_173300_create_password_resets_table.php index dea51494b..5b37e2464 100644 --- a/database/migrations/2020_04_06_173300_create_password_resets_table.php +++ b/database/migrations/2020_04_06_173300_create_password_resets_table.php @@ -8,15 +8,13 @@ * Taken from https://laracasts.com/discuss/channels/laravel/artisan-migrate-password-reset-table * as I couldn't find it anywhere else, the schema looks fine... */ -class CreatePasswordResetsTable extends Migration -{ +class CreatePasswordResetsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('password_resets', function (Blueprint $table) { $table->string('email')->index(); $table->string('token')->index(); @@ -29,8 +27,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::drop('password_resets'); } } diff --git a/database/migrations/2020_12_08_192540_drop_interests_table.php b/database/migrations/2020_12_08_192540_drop_interests_table.php index c85d17210..1d76ae6de 100644 --- a/database/migrations/2020_12_08_192540_drop_interests_table.php +++ b/database/migrations/2020_12_08_192540_drop_interests_table.php @@ -3,15 +3,12 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Support\Facades\Schema; -class DropInterestsTable extends Migration -{ - public function up() - { +class DropInterestsTable extends Migration { + public function up() { Schema::dropIfExists('interests'); } - public function down() - { + public function down() { // Do nothing } } diff --git a/database/migrations/2021_03_23_134722_modify_wiki_settings_value_length.php b/database/migrations/2021_03_23_134722_modify_wiki_settings_value_length.php index 289981434..b590a09eb 100644 --- a/database/migrations/2021_03_23_134722_modify_wiki_settings_value_length.php +++ b/database/migrations/2021_03_23_134722_modify_wiki_settings_value_length.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class ModifyWikiSettingsValueLength extends Migration -{ +class ModifyWikiSettingsValueLength extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::table('wiki_settings', function (Blueprint $table) { $table->text('value')->change(); }); @@ -23,8 +21,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::table('wiki_settings', function (Blueprint $table) { $table->string('value', 200)->change(); }); diff --git a/database/migrations/2021_03_27_134722_modify_oauth_clients_secret_nullable.php b/database/migrations/2021_03_27_134722_modify_oauth_clients_secret_nullable.php index 97e5e3dd2..a2149cc19 100644 --- a/database/migrations/2021_03_27_134722_modify_oauth_clients_secret_nullable.php +++ b/database/migrations/2021_03_27_134722_modify_oauth_clients_secret_nullable.php @@ -8,17 +8,14 @@ * For passport public clients, not that we are using this feature right now... * https://github.com/laravel/passport/blob/66b9088993f1be9a4a95129b61dca951e04223ff/UPGRADE.md#public-clients. */ -class ModifyOauthClientsSecretNullable extends Migration -{ - public function up() - { +class ModifyOauthClientsSecretNullable extends Migration { + public function up() { Schema::table('oauth_clients', function (Blueprint $table) { $table->string('secret', 100)->nullable()->change(); }); } - public function down() - { + public function down() { Schema::table('oauth_clients', function (Blueprint $table) { $table->string('secret', 100)->nullable(false)->change(); }); diff --git a/database/migrations/2021_03_27_194100_modify_oauth_clients_provider.php b/database/migrations/2021_03_27_194100_modify_oauth_clients_provider.php index ce8b27c2e..366b63a6b 100644 --- a/database/migrations/2021_03_27_194100_modify_oauth_clients_provider.php +++ b/database/migrations/2021_03_27_194100_modify_oauth_clients_provider.php @@ -11,19 +11,16 @@ * * As of writing this, this feature is not yet being turned on! */ -class ModifyOauthClientsProvider extends Migration -{ - public function up() - { - if (! Schema::hasColumn('oauth_clients', 'provider')) { +class ModifyOauthClientsProvider extends Migration { + public function up() { + if (!Schema::hasColumn('oauth_clients', 'provider')) { Schema::table('oauth_clients', function (Blueprint $table) { $table->string('provider')->after('secret')->nullable(); }); } } - public function down() - { + public function down() { Schema::table('oauth_clients', function ($table) { $table->dropColumn('provider'); }); diff --git a/database/migrations/2023_08_21_095824_create_wiki_site_stats_table.php b/database/migrations/2023_08_21_095824_create_wiki_site_stats_table.php index 712e44504..d9a4998ad 100644 --- a/database/migrations/2023_08_21_095824_create_wiki_site_stats_table.php +++ b/database/migrations/2023_08_21_095824_create_wiki_site_stats_table.php @@ -1,21 +1,16 @@ id(); @@ -46,8 +41,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wiki_site_stats'); Schema::dropColumns('wikis', ['description', 'is_featured']); } diff --git a/database/migrations/2023_08_29_145247_create_job_batches_table.php b/database/migrations/2023_08_29_145247_create_job_batches_table.php index be09cd5eb..8b858e013 100644 --- a/database/migrations/2023_08_29_145247_create_job_batches_table.php +++ b/database/migrations/2023_08_29_145247_create_job_batches_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateJobBatchesTable extends Migration -{ +class CreateJobBatchesTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('job_batches', function (Blueprint $table) { $table->string('id')->primary(); $table->string('name'); @@ -32,8 +30,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('job_batches'); } } diff --git a/database/migrations/2023_09_19_094751_create_wiki_lifecycle_events_table.php b/database/migrations/2023_09_19_094751_create_wiki_lifecycle_events_table.php index 4843d8729..28cf70c50 100644 --- a/database/migrations/2023_09_19_094751_create_wiki_lifecycle_events_table.php +++ b/database/migrations/2023_09_19_094751_create_wiki_lifecycle_events_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateWikiLifecycleEventsTable extends Migration -{ +class CreateWikiLifecycleEventsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('wiki_lifecycle_events', function (Blueprint $table) { $table->id(); $table->timestamps(); @@ -29,8 +27,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wiki_lifecycle_events'); } } diff --git a/database/migrations/2023_10_25_153643_qs_batches_add_pending_column.php b/database/migrations/2023_10_25_153643_qs_batches_add_pending_column.php index e21d2c11d..b986bf1ac 100644 --- a/database/migrations/2023_10_25_153643_qs_batches_add_pending_column.php +++ b/database/migrations/2023_10_25_153643_qs_batches_add_pending_column.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class QsBatchesAddPendingColumn extends Migration -{ +class QsBatchesAddPendingColumn extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::table('qs_batches', function (Blueprint $table) { $table->timestampTz('pending_since')->nullable()->default(null); $table->unsignedInteger('processing_attempts')->default(0); @@ -25,8 +23,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::table('qs_batches', function (Blueprint $table) { $table->dropColumn('pending_since'); $table->dropColumn('processing_attempts'); diff --git a/database/migrations/2023_10_31_204320_create_wiki_notification_sent_records_table.php b/database/migrations/2023_10_31_204320_create_wiki_notification_sent_records_table.php index cbdbf95ac..e3f87c95d 100644 --- a/database/migrations/2023_10_31_204320_create_wiki_notification_sent_records_table.php +++ b/database/migrations/2023_10_31_204320_create_wiki_notification_sent_records_table.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateWikiNotificationSentRecordsTable extends Migration -{ +class CreateWikiNotificationSentRecordsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('wiki_notification_sent_records', function (Blueprint $table) { $table->foreign('wiki_id')->references('id')->on('wikis'); @@ -31,8 +29,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('wiki_notification_sent_records'); } } diff --git a/database/migrations/2023_11_06_084718_event_page_update_title_length.php b/database/migrations/2023_11_06_084718_event_page_update_title_length.php index 58258c39d..2243f8e3f 100644 --- a/database/migrations/2023_11_06_084718_event_page_update_title_length.php +++ b/database/migrations/2023_11_06_084718_event_page_update_title_length.php @@ -1,19 +1,17 @@ text('title')->change(); }); @@ -24,8 +22,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { EventPageUpdate::query()->get()->each(function (EventPageUpdate $eventPageUpdate) { $eventPageUpdate->update(['title' => substr($eventPageUpdate->title, 0, 14)]); }); diff --git a/database/migrations/2023_11_21_091331_create_qs_checkpoints_table.php b/database/migrations/2023_11_21_091331_create_qs_checkpoints_table.php index bb520dd3a..70b51f9af 100644 --- a/database/migrations/2023_11_21_091331_create_qs_checkpoints_table.php +++ b/database/migrations/2023_11_21_091331_create_qs_checkpoints_table.php @@ -5,15 +5,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateQsCheckpointsTable extends Migration -{ +class CreateQsCheckpointsTable extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::create('qs_checkpoints', function (Blueprint $table) { // This does not use the `id` method as it would mean we // get auto-increment, which is not what we want in this case @@ -35,8 +33,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { Schema::dropIfExists('qs_checkpoints'); Schema::table('qs_batches', function (Blueprint $table) { diff --git a/database/migrations/2024_04_16_165700_enforce_site_stats_constraint.php b/database/migrations/2024_04_16_165700_enforce_site_stats_constraint.php index 338cb5022..33e428dd3 100644 --- a/database/migrations/2024_04_16_165700_enforce_site_stats_constraint.php +++ b/database/migrations/2024_04_16_165700_enforce_site_stats_constraint.php @@ -4,15 +4,13 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class EnforceSiteStatsConstraint extends Migration -{ +class EnforceSiteStatsConstraint extends Migration { /** * Run the migrations. * * @return void */ - public function up() - { + public function up() { Schema::table('wiki_site_stats', function (Blueprint $table) { $table->unique('wiki_id'); }); @@ -23,8 +21,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { // foreign key constraints need to be disabled as per https://github.com/laravel/framework/issues/13873 Schema::disableForeignKeyConstraints(); Schema::table('wiki_site_stats', function (Blueprint $table) { diff --git a/database/migrations/2024_05_15_042959_add_admin_role_to_users.php b/database/migrations/2024_05_15_042959_add_admin_role_to_users.php index 5e647db6a..bc3130791 100644 --- a/database/migrations/2024_05_15_042959_add_admin_role_to_users.php +++ b/database/migrations/2024_05_15_042959_add_admin_role_to_users.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { // is_admin is 0 for plain users and an integer > 0 for admins Schema::table('users', function (Blueprint $table) { $table->integer('is_admin')->default(false); @@ -20,8 +18,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { Schema::table('users', function (Blueprint $table) { $table->dropColumn('is_admin'); }); diff --git a/database/migrations/2024_05_15_043447_add_wiki_deletion_reason.php b/database/migrations/2024_05_15_043447_add_wiki_deletion_reason.php index bf1810929..2f8cdd6d3 100644 --- a/database/migrations/2024_05_15_043447_add_wiki_deletion_reason.php +++ b/database/migrations/2024_05_15_043447_add_wiki_deletion_reason.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { Schema::table('wikis', function (Blueprint $table) { $table->string('wiki_deletion_reason')->nullable(); }); @@ -19,8 +17,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { Schema::table('wikis', function (Blueprint $table) { $table->dropColumn('wiki_deletion_reason'); }); diff --git a/database/migrations/2024_06_19_110900_enforce_lifecycle_events_constraint.php b/database/migrations/2024_06_19_110900_enforce_lifecycle_events_constraint.php index 385cfcdb8..34f52e0cc 100644 --- a/database/migrations/2024_06_19_110900_enforce_lifecycle_events_constraint.php +++ b/database/migrations/2024_06_19_110900_enforce_lifecycle_events_constraint.php @@ -1,20 +1,18 @@ get(); // Albeit `createOrUpdate` was used when creating lifecycle events // was used, multiple copies per wiki were created. To clean up before @@ -41,8 +39,7 @@ public function up() * * @return void */ - public function down() - { + public function down() { // foreign key constraints need to be disabled as per https://github.com/laravel/framework/issues/13873 Schema::disableForeignKeyConstraints(); Schema::table('wiki_lifecycle_events', function (Blueprint $table) { diff --git a/database/migrations/2024_06_24_074114_create_wiki_entity_imports_table.php b/database/migrations/2024_06_24_074114_create_wiki_entity_imports_table.php index bcd5e5964..7ac6b391e 100644 --- a/database/migrations/2024_06_24_074114_create_wiki_entity_imports_table.php +++ b/database/migrations/2024_06_24_074114_create_wiki_entity_imports_table.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { Schema::create('wiki_entity_imports', function (Blueprint $table) { $table->id(); $table->timestamps(); @@ -28,8 +26,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { Schema::dropIfExists('wiki_entity_imports'); } }; diff --git a/database/migrations/2024_08_01_193038_remove_and_rebuild_wiki_lifecycle_events.php b/database/migrations/2024_08_01_193038_remove_and_rebuild_wiki_lifecycle_events.php index 6b660d844..b4d24df4d 100644 --- a/database/migrations/2024_08_01_193038_remove_and_rebuild_wiki_lifecycle_events.php +++ b/database/migrations/2024_08_01_193038_remove_and_rebuild_wiki_lifecycle_events.php @@ -4,13 +4,11 @@ use App\WikiLifecycleEvents; use Illuminate\Database\Migrations\Migration; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { WikiLifecycleEvents::query()->delete(); UpdateWikiSiteStatsJob::dispatch(); } @@ -18,8 +16,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { // } }; diff --git a/database/migrations/2025_01_28_144045_wiki_daily_metric.php b/database/migrations/2025_01_28_144045_wiki_daily_metric.php index c4fb30807..c4ce36b08 100755 --- a/database/migrations/2025_01_28_144045_wiki_daily_metric.php +++ b/database/migrations/2025_01_28_144045_wiki_daily_metric.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { Schema::create('wiki_daily_metrics', function (Blueprint $table) { $table->string('id')->primary(); $table->string('wiki_id'); @@ -25,8 +23,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { - Schema::dropIfExists('wiki_daily_metrics'); + public function down(): void { + Schema::dropIfExists('wiki_daily_metrics'); } }; diff --git a/database/migrations/2025_03_14_220054_create_wiki_profiles_table.php b/database/migrations/2025_03_14_220054_create_wiki_profiles_table.php index 3e37c30db..f61e54f44 100644 --- a/database/migrations/2025_03_14_220054_create_wiki_profiles_table.php +++ b/database/migrations/2025_03_14_220054_create_wiki_profiles_table.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { Schema::create('wiki_profiles', function (Blueprint $table) { $table->id(); $table->unsignedInteger('wiki_id'); @@ -28,8 +26,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { Schema::dropIfExists('wiki_profiles'); } }; diff --git a/database/migrations/2025_03_24_143626_add_columns_to_wiki_daily_metric_table.php b/database/migrations/2025_03_24_143626_add_columns_to_wiki_daily_metric_table.php index 332733e5a..34d0dd1ac 100644 --- a/database/migrations/2025_03_24_143626_add_columns_to_wiki_daily_metric_table.php +++ b/database/migrations/2025_03_24_143626_add_columns_to_wiki_daily_metric_table.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { Schema::table('wiki_daily_metrics', function (Blueprint $table) { $table->integer('daily_actions')->nullable(); $table->integer('weekly_actions')->nullable(); @@ -22,9 +20,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { - Schema::table('wiki_daily_metric', function (Blueprint $table) { - }); + public function down(): void { + Schema::table('wiki_daily_metric', function (Blueprint $table) {}); } }; diff --git a/database/migrations/2025_03_25_085142_wiki_profiles_audience_nullable.php b/database/migrations/2025_03_25_085142_wiki_profiles_audience_nullable.php index bc929b2fd..a9081dc5d 100644 --- a/database/migrations/2025_03_25_085142_wiki_profiles_audience_nullable.php +++ b/database/migrations/2025_03_25_085142_wiki_profiles_audience_nullable.php @@ -1,17 +1,13 @@ integer('number_of_triples')->nullable()->default(null); }); @@ -19,8 +17,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { Schema::table('wiki_daily_metrics', function (Blueprint $table) { $table->dropColumn('number_of_triples'); }); diff --git a/database/migrations/2025_05_19_142457_add_monthly_user_count_to_wiki_daily_metrics_table.php b/database/migrations/2025_05_19_142457_add_monthly_user_count_to_wiki_daily_metrics_table.php index c2e749f11..2b257f21c 100755 --- a/database/migrations/2025_05_19_142457_add_monthly_user_count_to_wiki_daily_metrics_table.php +++ b/database/migrations/2025_05_19_142457_add_monthly_user_count_to_wiki_daily_metrics_table.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { Schema::table('wiki_daily_metrics', function (Blueprint $table) { $table->integer('monthly_casual_users')->nullable(); $table->integer('monthly_active_users')->nullable(); @@ -20,8 +18,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { Schema::table('wiki_daily_metrics', function (Blueprint $table) { $table->dropColumn('monthly_casual_users'); $table->dropColumn('monthly_active_users'); diff --git a/database/migrations/2025_07_18_103841_create_complaint_records_table.php b/database/migrations/2025_07_18_103841_create_complaint_records_table.php index 44f4f8219..5e1e5cfee 100644 --- a/database/migrations/2025_07_18_103841_create_complaint_records_table.php +++ b/database/migrations/2025_07_18_103841_create_complaint_records_table.php @@ -4,13 +4,11 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ - public function up(): void - { + public function up(): void { Schema::create('complaint_records', function (Blueprint $table) { $table->id(); $table->timestamps(); @@ -25,8 +23,7 @@ public function up(): void /** * Reverse the migrations. */ - public function down(): void - { + public function down(): void { Schema::dropIfExists('complaint_records'); } }; diff --git a/database/mw/cleanSql.php b/database/mw/cleanSql.php index 2ac366fed..547c4a5e5 100644 --- a/database/mw/cleanSql.php +++ b/database/mw/cleanSql.php @@ -6,7 +6,7 @@ // TODO allow passing in file? or run for all files? $placeholder = '<>_'; -$filename = __DIR__.'/new/mw1.39-wbs1.sql'; +$filename = __DIR__ . '/new/mw1.39-wbs1.sql'; // Get the file $text = file_get_contents($filename); @@ -19,15 +19,15 @@ // Add new placeholders and space out the statements $replacementPrefixes = [ - 'CREATE TABLE `', - 'INSERT INTO `', - 'REPLACE INTO `', + 'CREATE TABLE `', + 'INSERT INTO `', + 'REPLACE INTO `', ]; foreach ($replacementPrefixes as $prefix) { - $text = str_replace($prefix, "\n".$prefix.$placeholder, $text); + $text = str_replace($prefix, "\n" . $prefix . $placeholder, $text); } // Write the file file_put_contents($filename, $text); -echo 'Done!'.PHP_EOL; +echo 'Done!' . PHP_EOL; diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 2cefe6af1..89690c689 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -7,10 +7,8 @@ * When new seeders are added to this class it is likely that you will need to run composer dump-autoload * as these classes are currently loaded in a class map (not PSR). */ -class DatabaseSeeder extends Seeder -{ - public function run() - { +class DatabaseSeeder extends Seeder { + public function run() { Model::unguard(); $this->call(UsersSeeder::class); $this->call(InvitationsSeeder::class); diff --git a/database/seeds/InvitationsSeeder.php b/database/seeds/InvitationsSeeder.php index 0e2ad5d4e..582c25dd7 100644 --- a/database/seeds/InvitationsSeeder.php +++ b/database/seeds/InvitationsSeeder.php @@ -3,13 +3,11 @@ use App\Invitation; use Illuminate\Database\Seeder; -class InvitationsSeeder extends Seeder -{ - public function run() - { +class InvitationsSeeder extends Seeder { + public function run() { Invitation::create(['code' => 'invite1']); Invitation::create(['code' => 'invite2']); Invitation::create(['code' => 'invite3']); App\Invitation::factory()->create(); } -} \ No newline at end of file +} diff --git a/database/seeds/QueryserviceNamespacesSeeder.php b/database/seeds/QueryserviceNamespacesSeeder.php index 47b346f45..20a5972ab 100644 --- a/database/seeds/QueryserviceNamespacesSeeder.php +++ b/database/seeds/QueryserviceNamespacesSeeder.php @@ -3,20 +3,17 @@ use App\QueryserviceNamespace; use Illuminate\Database\Seeder; -class QueryserviceNamespacesSeeder extends Seeder -{ - public function run() - { +class QueryserviceNamespacesSeeder extends Seeder { + public function run() { QueryserviceNamespace::create($this->getCreateArray(1)); QueryserviceNamespace::create($this->getCreateArray(2)); QueryserviceNamespace::create($this->getCreateArray(3)); QueryserviceNamespace::create($this->getCreateArray(4)); } - private function getCreateArray($index) - { + private function getCreateArray($index) { return [ - 'namespace' => 'qsnamespace'.$index, + 'namespace' => 'qsnamespace' . $index, 'backend' => 'someQueryserviceBackend', ]; } diff --git a/database/seeds/UsersSeeder.php b/database/seeds/UsersSeeder.php index 34c762d76..d66b38e65 100644 --- a/database/seeds/UsersSeeder.php +++ b/database/seeds/UsersSeeder.php @@ -4,24 +4,22 @@ use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Hash; -class UsersSeeder extends Seeder -{ - public function run() - { +class UsersSeeder extends Seeder { + public function run() { User::create([ - 'email' => 'adamshorland@gmail.com', - 'password' => Hash::make('a'), - 'verified' => true, + 'email' => 'adamshorland@gmail.com', + 'password' => Hash::make('a'), + 'verified' => true, ]); User::create([ - 'email' => 'a@a.a', - 'password' => Hash::make('a'), - 'verified' => true, + 'email' => 'a@a.a', + 'password' => Hash::make('a'), + 'verified' => true, ]); User::create([ - 'email' => 'b@b.b', - 'password' => Hash::make('b'), - 'verified' => false, + 'email' => 'b@b.b', + 'password' => Hash::make('b'), + 'verified' => false, ]); // create 10 users using the user factory App\User::factory()->create(); diff --git a/database/seeds/WikiDbsSeeder.php b/database/seeds/WikiDbsSeeder.php index 9f8ccbfb0..92b1fc295 100644 --- a/database/seeds/WikiDbsSeeder.php +++ b/database/seeds/WikiDbsSeeder.php @@ -4,24 +4,21 @@ use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Config; -class WikiDbsSeeder extends Seeder -{ - public function run() - { +class WikiDbsSeeder extends Seeder { + public function run() { WikiDb::create($this->getCreateArray(1)); WikiDb::create($this->getCreateArray(2)); WikiDb::create($this->getCreateArray(3)); WikiDb::create($this->getCreateArray(4)); } - private function getCreateArray($index) - { + private function getCreateArray($index) { return [ - 'name' => 'dbname'.$index, - 'user' => 'dbuser'.$index, - 'password' => 'dbpassword'.$index, + 'name' => 'dbname' . $index, + 'user' => 'dbuser' . $index, + 'password' => 'dbpassword' . $index, 'version' => Config::get('wbstack.wiki_db_use_version'), - 'prefix' => 'dbprefix'.$index, + 'prefix' => 'dbprefix' . $index, ]; } } diff --git a/database/seeds/WikisSeeder.php b/database/seeds/WikisSeeder.php index ba441c33b..10d77d0f3 100644 --- a/database/seeds/WikisSeeder.php +++ b/database/seeds/WikisSeeder.php @@ -13,25 +13,23 @@ use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; -class WikisSeeder extends Seeder -{ +class WikisSeeder extends Seeder { /** - * @param \App\User $user - * @param string $name - * @param array $stats + * @param \App\User $user + * @param string $name + * @param array $stats */ - private function createWiki($user, $name, $stats) - { + private function createWiki($user, $name, $stats) { $domain = $name . '.nodomain.example'; $wiki = Wiki::create([ 'sitename' => $name, - 'domain' => $domain + 'domain' => $domain, ]); WikiDomain::create([ 'domain' => $domain, - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); $index = substr(bin2hex(random_bytes(48)), 0, 10); @@ -42,48 +40,47 @@ private function createWiki($user, $name, $stats) 'password' => $index, 'version' => Config::get('wbstack.wiki_db_use_version'), 'prefix' => 'mwt_' . $index, - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); QueryserviceNamespace::create([ 'namespace' => 'qsns_' . $index, 'backend' => 'someQueryserviceBackend', - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); WikiSetting::create([ 'name' => 'wgSecretKey', 'value' => Str::random(64), - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); WikiSetting::create([ 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true, - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); WikiManager::create([ 'user_id' => $user->id, - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); WikiSiteStats::create( - array_merge($stats, [ 'wiki_id' => $wiki->id ]) + array_merge($stats, ['wiki_id' => $wiki->id]) ); } - public function run() - { + public function run() { $email = 'seeder@email.example'; $user = User::create([ 'email' => $email, 'password' => Hash::make($email), - 'verified' => true + 'verified' => true, ]); for ($id = 0; $id < 50; $id++) { - $this->createWiki($user, 'seededsite-' . $id, [ 'pages' => $id ]); + $this->createWiki($user, 'seededsite-' . $id, ['pages' => $id]); } } } diff --git a/pint.json b/pint.json new file mode 100644 index 000000000..e68a90147 --- /dev/null +++ b/pint.json @@ -0,0 +1,19 @@ +{ + "preset": "laravel", + "rules": { + "php_unit_method_casing": { + "case": "camel_case" + }, + "braces_position": { + "anonymous_classes_opening_brace": "same_line", + "anonymous_functions_opening_brace": "same_line", + "classes_opening_brace": "same_line", + "control_structures_opening_brace": "same_line", + "functions_opening_brace": "same_line" + }, + "concat_space": { + "spacing": "one" + }, + "not_operator_with_successor_space": false + } +} diff --git a/public/index.php b/public/index.php index 4584cbcd6..5eea7add1 100644 --- a/public/index.php +++ b/public/index.php @@ -3,10 +3,8 @@ /** * Laravel - A PHP Framework For Web Artisans * - * @package Laravel * @author Taylor Otwell */ - define('LARAVEL_START', microtime(true)); /* @@ -21,7 +19,7 @@ | */ -require __DIR__.'/../vendor/autoload.php'; +require __DIR__ . '/../vendor/autoload.php'; /* |-------------------------------------------------------------------------- @@ -35,7 +33,7 @@ | */ -$app = require_once __DIR__.'/../bootstrap/app.php'; +$app = require_once __DIR__ . '/../bootstrap/app.php'; /* |-------------------------------------------------------------------------- diff --git a/resources/lang/en/contact.php b/resources/lang/en/contact.php index c3eb58dd7..e1351b8f1 100644 --- a/resources/lang/en/contact.php +++ b/resources/lang/en/contact.php @@ -13,10 +13,10 @@ | */ - 'general-question' => 'General question', - 'feature-request' => 'Feature request', - 'report-a-problem' => 'Report a problem', - 'give-feedback' => 'Give feedback', - 'other' => 'Other', + 'general-question' => 'General question', + 'feature-request' => 'Feature request', + 'report-a-problem' => 'Report a problem', + 'give-feedback' => 'Give feedback', + 'other' => 'Other', ]; diff --git a/routes/api.php b/routes/api.php index 17f2bdce8..784de83fe 100644 --- a/routes/api.php +++ b/routes/api.php @@ -6,13 +6,14 @@ /** * This route file is loaded in the RouteServiceProvider optionally when an env var is set. * You'll find that service in the Providers directory. + * * @var Illuminate\Routing\Router $router */ $router->group(['middleware' => ['throttle:45,1']], function () use ($router) { // TODO actually use logout route in VUE app.. $router->post('user/register', [ - 'middleware' => ['throttle.signup:'.Config::get('wbstack.signup_throttling_limit').','.Config::get('wbstack.signup_throttling_range')], - 'uses' => 'Auth\RegisterController@register' + 'middleware' => ['throttle.signup:' . Config::get('wbstack.signup_throttling_limit') . ',' . Config::get('wbstack.signup_throttling_range')], + 'uses' => 'Auth\RegisterController@register', ]); $router->post('user/verifyEmail', ['uses' => 'UserVerificationTokenController@verify']); $router->post('user/forgotPassword', ['uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail']); diff --git a/routes/backend.php b/routes/backend.php index 92787a292..82024eee0 100644 --- a/routes/backend.php +++ b/routes/backend.php @@ -3,6 +3,7 @@ /** * This route file is loaded in the RouteServiceProvider optionally when an env var is set. * You'll find that service in the Providers directory. + * * @var Illuminate\Routing\Router $router */ diff --git a/routes/general.php b/routes/general.php index 189d79612..2dd90e1f9 100644 --- a/routes/general.php +++ b/routes/general.php @@ -3,6 +3,7 @@ /** * This route file is loaded in the RouteServiceProvider optionally when an env var is set. * You'll find that service in the Providers directory. + * * @var Illuminate\Routing\Router $router */ diff --git a/routes/sandbox.php b/routes/sandbox.php index b136d4d5f..a97fc600b 100644 --- a/routes/sandbox.php +++ b/routes/sandbox.php @@ -3,6 +3,7 @@ /** * This route file is loaded in the RouteServiceProvider optionally when an env var is set. * You'll find that service in the Providers directory. + * * @var Illuminate\Routing\Router $router */ $router->post('sandbox/create', ['uses' => 'Sandbox\SandboxController@create']) diff --git a/server.php b/server.php index 5fb6379e7..24c84117e 100644 --- a/server.php +++ b/server.php @@ -3,10 +3,8 @@ /** * Laravel - A PHP Framework For Web Artisans * - * @package Laravel * @author Taylor Otwell */ - $uri = urldecode( parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ); @@ -14,8 +12,8 @@ // This file allows us to emulate Apache's "mod_rewrite" functionality from the // built-in PHP web server. This provides a convenient way to test a Laravel // application without having installed a "real" web server software here. -if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { +if ($uri !== '/' && file_exists(__DIR__ . '/public' . $uri)) { return false; } -require_once __DIR__.'/public/index.php'; +require_once __DIR__ . '/public/index.php'; diff --git a/tests/Commands/RebuildQueryserviceDataTest.php b/tests/Commands/RebuildQueryserviceDataTest.php index ea9346ab2..aad23ed02 100644 --- a/tests/Commands/RebuildQueryserviceDataTest.php +++ b/tests/Commands/RebuildQueryserviceDataTest.php @@ -3,38 +3,34 @@ namespace Tests\Commands; use App\Constants\MediawikiNamespace; -use App\Wiki; +use App\Jobs\SpawnQueryserviceUpdaterJob; use App\QueryserviceNamespace; +use App\Wiki; use App\WikiSetting; -use App\Jobs\SpawnQueryserviceUpdaterJob; -use Tests\TestCase; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Illuminate\Http\Client\Request; use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Http; -use Illuminate\Http\Client\Request; -use Illuminate\Foundation\Testing\DatabaseTransactions; +use Tests\TestCase; -class RebuildQueryserviceDataTest extends TestCase -{ +class RebuildQueryserviceDataTest extends TestCase { use DatabaseTransactions; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); WikiSetting::query()->delete(); QueryserviceNamespace::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); WikiSetting::query()->delete(); QueryserviceNamespace::query()->delete(); parent::tearDown(); } - public function testEmpty() - { + public function testEmpty() { Bus::fake(); Http::fake(); @@ -44,8 +40,7 @@ public function testEmpty() Http::assertNothingSent(); } - public function testWikiWithLexemes() - { + public function testWikiWithLexemes() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'rebuild.wikibase.cloud']); WikiSetting::factory()->create([ @@ -60,7 +55,7 @@ public function testWikiWithLexemes() ]); Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ [ @@ -78,7 +73,7 @@ public function testWikiWithLexemes() ], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ 'continue' => [ 'apcontinue' => 'Q6', ], @@ -107,7 +102,7 @@ public function testWikiWithLexemes() ], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=Q6&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=Q6&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ [ @@ -127,9 +122,9 @@ public function testWikiWithLexemes() 'namespace' => MediawikiNamespace::item, ], ], - ] + ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ [ @@ -152,34 +147,35 @@ public function testWikiWithLexemes() $this->artisan('wbs-qs:rebuild', ['--chunkSize' => 10])->assertExitCode(0); Bus::assertDispatchedTimes(SpawnQueryserviceUpdaterJob::class, 2); Bus::assertDispatched(SpawnQueryserviceUpdaterJob::class, function ($job) { - if ('rebuild.wikibase.cloud' !== $job->wikiDomain) { + if ($job->wikiDomain !== 'rebuild.wikibase.cloud') { return false; } - if (10 !== count(explode(',', $job->entities))) { + if (count(explode(',', $job->entities)) !== 10) { return false; } - if ('http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql' !== $job->sparqlUrl) { + if ($job->sparqlUrl !== 'http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql') { return false; } + return true; }); Bus::assertDispatched(SpawnQueryserviceUpdaterJob::class, function ($job) { - if ('rebuild.wikibase.cloud' !== $job->wikiDomain) { + if ($job->wikiDomain !== 'rebuild.wikibase.cloud') { return false; } - if (5 !== count(explode(',', $job->entities))) { + if (count(explode(',', $job->entities)) !== 5) { return false; } - if ('http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql' !== $job->sparqlUrl) { + if ($job->sparqlUrl !== 'http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql') { return false; } + return true; }); Http::assertSentCount(4); } - public function testWikiNoLexemes() - { + public function testWikiNoLexemes() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'rebuild.wikibase.cloud']); QueryserviceNamespace::factory()->create([ @@ -189,7 +185,7 @@ public function testWikiNoLexemes() ]); Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ [ @@ -207,7 +203,7 @@ public function testWikiNoLexemes() ], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ [ @@ -233,29 +229,29 @@ public function testWikiNoLexemes() ], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ 'error' => 'Lexemes not enabled for this wiki', ], 400), ]); $this->artisan('wbs-qs:rebuild', ['--chunkSize' => 10])->assertExitCode(0); Bus::assertDispatched(SpawnQueryserviceUpdaterJob::class, function ($job) { - if ('rebuild.wikibase.cloud' !== $job->wikiDomain) { + if ($job->wikiDomain !== 'rebuild.wikibase.cloud') { return false; } - if (8 !== count(explode(',', $job->entities))) { + if (count(explode(',', $job->entities)) !== 8) { return false; } - if ('http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql' !== $job->sparqlUrl) { + if ($job->sparqlUrl !== 'http://queryservice.default.svc.cluster.local:9999/bigdata/namespace/test_ns_12345/sparql') { return false; } + return true; }); Http::assertSentCount(2); } - public function testFailure() - { + public function testFailure() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'rebuild.wikibase.cloud']); QueryserviceNamespace::factory()->create([ @@ -265,7 +261,7 @@ public function testFailure() ]); Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ [ @@ -283,10 +279,10 @@ public function testFailure() ], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ 'error' => 'THE DINOSAURS ESCAPED!', ], 500), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ 'error' => 'Lexemes not enabled for this wiki', ], 400), ]); @@ -295,8 +291,7 @@ public function testFailure() Bus::assertNothingDispatched(); } - public function testEmptyWiki() - { + public function testEmptyWiki() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'rebuild.wikibase.cloud']); QueryserviceNamespace::factory()->create([ @@ -306,17 +301,17 @@ public function testEmptyWiki() ]); Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=146&apcontinue=&aplimit=max&format=json' => Http::response([ 'error' => 'Lexemes not enabled for this wiki', ], 400), ]); @@ -326,8 +321,7 @@ public function testEmptyWiki() Http::assertSentCount(2); } - public function testDomainArg() - { + public function testDomainArg() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'rebuild.wikibase.cloud']); QueryserviceNamespace::factory()->create([ @@ -348,6 +342,7 @@ public function testDomainArg() if ($hostHeader !== 'rebuild.wikibase.cloud') { return Http::response('The dinosaurs escaped!!!', 500); } + return Http::response([ 'query' => [ 'allpages' => [], diff --git a/tests/Commands/User/ChangeEmailTest.php b/tests/Commands/User/ChangeEmailTest.php index 6575fdece..6cc3bf038 100644 --- a/tests/Commands/User/ChangeEmailTest.php +++ b/tests/Commands/User/ChangeEmailTest.php @@ -2,32 +2,30 @@ namespace Tests\Commands; +use App\Notifications\EmailReverificationNotification; use App\User; use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; -use App\Notifications\EmailReverificationNotification; use Illuminate\Support\Facades\Notification; +use Tests\TestCase; -class ChangeEmailTest extends TestCase -{ +class ChangeEmailTest extends TestCase { use DatabaseTransactions; const EMAIL_OLD = 'old@example.com'; + const EMAIL_NEW = 'new@example.com'; - - private function createUser($email) - { + + private function createUser($email) { $user = new User([ 'email' => $email, - 'password' => 'worldsstrongestpassword' + 'password' => 'worldsstrongestpassword', ]); $user->save(); - + return $user; } - public function testSuccess() - { + public function testSuccess() { Notification::fake(); $oldUser = $this->createUser(self::EMAIL_OLD); @@ -48,8 +46,7 @@ public function testSuccess() Notification::assertSentTo([$newUser], EmailReverificationNotification::class); } - public function testSame() - { + public function testSame() { Notification::fake(); $oldUser = $this->createUser(self::EMAIL_OLD); @@ -70,8 +67,7 @@ public function testSame() Notification::assertNothingSent(); } - public function testUserNotFound() - { + public function testUserNotFound() { Notification::fake(); $oldUser = $this->createUser(self::EMAIL_OLD); diff --git a/tests/Commands/Wiki/DeleteTest.php b/tests/Commands/Wiki/DeleteTest.php index b308feeb2..2b9e61bc9 100644 --- a/tests/Commands/Wiki/DeleteTest.php +++ b/tests/Commands/Wiki/DeleteTest.php @@ -7,12 +7,10 @@ use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\TestCase; -class DeleteTest extends TestCase -{ +class DeleteTest extends TestCase { use DatabaseTransactions; - public function testDeleteWikiBySiteName() - { + public function testDeleteWikiBySiteName() { $wikiName = 'potatoWiki'; $wiki = Wiki::factory(['sitename' => $wikiName])->create(); @@ -25,8 +23,7 @@ public function testDeleteWikiBySiteName() $this->assertSoftDeleted($wiki); } - public function testDeleteWikiByDomain() - { + public function testDeleteWikiByDomain() { $domain = 'deleted.wiki.org'; $wiki = Wiki::factory(['domain' => $domain])->create(); @@ -38,33 +35,30 @@ public function testDeleteWikiByDomain() $this->assertSoftDeleted($wiki); } - public function testGivenWikiDoesNotExist_commandFails() - { + public function testGivenWikiDoesNotExistCommandFails() { $this->artisan( 'wbs-wiki:delete', [ - 'key' => 'sitename', - 'value' => 'iDontExist', - ]) + 'key' => 'sitename', + 'value' => 'iDontExist', + ]) ->expectsOutput(Delete::ERR_WIKI_DOES_NOT_EXIST) ->assertFailed(); } - public function testGivenKeyValuePairMatchesMultipleWikis_commandFails() - { + public function testGivenKeyValuePairMatchesMultipleWikisCommandFails() { $name = 'potatoWiki'; $wiki1 = Wiki::factory(['sitename' => $name])->create(); $wiki2 = Wiki::factory(['sitename' => $name])->create(); $this->artisan( 'wbs-wiki:delete', [ - 'key' => 'sitename', - 'value' => $name, - ]) + 'key' => 'sitename', + 'value' => $name, + ]) ->expectsOutput(Delete::ERR_AMBIGUOUS_KEY_VALUE) ->assertFailed(); $this->assertNotSoftDeleted($wiki1); $this->assertNotSoftDeleted($wiki2); } - } diff --git a/tests/Helper/DomainHelperTest.php b/tests/Helper/DomainHelperTest.php index 61b6ec286..0be943ab0 100644 --- a/tests/Helper/DomainHelperTest.php +++ b/tests/Helper/DomainHelperTest.php @@ -2,14 +2,14 @@ namespace Tests\Jobs; -use Tests\TestCase; use App\Helper\DomainHelper; +use Tests\TestCase; class DomainHelperTest extends TestCase { /** * @return string[][] */ - static public function provideUnicodeDomains(): array { + public static function provideUnicodeDomains(): array { return [ 'Example IDNA encoding' => [ 'bücher.example', @@ -17,19 +17,19 @@ static public function provideUnicodeDomains(): array { ], 'Example IDNA encoding #2 - Latin-1' => [ 'então.carolinadoran.com', - 'xn--ento-ioa.carolinadoran.com' + 'xn--ento-ioa.carolinadoran.com', ], 'Example IDNA encoding #3 - Greek' => [ 'άλφα.wikibase.cloud', - 'xn--hxak3a7b.wikibase.cloud' + 'xn--hxak3a7b.wikibase.cloud', ], 'Example IDNA encoding #4 - Japanese' => [ 'ドメイン名例.wikibase.cloud', - 'xn--eckwd4c7cu47r2wf.wikibase.cloud' + 'xn--eckwd4c7cu47r2wf.wikibase.cloud', ], 'Example IDNA encoding #5 - Emoji' => [ '😃.wikibase.cloud', - 'xn--h28h.wikibase.cloud' + 'xn--h28h.wikibase.cloud', ], 'No double-encoding of "münchen.wikibase.cloud"' => [ 'xn--mnchen-3ya.wikibase.cloud', @@ -49,7 +49,7 @@ static public function provideUnicodeDomains(): array { /** * @return string[][] */ - static public function provideAsciiDomains(): array { + public static function provideAsciiDomains(): array { return [ 'Example IDNA decoding' => [ 'xn--bcher-kva.example', @@ -91,7 +91,7 @@ static public function provideAsciiDomains(): array { */ public function testEncoding($input, $expectedOutput) { $encoded = DomainHelper::encode($input); - + $this->assertSame( $encoded, $expectedOutput @@ -103,7 +103,7 @@ public function testEncoding($input, $expectedOutput) { */ public function testDecoding($input, $expectedOutput) { $decoded = DomainHelper::decode($input); - + $this->assertSame( $decoded, $expectedOutput diff --git a/tests/Helper/DomainValidatorTest.php b/tests/Helper/DomainValidatorTest.php index 55c2699c5..97aecfc75 100644 --- a/tests/Helper/DomainValidatorTest.php +++ b/tests/Helper/DomainValidatorTest.php @@ -2,31 +2,28 @@ namespace Tests\Jobs; -use Tests\TestCase; use App\Helper\DomainValidator; -use Illuminate\Support\Facades\Config; use App\Rules\ForbiddenSubdomainRule; +use Illuminate\Support\Facades\Config; +use Tests\TestCase; -class DomainValidatorTest extends TestCase -{ - public function testValidatorUsesOldValidation() - { +class DomainValidatorTest extends TestCase { + public function testValidatorUsesOldValidation() { $sut = new DomainValidator('.wbaas.localhost', []); $validator = $sut->validate('derp'); $this->assertCount(1, $validator->errors()); } - public function testValidatorUsesList() - { + + public function testValidatorUsesList() { $sut = new DomainValidator('.wbaas.localhost', [ - new ForbiddenSubdomainRule( ['long-terrible-word'], '.wbaas.localhost' ) + new ForbiddenSubdomainRule(['long-terrible-word'], '.wbaas.localhost'), ]); $validator = $sut->validate('long-terrible-word.wbaas.localhost'); $this->assertCount(1, $validator->errors()); $this->assertEquals(ForbiddenSubdomainRule::ERROR_MESSAGE, $validator->errors()->get('domain')[0]); } - public function testAppValidator() - { + public function testAppValidator() { Config::set('wbstack.subdomain_suffix', '.wbaas.localhost'); $sut = $this->app->make(DomainValidator::class); $validator = $sut->validate('statistics.wbaas.localhost'); diff --git a/tests/Helper/InviteHelperTest.php b/tests/Helper/InviteHelperTest.php index 162daf2b8..319249af6 100644 --- a/tests/Helper/InviteHelperTest.php +++ b/tests/Helper/InviteHelperTest.php @@ -2,16 +2,11 @@ namespace Tests\Jobs; -use Tests\TestCase; -use App\Helper\DomainValidator; -use Illuminate\Support\Facades\Config; -use App\Rules\ForbiddenSubdomainRule; use App\Helper\InviteHelper; +use Tests\TestCase; -class InviteHelperTest extends TestCase -{ - public function testGeneratesACode() - { +class InviteHelperTest extends TestCase { + public function testGeneratesACode() { $expectedPattern = "/wbcloud-(\d{4})-(\d{4})/"; $sut = new InviteHelper(2, 4); @@ -20,8 +15,7 @@ public function testGeneratesACode() $this->assertMatchesRegularExpression($expectedPattern, $code); } - public function testGeneratesAnotherCode() - { + public function testGeneratesAnotherCode() { $expectedPattern = "/wbcloud-(\d{12})-(\d{12})-(\d{12})/"; $sut = new InviteHelper(3, 12); @@ -29,5 +23,4 @@ public function testGeneratesAnotherCode() $this->assertIsString($code); $this->assertMatchesRegularExpression($expectedPattern, $code); } - } diff --git a/tests/Helper/MWTimestampHelperTest.php b/tests/Helper/MWTimestampHelperTest.php index f6ff43890..ed054cdb4 100644 --- a/tests/Helper/MWTimestampHelperTest.php +++ b/tests/Helper/MWTimestampHelperTest.php @@ -7,10 +7,8 @@ use Carbon\Exceptions\InvalidFormatException; use PHPUnit\Framework\TestCase; -class MWTimestampHelperTest extends TestCase -{ - public function testGetCarbonFromMWTimestamp() - { +class MWTimestampHelperTest extends TestCase { + public function testGetCarbonFromMWTimestamp() { $mwTimestamp = '20240513123456'; $expectedCarbon = CarbonImmutable::create(2024, 5, 13, 12, 34, 56); @@ -19,24 +17,21 @@ public function testGetCarbonFromMWTimestamp() $this->assertEquals($expectedCarbon, $carbon); } - public function testGetCarbonFromMWTimestampWithInvalidTimestamp() - { + public function testGetCarbonFromMWTimestampWithInvalidTimestamp() { $this->expectException(InvalidFormatException::class); $invalidMwTimestamp = 'invalid_timestamp'; MWTimestampHelper::getCarbonFromMWTimestamp($invalidMwTimestamp); } - public function testGetCarbonFromMWTimestampWithUnixTimestamp() - { + public function testGetCarbonFromMWTimestampWithUnixTimestamp() { $this->expectException(InvalidFormatException::class); $UnixTimestamp = CarbonImmutable::now()->timestamp; MWTimestampHelper::getCarbonFromMWTimestamp($UnixTimestamp); } - public function testGetMWTimestampFromCarbon() - { + public function testGetMWTimestampFromCarbon() { $carbon = CarbonImmutable::create(2024, 5, 13, 12, 34, 56); $expectedMwTimestamp = '20240513123456'; @@ -44,4 +39,4 @@ public function testGetMWTimestampFromCarbon() $this->assertEquals($expectedMwTimestamp, $mwTimestamp); } -} \ No newline at end of file +} diff --git a/tests/Helper/ProfileValidatorTest.php b/tests/Helper/ProfileValidatorTest.php index 12635a119..6d806f909 100644 --- a/tests/Helper/ProfileValidatorTest.php +++ b/tests/Helper/ProfileValidatorTest.php @@ -1,17 +1,17 @@ validate($profile); + $validatorFactory = new ProfileValidator; + $validator = $validatorFactory->validate($profile); $this->assertTrue($validator->passes()); } @@ -19,52 +19,51 @@ public function testProfileValidatorWorksWithValidProfile($profile): void { * @dataProvider invalidProfileProvider */ public function testProfileValidatorWorksWithInvalidProfile($profile): void { - $validatorFactory = new ProfileValidator(); - $validator=$validatorFactory->validate($profile); + $validatorFactory = new ProfileValidator; + $validator = $validatorFactory->validate($profile); $this->assertFalse($validator->passes()); } private function validProfileProvider() { return [ - [ 'boring profile with no other' => [ + ['boring profile with no other' => [ 'purpose' => 'data_hub', 'audience' => 'narrow', 'temporality' => 'permanent', - ] ], - [ 'with other values' => [ + ]], + ['with other values' => [ 'purpose' => 'data_hub', 'audience' => 'other', 'audience_other' => 'my cat', 'temporality' => 'other', 'temporality_other' => 'only in the past', - ] ], + ]], ]; } - private function invalidProfileProvider() { return [ - [ 'missing other keys' => [ + ['missing other keys' => [ 'purpose' => 'data_hub', 'audience' => 'narrow', 'temporality' => 'other', - ] ], - [ 'audience is empty string' => [ + ]], + ['audience is empty string' => [ 'purpose' => 'data_hub', 'audience' => '', 'temporality' => 'other', - ] ], - [ 'audience key present when purpose not data_hub' => [ + ]], + ['audience key present when purpose not data_hub' => [ 'purpose' => 'data_lab', 'audience' => 'narrow', 'temporality' => 'permanent', - ] ], - [ 'other keys when there should not be' => [ + ]], + ['other keys when there should not be' => [ 'purpose' => 'data_hub', 'purpose_other' => 'asdfasdf', 'audience' => 'narrow', 'temporality' => 'permanent', - ] ], + ]], ]; } -} \ No newline at end of file +} diff --git a/tests/Jobs/CirrusSearch/ElasticSearchAliasInitTest.php b/tests/Jobs/CirrusSearch/ElasticSearchAliasInitTest.php index 670dd744d..418bc84b1 100644 --- a/tests/Jobs/CirrusSearch/ElasticSearchAliasInitTest.php +++ b/tests/Jobs/CirrusSearch/ElasticSearchAliasInitTest.php @@ -2,150 +2,146 @@ namespace Tests\Jobs; -use Tests\TestCase; use App\Http\Curl\HttpRequest; -use Illuminate\Contracts\Queue\Job; use App\Jobs\ElasticSearchAliasInit; -use App\WikiDb; use App\Wiki; +use App\WikiDb; +use Illuminate\Contracts\Queue\Job; +use Tests\TestCase; -class ElasticSearchAliasInitTest extends TestCase -{ +class ElasticSearchAliasInitTest extends TestCase { private $wikiId; + private $prefix; + private $dbName; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->wikiId = Wiki::factory()->create()->id; - $this->dbName = WikiDb::factory()->create( [ 'wiki_id' => $this->wikiId ] )->name; + $this->dbName = WikiDb::factory()->create(['wiki_id' => $this->wikiId])->name; $this->prefix = 'testing_1'; - putenv( 'ELASTICSEARCH_SHARED_INDEX_PREFIX' ); + putenv('ELASTICSEARCH_SHARED_INDEX_PREFIX'); } - public function tearDown(): void - { - putenv( 'ELASTICSEARCH_SHARED_INDEX_PREFIX' ); + protected function tearDown(): void { + putenv('ELASTICSEARCH_SHARED_INDEX_PREFIX'); Wiki::query()->delete(); WikiDb::query()->delete(); parent::tearDown(); } - private function buildAlias( string $index, string $alias ) { + private function buildAlias(string $index, string $alias) { return [ 'add' => [ 'index' => $index, 'alias' => $alias, 'routing' => $alias, - 'filter' => [ 'prefix' => [ 'wiki' => $this->dbName . '-' ] ] - ] + 'filter' => ['prefix' => ['wiki' => $this->dbName . '-']], + ], ]; } private function getMockRequest() { - $request = $this->createMock( HttpRequest::class ); - $request->expects( $this->once() ) + $request = $this->createMock(HttpRequest::class); + $request->expects($this->once()) ->method('setOptions') ->with( [ - CURLOPT_URL => getenv( 'ELASTICSEARCH_SHARED_INDEX_HOST' ) . '/_aliases', + CURLOPT_URL => getenv('ELASTICSEARCH_SHARED_INDEX_HOST') . '/_aliases', CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60 * 15, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_HTTPHEADER => [ 'Content-Type: application/json' ], - CURLOPT_POSTFIELDS => json_encode( [ + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], + CURLOPT_POSTFIELDS => json_encode([ 'actions' => [ - $this->buildAlias( $this->prefix . '_content_first', $this->dbName ), - $this->buildAlias( $this->prefix . '_content_first', $this->dbName . '_content' ), - $this->buildAlias( $this->prefix . '_content_first', $this->dbName . '_content_first' ), - $this->buildAlias( $this->prefix . '_general_first', $this->dbName ), - $this->buildAlias( $this->prefix . '_general_first', $this->dbName . '_general' ), - $this->buildAlias( $this->prefix . '_general_first', $this->dbName . '_general_first' ) - ] - ] ) + $this->buildAlias($this->prefix . '_content_first', $this->dbName), + $this->buildAlias($this->prefix . '_content_first', $this->dbName . '_content'), + $this->buildAlias($this->prefix . '_content_first', $this->dbName . '_content_first'), + $this->buildAlias($this->prefix . '_general_first', $this->dbName), + $this->buildAlias($this->prefix . '_general_first', $this->dbName . '_general'), + $this->buildAlias($this->prefix . '_general_first', $this->dbName . '_general_first'), + ], + ]), ] ); + return $request; } - public function testSuccess() - { + public function testSuccess() { $request = $this->getMockRequest(); - $request->method( 'execute' ) - ->willReturn( json_encode( [ 'acknowledged' => true ] ) ); + $request->method('execute') + ->willReturn(json_encode(['acknowledged' => true])); - $mockJob = $this->createMock( Job::class ); - $mockJob->expects( $this->never() ) - ->method( 'fail' ) + $mockJob = $this->createMock(Job::class); + $mockJob->expects($this->never()) + ->method('fail') ->withAnyParameters(); - $job = new ElasticSearchAliasInit( $this->wikiId, $this->prefix ); - $job->setJob( $mockJob ); - $job->handle( $request ); + $job = new ElasticSearchAliasInit($this->wikiId, $this->prefix); + $job->setJob($mockJob); + $job->handle($request); } - public function testFailure() - { + public function testFailure() { $request = $this->getMockRequest(); - $request->method( 'execute' ) - ->willReturn( json_encode( [ 'acknowledged' => false ] ) ); + $request->method('execute') + ->willReturn(json_encode(['acknowledged' => false])); - $mockJob = $this->createMock( Job::class ); - $mockJob->expects( $this->once() ) - ->method( 'fail' ) - ->with( new \RuntimeException( "Updating Elasticsearch aliases failed for $this->wikiId with {\"acknowledged\":false}" ) ); + $mockJob = $this->createMock(Job::class); + $mockJob->expects($this->once()) + ->method('fail') + ->with(new \RuntimeException("Updating Elasticsearch aliases failed for $this->wikiId with {\"acknowledged\":false}")); - $job = new ElasticSearchAliasInit( $this->wikiId, $this->prefix ); - $job->setJob( $mockJob ); - $job->handle( $request ); + $job = new ElasticSearchAliasInit($this->wikiId, $this->prefix); + $job->setJob($mockJob); + $job->handle($request); } - public function testMissingDatabaseFailure() - { + public function testMissingDatabaseFailure() { $this->wikiId = -1; - $request = $this->createMock( HttpRequest::class ); + $request = $this->createMock(HttpRequest::class); - $mockJob = $this->createMock( Job::class ); - $mockJob->expects( $this->once() ) - ->method( 'fail' ) - ->with( new \RuntimeException( "Failed to get database name for $this->wikiId" ) ); + $mockJob = $this->createMock(Job::class); + $mockJob->expects($this->once()) + ->method('fail') + ->with(new \RuntimeException("Failed to get database name for $this->wikiId")); - $job = new ElasticSearchAliasInit( $this->wikiId, $this->prefix ); - $job->setJob( $mockJob ); - $job->handle( $request ); + $job = new ElasticSearchAliasInit($this->wikiId, $this->prefix); + $job->setJob($mockJob); + $job->handle($request); } - public function testSuccessWithPrefixEnv() - { + public function testSuccessWithPrefixEnv() { $this->prefix = 'env_1'; - putenv( "ELASTICSEARCH_SHARED_INDEX_PREFIX=$this->prefix" ); + putenv("ELASTICSEARCH_SHARED_INDEX_PREFIX=$this->prefix"); $request = $this->getMockRequest(); - $request->method( 'execute' ) - ->willReturn( json_encode( [ 'acknowledged' => true ] ) ); + $request->method('execute') + ->willReturn(json_encode(['acknowledged' => true])); - $mockJob = $this->createMock( Job::class ); - $mockJob->expects( $this->never() ) - ->method( 'fail' ) + $mockJob = $this->createMock(Job::class); + $mockJob->expects($this->never()) + ->method('fail') ->withAnyParameters(); - $job = new ElasticSearchAliasInit( $this->wikiId ); - $job->setJob( $mockJob ); - $job->handle( $request ); + $job = new ElasticSearchAliasInit($this->wikiId); + $job->setJob($mockJob); + $job->handle($request); } - public function testMissingPrefixFailure() - { - $request = $this->createMock( HttpRequest::class ); + public function testMissingPrefixFailure() { + $request = $this->createMock(HttpRequest::class); - $mockJob = $this->createMock( Job::class ); - $mockJob->expects( $this->once() ) - ->method( 'fail' ) - ->with( new \RuntimeException( "Missing shared index prefix for $this->wikiId" ) ); + $mockJob = $this->createMock(Job::class); + $mockJob->expects($this->once()) + ->method('fail') + ->with(new \RuntimeException("Missing shared index prefix for $this->wikiId")); - $job = new ElasticSearchAliasInit( $this->wikiId ); - $job->setJob( $mockJob ); - $job->handle( $request ); + $job = new ElasticSearchAliasInit($this->wikiId); + $job->setJob($mockJob); + $job->handle($request); } } diff --git a/tests/Jobs/CirrusSearch/ElasticSearchIndexInitTest.php b/tests/Jobs/CirrusSearch/ElasticSearchIndexInitTest.php index 59c00da8f..612eda280 100644 --- a/tests/Jobs/CirrusSearch/ElasticSearchIndexInitTest.php +++ b/tests/Jobs/CirrusSearch/ElasticSearchIndexInitTest.php @@ -3,28 +3,29 @@ namespace Tests\Jobs\CirrusSearch; use App\Http\Curl\CurlRequest; -use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; -use App\Jobs\CirrusSearch\ElasticSearchIndexInit; use App\Http\Curl\HttpRequest; +use App\Jobs\CirrusSearch\ElasticSearchIndexInit; +use App\User; +use App\Wiki; +use App\WikiDb; use App\WikiManager; use App\WikiSetting; -use App\Wiki; use Illuminate\Contracts\Queue\Job; -use App\WikiDb; use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Tests\TestCase; -class ElasticSearchIndexInitTest extends TestCase -{ +class ElasticSearchIndexInitTest extends TestCase { use DatabaseTransactions; use DispatchesJobs; private $wiki; + private $wikiDb; + private $user; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->user = User::factory()->create(['verified' => true]); @@ -34,12 +35,12 @@ public function setUp(): void { [ 'wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, - 'value' => true + 'value' => true, ] ); $this->wikiDb = WikiDb::factory()->create([ - 'wiki_id' => $this->wiki->id + 'wiki_id' => $this->wiki->id, ]); } @@ -52,16 +53,15 @@ public function testDispatching() { $job->handle(new CurlRequest); } - public function testSuccess() - { + public function testSuccess() { $mockResponse = [ 'warnings' => [], 'wbstackElasticSearchInit' => [ - "return" => 0, - "output" => [ - "\tCreating index...ok" // successfully created some index - ] - ] + 'return' => 0, + 'output' => [ + "\tCreating index...ok", // successfully created some index + ], + ], ]; $request = $this->createMock(HttpRequest::class); $request->method('execute')->willReturn(json_encode($mockResponse)); @@ -71,7 +71,7 @@ public function testSuccess() $request->expects($this->once()) ->method('setOptions') ->with([ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackElasticSearchInit&format=json&cluster=all', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackElasticSearchInit&format=json&cluster=all', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 1234, @@ -79,14 +79,14 @@ public function testSuccess() CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wiki->domain, - ] - ]); + 'host: ' . $this->wiki->domain, + ], + ]); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); + ->method('fail') + ->withAnyParameters(); $job = new ElasticSearchIndexInit($this->wiki->id); $job->setJob($mockJob); @@ -95,28 +95,27 @@ public function testSuccess() // feature should get enabled $this->assertSame( 1, - WikiSetting::where( ['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->count() + WikiSetting::where(['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->count() ); } - public function testUpdate() - { + public function testUpdate() { $mockResponse = [ 'warnings' => [], 'wbstackElasticSearchInit' => [ - "return" => 0, - "output" => [ - "\t\tValidating {$this->wikiDb->name}_general alias...ok" - ] - ] + 'return' => 0, + 'output' => [ + "\t\tValidating {$this->wikiDb->name}_general alias...ok", + ], + ], ]; $request = $this->createMock(HttpRequest::class); $request->method('execute')->willReturn(json_encode($mockResponse)); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); + ->method('fail') + ->withAnyParameters(); $job = new ElasticSearchIndexInit($this->wiki->id); $job->setJob($mockJob); @@ -124,30 +123,29 @@ public function testUpdate() // feature should get enabled $this->assertSame( - 1, - WikiSetting::where( ['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->count() + 1, + WikiSetting::where(['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->count() ); } - public function testJobTriggeredButNoSetting() - { - WikiSetting::where( ['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch ])->first()->delete(); + public function testJobTriggeredButNoSetting() { + WikiSetting::where(['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch])->first()->delete(); $request = $this->createMock(HttpRequest::class); - $request->expects( $this->never() )->method('execute'); + $request->expects($this->never())->method('execute'); $job = new ElasticSearchIndexInit($this->wiki->id); $job->handle($request); } /** - * @dataProvider failureProvider + * @dataProvider failureProvider + * * @expectedException RuntimeException - */ - public function testFailure( $request, string $expectedFailure, $mockResponse ) - { + */ + public function testFailure($request, string $expectedFailure, $mockResponse) { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) - ->method('fail'); + ->method('fail'); $request->method('execute')->willReturn(json_encode($mockResponse)); @@ -157,7 +155,7 @@ public function testFailure( $request, string $expectedFailure, $mockResponse ) $this->assertSame( 1, - WikiSetting::where( ['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->count() + WikiSetting::where(['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->count() ); } @@ -167,21 +165,21 @@ public function failureProvider() { yield [ $this->createMock(HttpRequest::class), 'wbstackElasticSearchInit call for . No wbstackElasticSearchInit key in response: []', - $mockResponse + $mockResponse, ]; $mockResponse = [ 'warnings' => [], 'wbstackElasticSearchInit' => [ - "return" => 0, - "output" => [] - ] + 'return' => 0, + 'output' => [], + ], ]; yield [ $this->createMock(HttpRequest::class), 'wbstackElasticSearchInit call for was not successful:{"warnings":[],"wbstackElasticSearchInit":{"return":0,"output":[]}}', - $mockResponse + $mockResponse, ]; $curlError = $this->createMock(HttpRequest::class); @@ -189,15 +187,14 @@ public function failureProvider() { yield [ $curlError, 'wbstackElasticSearchInit curl error for : Scary Error!', - $mockResponse + $mockResponse, ]; $mockResponse['wbstackElasticSearchInit']['return'] = 1; yield [ $this->createMock(HttpRequest::class), 'wbstackElasticSearchInit call for was not successful:{"warnings":[],"wbstackElasticSearchInit":{"return":1,"output":[]}}', - $mockResponse + $mockResponse, ]; } - } diff --git a/tests/Jobs/CirrusSearch/ForceSearchIndexTest.php b/tests/Jobs/CirrusSearch/ForceSearchIndexTest.php index a0f69d9a7..43df89ab5 100644 --- a/tests/Jobs/CirrusSearch/ForceSearchIndexTest.php +++ b/tests/Jobs/CirrusSearch/ForceSearchIndexTest.php @@ -2,33 +2,30 @@ namespace Tests\Jobs\CirrusSearch; -use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; -use App\Jobs\CirrusSearch\ElasticSearchIndexInit; use App\Http\Curl\HttpRequest; +use App\Jobs\CirrusSearch\ForceSearchIndex; +use App\User; +use App\Wiki; +use App\WikiDb; use App\WikiManager; use App\WikiSetting; -use App\Wiki; use Illuminate\Contracts\Queue\Job; -use App\WikiDb; use Illuminate\Foundation\Bus\DispatchesJobs; -use Illuminate\Support\Facades\DB; -use PHPUnit\TextUI\RuntimeException; -use App\Jobs\CirrusSearch\QueueSearchIndexBatches; -use App\Jobs\CirrusSearch\ForceSearchIndex; -use Illuminate\Support\Facades\Bus; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Queue; +use Tests\TestCase; -class ForceSearchIndexTest extends TestCase -{ +class ForceSearchIndexTest extends TestCase { use DatabaseTransactions; use DispatchesJobs; + private $wiki; + private $wikiDb; + private $user; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->user = User::factory()->create(['verified' => true]); @@ -38,16 +35,16 @@ public function setUp(): void { [ 'wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, - 'value' => true + 'value' => true, ] ); $this->wikiDb = WikiDb::factory()->create([ - 'wiki_id' => $this->wiki->id + 'wiki_id' => $this->wiki->id, ]); } - public function testSuccess() - { + + public function testSuccess() { Queue::fake(); $toId = 10; @@ -56,34 +53,34 @@ public function testSuccess() $mockResponse = [ 'warnings' => [], 'wbstackForceSearchIndex' => [ - "return" => 0, - "output" => [ - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 10 at 2/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 20 at 4/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 30 at 6/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 40 at 7/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 50 at 9/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 60 at 9/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 70 at 9/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 80 at 9/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 90 at 9/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 100 at 9/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 110 at 9/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 120 at 10/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 130 at 10/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 140 at 10/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 150 at 10/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 160 at 10/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 170 at 11/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 180 at 11/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 190 at 11/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 200 at 11/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 210 at 11/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 220 at 11/second", - "[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 9 pages ending at 229 at 11/second", - "Indexed a total of 229 pages at 11/second" - ] - ] + 'return' => 0, + 'output' => [ + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 10 at 2/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 20 at 4/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 30 at 6/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 40 at 7/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 50 at 9/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 60 at 9/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 70 at 9/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 80 at 9/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 90 at 9/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 100 at 9/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 110 at 9/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 120 at 10/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 130 at 10/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 140 at 10/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 150 at 10/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 160 at 10/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 170 at 11/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 180 at 11/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 190 at 11/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 200 at 11/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 210 at 11/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 10 pages ending at 220 at 11/second', + '[mwdb_febf08b4c7-mwt_f66e770e74_] Indexed 9 pages ending at 229 at 11/second', + 'Indexed a total of 229 pages at 11/second', + ], + ], ]; $request = $this->createMock(HttpRequest::class); @@ -92,7 +89,7 @@ public function testSuccess() $request->expects($this->once()) ->method('setOptions') ->with([ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackForceSearchIndex&format=json&fromId=' . $fromId . '&toId=' . $toId, + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackForceSearchIndex&format=json&fromId=' . $fromId . '&toId=' . $toId, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 1000, @@ -100,14 +97,14 @@ public function testSuccess() CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wiki->domain, - ] - ]); + 'host: ' . $this->wiki->domain, + ], + ]); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); + ->method('fail') + ->withAnyParameters(); $job = new ForceSearchIndex('id', $this->wiki->id, $fromId, $toId); $job->setJob($mockJob); diff --git a/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php b/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php index ed1740f10..892ddb347 100644 --- a/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php +++ b/tests/Jobs/CirrusSearch/QueueSearchIndexBatchesTest.php @@ -2,31 +2,31 @@ namespace Tests\Jobs\CirrusSearch; -use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; use App\Http\Curl\HttpRequest; +use App\Jobs\CirrusSearch\ForceSearchIndex; +use App\Jobs\CirrusSearch\QueueSearchIndexBatches; +use App\User; +use App\Wiki; +use App\WikiDb; use App\WikiManager; use App\WikiSetting; -use App\Wiki; use Illuminate\Contracts\Queue\Job; -use App\WikiDb; use Illuminate\Foundation\Bus\DispatchesJobs; -use PHPUnit\TextUI\RuntimeException; -use App\Jobs\CirrusSearch\QueueSearchIndexBatches; -use App\Jobs\CirrusSearch\ForceSearchIndex; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Queue; +use Tests\TestCase; -class QueueSearchIndexBatchesTest extends TestCase -{ +class QueueSearchIndexBatchesTest extends TestCase { use DatabaseTransactions; use DispatchesJobs; private $wiki; + private $wikiDb; + private $user; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->user = User::factory()->create(['verified' => true]); @@ -36,28 +36,28 @@ public function setUp(): void { [ 'wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, - 'value' => true + 'value' => true, ] ); $this->wikiDb = WikiDb::factory()->create([ - 'wiki_id' => $this->wiki->id + 'wiki_id' => $this->wiki->id, ]); } - public function testSuccess() - { + + public function testSuccess() { Queue::fake(); - + $mockResponse = [ 'warnings' => [], 'wbstackQueueSearchIndexBatches' => [ - "return" => 0, - "output" => [ - "php /var/www/html/w/extensions/CirrusSearch/maintenance/ForceSearchIndex.php --queue 1 --skipLinks 1 --indexOnSkip 1 --fromId 0 --toId 1000", - "php /var/www/html/w/extensions/CirrusSearch/maintenance/ForceSearchIndex.php --queue 1 --skipLinks 1 --indexOnSkip 1 --fromId 1001 --toId 1234", - "php /var/www/html/w/extensions/CirrusSearch/maintenance/ForceSearchIndex.php --queue 1 --skipLinks 1 --indexOnSkip 1 --fromId 1235 --toId 1236", - ] - ] + 'return' => 0, + 'output' => [ + 'php /var/www/html/w/extensions/CirrusSearch/maintenance/ForceSearchIndex.php --queue 1 --skipLinks 1 --indexOnSkip 1 --fromId 0 --toId 1000', + 'php /var/www/html/w/extensions/CirrusSearch/maintenance/ForceSearchIndex.php --queue 1 --skipLinks 1 --indexOnSkip 1 --fromId 1001 --toId 1234', + 'php /var/www/html/w/extensions/CirrusSearch/maintenance/ForceSearchIndex.php --queue 1 --skipLinks 1 --indexOnSkip 1 --fromId 1235 --toId 1236', + ], + ], ]; $request = $this->createMock(HttpRequest::class); $request->method('execute')->willReturn(json_encode($mockResponse)); @@ -65,7 +65,7 @@ public function testSuccess() $request->expects($this->once()) ->method('setOptions') ->with([ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackQueueSearchIndexBatches&format=json', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackQueueSearchIndexBatches&format=json', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 1000, @@ -73,14 +73,14 @@ public function testSuccess() CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wiki->domain, - ] - ]); + 'host: ' . $this->wiki->domain, + ], + ]); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); + ->method('fail') + ->withAnyParameters(); $job = new QueueSearchIndexBatches($this->wiki->id); $job->setJob($mockJob); @@ -105,7 +105,7 @@ public function testSuccess() public function testMediawikiErrorResponse() { $errorResponse = file_get_contents( - __DIR__.'/../../data/mediawiki-api-error-response.json' + __DIR__ . '/../../data/mediawiki-api-error-response.json' ); $request = $this->createMock(HttpRequest::class); @@ -114,7 +114,7 @@ public function testMediawikiErrorResponse() { $request->expects($this->once()) ->method('setOptions') ->with([ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackQueueSearchIndexBatches&format=json', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackQueueSearchIndexBatches&format=json', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 1000, @@ -122,18 +122,17 @@ public function testMediawikiErrorResponse() { CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wiki->domain, - ] - ]); + 'host: ' . $this->wiki->domain, + ], + ]); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) - ->method('fail') - ->with(new \RuntimeException('wbstackQueueSearchIndexBatches call failed with api error: Unrecognized value for parameter "action": wbstackQueueSearchIndexBatches.')); + ->method('fail') + ->with(new \RuntimeException('wbstackQueueSearchIndexBatches call failed with api error: Unrecognized value for parameter "action": wbstackQueueSearchIndexBatches.')); $job = new QueueSearchIndexBatches($this->wiki->id); $job->setJob($mockJob); $job->handle($request); } - } diff --git a/tests/Jobs/CreateQueryserviceBatchesJobTest.php b/tests/Jobs/CreateQueryserviceBatchesJobTest.php index dcf27ddbc..23496f4b6 100644 --- a/tests/Jobs/CreateQueryserviceBatchesJobTest.php +++ b/tests/Jobs/CreateQueryserviceBatchesJobTest.php @@ -3,24 +3,22 @@ namespace Tests\Jobs; use App\Constants\MediawikiNamespace; +use App\EventPageUpdate; +use App\Jobs\CreateQueryserviceBatchesJob; use App\QsBatch; use App\QsCheckpoint; use App\Wiki; -use App\EventPageUpdate; -use App\Jobs\CreateQueryserviceBatchesJob; -use Tests\TestCase; -use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Config; +use Tests\TestCase; -class CreateQueryserviceBatchesJobTest extends TestCase -{ +class CreateQueryserviceBatchesJobTest extends TestCase { use RefreshDatabase; private int $prevEntityLimit; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); QsBatch::query()->delete(); @@ -31,8 +29,7 @@ public function setUp(): void Config::set('wbstack.qs_batch_entity_limit', 10); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); QsBatch::query()->delete(); EventPageUpdate::query()->delete(); @@ -41,18 +38,16 @@ public function tearDown(): void parent::tearDown(); } - public function testEmpty (): void - { + public function testEmpty(): void { $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); $job->handle(); } - public function testBatchCreation (): void - { + public function testBatchCreation(): void { Wiki::factory()->create(['id' => 1, 'domain' => 'deleted.wikibase.cloud'])->delete(); Wiki::factory()->create(['id' => 88, 'domain' => 'test1.wikibase.cloud']); Wiki::factory()->create(['id' => 99, 'domain' => 'test2.wikibase.cloud']); @@ -69,7 +64,7 @@ public function testBatchCreation (): void EventPageUpdate::factory()->create(['id' => 6, 'wiki_id' => 1, 'namespace' => MediawikiNamespace::item, 'title' => 'Q152']); $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); @@ -84,8 +79,7 @@ public function testBatchCreation (): void $this->assertNull($batchForDeletedWiki); } - public function testBatchMerging(): void - { + public function testBatchMerging(): void { Wiki::factory()->create(['id' => 88, 'domain' => 'test1.wikibase.cloud']); Wiki::factory()->create(['id' => 99, 'domain' => 'test2.wikibase.cloud']); Wiki::factory()->create(['id' => 111, 'domain' => 'test3.wikibase.cloud']); @@ -95,7 +89,7 @@ public function testBatchMerging(): void EventPageUpdate::factory()->create(['id' => 234, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q34']); $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); @@ -108,8 +102,7 @@ public function testBatchMerging(): void $this->assertEquals(3, QsBatch::query()->count()); } - function testBigBatches(): void - { + public function testBigBatches(): void { Wiki::factory()->create(['id' => 88, 'domain' => 'test1.wikibase.cloud']); QsBatch::factory()->create(['id' => 1, 'done' => 0, 'wiki_id' => 88, 'entityIds' => 'Q1,Q2,Q3,Q4,Q5,Q6,Q7,Q8,Q9,Q10']); EventPageUpdate::factory()->create(['id' => 123, 'wiki_id' => 88, 'namespace' => MediawikiNamespace::item, 'title' => 'Q11']); @@ -122,7 +115,7 @@ function testBigBatches(): void EventPageUpdate::factory()->create(['id' => 124, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q11']); $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); @@ -147,7 +140,7 @@ function testBigBatches(): void EventPageUpdate::factory()->create(['id' => 125, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q999']); $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); @@ -158,8 +151,7 @@ function testBigBatches(): void $this->assertEquals($existingBatches->values()->get(2)->entityIds, 'Q999,Q11,Q12'); } - function testBackpressure(): void - { + public function testBackpressure(): void { Wiki::factory()->create(['id' => 99, 'domain' => 'test.wikibase.cloud']); EventPageUpdate::factory()->create(['id' => 124, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q1']); EventPageUpdate::factory()->create(['id' => 125, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q2']); @@ -174,7 +166,7 @@ function testBackpressure(): void EventPageUpdate::factory()->create(['id' => 134, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q12']); $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); @@ -183,8 +175,7 @@ function testBackpressure(): void $this->assertEquals(2, QsBatch::query()->count()); } - function testCheckpoints(): void - { + public function testCheckpoints(): void { Wiki::factory()->create(['id' => 99, 'domain' => 'test.wikibase.cloud']); EventPageUpdate::factory()->create(['id' => 124, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q1']); EventPageUpdate::factory()->create(['id' => 125, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q2']); @@ -198,7 +189,7 @@ function testCheckpoints(): void EventPageUpdate::factory()->create(['id' => 188, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q12']); $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); @@ -210,7 +201,7 @@ function testCheckpoints(): void EventPageUpdate::factory()->create(['id' => 198, 'wiki_id' => 99, 'namespace' => MediawikiNamespace::item, 'title' => 'Q126']); $mockJob = $this->createMock(Job::class); - $job = new CreateQueryserviceBatchesJob(); + $job = new CreateQueryserviceBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); diff --git a/tests/Jobs/DeleteQueryserviceNamespaceJobTest.php b/tests/Jobs/DeleteQueryserviceNamespaceJobTest.php index 5506dc2f0..8eacfff98 100644 --- a/tests/Jobs/DeleteQueryserviceNamespaceJobTest.php +++ b/tests/Jobs/DeleteQueryserviceNamespaceJobTest.php @@ -2,26 +2,24 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; use App\Http\Curl\HttpRequest; use App\Jobs\DeleteQueryserviceNamespaceJob; use App\QueryserviceNamespace; -use Illuminate\Support\Facades\DB; -use App\WikiManager; use App\User; use App\Wiki; +use App\WikiManager; use Carbon\Carbon; use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Illuminate\Support\Facades\DB; +use Tests\TestCase; -class DeleteQueryserviceNamespaceJobTest extends TestCase -{ +class DeleteQueryserviceNamespaceJobTest extends TestCase { use DatabaseTransactions; - public function testDeleteNamespace() - { + public function testDeleteNamespace() { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->subDays(30)->timestamp ] ); + $wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->subDays(30)->timestamp]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $namespace = 'asdf'; @@ -32,48 +30,47 @@ public function testDeleteNamespace() 'backend' => $host, ]); - DB::table('queryservice_namespaces')->where(['id'=>$dbRow->id])->limit(1)->update(['wiki_id' => $wiki->id]); + DB::table('queryservice_namespaces')->where(['id' => $dbRow->id])->limit(1)->update(['wiki_id' => $wiki->id]); putenv('CURLOPT_TIMEOUT_DELETE_QUERYSERVICE_NAMESPACE=1234'); - $mockResponse = 'DELETED: '.$namespace; + $mockResponse = 'DELETED: ' . $namespace; $request = $this->createMock(HttpRequest::class); $request->expects($this->exactly(1)) ->method('execute') - ->willReturn( $mockResponse ); + ->willReturn($mockResponse); $request->expects($this->exactly(1)) ->method('setOptions') - ->with( - [ - CURLOPT_URL => $dbRow->backend.'/bigdata/namespace/' . $namespace, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => '', - CURLOPT_TIMEOUT => 1234, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - // User agent is needed by the query service... - CURLOPT_USERAGENT => 'WBStack DeleteQueryserviceNamespaceJob', - CURLOPT_CUSTOMREQUEST => 'DELETE', - CURLOPT_HTTPHEADER => [ - 'content-type: text/plain', - ] - ]); - - + ->with( + [ + CURLOPT_URL => $dbRow->backend . '/bigdata/namespace/' . $namespace, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_TIMEOUT => 1234, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + // User agent is needed by the query service... + CURLOPT_USERAGENT => 'WBStack DeleteQueryserviceNamespaceJob', + CURLOPT_CUSTOMREQUEST => 'DELETE', + CURLOPT_HTTPHEADER => [ + 'content-type: text/plain', + ], + ]); + $job = new DeleteQueryserviceNamespaceJob($wiki->id); - $job->handle( $request ); + $job->handle($request); $this->assertSame( - 0, - QueryserviceNamespace::where( ['namespace' => $namespace ])->count() + 0, + QueryserviceNamespace::where(['namespace' => $namespace])->count() ); } public function testNoWiki() { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) - ->method('fail') - ->with(new \RuntimeException("Wiki not found for 123")); + ->method('fail') + ->with(new \RuntimeException('Wiki not found for 123')); $request = $this->createMock(HttpRequest::class); $request->expects($this->never()) @@ -84,17 +81,16 @@ public function testNoWiki() { $job->handle($request); } - public function testNoNamespace() { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->subDays(30)->timestamp ] ); + $wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->subDays(30)->timestamp]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) - ->method('fail') - ->with(new \RuntimeException("Namespace for wiki {$wiki->id} not found.")); + ->method('fail') + ->with(new \RuntimeException("Namespace for wiki {$wiki->id} not found.")); $request = $this->createMock(HttpRequest::class); $request->expects($this->never()) @@ -104,5 +100,4 @@ public function testNoNamespace() { $job->setJob($mockJob); $job->handle($request); } - -} \ No newline at end of file +} diff --git a/tests/Jobs/DeleteWikiDispatcherJobTest.php b/tests/Jobs/DeleteWikiDispatcherJobTest.php index f0b68c71d..28ec2a17a 100644 --- a/tests/Jobs/DeleteWikiDispatcherJobTest.php +++ b/tests/Jobs/DeleteWikiDispatcherJobTest.php @@ -2,44 +2,43 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; -use App\QueryserviceNamespace; -use Illuminate\Contracts\Queue\Job; +use App\Jobs\DeleteQueryserviceNamespaceJob; +use App\Jobs\DeleteWikiDbJob; use App\Jobs\DeleteWikiDispatcherJob; +use App\Jobs\DeleteWikiFinalizeJob; +use App\Jobs\ElasticSearchIndexDelete; +use App\Jobs\KubernetesIngressDeleteJob; +use App\Jobs\ProvisionWikiDbJob; +use App\QueryserviceNamespace; use App\User; use App\Wiki; +use App\WikiDb; use App\WikiManager; +use App\WikiSetting; use Carbon\Carbon; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Bus; -use App\Jobs\KubernetesIngressDeleteJob; -use App\Jobs\DeleteWikiDbJob; -use App\Jobs\DeleteWikiFinalizeJob; -use App\WikiSetting; -use App\Jobs\ElasticSearchIndexDelete; -use App\Jobs\DeleteQueryserviceNamespaceJob; +use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; -use TiMacDonald\Log\LogFake; -use TiMacDonald\Log\LogEntry; -use Illuminate\Support\Str; -use App\Jobs\ProvisionWikiDbJob; -use App\WikiDb; use Illuminate\Support\Facades\Storage; -use Illuminate\Support\Facades\Config; +use Illuminate\Support\Str; +use Tests\TestCase; +use TiMacDonald\Log\LogEntry; +use TiMacDonald\Log\LogFake; -class DeleteWikiDispatcherJobTest extends TestCase -{ +class DeleteWikiDispatcherJobTest extends TestCase { use DatabaseTransactions; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); Log::swap(new LogFake); Storage::fake('static-assets'); $this->wiki = $this->getWiki(); } - private function getWiki( $daysSinceDelete = 30 ): Wiki { + private function getWiki($daysSinceDelete = 30): Wiki { $user = User::factory()->create(['verified' => true]); $wiki = Wiki::factory()->create( [ @@ -47,36 +46,35 @@ private function getWiki( $daysSinceDelete = 30 ): Wiki { // new wikis are seeded as subdomains. // changes this to test k8s ingress delete gets dispatched - 'domain' => $user->id . '_DeleteWikiDispatcherJobTest.php' + 'domain' => $user->id . '_DeleteWikiDispatcherJobTest.php', - ] ); + ]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); + return $wiki; } - public function testDeleteDispatcher() - { + public function testDeleteDispatcher() { $wikiDB = WikiDb::create([ 'name' => 'mwdb_asdasfasfasf', 'user' => 'asdasd', 'password' => 'asdasfasfasf', 'version' => 'asdasdasdas', 'prefix' => 'asdasd', - 'wiki_id' => $this->wiki->id + 'wiki_id' => $this->wiki->id, ]); Bus::fake(); $mockJob = $this->createMock(Job::class); - $job = new DeleteWikiDispatcherJob(); + $job = new DeleteWikiDispatcherJob; $job->setJob($mockJob); $job->handle(); - Bus::assertChained([ - new KubernetesIngressDeleteJob( $this->wiki->id ), + new KubernetesIngressDeleteJob($this->wiki->id), new DeleteWikiDbJob($this->wiki->id), - new DeleteWikiFinalizeJob($this->wiki->id) + new DeleteWikiFinalizeJob($this->wiki->id), ]); } @@ -90,7 +88,7 @@ public function testNothingDispatchesUntilItsTime() { $existingWikiNotTimeYet = $this->getWiki(29); $mockJob = $this->createMock(Job::class); - $job = new DeleteWikiDispatcherJob(); + $job = new DeleteWikiDispatcherJob; $job->setJob($mockJob); $job->handle(); @@ -98,6 +96,7 @@ public function testNothingDispatchesUntilItsTime() { if ($log->level !== 'info') { return false; } + return Str::contains($log->message, 'Found no soft deleted wikis over threshold. exiting.'); }); @@ -109,30 +108,29 @@ public function testNothingDispatchesUntilItsTime() { } - public function testDeleteWithOptionalResources() - { + public function testDeleteWithOptionalResources() { Bus::fake(); $namespace = QueryserviceNamespace::create( [ 'namespace' => 'derp', - 'backend' => 'interwebs' + 'backend' => 'interwebs', ] ); - $nsAssignment = DB::table('queryservice_namespaces')->where(['id'=>$namespace->id])->limit(1)->update(['wiki_id' => $this->wiki->id]); + $nsAssignment = DB::table('queryservice_namespaces')->where(['id' => $namespace->id])->limit(1)->update(['wiki_id' => $this->wiki->id]); $this->assertNotNull($nsAssignment); WikiSetting::factory()->create( [ 'wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, - 'value' => true + 'value' => true, ] ); $mockJob = $this->createMock(Job::class); - $job = new DeleteWikiDispatcherJob(); + $job = new DeleteWikiDispatcherJob; $job->setJob($mockJob); $job->handle(); @@ -140,51 +138,51 @@ public function testDeleteWithOptionalResources() if ($log->level !== 'info') { return false; } + return Str::contains($log->message, "Dispatching hard delete job chain for id: {$this->wiki->id}"); }); Bus::assertChained([ - new DeleteQueryserviceNamespaceJob( $this->wiki->id ), - new ElasticSearchIndexDelete( $this->wiki->id ), - new KubernetesIngressDeleteJob( $this->wiki->id ), - new DeleteWikiFinalizeJob($this->wiki->id) + new DeleteQueryserviceNamespaceJob($this->wiki->id), + new ElasticSearchIndexDelete($this->wiki->id), + new KubernetesIngressDeleteJob($this->wiki->id), + new DeleteWikiFinalizeJob($this->wiki->id), ]); } - public function testActuallyRunningJobsThatDelete() - { + public function testActuallyRunningJobsThatDelete() { $this->wiki->update(['domain' => 'asdasdaf' . Config::get('wbstack.subdomain_suffix')]); // create db to be deleted $job = new ProvisionWikiDbJob('great_job', 'the_test_database', null); - $job->handle( $this->app->make('db') ); + $job->handle($this->app->make('db')); $res = WikiDb::where([ 'name' => 'the_test_database', 'prefix' => 'great_job', ])->first()->update(['wiki_id' => $this->wiki->id]); - $this->assertTrue( $res ); - $this->assertNotNull( WikiDb::where([ 'wiki_id' => $this->wiki->id ])->first() ); + $this->assertTrue($res); + $this->assertNotNull(WikiDb::where(['wiki_id' => $this->wiki->id])->first()); $mockJob = $this->createMock(Job::class); - $job = new DeleteWikiDispatcherJob(); + $job = new DeleteWikiDispatcherJob; $job->setJob($mockJob); $job->handle(); - $this->assertNull( WikiSetting::whereWikiId($this->wiki->id)->first() ); - $this->assertNull( WikiManager::whereWikiId($this->wiki->id)->first() ); - $this->assertNull( Wiki::whereId($this->wiki->id)->first() ); - $this->assertNull( WikiDb::where([ 'wiki_id' => $this->wiki->id ])->first() ); + $this->assertNull(WikiSetting::whereWikiId($this->wiki->id)->first()); + $this->assertNull(WikiManager::whereWikiId($this->wiki->id)->first()); + $this->assertNull(Wiki::whereId($this->wiki->id)->first()); + $this->assertNull(WikiDb::where(['wiki_id' => $this->wiki->id])->first()); Log::assertLogged(function (LogEntry $log) { if ($log->level !== 'info') { return false; } + return Str::contains($log->message, "Dispatching hard delete job chain for id: {$this->wiki->id}"); }); $mockJob->expects($this->never())->method('fail'); } - } diff --git a/tests/Jobs/DeleteWikiFinalizeJobTest.php b/tests/Jobs/DeleteWikiFinalizeJobTest.php index f5bb8b11a..8d9f25f49 100644 --- a/tests/Jobs/DeleteWikiFinalizeJobTest.php +++ b/tests/Jobs/DeleteWikiFinalizeJobTest.php @@ -2,50 +2,47 @@ namespace Tests\Routes\Auth; +use App\Http\Curl\HttpRequest; +use App\Jobs\DeleteWikiFinalizeJob; use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; -use App\WikiManager; use App\Wiki; +use App\WikiDb; +use App\WikiManager; use App\WikiSetting; use Carbon\Carbon; -use App\Jobs\DeleteWikiFinalizeJob; -use App\WikiDb; -use Illuminate\Support\Facades\Storage; -use App\Http\Curl\HttpRequest; use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Illuminate\Support\Facades\Storage; +use Tests\TestCase; -class DeleteWikiFinalizeJobTest extends TestCase -{ +class DeleteWikiFinalizeJobTest extends TestCase { use DatabaseTransactions; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); Storage::fake('static-assets'); } - public function testDeleteWiki() - { + public function testDeleteWiki() { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->timestamp ] ); + $wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->timestamp]); $manager = WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $setting = WikiSetting::create(['wiki_id' => $wiki->id, 'name' => 'asdf', 'value' => false]); $request = $this->createMock(HttpRequest::class); $request->expects($this->never())->method('execute'); - $job = new DeleteWikiFinalizeJob( $wiki->id ); + $job = new DeleteWikiFinalizeJob($wiki->id); $job->handle($request); - $this->assertNull( Wiki::withTrashed()->where('id', $wiki->id)->first() ); - $this->assertNull( WikiManager::whereId($manager->id)->first() ); - $this->assertNull( WikiSetting::whereId($setting->id)->first() ); + $this->assertNull(Wiki::withTrashed()->where('id', $wiki->id)->first()); + $this->assertNull(WikiManager::whereId($manager->id)->first()); + $this->assertNull(WikiSetting::whereId($setting->id)->first()); } - public function testDoesNotDeleteWhenResourcesStillExist() - { + public function testDoesNotDeleteWhenResourcesStillExist() { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->timestamp ] ); + $wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->timestamp]); $manager = WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $setting = WikiSetting::create(['wiki_id' => $wiki->id, 'name' => 'asdf', 'value' => false]); $wikiDbName = 'wikiDbName'; @@ -55,7 +52,7 @@ public function testDoesNotDeleteWhenResourcesStillExist() 'password' => 'asdasfasfasf', 'version' => 'asdasdasdas', 'prefix' => 'asdasd', - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); $mockResponse = "index\n" . "{$wikiDbName}_content_blabla\n" . "{$wikiDbName}_general_bla\n"; @@ -69,44 +66,42 @@ public function testDoesNotDeleteWhenResourcesStillExist() new \RuntimeException("Elasticsearch indices with basename {$wikiDbName} still exists in http://localhost:9200") ); - $job = new DeleteWikiFinalizeJob( $wiki->id ); + $job = new DeleteWikiFinalizeJob($wiki->id); $job->setJob($mockJob); $job->handle($request); // TODO should this dispatch the deletion job if some resources still existed? // should not delete because WikiDB job probably failed and couldn't delete - $this->assertNotNull( Wiki::withTrashed()->where('id', $wiki->id)->first() ); - $this->assertNotNull( WikiManager::whereId($manager->id)->first() ); - $this->assertNotNull( WikiSetting::whereId($setting->id)->first() ); - $this->assertNotNull( WikiDb::whereId($wikiDB->id)->first() ); + $this->assertNotNull(Wiki::withTrashed()->where('id', $wiki->id)->first()); + $this->assertNotNull(WikiManager::whereId($manager->id)->first()); + $this->assertNotNull(WikiSetting::whereId($setting->id)->first()); + $this->assertNotNull(WikiDb::whereId($wikiDB->id)->first()); } - public function testDoesNotDeleteNonDeletedWikis() - { + public function testDoesNotDeleteNonDeletedWikis() { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => null ] ); + $wiki = Wiki::factory()->create(['deleted_at' => null]); $manager = WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $setting = WikiSetting::create(['wiki_id' => $wiki->id, 'name' => 'asdf', 'value' => false]); $request = $this->createMock(HttpRequest::class); $request->expects($this->never())->method('execute'); - $job = new DeleteWikiFinalizeJob( $wiki->id ); + $job = new DeleteWikiFinalizeJob($wiki->id); $job->handle($request); // should not get deleted when deleted_at is not set to something. - $this->assertNotNull( Wiki::withTrashed()->where('id', $wiki->id)->first() ); - $this->assertNotNull( WikiManager::whereId($manager->id)->first() ); - $this->assertNotNull( WikiSetting::whereId($setting->id)->first() ); + $this->assertNotNull(Wiki::withTrashed()->where('id', $wiki->id)->first()); + $this->assertNotNull(WikiManager::whereId($manager->id)->first()); + $this->assertNotNull(WikiSetting::whereId($setting->id)->first()); } - public function testDeletesFiles() - { + public function testDeletesFiles() { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->timestamp ] ); + $wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->timestamp]); $manager = WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $setting = WikiSetting::create(['wiki_id' => $wiki->id, 'name' => WikiSetting::wgFavicon, 'value' => false]); @@ -120,13 +115,13 @@ public function testDeletesFiles() $request = $this->createMock(HttpRequest::class); $request->expects($this->never())->method('execute'); - $job = new DeleteWikiFinalizeJob( $wiki->id ); + $job = new DeleteWikiFinalizeJob($wiki->id); $job->handle($request); // deletion happened - $this->assertNull( Wiki::withTrashed()->where('id', $wiki->id)->first() ); - $this->assertNull( WikiManager::whereId($manager->id)->first() ); - $this->assertNull( WikiSetting::whereId($setting->id)->first() ); + $this->assertNull(Wiki::withTrashed()->where('id', $wiki->id)->first()); + $this->assertNull(WikiManager::whereId($manager->id)->first()); + $this->assertNull(WikiSetting::whereId($setting->id)->first()); // site dir gone Storage::disk('static-assets')->assertMissing($siteDir); diff --git a/tests/Jobs/DeleteWikiJobTest.php b/tests/Jobs/DeleteWikiJobTest.php index 0a6c00d27..d9943bd1d 100644 --- a/tests/Jobs/DeleteWikiJobTest.php +++ b/tests/Jobs/DeleteWikiJobTest.php @@ -2,45 +2,44 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Tests\TestCase; use App\Jobs\DeleteWikiDbJob; +use App\Jobs\ProvisionWikiDbJob; use App\User; use App\Wiki; -use App\WikiManager; use App\WikiDb; -use App\Jobs\ProvisionWikiDbJob; -use Illuminate\Support\Facades\DB; -use Illuminate\Contracts\Queue\Job; +use App\WikiManager; use Carbon\Carbon; -use PDOException; -use PHPUnit\TextUI\RuntimeException; -use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Contracts\Queue\Job; use Illuminate\Database\DatabaseManager; +use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\DB; +use PDOException; +use Tests\TestCase; -class DeleteWikiJobTest extends TestCase -{ +class DeleteWikiJobTest extends TestCase { use DispatchesJobs; use RefreshDatabase; private $wiki; + protected $connectionsToTransact = ['mysql', 'mw']; protected function setUp(): void { parent::setUp(); - DB::delete( "DELETE FROM wiki_dbs WHERE name='the_test_database';" ); - DB::delete( "DELETE FROM wiki_dbs WHERE name='the_test_database_not_to_be_deleted';" ); + DB::delete("DELETE FROM wiki_dbs WHERE name='the_test_database';"); + DB::delete("DELETE FROM wiki_dbs WHERE name='the_test_database_not_to_be_deleted';"); // The following statement breaks RefreshDatabase DB::connection('mysql')->getPdo()->exec('DROP DATABASE IF EXISTS the_test_database; DROP DATABASE IF EXISTS the_test_database_not_to_be_deleted'); } - private function getExpectedDeletedDatabaseName( $wiki ): string { - return "mwdb_deleted_1631534400_" . $wiki->id; + private function getExpectedDeletedDatabaseName($wiki): string { + return 'mwdb_deleted_1631534400_' . $wiki->id; } - private function getResultValues( $resultRows ) { + private function getResultValues($resultRows) { $results = []; - foreach($resultRows as $row) { + foreach ($resultRows as $row) { $results[] = array_unique(array_values($row))[0]; } @@ -56,39 +55,38 @@ public function testDispatching() { $job->handle($this->app->make('db')); } - public function testDeletesWiki() - { + public function testDeletesWiki() { $this->markTestSkipped('Pollutes the deleted wiki list'); // This is harder to resolve // because the setup is guaranteed to end the // transaction that refresh database has started ue to the DROP statement Carbon::setTestNow(Carbon::create(2021, 9, 13, 12)); $user = User::factory()->create(['verified' => true]); - $this->wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->timestamp ] ); + $this->wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->timestamp]); WikiManager::factory()->create(['wiki_id' => $this->wiki->id, 'user_id' => $user->id]); $databaseName = 'the_test_database'; - $expectedDeletedName = $this->getExpectedDeletedDatabaseName( $this->wiki ); + $expectedDeletedName = $this->getExpectedDeletedDatabaseName($this->wiki); $databases = [ [ - "prefix" => "prefix", - "name" => "the_test_database" + 'prefix' => 'prefix', + 'name' => 'the_test_database', ], [ - "prefix" => "prefix2", - "name" => "the_test_database_not_to_be_deleted" - ] + 'prefix' => 'prefix2', + 'name' => 'the_test_database_not_to_be_deleted', + ], ]; // Would be injected by the app $manager = $this->app->make('db'); - + $job = new ProvisionWikiDbJob($databases[0]['prefix'], $databases[0]['name'], null); $job->handle($manager); // Would be injected by the app $manager = $this->app->make('db'); - + $job = new ProvisionWikiDbJob($databases[1]['prefix'], $databases[1]['name'], null); $job->handle($manager); @@ -100,14 +98,14 @@ public function testDeletesWiki() ])->first()->update(['wiki_id' => $this->wiki->id]); // make sure it stuck - $wikiDB = WikiDb::where([ 'wiki_id' => $this->wiki->id ])->first(); - $this->assertNotNull( $wikiDB ); + $wikiDB = WikiDb::where(['wiki_id' => $this->wiki->id])->first(); + $this->assertNotNull($wikiDB); // get a new connection and look at the tables for later assertions $conn = $this->app->make('db')->connection('mw'); $pdo = $conn->getPdo(); $pdo->exec("USE {$wikiDB->name}"); - $initialTables = $pdo->query("SHOW TABLES")->fetchAll(); + $initialTables = $pdo->query('SHOW TABLES')->fetchAll(); $conn->disconnect(); // we now have some mediawiki tables here @@ -120,7 +118,7 @@ public function testDeletesWiki() $manager = $this->app->make('db'); // this job will kill the underlying connection - $job = new DeleteWikiDbJob( $this->wiki->id ); + $job = new DeleteWikiDbJob($this->wiki->id); $job->setJob($mockJob); $job->handle($manager); @@ -128,43 +126,42 @@ public function testDeletesWiki() $conn = $this->app->make('db')->connection('mw'); $pdo = $conn->getPdo(); $pdo->exec("USE {$wikiDB->name}"); - $databases = $this->getResultValues($pdo->query("SHOW DATABASES")->fetchAll()); + $databases = $this->getResultValues($pdo->query('SHOW DATABASES')->fetchAll()); - $this->assertNull( WikiDb::where([ 'wiki_id' => $this->wiki->id ])->first() ); + $this->assertNull(WikiDb::where(['wiki_id' => $this->wiki->id])->first()); // Both databases now exist, nothing has been dropped - $this->assertContains( $expectedDeletedName, $databases); + $this->assertContains($expectedDeletedName, $databases); // after delete job we don't have any tables here any more - $this->assertCount(0, $this->getResultValues( $pdo->query("SHOW TABLES")->fetchAll())); + $this->assertCount(0, $this->getResultValues($pdo->query('SHOW TABLES')->fetchAll())); // all tables are now in the new deleted database $pdo->exec("USE {$expectedDeletedName}"); - $this->assertCount(87, $this->getResultValues( $pdo->query("SHOW TABLES")->fetchAll())); + $this->assertCount(87, $this->getResultValues($pdo->query('SHOW TABLES')->fetchAll())); // Content now live in the deleted database $result = $pdo->query(sprintf('SELECT * FROM %s.interwiki', $expectedDeletedName))->fetchAll(); $this->assertCount(66, $result); // cleanup test deleted database - $pdo->exec("DROP DATABASE {$this->getExpectedDeletedDatabaseName( $this->wiki )}"); + $pdo->exec("DROP DATABASE {$this->getExpectedDeletedDatabaseName($this->wiki)}"); // Tables no longer exist in the old one $this->expectException(PDOException::class); $this->expectExceptionMessage("SQLSTATE[42S02]: Base table or view not found: 1146 Table 'the_test_database.prefix_interwiki' doesn't exist"); - $pdo->exec(sprintf('SELECT * FROM %s.%s_interwiki', $databaseName, $wikiDB->prefix )); + $pdo->exec(sprintf('SELECT * FROM %s.%s_interwiki', $databaseName, $wikiDB->prefix)); } /** - * @dataProvider failureProvider - */ - public function testFailure( $wiki_id, $deleted_at, string $expectedFailure) - { + * @dataProvider failureProvider + */ + public function testFailure($wiki_id, $deleted_at, string $expectedFailure) { $this->markTestSkipped('Pollutes the deleted wiki list'); // This is harder to resolve // because the setup is guaranteed to end the // transaction that refresh database has started ue to the DROP statement if ($wiki_id !== -1) { - $wiki = Wiki::factory()->create( [ 'deleted_at' => $deleted_at ] ); + $wiki = Wiki::factory()->create(['deleted_at' => $deleted_at]); $wiki_id = $wiki->id; } @@ -172,16 +169,15 @@ public function testFailure( $wiki_id, $deleted_at, string $expectedFailure) $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) - ->method('fail') - ->with(new \RuntimeException(str_replace('', $wiki_id, $expectedFailure))); - + ->method('fail') + ->with(new \RuntimeException(str_replace('', $wiki_id, $expectedFailure))); + $job = new DeleteWikiDbJob($wiki_id); $job->setJob($mockJob); $job->handle($mockMananger); } - static public function failureProvider() - { + public static function failureProvider() { yield [ -1, diff --git a/tests/Jobs/ElasticSearch/ElasticSearchIndexDeleteTest.php b/tests/Jobs/ElasticSearch/ElasticSearchIndexDeleteTest.php index 8ab9b4f42..2aa2d536b 100644 --- a/tests/Jobs/ElasticSearch/ElasticSearchIndexDeleteTest.php +++ b/tests/Jobs/ElasticSearch/ElasticSearchIndexDeleteTest.php @@ -2,26 +2,28 @@ namespace Tests\Jobs\ElasticSearch; -use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; use App\Http\Curl\HttpRequest; -use App\WikiManager; -use App\WikiSetting; -use App\Wiki; use App\Jobs\ElasticSearchIndexDelete; +use App\User; +use App\Wiki; use App\WikiDb; +use App\WikiManager; +use App\WikiSetting; use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Config; +use Tests\TestCase; -class ElasticSearchIndexDeleteTest extends TestCase -{ +class ElasticSearchIndexDeleteTest extends TestCase { use DatabaseTransactions; + private $wiki; + private $user; + private $wikiDb; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->user = User::factory()->create(['verified' => true]); @@ -31,16 +33,15 @@ public function setUp(): void { [ 'wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, - 'value' => true + 'value' => true, ] ); $this->wikiDb = WikiDb::factory()->create([ - 'wiki_id' => $this->wiki->id + 'wiki_id' => $this->wiki->id, ]); } - public function testDeletesElasticSearchIndex() - { + public function testDeletesElasticSearchIndex() { $this->wiki->delete(); $wikiBaseName = $this->wikiDb->name; @@ -52,33 +53,30 @@ public function testDeletesElasticSearchIndex() ->method('execute') ->willReturnOnConsecutiveCalls($mockResponse, $mockJsonSuccess); - $request->expects($this->exactly(2)) ->method('setOptions'); - $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new ElasticSearchIndexDelete( $this->wiki->id ); - $job->setJob( $mockJob ); - $job->handle( $request ); + $job = new ElasticSearchIndexDelete($this->wiki->id); + $job->setJob($mockJob); + $job->handle($request); // feature should get disabled $this->assertSame( - 1, - WikiSetting::where( ['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => false])->count() + 1, + WikiSetting::where(['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => false])->count() ); } /** - * @dataProvider failureProvider - */ - public function testFailure(string $expectedFailure, $mockResponse, $settingStateInDatabase, $deleteWiki = true ) - { + * @dataProvider failureProvider + */ + public function testFailure(string $expectedFailure, $mockResponse, $settingStateInDatabase, $deleteWiki = true) { $request = $this->createMock(HttpRequest::class); - if ( $deleteWiki ) { + if ($deleteWiki) { $this->wiki->delete(); } @@ -87,24 +85,24 @@ public function testFailure(string $expectedFailure, $mockResponse, $settingStat $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) - ->method('fail') - ->with(new \RuntimeException($expectedFailure)); + ->method('fail') + ->with(new \RuntimeException($expectedFailure)); $request->method('execute') - ->willReturnOnConsecutiveCalls( ...$mockResponse ); + ->willReturnOnConsecutiveCalls(...$mockResponse); $job = new ElasticSearchIndexDelete($this->wiki->id); $job->setJob($mockJob); - $job->handle( $request ); + $job->handle($request); $this->assertSame( - 1, - WikiSetting::where( ['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => $settingStateInDatabase])->count() + 1, + WikiSetting::where(['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => $settingStateInDatabase])->count() ); } - static public function failureProvider() { + public static function failureProvider() { $mockResponse = "index\n" . "some_index_content_blabla\n" . "some_index_general_bla\n"; $mockJsonSuccess = '{"acknowledged" : true}'; @@ -114,30 +112,29 @@ static public function failureProvider() { yield [ 'ElasticSearchIndexDelete job for was not successful: {"acknowledged" : false}', - [ $mockResponse, $mockFailure ], - true + [$mockResponse, $mockFailure], + true, ]; yield [ 'ElasticSearchIndexDelete job for was not successful: ', - [ $mockResponse, '' ], - true + [$mockResponse, ''], + true, ]; if ($elasticSearchHost) { yield [ - 'Response looks weird when querying http://'.$elasticSearchHost.'/_cat/indices/*?v&s=index&h=index', - [ "asdasd\n\nasdasd", $mockJsonSuccess ], - true + 'Response looks weird when querying http://' . $elasticSearchHost . '/_cat/indices/*?v&s=index&h=index', + ["asdasd\n\nasdasd", $mockJsonSuccess], + true, ]; } yield [ 'ElasticSearchIndexDelete job for but that wiki is not marked as deleted.', - [$mockResponse, $mockJsonSuccess ], + [$mockResponse, $mockJsonSuccess], true, - false // will not delete the wiki + false, // will not delete the wiki ]; } - } diff --git a/tests/Jobs/FailStalledEntityImportsJobTest.php b/tests/Jobs/FailStalledEntityImportsJobTest.php index 6a6270db5..55d29d3b0 100644 --- a/tests/Jobs/FailStalledEntityImportsJobTest.php +++ b/tests/Jobs/FailStalledEntityImportsJobTest.php @@ -2,35 +2,31 @@ namespace Tests\Jobs; -use App\WikiEntityImportStatus; -use Tests\TestCase; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Contracts\Queue\Job; -use Carbon\Carbon; +use App\Jobs\FailStalledEntityImportsJob; use App\Wiki; use App\WikiEntityImport; -use App\Jobs\FailStalledEntityImportsJob; - -class FailStalledEntityImportsJobTest extends TestCase -{ +use App\WikiEntityImportStatus; +use Carbon\Carbon; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\TestCase; +class FailStalledEntityImportsJobTest extends TestCase { use RefreshDatabase; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); WikiEntityImport::query()->delete(); Wiki::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { WikiEntityImport::query()->delete(); Wiki::query()->delete(); parent::tearDown(); } - public function testFailsEligible() - { + + public function testFailsEligible() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); WikiEntityImport::factory()->create([ 'wiki_id' => $wiki->id, @@ -51,7 +47,7 @@ public function testFailsEligible() $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new FailStalledEntityImportsJob(); + $job = new FailStalledEntityImportsJob; $job->setJob($mockJob); $job->handle(); diff --git a/tests/Jobs/Integration/ElasticSearchIndexDeleteTest.php b/tests/Jobs/Integration/ElasticSearchIndexDeleteTest.php index 5f091010b..1578bb22f 100644 --- a/tests/Jobs/Integration/ElasticSearchIndexDeleteTest.php +++ b/tests/Jobs/Integration/ElasticSearchIndexDeleteTest.php @@ -2,18 +2,18 @@ namespace Tests\Jobs\Integration; +use App\Http\Curl\CurlRequest; +use App\Jobs\ElasticSearchIndexDelete; use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; -use App\WikiManager; -use App\WikiSetting; use App\Wiki; -use App\Jobs\ElasticSearchIndexDelete; -use App\Http\Curl\CurlRequest; use App\WikiDb; +use App\WikiManager; +use App\WikiSetting; use Illuminate\Contracts\Queue\Job; use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Config; +use Tests\TestCase; /** * This is only meant to run when services is started with @@ -25,17 +25,17 @@ * * Example: docker-compose exec -e RUN_PHPUNIT_INTEGRATION_TEST=1 -e ELASTICSEARCH_HOST=elasticsearch.svc:9200 -T api vendor/bin/phpunit tests/Jobs/Integration/ElasticSearchIndexDeleteTest.php */ -class ElasticSearchIndexDeleteTest extends TestCase -{ +class ElasticSearchIndexDeleteTest extends TestCase { use DatabaseTransactions; use DispatchesJobs; private $wiki; + private $user; - public function makeRequest( $url, $method = 'GET' ) { + public function makeRequest($url, $method = 'GET') { // create some dummy index - $curlRequest = new CurlRequest(); + $curlRequest = new CurlRequest; $curlRequest->setOptions( [ CURLOPT_URL => $url, @@ -50,7 +50,7 @@ public function makeRequest( $url, $method = 'GET' ) { $err = $curlRequest->error(); var_dump($response); - if( $err ) { + if ($err) { var_dump($err); } $curlRequest->close(); @@ -58,19 +58,17 @@ public function makeRequest( $url, $method = 'GET' ) { return json_decode($response, true); } - public function testDeletion() - { - if ( !getenv('RUN_PHPUNIT_INTEGRATION_TEST') ) { + public function testDeletion() { + if (!getenv('RUN_PHPUNIT_INTEGRATION_TEST')) { $this->markTestSkipped('No blazegraph instance to connect to'); } $ELASTICSEARCH_HOST = data_get(Config::get('wbstack.elasticsearch_hosts'), 0); - if ( !$ELASTICSEARCH_HOST ) { + if (!$ELASTICSEARCH_HOST) { throw new \Exception('ELASTICSEARCH_HOST / wbstack.elasticsearch_hosts not set'); } - $response = $this->makeRequest("http://$ELASTICSEARCH_HOST/someotherdbname_general_first?pretty", 'PUT'); $this->assertTrue($response['acknowledged']); @@ -87,24 +85,24 @@ public function testDeletion() [ 'wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, - 'value' => false + 'value' => false, ] ); WikiDb::factory()->create([ 'wiki_id' => $this->wiki->id, - 'name' => 'test_db_name' + 'name' => 'test_db_name', ]); $this->wiki->delete(); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new ElasticSearchIndexDelete( $this->wiki->id); + $job = new ElasticSearchIndexDelete($this->wiki->id); $job->setJob($mockJob); $this->dispatchSync($job); // feature should get disabled - $this->assertNull( WikiSetting::where( ['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->first()); + $this->assertNull(WikiSetting::where(['wiki_id' => $this->wiki->id, 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => true])->first()); // first index should be gone $response = $this->makeRequest("http://$ELASTICSEARCH_HOST/test_db_name_content_first?pretty"); @@ -121,5 +119,4 @@ public function testDeletion() $this->makeRequest("http://$ELASTICSEARCH_HOST/someotherdbname_general_first?pretty", 'DELETE'); } - } diff --git a/tests/Jobs/Integration/QueryserviceNamespaceJobTest.php b/tests/Jobs/Integration/QueryserviceNamespaceJobTest.php index 2b95e3a81..cdda8b8cd 100644 --- a/tests/Jobs/Integration/QueryserviceNamespaceJobTest.php +++ b/tests/Jobs/Integration/QueryserviceNamespaceJobTest.php @@ -2,45 +2,43 @@ namespace Tests\Jobs\Integration; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; +use App\Jobs\DeleteQueryserviceNamespaceJob; use App\Jobs\ProvisionQueryserviceNamespaceJob; use App\QueryserviceNamespace; -use App\Jobs\DeleteQueryserviceNamespaceJob; use App\User; use App\Wiki; use App\WikiManager; -use Illuminate\Support\Facades\DB; use Carbon\Carbon; use Illuminate\Contracts\Queue\Job; use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Illuminate\Support\Facades\DB; +use Tests\TestCase; /** - * This is only meant to run when services is started with + * This is only meant to run when services is started with * additional services from docker-compose.integration.yml - * + * * Example: docker-compose exec -e RUN_PHPUNIT_INTEGRATION_TEST=1 -T api vendor/bin/phpunit tests/Jobs/Integration/QueryserviceNamespaceJobTest.php */ -class QueryserviceNamespaceJobTest extends TestCase -{ +class QueryserviceNamespaceJobTest extends TestCase { use DatabaseTransactions; use DispatchesJobs; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); - if ( !getenv('RUN_PHPUNIT_INTEGRATION_TEST') ) { + if (!getenv('RUN_PHPUNIT_INTEGRATION_TEST')) { $this->markTestSkipped('No blazegraph instance to connect to'); - } + } } - public function testIntegrationCreate() - { + public function testIntegrationCreate() { // both jobs should pass $mockJob = $this->createMock(Job::class); - $mockJob->expects($this->never()) ->method('fail'); + $mockJob->expects($this->never())->method('fail'); $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->subDays(30)->timestamp ] ); + $wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->subDays(30)->timestamp]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $namespace = 'testnamespace'; @@ -48,7 +46,7 @@ public function testIntegrationCreate() $job->setJob($mockJob); $this->dispatchSync($job); - DB::table('queryservice_namespaces')->where(['namespace'=>$namespace])->limit(1)->update(['wiki_id' => $wiki->id]); + DB::table('queryservice_namespaces')->where(['namespace' => $namespace])->limit(1)->update(['wiki_id' => $wiki->id]); $this->assertNotNull( QueryserviceNamespace::whereWikiId($wiki->id)->first() @@ -62,5 +60,4 @@ public function testIntegrationCreate() QueryserviceNamespace::whereWikiId($wiki->id)->first() ); } - -} \ No newline at end of file +} diff --git a/tests/Jobs/KubernetesIngressCreateTest.php b/tests/Jobs/KubernetesIngressCreateTest.php index 4dc4ccbcc..5e484c51d 100644 --- a/tests/Jobs/KubernetesIngressCreateTest.php +++ b/tests/Jobs/KubernetesIngressCreateTest.php @@ -2,39 +2,37 @@ namespace Tests\Jobs; +use App\Jobs\KubernetesIngressCreate; use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; use App\Wiki; use App\WikiManager; -use Illuminate\Contracts\Queue\Job; -use App\Jobs\KubernetesIngressCreate; -use Maclof\Kubernetes\Client; -use Http\Adapter\Guzzle7\Client as GuzzleClient; -use GuzzleHttp\HandlerStack; use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; +use Http\Adapter\Guzzle7\Client as GuzzleClient; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Maclof\Kubernetes\Client; +use Tests\TestCase; -class KubernetesIngressCreateTest extends TestCase -{ +class KubernetesIngressCreateTest extends TestCase { use DatabaseTransactions; - public function testCreateIngressJobDoesNotFail() - { + public function testCreateIngressJobDoesNotFail() { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => null ] ); + $wiki = Wiki::factory()->create(['deleted_at' => null]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new KubernetesIngressCreate( $wiki->id, "example.com" ); + $job = new KubernetesIngressCreate($wiki->id, 'example.com'); $job->setJob($mockJob); $mock = new MockHandler([ - new Response(200, [], json_encode([ 'items' => [] ]) ), - new Response(201, [], json_encode([])) + new Response(200, [], json_encode(['items' => []])), + new Response(201, [], json_encode([])), ]); $handlerStack = HandlerStack::create($mock); diff --git a/tests/Jobs/KubernetesIngressDeleteJobTest.php b/tests/Jobs/KubernetesIngressDeleteJobTest.php index ebdbc288b..6ec9e0ed0 100644 --- a/tests/Jobs/KubernetesIngressDeleteJobTest.php +++ b/tests/Jobs/KubernetesIngressDeleteJobTest.php @@ -2,27 +2,25 @@ namespace Tests\Jobs; -use App\User; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; use App\Jobs\KubernetesIngressDeleteJob; +use App\User; use App\Wiki; use App\WikiManager; use Illuminate\Contracts\Queue\Job; -use Maclof\Kubernetes\Client; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\App; +use Maclof\Kubernetes\Client; +use Tests\TestCase; -class KubernetesIngressDeleteJobTest extends TestCase -{ +class KubernetesIngressDeleteJobTest extends TestCase { use DatabaseTransactions; - public function testDoesNotDeleteNonDeletedWikis() - { - + public function testDoesNotDeleteNonDeletedWikis() { + $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => null ] ); + $wiki = Wiki::factory()->create(['deleted_at' => null]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); - + $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) ->method('fail') @@ -30,11 +28,10 @@ public function testDoesNotDeleteNonDeletedWikis() $job = new KubernetesIngressDeleteJob($wiki->id); $job->setJob($mockJob); - - App::call(function ( Client $client ) use ($job) { - $job->handle( $client ); - } ); - } + App::call(function (Client $client) use ($job) { + $job->handle($client); + }); + } } diff --git a/tests/Jobs/MediawikiInitTest.php b/tests/Jobs/MediawikiInitTest.php index 7892b7e03..6398b9b65 100644 --- a/tests/Jobs/MediawikiInitTest.php +++ b/tests/Jobs/MediawikiInitTest.php @@ -2,27 +2,26 @@ namespace Tests\Jobs; -use Tests\TestCase; use App\Http\Curl\HttpRequest; -use Illuminate\Contracts\Queue\Job; -use PHPUnit\TextUI\RuntimeException; use App\Jobs\MediawikiInit; +use Illuminate\Contracts\Queue\Job; +use Tests\TestCase; -class MediawikiInitTest extends TestCase -{ - +class MediawikiInitTest extends TestCase { private $wikiDomain; + private $email; + private $username; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); - $this->wikiDomain = "some.domain.com"; - $this->username = "username"; - $this->email = "some@email.com"; + $this->wikiDomain = 'some.domain.com'; + $this->username = 'username'; + $this->email = 'some@email.com'; } - private function getMockRequest( string $mockResponse ): HttpRequest { + private function getMockRequest(string $mockResponse): HttpRequest { $request = $this->createMock(HttpRequest::class); $request->method('execute')->willReturn($mockResponse); @@ -30,7 +29,7 @@ private function getMockRequest( string $mockResponse ): HttpRequest { ->method('setOptions') ->with( [ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackInit&format=json', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackInit&format=json', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_TIMEOUT => 60, @@ -42,7 +41,7 @@ private function getMockRequest( string $mockResponse ): HttpRequest { ]), CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wikiDomain, + 'host: ' . $this->wikiDomain, ], ] ); @@ -50,31 +49,29 @@ private function getMockRequest( string $mockResponse ): HttpRequest { return $request; } - public function testSuccess() - { + public function testSuccess() { $mockResponse = [ 'warnings' => [], 'wbstackInit' => [ - "success" => 1, - "output" => [] - ] + 'success' => 1, + 'output' => [], + ], ]; $mockResponseString = json_encode($mockResponse); - $request = $this->getMockRequest( $mockResponseString ); + $request = $this->getMockRequest($mockResponseString); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); + ->method('fail') + ->withAnyParameters(); - $job = new MediawikiInit( $this->wikiDomain, $this->username, $this->email ); + $job = new MediawikiInit($this->wikiDomain, $this->username, $this->email); $job->setJob($mockJob); $job->handle($request); } - public function testFatalErrorIsHandled() - { + public function testFatalErrorIsHandled() { $mockResponse = 'oh no'; $request = $this->getMockRequest($mockResponse); @@ -82,7 +79,7 @@ public function testFatalErrorIsHandled() $mockJob = $this->createMock(Job::class); - $job = new MediawikiInit( $this->wikiDomain, $this->username, $this->email ); + $job = new MediawikiInit($this->wikiDomain, $this->username, $this->email); $job->setJob($mockJob); $this->expectException(\RuntimeException::class); diff --git a/tests/Jobs/PlatformStatsSummaryJobTest.php b/tests/Jobs/PlatformStatsSummaryJobTest.php index 1616d84c5..282d32131 100644 --- a/tests/Jobs/PlatformStatsSummaryJobTest.php +++ b/tests/Jobs/PlatformStatsSummaryJobTest.php @@ -4,30 +4,32 @@ use App\Constants\MediawikiNamespace; use App\Helper\MWTimestampHelper; -use Carbon\CarbonImmutable; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Support\Facades\Http; -use Tests\TestCase; +use App\Jobs\PlatformStatsSummaryJob; +use App\Jobs\ProvisionWikiDbJob; use App\User; use App\Wiki; -use App\WikiManager; use App\WikiDb; -use App\Jobs\ProvisionWikiDbJob; -use Illuminate\Support\Facades\DB; -use Illuminate\Contracts\Queue\Job; +use App\WikiManager; use Carbon\Carbon; -use App\Jobs\PlatformStatsSummaryJob; +use Carbon\CarbonImmutable; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Http; +use Tests\TestCase; -class PlatformStatsSummaryJobTest extends TestCase -{ +class PlatformStatsSummaryJobTest extends TestCase { use RefreshDatabase; private $numWikis = 5; + private $wikis = []; + private $users = []; - private $db_prefix = "somecoolprefix"; - private $db_name = "some_cool_db_name"; + private $db_prefix = 'somecoolprefix'; + + private $db_name = 'some_cool_db_name'; protected function setUp(): void { parent::setUp(); @@ -48,25 +50,25 @@ protected function tearDown(): void { private function seedWikis() { $manager = $this->app->make('db'); - for($n = 0; $n < $this->numWikis; $n++ ) { + for ($n = 0; $n < $this->numWikis; $n++) { $user = User::factory()->create(['verified' => true]); - $wiki = Wiki::factory()->create( [ 'deleted_at' => null ] ); + $wiki = Wiki::factory()->create(['deleted_at' => null]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $job = new ProvisionWikiDbJob($this->db_prefix . $n, $this->db_name . $n, null); $job->handle($manager); - $wikiDb = WikiDb::whereName($this->db_name.$n)->first(); - $wikiDb->update( ['wiki_id' => $wiki->id] ); + $wikiDb = WikiDb::whereName($this->db_name . $n)->first(); + $wikiDb->update(['wiki_id' => $wiki->id]); $this->wikis[] = $wiki; $this->users[] = $user; } } - public function testQueryGetsStats() - { + + public function testQueryGetsStats() { $this->markTestSkipped('Pollutes the deleted wiki list'); Http::fake(); $this->seedWikis(); @@ -75,41 +77,40 @@ public function testQueryGetsStats() $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new PlatformStatsSummaryJob(); + $job = new PlatformStatsSummaryJob; $job->setJob($mockJob); $job->handle($manager); } - public function testGroupings() - { + public function testGroupings() { $this->markTestSkipped('Pollutes the deleted wiki list'); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new PlatformStatsSummaryJob(); + $job = new PlatformStatsSummaryJob; $job->setJob($mockJob); $wikis = [ - Wiki::factory()->create( [ 'deleted_at' => null, 'domain' => 'wiki1.com' ] ), - Wiki::factory()->create( [ 'deleted_at' => null, 'domain' => 'wiki2.com' ] ), - Wiki::factory()->create( [ 'deleted_at' => CarbonImmutable::now()->subDays(90)->timestamp, 'domain' => 'wiki3.com' ] ), - Wiki::factory()->create( [ 'deleted_at' => null, 'domain' => 'wiki4.com' ] ), - Wiki::factory()->create( [ 'deleted_at' => null, 'domain' => 'wiki5.com' ] ) + Wiki::factory()->create(['deleted_at' => null, 'domain' => 'wiki1.com']), + Wiki::factory()->create(['deleted_at' => null, 'domain' => 'wiki2.com']), + Wiki::factory()->create(['deleted_at' => CarbonImmutable::now()->subDays(90)->timestamp, 'domain' => 'wiki3.com']), + Wiki::factory()->create(['deleted_at' => null, 'domain' => 'wiki4.com']), + Wiki::factory()->create(['deleted_at' => null, 'domain' => 'wiki5.com']), ]; - foreach($wikis as $wiki) { + foreach ($wikis as $wiki) { WikiDb::create([ 'name' => 'mwdb_asdasfasfasf' . $wiki->id, 'user' => 'asdasd', 'password' => 'asdasfasfasf', 'version' => 'asdasdasdas', 'prefix' => 'asdasd', - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); - //Generate some items/properties for testing, each wiki will have 3 props and 9 items + // Generate some items/properties for testing, each wiki will have 3 props and 9 items Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=122&apcontinue=&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ ['title' => 'Property:P1', 'namespace' => MediawikiNamespace::property], @@ -118,7 +119,7 @@ public function testGroupings() ], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=&aplimit=max&format=json' => Http::response([ 'continue' => [ 'apcontinue' => 'Q6', ], @@ -132,7 +133,7 @@ public function testGroupings() ], ], ], 200), - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=Q6&aplimit=max&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&list=allpages&apnamespace=120&apcontinue=Q6&aplimit=max&format=json' => Http::response([ 'query' => [ 'allpages' => [ ['title' => 'Item:Q6', 'namespace' => MediawikiNamespace::item], @@ -140,114 +141,115 @@ public function testGroupings() ['title' => 'Item:Q8', 'namespace' => MediawikiNamespace::item], ['title' => 'Item:Q9', 'namespace' => MediawikiNamespace::item], ], - ] - ], 200) + ], + ], 200), ]); } $stats = [ [ // no edits in last 90days but recent enough to have a lastEdit - "wiki" => "wiki1.com", - "edits" => 1, - "pages" => 1, - "users" => 1, - "active_users" => NULL, - "lastEdit" => MWTimestampHelper::getMWTimestampFromCarbon(CarbonImmutable::now()->subDays(100)), - "first100UsingOauth" => "0", - "platform_summary_version" => "v1" + 'wiki' => 'wiki1.com', + 'edits' => 1, + 'pages' => 1, + 'users' => 1, + 'active_users' => null, + 'lastEdit' => MWTimestampHelper::getMWTimestampFromCarbon(CarbonImmutable::now()->subDays(100)), + 'first100UsingOauth' => '0', + 'platform_summary_version' => 'v1', ], [ // no edits in last 90 days so old that mediawiki reports no last edit - "wiki" => "wiki5.com", - "edits" => 1, - "pages" => 1, - "users" => 1, - "active_users" => NULL, - "lastEdit" => NULL, - "first100UsingOauth" => "0", - "platform_summary_version" => "v1" + 'wiki' => 'wiki5.com', + 'edits' => 1, + 'pages' => 1, + 'users' => 1, + 'active_users' => null, + 'lastEdit' => null, + 'first100UsingOauth' => '0', + 'platform_summary_version' => 'v1', ], [ // empty - "wiki" => "wiki2.com", - "edits" => NULL, - "pages" => NULL, - "users" => NULL, - "active_users" => NULL, - "lastEdit" => NULL, - "first100UsingOauth" => "0", - "platform_summary_version" => "v1" + 'wiki' => 'wiki2.com', + 'edits' => null, + 'pages' => null, + 'users' => null, + 'active_users' => null, + 'lastEdit' => null, + 'first100UsingOauth' => '0', + 'platform_summary_version' => 'v1', ], [ // edited within last 90 days - "wiki" => "wiki4.com", - "edits" => 1, - "pages" => 2, - "users" => 3, - "active_users" => 1, - "lastEdit" => MWTimestampHelper::getMWTimestampFromCarbon(CarbonImmutable::now()), - "first100UsingOauth" => "0", - "platform_summary_version" => "v1" + 'wiki' => 'wiki4.com', + 'edits' => 1, + 'pages' => 2, + 'users' => 3, + 'active_users' => 1, + 'lastEdit' => MWTimestampHelper::getMWTimestampFromCarbon(CarbonImmutable::now()), + 'first100UsingOauth' => '0', + 'platform_summary_version' => 'v1', ], [ // deleted - "wiki" => "wiki3.com", - "edits" => 1, - "pages" => 2, - "users" => 3, - "active_users" => 0, - "lastEdit" => MWTimestampHelper::getMWTimestampFromCarbon(CarbonImmutable::now()), - "first100UsingOauth" => "0", - "platform_summary_version" => "v1" + 'wiki' => 'wiki3.com', + 'edits' => 1, + 'pages' => 2, + 'users' => 3, + 'active_users' => 0, + 'lastEdit' => MWTimestampHelper::getMWTimestampFromCarbon(CarbonImmutable::now()), + 'first100UsingOauth' => '0', + 'platform_summary_version' => 'v1', ], ]; - $groups = $job->prepareStats($stats, $wikis); + $groups = $job->prepareStats($stats, $wikis); $this->assertEquals( [ - "total" => 5, - "deleted" => 1, - "edited_last_90_days" => 1, - "not_edited_last_90_days" => 2, - "empty" => 1, - "total_non_deleted_users" => 5, - "total_non_deleted_active_users" => 1, - "total_non_deleted_pages" => 4, - "total_non_deleted_edits" => 3, - "platform_summary_version" => "v1", - "total_items_count" => 4*9, //there are 4 non-deleted wikis and each has 9 items - "total_properties_count" => 4*3 //there are 4 non-deleted wikis and each has 3 properties + 'total' => 5, + 'deleted' => 1, + 'edited_last_90_days' => 1, + 'not_edited_last_90_days' => 2, + 'empty' => 1, + 'total_non_deleted_users' => 5, + 'total_non_deleted_active_users' => 1, + 'total_non_deleted_pages' => 4, + 'total_non_deleted_edits' => 3, + 'platform_summary_version' => 'v1', + 'total_items_count' => 4 * 9, // there are 4 non-deleted wikis and each has 9 items + 'total_properties_count' => 4 * 3, // there are 4 non-deleted wikis and each has 3 properties ], $groups, ); } - function testCreationStats() { + + public function testCreationStats() { $this->markTestSkipped('Pollutes the deleted wiki list'); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new PlatformStatsSummaryJob(); + $job = new PlatformStatsSummaryJob; $job->setJob($mockJob); Wiki::factory()->create([ - 'created_at' => Carbon::now()->subHours(1) + 'created_at' => Carbon::now()->subHours(1), ]); Wiki::factory()->create([ - 'created_at' => Carbon::now()->subDays(2) + 'created_at' => Carbon::now()->subDays(2), ]); Wiki::factory()->create([ - 'created_at' => Carbon::now()->subDays(90) + 'created_at' => Carbon::now()->subDays(90), ]); User::factory()->create([ - 'created_at' => Carbon::now()->subHours(1) + 'created_at' => Carbon::now()->subHours(1), ]); User::factory()->create([ - 'created_at' => Carbon::now()->subHours(2) + 'created_at' => Carbon::now()->subHours(2), ]); User::factory()->create([ - 'created_at' => Carbon::now()->subDays(200) + 'created_at' => Carbon::now()->subDays(200), ]); - $stats = $job->getCreationStats(); + $stats = $job->getCreationStats(); $this->assertEquals( [ diff --git a/tests/Jobs/PollForMediaWikiJobsJobTest.php b/tests/Jobs/PollForMediaWikiJobsJobTest.php index dfbf6657a..b46b1eb69 100644 --- a/tests/Jobs/PollForMediaWikiJobsJobTest.php +++ b/tests/Jobs/PollForMediaWikiJobsJobTest.php @@ -2,44 +2,40 @@ namespace Tests\Jobs; -use App\Wiki; use App\Jobs\PollForMediaWikiJobsJob; use App\Jobs\ProcessMediaWikiJobsJob; -use Tests\TestCase; +use App\Wiki; use Illuminate\Contracts\Queue\Job; +use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Bus; -use Illuminate\Database\Eloquent\Model; - -class PollForMediaWikiJobsJobTest extends TestCase -{ +use Illuminate\Support\Facades\Http; +use Tests\TestCase; +class PollForMediaWikiJobsJobTest extends TestCase { use RefreshDatabase; private Model $wiki; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); $this->wiki = Wiki::factory()->create(); } - public function testNoJobs() - { + public function testNoJobs() { Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' => Http::response([ 'query' => [ 'statistics' => [ - 'jobs' => 0 - ] - ] - ], 200) + 'jobs' => 0, + ], + ], + ], 200), ]); Bus::fake(); $mockJob = $this->createMock(Job::class); - $job = new PollForMediaWikiJobsJob(); + $job = new PollForMediaWikiJobsJob; $job->setJob($mockJob); $mockJob->expects($this->never())->method('fail'); @@ -48,22 +44,21 @@ public function testNoJobs() Bus::assertNothingDispatched(); } - public function testWithJobs() - { + public function testWithJobs() { Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' => Http::response([ + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' => Http::response([ 'query' => [ 'statistics' => [ - 'jobs' => 3 - ] - ] - ], 200) + 'jobs' => 3, + ], + ], + ], 200), ]); Bus::fake(); $mockJob = $this->createMock(Job::class); - $job = new PollForMediaWikiJobsJob(); + $job = new PollForMediaWikiJobsJob; $job->setJob($mockJob); $mockJob->expects($this->never())->method('fail'); @@ -72,18 +67,17 @@ public function testWithJobs() Bus::assertDispatched(ProcessMediaWikiJobsJob::class); } - public function testWithFailure() - { + public function testWithFailure() { Http::fake([ - getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' => Http::response([ - 'error' => 'Something went wrong' - ], 500) + getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json' => Http::response([ + 'error' => 'Something went wrong', + ], 500), ]); Bus::fake(); $mockJob = $this->createMock(Job::class); - $job = new PollForMediaWikiJobsJob(); + $job = new PollForMediaWikiJobsJob; $job->setJob($mockJob); $mockJob->expects($this->once())->method('markAsFailed'); diff --git a/tests/Jobs/ProcessMediaWikiJobsJobTest.php b/tests/Jobs/ProcessMediaWikiJobsJobTest.php index bc7a4690a..967efabe0 100644 --- a/tests/Jobs/ProcessMediaWikiJobsJobTest.php +++ b/tests/Jobs/ProcessMediaWikiJobsJobTest.php @@ -2,22 +2,20 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Tests\TestCase; -use Illuminate\Contracts\Queue\Job; use App\Jobs\ProcessMediaWikiJobsJob; -use Maclof\Kubernetes\Client; -use Http\Adapter\Guzzle7\Client as GuzzleClient; -use GuzzleHttp\HandlerStack; use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; +use Http\Adapter\Guzzle7\Client as GuzzleClient; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Maclof\Kubernetes\Client; +use Tests\TestCase; -class ProcessMediaWikiJobsJobTest extends TestCase -{ +class ProcessMediaWikiJobsJobTest extends TestCase { use RefreshDatabase; - public function testJobFailOnNoMediaWikiPod() - { + public function testJobFailOnNoMediaWikiPod() { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once())->method('fail'); @@ -25,7 +23,7 @@ public function testJobFailOnNoMediaWikiPod() $job->setJob($mockJob); $mock = new MockHandler([ - new Response(200, [], json_encode([ 'items' => [] ])), + new Response(200, [], json_encode(['items' => []])), ]); $handlerStack = HandlerStack::create($mock); @@ -40,8 +38,7 @@ public function testJobFailOnNoMediaWikiPod() ], null, $mockGuzzle)); } - public function testJobDoesNotFail() - { + public function testJobDoesNotFail() { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); @@ -49,7 +46,7 @@ public function testJobDoesNotFail() $job->setJob($mockJob); $mock = new MockHandler([ - new Response(200, [], json_encode([ 'items' => [ + new Response(200, [], json_encode(['items' => [ [ 'kind' => 'Pod', 'spec' => [ @@ -57,19 +54,19 @@ public function testJobDoesNotFail() [ 'image' => 'helloworld', 'env' => [ - 'SOMETHING' => 'something' - ] - ] - ] - ] - ] + 'SOMETHING' => 'something', + ], + ], + ], + ], + ], ]])), - new Response(200, [], json_encode([ 'items' => [] ])), + new Response(200, [], json_encode(['items' => []])), new Response(201, [], json_encode([ 'metadata' => [ - 'name' => 'some-job-name' - ] - ])) + 'name' => 'some-job-name', + ], + ])), ]); $handlerStack = HandlerStack::create($mock); diff --git a/tests/Jobs/ProvisionQueryserviceNamespaceJobTest.php b/tests/Jobs/ProvisionQueryserviceNamespaceJobTest.php index 40eb2ca73..7b4271e77 100644 --- a/tests/Jobs/ProvisionQueryserviceNamespaceJobTest.php +++ b/tests/Jobs/ProvisionQueryserviceNamespaceJobTest.php @@ -2,62 +2,56 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use Tests\TestCase; use App\Http\Curl\HttpRequest; use App\Jobs\ProvisionQueryserviceNamespaceJob; use App\QueryserviceNamespace; -use App\Jobs\DeleteQueryserviceNamespaceJob; +use Illuminate\Foundation\Testing\DatabaseTransactions; +use Tests\TestCase; -class ProvisionQueryserviceNamespaceJobTest extends TestCase -{ +class ProvisionQueryserviceNamespaceJobTest extends TestCase { use DatabaseTransactions; - public function testCreatesNamespace() - { + public function testCreatesNamespace() { $namespace = 'asdf'; - $mockResponse = 'CREATED: '.$namespace; + $mockResponse = 'CREATED: ' . $namespace; $request = $this->createMock(HttpRequest::class); $request->expects($this->exactly(1)) ->method('execute') - ->willReturn( $mockResponse ); + ->willReturn($mockResponse); - - $properties = file_get_contents(__DIR__.DIRECTORY_SEPARATOR.'../../app/data/RWStore.properties'); + $properties = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . '../../app/data/RWStore.properties'); $properties = str_replace('REPLACE_NAMESPACE', $namespace, $properties); $request->expects($this->exactly(1)) ->method('setOptions') - ->with( - [ - CURLOPT_URL => config('app.queryservice_host').'/bigdata/namespace', - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => '', - CURLOPT_TIMEOUT => 10, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - // User agent is needed by the query service... - CURLOPT_USERAGENT => 'WBStack ProvisionQueryserviceNamespaceJob', - CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_POSTFIELDS => $properties, - CURLOPT_HTTPHEADER => [ - 'content-type: text/plain', - ] - ]); - - + ->with( + [ + CURLOPT_URL => config('app.queryservice_host') . '/bigdata/namespace', + CURLOPT_RETURNTRANSFER => true, + CURLOPT_ENCODING => '', + CURLOPT_TIMEOUT => 10, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, + // User agent is needed by the query service... + CURLOPT_USERAGENT => 'WBStack ProvisionQueryserviceNamespaceJob', + CURLOPT_CUSTOMREQUEST => 'POST', + CURLOPT_POSTFIELDS => $properties, + CURLOPT_HTTPHEADER => [ + 'content-type: text/plain', + ], + ]); + $job = new ProvisionQueryserviceNamespaceJob($namespace, null); $job->handle($request); $this->assertSame( - 1, - QueryserviceNamespace::where( ['namespace' => $namespace ])->count() + 1, + QueryserviceNamespace::where(['namespace' => $namespace])->count() ); } - public function testMaxFree() - { + public function testMaxFree() { $namespace = 'asdf'; $request = $this->createMock(HttpRequest::class); @@ -66,7 +60,7 @@ public function testMaxFree() $request->expects($this->never()) ->method('setOptions'); - + QueryserviceNamespace::where([ 'wiki_id' => null, ])->delete(); @@ -84,8 +78,8 @@ public function testMaxFree() $job->handle($request); $this->assertSame( - 0, - QueryserviceNamespace::where( ['namespace' => $namespace ])->count() + 0, + QueryserviceNamespace::where(['namespace' => $namespace])->count() ); } -} \ No newline at end of file +} diff --git a/tests/Jobs/RequeuePendingQsBatchesJobTest.php b/tests/Jobs/RequeuePendingQsBatchesJobTest.php index b10c11687..259d98f82 100644 --- a/tests/Jobs/RequeuePendingQsBatchesJobTest.php +++ b/tests/Jobs/RequeuePendingQsBatchesJobTest.php @@ -2,31 +2,29 @@ namespace Tests\Jobs; -use App\QsBatch; use App\Jobs\RequeuePendingQsBatchesJob; -use Tests\TestCase; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Contracts\Queue\Job; +use App\QsBatch; use Carbon\Carbon; use Illuminate\Contracts\Debug\ExceptionHandler; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\TestCase; -class RequeuePendingQsBatchesJobTest extends TestCase -{ - +class RequeuePendingQsBatchesJobTest extends TestCase { use RefreshDatabase; - public function setUp(): void { + protected function setUp(): void { // Other tests leave dangling wikis around so we need to clean them up parent::setUp(); QsBatch::query()->delete(); } - public function tearDown(): void { + protected function tearDown(): void { QsBatch::query()->delete(); parent::tearDown(); } - public function testRequeue (): void { + public function testRequeue(): void { QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(200), 'id' => 1, 'done' => 0, 'wiki_id' => 1, 'entityIds' => 'a,b']); QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(400), 'id' => 2, 'done' => 0, 'wiki_id' => 1, 'entityIds' => 'a,b']); QsBatch::factory()->create(['processing_attempts' => 3, 'id' => 3, 'done' => 0, 'wiki_id' => 1, 'entityIds' => 'a,b']); @@ -40,7 +38,7 @@ public function testRequeue (): void { $this->app->instance(ExceptionHandler::class, $mockExceptionHandler); $mockJob = $this->createMock(Job::class); - $job = new RequeuePendingQsBatchesJob(); + $job = new RequeuePendingQsBatchesJob; $job->setJob($mockJob); $mockJob->expects($this->never()) ->method('fail'); diff --git a/tests/Jobs/SendEmptyWikiNotificationsJobTest.php b/tests/Jobs/SendEmptyWikiNotificationsJobTest.php index 0accf7513..7fb09ba36 100644 --- a/tests/Jobs/SendEmptyWikiNotificationsJobTest.php +++ b/tests/Jobs/SendEmptyWikiNotificationsJobTest.php @@ -6,34 +6,31 @@ use App\Notifications\EmptyWikiNotification; use App\User; use App\Wiki; -use App\WikiNotificationSentRecord; use App\WikiLifecycleEvents; use App\WikiManager; +use App\WikiNotificationSentRecord; +use Carbon\Carbon; use Illuminate\Contracts\Queue\Job; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Notification; use Tests\TestCase; -use Carbon\Carbon; -class SendEmptyWikiNotificationsJobTest extends TestCase -{ +class SendEmptyWikiNotificationsJobTest extends TestCase { use RefreshDatabase; // the job does not fail in general - public function testEmptyWikiNotifications_Success() - { + public function testEmptyWikiNotificationsSuccess() { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); - $job = new SendEmptyWikiNotificationsJob(); + ->method('fail') + ->withAnyParameters(); + $job = new SendEmptyWikiNotificationsJob; $job->setJob($mockJob); $job->handle(); } // empty wikis, that are older than 30 days, trigger a notification - public function testEmptyWikiNotifications_SendNotification() - { + public function testEmptyWikiNotificationsSendNotification() { $thresholdDaysAgo = Carbon::now()->subDays( config('wbstack.wiki_empty_notification_threshold') )->toDateTimeString(); @@ -44,7 +41,7 @@ public function testEmptyWikiNotifications_SendNotification() $manager = WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $wiki->wikiLifecycleEvents()->updateOrCreate(['first_edited' => null]); - $job = new SendEmptyWikiNotificationsJob(); + $job = new SendEmptyWikiNotificationsJob; $job->handle(); Notification::assertSentTo( @@ -54,8 +51,7 @@ public function testEmptyWikiNotifications_SendNotification() } // fresh wiki that does not have lifecycle event records yet - public function testEmptyWikiNotifications_FreshWiki() - { + public function testEmptyWikiNotificationsFreshWiki() { $now = Carbon::now()->toDateTimeString(); Notification::fake(); @@ -63,12 +59,12 @@ public function testEmptyWikiNotifications_FreshWiki() $wiki = Wiki::factory()->create(['created_at' => $now]); $manager = WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); - $job = new SendEmptyWikiNotificationsJob(); + $job = new SendEmptyWikiNotificationsJob; $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); + ->method('fail') + ->withAnyParameters(); $job->setJob($mockJob); $job->handle(); @@ -77,8 +73,7 @@ public function testEmptyWikiNotifications_FreshWiki() } // non-empty wikis which are older than 30 days do not trigger notifications - public function testEmptyWikiNotifications_ActiveWiki() - { + public function testEmptyWikiNotificationsActiveWiki() { $thresholdDaysAgo = Carbon::now()->subDays( config('wbstack.wiki_empty_notification_threshold') )->toDateTimeString(); @@ -92,18 +87,17 @@ public function testEmptyWikiNotifications_ActiveWiki() WikiLifecycleEvents::factory()->create([ 'wiki_id' => $wiki->id, - 'first_edited' => $now + 'first_edited' => $now, ]); - $job = new SendEmptyWikiNotificationsJob(); + $job = new SendEmptyWikiNotificationsJob; $job->handle(); Notification::assertNothingSent(); } // notifications do not get sent again - public function testEmptyWikiNotifications_EmptyNotificationReceived() - { + public function testEmptyWikiNotificationsEmptyNotificationReceived() { $thresholdDaysAgo = Carbon::now()->subDays( config('wbstack.wiki_empty_notification_threshold') )->toDateTimeString(); @@ -119,7 +113,7 @@ public function testEmptyWikiNotifications_EmptyNotificationReceived() 'user_id' => $manager->user_id, ]); - $job = new SendEmptyWikiNotificationsJob(); + $job = new SendEmptyWikiNotificationsJob; $job->handle(); Notification::assertNothingSent(); diff --git a/tests/Jobs/SetWikiLogoTest.php b/tests/Jobs/SetWikiLogoTest.php index c5d83e00f..520052a1f 100644 --- a/tests/Jobs/SetWikiLogoTest.php +++ b/tests/Jobs/SetWikiLogoTest.php @@ -15,13 +15,11 @@ use Intervention\Image\Facades\Image; use Tests\TestCase; -class SetWikiLogoTest extends TestCase -{ +class SetWikiLogoTest extends TestCase { use DatabaseTransactions; use DispatchesJobs; - private function assertJobFails(string $wikiKey, string $wikiValue, string $logoPath) - { + private function assertJobFails(string $wikiKey, string $wikiValue, string $logoPath) { $mockJob = $this->createMock(Job::class); $job = new SetWikiLogo($wikiKey, $wikiValue, $logoPath); $job->setJob($mockJob); @@ -30,8 +28,7 @@ private function assertJobFails(string $wikiKey, string $wikiValue, string $logo $job->handle(); } - private function assertJobSucceeds(string $wikiKey, string $wikiValue, string $logoPath) - { + private function assertJobSucceeds(string $wikiKey, string $wikiValue, string $logoPath) { $mockJob = $this->createMock(Job::class); $job = new SetWikiLogo($wikiKey, $wikiValue, $logoPath); $job->setJob($mockJob); @@ -43,8 +40,7 @@ private function assertJobSucceeds(string $wikiKey, string $wikiValue, string $l /** * @dataProvider invalidProvider */ - public function testSetLogoFails($wikiKey, $wikiValue, $logoPath) - { + public function testSetLogoFails($wikiKey, $wikiValue, $logoPath) { $storage = Storage::fake('static-assets'); $this->assertJobFails($wikiKey, $wikiValue, $logoPath); @@ -57,8 +53,7 @@ public function testSetLogoFails($wikiKey, $wikiValue, $logoPath) /** * @dataProvider validProvider */ - public function testSetLogoSucceeds($wikiKey, $wikiValue, $logoPath) - { + public function testSetLogoSucceeds($wikiKey, $wikiValue, $logoPath) { // create user and wiki for this test $user = User::factory()->create(['verified' => true]); $wiki = Wiki::factory('nodb')->create([$wikiKey => $wikiValue]); @@ -107,19 +102,17 @@ public function testSetLogoSucceeds($wikiKey, $wikiValue, $logoPath) $this->assertStringEndsWith($logoDir . '/64.ico', $currentFaviconSettingURL['path']); } - static public function validProvider() - { - # $wikiKey, $wikiValue, $logoPath - yield ['id', 42, __DIR__ . "/../data/logo_200x200.png"]; - yield ['domain', 'example.test.dev', __DIR__ . "/../data/logo_200x200.png"]; + public static function validProvider() { + // $wikiKey, $wikiValue, $logoPath + yield ['id', 42, __DIR__ . '/../data/logo_200x200.png']; + yield ['domain', 'example.test.dev', __DIR__ . '/../data/logo_200x200.png']; } - static public function invalidProvider() - { - # $wikiKey, $wikiValue, $logoPath - yield "id doesn't exist" => ['id', 999, __DIR__ . "/../data/logo_200x200.png"]; - yield "logo path doesn't exist" => ['id', 1, "/invalid/logo/path.png"]; - yield "domain doesn't exist" => ['domain', 'non.existant.dev', __DIR__ . "/../data/logo_200x200.png"]; - yield "invalid key" => ['wikiid', 1, __DIR__ . "/../data/logo_200x200.png"]; + public static function invalidProvider() { + // $wikiKey, $wikiValue, $logoPath + yield "id doesn't exist" => ['id', 999, __DIR__ . '/../data/logo_200x200.png']; + yield "logo path doesn't exist" => ['id', 1, '/invalid/logo/path.png']; + yield "domain doesn't exist" => ['domain', 'non.existant.dev', __DIR__ . '/../data/logo_200x200.png']; + yield 'invalid key' => ['wikiid', 1, __DIR__ . '/../data/logo_200x200.png']; } } diff --git a/tests/Jobs/SiteStatsUpdateJobTest.php b/tests/Jobs/SiteStatsUpdateJobTest.php index e596a22ac..c2cd839d7 100644 --- a/tests/Jobs/SiteStatsUpdateJobTest.php +++ b/tests/Jobs/SiteStatsUpdateJobTest.php @@ -2,28 +2,26 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Tests\TestCase; use App\Http\Curl\HttpRequest; -use Illuminate\Contracts\Queue\Job; -use PHPUnit\TextUI\RuntimeException; +use App\Jobs\SiteStatsUpdateJob; use App\User; use App\Wiki; use App\WikiManager; -use App\Jobs\SiteStatsUpdateJob; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\TestCase; -class SiteStatsUpdateJobTest extends TestCase -{ +class SiteStatsUpdateJobTest extends TestCase { use RefreshDatabase; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $this->user = User::factory()->create(['verified' => true]); $this->wiki = Wiki::factory()->create(); $this->manager = WikiManager::factory()->create(['wiki_id' => $this->wiki->id, 'user_id' => $this->user->id]); } - private function getMockRequest( string $mockResponse ): HttpRequest { + private function getMockRequest(string $mockResponse): HttpRequest { $request = $this->createMock(HttpRequest::class); $request->method('execute')->willReturn($mockResponse); @@ -31,15 +29,15 @@ private function getMockRequest( string $mockResponse ): HttpRequest { ->method('setOptions') ->with( [ - CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=wbstackSiteStatsUpdate&format=json', + CURLOPT_URL => getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=wbstackSiteStatsUpdate&format=json', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', - CURLOPT_TIMEOUT => 60*5, + CURLOPT_TIMEOUT => 60 * 5, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ 'content-type: application/x-www-form-urlencoded', - 'host: '.$this->wiki->domain, + 'host: ' . $this->wiki->domain, ], ] ); @@ -47,34 +45,32 @@ private function getMockRequest( string $mockResponse ): HttpRequest { return $request; } - public function testSuccess() - { + public function testSuccess() { $mockResponse = [ 'warnings' => [], 'wbstackSiteStatsUpdate' => [ - "return" => 0 - ] + 'return' => 0, + ], ]; $mockResponseString = json_encode($mockResponse); - $request = $this->getMockRequest( $mockResponseString ); + $request = $this->getMockRequest($mockResponseString); $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never()) - ->method('fail') - ->withAnyParameters(); + ->method('fail') + ->withAnyParameters(); - $job = new SiteStatsUpdateJob( $this->wiki->id ); + $job = new SiteStatsUpdateJob($this->wiki->id); $job->setJob($mockJob); $job->handle($request); } - public function testFatalErrorIsHandled() - { + public function testFatalErrorIsHandled() { $mockResponse = [ 'wbstackSiteStatsUpdate' => [ - "return" => 1 - ] + 'return' => 1, + ], ]; $mockResponseString = json_encode($mockResponse); @@ -82,10 +78,10 @@ public function testFatalErrorIsHandled() $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) - ->method('fail') - ->with(new \RuntimeException('wbstackSiteStatsUpdate call for ' . $this->wiki->domain . ' was not successful: ' . $mockResponseString )); + ->method('fail') + ->with(new \RuntimeException('wbstackSiteStatsUpdate call for ' . $this->wiki->domain . ' was not successful: ' . $mockResponseString)); - $job = new SiteStatsUpdateJob( $this->wiki->id ); + $job = new SiteStatsUpdateJob($this->wiki->id); $job->setJob($mockJob); $job->handle($request); } diff --git a/tests/Jobs/SpawnQueryserviceUpdaterJobTest.php b/tests/Jobs/SpawnQueryserviceUpdaterJobTest.php index 6a451d457..862de248d 100644 --- a/tests/Jobs/SpawnQueryserviceUpdaterJobTest.php +++ b/tests/Jobs/SpawnQueryserviceUpdaterJobTest.php @@ -2,22 +2,20 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Tests\TestCase; -use Illuminate\Contracts\Queue\Job; use App\Jobs\SpawnQueryserviceUpdaterJob; -use Maclof\Kubernetes\Client; -use Http\Adapter\Guzzle7\Client as GuzzleClient; -use GuzzleHttp\HandlerStack; use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; +use Http\Adapter\Guzzle7\Client as GuzzleClient; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Maclof\Kubernetes\Client; +use Tests\TestCase; -class SpawnQueryserviceUpdaterJobTest extends TestCase -{ +class SpawnQueryserviceUpdaterJobTest extends TestCase { use RefreshDatabase; - public function testJobFailOnNoUpdaterPod() - { + public function testJobFailOnNoUpdaterPod() { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once())->method('fail'); @@ -29,7 +27,7 @@ public function testJobFailOnNoUpdaterPod() $job->setJob($mockJob); $mock = new MockHandler([ - new Response(200, [], json_encode([ 'items' => [] ])), + new Response(200, [], json_encode(['items' => []])), ]); $handlerStack = HandlerStack::create($mock); @@ -44,8 +42,7 @@ public function testJobFailOnNoUpdaterPod() ], null, $mockGuzzle)); } - public function testJobDoesNotFail() - { + public function testJobDoesNotFail() { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); @@ -57,7 +54,7 @@ public function testJobDoesNotFail() $job->setJob($mockJob); $mock = new MockHandler([ - new Response(200, [], json_encode([ 'items' => [ + new Response(200, [], json_encode(['items' => [ [ 'kind' => 'Pod', 'spec' => [ @@ -65,19 +62,19 @@ public function testJobDoesNotFail() [ 'image' => 'helloworld', 'env' => [ - 'SOMETHING' => 'something' - ] - ] - ] - ] - ] + 'SOMETHING' => 'something', + ], + ], + ], + ], + ], ]])), - new Response(200, [], json_encode([ 'items' => [] ])), + new Response(200, [], json_encode(['items' => []])), new Response(201, [], json_encode([ 'metadata' => [ - 'name' => 'some-job-name' - ] - ])) + 'name' => 'some-job-name', + ], + ])), ]); $handlerStack = HandlerStack::create($mock); diff --git a/tests/Jobs/UpdateQueryserviceAllowListTest.php b/tests/Jobs/UpdateQueryserviceAllowListTest.php index ffa09aa0f..cbc6a46e6 100644 --- a/tests/Jobs/UpdateQueryserviceAllowListTest.php +++ b/tests/Jobs/UpdateQueryserviceAllowListTest.php @@ -2,31 +2,28 @@ namespace Tests\Jobs; -use Tests\TestCase; -use Illuminate\Contracts\Queue\Job; use App\Jobs\UpdateQueryserviceAllowList; use App\Wiki; -use Maclof\Kubernetes\Client; -use Http\Adapter\Guzzle7\Client as GuzzleClient; -use GuzzleHttp\HandlerStack; use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; use GuzzleHttp\Psr7\Response; +use Http\Adapter\Guzzle7\Client as GuzzleClient; +use Illuminate\Contracts\Queue\Job; use Illuminate\Foundation\Testing\RefreshDatabase; +use Maclof\Kubernetes\Client; +use Tests\TestCase; -class UpdateQueryserviceAllowListTest extends TestCase -{ +class UpdateQueryserviceAllowListTest extends TestCase { use RefreshDatabase; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::factory()->create(['domain' => 'somesite-5.localhost']); Wiki::factory()->create(['domain' => 'somesite-6.localhost']); } - public function testMissingConfigMapFailure(): void - { + public function testMissingConfigMapFailure(): void { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->once()) ->method('fail') @@ -34,32 +31,31 @@ public function testMissingConfigMapFailure(): void "Queryservice config map 'queryservice-allowlist' does not exist." )); - $job = new UpdateQueryserviceAllowList(); + $job = new UpdateQueryserviceAllowList; $job->setJob($mockJob); $mock = new MockHandler([ new Response(200, [], json_encode(['items' => []])), - new Response(200, [], json_encode(['items' => []])) + new Response(200, [], json_encode(['items' => []])), ]); $handlerStack = HandlerStack::create($mock); $mockGuzzle = GuzzleClient::createWithConfig([ 'handler' => $handlerStack, - 'verify' => '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt' + 'verify' => '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', ]); $job->handle(new Client([ 'master' => 'https://kubernetes.default.svc', - 'token' => '/var/run/secrets/kubernetes.io/serviceaccount/token' + 'token' => '/var/run/secrets/kubernetes.io/serviceaccount/token', ], null, $mockGuzzle)); } - public function testSuccess(): void - { + public function testSuccess(): void { $mockJob = $this->createMock(Job::class); $mockJob->expects($this->never())->method('fail'); - $job = new UpdateQueryserviceAllowList(); + $job = new UpdateQueryserviceAllowList; $job->setJob($mockJob); $mock = new MockHandler([ @@ -69,15 +65,15 @@ public function testSuccess(): void 'data' => [ 'allowlist-static.txt' => implode(PHP_EOL, [ 'https://somesite-1.localhost/query/sparql', - 'https://somesite-2.localhost/query/sparql' + 'https://somesite-2.localhost/query/sparql', ]), 'allowlist.txt' => implode(PHP_EOL, [ 'https://somesite-3.localhost/query/sparql', - 'https://somesite-4.localhost/query/sparql' - ]) - ] + 'https://somesite-4.localhost/query/sparql', + ]), + ], ]]])), - new Response(200, [], json_encode(['items' => []])) + new Response(200, [], json_encode(['items' => []])), ]); $requests = []; @@ -85,12 +81,12 @@ public function testSuccess(): void $handlerStack->push(Middleware::history($requests)); $mockGuzzle = GuzzleClient::createWithConfig([ 'handler' => $handlerStack, - 'verify' => '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt' + 'verify' => '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', ]); $job->handle(new Client([ 'master' => 'https://kubernetes.default.svc', - 'token' => '/var/run/secrets/kubernetes.io/serviceaccount/token' + 'token' => '/var/run/secrets/kubernetes.io/serviceaccount/token', ], null, $mockGuzzle)); $this->assertCount(2, $requests); @@ -101,15 +97,15 @@ public function testSuccess(): void 'data' => [ 'allowlist-static.txt' => implode(PHP_EOL, [ 'https://somesite-1.localhost/query/sparql', - 'https://somesite-2.localhost/query/sparql' + 'https://somesite-2.localhost/query/sparql', ]), 'allowlist.txt' => implode(PHP_EOL, [ 'https://somesite-5.localhost/query/sparql', 'https://somesite-6.localhost/query/sparql', 'https://somesite-1.localhost/query/sparql', - 'https://somesite-2.localhost/query/sparql' - ]) - ] + 'https://somesite-2.localhost/query/sparql', + ]), + ], ], json_decode($requests[1]['request']->getBody(), true) ); diff --git a/tests/Jobs/UpdateWikiDailyMetricJobTest.php b/tests/Jobs/UpdateWikiDailyMetricJobTest.php index 90123c2c7..8982eccf2 100644 --- a/tests/Jobs/UpdateWikiDailyMetricJobTest.php +++ b/tests/Jobs/UpdateWikiDailyMetricJobTest.php @@ -2,6 +2,7 @@ namespace Tests\Jobs; +use App\Jobs\ProvisionWikiDbJob; use App\Jobs\UpdateWikiDailyMetricJob; use App\Wiki; use App\WikiDb; @@ -9,16 +10,11 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Queue; use Tests\TestCase; -use App\Jobs\ProvisionWikiDbJob; - -class UpdateWikiDailyMetricJobTest extends TestCase -{ +class UpdateWikiDailyMetricJobTest extends TestCase { use RefreshDatabase; - - public function testDispatchJob() - { + public function testDispatchJob() { Queue::fake(); UpdateWikiDailyMetricJob::dispatch(); @@ -26,9 +22,7 @@ public function testDispatchJob() Queue::assertPushed(UpdateWikiDailyMetricJob::class); } - - public function testRunJobForAllWikisIncludingDeletedWikis() - { + public function testRunJobForAllWikisIncludingDeletedWikis() { $activeWiki = Wiki::factory()->create([ 'domain' => 'example.wikibase.cloud', ]); @@ -37,22 +31,20 @@ public function testRunJobForAllWikisIncludingDeletedWikis() ]); $manager = $this->app->make('db'); - $job = new ProvisionWikiDbJob(); - $job2 = new ProvisionWikiDbJob(); + $job = new ProvisionWikiDbJob; + $job2 = new ProvisionWikiDbJob; $job->handle($manager); $job2->handle($manager); $wikiDbActive = WikiDb::whereDoesntHave('wiki')->first(); - $wikiDbActive->update( ['wiki_id' => $activeWiki->id] ); + $wikiDbActive->update(['wiki_id' => $activeWiki->id]); $wikiDbDeleted = WikiDb::whereDoesntHave('wiki')->first(); - $wikiDbDeleted->update( ['wiki_id' => $deletedWiki->id] ); + $wikiDbDeleted->update(['wiki_id' => $deletedWiki->id]); $deletedWiki->delete(); - - - (new UpdateWikiDailyMetricJob())->handle(); + (new UpdateWikiDailyMetricJob)->handle(); $this->assertDatabaseHas('wiki_daily_metrics', [ 'wiki_id' => $activeWiki->id, @@ -72,5 +64,4 @@ public function testRunJobForAllWikisIncludingDeletedWikis() 'quarterly_actions' => null, ]); } - } diff --git a/tests/Jobs/UpdateWikiSiteStatsJobTest.php b/tests/Jobs/UpdateWikiSiteStatsJobTest.php index 400579dde..56f9709d6 100644 --- a/tests/Jobs/UpdateWikiSiteStatsJobTest.php +++ b/tests/Jobs/UpdateWikiSiteStatsJobTest.php @@ -2,22 +2,20 @@ namespace Tests\Jobs; -use App\Wiki; use App\Jobs\UpdateWikiSiteStatsJob; -use Tests\TestCase; +use App\Wiki; use Illuminate\Contracts\Queue\Job; use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Support\Facades\Http; use Illuminate\Http\Client\Request; +use Illuminate\Support\Facades\Http; +use Tests\TestCase; -class UpdateWikiSiteStatsJobTest extends TestCase -{ - +class UpdateWikiSiteStatsJobTest extends TestCase { use RefreshDatabase; private $fakeResponses; - public function setUp(): void { + protected function setUp(): void { // Other tests leave dangling wikis around so we need to clean them up parent::setUp(); Wiki::query()->delete(); @@ -25,79 +23,79 @@ public function setUp(): void { Http::preventStrayRequests(); } - public function tearDown(): void { + protected function tearDown(): void { Wiki::query()->delete(); parent::tearDown(); } private function addFakeSiteStatsResponse($site, $response) { - $siteStatsUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json'; + $siteStatsUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&meta=siteinfo&siprop=statistics&format=json'; $this->fakeResponses[$siteStatsUrl][$site] = $response; } private function addFakeRevisionTimestamp($site, $revid, $timestamp) { - $revTimestampUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&format=json&prop=revisions&rvprop=timestamp&formatversion=2&revids=' . $revid; + $revTimestampUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&format=json&prop=revisions&rvprop=timestamp&formatversion=2&revids=' . $revid; $this->fakeResponses[$revTimestampUrl][$site] = Http::response([ 'query' => [ 'pages' => [ [ 'revisions' => [ [ - 'timestamp' => $timestamp - ] - ] - ] - ] - ] + 'timestamp' => $timestamp, + ], + ], + ], + ], + ], ]); } private function addFakeEmptyRevisionList($site) { - $firstRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=newer'; + $firstRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=newer'; $this->fakeResponses[$firstRevisionIdUrl][$site] = Http::response([ 'query' => [ - 'allrevisions' => [] - ] + 'allrevisions' => [], + ], ]); - $lastRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=older'; + $lastRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=older'; $this->fakeResponses[$lastRevisionIdUrl][$site] = Http::response([ 'query' => [ - 'allrevisions' => [] - ] + 'allrevisions' => [], + ], ]); } private function addFakeFirstRevisionId($site, $id) { - $firstRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=newer'; + $firstRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=newer'; $this->fakeResponses[$firstRevisionIdUrl][$site] = Http::response([ 'query' => [ 'allrevisions' => [ [ 'revisions' => [ [ - 'revid' => $id - ] - ] - ] - ] - ] + 'revid' => $id, + ], + ], + ], + ], + ], ]); } private function addFakeLastRevisionId($site, $id) { - $lastRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST').'/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=older'; + $lastRevisionIdUrl = getenv('PLATFORM_MW_BACKEND_HOST') . '/w/api.php?action=query&format=json&list=allrevisions&formatversion=2&arvlimit=1&arvprop=ids&arvexcludeuser=PlatformReservedUser&arvdir=older'; $this->fakeResponses[$lastRevisionIdUrl][$site] = Http::response([ 'query' => [ 'allrevisions' => [ [ 'revisions' => [ [ - 'revid' => $id - ] - ] - ] - ] - ] + 'revid' => $id, + ], + ], + ], + ], + ], ]); } @@ -114,15 +112,16 @@ private function fakeResponse() { return $responses[$url][$hostHeader]; } } + return Http::response('not found', 404); }; - Http::fake( $fakeFunction ); + Http::fake($fakeFunction); } public function testWikiSiteStatsIsSuccessfullyUpdated() { Wiki::factory()->create([ - 'domain' => 'this.wikibase.cloud' + 'domain' => 'this.wikibase.cloud', ]); $this->addFakeSiteStatsResponse( @@ -137,14 +136,14 @@ public function testWikiSiteStatsIsSuccessfullyUpdated() { 'activeusers' => 6, 'admins' => 7, 'jobs' => 8, - 'cirrussearch-article-words' => 9 - ] + 'cirrussearch-article-words' => 9, + ], ]]) ); $this->fakeResponse(); $mockJob = $this->createMock(Job::class); - $job = new UpdateWikiSiteStatsJob(); + $job = new UpdateWikiSiteStatsJob; $job->setJob($mockJob); $mockJob->expects($this->never())->method('fail'); @@ -156,14 +155,13 @@ public function testWikiSiteStatsIsSuccessfullyUpdated() { } - public function testSuccessOfMultipleWikisTogether() - { - + public function testSuccessOfMultipleWikisTogether() { + Wiki::factory()->create([ - 'domain' => 'that.wikibase.cloud' + 'domain' => 'that.wikibase.cloud', ]); Wiki::factory()->create([ - 'domain' => 'this.wikibase.cloud' + 'domain' => 'this.wikibase.cloud', ]); $this->addFakeSiteStatsResponse( @@ -178,8 +176,8 @@ public function testSuccessOfMultipleWikisTogether() 'activeusers' => 6, 'admins' => 7, 'jobs' => 8, - 'cirrussearch-article-words' => 9 - ] + 'cirrussearch-article-words' => 9, + ], ]]) ); @@ -195,11 +193,11 @@ public function testSuccessOfMultipleWikisTogether() 'activeusers' => 14, 'admins' => 13, 'jobs' => 12, - 'cirrussearch-article-words' => 11 - ] + 'cirrussearch-article-words' => 11, + ], ]]) ); - + $this->addFakeFirstRevisionId('this.wikibase.cloud', 2); $this->addFakeFirstRevisionId('that.wikibase.cloud', 2); $this->addFakeLastRevisionId('this.wikibase.cloud', 1); @@ -211,7 +209,7 @@ public function testSuccessOfMultipleWikisTogether() $this->fakeResponse(); $mockJob = $this->createMock(Job::class); - $job = new UpdateWikiSiteStatsJob(); + $job = new UpdateWikiSiteStatsJob; $job->setJob($mockJob); $mockJob->expects($this->never())->method('fail'); @@ -233,7 +231,7 @@ public function testSuccessOfMultipleWikisTogether() public function testJobFailsIfSiteStatsLookupFails() { Wiki::factory()->create([ - 'domain' => 'fail.wikibase.cloud' + 'domain' => 'fail.wikibase.cloud', ]); $this->addFakeSiteStatsResponse( @@ -244,7 +242,7 @@ public function testJobFailsIfSiteStatsLookupFails() { $this->fakeResponse(); $mockJob = $this->createMock(Job::class); - $job = new UpdateWikiSiteStatsJob(); + $job = new UpdateWikiSiteStatsJob; $job->setJob($mockJob); $mockJob->expects($this->never())->method('fail'); @@ -254,27 +252,26 @@ public function testJobFailsIfSiteStatsLookupFails() { public function testIncompleteSiteStatsDoesNotCauseFailure() { Wiki::factory()->create([ - 'domain' => 'incomplete.wikibase.cloud' + 'domain' => 'incomplete.wikibase.cloud', ]); $this->addFakeSiteStatsResponse( 'incomplete.wikibase.cloud', Http::response(['query' => [ - 'statistics' => [ - 'articles' => 99, - 'not' => 129, - 'sure' => 11, - 'what' => 102, - 'happened' => 20 - ] + 'statistics' => [ + 'articles' => 99, + 'not' => 129, + 'sure' => 11, + 'what' => 102, + 'happened' => 20, + ], ]]) ); $this->fakeResponse(); - $mockJob = $this->createMock(Job::class); - $job = new UpdateWikiSiteStatsJob(); + $job = new UpdateWikiSiteStatsJob; $job->setJob($mockJob); $mockJob->expects($this->never())->method('fail'); @@ -288,25 +285,23 @@ public function testIncompleteSiteStatsDoesNotCauseFailure() { public function testNeverEditedWikiCreatesEmptyLifecycleEvents() { Wiki::factory()->create([ - 'domain' => 'this.wikibase.cloud' + 'domain' => 'this.wikibase.cloud', ]); $this->addFakeSiteStatsResponse('this.wikibase.cloud', Http::response()); $this->addFakeEmptyRevisionList('this.wikibase.cloud'); $this->fakeResponse(); - $mockJob = $this->createMock(Job::class); - $job = new UpdateWikiSiteStatsJob(); + $job = new UpdateWikiSiteStatsJob; $job->setJob($mockJob); $mockJob->expects($this->never())->method('fail'); $mockJob->expects($this->never())->method('markAsFailed'); $job->handle(); - + $events = Wiki::with('wikiLifecycleEvents')->where(['domain' => 'this.wikibase.cloud'])->first()->wikiLifecycleEvents()->first(); $this->assertNull($events['first_edited']); $this->assertNull($events['last_edited']); } - } diff --git a/tests/Jobs/WikiEntityImportJobTest.php b/tests/Jobs/WikiEntityImportJobTest.php index 778f2244e..ad8e62a48 100644 --- a/tests/Jobs/WikiEntityImportJobTest.php +++ b/tests/Jobs/WikiEntityImportJobTest.php @@ -2,54 +2,49 @@ namespace Tests\Jobs; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Support\Facades\Http; -use Tests\TestCase; +use App\Jobs\WikiEntityImportJob; use App\Wiki; use App\WikiEntityImport; use App\WikiEntityImportStatus; -use Illuminate\Contracts\Queue\Job; -use App\Jobs\WikiEntityImportJob; -use Maclof\Kubernetes\Client; -use Http\Adapter\Guzzle7\Client as GuzzleClient; -use GuzzleHttp\HandlerStack; use GuzzleHttp\Handler\MockHandler; +use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; +use Http\Adapter\Guzzle7\Client as GuzzleClient; +use Illuminate\Contracts\Queue\Job; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\Http; +use Maclof\Kubernetes\Client; +use Tests\TestCase; -class WikiEntityImportJobTest extends TestCase -{ +class WikiEntityImportJobTest extends TestCase { use RefreshDatabase; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); WikiEntityImport::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); WikiEntityImport::query()->delete(); parent::tearDown(); } - public function testJobDoesNotFail() - { + public function testJobDoesNotFail() { Http::fake([ - 'mediawiki-139-app-backend.default.svc.cluster.default/w/api.php?action=wbstackPlatformOauthGet&format=json' => - Http::response([ - 'wbstackPlatformOauthGet' => [ - 'success' => '1', - 'data' => [ - 'consumerKey' => 'aaa', - 'consumerSecret' => 'bbb', - 'accessKey' => 'yyy', - 'accessSecret' => 'zzz', - ], + 'mediawiki-139-app-backend.default.svc.cluster.default/w/api.php?action=wbstackPlatformOauthGet&format=json' => Http::response([ + 'wbstackPlatformOauthGet' => [ + 'success' => '1', + 'data' => [ + 'consumerKey' => 'aaa', + 'consumerSecret' => 'bbb', + 'accessKey' => 'yyy', + 'accessSecret' => 'zzz', ], - ], 200), + ], + ], 200), ]); $mockJob = $this->createMock(Job::class); @@ -74,9 +69,9 @@ public function testJobDoesNotFail() new Response(201, [], json_encode([ 'kind' => 'Job', 'metadata' => [ - 'name' => 'some-job-name' + 'name' => 'some-job-name', ], - ])) + ])), ]); $handlerStack = HandlerStack::create($mock); diff --git a/tests/Metrics/WikiMetricsTest.php b/tests/Metrics/WikiMetricsTest.php index 19140aeb5..b7f11bb50 100644 --- a/tests/Metrics/WikiMetricsTest.php +++ b/tests/Metrics/WikiMetricsTest.php @@ -2,109 +2,104 @@ namespace Tests\Metrics; +use App\Jobs\ProvisionWikiDbJob; use App\Metrics\App\WikiMetrics; use App\QueryserviceNamespace; use App\Wiki; -use App\WikiDb; use App\WikiDailyMetrics; -use App\Jobs\ProvisionWikiDbJob; +use App\WikiDb; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Http; use Tests\TestCase; -class WikiMetricsTest extends TestCase -{ +class WikiMetricsTest extends TestCase { use RefreshDatabase; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); $manager = $this->app->make('db'); - $job = new ProvisionWikiDbJob(); + $job = new ProvisionWikiDbJob; $job->handle($manager); } - public function testSuccessfullyAddRecords() - { + public function testSuccessfullyAddRecords() { $wiki = Wiki::factory()->create([ - 'domain' => 'thisfake.wikibase.cloud' + 'domain' => 'thisfake.wikibase.cloud', ]); $wikiDb = WikiDb::first(); - $wikiDb->update( ['wiki_id' => $wiki->id] ); + $wikiDb->update(['wiki_id' => $wiki->id]); - (new WikiMetrics())->saveMetrics($wiki); + (new WikiMetrics)->saveMetrics($wiki); // Assert the metric is updated in the database $this->assertDatabaseHas('wiki_daily_metrics', [ - 'date' => now()->toDateString() + 'date' => now()->toDateString(), ]); } - - public function testDoesNotAddDuplicateRecordsWithOnlyDateChange() - { + public function testDoesNotAddDuplicateRecordsWithOnlyDateChange() { $wiki = Wiki::factory()->create([ - 'domain' => 'thisfake.wikibase.cloud' + 'domain' => 'thisfake.wikibase.cloud', ]); $wikiDb = WikiDb::first(); - $wikiDb->update( ['wiki_id' => $wiki->id] ); + $wikiDb->update(['wiki_id' => $wiki->id]); - //Insert an old metric value for a wiki + // Insert an old metric value for a wiki WikiDailyMetrics::create([ - 'id' => $wiki->id. '_'. Carbon::yesterday()->toDateString(), + 'id' => $wiki->id . '_' . Carbon::yesterday()->toDateString(), 'wiki_id' => $wiki->id, 'date' => Carbon::yesterday()->toDateString(), 'pages' => 0, - 'is_deleted' => 0 + 'is_deleted' => 0, ]); - (new WikiMetrics())->saveMetrics($wiki); + (new WikiMetrics)->saveMetrics($wiki); - //Assert No new record was created for today + // Assert No new record was created for today $this->assertDatabaseMissing('wiki_daily_metrics', [ 'wiki_id' => $wiki->id, - 'date' => Carbon::today()->toDateString() + 'date' => Carbon::today()->toDateString(), ]); } - public function testAddRecordsWikiIsDeleted() - { + public function testAddRecordsWikiIsDeleted() { $wiki = Wiki::factory()->create([ - 'domain' => 'thisfake.wikibase.cloud' + 'domain' => 'thisfake.wikibase.cloud', ]); $wikiDb = WikiDb::first(); - $wikiDb->update( ['wiki_id' => $wiki->id] ); + $wikiDb->update(['wiki_id' => $wiki->id]); - //Insert an old metric value for a wiki + // Insert an old metric value for a wiki WikiDailyMetrics::create([ - 'id' => $wiki->id. '_'. Carbon::yesterday()->toDateString(), + 'id' => $wiki->id . '_' . Carbon::yesterday()->toDateString(), 'wiki_id' => $wiki->id, 'date' => Carbon::yesterday()->toDateString(), 'pages' => 0, - 'is_deleted' => 1 + 'is_deleted' => 1, ]); - //delete the wiki + // delete the wiki $wiki->delete(); $wiki->save(); - (new WikiMetrics())->saveMetrics($wiki); + (new WikiMetrics)->saveMetrics($wiki); - //Assert No new record was created for today + // Assert No new record was created for today $this->assertDatabaseMissing('wiki_daily_metrics', [ 'wiki_id' => $wiki->id, 'is_deleted' => 1, - 'date' => now()->toDateString() + 'date' => now()->toDateString(), ]); } - public function testItSaveTripleCountSuccessfully() - { + + public function testItSaveTripleCountSuccessfully() { $wiki = Wiki::factory()->create([ - 'domain' => 'somewikiforunittest.wikibase.cloud' + 'domain' => 'somewikiforunittest.wikibase.cloud', ]); $wikiDb = WikiDb::first(); - $wikiDb->update( ['wiki_id' => $wiki->id] ); + $wikiDb->update(['wiki_id' => $wiki->id]); $namespace = 'asdf'; $host = config('app.queryservice_host'); @@ -113,38 +108,38 @@ public function testItSaveTripleCountSuccessfully() 'backend' => $host, ]); - DB::table('queryservice_namespaces')->where(['id'=>$dbRow->id])->limit(1)->update(['wiki_id' => $wiki->id]); + DB::table('queryservice_namespaces')->where(['id' => $dbRow->id])->limit(1)->update(['wiki_id' => $wiki->id]); WikiDailyMetrics::create([ - 'id' => $wiki->id. '_'. Carbon::yesterday()->toDateString(), + 'id' => $wiki->id . '_' . Carbon::yesterday()->toDateString(), 'wiki_id' => $wiki->id, 'date' => Carbon::yesterday()->toDateString(), 'pages' => 0, - 'is_deleted' => 0 + 'is_deleted' => 0, ]); Http::fake([ '*' => Http::response([ 'results' => [ 'bindings' => [ [ - 'triples' => ['type' => 'literal', 'value' => '12345'] - ] - ] - ] - ], 200) + 'triples' => ['type' => 'literal', 'value' => '12345'], + ], + ], + ], + ], 200), ]); - (new WikiMetrics())->saveMetrics($wiki); + (new WikiMetrics)->saveMetrics($wiki); $this->assertDatabaseHas('wiki_daily_metrics', [ 'wiki_id' => $wiki->id, - 'number_of_triples' => 12345 + 'number_of_triples' => 12345, ]); } - public function testSaveNullForFailedRequestOfTriplesCount() - { + + public function testSaveNullForFailedRequestOfTriplesCount() { $wiki = Wiki::factory()->create([ - 'domain' => 'somewikitest.wikibase.cloud' + 'domain' => 'somewikitest.wikibase.cloud', ]); $wikiDb = WikiDb::first(); - $wikiDb->update( ['wiki_id' => $wiki->id] ); + $wikiDb->update(['wiki_id' => $wiki->id]); $namespace = 'asdf'; $host = config('app.queryservice_host'); @@ -153,22 +148,21 @@ public function testSaveNullForFailedRequestOfTriplesCount() 'backend' => $host, ]); - DB::table('queryservice_namespaces')->where(['id'=>$dbRow->id])->limit(1)->update(['wiki_id' => $wiki->id]); + DB::table('queryservice_namespaces')->where(['id' => $dbRow->id])->limit(1)->update(['wiki_id' => $wiki->id]); WikiDailyMetrics::create([ - 'id' => $wiki->id. '_'. Carbon::yesterday()->toDateString(), + 'id' => $wiki->id . '_' . Carbon::yesterday()->toDateString(), 'wiki_id' => $wiki->id, 'date' => Carbon::yesterday()->toDateString(), 'pages' => 0, - 'is_deleted' => 0 + 'is_deleted' => 0, ]); Http::fake([ - '*' => Http::response('Error', 500) + '*' => Http::response('Error', 500), ]); - (new WikiMetrics())->saveMetrics($wiki); + (new WikiMetrics)->saveMetrics($wiki); $this->assertDatabaseHas('wiki_daily_metrics', [ 'wiki_id' => $wiki->id, - 'number_of_triples' => null + 'number_of_triples' => null, ]); } } - diff --git a/tests/Middleware/LimitWikiAccessTest.php b/tests/Middleware/LimitWikiAccessTest.php index fc5c7d355..7d6cd7dc0 100644 --- a/tests/Middleware/LimitWikiAccessTest.php +++ b/tests/Middleware/LimitWikiAccessTest.php @@ -5,45 +5,40 @@ use App\User; use App\Wiki; use App\WikiManager; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Request; -use Tests\TestCase; use Illuminate\Support\Facades\Route; -use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\TestCase; -class LimitWikiAccessTest extends TestCase -{ +class LimitWikiAccessTest extends TestCase { use RefreshDatabase; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Route::middleware('limit_wiki_access')->get('/endpoint', function (Request $request) { return response()->json([ - 'wiki_id' => $request->attributes->get('wiki')->id + 'wiki_id' => $request->attributes->get('wiki')->id, ]); }); } - public function tearDown(): void - { + protected function tearDown(): void { parent::tearDown(); } - private function createWikiAndUser(): array - { + private function createWikiAndUser(): array { $wiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); - return array($wiki, $user); + + return [$wiki, $user]; } - private function getURI(Wiki $wiki): string - { + private function getURI(Wiki $wiki): string { return "/endpoint?wiki={$wiki->id}"; } - public function testSuccess(): void - { + public function testSuccess(): void { [$wiki, $user] = $this->createWikiAndUser(); $this->actingAs($user) @@ -52,8 +47,7 @@ public function testSuccess(): void ->assertJson(['wiki_id' => $wiki->id]); } - public function testFailOnWrongWikiManager(): void - { + public function testFailOnWrongWikiManager(): void { $userWiki = Wiki::factory()->create(); $otherWiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); @@ -61,22 +55,19 @@ public function testFailOnWrongWikiManager(): void $this->actingAs($user)->json('GET', $this->getURI($otherWiki))->assertStatus(403); } - public function testFailOnDeletedWiki(): void - { + public function testFailOnDeletedWiki(): void { [$wiki, $user] = $this->createWikiAndUser(); $wiki->wikiManagers()->delete(); $wiki->delete(); $this->actingAs($user)->json('GET', $this->getURI($wiki))->assertStatus(404); } - public function testFailOnMissingWiki(): void - { + public function testFailOnMissingWiki(): void { [$wiki, $user] = $this->createWikiAndUser(); $this->actingAs($user)->json('GET', '/endpoint')->assertStatus(422); } - public function testFailOnMissingUser(): void - { + public function testFailOnMissingUser(): void { [$wiki, $user] = $this->createWikiAndUser(); $this->json('GET', $this->getURI($wiki))->assertStatus(403); } diff --git a/tests/Middleware/ThrottleSignupTest.php b/tests/Middleware/ThrottleSignupTest.php index ac0ad22d7..57765bdf6 100644 --- a/tests/Middleware/ThrottleSignupTest.php +++ b/tests/Middleware/ThrottleSignupTest.php @@ -2,63 +2,60 @@ namespace Tests\Jobs; -use App\User; use App\Http\Middleware\ThrottleSignup; +use App\User; use Carbon\Carbon; -use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Http\Request; +use Tests\TestCase; -class ThrottleSignupTest extends TestCase -{ - +class ThrottleSignupTest extends TestCase { use RefreshDatabase; + public $connectionsToTransact = ['mysql']; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); // Tests running before this test do not clean up properly so this // also needs to happen in setUp User::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { User::query()->delete(); parent::tearDown(); } - private function seedUsers (array $dates) { + private function seedUsers(array $dates) { foreach ($dates as $date) { User::factory()->create(['created_at' => $date]); } } - public function testOk() - { + public function testOk() { $this->seedUsers( [ Carbon::now()->subHours(2), Carbon::now()->subMinutes(23), Carbon::now()->subHours(4), - Carbon::now()->subHours(2) + Carbon::now()->subHours(2), ] ); - $request = new Request(); - $middleware = new ThrottleSignup(); + $request = new Request; + $middleware = new ThrottleSignup; $called = false; $response = $middleware->handle($request, function ($req) use (&$called) { $called = true; + return response('OK', 200); }, '3', 'PT1H'); $this->assertEquals( 200, $response->getStatusCode(), - 'Expected 200 status code, got '.$response->getStatusCode(), + 'Expected 200 status code, got ' . $response->getStatusCode(), ); $this->assertEquals( @@ -68,69 +65,69 @@ public function testOk() ); } - public function testFailure() - { + public function testFailure() { $this->seedUsers( [ Carbon::now()->subMinutes(2), Carbon::now()->subMinutes(23), Carbon::now()->subMinutes(4), - Carbon::now()->subMinutes(2) + Carbon::now()->subMinutes(2), ] ); - $request = new Request(); - $middleware = new ThrottleSignup(); + $request = new Request; + $middleware = new ThrottleSignup; $called = false; $response = $middleware->handle($request, function ($req) use (&$called) { $called = true; + return response('OK', 200); }, '3', 'PT1H'); $this->assertEquals( 503, $response->getStatusCode(), - 'Expected 503 status code, got '.$response->getStatusCode(), + 'Expected 503 status code, got ' . $response->getStatusCode(), ); $this->assertEquals( false, $called, - "Expected callback not to be called when it was." + 'Expected callback not to be called when it was.' ); } - public function testNoConfiguration() - { + public function testNoConfiguration() { $this->seedUsers( [ Carbon::now()->subMinutes(2), Carbon::now()->subMinutes(23), Carbon::now()->subMinutes(4), - Carbon::now()->subMinutes(2) + Carbon::now()->subMinutes(2), ] ); - $request = new Request(); - $middleware = new ThrottleSignup(); + $request = new Request; + $middleware = new ThrottleSignup; $called = false; $response = $middleware->handle($request, function ($req) use (&$called) { $called = true; + return response('OK', 200); }, '', ''); $this->assertEquals( 200, $response->getStatusCode(), - 'Expected 200 status code, got '.$response->getStatusCode(), + 'Expected 200 status code, got ' . $response->getStatusCode(), ); $this->assertEquals( true, $called, - "Expected callback to be called when it was not." + 'Expected callback to be called when it was not.' ); } } diff --git a/tests/Routes/Auth/LoginTest.php b/tests/Routes/Auth/LoginTest.php index 381dd199a..7899809c3 100644 --- a/tests/Routes/Auth/LoginTest.php +++ b/tests/Routes/Auth/LoginTest.php @@ -7,36 +7,31 @@ use Tests\Routes\Traits\OptionsRequestAllowed; use Tests\TestCase; -class LoginTest extends TestCase -{ +class LoginTest extends TestCase { protected $route = 'auth/login'; - use OptionsRequestAllowed; use DatabaseTransactions; + use OptionsRequestAllowed; - public function setUp (): void - { + protected function setUp(): void { parent::setUp(); $this->artisan('passport:install', ['--no-interaction' => true]); } - public function testLoginFail_noExistingUser() - { + public function testLoginFailNoExistingUser() { // This random user probably doesn't exist in the db $user = User::factory()->make(); $this->json('POST', $this->route, ['email' => $user->email, 'password' => 'anyPassword']) - ->assertStatus(401); + ->assertStatus(401); } - public function testLoginFail_badPassword() - { + public function testLoginFailBadPassword() { $user = User::factory()->create(); $this->json('POST', $this->route, ['email' => $user->email, 'password' => 'someOtherPassword']) - ->assertStatus(401); + ->assertStatus(401); } - public function testLoginSuccess() - { + public function testLoginSuccess() { $password = 'apassword'; $user = User::factory()->create(['password' => password_hash($password, PASSWORD_DEFAULT)]); $response = $this->json('POST', $this->route, ['email' => $user->email, 'password' => $password]); @@ -46,19 +41,18 @@ public function testLoginSuccess() $userResponsePart = $response->json('user'); $this->assertEquals($user->email, $userResponsePart['email']); } - public function testGet() - { + + public function testGet() { $user = User::factory()->create(); $this->actingAs($user, 'api') - ->get($this->route) - ->assertStatus(200); + ->get($this->route) + ->assertStatus(200); } - public function testDelete() - { + public function testDelete() { $user = User::factory()->create(); $this->actingAs($user, 'api') - ->delete($this->route) - ->assertStatus(204); + ->delete($this->route) + ->assertStatus(204); } } diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php index 998f66a99..50bed012f 100644 --- a/tests/Routes/Complaint/SendMessageTest.php +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -5,79 +5,71 @@ use App\ComplaintRecord; use App\Notifications\ComplaintNotification; use App\Rules\ReCaptchaValidation; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Notifications\AnonymousNotifiable; use Illuminate\Support\Facades\Notification; use Tests\TestCase; -use Tests\Feature\ReCaptchaValidationTest; -use Illuminate\Foundation\Testing\RefreshDatabase; -class SendMessageTest extends TestCase -{ +class SendMessageTest extends TestCase { use RefreshDatabase; - + protected $route = 'complaint/sendMessage'; protected $postDataTemplateEmpty = [ - 'name' => '', - 'email' => '', - 'message' => '', - 'url' => '', + 'name' => '', + 'email' => '', + 'message' => '', + 'url' => '', 'recaptcha' => '', ]; protected $postDataTemplateFilled = [ - 'name' => 'Jane Doe', - 'email' => 'jane.doe@example.com', - 'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', - 'url' => 'https://example.com/1, https://example.com/2, https://example.com/3', + 'name' => 'Jane Doe', + 'email' => 'jane.doe@example.com', + 'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', + 'url' => 'https://example.com/1, https://example.com/2, https://example.com/3', 'recaptcha' => 'fake-token', ]; - private function mockReCaptchaValidation($passes=true) - { + private function mockReCaptchaValidation($passes = true) { // replace injected ReCaptchaValidation class with mock (ComplaintController::$recaptchaValidation) $mockRule = $this->createMock(ReCaptchaValidation::class); $mockRule->method('passes') ->willReturn($passes); - + $this->app->instance(ReCaptchaValidation::class, $mockRule); } - private function assertRecordCount(int $count) - { + + private function assertRecordCount(int $count) { $this->assertEquals(ComplaintRecord::count(), $count); } - private function assertComplaintMarkedAsDispatched() - { + private function assertComplaintMarkedAsDispatched() { $complaintRecord = ComplaintRecord::first(); $this->assertNotEmpty($complaintRecord->dispatched_at); } - private function assertComplaintNotMarkedAsDispatched() - { + private function assertComplaintNotMarkedAsDispatched() { $complaintRecord = ComplaintRecord::first(); $this->assertEmpty($complaintRecord->dispatched_at); } - private function assertComplaintRecorded() - { + private function assertComplaintRecorded() { $this->assertRecordCount(1); } - private function assertComplaintNotRecorded() - { + private function assertComplaintNotRecorded() { $this->assertRecordCount(0); } - public function testRecordOnMailFail() - { + public function testRecordOnMailFail() { $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; try { $response = $this->json('POST', $this->route, $data); - } catch(\Symfony\Component\Mailer\Exception\TransportException $e) { + } catch (\Symfony\Component\Mailer\Exception\TransportException $e) { return; } @@ -87,8 +79,7 @@ public function testRecordOnMailFail() $this->assertComplaintNotMarkedAsDispatched(); } - public function testSendMessage_NoData() - { + public function testSendMessageNoData() { Notification::fake(); $this->mockReCaptchaValidation(false); @@ -101,13 +92,12 @@ public function testSendMessage_NoData() $this->assertComplaintNotRecorded(); } - public function testSendMessage_InvalidMailAddressRfc() - { + public function testSendMessageInvalidMailAddressRfc() { Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['email'] = "invalid-mail-address"; + $data['email'] = 'invalid-mail-address'; $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -117,13 +107,12 @@ public function testSendMessage_InvalidMailAddressRfc() $this->assertComplaintNotRecorded(); } - public function testSendMessage_InvalidMailAddressMulti() - { + public function testSendMessageInvalidMailAddressMulti() { Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['email'] = "mail@example.com, foo@bar.com"; + $data['email'] = 'mail@example.com, foo@bar.com'; $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -131,13 +120,12 @@ public function testSendMessage_InvalidMailAddressMulti() $this->assertComplaintNotRecorded(); } - public function testSendMessage_ReasonTooLong() - { + public function testSendMessageReasonTooLong() { Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['message'] = str_repeat("Hi!", 10000); + $data['message'] = str_repeat('Hi!', 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -145,13 +133,12 @@ public function testSendMessage_ReasonTooLong() $this->assertComplaintNotRecorded(); } - public function testSendMessage_NameTooLong() - { + public function testSendMessageNameTooLong() { Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['name'] = str_repeat("Hi!", 10000); + $data['name'] = str_repeat('Hi!', 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -159,13 +146,12 @@ public function testSendMessage_NameTooLong() $this->assertComplaintNotRecorded(); } - public function testSendMessage_OffendingUrlsTooLong() - { + public function testSendMessageOffendingUrlsTooLong() { Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['url'] = str_repeat("Hi!", 10000); + $data['url'] = str_repeat('Hi!', 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -173,8 +159,7 @@ public function testSendMessage_OffendingUrlsTooLong() $this->assertComplaintNotRecorded(); } - public function testSendMessage_NoNameNorMailAddress() - { + public function testSendMessageNoNameNorMailAddress() { Notification::fake(); $this->mockReCaptchaValidation(); @@ -190,8 +175,7 @@ public function testSendMessage_NoNameNorMailAddress() $this->assertComplaintMarkedAsDispatched(); } - public function testSendMessage_Success() - { + public function testSendMessageSuccess() { Notification::fake(); $this->mockReCaptchaValidation(); @@ -199,11 +183,12 @@ public function testSendMessage_Success() $response = $this->json('POST', $this->route, $data); $response->assertStatus(200); - Notification::assertSentTo(new AnonymousNotifiable(), ComplaintNotification::class, function ($notification) { + Notification::assertSentTo(new AnonymousNotifiable, ComplaintNotification::class, function ($notification) { $this->assertSame( - "dsa@wikibase.cloud", - $notification->toMail(new AnonymousNotifiable())->from[0] + 'dsa@wikibase.cloud', + $notification->toMail(new AnonymousNotifiable)->from[0] ); + return true; }); @@ -212,8 +197,7 @@ public function testSendMessage_Success() $this->assertComplaintMarkedAsDispatched(); } - public function testSendMessage_RecaptchaFailure() - { + public function testSendMessageRecaptchaFailure() { Notification::fake(); $this->mockReCaptchaValidation(false); diff --git a/tests/Routes/Contact/SendMessageTest.php b/tests/Routes/Contact/SendMessageTest.php index e8f8660dd..a503faca0 100644 --- a/tests/Routes/Contact/SendMessageTest.php +++ b/tests/Routes/Contact/SendMessageTest.php @@ -7,26 +7,24 @@ use Illuminate\Notifications\AnonymousNotifiable; use Illuminate\Support\Facades\Notification; use Tests\TestCase; -use Tests\Feature\ReCaptchaValidationTest; -class SendMessageTest extends TestCase -{ +class SendMessageTest extends TestCase { protected $route = 'contact/sendMessage'; protected $postDataTemplateEmpty = [ - 'name' => '', + 'name' => '', 'contactDetails' => '', - 'subject' => '', - 'message' => '', - 'recaptcha' => '', + 'subject' => '', + 'message' => '', + 'recaptcha' => '', ]; protected $postDataTemplateValid = [ - 'name' => 'foo', + 'name' => 'foo', 'contactDetails' => 'bar', - 'subject' => 'general-question', - 'message' => 'baz', - 'recaptcha' => 'fake-token', + 'subject' => 'general-question', + 'message' => 'baz', + 'recaptcha' => 'fake-token', ]; protected $validSubjects = [ @@ -37,18 +35,16 @@ class SendMessageTest extends TestCase 'other', ]; - private function mockReCaptchaValidation($passes=true) - { + private function mockReCaptchaValidation($passes = true) { // replace injected ReCaptchaValidation class with mock (ContactController::$recaptchaValidation) $mockRule = $this->createMock(ReCaptchaValidation::class); $mockRule->method('passes') ->willReturn($passes); - + $this->app->instance(ReCaptchaValidation::class, $mockRule); } - public function testSendMessage_NoData() - { + public function testSendMessageNoData() { $this->mockReCaptchaValidation(false); $data = $this->postDataTemplateEmpty; @@ -57,90 +53,83 @@ public function testSendMessage_NoData() $response->assertStatus(401); } - public function testSendMessage_InvalidDataSubject() - { + public function testSendMessageInvalidDataSubject() { $this->mockReCaptchaValidation(); $data = $this->postDataTemplateValid; - $data['message'] = "Hi!"; - $data['subject'] = "not-valid"; + $data['message'] = 'Hi!'; + $data['subject'] = 'not-valid'; $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); } - public function testSendMessage_MessageTooLong() - { + public function testSendMessageMessageTooLong() { $this->mockReCaptchaValidation(); $data = $this->postDataTemplateValid; - $data['message'] = str_repeat("Hi!", 10000); + $data['message'] = str_repeat('Hi!', 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); } - public function testSendMessage_NameTooLong() - { + public function testSendMessageNameTooLong() { $this->mockReCaptchaValidation(); $data = $this->postDataTemplateValid; - $data['name'] = str_repeat("Hi!", 10000); + $data['name'] = str_repeat('Hi!', 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); } - public function testSendMessage_ContactDetailsTooLong() - { + public function testSendMessageContactDetailsTooLong() { $this->mockReCaptchaValidation(); $data = $this->postDataTemplateValid; - $data['contactDetails'] = str_repeat("Hi!", 10000); + $data['contactDetails'] = str_repeat('Hi!', 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); } - - public function testSendMessage_NoContactDetails() - { + public function testSendMessageNoContactDetails() { $this->mockReCaptchaValidation(); Notification::fake(); $data = [ - 'name' => 'foo', - 'subject' => 'general-question', - 'message' => 'baz', - 'recaptcha' => 'fake-token', + 'name' => 'foo', + 'subject' => 'general-question', + 'message' => 'baz', + 'recaptcha' => 'fake-token', ]; $response = $this->json('POST', $this->route, $data); $response->assertStatus(200); } - public function testSendMessage_Success() - { + public function testSendMessageSuccess() { $this->mockReCaptchaValidation(); Notification::fake(); $data = [ - 'name' => 'foo', + 'name' => 'foo', 'contactDetails' => 'bar', - 'subject' => 'general-question', - 'message' => 'baz', - 'recaptcha' => 'fake-token', + 'subject' => 'general-question', + 'message' => 'baz', + 'recaptcha' => 'fake-token', ]; $response = $this->json('POST', $this->route, $data); $response->assertStatus(200); - Notification::assertSentTo(new AnonymousNotifiable(), ContactNotification::class, function ($notification) { + Notification::assertSentTo(new AnonymousNotifiable, ContactNotification::class, function ($notification) { $this->assertSame( - "contact-general-question@wikibase.cloud", - $notification->toMail(new AnonymousNotifiable())->from[0] + 'contact-general-question@wikibase.cloud', + $notification->toMail(new AnonymousNotifiable)->from[0] ); + return true; }); } - public function testSendMessage_RecaptchaFailure() - { + public function testSendMessageRecaptchaFailure() { $this->mockReCaptchaValidation(false); Notification::fake(); diff --git a/tests/Routes/EmptyTest.php b/tests/Routes/EmptyTest.php index 82c921e81..434f0b13b 100644 --- a/tests/Routes/EmptyTest.php +++ b/tests/Routes/EmptyTest.php @@ -4,17 +4,14 @@ use Tests\TestCase; -class EmptyTest extends TestCase -{ - public function testRootGetNotFound() - { +class EmptyTest extends TestCase { + public function testRootGetNotFound() { $response = $this->get('/'); // Method not allowed $this->assertEquals(404, $response->status()); } - public function testRootPostNotFound() - { + public function testRootPostNotFound() { $response = $this->post('/'); // Method not allowed $this->assertEquals(404, $response->status()); diff --git a/tests/Routes/Ingress/GetWikiVersionForDomainTest.php b/tests/Routes/Ingress/GetWikiVersionForDomainTest.php index 65f468429..fc4df5aa6 100644 --- a/tests/Routes/Ingress/GetWikiVersionForDomainTest.php +++ b/tests/Routes/Ingress/GetWikiVersionForDomainTest.php @@ -2,19 +2,17 @@ namespace Tests\Routes\Ingress; -use Tests\TestCase; use App\Wiki; use App\WikiDb; use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\TestCase; -class GetWikiVersionForDomainTest extends TestCase -{ +class GetWikiVersionForDomainTest extends TestCase { protected $route = '/backend/ingress/getWikiVersionForDomain'; use RefreshDatabase; - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); parent::tearDown(); } @@ -27,18 +25,16 @@ private function createWiki(string $domain, string $version) { 'password' => 'somePassword', 'version' => $version, 'prefix' => 'somePrefix', - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); } - public function testNotFound() - { + public function testNotFound() { $this->createWiki('found.wikibase.cloud', 'someVersion'); $this->json('GET', $this->route . '?domain=notfound.wikibase.cloud')->assertStatus(401); } - public function testFoundVersion() - { + public function testFoundVersion() { $version = 'someVersion'; $this->createWiki('found.wikibase.cloud', $version); $this->createWiki('other.wikibase.cloud', 'otherVersion'); diff --git a/tests/Routes/QsBatch/QsControllerTest.php b/tests/Routes/QsBatch/QsControllerTest.php index cf7037c4e..9b41e1598 100644 --- a/tests/Routes/QsBatch/QsControllerTest.php +++ b/tests/Routes/QsBatch/QsControllerTest.php @@ -9,45 +9,39 @@ use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\TestCase; -class QsControllerTest extends TestCase -{ +class QsControllerTest extends TestCase { protected $route = 'backend/qs'; use DatabaseTransactions; - public function setUp (): void - { + protected function setUp(): void { parent::setUp(); EventPageUpdate::query()->delete(); QsBatch::query()->delete(); Wiki::query()->delete(); } - public function tearDown (): void - { + protected function tearDown(): void { EventPageUpdate::query()->delete(); QsBatch::query()->delete(); Wiki::query()->delete(); parent::tearDown(); } - public function testGetEmpty (): void - { - $this->json('GET', $this->route.'/getBatches') + public function testGetEmpty(): void { + $this->json('GET', $this->route . '/getBatches') ->assertExactJson([]) ->assertStatus(200); } - public function testSkipNoWiki (): void - { + public function testSkipNoWiki(): void { QsBatch::factory()->create(['id' => 1, 'done' => 0, 'wiki_id' => 99, 'entityIds' => 'a,b']); - $this->json('GET', $this->route.'/getBatches') + $this->json('GET', $this->route . '/getBatches') ->assertExactJson([]) ->assertStatus(200); } - public function testGetOldestBatch (): void - { + public function testGetOldestBatch(): void { Wiki::factory()->create(['id' => 99, 'domain' => 'test.wikibase.cloud']); QsBatch::factory()->create(['id' => 1, 'done' => 0, 'failed' => true, 'wiki_id' => 99, 'entityIds' => 'a,b']); QsBatch::factory()->create(['id' => 2, 'done' => 1, 'wiki_id' => 99, 'entityIds' => 'a,b']); @@ -55,7 +49,7 @@ public function testGetOldestBatch (): void QsBatch::factory()->create(['id' => 4, 'done' => 0, 'wiki_id' => 99, 'entityIds' => 'a,b']); QsBatch::factory()->create(['id' => 5, 'done' => 0, 'wiki_id' => 99, 'entityIds' => 'a,b']); - $response = $this->json('GET', $this->route.'/getBatches') + $response = $this->json('GET', $this->route . '/getBatches') ->assertJsonPath('0.id', 4) ->assertJsonPath('0.done', 0) ->assertJsonPath('0.wiki.domain', 'test.wikibase.cloud') @@ -64,13 +58,13 @@ public function testGetOldestBatch (): void $this->assertNotNull($response->json()[0]['pending_since']); } - public function testMarkDone (): void { + public function testMarkDone(): void { QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(1), 'id' => 1, 'done' => 1, 'wiki_id' => 1, 'entityIds' => 'a,b']); QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(2), 'id' => 2, 'done' => 0, 'wiki_id' => 1, 'entityIds' => 'c,d']); QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(3), 'id' => 3, 'done' => 0, 'wiki_id' => 1, 'entityIds' => 'e,f']); QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(4), 'id' => 4, 'done' => 0, 'wiki_id' => 6, 'entityIds' => 'g,h']); - $this->json('POST', $this->route.'/markDone', ['batches' => [2, 3]]) + $this->json('POST', $this->route . '/markDone', ['batches' => [2, 3]]) ->assertStatus(200); $this->assertEquals(QsBatch::where('id', 1)->first()->done, 1); @@ -82,13 +76,14 @@ public function testMarkDone (): void { $this->assertEquals(QsBatch::where('id', 4)->first()->done, 0); $this->assertNotNull(QsBatch::where('id', 4)->first()->pending_since); } - public function testMarkNotDone (): void { + + public function testMarkNotDone(): void { QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(1), 'id' => 1, 'done' => 1, 'wiki_id' => 1, 'entityIds' => 'a,b']); QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(2), 'id' => 2, 'done' => 0, 'wiki_id' => 1, 'entityIds' => 'c,d']); QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(3), 'id' => 3, 'done' => 0, 'wiki_id' => 1, 'entityIds' => 'e,f']); QsBatch::factory()->create(['pending_since' => Carbon::now()->subSeconds(4), 'id' => 4, 'done' => 1, 'wiki_id' => 6, 'entityIds' => 'g,h']); - $this->json('POST', $this->route.'/markNotDone', ['batches' => [1, 2]]) + $this->json('POST', $this->route . '/markNotDone', ['batches' => [1, 2]]) ->assertStatus(200); $this->assertEquals(QsBatch::where('id', 1)->first()->done, 0); diff --git a/tests/Routes/Traits/OptionsRequestAllowed.php b/tests/Routes/Traits/OptionsRequestAllowed.php index 7b7a462d8..bcd989b2e 100644 --- a/tests/Routes/Traits/OptionsRequestAllowed.php +++ b/tests/Routes/Traits/OptionsRequestAllowed.php @@ -2,10 +2,8 @@ namespace Tests\Routes\Traits; -trait OptionsRequestAllowed -{ - public function testOptionsRequestResponds200() - { +trait OptionsRequestAllowed { + public function testOptionsRequestResponds200() { $response = $this->json('OPTIONS', $this->route); $this->assertEquals(200, $response->status()); } diff --git a/tests/Routes/Traits/PostRequestNeedAuthentication.php b/tests/Routes/Traits/PostRequestNeedAuthentication.php index c6d57c66c..880667ff9 100644 --- a/tests/Routes/Traits/PostRequestNeedAuthentication.php +++ b/tests/Routes/Traits/PostRequestNeedAuthentication.php @@ -2,10 +2,8 @@ namespace Tests\Routes\Traits; -trait PostRequestNeedAuthentication -{ - public function testPostRequestWhenUnauthenticatedRespondes401() - { +trait PostRequestNeedAuthentication { + public function testPostRequestWhenUnauthenticatedRespondes401() { $response = $this->json('POST', $this->route); $this->assertEquals(401, $response->status()); } diff --git a/tests/Routes/User/ForgotAndResetPasswordIntegrationTest.php b/tests/Routes/User/ForgotAndResetPasswordIntegrationTest.php index 819a205ab..1d261c620 100644 --- a/tests/Routes/User/ForgotAndResetPasswordIntegrationTest.php +++ b/tests/Routes/User/ForgotAndResetPasswordIntegrationTest.php @@ -1,6 +1,5 @@ create(['email' => 'foo+bar@example.com']); - $this->json('POST', $this->forgot_route, ['email' => $user->email,]); + $this->json('POST', $this->forgot_route, ['email' => $user->email]); Notification::assertSentTo( $user, function (ResetPasswordNotification $notification) use ($user) { @@ -28,8 +26,9 @@ function (ResetPasswordNotification $notification) use ($user) { 'email' => $user->email, 'password' => 'AnyPassword122333', 'password_confirmation' => 'AnyPassword122333', - 'token' => $notification->token + 'token' => $notification->token, ])->assertStatus(200); + return true; } ); diff --git a/tests/Routes/User/ForgotPasswordTest.php b/tests/Routes/User/ForgotPasswordTest.php index a2bb8f6de..0e8d5d9db 100644 --- a/tests/Routes/User/ForgotPasswordTest.php +++ b/tests/Routes/User/ForgotPasswordTest.php @@ -9,18 +9,16 @@ use Tests\Routes\Traits\OptionsRequestAllowed; use Tests\TestCase; -class ForgotPasswordTest extends TestCase -{ +class ForgotPasswordTest extends TestCase { protected $route = 'user/forgotPassword'; - use OptionsRequestAllowed; use DatabaseTransactions; + use OptionsRequestAllowed; - public function testForgotPasswordSubmission_Success() - { + public function testForgotPasswordSubmissionSuccess() { Notification::fake(); $user = User::factory()->create(['email' => 'foo+bar@example.com']); - $this->json('POST', $this->route, ['email' => $user->email,]) + $this->json('POST', $this->route, ['email' => $user->email]) ->assertStatus(200); Notification::assertSentTo( $user, @@ -30,11 +28,10 @@ function (ResetPasswordNotification $notification) use ($user) { ); } - public function testForgotPasswordSubmission_NotFound() - { + public function testForgotPasswordSubmissionNotFound() { Notification::fake(); $user = User::factory()->create(['email' => 'foo+bar@example.com']); - $this->json('POST', $this->route, ['email' => 'foo+baz@example.com',]) + $this->json('POST', $this->route, ['email' => 'foo+baz@example.com']) ->assertStatus(200); Notification::assertNothingSent(); } diff --git a/tests/Routes/User/RegisterTest.php b/tests/Routes/User/RegisterTest.php index dbc889fe9..34982dfdf 100644 --- a/tests/Routes/User/RegisterTest.php +++ b/tests/Routes/User/RegisterTest.php @@ -4,24 +4,22 @@ use App\Invitation; use App\Notifications\UserCreationNotification; -use App\User; use App\Rules\ReCaptchaValidation; +use App\User; use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Notification; use Tests\Routes\Traits\OptionsRequestAllowed; use Tests\TestCase; -class RegisterTest extends TestCase -{ +class RegisterTest extends TestCase { protected $route = 'user/register'; - use OptionsRequestAllowed; use DatabaseTransactions; + use OptionsRequestAllowed; // TODO test password length when not deving - private function mockReCaptchaValidation($passes=true) - { + private function mockReCaptchaValidation($passes = true) { // replace injected ReCaptchaValidation class with mock (ContactController::$recaptchaValidation) $mockRule = $this->createMock(ReCaptchaValidation::class); $mockRule->method('passes') @@ -30,8 +28,7 @@ private function mockReCaptchaValidation($passes=true) $this->app->instance(ReCaptchaValidation::class, $mockRule); } - public function testCreate_Success() - { + public function testCreateSuccess() { $this->mockReCaptchaValidation(); Notification::fake(); @@ -39,72 +36,68 @@ public function testCreate_Success() $userToCreate = User::factory()->make(); $resp = $this->json('POST', $this->route, [ - 'email' => $userToCreate->email, - 'password' => 'anyPassword', - 'recaptcha' => 'someToken' + 'email' => $userToCreate->email, + 'password' => 'anyPassword', + 'recaptcha' => 'someToken', ]); $resp->assertStatus(200) - ->assertJsonStructure(['data' => ['email', 'id'], 'message', 'success']) - ->assertJsonFragment(['email' => $userToCreate->email, 'success' => true]); + ->assertJsonStructure(['data' => ['email', 'id'], 'message', 'success']) + ->assertJsonFragment(['email' => $userToCreate->email, 'success' => true]); Notification::assertSentTo( [User::whereEmail($userToCreate->email)->first()], UserCreationNotification::class ); // SHIFT doesnt have missingFromDatabase - //->missingFromDatabase('invitations', ['code' => $invite->code]); + // ->missingFromDatabase('invitations', ['code' => $invite->code]); } - public function testCreate_EmailAlreadyTaken() - { + public function testCreateEmailAlreadyTaken() { $this->mockReCaptchaValidation(); $invite = Invitation::factory()->create(); $user = User::factory()->create(); $this->json('POST', $this->route, [ - 'email' => $user->email, - 'password' => 'anyPassword', + 'email' => $user->email, + 'password' => 'anyPassword', ]) - ->assertStatus(422) - ->assertJsonStructure(['errors' => ['email']]); + ->assertStatus(422) + ->assertJsonStructure(['errors' => ['email']]); } - public function testCreate_NoToken() - { + public function testCreateNoToken() { $this->mockReCaptchaValidation(false); $invite = Invitation::factory()->create(); $user = User::factory()->make(); $this->json('POST', $this->route, [ - 'email' => $user->email, - 'password' => 'anyPassword', + 'email' => $user->email, + 'password' => 'anyPassword', ]) - ->assertStatus(422) - ->assertJsonStructure(['errors' => ['recaptcha']]); + ->assertStatus(422) + ->assertJsonStructure(['errors' => ['recaptcha']]); } - public function testCreate_NoEmailOrPassword() - { + public function testCreateNoEmailOrPassword() { $this->mockReCaptchaValidation(); $this->json('POST', $this->route, []) - ->assertStatus(422) - ->assertJsonStructure(['errors' => ['email', 'password']]); + ->assertStatus(422) + ->assertJsonStructure(['errors' => ['email', 'password']]); } - public function testCreate_BadEmail() - { + public function testCreateBadEmail() { $this->mockReCaptchaValidation(); $invite = Invitation::factory()->create(); $this->json('POST', $this->route, [ - 'email' => 'notAnEmail', - 'password' => 'anyPassword', + 'email' => 'notAnEmail', + 'password' => 'anyPassword', ]) - ->assertStatus(422) - ->assertJsonStructure(['errors' => ['email']]); + ->assertStatus(422) + ->assertJsonStructure(['errors' => ['email']]); } } diff --git a/tests/Routes/User/ResetPasswordTest.php b/tests/Routes/User/ResetPasswordTest.php index 2f5aee54e..1b577bee2 100644 --- a/tests/Routes/User/ResetPasswordTest.php +++ b/tests/Routes/User/ResetPasswordTest.php @@ -8,15 +8,13 @@ use Tests\Routes\Traits\OptionsRequestAllowed; use Tests\TestCase; -class ResetPasswordTest extends TestCase -{ +class ResetPasswordTest extends TestCase { protected $route = 'user/resetPassword'; - use OptionsRequestAllowed; use DatabaseTransactions; + use OptionsRequestAllowed; - public function testForgotPasswordEmail_Success() - { + public function testForgotPasswordEmailSuccess() { $user = User::factory()->create(); $passwordBroker = $this->app->make(PasswordBroker::class); $token = $passwordBroker->createToken($user); @@ -25,7 +23,7 @@ public function testForgotPasswordEmail_Success() 'email' => $user->email, 'password' => 'AnyPassword122333', 'password_confirmation' => 'AnyPassword122333', - 'token' => $token - ])->assertStatus(200); + 'token' => $token, + ])->assertStatus(200); } } diff --git a/tests/Routes/Wiki/ConversionMetricTest.php b/tests/Routes/Wiki/ConversionMetricTest.php index ea852d324..a1c479401 100644 --- a/tests/Routes/Wiki/ConversionMetricTest.php +++ b/tests/Routes/Wiki/ConversionMetricTest.php @@ -1,23 +1,23 @@ delete(); WikiSiteStats::query()->delete(); @@ -26,7 +26,7 @@ public function setUp(): void { CarbonImmutable::setTestNow(Carbon::parse('first day of October 2023')); } - public function tearDown(): void { + protected function tearDown(): void { Wiki::query()->delete(); WikiSiteStats::query()->delete(); WikiSetting::query()->delete(); @@ -35,26 +35,25 @@ public function tearDown(): void { parent::tearDown(); } - public function testDownloadCsv() - { + public function testDownloadCsv() { $this->createTestWiki('one.wikibase.cloud', 0, 1, 2); - $this->createTestWiki( 'two.wikibase.cloud', 0, 0, 3 ); + $this->createTestWiki('two.wikibase.cloud', 0, 0, 3); $response = $this->get($this->route); $response->assertStatus(200) - ->assertDownload(CarbonImmutable::now()->toIso8601String().'-conversion_metric_for_all_wikis.csv'); + ->assertDownload(CarbonImmutable::now()->toIso8601String() . '-conversion_metric_for_all_wikis.csv'); $response->assertSee('abandoned'); $response->assertSee('one.wikibase.cloud'); $response->assertSee('two.wikibase.cloud'); } - private function createTestWiki( $name, $createdWeeksAgo, $firstEditedWeeksAgo, $lastEditedWeeksAgo, $active_users = 0): Wiki { + private function createTestWiki($name, $createdWeeksAgo, $firstEditedWeeksAgo, $lastEditedWeeksAgo, $active_users = 0): Wiki { $current_date = CarbonImmutable::now(); $wiki = Wiki::factory()->create([ - 'domain' => $name, 'sitename' => 'bsite' + 'domain' => $name, 'sitename' => 'bsite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77, 'activeusers' => $active_users + 'wiki_id' => $wiki->id, 'pages' => 77, 'activeusers' => $active_users, ]); $wiki->created_at = $current_date->subWeeks($createdWeeksAgo); $events = $wiki->wikiLifecycleEvents(); @@ -67,16 +66,17 @@ private function createTestWiki( $name, $createdWeeksAgo, $firstEditedWeeksAgo, } $events->updateOrCreate($update); $wiki->save(); + return $wiki; } public function testDownloadJson() { $this->createTestWiki('new.but.never.edited.wikibase.cloud', 0, null, null); - $this->createTestWiki('old.and.never.edited.wikibase.cloud', 53, null, null ); - $this->createTestWiki('old.and.used.only.one.week.wikibase.cloud', 53, 52, 51 ); - $this->createTestWiki('unused.for.a.year.but.now.active.wikibase.cloud', 53, 1, 0, 4 ); - $this->createTestWiki('acvtively.used.for.the.last.year.wikibase.cloud', 53, 53, 0, 5 ); - $this->createTestWiki('creation.time.after.first.edit.wikibase.cloud', 0, 53, 0, 1 ); + $this->createTestWiki('old.and.never.edited.wikibase.cloud', 53, null, null); + $this->createTestWiki('old.and.used.only.one.week.wikibase.cloud', 53, 52, 51); + $this->createTestWiki('unused.for.a.year.but.now.active.wikibase.cloud', 53, 1, 0, 4); + $this->createTestWiki('acvtively.used.for.the.last.year.wikibase.cloud', 53, 53, 0, 5); + $this->createTestWiki('creation.time.after.first.edit.wikibase.cloud', 0, 53, 0, 1); $response = $this->getJson($this->route); $response->assertStatus(200); $response->assertJsonFragment( @@ -86,7 +86,7 @@ public function testDownloadJson() { 'time_before_wiki_abandoned_days' => null, 'number_of_active_editors' => 0, 'first_edited_time' => null, - 'last_edited_time' => null + 'last_edited_time' => null, ] ); $response->assertJsonFragment( @@ -94,7 +94,7 @@ public function testDownloadJson() { 'domain' => 'old.and.never.edited.wikibase.cloud', 'time_to_engage_days' => null, 'time_before_wiki_abandoned_days' => null, - 'number_of_active_editors' => 0 + 'number_of_active_editors' => 0, ] ); $response->assertJsonFragment( @@ -113,7 +113,7 @@ public function testDownloadJson() { 'domain' => 'unused.for.a.year.but.now.active.wikibase.cloud', 'time_to_engage_days' => 364, 'time_before_wiki_abandoned_days' => null, - 'number_of_active_editors' => 4 + 'number_of_active_editors' => 4, ] ); $response->assertJsonFragment( @@ -121,7 +121,7 @@ public function testDownloadJson() { 'domain' => 'unused.for.a.year.but.now.active.wikibase.cloud', 'time_to_engage_days' => 0, 'time_before_wiki_abandoned_days' => null, - 'number_of_active_editors' => 5 + 'number_of_active_editors' => 5, ] ); $response->assertJsonFragment( @@ -129,14 +129,14 @@ public function testDownloadJson() { 'domain' => 'creation.time.after.first.edit.wikibase.cloud', 'time_to_engage_days' => -371, 'time_before_wiki_abandoned_days' => null, - 'number_of_active_editors' => 1 + 'number_of_active_editors' => 1, ] ); } public function testFunctionalWithMissingLifecycleEventsandStats() { $wiki = Wiki::factory()->create([ - 'domain' => 'very.new.wikibase.cloud', 'sitename' => 'bsite' + 'domain' => 'very.new.wikibase.cloud', 'sitename' => 'bsite', ]); $response = $this->get($this->route); diff --git a/tests/Routes/Wiki/CreateTest.php b/tests/Routes/Wiki/CreateTest.php index cd0b58a45..a5e482e9b 100644 --- a/tests/Routes/Wiki/CreateTest.php +++ b/tests/Routes/Wiki/CreateTest.php @@ -2,25 +2,24 @@ namespace Tests\Routes\Wiki\Managers; -use App\WikiProfile; -use Tests\Routes\Traits\OptionsRequestAllowed; -use Tests\TestCase; -use Illuminate\Foundation\Testing\DatabaseTransactions; -use App\User; -use Illuminate\Support\Facades\Queue; use App\Jobs\CirrusSearch\ElasticSearchIndexInit; use App\Jobs\ElasticSearchAliasInit; -use App\Jobs\ProvisionWikiDbJob; use App\Jobs\MediawikiInit; -use App\WikiSetting; -use App\WikiManager; +use App\Jobs\ProvisionWikiDbJob; +use App\QueryserviceNamespace; +use App\User; use App\Wiki; +use App\WikiManager; +use App\WikiProfile; +use App\WikiSetting; use Carbon\Carbon; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Support\Facades\Config; -use App\QueryserviceNamespace; +use Illuminate\Support\Facades\Queue; +use Tests\Routes\Traits\OptionsRequestAllowed; +use Tests\TestCase; -class CreateTest extends TestCase -{ +class CreateTest extends TestCase { protected $route = 'wiki/create'; const defaultData = [ @@ -31,26 +30,25 @@ class CreateTest extends TestCase "audience": "narrow", "temporality": "permanent", "purpose": "data_hub" - }' + }', ]; - use OptionsRequestAllowed; use DatabaseTransactions; + use OptionsRequestAllowed; /** - * @dataProvider createDispatchesSomeJobsProvider - */ - public function testWikiCreateDispatchesSomeJobs( $elasticSearchConfig ) - { - $enabledForNewWikis = $elasticSearchConfig[ 'enabledForNewWikis' ]; - $clusterWithoutSharedIndex = $elasticSearchConfig[ 'clusterWithoutSharedIndex' ] ?? null; - $sharedIndexHost = $elasticSearchConfig[ 'sharedIndexHost' ] ?? null; - $sharedIndexPrefix = $elasticSearchConfig[ 'sharedIndexPrefix' ] ?? null; - - Config::set( 'wbstack.elasticsearch_enabled_by_default', $enabledForNewWikis ); - Config::set( 'wbstack.elasticsearch_cluster_without_shared_index', $clusterWithoutSharedIndex ); - Config::set( 'wbstack.elasticsearch_shared_index_host', $sharedIndexHost ); - Config::set( 'wbstack.elasticsearch_shared_index_prefix', $sharedIndexPrefix ); + * @dataProvider createDispatchesSomeJobsProvider + */ + public function testWikiCreateDispatchesSomeJobs($elasticSearchConfig) { + $enabledForNewWikis = $elasticSearchConfig['enabledForNewWikis']; + $clusterWithoutSharedIndex = $elasticSearchConfig['clusterWithoutSharedIndex'] ?? null; + $sharedIndexHost = $elasticSearchConfig['sharedIndexHost'] ?? null; + $sharedIndexPrefix = $elasticSearchConfig['sharedIndexPrefix'] ?? null; + + Config::set('wbstack.elasticsearch_enabled_by_default', $enabledForNewWikis); + Config::set('wbstack.elasticsearch_cluster_without_shared_index', $clusterWithoutSharedIndex); + Config::set('wbstack.elasticsearch_shared_index_host', $sharedIndexHost); + Config::set('wbstack.elasticsearch_shared_index_prefix', $sharedIndexPrefix); $this->createSQLandQSDBs(); @@ -60,114 +58,113 @@ public function testWikiCreateDispatchesSomeJobs( $elasticSearchConfig ) Queue::assertNothingPushed(); $response = $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'domain' => 'dErP.com', - 'sitename' => 'merp', - 'username' => 'AdminBoss', - 'profile' => '{ + ->json( + 'POST', + $this->route, + [ + 'domain' => 'dErP.com', + 'sitename' => 'merp', + 'username' => 'AdminBoss', + 'profile' => '{ "audience": "narrow", "temporality": "permanent", "purpose": "data_hub" - }' - ] - ); + }', + ] + ); - if ( $enabledForNewWikis && $clusterWithoutSharedIndex ) { - Queue::assertPushed( function ( ElasticSearchIndexInit $job ) use ( $clusterWithoutSharedIndex ) { + if ($enabledForNewWikis && $clusterWithoutSharedIndex) { + Queue::assertPushed(function (ElasticSearchIndexInit $job) use ($clusterWithoutSharedIndex) { return $job->cluster() === $clusterWithoutSharedIndex; - } ); + }); } else { - Queue::assertNotPushed( ElasticSearchIndexInit::class ); + Queue::assertNotPushed(ElasticSearchIndexInit::class); } - if ( $enabledForNewWikis && $sharedIndexHost && $sharedIndexPrefix ) { - Queue::assertPushed( ElasticSearchAliasInit::class, 1 ); + if ($enabledForNewWikis && $sharedIndexHost && $sharedIndexPrefix) { + Queue::assertPushed(ElasticSearchAliasInit::class, 1); } else { - Queue::assertNotPushed( ElasticSearchAliasInit::class ); + Queue::assertNotPushed(ElasticSearchAliasInit::class); } - if ( $enabledForNewWikis && !$clusterWithoutSharedIndex && !( $sharedIndexHost && $sharedIndexPrefix ) ) { - $response->assertStatus( 503 ) - ->assertJsonPath( 'message', 'Search enabled, but its configuration is invalid' ); + if ($enabledForNewWikis && !$clusterWithoutSharedIndex && !($sharedIndexHost && $sharedIndexPrefix)) { + $response->assertStatus(503) + ->assertJsonPath('message', 'Search enabled, but its configuration is invalid'); - Queue::assertNotPushed( ProvisionWikiDbJob::class ); - Queue::assertNotPushed( MediawikiInit::class ); + Queue::assertNotPushed(ProvisionWikiDbJob::class); + Queue::assertNotPushed(MediawikiInit::class); } else { - $response->assertStatus( 200 ) - ->assertJsonPath( 'data.domain', 'derp.com' ) - ->assertJsonPath( 'data.name', null ) - ->assertJsonPath( 'success', true ); + $response->assertStatus(200) + ->assertJsonPath('data.domain', 'derp.com') + ->assertJsonPath('data.name', null) + ->assertJsonPath('success', true); - Queue::assertPushed( ProvisionWikiDbJob::class, 1 ); - Queue::assertPushed( MediawikiInit::class, 1 ); + Queue::assertPushed(ProvisionWikiDbJob::class, 1); + Queue::assertPushed(MediawikiInit::class, 1); - $id = $response->original[ 'data' ][ 'id' ]; + $id = $response->original['data']['id']; $this->assertSame( 1, - WikiSetting::where( [ 'name' => WikiSetting::wgSecretKey, 'wiki_id' => $id ] )->count() + WikiSetting::where(['name' => WikiSetting::wgSecretKey, 'wiki_id' => $id])->count() ); $this->assertSame( 1, - WikiSetting::where( [ 'name' => WikiSetting::wwExtEnableElasticSearch, 'value' => $enabledForNewWikis, 'wiki_id' => $id ] )->count() + WikiSetting::where(['name' => WikiSetting::wwExtEnableElasticSearch, 'value' => $enabledForNewWikis, 'wiki_id' => $id])->count() ); } } - static public function createDispatchesSomeJobsProvider() { - yield [ [ + public static function createDispatchesSomeJobsProvider() { + yield [[ 'enabledForNewWikis' => true, 'clusterWithoutSharedIndex' => 'all', 'sharedIndexHost' => 'somehost', - 'sharedIndexPrefix' => 'testing_1' - ] ]; + 'sharedIndexPrefix' => 'testing_1', + ]]; - yield [ [ + yield [[ 'enabledForNewWikis' => true, 'clusterWithoutSharedIndex' => 'default', - ] ]; + ]]; - yield [ [ + yield [[ 'enabledForNewWikis' => true, 'sharedIndexHost' => 'somehost', - 'sharedIndexPrefix' => 'testing_1' - ] ]; + 'sharedIndexPrefix' => 'testing_1', + ]]; - yield [ [ + yield [[ 'enabledForNewWikis' => true, - 'sharedIndexPrefix' => 'testing_1' - ] ]; + 'sharedIndexPrefix' => 'testing_1', + ]]; - yield [ [ - 'enabledForNewWikis' => true - ] ]; + yield [[ + 'enabledForNewWikis' => true, + ]]; - yield [ [ - 'enabledForNewWikis' => false - ] ]; + yield [[ + 'enabledForNewWikis' => false, + ]]; } - public function testCreateWikiLimitsNumWikisPerUser() - { + public function testCreateWikiLimitsNumWikisPerUser() { $manager = $this->app->make('db'); - $job1 = new ProvisionWikiDbJob(); + $job1 = new ProvisionWikiDbJob; $job1->handle($manager); - $job2 = new ProvisionWikiDbJob(); + $job2 = new ProvisionWikiDbJob; $job2->handle($manager); QueryserviceNamespace::create([ - 'namespace' => "ns-1", - 'backend' => "wdqs.svc", + 'namespace' => 'ns-1', + 'backend' => 'wdqs.svc', ]); QueryserviceNamespace::create([ - 'namespace' => "ns-2", - 'backend' => "wdqs.svc", + 'namespace' => 'ns-2', + 'backend' => 'wdqs.svc', ]); Config::set('wbstack.wiki_max_per_user', 1); @@ -178,23 +175,23 @@ public function testCreateWikiLimitsNumWikisPerUser() Queue::assertNothingPushed(); // This shouldn't stop first create since it's deleted - $this->wiki = Wiki::factory()->create( [ 'deleted_at' => Carbon::now()->timestamp ] ); + $this->wiki = Wiki::factory()->create(['deleted_at' => Carbon::now()->timestamp]); WikiManager::factory()->create(['wiki_id' => $this->wiki->id, 'user_id' => $user->id]); $response = $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'domain' => 'mywikidomain.com', - 'sitename' => 'merp', - 'username' => 'AdminBoss' - ] - ); + ->json( + 'POST', + $this->route, + [ + 'domain' => 'mywikidomain.com', + 'sitename' => 'merp', + 'username' => 'AdminBoss', + ] + ); $response->assertStatus(200) ->assertJsonPath('data.domain', 'mywikidomain.com') - ->assertJsonPath('success', true ); + ->assertJsonPath('success', true); $response = $this->actingAs($user, 'api') ->json( @@ -203,7 +200,7 @@ public function testCreateWikiLimitsNumWikisPerUser() [ 'domain' => 'mywikidomain-2.com', 'sitename' => 'merp', - 'username' => 'AdminBoss' + 'username' => 'AdminBoss', ] ); $response->assertStatus(403) @@ -213,30 +210,29 @@ public function testCreateWikiLimitsNumWikisPerUser() Config::set('wbstack.wiki_max_per_user', false); $response = $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'domain' => 'mywikidomain-2.com', - 'sitename' => 'merp', - 'username' => 'AdminBoss' - ] - ); - + ->json( + 'POST', + $this->route, + [ + 'domain' => 'mywikidomain-2.com', + 'sitename' => 'merp', + 'username' => 'AdminBoss', + ] + ); $response->assertStatus(200) ->assertJsonPath('data.domain', 'mywikidomain-2.com') - ->assertJsonPath('success', true ); + ->assertJsonPath('success', true); } private function createSQLandQSDBs(): void { $manager = $this->app->make('db'); - $job = new ProvisionWikiDbJob(); + $job = new ProvisionWikiDbJob; $job->handle($manager); QueryserviceNamespace::create([ - 'namespace' => "derp", - 'backend' => "wdqs.svc", + 'namespace' => 'derp', + 'backend' => 'wdqs.svc', ]); } @@ -248,15 +244,15 @@ public function testCreateWikiHandlesRangeOfPostValues($data, $expectedStatus): Queue::fake(); $user = User::factory()->create(['verified' => true]); $response = $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - $data - ); - $response->assertStatus( $expectedStatus ); + ->json( + 'POST', + $this->route, + $data + ); + $response->assertStatus($expectedStatus); } - static public function createWikiHandlesRangeOfPostValuesProvider(): array { + public static function createWikiHandlesRangeOfPostValuesProvider(): array { $noDomain = self::defaultData; unset($noDomain['domain']); $noSitename = self::defaultData; @@ -278,20 +274,21 @@ static public function createWikiHandlesRangeOfPostValuesProvider(): array { "temporality": "permanent", "purpose": "data_hub" }'; - $profileWithExtraneousOther = self::defaultData; + $profileWithExtraneousOther = self::defaultData; $profileWithExtraneousOther['profile'] = '{ "audience_other": "just my cat", "temporality": "permanent", "purpose": "data_hub" }'; - $profileWithAudienceBlank = self::defaultData; + $profileWithAudienceBlank = self::defaultData; $profileWithAudienceBlank['profile'] = '{ "audience": "", "temporality": "permanent", "purpose": "data_hub" }'; + return [ - 'all params present' => [self::defaultData , 200], + 'all params present' => [self::defaultData, 200], 'missing domain' => [$noDomain, 422], 'missing sitename' => [$noSitename, 422], 'missing username' => [$noUsername, 422], @@ -299,7 +296,7 @@ static public function createWikiHandlesRangeOfPostValuesProvider(): array { 'profile with other' => [$profileWithOther, 200], 'profile with other string missing' => [$profileWithOtherStringMissing, 422], 'profile with extraneous other' => [$profileWithExtraneousOther, 422], - 'profile with audience blank string' => [$profileWithAudienceBlank, 422] + 'profile with audience blank string' => [$profileWithAudienceBlank, 422], ]; } @@ -308,15 +305,14 @@ public function testCreateWithProfileCreatesProfiles(): void { Queue::fake(); $user = User::factory()->create(['verified' => true]); $response = $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - self::defaultData - ); + ->json( + 'POST', + $this->route, + self::defaultData + ); $id = $response->decodeResponseJson()['data']['id']; - $this->assertEquals( 1, - WikiProfile::where( [ 'wiki_id' => $id ] )->count() + $this->assertEquals(1, + WikiProfile::where(['wiki_id' => $id])->count() ); } - } diff --git a/tests/Routes/Wiki/DeleteWikiTest.php b/tests/Routes/Wiki/DeleteWikiTest.php index 66c8de652..abb972ae5 100644 --- a/tests/Routes/Wiki/DeleteWikiTest.php +++ b/tests/Routes/Wiki/DeleteWikiTest.php @@ -9,13 +9,11 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; -class DeleteWikiTest extends TestCase -{ +class DeleteWikiTest extends TestCase { use HasFactory; use RefreshDatabase; - public function testDelete() - { + public function testDelete() { $user = User::factory()->create(['verified' => true]); $wiki = Wiki::factory('nodb')->create(); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); @@ -35,8 +33,7 @@ public function testDelete() ); } - public function testFailOnWrongWikiManager(): void - { + public function testFailOnWrongWikiManager(): void { $userWiki = Wiki::factory()->create(); $otherWiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); diff --git a/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php b/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php index 83543e357..285518584 100644 --- a/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php +++ b/tests/Routes/Wiki/DeletedWikiMetricsControllerTest.php @@ -1,48 +1,45 @@ delete(); WikiSiteStats::query()->delete(); WikiSetting::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); WikiSiteStats::query()->delete(); WikiSetting::query()->delete(); parent::tearDown(); } - public function testUnauthorisedStatusIfUserNotLoggedIn() - { + public function testUnauthorisedStatusIfUserNotLoggedIn() { $this->createAndDeleteTestWiki('one.wikibase.cloud', 0, '', 1, 2); $this->createAndDeleteTestWiki('two.wikibase.cloud', 10, 'Some Reason', 0, 3); $response = $this->get($this->route); $response->assertStatus(401); } - public function testRedirectIfUserIsLoggedInAsNotAdmin() - { + + public function testRedirectIfUserIsLoggedInAsNotAdmin() { $user = $this->createUserWithPrivileges(0); $this->actingAs($user, 'api')->get('auth/login'); $this->createAndDeleteTestWiki('one.wikibase.cloud', 0, '', 1, 2); @@ -51,8 +48,7 @@ public function testRedirectIfUserIsLoggedInAsNotAdmin() $response->assertStatus(302); } - public function testDownloadCsvIfUserIsLoggedInAsAdmin() - { + public function testDownloadCsvIfUserIsLoggedInAsAdmin() { $user = $this->createUserWithPrivileges(1); $this->actingAs($user, 'api')->get('auth/login'); $this->createAndDeleteTestWiki('one.wikibase.cloud', 0, '', 1, 2); @@ -62,10 +58,9 @@ public function testDownloadCsvIfUserIsLoggedInAsAdmin() ->assertDownload(CarbonImmutable::now()->toIso8601String() . '-deleted_wiki_metric.csv'); } - public function testOutputHasCorrectContent() - { - $user1 = User::factory()->create(['verified' => true,]); - $user2 = User::factory()->create(['verified' => true,]); + public function testOutputHasCorrectContent() { + $user1 = User::factory()->create(['verified' => true]); + $user2 = User::factory()->create(['verified' => true]); $deletedWikis = [ $this->createAndDeleteTestWiki('one.wikibase.cloud', $user1->id, '', 1, 2), $this->createAndDeleteTestWiki('two.wikibase.cloud', $user2->id, 'Some Reason', 0, 3), @@ -80,22 +75,21 @@ public function testOutputHasCorrectContent() $output = array_map('str_getcsv', explode("\n", $rawCsv)); $this->assertSame('one.wikibase.cloud', $output[1][0]); $this->assertSame('two.wikibase.cloud', $output[2][0]); - $this->assertSame('Some Reason',$output[2][1]); + $this->assertSame('Some Reason', $output[2][1]); } - private function createUserWithPrivileges($userPrivilege) - { + private function createUserWithPrivileges($userPrivilege) { $password = 'apassword'; + return User::factory()->create([ 'verified' => true, 'email' => 'atestmail@gmail.com', 'password' => password_hash($password, PASSWORD_DEFAULT), - 'is_admin' => $userPrivilege + 'is_admin' => $userPrivilege, ]); } - private function createAndDeleteTestWiki($domain, $user_id, $wikiDeletionReason, $createdWeeksAgo = 1, $wiki_users = 1) - { + private function createAndDeleteTestWiki($domain, $user_id, $wikiDeletionReason, $createdWeeksAgo = 1, $wiki_users = 1) { $current_date = CarbonImmutable::now(); $wiki = Wiki::factory()->create([ @@ -105,12 +99,13 @@ private function createAndDeleteTestWiki($domain, $user_id, $wikiDeletionReason, 'wiki_id' => $wiki->id, 'user_id' => $user_id, ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77, 'users' => $wiki_users + 'wiki_id' => $wiki->id, 'pages' => 77, 'users' => $wiki_users, ]); $wiki->save(); $wiki->update(['wiki_deletion_reason' => $wikiDeletionReason]); $wiki->delete(); + return $wiki; } } diff --git a/tests/Routes/Wiki/DetailsTest.php b/tests/Routes/Wiki/DetailsTest.php index 91204b624..d4f98b977 100644 --- a/tests/Routes/Wiki/DetailsTest.php +++ b/tests/Routes/Wiki/DetailsTest.php @@ -2,40 +2,35 @@ namespace Tests\Routes\Wiki\Managers; -use Illuminate\Foundation\Testing\RefreshDatabase; - -use Tests\Routes\Traits\OptionsRequestAllowed; -use Tests\TestCase; -use App\Wiki; -use App\WikiSetting; use App\User; +use App\Wiki; use App\WikiManager; use App\WikiProfile; +use App\WikiSetting; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\Routes\Traits\OptionsRequestAllowed; +use Tests\TestCase; -class DetailsTest extends TestCase -{ +class DetailsTest extends TestCase { protected $route = 'wiki/details'; use OptionsRequestAllowed, RefreshDatabase; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); WikiSetting::query()->delete(); WikiManager::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); WikiSetting::query()->delete(); WikiManager::query()->delete(); parent::tearDown(); } - public function testNoCredentials() - { + public function testNoCredentials() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); WikiSetting::factory()->create(['name' => 'wwUseQuestyCaptcha', 'value' => 1]); @@ -43,8 +38,7 @@ public function testNoCredentials() ->assertStatus(401); } - public function testSkipsNonPublicSettings() - { + public function testSkipsNonPublicSettings() { $user = User::factory()->create(['verified' => true]); $wiki = Wiki::factory()->create(['domain' => 'other.wikibase.cloud']); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); @@ -61,8 +55,7 @@ public function testSkipsNonPublicSettings() $this->assertEquals(1, $publicSettings[0]['value']); } - public function testReturnsCorrectWikiNotFirstWiki(): void - { + public function testReturnsCorrectWikiNotFirstWiki(): void { $firstWiki = Wiki::factory()->create(); $userWiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); @@ -74,8 +67,7 @@ public function testReturnsCorrectWikiNotFirstWiki(): void ->assertStatus(200); } - public function testFailOnWrongWikiManager(): void - { + public function testFailOnWrongWikiManager(): void { $userWiki = Wiki::factory()->create(); $otherWiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); @@ -85,8 +77,7 @@ public function testFailOnWrongWikiManager(): void ->assertStatus(403); } - public function testWikiProfile() - { + public function testWikiProfile() { $wiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); @@ -95,12 +86,12 @@ public function testWikiProfile() 'wiki_id' => $wiki->id, 'audience' => 'wide', 'temporality' => 'temporary', - 'purpose' => 'data_hub' + 'purpose' => 'data_hub', ])->refresh()->toArray(); $response = $this->actingAs($user, 'api') - ->postJson($this->route, ['wiki' => $wiki->id]) - ->assertStatus(200); + ->postJson($this->route, ['wiki' => $wiki->id]) + ->assertStatus(200); $profile = data_get($response->json(), 'data.wiki_latest_profile', []); $this->assertNotEmpty($profile); @@ -110,12 +101,12 @@ public function testWikiProfile() 'wiki_id' => $wiki->id, 'audience' => 'wide', 'temporality' => 'permanent', - 'purpose' => 'data_hub' + 'purpose' => 'data_hub', ])->refresh()->toArray(); $response = $this->actingAs($user, 'api') - ->postJson($this->route, ['wiki' => $wiki->id]) - ->assertStatus(200); + ->postJson($this->route, ['wiki' => $wiki->id]) + ->assertStatus(200); $profile = data_get($response->json(), 'data.wiki_latest_profile', []); $this->assertNotEmpty($profile); diff --git a/tests/Routes/Wiki/EntityImportBackendTest.php b/tests/Routes/Wiki/EntityImportBackendTest.php index 71961cd4d..bad0fdcca 100644 --- a/tests/Routes/Wiki/EntityImportBackendTest.php +++ b/tests/Routes/Wiki/EntityImportBackendTest.php @@ -2,73 +2,65 @@ namespace Tests\Routes\Wiki\Managers; -use App\WikiEntityImportStatus; -use Illuminate\Foundation\Testing\RefreshDatabase; - -use Tests\TestCase; use App\Wiki; use App\WikiEntityImport; +use App\WikiEntityImportStatus; use App\WikiManager; +use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\TestCase; -class EntityImportBackendTest extends TestCase -{ +class EntityImportBackendTest extends TestCase { protected $route = 'backend/wiki/updateEntityImport'; use RefreshDatabase; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); WikiManager::query()->delete(); WikiEntityImport::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); WikiManager::query()->delete(); WikiEntityImport::query()->delete(); parent::tearDown(); } - public function testNoUpdate() - { + public function testNoUpdate() { $this->json('PATCH', $this->route, ['wiki_entity_import' => 789, 'status' => 'success']) ->assertStatus(404); } - public function testBadStatus() - { + public function testBadStatus() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $import = WikiEntityImport::factory()->create([ 'status' => WikiEntityImportStatus::Pending, 'wiki_id' => $wiki->id, ]); - $this->json('PATCH', $this->route."?wiki_entity_import=".$import->id, ['status' => 'finished']) + $this->json('PATCH', $this->route . '?wiki_entity_import=' . $import->id, ['status' => 'finished']) ->assertStatus(422); } - public function testUpdate() - { + public function testUpdate() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $import = WikiEntityImport::factory()->create([ 'status' => WikiEntityImportStatus::Pending, 'wiki_id' => $wiki->id, ]); - $this->json('PATCH', $this->route."?wiki_entity_import=".$import->id, ['status' => 'failed']) + $this->json('PATCH', $this->route . '?wiki_entity_import=' . $import->id, ['status' => 'failed']) ->assertStatus(200) ->assertJsonPath('data.status', 'failed'); } - public function testUpdateWhenDone() - { + public function testUpdateWhenDone() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $import = WikiEntityImport::factory()->create([ 'status' => WikiEntityImportStatus::Failed, 'wiki_id' => $wiki->id, ]); - $this->json('PATCH', $this->route."?wiki_entity_import=".$import->id, ['status' => 'success']) + $this->json('PATCH', $this->route . '?wiki_entity_import=' . $import->id, ['status' => 'success']) ->assertStatus(400); $this->assertEquals( WikiEntityImportStatus::Failed, diff --git a/tests/Routes/Wiki/EntityImportTest.php b/tests/Routes/Wiki/EntityImportTest.php index 1d9cd978b..13d4605f0 100644 --- a/tests/Routes/Wiki/EntityImportTest.php +++ b/tests/Routes/Wiki/EntityImportTest.php @@ -2,63 +2,56 @@ namespace Tests\Routes\Wiki\Managers; +use App\Jobs\WikiEntityImportJob; +use App\User; +use App\Wiki; +use App\WikiEntityImport; use App\WikiEntityImportStatus; +use App\WikiManager; use Carbon\Carbon; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Bus; - use Tests\Routes\Traits\OptionsRequestAllowed; use Tests\TestCase; -use App\Wiki; -use App\WikiEntityImport; -use App\User; -use App\WikiManager; -use App\Jobs\WikiEntityImportJob; -class EntityImportTest extends TestCase -{ +class EntityImportTest extends TestCase { protected $route = 'wiki/entityImport'; use OptionsRequestAllowed, RefreshDatabase; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); WikiManager::query()->delete(); WikiEntityImport::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); WikiManager::query()->delete(); WikiEntityImport::query()->delete(); parent::tearDown(); } - public function testNoCredentials() - { + public function testNoCredentials() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); $this->actingAs($user, 'api') - ->json('GET', $this->route.'?wiki='.$wiki->id) + ->json('GET', $this->route . '?wiki=' . $wiki->id) ->assertStatus(403); } - public function testEmpty() - { + public function testEmpty() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') - ->json('GET', $this->route.'?wiki='.$wiki->id) + ->json('GET', $this->route . '?wiki=' . $wiki->id) ->assertStatus(200) ->assertJsonFragment(['data' => []]); } - public function testResults() - { + public function testResults() { $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $otherWiki = Wiki::factory()->create(['domain' => 'other.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); @@ -79,14 +72,13 @@ public function testResults() ]); $this->actingAs($user, 'api') - ->json('GET', $this->route.'?wiki='.$wiki->id) + ->json('GET', $this->route . '?wiki=' . $wiki->id) ->assertStatus(200) ->assertJsonCount(1, 'data') ->assertJsonPath('data.0.status', WikiEntityImportStatus::Success->value); } - public function testCreateWhilePending() - { + public function testCreateWhilePending() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); @@ -99,15 +91,14 @@ public function testCreateWhilePending() ]); $this->actingAs($user, 'api') - ->json('POST', $this->route.'?wiki='.$wiki->id, ['entity_ids' => 'P1', 'source_wiki_url' => 'https://source.wikibase.cloud']) + ->json('POST', $this->route . '?wiki=' . $wiki->id, ['entity_ids' => 'P1', 'source_wiki_url' => 'https://source.wikibase.cloud']) ->assertStatus(400); $this->assertEquals(1, WikiEntityImport::count()); Bus::assertNothingDispatched(); } - public function testCreateWhenSucceeded() - { + public function testCreateWhenSucceeded() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); @@ -120,44 +111,42 @@ public function testCreateWhenSucceeded() ]); $this->actingAs($user, 'api') - ->json('POST', $this->route.'?wiki='.$wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1']) + ->json('POST', $this->route . '?wiki=' . $wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1']) ->assertStatus(400); $this->assertEquals(1, WikiEntityImport::count()); Bus::assertNothingDispatched(); } - public function testCreateWhenEmpty() - { + public function testCreateWhenEmpty() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') - ->json('POST', $this->route.'?wiki='.$wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1,P2,Q1@123']) + ->json('POST', $this->route . '?wiki=' . $wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1,P2,Q1@123']) ->assertStatus(200); $this->assertEquals(1, WikiEntityImport::count()); Bus::assertDispatchedTimes(WikiEntityImportJob::class, 1); } - public function testCreateValidation() - { + public function testCreateValidation() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') - ->json('POST', $this->route.'?wiki='.$wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1,P2; echo "P4Wn3D!!",Q42']) + ->json('POST', $this->route . '?wiki=' . $wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1,P2; echo "P4Wn3D!!",Q42']) ->assertStatus(422); $this->assertEquals(0, WikiEntityImport::count()); Bus::assertDispatchedTimes(WikiEntityImportJob::class, 0); } - public function testCreateWhenFailed() - { + + public function testCreateWhenFailed() { Bus::fake(); $wiki = Wiki::factory()->create(['domain' => 'test.wikibase.cloud']); $user = User::factory()->create(['verified' => true]); @@ -170,7 +159,7 @@ public function testCreateWhenFailed() ]); $this->actingAs($user, 'api') - ->json('POST', $this->route.'?wiki='.$wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1,P2']) + ->json('POST', $this->route . '?wiki=' . $wiki->id, ['source_wiki_url' => 'https://source.wikibase.cloud', 'entity_ids' => 'P1,P2']) ->assertStatus(200); $this->assertEquals(2, WikiEntityImport::count()); diff --git a/tests/Routes/Wiki/GetWikiForDomainTest.php b/tests/Routes/Wiki/GetWikiForDomainTest.php index a7522f84f..858abe3cc 100644 --- a/tests/Routes/Wiki/GetWikiForDomainTest.php +++ b/tests/Routes/Wiki/GetWikiForDomainTest.php @@ -2,33 +2,30 @@ namespace Tests\Routes\Wiki; -use Tests\TestCase; use App\Wiki; use Illuminate\Foundation\Testing\RefreshDatabase; +use Tests\TestCase; -class GetWikiForDomainTest extends TestCase -{ +class GetWikiForDomainTest extends TestCase { protected $route = '/backend/wiki/getWikiForDomain'; use RefreshDatabase; - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); parent::tearDown(); } - public function testNotFound() - { + public function testNotFound() { Wiki::factory()->create(['domain' => 'found.wikibase.cloud']); - $this->json('GET', $this->route."?domain=notfound.wikibase.cloud")->assertStatus(404); + $this->json('GET', $this->route . '?domain=notfound.wikibase.cloud')->assertStatus(404); } - public function testFoundOne() - { + + public function testFoundOne() { Wiki::factory()->create(['domain' => 'found.wikibase.cloud']); - $this->json('GET', $this->route."?domain=found.wikibase.cloud") + $this->json('GET', $this->route . '?domain=found.wikibase.cloud') ->assertStatus(200) ->assertJsonPath('data.domain', 'found.wikibase.cloud'); } diff --git a/tests/Routes/Wiki/LogoUpdateTest.php b/tests/Routes/Wiki/LogoUpdateTest.php index cb39b3041..d23c2ef4e 100644 --- a/tests/Routes/Wiki/LogoUpdateTest.php +++ b/tests/Routes/Wiki/LogoUpdateTest.php @@ -12,14 +12,12 @@ use Intervention\Image\Facades\Image; use Tests\TestCase; -class LogoUpdateTest extends TestCase -{ +class LogoUpdateTest extends TestCase { use HasFactory; - public function testUpdate() - { + public function testUpdate() { $storage = Storage::fake('static-assets'); - $file = UploadedFile::fake()->createWithContent("logo_200x200.png", file_get_contents(__DIR__ . "/../../data/logo_200x200.png")); + $file = UploadedFile::fake()->createWithContent('logo_200x200.png', file_get_contents(__DIR__ . '/../../data/logo_200x200.png')); $user = User::factory()->create(['verified' => true]); $wiki = Wiki::factory('nodb')->create(); @@ -55,14 +53,13 @@ public function testUpdate() $this->assertSame(64, $logo->width()); } - public function testFailOnWrongWikiManager(): void - { + public function testFailOnWrongWikiManager(): void { $userWiki = Wiki::factory()->create(); $otherWiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $userWiki->id, 'user_id' => $user->id]); $file = UploadedFile::fake() - ->createWithContent("logo_200x200.png", file_get_contents(__DIR__ . "/../../data/logo_200x200.png")); + ->createWithContent('logo_200x200.png', file_get_contents(__DIR__ . '/../../data/logo_200x200.png')); $this->actingAs($user, 'api') ->post('wiki/logo/update', ['wiki' => $otherWiki->id, 'logo' => $file]) ->assertStatus(403); diff --git a/tests/Routes/Wiki/MineTest.php b/tests/Routes/Wiki/MineTest.php index aa06bd64a..21496919d 100644 --- a/tests/Routes/Wiki/MineTest.php +++ b/tests/Routes/Wiki/MineTest.php @@ -2,34 +2,31 @@ namespace Tests\Routes\Wiki\Managers; -use Tests\Routes\Traits\OptionsRequestAllowed; -use Tests\TestCase; use App\User; -use Illuminate\Support\Facades\Config; use App\Wiki; use App\WikiManager; use Illuminate\Foundation\Testing\DatabaseTransactions; +use Illuminate\Support\Facades\Config; +use Tests\Routes\Traits\OptionsRequestAllowed; +use Tests\TestCase; -class MineTest extends TestCase -{ +class MineTest extends TestCase { protected $route = 'wiki/mine'; - use OptionsRequestAllowed; use DatabaseTransactions; + use OptionsRequestAllowed; - public function testMineDefault() - { + public function testMineDefault() { Config::set('wbstack.wiki_max_per_user', false); $user = User::factory()->create(['verified' => true]); $this->actingAs($user, 'api') ->json('POST', $this->route, []) ->assertStatus(200) - ->assertJsonFragment([ "wikis" => [], "count" => 0, "limit" => false]); + ->assertJsonFragment(['wikis' => [], 'count' => 0, 'limit' => false]); } - public function testMineWithWikis() - { + public function testMineWithWikis() { Config::set('wbstack.wiki_max_per_user', 1); $user = User::factory()->create(['verified' => true]); @@ -39,9 +36,8 @@ public function testMineWithWikis() $content = $this->actingAs($user, 'api') ->json('POST', $this->route, []) ->assertStatus(200) - ->assertJson([ "wikis" => [], "count" => 1, "limit" => 1])->getContent(); - + ->assertJson(['wikis' => [], 'count' => 1, 'limit' => 1])->getContent(); - $this->assertEquals( $wiki->id, json_decode($content)->wikis[0]->id ); + $this->assertEquals($wiki->id, json_decode($content)->wikis[0]->id); } } diff --git a/tests/Routes/Wiki/ProfileControllerTest.php b/tests/Routes/Wiki/ProfileControllerTest.php index c04b305ab..24c99f118 100644 --- a/tests/Routes/Wiki/ProfileControllerTest.php +++ b/tests/Routes/Wiki/ProfileControllerTest.php @@ -8,155 +8,147 @@ use App\WikiProfile; use Tests\TestCase; -class ProfileControllerTest extends TestCase -{ +class ProfileControllerTest extends TestCase { protected $route = 'wiki/profile'; - public function setUp(): void - { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); WikiManager::query()->delete(); WikiProfile::query()->delete(); } - public function tearDown(): void - { + protected function tearDown(): void { Wiki::query()->delete(); WikiManager::query()->delete(); WikiProfile::query()->delete(); parent::tearDown(); } - public function testFailOnMissingWiki(): void - { + public function testFailOnMissingWiki(): void { $wiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $wiki->delete(); $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'wiki' => $wiki->id, - 'profile' => json_encode([ - 'audience' => 'wide', - 'temporality' => 'permanent', - 'purpose' => 'data_hub' - ]) - ] - ) - ->assertStatus(404); + ->json( + 'POST', + $this->route, + [ + 'wiki' => $wiki->id, + 'profile' => json_encode([ + 'audience' => 'wide', + 'temporality' => 'permanent', + 'purpose' => 'data_hub', + ]), + ] + ) + ->assertStatus(404); } - public function testFailOnWrongWikiManager(): void - { + public function testFailOnWrongWikiManager(): void { $userWiki = Wiki::factory()->create(); $otherWiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $userWiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'wiki' => $otherWiki->id, - 'profile' => json_encode([ - 'audience' => 'wide', - 'temporality' => 'permanent', - 'purpose' => 'data_hub' - ]) - ] - ) - ->assertStatus(403); + ->json( + 'POST', + $this->route, + [ + 'wiki' => $otherWiki->id, + 'profile' => json_encode([ + 'audience' => 'wide', + 'temporality' => 'permanent', + 'purpose' => 'data_hub', + ]), + ] + ) + ->assertStatus(403); } - public function testFailOnEmptyProfile(): void - { + public function testFailOnEmptyProfile(): void { $userWiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $userWiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'wiki' => $userWiki->id, - 'profile' => '{}' - ] - ) - ->assertStatus(422); + ->json( + 'POST', + $this->route, + [ + 'wiki' => $userWiki->id, + 'profile' => '{}', + ] + ) + ->assertStatus(422); } - public function testFailOnInvalidProfile(): void - { + public function testFailOnInvalidProfile(): void { $wiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'wiki' => $wiki->id, - 'profile' => json_encode([ - 'audience' => 'invalid option', - 'temporality' => 'permanent', - 'purpose' => 'data_hub' - ]) - ] - ) - ->assertStatus(422) - ->assertJson([ - 'message' => 'The selected audience is invalid.', - 'errors' => [ - 'audience' => [ - 'The selected audience is invalid.' + ->json( + 'POST', + $this->route, + [ + 'wiki' => $wiki->id, + 'profile' => json_encode([ + 'audience' => 'invalid option', + 'temporality' => 'permanent', + 'purpose' => 'data_hub', + ]), ] - ] - ]); + ) + ->assertStatus(422) + ->assertJson([ + 'message' => 'The selected audience is invalid.', + 'errors' => [ + 'audience' => [ + 'The selected audience is invalid.', + ], + ], + ]); } - public function testKeepAllVersions(): void - { + public function testKeepAllVersions(): void { $wiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $versionA = $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'wiki' => $wiki->id, - 'profile' => json_encode([ - 'audience' => 'wide', - 'temporality' => 'permanent', - 'purpose' => 'data_hub' - ]) - ] - ) - ->assertStatus(200); + ->json( + 'POST', + $this->route, + [ + 'wiki' => $wiki->id, + 'profile' => json_encode([ + 'audience' => 'wide', + 'temporality' => 'permanent', + 'purpose' => 'data_hub', + ]), + ] + ) + ->assertStatus(200); $versionB = $this->actingAs($user, 'api') - ->json( - 'POST', - $this->route, - [ - 'wiki' => $wiki->id, - 'profile' => json_encode([ - 'audience' => 'wide', - 'temporality' => 'temporary', - 'purpose' => 'data_hub' - ]) - ] - ) - ->assertStatus(200); + ->json( + 'POST', + $this->route, + [ + 'wiki' => $wiki->id, + 'profile' => json_encode([ + 'audience' => 'wide', + 'temporality' => 'temporary', + 'purpose' => 'data_hub', + ]), + ] + ) + ->assertStatus(200); $this->assertEquals( 2, diff --git a/tests/Routes/Wiki/PublicWikiTest.php b/tests/Routes/Wiki/PublicWikiTest.php index 499eeeb27..c7ed46fbb 100644 --- a/tests/Routes/Wiki/PublicWikiTest.php +++ b/tests/Routes/Wiki/PublicWikiTest.php @@ -2,37 +2,35 @@ namespace Tests\Routes\Wiki; -use Tests\Routes\Traits\OptionsRequestAllowed; -use Tests\TestCase; -use App\WikiSiteStats; -use App\WikiSetting; use App\Wiki; +use App\WikiSetting; +use App\WikiSiteStats; use Illuminate\Foundation\Testing\DatabaseTransactions; +use Tests\Routes\Traits\OptionsRequestAllowed; +use Tests\TestCase; -class PublicWikiTest extends TestCase -{ +class PublicWikiTest extends TestCase { protected $route = 'wiki'; - use OptionsRequestAllowed; use DatabaseTransactions; + use OptionsRequestAllowed; - public function setUp(): void { + protected function setUp(): void { parent::setUp(); Wiki::query()->delete(); WikiSiteStats::query()->delete(); WikiSetting::query()->delete(); } - public function tearDown(): void { + protected function tearDown(): void { Wiki::query()->delete(); WikiSiteStats::query()->delete(); WikiSetting::query()->delete(); parent::tearDown(); } - public function testEmpty() - { - $this->json('GET', $this->route.'/12') + public function testEmpty() { + $this->json('GET', $this->route . '/12') ->assertStatus(404) ->assertJsonStructure(['message']); @@ -41,42 +39,40 @@ public function testEmpty() ->assertJsonPath('data', []); } - public function testGetOne() - { + public function testGetOne() { $wiki = Wiki::factory()->create([ - 'domain' => 'one.wikibase.cloud' + 'domain' => 'one.wikibase.cloud', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77 + 'wiki_id' => $wiki->id, 'pages' => 77, ]); $wiki2 = Wiki::factory()->create([ - 'domain' => 'two.wikibase.cloud' + 'domain' => 'two.wikibase.cloud', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki2->id, 'pages' => 66 + 'wiki_id' => $wiki2->id, 'pages' => 66, ]); - $this->json('GET', $this->route.'/'.$wiki->id) + $this->json('GET', $this->route . '/' . $wiki->id) ->assertStatus(200) ->assertJsonPath('data.domain', 'one.wikibase.cloud') ->assertJsonPath('data.wiki_site_stats.pages', 77); } - public function testGetAll() - { + public function testGetAll() { $wiki = Wiki::factory()->create([ - 'domain' => 'one.wikibase.cloud', 'sitename' => 'bsite' + 'domain' => 'one.wikibase.cloud', 'sitename' => 'bsite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77 + 'wiki_id' => $wiki->id, 'pages' => 77, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'two.wikibase.cloud', 'sitename' => 'asite' + 'domain' => 'two.wikibase.cloud', 'sitename' => 'asite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 66 + 'wiki_id' => $wiki->id, 'pages' => 66, ]); $this->json('GET', $this->route) @@ -87,27 +83,26 @@ public function testGetAll() ->assertJsonPath('data.1.wiki_site_stats.pages', 77); } - public function testCustomSorting() - { + public function testCustomSorting() { $wiki = Wiki::factory()->create([ - 'domain' => 'one.wikibase.cloud', 'sitename' => 'bsite' + 'domain' => 'one.wikibase.cloud', 'sitename' => 'bsite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77 + 'wiki_id' => $wiki->id, 'pages' => 77, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'two.wikibase.cloud', 'sitename' => 'asite' + 'domain' => 'two.wikibase.cloud', 'sitename' => 'asite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 66 + 'wiki_id' => $wiki->id, 'pages' => 66, ]); Wiki::factory()->create([ - 'domain' => 'nostats.wikibase.cloud', 'sitename' => 'zsite' + 'domain' => 'nostats.wikibase.cloud', 'sitename' => 'zsite', ]); - $this->json('GET', $this->route.'?sort=pages&direction=desc') + $this->json('GET', $this->route . '?sort=pages&direction=desc') ->assertStatus(200) ->assertJsonPath('data.0.domain', 'one.wikibase.cloud') ->assertJsonPath('data.0.wiki_site_stats.pages', 77) @@ -116,7 +111,7 @@ public function testCustomSorting() ->assertJsonPath('data.2.domain', 'nostats.wikibase.cloud') ->assertJsonPath('data.2.wiki_site_stats', null); - $this->json('GET', $this->route.'?direction=desc') + $this->json('GET', $this->route . '?direction=desc') ->assertStatus(200) ->assertJsonPath('data.0.domain', 'nostats.wikibase.cloud') ->assertJsonPath('data.0.wiki_site_stats', null) @@ -125,7 +120,7 @@ public function testCustomSorting() ->assertJsonPath('data.2.domain', 'two.wikibase.cloud') ->assertJsonPath('data.2.wiki_site_stats.pages', 66); - $this->json('GET', $this->route.'?sort=pages') + $this->json('GET', $this->route . '?sort=pages') ->assertStatus(200) ->assertJsonPath('data.0.domain', 'nostats.wikibase.cloud') ->assertJsonPath('data.0.wiki_site_stats', null) @@ -134,46 +129,45 @@ public function testCustomSorting() ->assertJsonPath('data.2.domain', 'one.wikibase.cloud') ->assertJsonPath('data.2.wiki_site_stats.pages', 77); - $this->json('GET', $this->route.'?sort=dinosaur') + $this->json('GET', $this->route . '?sort=dinosaur') ->assertStatus(422) ->assertJsonStructure(['message']); - $this->json('GET', $this->route.'?direction=random') + $this->json('GET', $this->route . '?direction=random') ->assertStatus(422) ->assertJsonStructure(['message']); } - public function testPagination() - { + public function testPagination() { $wiki = Wiki::factory()->create([ - 'domain' => 'one.wikibase.cloud', 'sitename' => 'csite' + 'domain' => 'one.wikibase.cloud', 'sitename' => 'csite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77 + 'wiki_id' => $wiki->id, 'pages' => 77, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'two.wikibase.cloud', 'sitename' => 'bsite' + 'domain' => 'two.wikibase.cloud', 'sitename' => 'bsite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 66 + 'wiki_id' => $wiki->id, 'pages' => 66, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'three.wikibase.cloud', 'sitename' => 'asite' + 'domain' => 'three.wikibase.cloud', 'sitename' => 'asite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 55 + 'wiki_id' => $wiki->id, 'pages' => 55, ]); - $this->json('GET', $this->route.'?per_page=1') + $this->json('GET', $this->route . '?per_page=1') ->assertStatus(200) ->assertJsonPath('data.0.domain', 'three.wikibase.cloud') ->assertJsonPath('data.0.wiki_site_stats.pages', 55) ->assertJsonCount(1, 'data') ->assertJsonPath('meta.total', 3); - $this->json('GET', $this->route.'?per_page=1&page=3') + $this->json('GET', $this->route . '?per_page=1&page=3') ->assertStatus(200) ->assertJsonPath('data.0.domain', 'one.wikibase.cloud') ->assertJsonPath('data.0.wiki_site_stats.pages', 77) @@ -181,30 +175,29 @@ public function testPagination() ->assertJsonPath('meta.total', 3); } - public function testFilterIsFeatured() - { + public function testFilterIsFeatured() { $wiki = Wiki::factory()->create([ - 'domain' => 'one.wikibase.cloud', 'is_featured' => false + 'domain' => 'one.wikibase.cloud', 'is_featured' => false, ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77 + 'wiki_id' => $wiki->id, 'pages' => 77, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'two.wikibase.cloud', 'is_featured' => true + 'domain' => 'two.wikibase.cloud', 'is_featured' => true, ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 66 + 'wiki_id' => $wiki->id, 'pages' => 66, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'three.wikibase.cloud', 'is_featured' => false + 'domain' => 'three.wikibase.cloud', 'is_featured' => false, ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 55 + 'wiki_id' => $wiki->id, 'pages' => 55, ]); - $this->json('GET', $this->route.'?is_featured=1') + $this->json('GET', $this->route . '?is_featured=1') ->assertStatus(200) ->assertJsonPath('data.0.domain', 'two.wikibase.cloud') ->assertJsonPath('data.0.wiki_site_stats.pages', 66) @@ -212,41 +205,40 @@ public function testFilterIsFeatured() ->assertJsonPath('meta.total', 1); } - public function testFilterIsActive() - { + public function testFilterIsActive() { $wiki = Wiki::factory()->create([ - 'domain' => 'one.wikibase.cloud', 'sitename' => 'csite' + 'domain' => 'one.wikibase.cloud', 'sitename' => 'csite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 77 + 'wiki_id' => $wiki->id, 'pages' => 77, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'two.wikibase.cloud', 'sitename' => 'bsite' + 'domain' => 'two.wikibase.cloud', 'sitename' => 'bsite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 0 + 'wiki_id' => $wiki->id, 'pages' => 0, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'three.wikibase.cloud', 'sitename' => 'asite' + 'domain' => 'three.wikibase.cloud', 'sitename' => 'asite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 55 + 'wiki_id' => $wiki->id, 'pages' => 55, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'four.wikibase.cloud', 'sitename' => 'dsite' + 'domain' => 'four.wikibase.cloud', 'sitename' => 'dsite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id, 'pages' => 1 + 'wiki_id' => $wiki->id, 'pages' => 1, ]); $wiki = Wiki::factory()->create([ - 'domain' => 'nostats.wikibase.cloud', 'sitename' => 'zsite' + 'domain' => 'nostats.wikibase.cloud', 'sitename' => 'zsite', ]); - $this->json('GET', $this->route.'?is_active=1') + $this->json('GET', $this->route . '?is_active=1') ->assertStatus(200) ->assertJsonPath('data.0.domain', 'three.wikibase.cloud') ->assertJsonPath('data.1.domain', 'one.wikibase.cloud') @@ -259,25 +251,24 @@ public function testFilterIsActive() ->assertJsonPath('meta.total', 5); } - public function testLogoUrl() - { + public function testLogoUrl() { $wiki = Wiki::factory()->create([ - 'domain' => 'one.wikibase.cloud', 'sitename' => 'asite' + 'domain' => 'one.wikibase.cloud', 'sitename' => 'asite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); WikiSetting::factory()->create([ 'wiki_id' => $wiki->id, 'name' => 'wgLogo', - 'value' => 'https://storage.googleapis.com/wikibase-cloud/foo.bar.png' + 'value' => 'https://storage.googleapis.com/wikibase-cloud/foo.bar.png', ]); $wiki = Wiki::factory()->create([ - 'domain' => 'two.wikibase.cloud', 'sitename' => 'bsite' + 'domain' => 'two.wikibase.cloud', 'sitename' => 'bsite', ]); WikiSiteStats::factory()->create([ - 'wiki_id' => $wiki->id + 'wiki_id' => $wiki->id, ]); $this->json('GET', $this->route) diff --git a/tests/Routes/Wiki/SettingUpdateTest.php b/tests/Routes/Wiki/SettingUpdateTest.php index c0cfd600a..5f9f1e4b3 100644 --- a/tests/Routes/Wiki/SettingUpdateTest.php +++ b/tests/Routes/Wiki/SettingUpdateTest.php @@ -6,14 +6,13 @@ use App\Wiki; use App\WikiManager; use App\WikiSetting; -use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\Routes\Traits\OptionsRequestAllowed; use Tests\Routes\Traits\PostRequestNeedAuthentication; use Tests\TestCase; -class SettingUpdateTest extends TestCase -{ +class SettingUpdateTest extends TestCase { use HasFactory; protected $route = 'wiki/setting/foo/update'; @@ -22,24 +21,22 @@ class SettingUpdateTest extends TestCase use OptionsRequestAllowed; use PostRequestNeedAuthentication; - public function testSetInvalidSetting() - { + public function testSetInvalidSetting() { $settingName = 'iDoNotExistAsASetting'; $wiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') ->json('POST', str_replace('foo', $settingName, $this->route), [ - 'wiki' => $wiki->id, - 'setting' => $settingName, - 'value' => '1', - ]) - ->assertStatus(422) - ->assertJsonStructure(['errors' => ['setting']]); + 'wiki' => $wiki->id, + 'setting' => $settingName, + 'value' => '1', + ]) + ->assertStatus(422) + ->assertJsonStructure(['errors' => ['setting']]); } - public function testFailOnWrongWikiManager(): void - { + public function testFailOnWrongWikiManager(): void { $settingName = 'wwExtEnableConfirmAccount'; $userWiki = Wiki::factory()->create(); $otherWiki = Wiki::factory()->create(); @@ -49,13 +46,12 @@ public function testFailOnWrongWikiManager(): void ->postJson(str_replace('foo', $settingName, $this->route), [ 'wiki' => $otherWiki->id, 'setting' => $settingName, - 'value' => '1' + 'value' => '1', ]) ->assertStatus(403); } - static public function provideValidSettings() - { + public static function provideValidSettings() { yield ['wgDefaultSkin', 'vector', 'vector']; yield ['wwExtEnableConfirmAccount', '1', '1']; yield ['wwExtEnableConfirmAccount', '0', '0']; @@ -65,7 +61,7 @@ static public function provideValidSettings() yield ['wikibaseFedPropsEnable', '1', '1']; yield ['wikibaseFedPropsEnable', '0', '0']; - $emptyArrays = json_encode(['items' => [], 'properties'=> []]); + $emptyArrays = json_encode(['items' => [], 'properties' => []]); yield ['wikibaseManifestEquivEntities', $emptyArrays, $emptyArrays]; $somePropsNoItems = json_encode(['properties' => ['P31' => 'P1'], 'items' => []]); @@ -77,38 +73,36 @@ static public function provideValidSettings() yield ['wwUseQuestyCaptcha', '1', '1']; yield ['wwUseQuestyCaptcha', '0', '0']; $validCaptchaQuestions = json_encode([ - "How many vowels are in this question?" => ['12', 'twelve'], - "What is the chemical formula of water" => ['H2O'], - "2 + 4 = ?" => ['6', 'six'] + 'How many vowels are in this question?' => ['12', 'twelve'], + 'What is the chemical formula of water' => ['H2O'], + '2 + 4 = ?' => ['6', 'six'], ]); - yield ['wwCaptchaQuestions', $validCaptchaQuestions, $validCaptchaQuestions ]; + yield ['wwCaptchaQuestions', $validCaptchaQuestions, $validCaptchaQuestions]; } /** * @dataProvider provideValidSettings */ - public function testValidSetting($settingName, $settingValue, $expectedStored) - { + public function testValidSetting($settingName, $settingValue, $expectedStored) { $user = User::factory()->create(['verified' => true]); $wiki = Wiki::factory('nodb')->create(); $manager = WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') ->json('POST', str_replace('foo', $settingName, $this->route), [ - 'wiki' => $wiki->id, - 'setting' => $settingName, - 'value' => $settingValue, + 'wiki' => $wiki->id, + 'setting' => $settingName, + 'value' => $settingValue, ]) ->assertStatus(200); $this->assertSame( $expectedStored, - WikiSetting::whereWikiId($wiki->id)->whereName($settingName)->first()->value - ); + WikiSetting::whereWikiId($wiki->id)->whereName($settingName)->first()->value + ); } - static public function provideValidSettingsBadValues() - { + public static function provideValidSettingsBadValues() { yield ['wgDefaultSkin', 'foo']; yield ['wwExtEnableConfirmAccount', 'foo']; yield ['wwWikibaseStringLengthString', 12]; @@ -131,40 +125,39 @@ static public function provideValidSettingsBadValues() yield ['wikibaseManifestEquivEntities', json_encode(['properties' => ['P1' => 'P2'], 'items' => ['Q2' => 'Q2', 'P2' => 'P2']])]; // no answers yield ['wwCaptchaQuestions', json_encode([ - "How many vowels are in this question?" => [] + 'How many vowels are in this question?' => [], ])]; // Question too long yield ['wwCaptchaQuestions', json_encode([ - "How many vowels are in this question?How many vowels are in this question? + 'How many vowels are in this question?How many vowels are in this question? How many vowels are in this question?How many vowels are in this question? How many vowels are in this question?How many vowels are in this question? - How many vowels are in this question?How many vowels are in this question?" => ['12', 'twelve'] + How many vowels are in this question?How many vowels are in this question?' => ['12', 'twelve'], ])]; // Answer too long yield ['wwCaptchaQuestions', json_encode([ - "Is this too long?" => [ - "LongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswer + 'Is this too long?' => [ + 'LongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswer LongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswer LongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswer - LongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswer" - ] + LongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswerLongAnswer', + ], ])]; } /** * @dataProvider provideValidSettingsBadValues */ - public function testValidSettingBadValues($settingName, $settingValue) - { + public function testValidSettingBadValues($settingName, $settingValue) { $wiki = Wiki::factory()->create(); $user = User::factory()->create(['verified' => true]); WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); $this->actingAs($user, 'api') ->json('POST', str_replace('foo', $settingName, $this->route), [ - 'wiki' => $wiki->id, - 'setting' => $settingName, - 'value' => $settingValue, + 'wiki' => $wiki->id, + 'setting' => $settingName, + 'value' => $settingValue, ]) ->assertStatus(422) ->assertJsonStructure(['errors' => ['value']]); diff --git a/tests/TestCase.php b/tests/TestCase.php index bb92ba8c0..f6b421cb7 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,17 +5,15 @@ use Illuminate\Contracts\Console\Kernel; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; -abstract class TestCase extends BaseTestCase -{ +abstract class TestCase extends BaseTestCase { /** * Creates the application. * * @return \Illuminate\Foundation\Application */ - public function createApplication() - { + public function createApplication() { putenv('QUEUE_CONNECTION=sync'); - $app = require __DIR__.'/../bootstrap/app.php'; + $app = require __DIR__ . '/../bootstrap/app.php'; $app->make(Kernel::class)->bootstrap(); return $app; diff --git a/tests/Validation/ReCaptchaValidationTest.php b/tests/Validation/ReCaptchaValidationTest.php index fc64b5e14..8621ce0ca 100644 --- a/tests/Validation/ReCaptchaValidationTest.php +++ b/tests/Validation/ReCaptchaValidationTest.php @@ -2,68 +2,62 @@ namespace Tests\Feature; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Foundation\Testing\WithFaker; -use Tests\TestCase; use App\Rules\ReCaptchaValidation; -use \ReCaptcha\ReCaptcha; +use ReCaptcha\ReCaptcha; +use Tests\TestCase; -class ReCaptchaValidationTest extends TestCase -{ - public function buildMockedReCaptcha($fakeResponse) - { +class ReCaptchaValidationTest extends TestCase { + public function buildMockedReCaptcha($fakeResponse) { $mockRuleBuilder = $this->getMockBuilder(ReCaptcha::class); $mockRuleBuilder->setConstructorArgs([ config('recaptcha.secret_key', 'someSecret'), ]); $mockRuleBuilder->onlyMethods([ - 'verify' + 'verify', ]); $mockRule = $mockRuleBuilder->getMock(); $mockRule->method('verify') - ->willReturn( - \ReCaptcha\Response::fromJson( - json_encode($fakeResponse) - ) - ); + ->willReturn( + \ReCaptcha\Response::fromJson( + json_encode($fakeResponse) + ) + ); return $mockRule; } - public function buildReCaptchaFakeResponse(array $data=[]) - { + public function buildReCaptchaFakeResponse(array $data = []) { $template = [ - 'success' => true, - 'hostname' => 'localhost', - 'challenge_ts' => date('Y-m-d\TH:i:s\Z', time() - 120), - 'apk_package_name' => null, - 'score' => config('recaptcha.min_score'), - 'action' => 'default', - 'error-codes' => [], + 'success' => true, + 'hostname' => 'localhost', + 'challenge_ts' => date('Y-m-d\TH:i:s\Z', time() - 120), + 'apk_package_name' => null, + 'score' => config('recaptcha.min_score'), + 'action' => 'default', + 'error-codes' => [], ]; return array_merge($template, $data); } - public function buildReCaptchaValidation($recaptcha=false, $minScore=false, $appUrl=false) { - if (false === $recaptcha) { + public function buildReCaptchaValidation($recaptcha = false, $minScore = false, $appUrl = false) { + if ($recaptcha === false) { $recaptcha = new ReCaptcha('secret'); } - if (false === $minScore) { + if ($minScore === false) { $minScore = config('recaptcha.min_score', 0.5); } - if (false === $appUrl) { + if ($appUrl === false) { $appUrl = config('app.url', 'http://www.wbaas.localhost'); } return new ReCaptchaValidation($recaptcha, $minScore, $appUrl); } - public function testBypassFails() - { + public function testBypassFails() { $rule = $this->buildReCaptchaValidation(); $this->assertFalse( @@ -71,10 +65,9 @@ public function testBypassFails() ); } - public function testLowScore() - { + public function testLowScore() { $fakeResponse = $this->buildReCaptchaFakeResponse([ - 'score' => config('recaptcha.min_score') -1, + 'score' => config('recaptcha.min_score') - 1, ]); $mockReCaptcha = $this->buildMockedReCaptcha($fakeResponse); @@ -85,10 +78,9 @@ public function testLowScore() ); } - public function testInactiveHostVerification() - { + public function testInactiveHostVerification() { $fakeResponse = $this->buildReCaptchaFakeResponse([ - 'hostname' => 'example.com' + 'hostname' => 'example.com', ]); $mockReCaptcha = $this->buildMockedReCaptcha($fakeResponse); @@ -99,10 +91,9 @@ public function testInactiveHostVerification() ); } - public function testWrongHostname() - { + public function testWrongHostname() { $fakeResponse = $this->buildReCaptchaFakeResponse([ - 'hostname' => 'example.com' + 'hostname' => 'example.com', ]); $mockReCaptcha = $this->buildMockedReCaptcha($fakeResponse); @@ -113,10 +104,9 @@ public function testWrongHostname() ); } - public function testNoSuccess() - { + public function testNoSuccess() { $fakeResponse = $this->buildReCaptchaFakeResponse([ - 'success' => false + 'success' => false, ]); $mockReCaptcha = $this->buildMockedReCaptcha($fakeResponse); @@ -127,8 +117,7 @@ public function testNoSuccess() ); } - public function testSuccess() - { + public function testSuccess() { $fakeResponse = $this->buildReCaptchaFakeResponse(); $mockReCaptcha = $this->buildMockedReCaptcha($fakeResponse); diff --git a/tests/WikiDailyMetricsTest.php b/tests/WikiDailyMetricsTest.php index b63581924..a0a61639c 100644 --- a/tests/WikiDailyMetricsTest.php +++ b/tests/WikiDailyMetricsTest.php @@ -2,37 +2,35 @@ namespace Tests; -use Tests\TestCase; use App\WikiDailyMetrics; use Illuminate\Foundation\Testing\RefreshDatabase; -class WikiDailyMetricsTest extends TestCase -{ +class WikiDailyMetricsTest extends TestCase { use RefreshDatabase; - public static function areMetricsEqualProvider(){ + public static function areMetricsEqualProvider() { yield 'is the same' => [ - new WikiDailyMetrics(["pages" => 1, "is_deleted" => false ]), - new WikiDailyMetrics(["pages" => 1, "is_deleted" => false ]), - true + new WikiDailyMetrics(['pages' => 1, 'is_deleted' => false]), + new WikiDailyMetrics(['pages' => 1, 'is_deleted' => false]), + true, ]; yield 'more pages' => [ - new WikiDailyMetrics(["pages" => 1, "is_deleted" => false ]), - new WikiDailyMetrics(["pages" => 20, "is_deleted" => false ]), - false + new WikiDailyMetrics(['pages' => 1, 'is_deleted' => false]), + new WikiDailyMetrics(['pages' => 20, 'is_deleted' => false]), + false, ]; yield 'less pages' => [ - new WikiDailyMetrics(["pages" => 10, "is_deleted" => false ]), - new WikiDailyMetrics(["pages" => 1, "is_deleted" => false ]), - false + new WikiDailyMetrics(['pages' => 10, 'is_deleted' => false]), + new WikiDailyMetrics(['pages' => 1, 'is_deleted' => false]), + false, ]; yield 'is deleted' => [ - new WikiDailyMetrics(["pages" => 1, "is_deleted" => false ]), - new WikiDailyMetrics(["pages" => 1, "is_deleted" => true ]), - false + new WikiDailyMetrics(['pages' => 1, 'is_deleted' => false]), + new WikiDailyMetrics(['pages' => 1, 'is_deleted' => true]), + false, ]; } @@ -43,8 +41,7 @@ public function testAreMetricsEqual( WikiDailyMetrics $wikiDailyMetrics1, WikiDailyMetrics $wikiDailyMetrics2, $assertion - ): void - { + ): void { $this->assertEquals( $wikiDailyMetrics1->areMetricsEqual($wikiDailyMetrics2), $assertion diff --git a/tests/WikiProfileTest.php b/tests/WikiProfileTest.php index b5e0b2d56..ac38b9577 100644 --- a/tests/WikiProfileTest.php +++ b/tests/WikiProfileTest.php @@ -5,10 +5,8 @@ use App\Wiki; use App\WikiProfile; use Illuminate\Foundation\Testing\RefreshDatabase; -use Tests\TestCase; -class WikiProfileTest extends TestCase -{ +class WikiProfileTest extends TestCase { use RefreshDatabase; protected Wiki $wiki; @@ -17,9 +15,8 @@ protected function setUp(): void { parent::setUp(); $this->wiki = Wiki::factory()->create(); } - - public function testCreateValidWikiProfile(): void - { + + public function testCreateValidWikiProfile(): void { $profile = new WikiProfile([ 'wiki_id' => $this->wiki->id, 'purpose' => 'data_hub', @@ -37,8 +34,7 @@ public function testCreateValidWikiProfile(): void ]); } - public function testCreateWikiProfileWithOtherFields(): void - { + public function testCreateWikiProfileWithOtherFields(): void { $profile = new WikiProfile([ 'wiki_id' => $this->wiki->id, 'purpose' => 'other', @@ -61,5 +57,4 @@ public function testCreateWikiProfileWithOtherFields(): void 'temporality_other' => 'Custom temporality', ]); } - -} \ No newline at end of file +}