Skip to content

Commit

Permalink
Merge pull request #135 from wri/feat/TM-785-unit-tests
Browse files Browse the repository at this point in the history
[TM-785] Unit testing and linting for the BE repo
  • Loading branch information
roguenet authored Apr 10, 2024
2 parents 6dca35d + 2c17192 commit fc77911
Show file tree
Hide file tree
Showing 341 changed files with 738 additions and 18,248 deletions.
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
MAIL_FROM_ADDRESS=[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

0 comments on commit fc77911

Please sign in to comment.