Skip to content

Commit

Permalink
[BREAKING] Fix empty param bag (#82)
Browse files Browse the repository at this point in the history
* fix: empty param bag

* test: access scope in transformer

this test demonstrates that scopes can be accessed in the transformers
  • Loading branch information
Mohammad-Alavi authored Jan 20, 2025
1 parent 4b54563 commit 6469bf6
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/Fractal.php
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ public function createData()
$this->manager->parseFieldsets($this->fieldsets);
}

return $this->manager->createData($this->getResource(), $this->resourceName);
return $this->manager->createData($this->getResource());
}

/**
Expand Down
14 changes: 14 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Spatie\Fractalistic\Fractal;
use Spatie\Fractalistic\Test\TestClasses\Author;
use Spatie\Fractalistic\Test\TestClasses\Book;
use Spatie\Fractalistic\Test\TestClasses\Character;
use Spatie\Fractalistic\Test\TestClasses\Publisher;

uses()
Expand Down Expand Up @@ -56,6 +57,11 @@ function getTestPublishers(): array
$authorA = new Author('Philip K Dick', '[email protected]');
$authorB = new Author('George R. R. Satan', '[email protected]');

$charA = new Character('Death');
$charB = new Character('Hex');
$charC = new Character('Ned Stark');
$charD = new Character('Tywin Lannister');

$bookA = new Book(
'1',
'Hogfather',
Expand All @@ -78,11 +84,19 @@ function getTestPublishers(): array

$bookA->author = $authorA;
$bookA->publisher = $publisherA;
$bookA->characters = [$charA, $charB];
$authorA->characters = [$charA, $charB];
$charA->book = $bookA;
$charB->book = $bookA;
$publisherA->books = [$bookA];
$authorA->books = [$bookA];

$bookB->author = $authorB;
$bookB->publisher = $publisherB;
$bookB->characters = [$charC, $charD];
$authorB->characters = [$charC, $charD];
$charC->book = $bookB;
$charD->book = $bookB;
$publisherB->books = [$bookB];
$authorB->books = [$bookB];

Expand Down
171 changes: 163 additions & 8 deletions tests/ScopeTest.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,168 @@
<?php

use Spatie\Fractalistic\Test\TestClasses\TestTransformer;
use function PHPUnit\Framework\assertEquals;
use League\Fractal\ParamBag;
use Spatie\Fractalistic\Fractal;
use Spatie\Fractalistic\Test\TestClasses\PublisherTransformer;

it('uses an identifier for the scope', function () {
$scope = $this->fractal
->collection($this->testBooks, new TestTransformer(), 'books')
->parseIncludes('characters')
->createData();
it('can parse include parameters', function ($resourceName, string $include, string $includeWithParams, ParamBag $expected): void {
$fractal = Fractal::create(getTestPublishers(), new PublisherTransformer())
->withResourceName($resourceName)
->parseIncludes($includeWithParams);

assertEquals('books', $scope->getIdentifier());
$scope = $fractal->createData();

$identifier = $scope->getIdentifier($include);
$actualParams = $scope->getManager()->getIncludeParams($identifier);
expect($actualParams)->toEqual($expected);
})->with([
[
'resource name: string' => 'Publisher',
],
[
'resource name: null' => null,
],
])->with([
[
'include' => 'books',
'include_with_params' => 'books:test(2|value)',
'expected' => new ParamBag([
'test' => ['2', 'value'],
]),
],
[
'include' => 'books',
'include_with_params' => 'books:test(another_value|3):another(1|2|3)',
'expected' => new ParamBag([
'test' => ['another_value', '3'],
'another' => ['1', '2', '3'],
]),
],
[
'include' => 'books.author',
'include_with_params' => 'books.author:test(test|value)',
'expected' => new ParamBag([
'test' => ['test', 'value'],
]),
],
]);

it('can access scope in transformer', function (): void {
$fractal = Fractal::create(getTestPublishers(), new PublisherTransformer())
->parseIncludes('books.characters,books.author.characters');

$result = $fractal->toArray();

expect($result)->toEqual([
'data' => [
[
'name' => 'Elephant books',
'address' => 'Amazon rainforests, near the river',
'books' =>
[
'data' => [
[
'id' => 1,
'title' => 'Hogfather',
'characters' => [
'data' => [
[
'name' => 'Death',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
[
'name' => 'Hex',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
]
],
'author' => [
'data' => [
'name' => 'Philip K Dick',
'email' => '[email protected]',
'characters' => [
'data' => [
[
'name' => 'Death',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
[
'name' => 'Hex',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
]
],
]
],
],
],
],
],
[
'name' => 'Bloody Fantasy inc.',
'address' => 'Diagon Alley, before the bank, to the left',
'books' => [
'data' => [
[
'id' => 2,
'title' => 'Game Of Kill Everyone',
'characters' => [
'data' => [
[
'name' => 'Ned Stark',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
[
'name' => 'Tywin Lannister',
'current_scope' => 'characters',
'parent_scope' => 'books',
'scope_identifier' => 'books.characters',
'called_by_book' => 'yes!',
],
]
],
'author' => [
'data' => [
'name' => 'George R. R. Satan',
'email' => '[email protected]',
'characters' => [
'data' => [
[
'name' => 'Ned Stark',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
[
'name' => 'Tywin Lannister',
'current_scope' => 'characters',
'parent_scope' => 'author',
'scope_identifier' => 'books.author.characters',
'called_by_author' => 'indeed!',
],
]
],
],
]
],
],
],
],
],
]);
});
7 changes: 7 additions & 0 deletions tests/TestClasses/Author.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Author
public string $email;
/** @var Book[] */
public ?array $books = [];
/** @var Character[] */
public array $characters = [];

public function __construct(string $name, string $email)
{
Expand All @@ -19,4 +21,9 @@ public function books(): array
{
return $this->books;
}

public function characters(): array
{
return $this->characters;
}
}
6 changes: 6 additions & 0 deletions tests/TestClasses/AuthorTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AuthorTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'books',
'characters'
];

public function transform(Author $author): array
Expand All @@ -23,4 +24,9 @@ public function includeBooks(Author $author): Collection
{
return $this->collection($author->books(), new BookTransformer());
}

public function includeCharacters(Author $author): Collection
{
return $this->collection($author->characters(), new CharacterTransformer());
}
}
10 changes: 10 additions & 0 deletions tests/TestClasses/Book.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class Book
public string $id;
public string $title;
public string $yr;
/** @var Character[] */
public array $characters = [];
public ?Publisher $publisher = null;
public ?Author $author = null;

Expand All @@ -25,6 +27,14 @@ public function publisher(): ?Publisher
return $this->publisher;
}

/**
* @return Character[]
*/
public function characters(): array
{
return $this->characters;
}

public function author(): ?Author
{
return $this->author;
Expand Down
7 changes: 7 additions & 0 deletions tests/TestClasses/BookTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

namespace Spatie\Fractalistic\Test\TestClasses;

use League\Fractal\Resource\Collection;
use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;

class BookTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'publisher',
'characters',
'author',
];

Expand All @@ -25,6 +27,11 @@ public function includePublisher(Book $book): Item
return $this->item($book->publisher(), new PublisherTransformer());
}

public function includeCharacters(Book $book): Collection
{
return $this->collection($book->characters(), new CharacterTransformer());
}

public function includeAuthor(Book $book): Item
{
return $this->item($book->author(), new AuthorTransformer());
Expand Down
19 changes: 19 additions & 0 deletions tests/TestClasses/Character.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Spatie\Fractalistic\Test\TestClasses;

class Character
{
public string $name;
public ?Book $book = null;

public function __construct(string $name)
{
$this->name = $name;
}

public function book(): ?Book
{
return $this->book;
}
}
40 changes: 40 additions & 0 deletions tests/TestClasses/CharacterTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Spatie\Fractalistic\Test\TestClasses;

use League\Fractal\Resource\Item;
use League\Fractal\TransformerAbstract;

final class CharacterTransformer extends TransformerAbstract
{
protected array $availableIncludes = [
'book',
'author',
];

public function transform(Character $character): array
{
$parentScope = last($this->getCurrentScope()->getParentScopes());
$data = [
'name' => $character->name,
'current_scope' => $this->getCurrentScope()->getScopeIdentifier(),
'parent_scope' => $parentScope,
'scope_identifier' => $this->getCurrentScope()->getIdentifier(),
];

if ($parentScope === 'author') {
$data['called_by_author'] = 'indeed!';
}

if ($parentScope === 'books') {
$data['called_by_book'] = 'yes!';
}

return $data;
}

public function includeBook(Character $character): Item
{
return $this->item($character->book(), new BookTransformer());
}
}

0 comments on commit 6469bf6

Please sign in to comment.