first commit

This commit is contained in:
Noor E Ilahi
2026-01-09 12:54:53 +05:30
commit 7ccf44f7da
1070 changed files with 113036 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
<?php
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Foundation\Application;
use Settings;
trait CreatesApplication
{
public function createApplication(): Application
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
Settings::scope('core')->set('installed', true);
return $app;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Tests\Facades;
use App\Models\Task;
use App\Models\TimeInterval;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;
use Tests\Factories\IntervalFactory as BaseIntervalFactory;
/**
* @method static TimeInterval create(array $attributes = [])
* @method static Collection createMany(int $amount = 1)
* @method static array createRandomModelData()
* @method static array createRandomModelDataWithRelation()
* @method static array createRandomManualModelDataWithRelations()
* @method static BaseIntervalFactory forUser(User $user)
* @method static BaseIntervalFactory forTask(Task $task)
* @method static BaseIntervalFactory withRandomRelations()
*/
class IntervalFactory extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return BaseIntervalFactory::class;
}
/**
* Resolve a new instance for the facade
*
* @return mixed
*/
public static function refresh()
{
static::clearResolvedInstance(static::getFacadeAccessor());
return static::getFacadeRoot();
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Tests\Facades;
use App\Models\Invitation;
use Illuminate\Support\Facades\Facade;
use Tests\Factories\InvitationFactory as BaseInvitationFactory;
/**
* @method static Invitation create(array $attributes = [])
* @method static array createRandomModelData()
* @method static array createRequestData()
*/
class InvitationFactory extends Facade
{
protected static function getFacadeAccessor(): string
{
return BaseInvitationFactory::class;
}
/**
* Resolve a new instance for the facade
*
* @return mixed
*/
public static function refresh()
{
static::clearResolvedInstance(static::getFacadeAccessor());
return static::getFacadeRoot();
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Tests\Facades;
use App\Models\Project;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;
use Tests\Factories\ProjectFactory as BaseProjectFactory;
/**
* @method static Project create(array $attributes = [])
* @method static Collection createMany(int $amount = 1)
* @method static array createRandomModelData()
* @method static BaseProjectFactory withTasks(int $quantity = 1)
* @method static BaseProjectFactory forUsers(array $users)
* @method static BaseProjectFactory createTasks(Project $project)
*/
class ProjectFactory extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return BaseProjectFactory::class;
}
/**
* Resolve a new instance for the facade
*
* @return mixed
*/
public static function refresh()
{
static::clearResolvedInstance(static::getFacadeAccessor());
return static::getFacadeRoot();
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Tests\Facades;
use App\Models\ProjectsUsers;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;
use Tests\Factories\ProjectUserFactory as BaseProjectUserFactory;
/**
* @method static ProjectsUsers create(array $attributes = [])
* @method static BaseProjectUserFactory forUser(User $user)
* @method static BaseProjectUserFactory setRole(int $roleId)
* @method static Collection createMany(int $amount = 1)
* @method static array createRandomModelData()
*/
class ProjectUserFactory extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return BaseProjectUserFactory::class;
}
/**
* Resolve a new instance for the facade
*
* @return mixed
*/
public static function refresh()
{
static::clearResolvedInstance(static::getFacadeAccessor());
return static::getFacadeRoot();
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Tests\Facades;
use App\Models\Screenshot;
use App\Models\TimeInterval;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;
use Tests\Factories\ScreenshotFactory as BaseScreenshotFactory;
/**
* @method static Screenshot create(array $attributes = [])
* @method static array createRandomModelData()
* @method static Collection createMany(int $amount = 1)
* @method static BaseScreenshotFactory withRandomRelations()
* @method static BaseScreenshotFactory forInterval(TimeInterval $interval)
* @method static BaseScreenshotFactory fake()
*/
class ScreenshotFactory extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return BaseScreenshotFactory::class;
}
/**
* Resolve a new instance for the facade
*
* @return mixed
*/
public static function refresh()
{
static::clearResolvedInstance(static::getFacadeAccessor());
return static::getFacadeRoot();
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Tests\Facades;
use App\Models\Task;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;
use Tests\Factories\TaskFactory as BaseTaskFactory;
/**
* @method static Task create(array $attributes = [])
* @method static Collection createMany(int $amount = 1)
* @method static BaseTaskFactory forUser(User $user)
* @method static array createRandomModelData()
* @method static BaseTaskFactory withIntervals(int $quantity = 1)
*/
class TaskFactory extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return BaseTaskFactory::class;
}
/**
* Resolve a new instance for the facade
*
* @return mixed
*/
public static function refresh()
{
static::clearResolvedInstance(static::getFacadeAccessor());
return static::getFacadeRoot();
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Tests\Facades;
use App\Models\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Facade;
use Tests\Factories\UserFactory as BaseUserFactory;
/**
* @method static User create()
* @method static Collection createMany(int $amount = 1)
* @method static BaseUserFactory withTokens(int $amount = 1)
* @method static BaseUserFactory asAdmin()
* @method static BaseUserFactory asUser()
* @method static array createRandomModelData()
* @method static array createRandomRegistrationModelData()
*/
class UserFactory extends Facade
{
/**
* Get the registered name of the component.
*/
protected static function getFacadeAccessor(): string
{
return BaseUserFactory::class;
}
/**
* Resolve a new instance for the facade
*
* @return mixed
*/
public static function refresh()
{
static::clearResolvedInstance(static::getFacadeAccessor());
return static::getFacadeRoot();
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Tests\Factories;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
abstract class Factory
{
protected bool $timestampsHidden = true;
protected bool $randomRelations = false;
abstract protected function getModelInstance(): Model;
abstract public function createRandomModelData(): array;
abstract public function create(): Model;
public function createMany(int $amount = 1): Collection
{
$models = array_map(fn () => $this->create(), range(0, $amount));
return collect($models);
}
protected function hideTimestamps(): void
{
$this->getModelInstance()->makeHidden(['created_at', 'updated_at', 'deleted_at']);
}
protected function hideCanAttribute(): void
{
$this->getModelInstance()->makeHidden(['can']);
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Tests\Factories;
use App\Models\Task;
use App\Models\TimeInterval;
use App\Models\User;
use Carbon\Carbon;
use Faker\Factory as FakerFactory;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
class IntervalFactory extends Factory
{
private ?User $user = null;
private ?Task $task = null;
private TimeInterval $interval;
public function createRandomModelDataWithRelation(): array
{
return array_merge($this->createRandomModelData(), [
'task_id' => TaskFactory::create()->id,
'user_id' => UserFactory::create()->id,
]);
}
public function createRandomModelData(): array
{
$randomDateTime = FakerFactory::create()->unique()->dateTimeThisYear();
$randomDateTime = Carbon::instance($randomDateTime);
return [
'end_at' => $randomDateTime->toIso8601String(),
'start_at' => $randomDateTime->subSeconds(random_int(1, 3600))->toIso8601String(),
'activity_fill' => random_int(1, 100),
'mouse_fill' => random_int(1, 100),
'keyboard_fill' => random_int(1, 100),
];
}
public function forUser(User $user): self
{
$this->user = $user;
return $this;
}
public function forTask(Task $task): self
{
$this->task = $task;
return $this;
}
public function withRandomRelations(): self
{
$this->randomRelations = true;
return $this;
}
public function create(): TimeInterval
{
$modelData = $this->createRandomModelData();
$this->interval = TimeInterval::make($modelData);
$this->defineUser();
$this->defineTask();
if ($this->timestampsHidden) {
$this->hideTimestamps();
}
$this->interval->save();
return $this->interval;
}
private function defineUser(): void
{
if ($this->randomRelations || !$this->user) {
$this->user = UserFactory::create();
}
$this->interval->user_id = $this->user->id;
}
private function defineTask(): void
{
if ($this->randomRelations || !$this->task) {
$this->task = TaskFactory::forUser($this->user)->create();
}
$this->interval->task_id = $this->task->id;
}
protected function getModelInstance(): TimeInterval
{
return $this->interval;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Tests\Factories;
use App\Models\Invitation;
use Faker\Factory as FakerFactory;
use Illuminate\Database\Eloquent\Model;
class InvitationFactory extends Factory
{
private Invitation $invitation;
protected function getModelInstance(): Model
{
return $this->invitation;
}
public function createRequestData(): array
{
$faker = FakerFactory::create();
return [
'users' => [
[
'email' => $faker->unique()->email,
'role_id' => 1
]
],
];
}
public function createRandomModelData(): array
{
$faker = FakerFactory::create();
return [
'email' => $faker->unique()->email,
'key' => $faker->uuid,
'expires_at' => now()->addDays(1),
];
}
public function create(): Model
{
$modelData = $this->createRandomModelData();
$this->invitation = Invitation::make($modelData);
$this->invitation->save();
return $this->invitation;
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Tests\Factories;
use App\Models\Project;
use Faker\Factory as FakerFactory;
use Tests\Facades\TaskFactory;
class ProjectFactory extends Factory
{
private const COMPANY_ID = 1;
private const DESCRIPTION_LENGTH = 300;
private int $needsTasks = 0;
private int $needsIntervals = 0;
private array $users = [];
private ?Project $project = null;
protected function getModelInstance(): Project
{
return $this->project;
}
public function withTasks(int $quantity = 1): self
{
$this->needsTasks = $quantity;
return $this;
}
public function create(): Project
{
$modelData = $this->createRandomModelData();
$this->project = Project::create($modelData);
if ($this->users) {
foreach ($this->users as $user) {
$this->project->users()->attach($user->id);
}
}
if ($this->needsTasks) {
$this->createTasks();
}
if ($this->timestampsHidden) {
$this->hideTimestamps();
}
$this->hideCanAttribute();
return $this->project;
}
public function forUsers(array $users): self
{
$this->users = $users;
return $this;
}
public function createRandomModelData(): array
{
$faker = FakerFactory::create();
return [
'company_id' => self::COMPANY_ID,
'name' => $faker->company,
'description' => $faker->text(self::DESCRIPTION_LENGTH),
'source' => 'internal',
];
}
protected function createTasks(): void
{
do {
TaskFactory::withIntervals($this->needsIntervals)
->forProject($this->project)
->create();
} while (--$this->needsTasks);
}
}

View File

@@ -0,0 +1,79 @@
<?php
namespace Tests\Factories;
use App\Models\ProjectsUsers;
use App\Models\User;
use Illuminate\Support\Arr;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
class ProjectUserFactory extends Factory
{
public const USER_ROLE = 2;
public const MANAGER_ROLE = 1;
public const AUDITOR_ROLE = 3;
private ProjectsUsers $projectUser;
private ?User $user = null;
private ?int $roleId = null;
protected function getModelInstance(): ProjectsUsers
{
return $this->projectUser;
}
public function createRandomModelData(): array
{
return $this->createModelDataWithRelations();
}
public function createModelDataWithRelations(): array
{
return [
'project_id' => ProjectFactory::create()->id,
'user_id' => UserFactory::create()->id,
'role_id' =>$this->getRandomRoleId()
];
}
private function defineModelData(): array
{
$this->user ??= UserFactory::create();
$this->roleId ??= $this->getRandomRoleId();
return [
'project_id' => ProjectFactory::create()->id,
'user_id' => $this->user->id,
'role_id' => $this->roleId
];
}
private function getRandomRoleId()
{
return Arr::random([self::USER_ROLE, self::MANAGER_ROLE, self::AUDITOR_ROLE]);
}
public function forUser(User $user): self
{
$this->user = $user;
return $this;
}
public function setRole(int $roleId): self
{
$this->roleId = $roleId;
return $this;
}
public function create(): ProjectsUsers
{
$this->projectUser = ProjectsUsers::create($this->defineModelData());
if ($this->timestampsHidden) {
$this->hideTimestamps();
}
return $this->projectUser;
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Tests\Factories;
use App\Models\Screenshot;
use App\Models\TimeInterval;
use Faker\Factory as FakerFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\UploadedFile;
use Storage;
use Tests\Facades\IntervalFactory;
class ScreenshotFactory extends Factory
{
private ?TimeInterval $interval = null;
private Screenshot $screenshot;
private bool $fakeStorage = false;
public function fake(): self
{
$this->fakeStorage = true;
return $this;
}
protected function getModelInstance(): Model
{
return $this->screenshot;
}
public function createRandomModelData(): array
{
return $this->generateScreenshotData();
}
private function generateScreenshotData(): array
{
$name = FakerFactory::create()->unique()->firstName . '.jpg';
$image = UploadedFile::fake()->image($name);
$path = Storage::put('uploads/screenshots', $image);
$thumbnail = Storage::put('uploads/screenshots', UploadedFile::fake()->image($name));
return compact('path', 'thumbnail');
}
public function create(array $attributes = []): Screenshot
{
if ($this->fakeStorage) {
Storage::fake();
}
$modelData = $this->createRandomModelData();
$this->screenshot = Screenshot::make($modelData);
$this->defineInterval();
$this->screenshot->save();
if ($this->timestampsHidden) {
$this->hideTimestamps();
}
return $this->screenshot;
}
public function withRandomRelations(): self
{
$this->randomRelations = true;
return $this;
}
public function forInterval(TimeInterval $interval): self
{
$this->interval = $interval;
return $this;
}
private function defineInterval(): void
{
if ($this->randomRelations || !$this->interval) {
$this->interval = IntervalFactory::create();
}
$this->screenshot->time_interval_id = $this->interval->id;
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Tests\Factories;
use App\Models\Priority;
use App\Models\Project;
use App\Models\Status;
use App\Models\Task;
use App\Models\User;
use Faker\Factory as FakerFactory;
use Illuminate\Database\Eloquent\Model;
use Tests\Facades\IntervalFactory;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
class TaskFactory extends Factory
{
private const DESCRIPTION_LENGTH = 10;
private int $intervalsAmount = 0;
private ?User $user = null;
private ?Project $project = null;
private Task $task;
protected function getModelInstance(): Model
{
return $this->task;
}
public function withIntervals(int $quantity = 1): self
{
$this->intervalsAmount = $quantity;
return $this;
}
public function forUser(User $user): self
{
$this->user = $user;
return $this;
}
public function forProject(Project $project): self
{
$this->project = $project;
return $this;
}
public function create(array $attributes = []): Task
{
$modelData = $this->createRandomModelData();
$this->task = Task::make($modelData);
$this->defineProject();
$this->defineUser();
$this->task->save();
if (isset($this->user)) {
$this->task->users()->attach($this->user->id);
}
if ($this->intervalsAmount) {
$this->createIntervals();
}
if ($this->timestampsHidden) {
$this->hideTimestamps();
}
return $this->task;
}
public function createRandomModelData(): array
{
$faker = FakerFactory::create();
return [
'task_name' => $faker->jobTitle,
'description' => $faker->text(self::DESCRIPTION_LENGTH),
'priority_id' => Priority::min('id'),
'status_id' => Status::min('id'),
];
}
private function defineProject(): void
{
if (!isset($this->project)) {
$this->project = ProjectFactory::create();
}
$this->task->project_id = $this->project->id;
}
private function defineUser(): void
{
if (!isset($this->user)) {
$this->user = UserFactory::create();
}
}
private function createIntervals(): void
{
do {
IntervalFactory::forUser($this->user)
->forTask($this->task)
->create();
} while (--$this->intervalsAmount);
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace Tests\Factories;
use App\Enums\ScreenshotsState;
use App\Models\User;
use Carbon\Carbon;
use Faker\Factory as FakerFactory;
use Illuminate\Database\Eloquent\Model;
use Tymon\JWTAuth\Facades\JWTAuth;
class UserFactory extends Factory
{
public const USER_ROLE = 2;
public const MANAGER_ROLE = 1;
public const AUDITOR_ROLE = 3;
private int $tokensAmount = 0;
private ?int $roleId = null;
private User $user;
private bool $isAdmin = false;
protected function getModelInstance(): Model
{
return $this->user;
}
public function create(): User
{
$modelData = $this->createRandomModelData();
if ($this->isAdmin) {
$modelData['is_admin'] = true;
}
$this->user = User::create($modelData);
if ($this->tokensAmount) {
$this->createTokens();
}
if ($this->roleId) {
$this->assignRole();
}
$this->user->save();
if ($this->timestampsHidden) {
$this->hideTimestamps();
}
return $this->user;
}
public function createRandomModelData(): array
{
$faker = FakerFactory::create();
$fullName = $faker->name;
return [
'full_name' => $fullName,
'email' => $faker->unique()->safeEmail,
'url' => '',
'company_id' => 1,
'avatar' => '',
'screenshots_state' => ScreenshotsState::REQUIRED,
'manual_time' => 0,
'computer_time_popup' => 300,
'blur_screenshots' => 0,
'web_and_app_monitoring' => 1,
'screenshots_interval' => 5,
'active' => 1,
'password' => $fullName,
'user_language' => 'en',
'role_id' => 2,
'type' => 'employee',
'nonce' => 0,
'last_activity' => Carbon::now()->subMinutes(rand(1, 55)),
];
}
public function createRandomRegistrationModelData(): array
{
$faker = FakerFactory::create();
return [
'full_name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'active' => 1,
'password' => $faker->password,
'screenshots_interval' => 5,
'user_language' => 'en',
'screenshots_state' => ScreenshotsState::REQUIRED,
'computer_time_popup' => 10,
'timezone' => 'UTC',
'role_id' => 2,
'type' => 'employee'
];
}
public function withTokens(int $quantity = 1): self
{
$this->tokensAmount = $quantity;
return $this;
}
public function asAdmin(): self
{
$this->roleId = self::USER_ROLE;
$this->isAdmin = true;
return $this;
}
public function asManager(): self
{
$this->roleId = self::MANAGER_ROLE;
return $this;
}
public function asAuditor(): self
{
$this->roleId = self::AUDITOR_ROLE;
return $this;
}
public function asUser(): self
{
$this->roleId = self::USER_ROLE;
return $this;
}
protected function createTokens(): void
{
$tokens = array_map(fn() => [
'token' => JWTAuth::fromUser($this->user),
'expires_at' => now()->addDay()
], range(0, $this->tokensAmount));
cache(["testing:{$this->user->id}:tokens" => $tokens]);
}
protected function assignRole(): void
{
$this->user->role_id = $this->roleId;
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace Tests\Feature\Auth;
use App\Models\User;
use Cache;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class LoginTest extends TestCase
{
private const URI = 'auth/login';
private const TEST_URI = 'auth/me';
private User $user;
private array $loginData;
private const CAPTCHA_CACHE_KEY = 'AUTH_RECAPTCHA_LIMITER_{ip}_{email}_ATTEMPTS';
private const BAN_CACHE_KEY = 'AUTH_RATE_LIMITER_{ip}';
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::create();
$this->loginData = [
'email' => $this->user->email,
'password' => $this->user->full_name
];
}
public function test_success(): void
{
$response = $this->postJson(self::URI, $this->loginData);
$response->assertOk();
$this->actingAs($response->decodeResponseJson()['access_token'])->get(self::TEST_URI)->assertOk();
}
public function test_wrong_credentials(): void
{
$this->loginData['password'] = 'wrong_password';
$response = $this->postJson(self::URI, $this->loginData);
$response->assertUnauthorized();
}
public function test_disabled_user(): void
{
$this->user->active = false;
$this->user->save();
$response = $this->postJson(self::URI, $this->loginData);
$response->assertForbidden('authorization.user_disabled', false);
}
public function test_soft_deleted_user(): void
{
$this->user->delete();
$response = $this->postJson(self::URI, $this->loginData);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->postJson(self::URI);
$response->assertError(self::HTTP_BAD_REQUEST);
}
public function test_recaptcha(): void
{
config(['recaptcha.enabled' => true]);
config(['recaptcha.failed_attempts' => 1]);
$cacheKey = str_replace(
['{email}', '{ip}'],
[$this->loginData['email'], '127.0.0.1'],
self::CAPTCHA_CACHE_KEY
);
$this->assertFalse(Cache::has($cacheKey));
$this->loginData['password'] = 'wrong_password';
$this->postJson(self::URI, $this->loginData);
$this->assertTrue(Cache::has($cacheKey));
$this->assertEquals(1, Cache::get($cacheKey));
$response = $this->postJson(self::URI, $this->loginData);
$response->assertError(self::HTTP_TOO_MANY_REQUESTS, 'authorization.captcha');
}
public function test_ban(): void
{
config(['recaptcha.enabled' => true]);
config(['recaptcha.rate_limiter_enabled' => true]);
config(['recaptcha.failed_attempts' => 0]);
config(['recaptcha.ban_attempts' => 1]);
$cacheKey = str_replace('{ip}', '127.0.0.1', self::BAN_CACHE_KEY);
$this->assertFalse(Cache::has($cacheKey));
$this->loginData['password'] = 'wrong_password';
$this->postJson(self::URI, $this->loginData);
$this->assertTrue(Cache::has($cacheKey));
$cacheResponse = Cache::get($cacheKey);
$this->assertArrayHasKey('amounts', $cacheResponse);
$this->assertArrayHasKey('time', $cacheResponse);
$this->assertEquals(1, $cacheResponse['amounts']);
$response = $this->postJson(self::URI, $this->loginData);
$response->assertError(self::HTTP_LOCKED, 'authorization.banned');
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Tests\Feature\Auth;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class LogoutFromAllTest extends TestCase
{
private const URI = 'auth/logout-from-all';
private const TEST_URI = 'auth/me';
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::withTokens(4)->create();
}
public function test_logout_from_all(): void
{
$tokens = cache("testing:{$this->user->id}:tokens");
$this->assertNotEmpty($tokens);
foreach ($tokens as $token) {
$this->actingAs($token['token'])->get(self::TEST_URI)->assertOk();
}
$response = $this->actingAs($tokens[0]['token'])->postJson(self::URI);
$response->assertOk();
foreach ($tokens as $token) {
$this->actingAs($token['token'])->get(self::TEST_URI)->assertUnauthorized();
}
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Tests\Feature\Auth;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class LogoutTest extends TestCase
{
private const URI = 'auth/logout';
private const TEST_URI = 'auth/me';
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::withTokens()->create();
}
public function test_logout(): void
{
$token = cache("testing:{$this->user->id}:tokens");
$this->assertNotEmpty($token);
$this->assertNotEmpty($token[0]);
$this->assertNotEmpty($token[0]['token']);
$response = $this->actingAs($token[0]['token'])->postJson(self::URI);
$response->assertOk();
$response = $this->actingAs($token[0]['token'])->get(self::TEST_URI);
$response->assertUnauthorized();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Tests\Feature\Auth;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class MeTest extends TestCase
{
private const URI = 'auth/me';
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::withTokens()->create();
}
public function test_me(): void
{
$response = $this->actingAs($this->user)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['user' => $this->user->toArray()]);
}
public function test_without_auth(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,104 @@
<?php
namespace Tests\Feature\Auth\PasswordReset;
use App\Models\User;
use DB;
use Hash;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ProcessTest extends TestCase
{
private const URI = 'auth/password/reset/process';
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::create();
}
protected function createReset(string $email, string $token, string $createdAt): array
{
DB::table('password_resets')->insert([
'email' => $email,
'token' => Hash::make($token),
'created_at' => $createdAt
]);
return [
'email' => $email,
'token' => $token,
'password' => 'new_password',
'password_confirmation' => 'new_password'
];
}
public function test_process(): void
{
$reset = $this->createReset($this->user->email, 'token', now());
$response = $this->postJson(self::URI, $reset);
$response->assertOk();
$this->user->refresh();
$this->assertTrue(Hash::check($reset['password'], $this->user->password));
$response->assertJsonStructure(['access_token']);
}
public function test_invalid_token(): void
{
$reset = $this->createReset($this->user->email, 'token', now());
$reset['token'] = 'invalid_token';
$response = $this->postJson(self::URI, $reset);
$response->assertUnauthorized();
}
public function test_invalid_email(): void
{
$reset = $this->createReset($this->user->email, 'token', now());
$reset['email'] = 'invalidemail@example.com';
$response = $this->postJson(self::URI, $reset);
$response->assertUnauthorized('authorization.invalid_password_data');
}
public function test_almost_expired(): void
{
$reset = [$this->user->email, 'expired', now()->subMinutes(config('auth.passwords.users.expire') - 1)];
$reset = $this->createReset(...$reset);
$response = $this->postJson(self::URI, $reset);
$response->assertOk();
$this->user->refresh();
$this->assertTrue(Hash::check($reset['password'], $this->user->password));
$response->assertJsonStructure(['access_token']);
}
public function test_expired(): void
{
$reset = [$this->user->email, 'expired', now()->subMinutes(config('auth.passwords.users.expire'))];
$reset = $this->createReset(...$reset);
$response = $this->postJson(self::URI, $reset);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->postJson(self::URI);
$response->assertError(self::HTTP_BAD_REQUEST);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Tests\Feature\Auth\PasswordReset;
use App\Mail\ResetPassword;
use App\Models\User;
use Notification;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class RequestTest extends TestCase
{
private const URI = 'auth/password/reset/request';
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::create();
}
public function test_request(): void
{
Notification::fake();
Notification::assertNothingSent();
$response = $this->postJson(self::URI, ['email' => $this->user->email]);
$response->assertOk();
Notification::assertSentTo($this->user, ResetPassword::class);
}
public function test_wrong_email(): void
{
Notification::fake();
Notification::assertNothingSent();
$response = $this->postJson(self::URI, ['email' => 'wronemail@example.com']);
$response->assertNotFound('authorization.user_not_found');
Notification::assertNothingSent();
}
public function test_without_params(): void
{
Notification::fake();
Notification::assertNothingSent();
$response = $this->postJson(self::URI);
$response->assertError(self::HTTP_BAD_REQUEST);
Notification::assertNothingSent();
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace Tests\Feature\Auth\PasswordReset;
use App\Models\User;
use DB;
use Hash;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ValidateTest extends TestCase
{
private const URI = 'auth/password/reset/validate';
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::create();
}
protected function createReset(string $email, string $token, string $createdAt): array
{
DB::table('password_resets')->insert([
'email' => $email,
'token' => Hash::make($token),
'created_at' => $createdAt
]);
return ['email' => $email, 'token' => $token];
}
public function test_validate(): void
{
$reset = $this->createReset($this->user->email, 'token', now());
$response = $this->postJson(self::URI, $reset);
$response->assertOk();
}
public function test_invalid_token(): void
{
$reset = $this->createReset($this->user->email, 'token', now());
$reset['token'] = 'invalid_token';
$response = $this->postJson(self::URI, $reset);
$response->assertUnauthorized('authorization.invalid_password_data');
}
public function test_invalid_email(): void
{
$reset = $this->createReset($this->user->email, 'token', now());
$reset['email'] = 'invalidemail@example.com';
$response = $this->postJson(self::URI, $reset);
$response->assertUnauthorized('authorization.invalid_password_data');
}
public function test_almost_expired(): void
{
$reset = [$this->user->email, 'expired', now()->subMinutes(config('auth.passwords.users.expire') - 1)];
$reset = $this->createReset(...$reset);
$response = $this->postJson(self::URI, $reset);
$response->assertOk();
}
public function test_expired(): void
{
$reset = [$this->user->email, 'expired', now()->subMinutes(config('auth.passwords.users.expire'))];
$reset = $this->createReset(...$reset);
$response = $this->postJson(self::URI, $reset);
$response->assertUnauthorized('authorization.invalid_password_data');
}
public function test_without_params(): void
{
$response = $this->postJson(self::URI);
$response->assertError(self::HTTP_BAD_REQUEST);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Tests\Feature\Auth;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class RefreshTest extends TestCase
{
private const URI = 'auth/refresh';
private const TEST_URI = 'auth/me';
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::withTokens()->create();
}
public function test_refresh(): void
{
$token = cache("testing:{$this->user->id}:tokens");
$this->assertNotEmpty($token);
$this->assertNotEmpty($token[0]);
$this->assertNotEmpty($token[0]['token']);
$this->actingAs($token[0]['token'])->get(self::TEST_URI)->assertOk();
$response = $this->actingAs($token[0]['token'])->postJson(self::URI);
$response->assertOk();
$this->actingAs($token[0]['token'])->get(self::TEST_URI)->assertUnauthorized();
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Tests\Feature\CompanySettings;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class IndexTest extends TestCase
{
private const URI = 'company-settings';
private User $admin;
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->withTokens()->asAdmin()->create();
$this->user = UserFactory::refresh()->withTokens()->asUser()->create();
}
public function test_index_as_admin(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
}
public function test_index_as_user(): void
{
$response = $this->actingAs($this->user)->getJson(self::URI);
$response->assertOk();
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Tests\Feature\CompanySettings;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class UpdateTest extends TestCase
{
use WithFaker;
private const URI = 'company-settings';
private User $admin;
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->withTokens()->asAdmin()->create();
$this->user = UserFactory::refresh()->withTokens()->asUser()->create();
}
public function test_index_as_admin(): void
{
$response = $this->actingAs($this->admin)->patchJson(self::URI);
$response->assertOk();
}
public function test_index_wrong_params(): void
{
$response = $this->actingAs($this->admin)->patchJson(self::URI, [
'timezone' => $this->faker->text,
]);
$response->assertValidationError();
}
public function test_index_as_user(): void
{
$response = $this->actingAs($this->user)->patchJson(self::URI);
$response->assertForbidden();
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Tests\Feature\Invitations;
use App\Models\Invitation;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CountTest extends TestCase
{
private const URI = 'invitations/count';
private User $admin;
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->user = UserFactory::withTokens()->asUser()->create();
$this->admin = UserFactory::withTokens()->asAdmin()->create();
}
public function test_count_as_admin(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['total' => Invitation::count()]);
}
public function test_count_as_user(): void
{
$response = $this->actingAs($this->user)->getJson(self::URI);
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,94 @@
<?php
namespace Tests\Feature\Invitations;
use App\Models\User;
use App\Models\invitation;
use Tests\Facades\UserFactory;
use Tests\Facades\InvitationFactory;
use Tests\TestCase;
class CreateTest extends TestCase
{
private const URI = 'invitations/create';
private User $admin;
private User $manager;
private User $auditor;
private User $user;
private array $invitationRequestData;
private array $invitationModelData;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->invitationRequestData = InvitationFactory::createRequestData();
$this->invitationModelData = InvitationFactory::createRandomModelData();
}
public function test_create_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->invitationRequestData);
$response->assertOk();
$this->assertDatabaseHas((new Invitation)->getTable(), $this->invitationRequestData['users'][0]);
foreach ($response->json('res') as $invitation) {
$this->assertDatabaseHas((new Invitation)->getTable(), $invitation);
}
}
public function test_create_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->invitationRequestData);
$response->assertForbidden();
}
public function test_create_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->invitationRequestData);
$response->assertForbidden();
}
public function test_create_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->invitationRequestData);
$response->assertForbidden();
}
public function test_create_already_exists(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->invitationRequestData);
$this->assertDatabaseHas((new Invitation)->getTable(), $response->decodeResponseJson()['res'][0]);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->invitationRequestData);
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace Tests\Feature\Invitations;
use App\Models\invitation;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'invitations/list';
private User $admin;
private User $manager;
private User $auditor;
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
}
public function test_list_as_admin(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$invitations = invitation::all()->toArray();
$response->assertJson($invitations);
}
public function test_list_as_manager(): void
{
$response = $this->actingAs($this->manager)->getJson(self::URI);
$response->assertForbidden();
}
public function test_list_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->getJson(self::URI);
$response->assertForbidden();
}
public function test_list_as_user(): void
{
$response = $this->actingAs($this->user)->getJson(self::URI);
$response->assertForbidden();
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Tests\Feature\Invitations;
use App\Models\User;
use App\Models\invitation;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Facades\UserFactory;
use Tests\Facades\InvitationFactory;
use Tests\TestCase;
class RemoveTest extends TestCase
{
use WithFaker;
private const URI = 'invitations/remove';
private User $admin;
private User $manager;
private User $auditor;
private User $user;
private invitation $invitation;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->invitation = InvitationFactory::create();
}
public function test_remove_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->invitation->only('id'));
$response->assertOk();
$this->assertDeleted((new Invitation)->getTable(), $this->invitation->only('id'));
}
public function test_remove_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->invitation->only('id'));
$response->assertForbidden();
}
public function test_remove_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->invitation->only('id'));
$response->assertForbidden();
}
public function test_not_existing(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, ['id' => $this->faker->randomNumber()]);
$response->assertValidationError();
}
public function test_remove_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->invitation->only('id'));
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace Tests\Feature\Invitations;
use App\Models\User;
use App\Models\Invitation;
use Tests\Facades\UserFactory;
use Tests\Facades\InvitationFactory;
use Tests\TestCase;
class ResendTest extends TestCase
{
private const URI = 'invitations/resend';
private User $admin;
private User $manager;
private User $auditor;
private User $user;
private Invitation $invitation;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->invitation = InvitationFactory::create();
}
public function test_resend_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, ['id' => $this->invitation->id]);
$response->assertOk();
$response->assertNotEquals(
$response->decodeResponseJson()['res']['expires_at'],
$this->invitation->expires_at->toISOString()
);
}
public function test_resend_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, ['id' => $this->invitation->id]);
$response->assertForbidden();
}
public function test_resend_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, ['id' => $this->invitation->id]);
$response->assertForbidden();
}
public function test_resend_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, ['id' => $this->invitation->id]);
$response->assertForbidden();
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Tests\Feature\Invitations;
use App\Models\User;
use App\Models\Invitation;
use Tests\Facades\InvitationFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ShowTest extends TestCase
{
private const URI = 'invitations/show';
private User $admin;
private User $manager;
private User $auditor;
private User $user;
private Invitation $invitation;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->invitation = InvitationFactory::create();
}
public function test_show_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->invitation->only('id'));
$response->assertOk();
$response->assertJson($this->invitation->toArray());
}
public function test_show_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->invitation->only('id'));
$response->assertForbidden();
}
public function test_show_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->invitation->only('id'));
$response->assertForbidden();
}
public function test_show_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->invitation->only('id'));
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,143 @@
<?php
namespace Tests\Feature\ProjectMembers;
use App\Models\Project;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Facades\UserFactory;
use Tests\Facades\ProjectFactory;
use Tests\TestCase;
class BulkEditTest extends TestCase
{
use WithFaker;
private const URI = 'project-members/bulk-edit';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Project $project */
private Project $project;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->project = ProjectFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->project->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->project->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->project->id, ['role_id' => 2]);
}
public function test_bulk_edit_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->generateRequest());
$response->assertOk();
}
public function test_bulk_edit_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->generateRequest());
$response->assertOk();
}
public function test_bulk_edit_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->generateRequest());
$response->assertForbidden();
}
public function test_bulk_edit_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->generateRequest());
$response->assertForbidden();
}
public function test_bulk_edit_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->generateRequest());
$response->assertOk();
}
public function test_bulk_edit_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->generateRequest());
$response->assertForbidden();
}
public function test_bulk_edit_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->generateRequest());
$response->assertForbidden();
}
public function test_not_existing_project(): void
{
$this->project->id = $this->faker->randomNumber();
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->generateRequest());
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
private function generateRequest(): array
{
return [
'project_id' => $this->project->id,
'user_roles' => [
[
'user_id' => UserFactory::refresh()->asUser()->create()->id,
'role_id' => $this->faker->numberBetween(1, 3),
]
],
];
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace Tests\Feature\ProjectMembers;
use App\Models\Project;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ShowTest extends TestCase
{
use WithFaker;
private const URI = 'project-members/show';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Project $project */
private Project $project;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->project = ProjectFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->project->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->project->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->project->id, ['role_id' => 2]);
}
public function test_show_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, ['project_id' => $this->project->id]);
$response->assertOk();
}
public function test_show_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, ['project_id' => $this->project->id]);
$response->assertOk();
}
public function test_show_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, ['project_id' => $this->project->id]);
$response->assertForbidden();
}
public function test_show_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, ['project_id' => $this->project->id]);
$response->assertForbidden();
}
public function test_show_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->postJson(self::URI, ['project_id' => $this->project->id]);
$response->assertOk();
}
public function test_show_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, ['project_id' => $this->project->id]);
$response->assertForbidden();
}
public function test_show_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->postJson(self::URI, ['project_id' => $this->project->id]);
$response->assertForbidden();
}
public function test_not_existing_project(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, ['project_id' => $this->faker->randomNumber()]);
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Tests\Feature\ProjectReport;
use App\Models\TimeInterval;
use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\ScreenshotFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
use Tests\TestResponse;
class ListTest extends TestCase
{
private const URI = 'project-report/list';
private const INTERVALS_AMOUNT = 10;
private User $admin;
private array $pids;
private array $uids;
private Collection $intervals;
private int $duration = 0;
private array $requestData;
private function collectResponseProjects(TestResponse $response): Collection
{
return collect($response->json('projects'));
}
private function collectResponseUsers(TestResponse $response): Collection
{
return $this->collectResponseProjects($response)->pluck('users')->collapse();
}
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->intervals = IntervalFactory::withRandomRelations()->createMany(self::INTERVALS_AMOUNT);
$this->intervals->each(function (TimeInterval $interval) {
ScreenshotFactory::fake()->forInterval($interval)->create();
$this->uids[] = $interval->user_id;
$this->pids[] = $interval->task->project->id;
$this->duration += Carbon::parse($interval->end_at)->diffInSeconds($interval->start_at);
});
$this->requestData = [
'start_at' => $this->intervals->min('start_at'),
'end_at' => $this->intervals->max('end_at')->addMinute(),
'uids' => $this->uids,
'pids' => $this->pids
];
}
public function test_list(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->requestData);
$response->assertOk();
$users = $this->collectResponseUsers($response);
$this->assertEquals($this->duration, $users->sum('tasks_time'));
$this->assertEquals(count($this->uids), $users->count());
//TODO change later
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Tests\Feature\ProjectReport;
use App\Models\Task;
use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class TaskTest extends TestCase
{
private const URI = 'project-report/list/tasks';
private User $admin;
private Collection $intervals;
private int $duration = 0;
private array $requestData;
private Task $task;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->task = TaskFactory::forUser($this->admin)->create();
$this->intervals = collect([
IntervalFactory::forTask($this->task)->create(),
IntervalFactory::forTask($this->task)->create(),
IntervalFactory::forTask($this->task)->create(),
]);
$this->requestData = [
'start_at' => $this->intervals->min('start_at'),
'end_at' => $this->intervals->max('end_at')->addMinute(),
'uid' => $this->intervals->first()->user->id
];
$this->duration = $this->intervals->sum(
fn ($interval) => Carbon::parse($interval->end_at)->diffInSeconds($interval->start_at)
);
}
public function test_list_task(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI . '/' . $this->task->id, $this->requestData);
$response->assertOk();
$response->assertJsonFragment(['duration' => (string)$this->duration]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI . '/' . $this->task->id);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI . '/' . $this->task->id);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Tests\Feature\Projects;
use App\Models\Project;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CountTest extends TestCase
{
private const URI = 'projects/count';
private const PROJECTS_AMOUNT = 10;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
ProjectFactory::createMany(self::PROJECTS_AMOUNT);
}
public function test_count(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['total' => Project::count()]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Tests\Feature\Projects;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CreateTest extends TestCase
{
private const URI = 'projects/create';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
private array $projectData;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectData = ProjectFactory::createRandomModelData();
}
public function test_create_as_admin(): void
{
$this->assertDatabaseMissing('projects', $this->projectData);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->projectData);
$response->assertOk();
$response->assertJson(['res' => $this->projectData]);
$this->assertDatabaseHas('projects', $this->projectData);
}
public function test_create_as_manager(): void
{
$this->assertDatabaseMissing('projects', $this->projectData);
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->projectData);
$response->assertOk();
$response->assertJson(['res' => $this->projectData]);
$this->assertDatabaseHas('projects', $this->projectData);
}
public function test_create_as_auditor(): void
{
$this->assertDatabaseMissing('projects', $this->projectData);
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->projectData);
$response->assertForbidden();
}
public function test_create_as_user(): void
{
$this->assertDatabaseMissing('projects', $this->projectData);
$response = $this->actingAs($this->user)->postJson(self::URI, $this->projectData);
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,156 @@
<?php
namespace Tests\Feature\Projects;
use App\Models\Project;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class EditTest extends TestCase
{
use WithFaker;
private const URI = 'projects/edit';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Project $project */
private Project $project;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->project = ProjectFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->project->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->project->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->project->id, ['role_id' => 2]);
}
public function test_edit_as_admin(): void
{
$this->project->name = $this->faker->text;
$this->project->description = $this->faker->text;
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->project->toArray());
$response->assertOk();
$response->assertJson(['res' => $this->project->toArray()]);
$this->assertDatabaseHas('projects', $this->project->toArray());
}
public function test_edit_as_manager(): void
{
$this->project->name = $this->faker->text;
$this->project->description = $this->faker->text;
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->project->toArray());
$response->assertOk();
$response->assertJson(['res' => $this->project->toArray()]);
$this->assertDatabaseHas('projects', $this->project->toArray());
}
public function test_edit_as_auditor(): void
{
$this->project->name = $this->faker->text;
$this->project->description = $this->faker->text;
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->project->toArray());
$response->assertForbidden();
}
public function test_edit_as_detached_user(): void
{
$this->project->name = $this->faker->text;
$this->project->description = $this->faker->text;
$response = $this->actingAs($this->user)->postJson(self::URI, $this->project->toArray());
$response->assertForbidden();
}
public function test_edit_as_project_manager(): void
{
$this->project->name = $this->faker->text;
$this->project->description = $this->faker->text;
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->project->toArray());
$response->assertOk();
$response->assertJson(['res' => $this->project->toArray()]);
$this->assertDatabaseHas('projects', $this->project->toArray());
}
public function test_edit_as_project_auditor(): void
{
$this->project->name = $this->faker->text;
$this->project->description = $this->faker->text;
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->project->toArray());
$response->assertForbidden();
}
public function test_edit_as_project_user(): void
{
$this->project->name = $this->faker->text;
$this->project->description = $this->faker->text;
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->project->toArray());
$response->assertForbidden();
}
public function test_not_existing_project(): void
{
$this->project->id = $this->faker->randomNumber();
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->project->toArray());
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace Tests\Feature\Projects;
use App\Models\Project;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'projects/list';
private const PROJECTS_AMOUNT = 10;
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
ProjectFactory::createMany(self::PROJECTS_AMOUNT);
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach(Project::first()->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach(Project::first()->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach(Project::first()->id, ['role_id' => 2]);
}
public function test_list_as_admin(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(Project::all()->toArray());
}
public function test_list_as_manager(): void
{
$response = $this->actingAs($this->manager)->getJson(self::URI);
$response->assertOk();
$response->assertJson(Project::all()->toArray());
}
public function test_list_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->getJson(self::URI);
$response->assertOk();
$response->assertJson(Project::all()->toArray());
}
public function test_list_as_user(): void
{
$response = $this->actingAs($this->user)->getJson(self::URI);
$response->assertOk();
$response->assertExactJson([]);
}
public function test_list_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->getJson(self::URI);
$response->assertOk();
$response->assertExactJson([Project::first()->toArray()]);
}
public function test_list_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->getJson(self::URI);
$response->assertOk();
$response->assertExactJson([Project::first()->toArray()]);
}
public function test_list_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->getJson(self::URI);
$response->assertOk();
$response->assertExactJson([Project::first()->toArray()]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace Tests\Feature\Projects;
use App\Models\Project;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class RemoveTest extends TestCase
{
private const URI = 'projects/remove';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Project $project */
private Project $project;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->project = ProjectFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->project->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->project->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->project->id, ['role_id' => 2]);
}
public function test_remove_as_admin(): void
{
$this->assertDatabaseHas('projects', $this->project->toArray());
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$this->assertSoftDeleted('projects', $this->project->only('id'));
}
public function test_remove_as_manager(): void
{
$this->assertDatabaseHas('projects', $this->project->toArray());
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$this->assertSoftDeleted('projects', $this->project->only('id'));
}
public function test_remove_as_auditor(): void
{
$this->assertDatabaseHas('projects', $this->project->toArray());
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->project->only('id'));
$response->assertForbidden();
}
public function test_remove_as_user(): void
{
$this->assertDatabaseHas('projects', $this->project->toArray());
$response = $this->actingAs($this->user)->postJson(self::URI, $this->project->only('id'));
$response->assertForbidden();
}
public function test_remove_as_project_manager(): void
{
$this->assertDatabaseHas('projects', $this->project->toArray());
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$this->assertSoftDeleted('projects', $this->project->only('id'));
}
public function test_remove_as_project_auditor(): void
{
$this->assertDatabaseHas('projects', $this->project->toArray());
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->project->only('id'));
$response->assertForbidden();
}
public function test_remove_as_project_user(): void
{
$this->assertDatabaseHas('projects', $this->project->toArray());
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->project->only('id'));
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_not_existing_project(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,123 @@
<?php
namespace Tests\Feature\Projects;
use App\Models\Project;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ShowTest extends TestCase
{
private const URI = 'projects/show';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Project $project */
private Project $project;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->project = ProjectFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->project->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->project->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->project->id, ['role_id' => 2]);
}
public function test_show_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$response->assertJson($this->project->toArray());
}
public function test_show_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$response->assertJson($this->project->toArray());
}
public function test_show_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$response->assertJson($this->project->toArray());
}
public function test_show_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->project->only('id'));
$response->assertForbidden();
}
public function test_show_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$response->assertJson($this->project->toArray());
}
public function test_show_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$response->assertJson($this->project->toArray());
}
public function test_show_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->project->only('id'));
$response->assertOk();
$response->assertJson($this->project->toArray());
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Tests\Feature\Roles;
use App\Models\Role;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CountTest extends TestCase
{
private const URI = 'roles/count';
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::withTokens()->asAdmin()->create();
}
public function test_count(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['total' => Role::count()]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Tests\Feature\Roles;
use App\Models\Role;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'roles/list';
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::withTokens()->asAdmin()->create();
}
public function test_list(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(Role::all()->toArray());
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Tests\Feature\Screenshots;
use App\Models\Screenshot;
use App\Models\User;
use Tests\Facades\ScreenshotFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CountTest extends TestCase
{
private const URI = 'screenshots/count';
private const SCREENSHOTS_AMOUNT = 10;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
ScreenshotFactory::fake()->createMany(self::SCREENSHOTS_AMOUNT);
}
public function test_count(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['total' => Screenshot::count()]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Tests\Feature\Screenshots;
use App\Models\TimeInterval;
use App\Models\User;
use Faker\Factory;
use Illuminate\Http\Testing\File;
use Illuminate\Http\UploadedFile;
use Storage;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CreateTest extends TestCase
{
private const URI = '/screenshots/create';
private User $admin;
private File $screenshotFile;
private TimeInterval $interval;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
Storage::fake();
$screenshotName = Factory::create()->firstName . '.jpg';
$this->screenshotFile = UploadedFile::fake()->image($screenshotName);
$this->interval = IntervalFactory::create();
}
public function test_create(): void
{
$requestData = ['time_interval_id' => $this->interval->id, 'screenshot' => $this->screenshotFile];
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertOk();
$this->assertDatabaseHas('screenshots', $response->json('screenshot'));
Storage::assertExists('uploads/screenshots/' . basename($response->json('screenshot.path')));
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Tests\Feature\Screenshots;
use App\Models\Screenshot;
use App\Models\User;
use Tests\Facades\ScreenshotFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'screenshots/list';
private const SCREENSHOTS_AMOUNT = 10;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
ScreenshotFactory::fake()->withRandomRelations()->createMany(self::SCREENSHOTS_AMOUNT);
}
public function test_list(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertOk();
$response->assertJson(Screenshot::all()->toArray());
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Tests\Feature\Screenshots;
use App\Models\Screenshot;
use App\Models\User;
use Tests\Facades\ScreenshotFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class RemoveTest extends TestCase
{
private const URI = '/screenshots/remove';
private User $admin;
private Screenshot $screenshot;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->screenshot = ScreenshotFactory::fake()->create();
}
public function test_remove(): void
{
$this->assertDatabaseHas('screenshots', $this->screenshot->toArray());
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->screenshot->only('id'));
$response->assertOk();
$this->assertSoftDeleted('screenshots', $this->screenshot->only('id'));
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Tests\Feature\Screenshots;
use App\Models\Screenshot;
use App\Models\User;
use Tests\Facades\ScreenshotFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ShowTest extends TestCase
{
private const URI = '/screenshots/show';
private User $admin;
private Screenshot $screenshot;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->screenshot = ScreenshotFactory::fake()->create();
}
public function test_show(): void
{
$this->assertDatabaseHas('screenshots', $this->screenshot->toArray());
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->screenshot->only('id'));
$response->assertOk();
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Tests\Feature\Status;
use Tests\TestCase;
class IndexTest extends TestCase
{
private const URI = 'status';
public function test_index(): void
{
$response = $this->getJson(self::URI);
$response->assertOk();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Tests\Feature\Tasks;
use App\Models\Task;
use App\Models\User;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CountTest extends TestCase
{
private const URI = 'tasks/count';
private const TASKS_AMOUNT = 10;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
TaskFactory::createMany(self::TASKS_AMOUNT);
}
public function test_count(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['total' => Task::count()]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,235 @@
<?php
namespace Tests\Feature\Tasks;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CreateTest extends TestCase
{
private const URI = 'tasks/create';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var array */
private $taskData;
/** @var array */
private $taskRequest;
/** @var array */
private $taskRequestWithMultipleUsers;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->taskData = array_merge(TaskFactory::createRandomModelData(), [
'project_id' => ProjectFactory::create()->id,
]);
$this->taskRequest = array_merge($this->taskData, [
'users' => [UserFactory::create()->id],
]);
$this->taskRequestWithMultipleUsers = array_merge($this->taskData, [
'users' => [
UserFactory::create()->id,
UserFactory::create()->id,
UserFactory::create()->id,
],
]);
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->taskData['project_id'], ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->taskData['project_id'], ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->taskData['project_id'], ['role_id' => 2]);
}
public function test_create_without_user(): void
{
$this->taskRequest['users'] = [];
$this->assertDatabaseMissing('tasks', $this->taskData);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->taskRequest);
$response->assertSuccess();
$response->assertJson(['res' => $this->taskData]);
$this->assertDatabaseHas('tasks', $this->taskData);
}
public function test_create_as_admin(): void
{
$this->assertDatabaseMissing('tasks', $this->taskData);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->taskRequest);
$response->assertOk();
$response->assertJson(['res' => $this->taskData]);
$this->assertDatabaseHas('tasks', $this->taskData);
foreach ($this->taskRequest['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_create_with_multiple_users_as_admin(): void
{
$this->assertDatabaseMissing('tasks', $this->taskData);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->taskRequestWithMultipleUsers);
$response->assertOk();
$response->assertJson(['res' => $this->taskData]);
$this->assertDatabaseHas('tasks', $this->taskData);
foreach ($this->taskRequestWithMultipleUsers['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_create_as_manager(): void
{
$this->assertDatabaseMissing('tasks', $this->taskData);
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->taskRequest);
$response->assertOk();
$response->assertJson(['res' => $this->taskData]);
$this->assertDatabaseHas('tasks', $this->taskData);
foreach ($this->taskRequest['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_create_with_multiple_users_as_manager(): void
{
$this->assertDatabaseMissing('tasks', $this->taskData);
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->taskRequestWithMultipleUsers);
$response->assertOk();
$response->assertJson(['res' => $this->taskData]);
$this->assertDatabaseHas('tasks', $this->taskData);
foreach ($this->taskRequestWithMultipleUsers['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_create_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_create_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_create_as_project_manager(): void
{
$this->assertDatabaseMissing('tasks', $this->taskData);
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->taskRequest);
$response->assertOk();
$response->assertJson(['res' => $this->taskData]);
$this->assertDatabaseHas('tasks', $this->taskData);
foreach ($this->taskRequest['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_create_with_multiple_users_as_project_manager(): void
{
$this->assertDatabaseMissing('tasks', $this->taskData);
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->taskRequestWithMultipleUsers);
$response->assertOk();
$response->assertJson(['res' => $this->taskData]);
$this->assertDatabaseHas('tasks', $this->taskData);
foreach ($this->taskRequestWithMultipleUsers['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_create_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_create_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,251 @@
<?php
namespace Tests\Feature\Tasks;
use App\Models\Task;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class EditTest extends TestCase
{
use WithFaker;
private const URI = 'tasks/edit';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Task $task */
private Task $task;
/** @var array $taskRequest */
private array $taskRequest;
/** @var array */
private $taskRequestWithMultipleUsers;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->task = TaskFactory::create();
$this->taskRequest = array_merge($this->task->toArray(), [
'users' => [UserFactory::create()->id],
]);
$this->taskRequestWithMultipleUsers = array_merge($this->task->toArray(), [
'users' => [
UserFactory::create()->id,
UserFactory::create()->id,
UserFactory::create()->id,
],
]);
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->task->project_id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->task->project_id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->task->project_id, ['role_id' => 2]);
}
public function test_edit_without_user(): void
{
$this->task->users = $this->taskRequest['users'] = [];
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->taskRequest);
$response->assertSuccess();
$response->assertJson(['res' => $this->task->toArray()]);
$this->assertDatabaseHas('tasks', ['id' => $this->task->id]);
}
public function test_edit_as_admin(): void
{
$this->task->description = $this->taskRequest['description'] = $this->faker->text;
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->taskRequest);
$response->assertOk();
$response->assertJson(['res' => $this->task->toArray()]);
$this->assertDatabaseHas('tasks', ['id' => $this->task->id, 'description' => $this->taskRequest['description']]);
foreach ($this->taskRequest['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_edit_with_multiple_users_as_admin(): void
{
$this->task->description = $this->taskRequestWithMultipleUsers['description'] = $this->faker->text;
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->taskRequestWithMultipleUsers);
$response->assertOk();
$response->assertJson(['res' => $this->task->toArray()]);
$this->assertDatabaseHas('tasks', ['id' => $this->task->id, 'description' => $this->taskRequestWithMultipleUsers['description']]);
foreach ($this->taskRequestWithMultipleUsers['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_edit_as_manager(): void
{
$this->task->description = $this->taskRequest['description'] = $this->faker->text;
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->taskRequest);
$response->assertOk();
$response->assertJson(['res' => $this->task->toArray()]);
$this->assertDatabaseHas('tasks', ['id' => $this->task->id, 'description' => $this->taskRequest['description']]);
foreach ($this->taskRequest['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_edit_with_multiple_users_as_manager(): void
{
$this->task->description = $this->taskRequestWithMultipleUsers['description'] = $this->faker->text;
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->taskRequestWithMultipleUsers);
$response->assertOk();
$response->assertJson(['res' => $this->task->toArray()]);
$this->assertDatabaseHas('tasks', ['id' => $this->task->id, 'description' => $this->taskRequestWithMultipleUsers['description']]);
foreach ($this->taskRequestWithMultipleUsers['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_edit_as_auditor(): void
{
$this->task->description = $this->taskRequest['description'] = $this->faker->text;
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_edit_as_user(): void
{
$this->task->description = $this->taskRequest['description'] = $this->faker->text;
$response = $this->actingAs($this->user)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_edit_as_project_manager(): void
{
$this->task->description = $this->taskRequest['description'] = $this->faker->text;
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->taskRequest);
$response->assertOk();
$response->assertJson(['res' => $this->task->toArray()]);
$this->assertDatabaseHas('tasks', ['id' => $this->task->id, 'description' => $this->taskRequest['description']]);
foreach ($this->taskRequest['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_edit_with_multiple_users_as_project_manager(): void
{
$this->task->description = $this->taskRequestWithMultipleUsers['description'] = $this->faker->text;
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->taskRequestWithMultipleUsers);
$response->assertOk();
$response->assertJson(['res' => $this->task->toArray()]);
$this->assertDatabaseHas('tasks', ['id' => $this->task->id, 'description' => $this->taskRequestWithMultipleUsers['description']]);
foreach ($this->taskRequestWithMultipleUsers['users'] as $user) {
$this->assertDatabaseHas('tasks_users', [
'task_id' => $response->json()['res']['id'],
'user_id' => $user,
]);
}
}
public function test_edit_as_project_auditor(): void
{
$this->task->description = $this->taskRequest['description'] = $this->faker->text;
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_edit_as_project_project_user(): void
{
$this->task->description = $this->taskRequest['description'] = $this->faker->text;
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->taskRequest);
$response->assertForbidden();
}
public function test_edit_not_existing(): void
{
$this->taskRequest['id'] = Task::withoutGlobalScopes()->count() + 20;
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->taskRequest);
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,192 @@
<?php
namespace Tests\Feature\Tasks;
use App\Models\Task;
use App\Models\User;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'tasks/list';
private const TASKS_AMOUNT = 10;
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var User $assignedUser */
private User $assignedUser;
/** @var Task $assignedTask */
private Task $assignedTask;
/** @var User $assignedProjectUser */
private User $assignedProjectUser;
/** @var Task $assignedProjectTask */
private Task $assignedProjectTask;
/** @var Task $task */
private Task $task;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->task = TaskFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->task->project_id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->task->project_id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->task->project_id, ['role_id' => 2]);
$this->assignedUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->assignedTask = TaskFactory::refresh()->forUser($this->assignedUser)->create();
$this->assignedProjectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->assignedProjectTask = TaskFactory::refresh()->forUser($this->assignedProjectUser)->create();
$this->assignedProjectUser->projects()->attach($this->assignedProjectTask->project_id, ['role_id' => 2]);
}
public function test_list_as_admin(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$tasks = Task::query()
->leftJoin('statuses as s', 'tasks.status_id', '=', 's.id')
->select('tasks.*')
->orderBy('s.active', 'desc')
->orderBy('tasks.created_at', 'desc')
->get();
$response->assertJson($tasks->toArray());
}
public function test_list_as_manager(): void
{
$response = $this->actingAs($this->manager)->getJson(self::URI);
$response->assertOk();
$tasks = Task::query()
->leftJoin('statuses as s', 'tasks.status_id', '=', 's.id')
->select('tasks.*')
->orderBy('s.active', 'desc')
->orderBy('tasks.created_at', 'desc')
->get();
$response->assertJson($tasks->toArray());
}
public function test_list_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->getJson(self::URI);
$response->assertOk();
$tasks = Task::query()
->leftJoin('statuses as s', 'tasks.status_id', '=', 's.id')
->select('tasks.*')
->orderBy('s.active', 'desc')
->orderBy('tasks.created_at', 'desc')
->get();
$response->assertJson($tasks->toArray());
}
public function test_list_as_user(): void
{
$response = $this->actingAs($this->user)->getJson(self::URI);
$response->assertOk();
$response->assertExactJson([]);
}
public function test_list_as_assigned_user(): void
{
$response = $this->actingAs($this->assignedUser)->getJson(self::URI);
$response->assertOk();
$response->assertExactJson(
Task::query()
->where('id', '=', $this->assignedTask->id)
->get()->toArray()
);
}
public function test_list_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->getJson(self::URI);
$task = Task::where('project_id', $this->task->project_id)->get()->toArray();
$response->assertOk();
$response->assertExactJson($task);
}
public function test_list_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->getJson(self::URI);
$task = Task::where('project_id', $this->task->project_id)->get()->toArray();
$response->assertOk();
$response->assertExactJson($task);
}
public function test_list_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->getJson(self::URI);
$task = Task::where('project_id', $this->task->project_id)->get()->toArray();
$response->assertOk();
$response->assertExactJson($task);
}
public function test_list_as_assigned_project_user(): void
{
$response = $this
->actingAs($this->assignedProjectUser)
->postJson(self::URI, $this->assignedProjectTask->only('id'));
$task = Task::where('project_id', $this->assignedProjectTask->project_id)
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($task);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,132 @@
<?php
namespace Tests\Feature\Tasks;
use App\Models\Task;
use App\Models\User;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class RemoveTest extends TestCase
{
private const URI = 'tasks/remove';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Task $task */
private Task $task;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->task = TaskFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->task->project_id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->task->project_id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->task->project_id, ['role_id' => 2]);
}
public function test_remove_as_admin(): void
{
$this->assertDatabaseHas('tasks', ['id' => $this->task->id]);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$this->assertSoftDeleted('tasks', $this->task->only('id'));
}
public function test_remove_as_manager(): void
{
$this->assertDatabaseHas('tasks', ['id' => $this->task->id]);
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$this->assertSoftDeleted('tasks', $this->task->only('id'));
}
public function test_remove_as_auditor(): void
{
$this->assertDatabaseHas('tasks', ['id' => $this->task->id]);
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->task->only('id'));
$response->assertForbidden();
}
public function test_remove_as_project_manager(): void
{
$this->assertDatabaseHas('tasks', ['id' => $this->task->id]);
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$this->assertSoftDeleted('tasks', $this->task->only('id'));
}
public function test_remove_as_project_auditor(): void
{
$this->assertDatabaseHas('tasks', ['id' => $this->task->id]);
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->task->only('id'));
$response->assertForbidden();
}
public function test_remove_as_project_user(): void
{
$this->assertDatabaseHas('tasks', ['id' => $this->task->id]);
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->task->only('id'));
$response->assertForbidden();
}
public function test_remove_not_existing(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,160 @@
<?php
namespace Tests\Feature\Tasks;
use App\Models\Task;
use App\Models\User;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ShowTest extends TestCase
{
private const URI = 'tasks/show';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var User $assignedUser */
private User $assignedUser;
/** @var Task $assignedTask */
private Task $assignedTask;
/** @var User $assignedProjectUser */
private User $assignedProjectUser;
/** @var Task $assignedProjectTask */
private Task $assignedProjectTask;
/** @var Task $task */
private Task $task;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->task = TaskFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->task->project_id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->task->project_id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->task->project_id, ['role_id' => 2]);
$this->assignedUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->assignedTask = TaskFactory::refresh()->forUser($this->assignedUser)->create();
$this->assignedProjectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->assignedProjectTask = TaskFactory::refresh()->forUser($this->assignedProjectUser)->create();
$this->assignedProjectUser->projects()->attach($this->assignedProjectTask->project_id, ['role_id' => 2]);
}
public function test_show_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$response->assertJson($this->task->toArray());
}
public function test_show_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$response->assertJson($this->task->toArray());
}
public function test_show_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$response->assertJson($this->task->toArray());
}
public function test_show_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->task->only('id'));
$response->assertForbidden();
}
public function test_show_as_assigned_user(): void
{
$response = $this
->actingAs($this->assignedUser)
->postJson(self::URI, $this->assignedTask->only('id'));
$response->assertOk();
$response->assertJson($this->assignedTask->toArray());
}
public function test_show_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$response->assertJson($this->task->toArray());
}
public function test_show_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$response->assertJson($this->task->toArray());
}
public function test_show_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->task->only('id'));
$response->assertOk();
$response->assertJson($this->task->toArray());
}
public function test_show_as_assigned_project_user(): void
{
$response = $this
->actingAs($this->assignedProjectUser)
->postJson(self::URI, $this->assignedProjectTask->only('id'));
$response->assertOk();
$response->assertJson($this->assignedProjectTask->toArray());
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Tests\Feature\Time;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class TasksTest extends TestCase
{
private const URI = 'time/tasks';
private const INTERVALS_AMOUNT = 10;
private Collection $intervals;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->intervals = IntervalFactory::forUser($this->admin)->createMany(self::INTERVALS_AMOUNT);
}
public function test_total(): void
{
$requestData = [
'start_at' => $this->intervals->min('start_at'),
'end_at' => $this->intervals->max('end_at')->addMinute(),
'user_id' => $this->admin->id
];
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertOk();
//TODO CHECK RESPONSE CONTENT
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
public function test_wrong_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, ['task_id' => 'wrong']);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace Tests\Feature\Time;
use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class TotalTest extends TestCase
{
private const URI = 'time/total';
private const INTERVALS_AMOUNT = 10;
private Collection $intervals;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->intervals = IntervalFactory::forUser($this->admin)->createMany(self::INTERVALS_AMOUNT);
}
public function test_total(): void
{
$requestData = [
'start_at' => $this->intervals->min('start_at'),
'end_at' => $this->intervals->max('end_at')->addMinute(),
'user_id' => $this->admin->id
];
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertOk();
$totalTime = $this->intervals->sum(static function ($interval) {
return Carbon::parse($interval->end_at)->diffInSeconds($interval->start_at);
});
$response->assertJson(['time' => $totalTime]);
$response->assertJsonFragment(['start' => $this->intervals->min('start_at')]);
$response->assertJsonFragment(['end' => $this->intervals->max('end_at')]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,218 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\Task;
use App\Models\TimeInterval;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class BulkEditTest extends TestCase
{
use WithFaker;
private const URI = 'time-intervals/bulk-edit';
private const INTERVALS_AMOUNT = 5;
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
private Collection $intervals;
private Collection $intervalsForManager;
private Collection $intervalsForAuditor;
private Collection $intervalsForUser;
private Task $task;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->task = TaskFactory::refresh()->create();
$this->intervals = IntervalFactory::refresh()->withRandomRelations()->createMany(self::INTERVALS_AMOUNT);
$this->intervalsForManager = IntervalFactory::refresh()
->forUser($this->manager)
->createMany(self::INTERVALS_AMOUNT);
$this->intervalsForAuditor = IntervalFactory::refresh()
->forUser($this->auditor)
->createMany(self::INTERVALS_AMOUNT);
$this->intervalsForUser = IntervalFactory::refresh()
->forUser($this->user)
->createMany(self::INTERVALS_AMOUNT);
}
public function test_bulk_edit_as_admin(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
foreach ($this->intervals as $interval) {
$this->assertDatabaseMissing('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervals->toArray()];
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervals as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
}
public function test_bulk_edit_as_manager(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
foreach ($this->intervals as $interval) {
$this->assertDatabaseMissing('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervals->toArray()];
$response = $this->actingAs($this->manager)->postJson(self::URI, $requestData);
$response->assertForbidden();
}
public function test_bulk_edit_your_own_as_manager(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
foreach ($this->intervalsForManager as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervalsForManager->toArray()];
$response = $this->actingAs($this->manager)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervalsForManager as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
}
public function test_bulk_edit_as_auditor(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
foreach ($this->intervals as $interval) {
$this->assertDatabaseMissing('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervals->toArray()];
$response = $this->actingAs($this->auditor)->postJson(self::URI, $requestData);
$response->assertForbidden();
}
public function test_bulk_edit_your_own_as_auditor(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
foreach ($this->intervalsForAuditor as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervalsForAuditor->toArray()];
$response = $this->actingAs($this->auditor)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervalsForAuditor as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
}
public function test_bulk_edit_as_user(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
foreach ($this->intervals as $interval) {
$this->assertDatabaseMissing('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervals->toArray()];
$response = $this->actingAs($this->user)->postJson(self::URI, $requestData);
$response->assertForbidden();
}
public function test_bulk_edit_your_own_as_user(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
foreach ($this->intervalsForUser as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervalsForUser->toArray()];
$response = $this->actingAs($this->user)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervalsForUser as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
}
public function test_with_not_existing_intervals(): void
{
$this->intervals->each->setAttribute('task_id', $this->task->id);
$nonIntervals = [
['id' => TimeInterval::max('id') + 1, 'task_id' => $this->task->id],
['id' => TimeInterval::max('id') + 2, 'task_id' => $this->task->id]
];
$requestData = ['intervals' => array_merge($this->intervals->toArray(), $nonIntervals)];
foreach ($this->intervals as $interval) {
$this->assertDatabaseMissing('time_intervals', $interval->toArray());
}
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,177 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\TimeInterval;
use App\Models\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class BulkRemoveTest extends TestCase
{
private const URI = 'time-intervals/bulk-remove';
private const INTERVALS_AMOUNT = 5;
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
private Collection $intervals;
private Collection $intervalsForManager;
private Collection $intervalsForAuditor;
private Collection $intervalsForUser;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->intervals = IntervalFactory::refresh()->withRandomRelations()->createMany(self::INTERVALS_AMOUNT);
$this->intervalsForManager = IntervalFactory::refresh()
->forUser($this->manager)
->createMany(self::INTERVALS_AMOUNT);
$this->intervalsForAuditor = IntervalFactory::refresh()
->forUser($this->auditor)
->createMany(self::INTERVALS_AMOUNT);
$this->intervalsForUser = IntervalFactory::refresh()
->forUser($this->user)
->createMany(self::INTERVALS_AMOUNT);
}
public function test_bulk_remove_as_admin(): void
{
foreach ($this->intervals as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervals->pluck('id')->toArray()];
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervals as $interval) {
$this->assertSoftDeleted('time_intervals', $interval->toArray());
}
}
public function test_bulk_remove_as_manager(): void
{
foreach ($this->intervals as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervals->pluck('id')->toArray()];
$response = $this->actingAs($this->manager)->postJson(self::URI, $requestData);
$response->assertForbidden();
}
public function test_bulk_remove_your_own_as_manager(): void
{
foreach ($this->intervalsForManager as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervalsForManager->pluck('id')->toArray()];
$response = $this->actingAs($this->manager)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervalsForManager as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
}
public function test_bulk_remove_as_user(): void
{
foreach ($this->intervals as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervals->pluck('id')->toArray()];
$response = $this->actingAs($this->user)->postJson(self::URI, $requestData);
$response->assertForbidden();
}
public function test_bulk_remove_your_own_as_user(): void
{
foreach ($this->intervalsForUser as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervalsForUser->pluck('id')->toArray()];
$response = $this->actingAs($this->user)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervalsForUser as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
}
public function test_bulk_remove_your_own_as_auditor(): void
{
foreach ($this->intervalsForAuditor as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$requestData = ['intervals' => $this->intervalsForAuditor->pluck('id')->toArray()];
$response = $this->actingAs($this->auditor)->postJson(self::URI, $requestData);
$response->assertOk();
foreach ($this->intervalsForAuditor as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
}
public function test_with_not_existing_intervals(): void
{
$nonIntervals = [TimeInterval::max('id') + 1, TimeInterval::max('id') + 2];
$requestData = ['intervals' => array_merge($this->intervals->pluck('id')->toArray(), $nonIntervals)];
foreach ($this->intervals as $interval) {
$this->assertDatabaseHas('time_intervals', $interval->toArray());
}
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\TimeInterval;
use App\Models\User;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CountTest extends TestCase
{
private const URI = 'time-intervals/count';
private const SCREENSHOTS_AMOUNT = 10;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
IntervalFactory::createMany(self::SCREENSHOTS_AMOUNT);
}
public function test_count(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['total' => TimeInterval::count()]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,169 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\Task;
use App\Models\TimeInterval;
use App\Models\User;
use Tests\Facades\IntervalFactory;
use Tests\Facades\TaskFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CreateTest extends TestCase
{
private const URI = 'time-intervals/create';
private User $admin;
private Task $task;
private array $intervalData;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->task = TaskFactory::forUser($this->admin)->create();
$this->intervalData = IntervalFactory::createRandomModelDataWithRelation();
$this->intervalData['user_id'] = $this->admin->id;
}
public function test_create(): void
{
$this->assertDatabaseMissing('time_intervals', $this->intervalData);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->intervalData);
$response->assertOk();
$this->assertDatabaseHas('time_intervals', $this->intervalData);
}
public function test_already_exists_left(): void
{
$this->intervalData['start_at'] = '1900-01-01 01:00:00';
$this->intervalData['end_at'] = '1900-01-01 01:05:00';
TimeInterval::create($this->intervalData);
$this->assertDatabaseHas('time_intervals', $this->intervalData);
$newInterval = $this->intervalData;
$newInterval['start_at'] = '1900-01-01 00:55:00';
$newInterval['end_at'] = '1900-01-01 01:05:00';
$response = $this->actingAs($this->admin)->postJson(self::URI, $newInterval);
$response->assertValidationError();
}
public function test_already_exists_right(): void
{
$this->intervalData['start_at'] = '1900-01-01 01:00:00';
$this->intervalData['end_at'] = '1900-01-01 01:05:00';
TimeInterval::create($this->intervalData);
$this->assertDatabaseHas('time_intervals', $this->intervalData);
$newInterval = $this->intervalData;
$newInterval['start_at'] = '1900-01-01 01:00:00';
$newInterval['end_at'] = '1900-01-01 01:10:00';
$response = $this->actingAs($this->admin)->postJson(self::URI, $newInterval);
$response->assertValidationError();
}
public function test_already_exists_left_inner(): void
{
$this->intervalData['start_at'] = '1900-01-01 01:00:00';
$this->intervalData['end_at'] = '1900-01-01 01:05:00';
TimeInterval::create($this->intervalData);
$this->assertDatabaseHas('time_intervals', $this->intervalData);
$newInterval = $this->intervalData;
$newInterval['start_at'] = '1900-01-01 00:55:00';
$newInterval['end_at'] = '1900-01-01 01:03:00';
$response = $this->actingAs($this->admin)->postJson(self::URI, $newInterval);
$response->assertValidationError();
}
public function test_already_exists_right_inner(): void
{
$this->intervalData['start_at'] = '1900-01-01 01:00:00';
$this->intervalData['end_at'] = '1900-01-01 01:05:00';
TimeInterval::create($this->intervalData);
$this->assertDatabaseHas('time_intervals', $this->intervalData);
$newInterval = $this->intervalData;
$newInterval['start_at'] = '1900-01-01 01:03:00';
$newInterval['end_at'] = '1900-01-01 01:10:00';
$response = $this->actingAs($this->admin)->postJson(self::URI, $newInterval);
$response->assertValidationError();
}
public function test_already_exists_inner(): void
{
$this->intervalData['start_at'] = '1900-01-01 01:00:00';
$this->intervalData['end_at'] = '1900-01-01 01:05:00';
TimeInterval::create($this->intervalData);
$this->assertDatabaseHas('time_intervals', $this->intervalData);
$newInterval = $this->intervalData;
$newInterval['start_at'] = '1900-01-01 01:01:00';
$newInterval['end_at'] = '1900-01-01 01:03:00';
$response = $this->actingAs($this->admin)->postJson(self::URI, $newInterval);
$response->assertValidationError();
}
public function test_already_exists_outer(): void
{
$this->intervalData['start_at'] = '1900-01-01 01:00:00';
$this->intervalData['end_at'] = '1900-01-01 01:05:00';
TimeInterval::create($this->intervalData);
$this->assertDatabaseHas('time_intervals', $this->intervalData);
$newInterval = $this->intervalData;
$newInterval['start_at'] = '1900-01-01 00:55:00';
$newInterval['end_at'] = '1900-01-01 01:10:00';
$response = $this->actingAs($this->admin)->postJson(self::URI, $newInterval);
$response->assertValidationError();
}
public function test_already_exists(): void
{
TimeInterval::create($this->intervalData);
$this->assertDatabaseHas('time_intervals', $this->intervalData);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->intervalData);
$response->assertValidationError();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\User;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class DashboardTest extends TestCase
{
private const URI = 'time-intervals/dashboard';
private const INTERVALS_AMOUNT = 2;
private Collection $intervals;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->intervals = IntervalFactory::forUser($this->admin)->createMany(self::INTERVALS_AMOUNT);
}
public function test_dashboard(): void
{
$requestData = [
'start_at' => $this->intervals->min('start_at'),
'end_at' => $this->intervals->max('start_at')->addHour(),
'user_ids' => [$this->admin->id]
];
$response = $this->actingAs($this->admin)->postJson(self::URI, $requestData);
$response->assertOk();
$this->assertCount(
$this->intervals->count(),
$response->json('userIntervals')[$this->admin->id]['intervals']
);
#TODO change later
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\TimeInterval;
use App\Models\User;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class EditTest extends TestCase
{
private const URI = 'time-intervals/edit';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var TimeInterval $timeInterval */
private TimeInterval $timeInterval;
/** @var TimeInterval $timeIntervalForManager */
private TimeInterval $timeIntervalForManager;
/** @var TimeInterval $timeIntervalForAuditor */
private TimeInterval $timeIntervalForAuditor;
/** @var TimeInterval $timeIntervalForUser */
private TimeInterval $timeIntervalForUser;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->timeInterval = IntervalFactory::create();
$this->timeIntervalForManager = IntervalFactory::forUser($this->manager)->create();
$this->timeIntervalForAuditor = IntervalFactory::forUser($this->auditor)->create();
$this->timeIntervalForUser = IntervalFactory::forUser($this->user)->create();
}
public function test_edit_as_admin(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$editedInterval = clone $this->timeInterval;
$editedInterval->user_id = UserFactory::refresh()->asUser()->create()->id;
$response = $this->actingAs($this->admin)->postJson(self::URI, $editedInterval->toArray());
$response->assertOk();
$this->assertDatabaseHas('time_intervals', $editedInterval->toArray());
}
public function test_edit_as_manager(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$editedInterval = clone $this->timeInterval;
$editedInterval->user_id = UserFactory::refresh()->asUser()->create()->id;
$response = $this->actingAs($this->manager)->postJson(self::URI, $editedInterval->toArray());
$response->assertForbidden();
}
public function test_edit_your_own_as_manager(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$editedInterval = clone $this->timeIntervalForManager;
$editedInterval->user_id = UserFactory::refresh()->asUser()->create()->id;
$response = $this->actingAs($this->manager)->postJson(self::URI, $editedInterval->toArray());
$response->assertOk();
$this->assertDatabaseHas('time_intervals', $editedInterval->toArray());
}
public function test_edit_as_auditor(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$editedInterval = clone $this->timeInterval;
$editedInterval->user_id = UserFactory::refresh()->asUser()->create()->id;
$response = $this->actingAs($this->auditor)->postJson(self::URI, $editedInterval->toArray());
$response->assertForbidden();
}
public function test_edit_your_own_as_auditor(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeIntervalForAuditor->toArray());
$editedInterval = clone $this->timeIntervalForAuditor;
$editedInterval->user_id = UserFactory::refresh()->asUser()->create()->id;
$response = $this->actingAs($this->auditor)->postJson(self::URI, $editedInterval->toArray());
$response->assertOk();
$this->assertDatabaseHas('time_intervals', $editedInterval->toArray());
}
public function test_edit_as_user(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$editedInterval = clone $this->timeInterval;
$editedInterval->user_id = UserFactory::refresh()->asUser()->create()->id;
$response = $this->actingAs($this->user)->postJson(self::URI, $editedInterval->toArray());
$response->assertForbidden();
}
public function test_edit_your_own_as_user(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeIntervalForManager->toArray());
$editedInterval = clone $this->timeIntervalForUser;
$editedInterval->user_id = UserFactory::refresh()->asUser()->create()->id;
$response = $this
->actingAs($this->user)
->postJson(self::URI, $editedInterval->toArray());
$response->assertOk();
$this->assertDatabaseHas('time_intervals', $editedInterval->toArray());
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\TimeInterval;
use App\Models\User;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'time-intervals/list';
private const INTERVALS_AMOUNT = 10;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
IntervalFactory::createMany(self::INTERVALS_AMOUNT);
}
public function test_list(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(TimeInterval::all()->toArray());
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,135 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\TimeInterval;
use App\Models\User;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class RemoveTest extends TestCase
{
private const URI = 'time-intervals/remove';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var TimeInterval $timeInterval */
private TimeInterval $timeInterval;
/** @var TimeInterval $timeIntervalForManager */
private TimeInterval $timeIntervalForManager;
/** @var TimeInterval $timeIntervalForAuditor */
private TimeInterval $timeIntervalForAuditor;
/** @var TimeInterval $timeIntervalForUser */
private TimeInterval $timeIntervalForUser;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->timeInterval = IntervalFactory::create();
$this->timeIntervalForManager = IntervalFactory::forUser($this->manager)->create();
$this->timeIntervalForAuditor = IntervalFactory::forUser($this->auditor)->create();
$this->timeIntervalForUser = IntervalFactory::forUser($this->user)->create();
}
public function test_remove_as_admin(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertOk();
$this->assertSoftDeleted('time_intervals', ['id' => $this->timeInterval->id]);
}
public function test_remove_as_manager(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertForbidden();
}
public function test_remove_your_own_as_manager(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeIntervalForManager->toArray());
$response = $this
->actingAs($this->manager)
->postJson(self::URI, $this->timeIntervalForManager->only('id'));
$response->assertOk();
$this->assertSoftDeleted('time_intervals', ['id' => $this->timeIntervalForManager->id]);
}
public function test_remove_as_auditor(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertForbidden();
}
public function test_remove_your_own_as_auditor(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeIntervalForManager->toArray());
$response = $this
->actingAs($this->auditor)
->postJson(self::URI, $this->timeIntervalForAuditor->only('id'));
$response->assertOk();
$this->assertSoftDeleted('time_intervals', ['id' => $this->timeIntervalForAuditor->id]);
}
public function test_remove_as_user(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->user)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertForbidden();
}
public function test_remove_your_own_as_user(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeIntervalForManager->toArray());
$response = $this
->actingAs($this->user)
->postJson(self::URI, $this->timeIntervalForUser->only('id'));
$response->assertOk();
$this->assertSoftDeleted('time_intervals', ['id' => $this->timeIntervalForUser->id]);
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace Tests\Feature\TimeIntervals;
use App\Models\TimeInterval;
use App\Models\User;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ShowTest extends TestCase
{
private const URI = 'time-intervals/show';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var TimeInterval $timeInterval */
private TimeInterval $timeInterval;
/** @var TimeInterval $timeIntervalForUser */
private TimeInterval $timeIntervalForUser;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->timeInterval = IntervalFactory::create();
$this->timeIntervalForUser = IntervalFactory::forUser($this->user)->create();
}
public function test_show_as_admin(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertOk();
$response->assertJson($this->timeInterval->toArray());
}
public function test_show_as_manager(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertOk();
$response->assertJson($this->timeInterval->toArray());
}
public function test_show_as_auditor(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertOk();
$response->assertJson($this->timeInterval->toArray());
}
public function test_show_as_user(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeInterval->toArray());
$response = $this->actingAs($this->user)->postJson(self::URI, $this->timeInterval->only('id'));
$response->assertForbidden();
}
public function test_show_your_own_as_user(): void
{
$this->assertDatabaseHas('time_intervals', $this->timeIntervalForUser->toArray());
$response = $this
->actingAs($this->user)
->postJson(self::URI, $this->timeIntervalForUser->only('id'));
$response->assertJson($this->timeIntervalForUser->toArray());
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Tests\Feature\TimeUseReport;
use App\Models\TimeInterval;
use App\Models\User;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Tests\Facades\IntervalFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'time-use-report/list';
private const INTERVALS_AMOUNT = 10;
private Collection $intervals;
private User $admin;
private int $duration = 0;
private array $userIds;
private array $requestData;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
$this->intervals = IntervalFactory::withRandomRelations()->createMany(self::INTERVALS_AMOUNT);
$this->intervals->each(function (TimeInterval $interval) {
$this->userIds[] = $interval->user_id;
$this->duration += Carbon::parse($interval->end_at)->diffInSeconds($interval->start_at);
});
$this->requestData = [
'start_at' => $this->intervals->min('start_at'),
'end_at' => $this->intervals->max('end_at')->addMinute(),
'user_ids' => $this->userIds
];
}
public function test_list(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->requestData);
$response->assertOk();
$totalTime = collect($response->json())->pluck('total_time')->sum();
$this->assertEquals($this->duration, $totalTime);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Tests\Feature\Users;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ActivityTest extends TestCase
{
private const URI = 'users/activity';
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
}
public function test_update(): void
{
/* @var \Carbon\Carbon $lastActivity */
$lastActivity = $this->admin->last_activity;
$response = $this->actingAs($this->admin)->patchJson(self::URI);
$user = User::find($this->admin->id);
$response->assertOk();
$this->assertNotEquals($lastActivity->toString(), $user->last_activity->toString());
$this->assertTrue($user->online);
}
public function test_unauthorized(): void
{
$response = $this->patchJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Tests\Feature\Users;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CountTest extends TestCase
{
private const URI = 'users/count';
private const USERS_AMOUNT = 10;
private User $admin;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::asAdmin()->withTokens()->create();
UserFactory::createMany(self::USERS_AMOUNT);
}
public function test_count(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$response->assertOk();
$response->assertJson(['total' => User::count()]);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace Tests\Feature\Users;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class CreateTest extends TestCase
{
private const URI = 'users/create';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
private array $userData;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$this->userData = UserFactory::createRandomRegistrationModelData();
}
public function test_create_as_admin(): void
{
$this->assertDatabaseMissing('users', $this->userData);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->userData);
unset($this->userData['password']);
$response->assertOk();
$this->assertDatabaseHas('users', $this->userData);
$responseData = $response->json('res');
unset($responseData['online']);
$this->assertDatabaseHas('users', $responseData);
}
public function test_create_as_manager(): void
{
$this->assertDatabaseMissing('users', $this->userData);
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->userData);
$response->assertForbidden();
}
public function test_create_as_auditor(): void
{
$this->assertDatabaseMissing('users', $this->userData);
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->userData);
$response->assertForbidden();
}
public function test_create_as_user(): void
{
$this->assertDatabaseMissing('users', $this->userData);
$response = $this->actingAs($this->user)->postJson(self::URI, $this->userData);
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,134 @@
<?php
namespace Tests\Feature\Users;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\Facades\UserFactory;
use Tests\TestCase;
use Faker\Factory as FakerFactory;
class EditTest extends TestCase
{
use WithFaker;
private const URI = '/users/edit';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
}
public function test_edit_as_admin(): void
{
$this->user->full_name = $this->faker->name;
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->user->toArray());
$response->assertOk();
$response->assertJson(['res' => $this->user->toArray()]);
$this->assertDatabaseHas('users', $this->user->only('id', 'full_name'));
}
public function test_edit_as_manager(): void
{
$this->user->full_name = $this->faker->name;
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->user->toArray());
$response->assertForbidden();
}
public function test_edit_as_auditor(): void
{
$this->user->full_name = $this->faker->name;
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->user->toArray());
$response->assertForbidden();
}
public function test_edit_as_user(): void
{
$this->admin->full_name = $this->faker->name;
$response = $this->actingAs($this->user)->postJson(self::URI, $this->admin->toArray());
$response->assertForbidden();
}
public function test_edit_as_your_own_user(): void
{
$faker = FakerFactory::create();
$user = clone $this->user;
$user->full_name = $faker->unique()->firstName;
$user->email = $faker->unique()->email;
$user->password = $faker->unique()->password;
$user->user_language = 'en';
$response = $this->actingAs($this->user)->postJson(
self::URI,
$user->only('id', 'full_name', 'email', 'password', 'user_language')
);
$response->assertOk();
$response->assertJson(['res' => $user->toArray()]);
$this->assertDatabaseHas(
'users',
$user->only('id', 'full_name', 'email', 'user_language')
);
}
public function test_edit_forbidden_field_as_user(): void
{
$user = clone $this->user;
$user->is_admin = true;
$response = $this->actingAs($this->user)->postJson(
self::URI,
$user->only('id', 'is_admin')
);
$response->assertValidationError();
}
public function test_not_existing(): void
{
$this->user->id++;
$this->user->email = 'newemail@example.com';
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->user->toArray());
$response->assertNotFound();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,170 @@
<?php
namespace Tests\Feature\Users;
use App\Models\Project;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ListTest extends TestCase
{
private const URI = 'users/list';
private const USERS_AMOUNT = 10;
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
/** @var Project $project */
private Project $project;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
UserFactory::createMany(self::USERS_AMOUNT);
$this->project = ProjectFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($this->project->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($this->project->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($this->project->id, ['role_id' => 2]);
}
public function test_list_as_admin(): void
{
$response = $this->actingAs($this->admin)->getJson(self::URI);
$users = User::withoutGlobalScopes()->setEagerLoads([])->get()->toArray();
$response->assertOk();
$response->assertExactJson($users);
}
public function test_list_as_manager(): void
{
$response = $this->actingAs($this->manager)->getJson(self::URI);
$users = User::withoutGlobalScopes()->setEagerLoads([])->get()->toArray();
$response->assertOk();
$response->assertExactJson($users);
}
public function test_list_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->getJson(self::URI);
$users = User::withoutGlobalScopes()->setEagerLoads([])->get()->toArray();
$response->assertOk();
$response->assertExactJson($users);
}
public function test_list_as_user(): void
{
$response = $this->actingAs($this->user)->getJson(self::URI);
$user = User::withoutGlobalScopes()
->where('id', $this->user->id)
->setEagerLoads([])
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($user);
}
public function test_list_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->getJson(self::URI);
$users = User::withoutGlobalScopes()
->whereHas('projects', function ($query) {
$query->where('project_id', $this->project->id);
})
->setEagerLoads([])
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($users);
}
public function test_list_as_project_manager_with_global_scope(): void
{
$response = $this->actingAs($this->projectManager)->postJson(self::URI, ['global_scope' => true]);
$users = User::withoutGlobalScope(\App\Scopes\UserAccessScope::class)
->setEagerLoads([])
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($users);
}
public function test_list_as_project_auditor(): void
{
$response = $this->actingAs($this->projectAuditor)->getJson(self::URI);
$users = User::withoutGlobalScopes()
->whereHas('projects', function ($query) {
$query->where('project_id', $this->project->id);
})
->setEagerLoads([])
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($users);
}
public function test_list_as_project_user(): void
{
$response = $this->actingAs($this->projectManager)->getJson(self::URI);
$users = User::withoutGlobalScopes()
->whereHas('projects', function ($query) {
$query->where('project_id', $this->project->id);
})
->setEagerLoads([])
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($users);
}
public function test_unauthorized(): void
{
$response = $this->getJson(self::URI);
$response->assertUnauthorized();
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace Tests\Feature\Users;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class RemoveTest extends TestCase
{
private const URI = 'users/remove';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
}
public function test_remove_as_admin(): void
{
$user = $this->user->makeHidden('online')->toArray();
unset($user['online']);
$this->assertDatabaseHas('users', $user);
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->user->only('id'));
$response->assertOk();
$this->assertSoftDeleted('users', $this->user->only('id'));
}
public function test_remove_as_manager(): void
{
$this->assertDatabaseHas('users', $this->user->makeHidden('online')->toArray());
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->user->only('id'));
$response->assertForbidden();
}
public function test_remove_as_auditor(): void
{
$this->assertDatabaseHas('users', $this->user->makeHidden('online')->toArray());
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->user->only('id'));
$response->assertForbidden();
}
public function test_remove_as_user(): void
{
$this->assertDatabaseHas('users', $this->user->makeHidden('online')->toArray());
$response = $this->actingAs($this->user)->postJson(self::URI, $this->user->only('id'));
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Tests\Feature\Users;
use App\Models\User;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class SendInviteTest extends TestCase
{
private const URI = 'users/send-invite';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
}
public function test_send_invite_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->user->only('id'));
$response->assertOk();
}
public function test_send_invite_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->user->only('id'));
$response->assertForbidden();
}
public function test_send_invite_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->user->only('id'));
$response->assertForbidden();
}
public function test_send_invite_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->user->only('id'));
$response->assertForbidden();
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace Tests\Feature\Users;
use App\Models\User;
use Tests\Facades\ProjectFactory;
use Tests\Facades\UserFactory;
use Tests\TestCase;
class ShowTest extends TestCase
{
private const URI = 'users/show';
/** @var User $admin */
private User $admin;
/** @var User $manager */
private User $manager;
/** @var User $auditor */
private User $auditor;
/** @var User $user */
private User $user;
/** @var User $projectManager */
private User $projectManager;
/** @var User $projectAuditor */
private User $projectAuditor;
/** @var User $projectUser */
private User $projectUser;
protected function setUp(): void
{
parent::setUp();
$this->admin = UserFactory::refresh()->asAdmin()->withTokens()->create();
$this->manager = UserFactory::refresh()->asManager()->withTokens()->create();
$this->auditor = UserFactory::refresh()->asAuditor()->withTokens()->create();
$this->user = UserFactory::refresh()->asUser()->withTokens()->create();
$project = ProjectFactory::create();
$this->projectManager = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectManager->projects()->attach($project->id, ['role_id' => 1]);
$this->projectAuditor = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectAuditor->projects()->attach($project->id, ['role_id' => 3]);
$this->projectUser = UserFactory::refresh()->asUser()->withTokens()->create();
$this->projectUser->projects()->attach($project->id, ['role_id' => 2]);
}
public function test_show_as_admin(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI, $this->user->only('id'));
$response->assertOk();
$response->assertJson($this->user->toArray());
}
public function test_show_as_manager(): void
{
$response = $this->actingAs($this->manager)->postJson(self::URI, $this->user->only('id'));
$response->assertOk();
$response->assertJson($this->user->toArray());
}
public function test_show_as_auditor(): void
{
$response = $this->actingAs($this->auditor)->postJson(self::URI, $this->user->only('id'));
$response->assertOk();
$response->assertJson($this->user->toArray());
}
public function test_show_as_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->admin->only('id'));
$response->assertForbidden();
}
public function test_show_as_your_own_user(): void
{
$response = $this->actingAs($this->user)->postJson(self::URI, $this->user->only('id'));
$this->user->makeHidden('role');
$response->assertOk();
$response->assertJson($this->user->toArray());
}
public function test_show_as_project_manager(): void
{
$response = $this->actingAs($this->projectManager)->postJson(self::URI, $this->projectUser->only('id'));
$user = User::where('id', $this->projectUser->id)
->setEagerLoads([])
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($user[0]);
}
public function test_show_as_project_auditor(): void
{
$response = $this
->actingAs($this->projectAuditor)
->postJson(self::URI, $this->projectUser->only('id'));
$user = User::where('id', $this->projectUser->id)
->setEagerLoads([])
->get()
->toArray();
$response->assertOk();
$response->assertExactJson($user[0]);
}
public function test_show_as_project_user(): void
{
$response = $this->actingAs($this->projectUser)->postJson(self::URI, $this->projectAuditor->only('id'));
$response->assertForbidden();
}
public function test_unauthorized(): void
{
$response = $this->postJson(self::URI);
$response->assertUnauthorized();
}
public function test_without_params(): void
{
$response = $this->actingAs($this->admin)->postJson(self::URI);
$response->assertValidationError();
}
}

84
tests/README.md Normal file
View File

@@ -0,0 +1,84 @@
# Running Tests From PhpStorm
# TEST!
### IDE Configuration
* Make sure correct interpreter configured for the project.
(_File | Settings | Languages & Frameworks | PHP_)
* Make sure path to composer autoloader is correct in test frameworks configuration options,
as well as default configuration file (`phpunit.xml`) for test runner,
which can be find inside project root directory.
(_File | Settings | Languages & Frameworks | PHP | Test Frameworks_)
### Environment and DB configuration
* Create new test dedicated database, for example `amazing_time_tests`.
* Copy `.env.testing.example` file and rename it to `.env.testing`.
* Inside `.env.testing` edit DB connection info to match yours.
* Apply migrations to testing database: `php artisan migrate --env=testing`.
* Run RoleSeeder: `php artisan db:seed --class=RoleSeeder --env=testing`.
### Running tests
You can run and debug single test as well as tests from entire files and folders.
PhpStorm creates a run/debug configuration with the default settings and launches the tests.
You can also run tests with coverage (_if xdebug extension installed_) to see test coverage situation
up to the highlighting of executed and non-executed lines right inside the code editor.
_For more information check official PhpStorm documentation._
# Running tests from command line
To run tests from CLI use phpunit script from `vendor/phpunit/phpunit`.
Don't forget to provide path to phpunit.xml with `--configuration` parameter.
For example:
`vendor/phpunit/phpunit/phpunit --configuration phpunit.xml tests/Feature`.
For more information check [PHPUnit docs](https://phpunit.readthedocs.io/en/8.5/).
# Running Tests in CI pipelines
### GitLab
Configuration at `.gitlab-ci.yml` allows you to run tests automatically
when you push commits to your repository.
It will appear as "integration_testing" job at the test stage.
You can select branches, that job will run on by pointing them in **only** directive at `.gitalb-ci.yml`.
Or exclude branches by **except** directive.
For more information check [gitlab-ci.yml reference](https://docs.gitlab.com/ee/ci/yaml/)
and [GitLab CI/CD](https://docs.gitlab.com/ee/ci/)
# Writing Tests
For basic information check [Laravel Documentation](https://laravel.com/docs/6.x/testing).
#### Main TestCase class
Every test should extend `tests/TestCase` class, which creates application before running tests.
It uses `DatabaseTransaction` trait to wrap each test case in a database transaction
to isolate a database from any changes while running tests.
Because of that it's worth mentioning that there is no point in trying to look into the database during debugging,
because there will be no changes,
but nothing prevents you from making queries directly from the tests.
#### Requests
All requests return a slightly extended `TestResponse` class, which can be found in `tests/TestResponse.php`.
It provides methods to conveniently check different types of responses and their structure.
The overridden `actingAs` helper method provides a simple way to authenticate a given user model as the current user.
The user must have valid tokens for successful authentication.
Also, it's highly recommended to use constants when specifying the expected answer status code,
which are defined in `tests/TestCase` as well as in `tests/TestResponse`.
### Factories
The data that's necessary for tests generated with the use of factories that are placed in `tests/Factories`,
and facades for them in `tests/Facades`.

115
tests/TestCase.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
namespace Tests;
use App\Models\User;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
/**
* @method TestResponse get($uri, array $headers = [])
* @method TestResponse getJson($uri, array $headers = [])
* @method TestResponse post($uri, array $data = [], array $headers = [])
* @method TestResponse postJson($uri, array $data = [], array $headers = [])
* @method TestResponse put($uri, array $data = [], array $headers = [])
* @method TestResponse putJson($uri, array $data = [], array $headers = [])
* @method TestResponse patch($uri, array $data = [], array $headers = [])
* @method TestResponse patchJson($uri, array $data = [], array $headers = [])
* @method TestResponse delete($uri, array $data = [], array $headers = [])
* @method TestResponse deleteJson($uri, array $data = [], array $headers = [])
* @method TestResponse json($method, $uri, array $data = [], array $headers = [])
*/
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
use DatabaseTransactions;
public const HTTP_CONTINUE = 100;
public const HTTP_SWITCHING_PROTOCOLS = 101;
public const HTTP_PROCESSING = 102;
public const HTTP_EARLY_HINTS = 103;
public const HTTP_OK = 200;
public const HTTP_CREATED = 201;
public const HTTP_ACCEPTED = 202;
public const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
public const HTTP_NO_CONTENT = 204;
public const HTTP_RESET_CONTENT = 205;
public const HTTP_PARTIAL_CONTENT = 206;
public const HTTP_MULTI_STATUS = 207;
public const HTTP_ALREADY_REPORTED = 208;
public const HTTP_IM_USED = 226;
public const HTTP_MULTIPLE_CHOICES = 300;
public const HTTP_MOVED_PERMANENTLY = 301;
public const HTTP_FOUND = 302;
public const HTTP_SEE_OTHER = 303;
public const HTTP_NOT_MODIFIED = 304;
public const HTTP_USE_PROXY = 305;
public const HTTP_RESERVED = 306;
public const HTTP_TEMPORARY_REDIRECT = 307;
public const HTTP_PERMANENTLY_REDIRECT = 308;
public const HTTP_BAD_REQUEST = 400;
public const HTTP_UNAUTHORIZED = 401;
public const HTTP_PAYMENT_REQUIRED = 402;
public const HTTP_FORBIDDEN = 403;
public const HTTP_NOT_FOUND = 404;
public const HTTP_METHOD_NOT_ALLOWED = 405;
public const HTTP_NOT_ACCEPTABLE = 406;
public const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
public const HTTP_REQUEST_TIMEOUT = 408;
public const HTTP_CONFLICT = 409;
public const HTTP_GONE = 410;
public const HTTP_LENGTH_REQUIRED = 411;
public const HTTP_PRECONDITION_FAILED = 412;
public const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
public const HTTP_REQUEST_URI_TOO_LONG = 414;
public const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
public const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
public const HTTP_EXPECTATION_FAILED = 417;
public const HTTP_I_AM_A_TEAPOT = 418;
public const HTTP_MISDIRECTED_REQUEST = 421;
public const HTTP_UNPROCESSABLE_ENTITY = 422;
public const HTTP_LOCKED = 423;
public const HTTP_FAILED_DEPENDENCY = 424;
public const HTTP_TOO_EARLY = 425;
public const HTTP_UPGRADE_REQUIRED = 426;
public const HTTP_PRECONDITION_REQUIRED = 428;
public const HTTP_TOO_MANY_REQUESTS = 429;
public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
public const HTTP_INTERNAL_SERVER_ERROR = 500;
public const HTTP_NOT_IMPLEMENTED = 501;
public const HTTP_BAD_GATEWAY = 502;
public const HTTP_SERVICE_UNAVAILABLE = 503;
public const HTTP_GATEWAY_TIMEOUT = 504;
public const HTTP_VERSION_NOT_SUPPORTED = 505;
public const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506;
public const HTTP_INSUFFICIENT_STORAGE = 507;
public const HTTP_LOOP_DETECTED = 508;
public const HTTP_NOT_EXTENDED = 510;
public const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511;
public function actingAs($user, $driver = null, int $tokenOffset = 0): self
{
$token = '';
if (!is_string($user)) {
$tokens = cache("testing:{$user->id}:tokens");
if ($tokens && isset($tokens[$tokenOffset])) {
$token = $tokens[$tokenOffset]['token'];
}
} else {
$token = $user;
}
$this->withHeader('Authorization', "Bearer $token");
return $this;
}
protected function createTestResponse($response): TestResponse
{
return TestResponse::fromBaseResponse($response);
}
}

140
tests/TestResponse.php Normal file
View File

@@ -0,0 +1,140 @@
<?php
namespace Tests;
use App\Exceptions\Entities\AuthorizationException;
use Illuminate\Testing\TestResponse as BaseTestResponse;
use PHPUnit\Framework\Assert as PHPUnit;
class TestResponse extends BaseTestResponse
{
public const HTTP_CONTINUE = 100;
public const HTTP_SWITCHING_PROTOCOLS = 101;
public const HTTP_PROCESSING = 102;
public const HTTP_EARLY_HINTS = 103;
public const HTTP_OK = 200;
public const HTTP_CREATED = 201;
public const HTTP_ACCEPTED = 202;
public const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
public const HTTP_NO_CONTENT = 204;
public const HTTP_RESET_CONTENT = 205;
public const HTTP_PARTIAL_CONTENT = 206;
public const HTTP_MULTI_STATUS = 207;
public const HTTP_ALREADY_REPORTED = 208;
public const HTTP_IM_USED = 226;
public const HTTP_MULTIPLE_CHOICES = 300;
public const HTTP_MOVED_PERMANENTLY = 301;
public const HTTP_FOUND = 302;
public const HTTP_SEE_OTHER = 303;
public const HTTP_NOT_MODIFIED = 304;
public const HTTP_USE_PROXY = 305;
public const HTTP_RESERVED = 306;
public const HTTP_TEMPORARY_REDIRECT = 307;
public const HTTP_PERMANENTLY_REDIRECT = 308;
public const HTTP_BAD_REQUEST = 400;
public const HTTP_UNAUTHORIZED = 401;
public const HTTP_PAYMENT_REQUIRED = 402;
public const HTTP_FORBIDDEN = 403;
public const HTTP_NOT_FOUND = 404;
public const HTTP_METHOD_NOT_ALLOWED = 405;
public const HTTP_NOT_ACCEPTABLE = 406;
public const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
public const HTTP_REQUEST_TIMEOUT = 408;
public const HTTP_CONFLICT = 409;
public const HTTP_GONE = 410;
public const HTTP_LENGTH_REQUIRED = 411;
public const HTTP_PRECONDITION_FAILED = 412;
public const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
public const HTTP_REQUEST_URI_TOO_LONG = 414;
public const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
public const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
public const HTTP_EXPECTATION_FAILED = 417;
public const HTTP_I_AM_A_TEAPOT = 418;
public const HTTP_MISDIRECTED_REQUEST = 421;
public const HTTP_UNPROCESSABLE_ENTITY = 422;
public const HTTP_LOCKED = 423;
public const HTTP_FAILED_DEPENDENCY = 424;
public const HTTP_TOO_EARLY = 425;
public const HTTP_UPGRADE_REQUIRED = 426;
public const HTTP_PRECONDITION_REQUIRED = 428;
public const HTTP_TOO_MANY_REQUESTS = 429;
public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
public const HTTP_INTERNAL_SERVER_ERROR = 500;
public const HTTP_NOT_IMPLEMENTED = 501;
public const HTTP_BAD_GATEWAY = 502;
public const HTTP_SERVICE_UNAVAILABLE = 503;
public const HTTP_GATEWAY_TIMEOUT = 504;
public const HTTP_VERSION_NOT_SUPPORTED = 505;
public const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506;
public const HTTP_INSUFFICIENT_STORAGE = 507;
public const HTTP_LOOP_DETECTED = 508;
public const HTTP_NOT_EXTENDED = 510;
public const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511;
public function assertError(int $status, string $type = null, bool $hasInfo = false): TestResponse
{
$this->assertStatus($status);
if ($type) {
$this->assertJson(['error_type' => $type]);
}
$structure = ['message', 'error_type'];
if ($hasInfo) {
$structure[] = 'info';
} else {
PHPUnit::assertArrayNotHasKey('info', $this->decodeResponseJson());
}
$this->assertJsonStructure($structure);
return $this;
}
public function assertUnauthorized(
string $type = AuthorizationException::ERROR_TYPE_UNAUTHORIZED,
bool $hasInfo = false
): TestResponse {
return $this->assertError(self::HTTP_UNAUTHORIZED, $type, $hasInfo);
}
public function assertForbidden(
string $type = AuthorizationException::ERROR_TYPE_FORBIDDEN,
bool $hasInfo = false
): TestResponse {
return $this->assertError(self::HTTP_FORBIDDEN, $type, $hasInfo);
}
public function assertValidationError(string $type = 'validation', bool $hasInfo = true): TestResponse
{
return $this->assertError(self::HTTP_BAD_REQUEST, $type, $hasInfo);
}
public function assertNotFound(string $type = 'query.item_not_found', bool $hasInfo = false): TestResponse
{
return $this->assertError(self::HTTP_NOT_FOUND, $type, $hasInfo);
}
public function assertConflict(string $type = 'query.item_already_exists', bool $hasInfo = false): TestResponse
{
return $this->assertError(self::HTTP_CONFLICT, $type, $hasInfo);
}
public function assertSuccess(int $status = self::HTTP_OK): TestResponse
{
$this->assertStatus($status);
return $this;
}
public static function assertEquals(...$params): void
{
PHPUnit::assertEquals(...$params);
}
public static function assertNotEquals(...$params): void
{
PHPUnit::assertNotEquals(...$params);
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Tests\Unit;
use App\Models\Setting;
use App\Services\SettingsProviderService;
use Tests\TestCase;
class SettingsTest extends TestCase
{
public function test_get_setting(): void
{
$service = resolve(SettingsProviderService::class);
$service->set('test', 'language', 'en');
$setting = $service->get('test', 'language');
$this->assertEquals($setting, 'en');
}
public function test_get_all_settings(): void
{
$service = resolve(SettingsProviderService::class);
$service->set('test', 'language', 'en');
$service->set('test', 'key', 'value');
$settings = $service->all('test');
$this->assertDatabaseHas((new Setting)->getTable(), ['value' => reset($settings)]);
}
public function test_set_one_setting(): void
{
$service = resolve(SettingsProviderService::class);
$result = $service->set('test', 'language', 'en');
$this->assertEquals($result, ['language' => 'en']);
}
public function test_set_multiple_settings(): void
{
$service = resolve(SettingsProviderService::class);
$data = ['language' => 'en', 'timezone' => 'utc'];
$result = $service->set('test', $data);
$this->assertEquals($result, $data);
}
}