mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 00:02:15 +01:00
Add chart endpoints
This commit is contained in:
committed by
Constantin Graf
parent
aa3c64e496
commit
01f6f0f5ea
136
app/Http/Controllers/Api/V1/ChartController.php
Normal file
136
app/Http/Controllers/Api/V1/ChartController.php
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\V1;
|
||||||
|
|
||||||
|
use App\Enums\Role;
|
||||||
|
use App\Models\Organization;
|
||||||
|
use App\Service\DashboardService;
|
||||||
|
use App\Service\PermissionStore;
|
||||||
|
use Illuminate\Auth\Access\AuthorizationException;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
|
||||||
|
class ChartController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function weeklyProjectOverview(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$weeklyProjectOverview = $dashboardService->weeklyProjectOverview($user, $organization);
|
||||||
|
|
||||||
|
return response()->json($weeklyProjectOverview);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function latestTasks(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$latestTasks = $dashboardService->latestTasks($user, $organization);
|
||||||
|
|
||||||
|
return response()->json($latestTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function lastSevenDays(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$lastSevenDays = $dashboardService->lastSevenDays($user, $organization);
|
||||||
|
|
||||||
|
return response()->json($lastSevenDays);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function latestTeamActivity(Organization $organization, DashboardService $dashboardService, PermissionStore $permissionStore): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:all');
|
||||||
|
|
||||||
|
$latestTeamActivity = $dashboardService->latestTeamActivity($organization);
|
||||||
|
|
||||||
|
return response()->json($latestTeamActivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function dailyTrackedHours(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$dailyTrackedHours = $dashboardService->getDailyTrackedHours($user, $organization, 60);
|
||||||
|
|
||||||
|
return response()->json($dailyTrackedHours);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function totalWeeklyTime(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$totalWeeklyTime = $dashboardService->totalWeeklyTime($user, $organization);
|
||||||
|
|
||||||
|
return response()->json($totalWeeklyTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function totalWeeklyBillableTime(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$totalWeeklyBillableTime = $dashboardService->totalWeeklyBillableTime($user, $organization);
|
||||||
|
|
||||||
|
return response()->json($totalWeeklyBillableTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function totalWeeklyBillableAmount(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$showBillableRate = $this->member($organization)->role !== Role::Employee->value || $organization->employees_can_see_billable_rates;
|
||||||
|
if (! $showBillableRate) {
|
||||||
|
throw new AuthorizationException('You do not have permission to view billable rates.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalWeeklyBillableAmount = $dashboardService->totalWeeklyBillableAmount($user, $organization);
|
||||||
|
|
||||||
|
return response()->json($totalWeeklyBillableAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws AuthorizationException
|
||||||
|
*/
|
||||||
|
public function weeklyHistory(Organization $organization, DashboardService $dashboardService): JsonResponse
|
||||||
|
{
|
||||||
|
$this->checkPermission($organization, 'charts:view:own');
|
||||||
|
$user = $this->user();
|
||||||
|
|
||||||
|
$weeklyHistory = $dashboardService->getWeeklyHistory($user, $organization);
|
||||||
|
|
||||||
|
return response()->json($weeklyHistory);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,6 +80,8 @@ class JetstreamServiceProvider extends ServiceProvider
|
|||||||
Jetstream::defaultApiTokenPermissions([]);
|
Jetstream::defaultApiTokenPermissions([]);
|
||||||
|
|
||||||
Jetstream::role(Role::Owner->value, 'Owner', [
|
Jetstream::role(Role::Owner->value, 'Owner', [
|
||||||
|
'charts:view:own',
|
||||||
|
'charts:view:all',
|
||||||
'projects:view',
|
'projects:view',
|
||||||
'projects:view:all',
|
'projects:view:all',
|
||||||
'projects:create',
|
'projects:create',
|
||||||
@@ -134,6 +136,8 @@ class JetstreamServiceProvider extends ServiceProvider
|
|||||||
])->description('Owner users can perform any action. There is only one owner per organization.');
|
])->description('Owner users can perform any action. There is only one owner per organization.');
|
||||||
|
|
||||||
Jetstream::role(Role::Admin->value, 'Administrator', [
|
Jetstream::role(Role::Admin->value, 'Administrator', [
|
||||||
|
'charts:view:own',
|
||||||
|
'charts:view:all',
|
||||||
'projects:view',
|
'projects:view',
|
||||||
'projects:view:all',
|
'projects:view:all',
|
||||||
'projects:create',
|
'projects:create',
|
||||||
@@ -184,6 +188,8 @@ class JetstreamServiceProvider extends ServiceProvider
|
|||||||
])->description('Administrator users can perform any action, except accessing the billing dashboard.');
|
])->description('Administrator users can perform any action, except accessing the billing dashboard.');
|
||||||
|
|
||||||
Jetstream::role(Role::Manager->value, 'Manager', [
|
Jetstream::role(Role::Manager->value, 'Manager', [
|
||||||
|
'charts:view:own',
|
||||||
|
'charts:view:all',
|
||||||
'projects:view',
|
'projects:view',
|
||||||
'projects:view:all',
|
'projects:view:all',
|
||||||
'projects:create',
|
'projects:create',
|
||||||
@@ -224,6 +230,7 @@ class JetstreamServiceProvider extends ServiceProvider
|
|||||||
])->description('Managers have full access to all projects, time entries, ect. but cannot manage the organization (add/remove member, edit the organization, ect.).');
|
])->description('Managers have full access to all projects, time entries, ect. but cannot manage the organization (add/remove member, edit the organization, ect.).');
|
||||||
|
|
||||||
Jetstream::role(Role::Employee->value, 'Employee', [
|
Jetstream::role(Role::Employee->value, 'Employee', [
|
||||||
|
'charts:view:own',
|
||||||
'projects:view',
|
'projects:view',
|
||||||
'tags:view',
|
'tags:view',
|
||||||
'tasks:view',
|
'tasks:view',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use App\Http\Controllers\Api\V1\ApiTokenController;
|
use App\Http\Controllers\Api\V1\ApiTokenController;
|
||||||
|
use App\Http\Controllers\Api\V1\ChartController;
|
||||||
use App\Http\Controllers\Api\V1\ClientController;
|
use App\Http\Controllers\Api\V1\ClientController;
|
||||||
use App\Http\Controllers\Api\V1\ExportController;
|
use App\Http\Controllers\Api\V1\ExportController;
|
||||||
use App\Http\Controllers\Api\V1\ImportController;
|
use App\Http\Controllers\Api\V1\ImportController;
|
||||||
@@ -123,6 +124,19 @@ Route::prefix('v1')->name('v1.')->group(static function (): void {
|
|||||||
Route::delete('/reports/{report}', [ReportController::class, 'destroy'])->name('destroy');
|
Route::delete('/reports/{report}', [ReportController::class, 'destroy'])->name('destroy');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Chart routes
|
||||||
|
Route::name('charts.')->prefix('/organizations/{organization}/charts')->group(static function (): void {
|
||||||
|
Route::get('/weekly-project-overview', [ChartController::class, 'weeklyProjectOverview'])->name('weekly-project-overview');
|
||||||
|
Route::get('/latest-tasks', [ChartController::class, 'latestTasks'])->name('latest-tasks');
|
||||||
|
Route::get('/last-seven-days', [ChartController::class, 'lastSevenDays'])->name('last-seven-days');
|
||||||
|
Route::get('/latest-team-activity', [ChartController::class, 'latestTeamActivity'])->name('latest-team-activity');
|
||||||
|
Route::get('/daily-tracked-hours', [ChartController::class, 'dailyTrackedHours'])->name('daily-tracked-hours');
|
||||||
|
Route::get('/total-weekly-time', [ChartController::class, 'totalWeeklyTime'])->name('total-weekly-time');
|
||||||
|
Route::get('/total-weekly-billable-time', [ChartController::class, 'totalWeeklyBillableTime'])->name('total-weekly-billable-time');
|
||||||
|
Route::get('/total-weekly-billable-amount', [ChartController::class, 'totalWeeklyBillableAmount'])->name('total-weekly-billable-amount');
|
||||||
|
Route::get('/weekly-history', [ChartController::class, 'weeklyHistory'])->name('weekly-history');
|
||||||
|
});
|
||||||
|
|
||||||
// Tag routes
|
// Tag routes
|
||||||
Route::name('tags.')->prefix('/organizations/{organization}')->group(static function (): void {
|
Route::name('tags.')->prefix('/organizations/{organization}')->group(static function (): void {
|
||||||
Route::get('/tags', [TagController::class, 'index'])->name('index');
|
Route::get('/tags', [TagController::class, 'index'])->name('index');
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ abstract class TestCaseWithDatabase extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return object{user: User, organization: Organization, member: Member, owner: User, ownerMember: Member}
|
||||||
|
*/
|
||||||
public function createUserWithRole(Role $role): object
|
public function createUserWithRole(Role $role): object
|
||||||
{
|
{
|
||||||
$owner = User::factory()->create();
|
$owner = User::factory()->create();
|
||||||
|
|||||||
303
tests/Unit/Endpoint/Api/V1/ChartEndpointTest.php
Normal file
303
tests/Unit/Endpoint/Api/V1/ChartEndpointTest.php
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Unit\Endpoint\Api\V1;
|
||||||
|
|
||||||
|
use App\Enums\Role;
|
||||||
|
use Laravel\Passport\Passport;
|
||||||
|
use Tests\Unit\Endpoint\Web\EndpointTestAbstract;
|
||||||
|
|
||||||
|
class ChartEndpointTest extends EndpointTestAbstract
|
||||||
|
{
|
||||||
|
public function test_weekly_project_overview_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.weekly-project-overview', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_weekly_project_overview_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:own']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.weekly-project-overview', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_latest_tasks_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.latest-tasks', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_latest_tasks_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:own']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.latest-tasks', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_last_seven_days_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.last-seven-days', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_last_seven_days_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:own']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.last-seven-days', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_latest_team_activity_endpoint_fails_if_user_has_no_permission_to_view_chart_for_the_whole_orgnaization(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.latest-team-activity', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_latest_team_activity_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:all']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.latest-team-activity', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_daily_tracked_hours_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.daily-tracked-hours', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_daily_tracked_hours_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:own']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.daily-tracked-hours', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_total_weekly_time_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.total-weekly-time', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_total_weekly_time_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:own']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.total-weekly-time', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_total_weekly_billable_time_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.total-weekly-billable-time', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_total_weekly_billable_time_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:own']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.total-weekly-billable-time', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_total_weekly_billable_amount_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.total-weekly-billable-amount', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_total_weekly_billable_amount_endpoint_fails_if_the_user_is_an_employee_but_the_organization_does_not_allow_employees_to_view_billable_rates(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithRole(Role::Employee);
|
||||||
|
$organization = $user->organization;
|
||||||
|
$organization->employees_can_see_billable_rates = false;
|
||||||
|
$organization->save();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.total-weekly-billable-amount', [
|
||||||
|
'organization' => $organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_total_weekly_billable_amount_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithRole(Role::Employee);
|
||||||
|
$organization = $user->organization;
|
||||||
|
$organization->employees_can_see_billable_rates = true;
|
||||||
|
$organization->save();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.total-weekly-billable-amount', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_weekly_history_endpoint_fails_if_user_has_no_permission_to_view_chart(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission();
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.weekly-history', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertStatus(403);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_weekly_history_endpoint_returns_chart_data(): void
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
$user = $this->createUserWithPermission(['charts:view:own']);
|
||||||
|
Passport::actingAs($user->user);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
$response = $this->getJson(route('api.v1.charts.weekly-history', [
|
||||||
|
'organization' => $user->organization,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
$response->assertOk();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user