Skip to content

Commit 6d02e20

Browse files
committed
test: relation
1 parent 4f421f7 commit 6d02e20

File tree

3 files changed

+144
-2
lines changed

3 files changed

+144
-2
lines changed

src/Descriptors/Relations/Relation.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,37 @@ public function whenIncluded(): static
6363
return $this;
6464
}
6565

66+
/**
67+
* @see \Illuminate\Http\Resources\ConditionallyLoadsAttributes::whenLoaded
68+
*
69+
* @param string|null $relation
70+
*
71+
* @return $this
72+
*/
6673
public function whenLoaded(string $relation = null): static
6774
{
6875
return $this->when(fn(
6976
Request $request,
7077
Model $model,
7178
string $attribute
72-
): bool => $model->relationLoaded($relation ?? $this->relation ?? $attribute));
79+
): bool => $model->relationLoaded($relation ?? (is_string($this->relation) ? $this->relation : $attribute)));
7380
}
7481

82+
/**
83+
* @see \Illuminate\Http\Resources\ConditionallyLoadsAttributes::whenPivotLoadedAs
84+
*
85+
* @param string $table
86+
* @param string|null $accessor
87+
*
88+
* @return $this
89+
*/
7590
public function whenPivotLoaded(string $table, string $accessor = null): static
7691
{
7792
return $this->when(fn(
7893
Request $request,
7994
Model $model,
8095
string $attribute
81-
): bool => ($pivot = $model->{$accessor ?? $this->relation ?? $attribute})
96+
): bool => ($pivot = $model->{$accessor ?? (is_string($this->relation) ? $this->relation : $attribute)})
8297
&& (
8398
$pivot instanceof $table ||
8499
$pivot->getTable() === $table

tests/Support/Reflect.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,13 @@ public static function set($object, string $property, $value)
2323

2424
$reflectProperty->setValue($object, $value);
2525
}
26+
27+
public static function get($object, string $property): mixed
28+
{
29+
$reflect = new ReflectionClass($object);
30+
$reflectProperty = $reflect->getProperty($property);
31+
$reflectProperty->setAccessible(true);
32+
33+
return $reflectProperty->getValue($object);
34+
}
2635
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
namespace Test\Unit\Descriptors;
4+
5+
use Ark4ne\JsonApi\Descriptors\Relations\RelationOne;
6+
use Ark4ne\JsonApi\Resources\Relationship;
7+
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Http\Request;
9+
use Illuminate\Http\Resources\MissingValue;
10+
use stdClass;
11+
use Test\app\Http\Resources\UserResource;
12+
use Test\Support\Reflect;
13+
use Test\TestCase;
14+
15+
class RelationTest extends TestCase
16+
{
17+
public function testIncluded()
18+
{
19+
$stub = new RelationOne(UserResource::class, fn() => null);
20+
21+
$relation = $stub->resolveFor(new Request, new class extends Model {
22+
}, 'null');
23+
24+
$this->assertInstanceOf(Relationship::class, $relation);
25+
$this->assertFalse(Reflect::get($relation, 'whenIncluded'));
26+
27+
$stub->whenIncluded();
28+
$relation = $stub->resolveFor(new Request, new class extends Model {
29+
}, 'null');
30+
31+
$this->assertInstanceOf(Relationship::class, $relation);
32+
$this->assertTrue(Reflect::get($relation, 'whenIncluded'));
33+
}
34+
35+
public function testMeta()
36+
{
37+
$stub = new RelationOne(UserResource::class, fn() => null);
38+
39+
$relation = $stub->resolveFor(new Request, new class extends Model {
40+
}, 'null');
41+
42+
$this->assertInstanceOf(Relationship::class, $relation);
43+
$this->assertEmpty(Reflect::get($relation, 'meta'));
44+
45+
$stub->meta(fn() => ['test']);
46+
$relation = $stub->resolveFor(new Request, new class extends Model {
47+
}, 'null');
48+
49+
$this->assertInstanceOf(Relationship::class, $relation);
50+
$this->assertInstanceOf(\Closure::class, Reflect::get($relation, 'meta'));
51+
$this->assertEquals(['test'], Reflect::get($relation, 'meta')());
52+
}
53+
54+
public function testLinks()
55+
{
56+
$stub = new RelationOne(UserResource::class, fn() => null);
57+
58+
$relation = $stub->resolveFor(new Request, new class extends Model {
59+
}, 'null');
60+
61+
$this->assertInstanceOf(Relationship::class, $relation);
62+
$this->assertEmpty(Reflect::get($relation, 'links'));
63+
64+
$stub->links(fn() => ['test']);
65+
$relation = $stub->resolveFor(new Request, new class extends Model {
66+
}, 'null');
67+
68+
$this->assertInstanceOf(Relationship::class, $relation);
69+
$this->assertInstanceOf(\Closure::class, Reflect::get($relation, 'links'));
70+
$this->assertEquals(['test'], Reflect::get($relation, 'links')());
71+
}
72+
73+
public function dataWhenLoaded() {
74+
return [
75+
['attr', null, 'attr'],
76+
['attr', fn() => null, 'attr'],
77+
['field', 'field', 'attr'],
78+
];
79+
}
80+
81+
/**
82+
* @dataProvider dataWhenLoaded
83+
*/
84+
public function testWhenLoaded($expectedAttr, $relation, $invokedAttr)
85+
{
86+
$mockModel = $this->getMockForAbstractClass(Model::class, mockedMethods: ['relationLoaded']);
87+
$mockModel->expects(self::once())->method('relationLoaded')->with($expectedAttr)->willReturn(false);
88+
89+
$stub = new RelationOne(UserResource::class, $relation);
90+
$stub->whenLoaded();
91+
92+
$check = Reflect::invoke($stub, 'check', new Request, $mockModel, $invokedAttr);
93+
$this->assertFalse($check);
94+
}
95+
96+
public function dataWhenPivotLoaded() {
97+
return [
98+
['attr', null, 'attr'],
99+
['attr', fn() => null, 'attr'],
100+
['field', 'field', 'attr'],
101+
];
102+
}
103+
104+
/**
105+
* @dataProvider dataWhenPivotLoaded
106+
*/
107+
public function testWhenPivotLoaded($expectedAttr, $relation, $invokedAttr)
108+
{
109+
$model = new class extends Model {};
110+
111+
$model->$expectedAttr = new stdClass;
112+
$stub = new RelationOne(UserResource::class, $relation);
113+
$stub->whenPivotLoaded(stdClass::class);
114+
115+
$check = Reflect::invoke($stub, 'check', new Request, $model, $invokedAttr);
116+
$this->assertTrue($check);
117+
}
118+
}

0 commit comments

Comments
 (0)