157 lines
5.0 KiB
PHP
157 lines
5.0 KiB
PHP
<?php
|
|
|
|
use App\Enums\WorkoutSource;
|
|
use App\Models\User;
|
|
use App\Models\WorkoutSessions;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Laravel\Sanctum\Sanctum;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
it('creates a workout for the authenticated user', function () {
|
|
$user = User::factory()->create();
|
|
|
|
Sanctum::actingAs($user);
|
|
|
|
$response = $this->postJson('/api/workouts', [
|
|
'external_id' => 'apple-workout-1',
|
|
'source' => WorkoutSource::APPLE_HEALTH->value,
|
|
'type' => 'running',
|
|
'title' => 'Morning run',
|
|
'duration_seconds' => 1800,
|
|
'calories_burned' => 450,
|
|
'distance_meters' => 5200,
|
|
'started_at' => '2026-05-19T07:30:00.000Z',
|
|
]);
|
|
|
|
$response
|
|
->assertCreated()
|
|
->assertJsonPath('data.externalId', 'apple-workout-1')
|
|
->assertJsonPath('data.source', WorkoutSource::APPLE_HEALTH->value)
|
|
->assertJsonPath('data.type', 'running')
|
|
->assertJsonPath('data.title', 'Morning run')
|
|
->assertJsonPath('data.durationSeconds', 1800)
|
|
->assertJsonPath('data.caloriesBurned', 450)
|
|
->assertJsonPath('data.distanceMeters', 5200);
|
|
|
|
$this->assertDatabaseHas('workout_sessions', [
|
|
'id' => $response->json('data.id'),
|
|
'user_id' => $user->id,
|
|
'external_id' => 'apple-workout-1',
|
|
'source' => WorkoutSource::APPLE_HEALTH->value,
|
|
'type' => 'running',
|
|
'title' => 'Morning run',
|
|
'duration_seconds' => 1800,
|
|
'calories_burned' => 450,
|
|
'distance_meters' => 5200,
|
|
]);
|
|
});
|
|
|
|
it('returns workouts for the authenticated user', function () {
|
|
$user = User::factory()->create();
|
|
$otherUser = User::factory()->create();
|
|
|
|
$oldWorkoutSession = WorkoutSessions::factory()->for($user, 'user')->create([
|
|
'external_id' => 'manual-1',
|
|
'source' => WorkoutSource::MANUAL,
|
|
'type' => 'strength',
|
|
'title' => 'Upper body',
|
|
'duration_seconds' => 2400,
|
|
'calories_burned' => 320,
|
|
'distance_meters' => 0,
|
|
'started_at' => '2026-05-18 10:00:00',
|
|
]);
|
|
$latestWorkoutSession = WorkoutSessions::factory()->for($user, 'user')->create([
|
|
'external_id' => 'apple-1',
|
|
'source' => WorkoutSource::APPLE_HEALTH,
|
|
'type' => 'running',
|
|
'title' => 'Morning run',
|
|
'duration_seconds' => 1800,
|
|
'calories_burned' => 450,
|
|
'distance_meters' => 5200,
|
|
'started_at' => '2026-05-19 07:30:00',
|
|
]);
|
|
$otherWorkoutSession = WorkoutSessions::factory()->for($otherUser, 'user')->create([
|
|
'title' => 'Hidden workout',
|
|
'started_at' => '2026-05-20 07:30:00',
|
|
]);
|
|
|
|
Sanctum::actingAs($user);
|
|
|
|
$response = $this->getJson('/api/workouts');
|
|
|
|
$response
|
|
->assertOk()
|
|
->assertJsonCount(2, 'data')
|
|
->assertJsonPath('data.0.id', $latestWorkoutSession->id)
|
|
->assertJsonPath('data.0.externalId', 'apple-1')
|
|
->assertJsonPath('data.0.source', WorkoutSource::APPLE_HEALTH->value)
|
|
->assertJsonPath('data.0.type', 'running')
|
|
->assertJsonPath('data.0.title', 'Morning run')
|
|
->assertJsonPath('data.0.durationSeconds', 1800)
|
|
->assertJsonPath('data.0.caloriesBurned', 450)
|
|
->assertJsonPath('data.0.distanceMeters', 5200)
|
|
->assertJsonPath('data.1.id', $oldWorkoutSession->id)
|
|
->assertJsonMissing([
|
|
'id' => $otherWorkoutSession->id,
|
|
]);
|
|
});
|
|
|
|
it('validates the workouts pagination size', function () {
|
|
Sanctum::actingAs(User::factory()->create());
|
|
|
|
$this
|
|
->getJson('/api/workouts?per_page=101')
|
|
->assertUnprocessable()
|
|
->assertJsonValidationErrors(['per_page']);
|
|
});
|
|
|
|
it('validates workout creation data', function () {
|
|
Sanctum::actingAs(User::factory()->create());
|
|
|
|
$this
|
|
->postJson('/api/workouts', [
|
|
'source' => 'invalid',
|
|
'type' => '',
|
|
'title' => '',
|
|
'duration_seconds' => 0,
|
|
'calories_burned' => -1,
|
|
'distance_meters' => -1,
|
|
'started_at' => 'not-a-date',
|
|
])
|
|
->assertUnprocessable()
|
|
->assertJsonValidationErrors([
|
|
'source',
|
|
'type',
|
|
'title',
|
|
'duration_seconds',
|
|
'calories_burned',
|
|
'distance_meters',
|
|
'started_at',
|
|
]);
|
|
});
|
|
|
|
it('validates workout external ids per source', function () {
|
|
$user = User::factory()->create();
|
|
|
|
WorkoutSessions::factory()->create([
|
|
'external_id' => 'manual-1',
|
|
'source' => WorkoutSource::MANUAL,
|
|
]);
|
|
|
|
Sanctum::actingAs($user);
|
|
|
|
$this
|
|
->postJson('/api/workouts', [
|
|
'external_id' => 'manual-1',
|
|
'source' => WorkoutSource::MANUAL->value,
|
|
'type' => 'running',
|
|
'title' => 'Morning run',
|
|
'duration_seconds' => 1800,
|
|
'calories_burned' => 450,
|
|
'distance_meters' => 5200,
|
|
])
|
|
->assertUnprocessable()
|
|
->assertJsonValidationErrors(['external_id']);
|
|
});
|