Skip to content
23 changes: 23 additions & 0 deletions app/Http/Controllers/PoliciesController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Http\Controllers;

use App\Http\Resources\PoliciesCollection;
use App\Policy;
use Carbon\CarbonImmutable;

class PoliciesController extends Controller {
public function getCurrentPolicies(): PoliciesCollection {
$now = CarbonImmutable::now();

// This works based on the assumption that the latest policy has the highest id given that id is AUTO_INCREMENT
$latestPolicyIds = Policy::where('active_from', '<', $now)
->selectRaw('MAX(id) as id')
->groupBy('policy_type')
->pluck('id');

$currentPolicies = Policy::whereIn('id', $latestPolicyIds)->get();

return new PoliciesCollection($currentPolicies);
}
}
20 changes: 20 additions & 0 deletions app/Http/Resources/PoliciesCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Support\Collection;

class PoliciesCollection extends ResourceCollection {
public static $wrap = null;

/**
* Transform the resource collection into an array.
*/
public function toArray(Request $request): array {
return ['items' => $this->collection->map(function ($policy) {
return new PolicyResource($policy);
}), ];
}
}
23 changes: 23 additions & 0 deletions app/Http/Resources/PolicyResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class PolicyResource extends JsonResource {
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array {
return ['metadata' => [
'policy_id' => $this->id,
'type' => $this->type,
'active_from' => $this->active_from,
'content_vue_file' => $this->content_vue_file,
],
];
}
}
4 changes: 4 additions & 0 deletions app/Policy.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Carbon\CarbonImmutable;
use Eloquent;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

/**
Expand All @@ -24,10 +25,13 @@
* @method static Builder<static>|Policy whereId($value)
* @method static Builder<static>|Policy wherePolicyType($value)
* @method static Builder<static>|Policy whereUpdatedAt($value)
* @method static \Database\Factories\PolicyFactory factory(...$parameters)
*
* @mixin Eloquent
*/
class Policy extends Model {
use HasFactory;

// define which attributes are mass assignable
protected $fillable = [
'policy_type',
Expand Down
26 changes: 26 additions & 0 deletions database/factories/PolicyFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Database\Factories;

use App\Policy;
use Illuminate\Database\Eloquent\Factories\Factory;

/**
* @extends Factory<Policy>
*/
class PolicyFactory extends Factory {
protected $model = Policy::class;

/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array {
return [
'policy_type' => $this->faker->randomElement(['terms-of-use', 'hosting-policy']),
'active_from' => now(),
'content_vue_file' => fake()->slug() . '.vue',
];
}
}
1 change: 1 addition & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
$router->post('user/resetPassword', ['uses' => 'Auth\ResetPasswordController@reset']);
$router->post('contact/sendMessage', ['uses' => 'ContactController@sendMessage']);
$router->post('complaint/sendMessage', ['uses' => 'ComplaintController@sendMessage']);
$router->get('v1/policies/current', ['uses' => 'PoliciesController@getCurrentPolicies']);

$router->post('auth/login', ['uses' => 'Auth\LoginController@postLogin'])->name('login');
// Authed
Expand Down
61 changes: 61 additions & 0 deletions tests/Http/Controllers/PoliciesControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Tests\Http\Controllers;

use App\Policy;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\TestCase;

class PoliciesControllerTest extends TestCase {
use DatabaseTransactions;

public function testGetCurrentPolicies(): void {
$currentTime = now();
// Future policy
Policy::factory()->create([
'policy_type' => 'terms-of-use',
'active_from' => $currentTime->addDay(),
]);
// Old policy
Policy::factory()->create([
'policy_type' => 'hosting-policy',
'active_from' => $currentTime->subMonth(),
]);
// Active policies
$latestActiveToUPolicy = Policy::factory()->create([
'policy_type' => 'terms-of-use',
'active_from' => $currentTime->subMonth(),
]);
$latestActiveHostingPolicy = Policy::factory()->create([
'policy_type' => 'hosting-policy',
'active_from' => $currentTime->subWeek(),
]);

$response = $this->getJson('/v1/policies/current');

$response->assertOk();

$response->assertJsonStructure([
'items' => [
'*' => [
'metadata' => [
'policy_id',
'active_from',
'content_vue_file',
'type',
],

],
],
]);

$response->assertJsonFragment([
'policy_id' => $latestActiveToUPolicy->id,
'active_from' => $latestActiveToUPolicy->active_from,
]);
$response->assertJsonFragment([
'policy_id' => $latestActiveHostingPolicy->id,
'active_from' => $latestActiveHostingPolicy->active_from,
]);
}
}
Loading