Skip to content

Commit

Permalink
Added endpoint for current time entry
Browse files Browse the repository at this point in the history
  • Loading branch information
korridor committed Apr 3, 2024
1 parent fc6cc2b commit 7cbfe53
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
50 changes: 50 additions & 0 deletions app/Http/Controllers/Api/V1/UserTimeEntryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\V1;

use App\Http\Resources\V1\TimeEntry\TimeEntryResource;
use App\Models\Organization;
use App\Models\TimeEntry;
use App\Models\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;

class UserTimeEntryController extends Controller
{
/**
* Get the active time entry of the current user
*
* This endpoint is independent of organization.
*
* @operationId getMyActiveTimeEntry
*/
public function myActive(): JsonResource
{
/** @var User $user */
$user = Auth::user();

$activeTimeEntriesOfUser = TimeEntry::query()
->whereBelongsTo($user, 'user')
->whereNull('end')
->orderBy('start', 'desc')
->get();

if ($activeTimeEntriesOfUser->count() > 1) {
Log::warning('User has more than one active time entry.', [
'user' => $user->getKey(),
]);
}

$activeTimeEntry = $activeTimeEntriesOfUser->first();

if ($activeTimeEntry !== null) {
return new TimeEntryResource($activeTimeEntry);
} else {
throw new ModelNotFoundException('No active time entry');
}
}
}
5 changes: 5 additions & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use App\Http\Controllers\Api\V1\TagController;
use App\Http\Controllers\Api\V1\TaskController;
use App\Http\Controllers\Api\V1\TimeEntryController;
use App\Http\Controllers\Api\V1\UserTimeEntryController;
use Illuminate\Support\Facades\Route;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

Expand Down Expand Up @@ -63,6 +64,10 @@
Route::delete('/organizations/{organization}/time-entries/{timeEntry}', [TimeEntryController::class, 'destroy'])->name('destroy');
});

Route::name('users.time-entries.')->group(static function () {
Route::get('/users/me/time-entries/active', [UserTimeEntryController::class, 'myActive'])->name('my-active');
});

// Tag routes
Route::name('tags.')->group(static function () {
Route::get('/organizations/{organization}/tags', [TagController::class, 'index'])->name('index');
Expand Down
55 changes: 55 additions & 0 deletions tests/Unit/Endpoint/Api/V1/UserTimeEntryEndpointTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace Tests\Unit\Endpoint\Api\V1;

use App\Models\TimeEntry;
use Laravel\Passport\Passport;

class UserTimeEntryEndpointTest extends ApiEndpointTestAbstract
{
public function test_my_active_endpoint_returns_unauthorized_if_user_is_not_logged_in(): void
{
// Arrange
$data = $this->createUserWithPermission([
]);

// Act
$response = $this->getJson(route('api.v1.users.time-entries.my-active'));

// Assert
$response->assertUnauthorized();
}

public function test_my_active_endpoint_returns_current_time_entry_of_logged_in_user(): void
{
// Arrange
$data = $this->createUserWithPermission([
]);
$activeTimeEntry = TimeEntry::factory()->forUser($data->user)->active()->create();
$inactiveTimeEntry = TimeEntry::factory()->forUser($data->user)->create();
Passport::actingAs($data->user);

// Act
$response = $this->getJson(route('api.v1.users.time-entries.my-active'));

// Assert
$response->assertSuccessful();
}

public function test_my_active_endpoint_returns_not_found_if_user_has_no_active_time_entry(): void
{
// Arrange
$data = $this->createUserWithPermission([
]);
$inactiveTimeEntry = TimeEntry::factory()->forUser($data->user)->create();
Passport::actingAs($data->user);

// Act
$response = $this->getJson(route('api.v1.users.time-entries.my-active'));

// Assert
$response->assertNotFound();
}
}

0 comments on commit 7cbfe53

Please sign in to comment.