Skip to content

Commit

Permalink
Merge pull request #233 from art-institute-of-chicago/feature/feature…
Browse files Browse the repository at this point in the history
…d-tours-json

Add featured tours to JSON
  • Loading branch information
zachgarwood authored Nov 10, 2023
2 parents c3d9793 + 1d81da2 commit c6bf981
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 3 deletions.
16 changes: 16 additions & 0 deletions app/Models/Transformers/FeaturedTourTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace App\Models\Transformers;

use A17\Twill\Models\Contracts\TwillModelContract;
use League\Fractal\TransformerAbstract;

class FeaturedTourTransformer extends TransformerAbstract
{
public function transform(TwillModelContract $tour)
{
return [
(string) $tour->id,
];
}
}
23 changes: 23 additions & 0 deletions app/Repositories/Serializers/DashboardSerializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Repositories\Serializers;

/**
* Due to legacy constraints, the dashboard serializer is essentially a wrapper
* around the featured tour serializer with an additional unused
* `featured_exhibitions` key.
*/
class DashboardSerializer
{
public function serialize($featuredTours)
{
$featuredTourSerializer = new FeaturedTourSerializer();
return [
'dashboard' =>
array_merge(
$featuredTourSerializer->serialize($featuredTours),
['featured_exhibitions' => []], // Legacy from Drupal
)
];
}
}
25 changes: 25 additions & 0 deletions app/Repositories/Serializers/FeaturedTourSerializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Repositories\Serializers;

use App\Models\Transformers\FeaturedTourTransformer;
use League\Fractal\Manager;
use League\Fractal\Resource;

class FeaturedTourSerializer
{
protected ?Manager $manager = null;

public function __construct()
{
$this->manager = new Manager();
$this->manager->setSerializer(new FlatArraySerializer());
}

public function serialize($tours)
{
$tours = collect($tours)->sortBy('position');
$resource = new Resource\Collection($tours, new FeaturedTourTransformer(), 'featured_tours');
return $this->manager->createData($resource)->toArray();
}
}
13 changes: 13 additions & 0 deletions app/Repositories/Serializers/FlatArraySerializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Repositories\Serializers;

use League\Fractal\Serializer\ArraySerializer;

class FlatArraySerializer extends ArraySerializer
{
public function collection($resourceKey, array $data): array
{
return [$resourceKey => collect($data)->flatten()];
}
}
5 changes: 3 additions & 2 deletions database/factories/TourFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ public function definition(): array
{
return [
'active' => true, // Simulates an active translation
'title' => fake()->words(5, asText: true),
'description' => fake()->words(100, asText: true),
'intro' => fake()->words(100, asText: true),
'duration' => fake()->numberBetween(10, 60),
'featured' => fake()->boolean(),
'intro' => fake()->words(100, asText: true),
'position' => fake()->unique()->numberBetween(0, 20),
'published' => fake()->boolean(),
'title' => fake()->words(5, asText: true),
];
}
}
10 changes: 9 additions & 1 deletion routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
use App\Repositories\Api\GalleryRepository;
use App\Repositories\Api\SoundRepository;
use App\Repositories\Serializers\AudioSerializer;
use App\Repositories\TourRepository;
use App\Repositories\Serializers\DashboardSerializer;
use App\Repositories\Serializers\GallerySerializer;
use App\Repositories\Serializers\ObjectSerializer;
use App\Repositories\Serializers\TourSerializer;
use App\Repositories\TourRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Route;
Expand All @@ -33,6 +34,13 @@
return $serializer->serialize($audios);
});

Route::get('/dashboard', function () {
$tourRepository = App::make(TourRepository::class);
$featuredTours = $tourRepository->getBaseModel()->newQuery()->visible()->published()->featured()->get();
$dashboardSerializer = new DashboardSerializer();
return $dashboardSerializer->serialize($featuredTours);
});

Route::get('/galleries', function () {
$repository = App::make(GalleryRepository::class);
$galleries = $repository->getBaseModel()->newQuery()->get();
Expand Down
26 changes: 26 additions & 0 deletions tests/Feature/DashboardSerializerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Tests\Feature;

use App\Models\Tour;
use App\Repositories\Serializers\DashboardSerializer;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class DashboardSerializerTest extends TestCase
{
use RefreshDatabase;

public function test_serialize(): void
{
$serializer = new DashboardSerializer();
$featuredTours = Tour::factory(['featured' => true])->count(2)->create();
$serialized = $serializer->serialize($featuredTours);

$this->assertArrayHasKey('dashboard', $serialized);
$this->assertArrayHasKey('featured_tours', $serialized['dashboard']);
$this->assertNotEmpty($serialized['dashboard']['featured_tours']);
$this->assertArrayHasKey('featured_exhibitions', $serialized['dashboard']);
$this->assertEmpty($serialized['dashboard']['featured_exhibitions']);
}
}
29 changes: 29 additions & 0 deletions tests/Feature/FeaturedTourSerializerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Tests\Feature;

use App\Models\Tour;
use App\Repositories\Serializers\FeaturedTourSerializer;
use Illuminate\Database\Eloquent\Factories\Sequence;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class FeaturedTourSerializerTest extends TestCase
{
use RefreshDatabase;

public function test_serialize(): void
{
$serializer = new FeaturedTourSerializer();
Tour::factory()->count(3)->sequence(['featured' => true], ['featured' => false])->create();
$featuredTours = Tour::featured()->get();
$serialized = $serializer->serialize($featuredTours);

$this->assertArrayHasKey('featured_tours', $serialized);
$this->assertCount($featuredTours->count(), $serialized['featured_tours']);
foreach ($serialized['featured_tours'] as $id) {
$this->assertIsString($id);
$this->assertContains((int) $id, $featuredTours->pluck('id'));
}
}
}
43 changes: 43 additions & 0 deletions tests/Unit/FlatArraySerializerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Tests\Unit;

use App\Repositories\Serializers\FlatArraySerializer;
use PHPUnit\Framework\TestCase;

class FlatArraySerializerTest extends TestCase
{
public function test_collection_returns_a_flattened_array(): void
{
$data = [
[
[
'123',
],
],
[
[
'456',
],
],
[
[
'789',
],
],
];
$serializer = new FlatArraySerializer();
$collection = $serializer->collection('test', $data);
$this->assertArrayHasKey('test', $collection, 'The collection is serialized with the correct key');
foreach ($data as $datum) {
foreach ($datum as $record) {
$id = current($record);
$this->assertContains(
$id,
$collection['test'],
'The serialized collection is flattened array of ids',
);
}
}
}
}

0 comments on commit c6bf981

Please sign in to comment.