Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TM-785] Unit testing and linting for the BE repo #135

Merged
merged 22 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4adf29c
[TM-785] Move constants to avoid a problem in PHPUnit.
roguenet Apr 3, 2024
57900ba
[TM-785] Fix old migration that was throwing an error in PHPUnit
roguenet Apr 3, 2024
0d5d2ca
[TM-785] Fail gracefully if SNS is not enabled.
roguenet Apr 3, 2024
1c18d99
[TM-785] Remove the legacy unit tests.
roguenet Apr 5, 2024
081c5cb
[TM-785] Get the linter passing.
roguenet Apr 5, 2024
22ac48d
[TM-785] Get the UpdateRequests tests passing.
roguenet Apr 5, 2024
1b39e58
[TM-785] Stages tests passing.
roguenet Apr 5, 2024
8a254d8
[TM-785] Don't let faker create random statuses; it leads to flaky te…
roguenet Apr 8, 2024
446244b
[TM-785] Avoid generating multiple forms for the same framework/entit…
roguenet Apr 8, 2024
9d60eb5
[TM-785] Sites tests all passing.
roguenet Apr 8, 2024
da09048
[TM-785] Projects tests all passing.
roguenet Apr 8, 2024
be83f11
[TM-785] Nursery tests all passing.
roguenet Apr 8, 2024
fc602d4
[TM-785] Task tests passing.
roguenet Apr 8, 2024
b51534b
[TM-785] Report tests passing.
roguenet Apr 8, 2024
999eabe
[TM-785] Get use of the roles migration consistent.
roguenet Apr 8, 2024
81db145
[TM-785] Clean up some warnings in tests found by PhpStorm
roguenet Apr 8, 2024
973d987
[TM-785] All V2 tests passing.
roguenet Apr 8, 2024
5a8deaa
[TM-785] Another lint pass after fixing the tests.
roguenet Apr 9, 2024
3af2e8a
[TM-785] `make test` now runs locally without overwriting the local d…
roguenet Apr 9, 2024
5818748
[TM-785] Github workflow to run tests.
roguenet Apr 9, 2024
ea861e0
Merge remote-tracking branch 'origin/staging' into feat/TM-785-unit-t…
roguenet Apr 9, 2024
2c17192
Fix linting problem with new code from staging
roguenet Apr 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ SESSION_LIFETIME=120
SNS_PLATFORM_ARN_IOS=arn:aws:sns:us-west-2:123456789012:app/APNS/wri_rm_ios
SNS_PLATFORM_ARN_ANDROID=arn:aws:sns:us-west-2:123456789012:app/FCM/wri_rm_android
SNS_PREFIX=http://motocker:9911
SNS_ENABLED=true
SNS_ENABLED=false

REDIS_HOST=redis
REDIS_PASSWORD=
Expand Down
70 changes: 70 additions & 0 deletions .env.testing
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:dGJr4Cs1jvRm98V15YvJhtrkkDiU4aXPK/0LAZhjSFA=
APP_DEBUG=true
APP_URL=http://127.0.0.1:8080
APP_FRONT_END=http://localhost:3000

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=mariadb
DB_PORT=3306
DB_DATABASE=terramatch_test
DB_USERNAME=wri
DB_PASSWORD=wri

BROADCAST_DRIVER=log
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
SESSION_CONNECTION=default
SESSION_LIFETIME=120

SNS_PLATFORM_ARN_IOS=arn:aws:sns:us-west-2:123456789012:app/APNS/wri_rm_ios
SNS_PLATFORM_ARN_ANDROID=arn:aws:sns:us-west-2:123456789012:app/FCM/wri_rm_android
SNS_PREFIX=http://motocker:9911
SNS_ENABLED=false

REDIS_HOST=redis
REDIS_PASSWORD=
REDIS_PORT=6379
REDIS_QUEUE_NAME=wri_test
REDIS_DB=0
REDIS_CACHE_DB=1

MAIL_MAILER=smtp
MAIL_HOST=mailcatcher
MAIL_PORT=1025
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=null
[email protected]
MAIL_FROM_NAME="WRI TerraMatch"

AWS_ACCESS_KEY_ID=AKIABUVWH1HUD7YQZQAR
AWS_SECRET_ACCESS_KEY=PVMlDMep3/jLSz9GxPV3mTvH4JZynkf2BFeTu+i8
AWS_DEFAULT_REGION=us-west-2
AWS_BUCKET=wri
S3_PREFIX=http://minio:9000
S3_BUCKET=wri

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=

MIX_PUSHER_APP_KEY=
MIX_PUSHER_APP_CLUSTER=

JWT_SECRET=qu3sep4GKdbg6PiVPCKLKljHukXALorq6nLHDBOCSwvs6BrgE6zb8gPmZfrNspKt

ELASTIC_TRANSCODER_PREFIX=http://elastictranscoder:2323
ELASTIC_TRANSCODER_PIPELINE_ID=1111111111111-abcde1
ELASTIC_TRANSCODER_PRESET_ID=1351620000001-000001

LOG_SLACK_WEBHOOK_URL=

SENTRY_LARAVEL_DSN=

TREE_SEARCH_API_URL=
15 changes: 15 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: pull-request
on:
pull_request:
branches: [main, staging, release/**]
jobs:
lintTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install deps
run: make composer
- name: Bring up Docker
run: make up
- name: Lint & Test
run: make test
18 changes: 13 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,28 @@ migrate-seed:
docker-compose exec php php ./artisan migrate-services
docker-compose exec php php ./artisan db:seed

test: migrate-seed
docker-compose exec php ./vendor/bin/php-cs-fixer fix -v --dry-run --stop-on-violation --using-cache=no
docker-compose exec php ./vendor/bin/phpunit
migrate-seed-test:
echo "create database if not exists terramatch_test;" | docker-compose exec -T mariadb mysql -h localhost -u root -proot
echo "grant all on terramatch_test.* to 'wri'@'%';" | docker-compose exec -T mariadb mysql -h localhost -u root -proot
docker-compose exec -T php php artisan --env=testing migrate:fresh
docker-compose exec -T php php artisan --env=testing migrate-services
docker-compose exec -T php php artisan --env=testing db:seed

test: lint migrate-seed-test
docker-compose exec -T php ./vendor/bin/phpunit

test-single:
docker-compose exec php ./vendor/bin/phpunit --filter $(t)

ts: test-single

quick-test: migrate-seed
docker-compose exec php ./vendor/bin/php-cs-fixer fix -v --dry-run --stop-on-violation --using-cache=no
quick-test: lint migrate-seed-test
docker-compose exec php ./vendor/bin/phpunit --exclude=skipPipeline,slow

lint:
docker-compose exec -T php ./vendor/bin/php-cs-fixer fix -v --dry-run --stop-on-violation --using-cache=no

lint-fix:
docker-compose exec php ./vendor/bin/php-cs-fixer fix -v

lint-test:
Expand Down
8 changes: 4 additions & 4 deletions app/Auth/ServiceAccountGuard.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ class ServiceAccountGuard implements Guard
{
use GuardHelpers;

const HEADER = 'authorization';
CONST PREFIX = 'bearer';
const API_KEY_LENGTH = 64;
public const HEADER = 'authorization';
public const PREFIX = 'bearer';
public const API_KEY_LENGTH = 64;

protected Request $request;

Expand Down Expand Up @@ -73,4 +73,4 @@ protected function isJwt($value): bool
return false;
}
}
}
}
15 changes: 10 additions & 5 deletions app/Console/Commands/CreateBackdatedReportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@

use App\Models\V2\Nurseries\Nursery;
use App\Models\V2\Nurseries\NurseryReport;
use App\Models\V2\Sites\Site;
use App\Models\V2\Sites\SiteReport;
use App\Models\V2\Projects\Project;
use App\Models\V2\Projects\ProjectReport;
use App\StateMachines\TaskStatusStateMachine;
use App\Models\V2\Sites\Site;
use App\Models\V2\Sites\SiteReport;
use App\Models\V2\Tasks\Task;
use Carbon\Carbon;
use App\StateMachines\TaskStatusStateMachine;
use Illuminate\Console\Command;

class CreateBackdatedReportCommand extends Command
Expand All @@ -36,20 +35,24 @@ public function handle(): int
case 'project':
$entityModel = Project::class;
$reportModel = ProjectReport::class;

break;

case 'site':
$entityModel = Site::class;
$reportModel = SiteReport::class;

break;

case 'nursery':
$entityModel = Nursery::class;
$reportModel = NurseryReport::class;

break;

default:
$this->error('Type must be one of "site" or "nursery"');

return 1;
}

Expand All @@ -58,6 +61,7 @@ public function handle(): int
$entity = $entityModel::where('uuid', $uuid)->first();
if ($entity == null) {
$this->error("Entity.php not found [type=$type, uuid=$uuid]");

return 1;
}

Expand All @@ -73,6 +77,7 @@ public function handle(): int

if ($task == null) {
$this->error("Task not found for project [$entity->project_id]");

return 1;
}

Expand All @@ -97,4 +102,4 @@ public function handle(): int

return 0;
}
}
}
3 changes: 2 additions & 1 deletion app/Console/Commands/CreateServiceAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use DateTimeZone;
use Exception;
use Illuminate\Console\Command;
use Spatie\Permission\Models\Role;

class CreateServiceAccount extends Command
{
Expand Down Expand Up @@ -51,11 +50,13 @@ public function handle()
$user->assignRole('greenhouse-service-account');

$this->info("Created service account $email with API Key: $apiKey");

return 0;

} catch (Exception $exception) {
$this->error($exception->getMessage());
$this->error('Creation failed');

return -1;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use App\Models\V2\Projects\Project;
use App\Models\V2\Projects\ProjectReport;
use App\Models\V2\Tasks\Task;
use App\StateMachines\TaskStatusStateMachine;
use Illuminate\Console\Command;

class CreateTasksMigrationCommand extends Command
Expand Down
6 changes: 4 additions & 2 deletions app/Console/Commands/OneOff/AssociateReportsTasksCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function handle()
);
}

protected function addTaskIds ($class, $projectGetter = null): void
protected function addTaskIds($class, $projectGetter = null): void
{
if ($projectGetter == null) {
$projectGetter = fn ($report) => $report->project()->withTrashed()->first();
Expand All @@ -61,12 +61,14 @@ protected function addTaskIds ($class, $projectGetter = null): void
$project = $projectGetter($report);
if ($project == null) {
$skipped++;

continue;
}

$task = $this->taskForProjectAndDate($project, $report->due_at)->first();
if ($task == null) {
$skipped++;

continue;
}

Expand All @@ -82,7 +84,7 @@ protected function addTaskIds ($class, $projectGetter = null): void
$this->info("Completed $className migration [target=$target, updated=$updated, skipped=$skipped]");
}

protected function taskForProjectAndDate (Project $project, Carbon $date): Builder
protected function taskForProjectAndDate(Project $project, Carbon $date): Builder
{
return Task::where('project_id', $project->id)
->whereMonth('due_at', $date->month)
Expand Down
2 changes: 1 addition & 1 deletion app/Console/Commands/OneOff/FixReportCompletion.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function handle()
$totalUpdated = 0;
$totalAlreadyCorrect = 0;
collect([ProjectReport::class, SiteReport::class, NurseryReport::class])->each(
function($modelClass) use (&$totalUpdated, &$totalAlreadyCorrect) {
function ($modelClass) use (&$totalUpdated, &$totalAlreadyCorrect) {
$modelClass::withoutTimestamps(function () use ($modelClass, &$totalUpdated, &$totalAlreadyCorrect) {
$modelClass::whereNot('status', ReportStatusStateMachine::DUE)->where('completion', '<', 100)->chunkById(
100,
Expand Down
10 changes: 7 additions & 3 deletions app/Console/Commands/OneOff/MigrateTaskStatuses.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function handle()
// statuses aren't part of the updated state machine), we're re-implementing most of the logic in
// Task->checkStatus
Task::withoutTimestamps(function () use (&$numErrors, &$numClean) {
Task::withTrashed()->whereNotIn('status',self::VALID_STATUSES)->chunkbyId(
Task::withTrashed()->whereNotIn('status', self::VALID_STATUSES)->chunkbyId(
100,
function ($tasks) use (&$numErrors, &$numClean) {
foreach ($tasks as $task) {
Expand All @@ -66,18 +66,20 @@ function ($tasks) use (&$numErrors, &$numClean) {
}
}
}
});
}
);
});

echo "Migration completed. [Tasks with errors: $numErrors, successful transitions: $numClean]";
}

private function processException(Task $task, InvalidStatusException $exception): bool
{
if (!$task->projectReport()->exists() && !$task->siteReports()->exists() && !$task->nurseryReports()->exists()) {
if (! $task->projectReport()->exists() && ! $task->siteReports()->exists() && ! $task->nurseryReports()->exists()) {
echo "Task $task->id was due on $task->due_at and has no associated reports. Moving to 'approved'.\n";
$task->status = TaskStatusStateMachine::APPROVED;
$task->save();

return true;
}

Expand All @@ -93,11 +95,13 @@ private function processException(Task $task, InvalidStatusException $exception)
echo "Task $task->id was due on $task->due_at and has reports in 'due' or 'started'. Moving to 'due'.\n";
$task->status = TaskStatusStateMachine::DUE;
$task->save();

return true;
}

$message = $exception->getMessage();
echo "Task $task->id: $message\n";

return false;
}
}
1 change: 1 addition & 0 deletions app/Console/Commands/UpdateUrlBucketCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public function handle(): int
// Add more tables if needed

$this->info('Update completed successfully.');

return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion app/Exceptions/InvalidStatusException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

class InvalidStatusException extends Exception
{
}
}
Loading
Loading