Skip to content

Commit 6fc5b45

Browse files
test: add unit tests for StatefullyLoadsAttributes methods
1 parent 4b6733c commit 6fc5b45

File tree

1 file changed

+356
-0
lines changed

1 file changed

+356
-0
lines changed
Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
<?php
2+
3+
use Farbcode\StatefulResources\Concerns\StatefullyLoadsAttributes;
4+
use Farbcode\StatefulResources\Enums\State;
5+
use Illuminate\Http\Request;
6+
use Illuminate\Http\Resources\Json\JsonResource;
7+
use Illuminate\Http\Resources\MergeValue;
8+
use Illuminate\Http\Resources\MissingValue;
9+
10+
/**
11+
* Test resource class that uses the StatefullyLoadsAttributes trait
12+
*/
13+
class TestStatefulResource extends JsonResource
14+
{
15+
use StatefullyLoadsAttributes;
16+
17+
private string $state;
18+
19+
public function __construct($resource, string $state = 'default')
20+
{
21+
parent::__construct($resource);
22+
$this->state = $state;
23+
}
24+
25+
protected function getState(): string
26+
{
27+
return $this->state;
28+
}
29+
30+
public function toArray(Request $request): array
31+
{
32+
return ['id' => $this->id];
33+
}
34+
35+
// Expose protected methods for testing
36+
public function testWhenState($state, $value, $default = null)
37+
{
38+
return func_num_args() === 3
39+
? $this->whenState($state, $value, $default)
40+
: $this->whenState($state, $value);
41+
}
42+
43+
public function testUnlessState($state, $value, $default = null)
44+
{
45+
return func_num_args() === 3
46+
? $this->unlessState($state, $value, $default)
47+
: $this->unlessState($state, $value);
48+
}
49+
50+
public function testWhenStateIn(array $states, $value, $default = null)
51+
{
52+
return func_num_args() === 3
53+
? $this->whenStateIn($states, $value, $default)
54+
: $this->whenStateIn($states, $value);
55+
}
56+
57+
public function testUnlessStateIn(array $states, $value, $default = null)
58+
{
59+
return func_num_args() === 3
60+
? $this->unlessStateIn($states, $value, $default)
61+
: $this->unlessStateIn($states, $value);
62+
}
63+
64+
public function testMergeWhenState($state, $value, $default = null)
65+
{
66+
return func_num_args() === 3
67+
? $this->mergeWhenState($state, $value, $default)
68+
: $this->mergeWhenState($state, $value);
69+
}
70+
71+
public function testMergeUnlessState($state, $value, $default = null)
72+
{
73+
return func_num_args() === 3
74+
? $this->mergeUnlessState($state, $value, $default)
75+
: $this->mergeUnlessState($state, $value);
76+
}
77+
78+
public function testMergeWhenStateIn(array $states, $value, $default = null)
79+
{
80+
return func_num_args() === 3
81+
? $this->mergeWhenStateIn($states, $value, $default)
82+
: $this->mergeWhenStateIn($states, $value);
83+
}
84+
85+
public function testMergeUnlessStateIn(array $states, $value, $default = null)
86+
{
87+
return func_num_args() === 3
88+
? $this->mergeUnlessStateIn($states, $value, $default)
89+
: $this->mergeUnlessStateIn($states, $value);
90+
}
91+
}
92+
93+
beforeEach(function () {
94+
$this->resource = new TestStatefulResource((object) ['id' => 1], 'full');
95+
});
96+
97+
describe('whenState', function () {
98+
test('returns value when state matches', function () {
99+
$result = $this->resource->testWhenState('full', 'test_value');
100+
expect($result)->toBe('test_value');
101+
});
102+
103+
test('returns MissingValue when state does not match', function () {
104+
$result = $this->resource->testWhenState('table', 'test_value');
105+
expect($result)->toBeInstanceOf(MissingValue::class);
106+
});
107+
108+
test('returns default when state does not match and default is provided', function () {
109+
$result = $this->resource->testWhenState('table', 'test_value', 'default_value');
110+
expect($result)->toBe('default_value');
111+
});
112+
113+
test('works with State enum', function () {
114+
$result = $this->resource->testWhenState(State::Full, 'test_value');
115+
expect($result)->toBe('test_value');
116+
});
117+
});
118+
119+
describe('unlessState', function () {
120+
test('returns MissingValue when state matches', function () {
121+
$result = $this->resource->testUnlessState('full', 'test_value');
122+
expect($result)->toBeInstanceOf(MissingValue::class);
123+
});
124+
125+
test('returns value when state does not match', function () {
126+
$result = $this->resource->testUnlessState('table', 'test_value');
127+
expect($result)->toBe('test_value');
128+
});
129+
130+
test('returns default when state matches and default is provided', function () {
131+
$result = $this->resource->testUnlessState('full', 'test_value', 'default_value');
132+
expect($result)->toBe('default_value');
133+
});
134+
135+
test('works with State enum', function () {
136+
$result = $this->resource->testUnlessState(State::Table, 'test_value');
137+
expect($result)->toBe('test_value');
138+
});
139+
});
140+
141+
describe('whenStateIn', function () {
142+
test('returns value when current state is in the array', function () {
143+
$result = $this->resource->testWhenStateIn(['full', 'table'], 'test_value');
144+
expect($result)->toBe('test_value');
145+
});
146+
147+
test('returns MissingValue when current state is not in the array', function () {
148+
$result = $this->resource->testWhenStateIn(['table', 'minimal'], 'test_value');
149+
expect($result)->toBeInstanceOf(MissingValue::class);
150+
});
151+
152+
test('returns default when current state is not in array and default is provided', function () {
153+
$result = $this->resource->testWhenStateIn(['table', 'minimal'], 'test_value', 'default_value');
154+
expect($result)->toBe('default_value');
155+
});
156+
157+
test('works with State enums in array', function () {
158+
$result = $this->resource->testWhenStateIn([State::Full, State::Table], 'test_value');
159+
expect($result)->toBe('test_value');
160+
});
161+
162+
test('works with mixed string and enum states', function () {
163+
$result = $this->resource->testWhenStateIn([State::Table, 'full'], 'test_value');
164+
expect($result)->toBe('test_value');
165+
});
166+
});
167+
168+
describe('unlessStateIn', function () {
169+
test('returns MissingValue when current state is in the array', function () {
170+
$result = $this->resource->testUnlessStateIn(['full', 'table'], 'test_value');
171+
expect($result)->toBeInstanceOf(MissingValue::class);
172+
});
173+
174+
test('returns value when current state is not in the array', function () {
175+
$result = $this->resource->testUnlessStateIn(['table', 'minimal'], 'test_value');
176+
expect($result)->toBe('test_value');
177+
});
178+
179+
test('returns default when current state is in array and default is provided', function () {
180+
$result = $this->resource->testUnlessStateIn(['full', 'table'], 'test_value', 'default_value');
181+
expect($result)->toBe('default_value');
182+
});
183+
184+
test('works with State enums in array', function () {
185+
$result = $this->resource->testUnlessStateIn([State::Table, State::Minimal], 'test_value');
186+
expect($result)->toBe('test_value');
187+
});
188+
});
189+
190+
describe('mergeWhenState', function () {
191+
test('returns MergeValue when state matches', function () {
192+
$result = $this->resource->testMergeWhenState('full', ['key' => 'value']);
193+
expect($result)->toBeInstanceOf(MergeValue::class);
194+
});
195+
196+
test('returns MissingValue when state does not match', function () {
197+
$result = $this->resource->testMergeWhenState('table', ['key' => 'value']);
198+
expect($result)->toBeInstanceOf(MissingValue::class);
199+
});
200+
201+
test('returns default when state does not match and default is provided', function () {
202+
$result = $this->resource->testMergeWhenState('table', ['key' => 'value'], 'default_value');
203+
expect($result)->toBeInstanceOf(MergeValue::class);
204+
expect($result->data)->toBe('default_value');
205+
});
206+
207+
test('works with State enum', function () {
208+
$result = $this->resource->testMergeWhenState(State::Full, ['key' => 'value']);
209+
expect($result)->toBeInstanceOf(MergeValue::class);
210+
});
211+
});
212+
213+
describe('mergeUnlessState', function () {
214+
test('returns MissingValue when state matches', function () {
215+
$result = $this->resource->testMergeUnlessState('full', ['key' => 'value']);
216+
expect($result)->toBeInstanceOf(MissingValue::class);
217+
});
218+
219+
test('returns MergeValue when state does not match', function () {
220+
$result = $this->resource->testMergeUnlessState('table', ['key' => 'value']);
221+
expect($result)->toBeInstanceOf(MergeValue::class);
222+
});
223+
224+
test('returns default when state matches and default is provided', function () {
225+
$result = $this->resource->testMergeUnlessState('full', ['key' => 'value'], 'default_value');
226+
expect($result)->toBeInstanceOf(MergeValue::class);
227+
expect($result->data)->toBe('default_value');
228+
});
229+
230+
test('works with State enum', function () {
231+
$result = $this->resource->testMergeUnlessState(State::Table, ['key' => 'value']);
232+
expect($result)->toBeInstanceOf(MergeValue::class);
233+
});
234+
});
235+
236+
describe('mergeWhenStateIn', function () {
237+
test('returns MergeValue when current state is in the array', function () {
238+
$result = $this->resource->testMergeWhenStateIn(['full', 'table'], ['key' => 'value']);
239+
expect($result)->toBeInstanceOf(MergeValue::class);
240+
});
241+
242+
test('returns MissingValue when current state is not in the array', function () {
243+
$result = $this->resource->testMergeWhenStateIn(['table', 'minimal'], ['key' => 'value']);
244+
expect($result)->toBeInstanceOf(MissingValue::class);
245+
});
246+
247+
test('returns default when current state is not in array and default is provided', function () {
248+
$result = $this->resource->testMergeWhenStateIn(['table', 'minimal'], ['key' => 'value'], 'default_value');
249+
expect($result)->toBeInstanceOf(MergeValue::class);
250+
expect($result->data)->toBe('default_value');
251+
});
252+
253+
test('works with State enums in array', function () {
254+
$result = $this->resource->testMergeWhenStateIn([State::Full, State::Table], ['key' => 'value']);
255+
expect($result)->toBeInstanceOf(MergeValue::class);
256+
});
257+
258+
test('works with mixed string and enum states', function () {
259+
$result = $this->resource->testMergeWhenStateIn([State::Table, 'full'], ['key' => 'value']);
260+
expect($result)->toBeInstanceOf(MergeValue::class);
261+
});
262+
});
263+
264+
describe('mergeUnlessStateIn', function () {
265+
test('returns MissingValue when current state is in the array', function () {
266+
$result = $this->resource->testMergeUnlessStateIn(['full', 'table'], ['key' => 'value']);
267+
expect($result)->toBeInstanceOf(MissingValue::class);
268+
});
269+
270+
test('returns MergeValue when current state is not in the array', function () {
271+
$result = $this->resource->testMergeUnlessStateIn(['table', 'minimal'], ['key' => 'value']);
272+
expect($result)->toBeInstanceOf(MergeValue::class);
273+
});
274+
275+
test('returns default when current state is in array and default is provided', function () {
276+
$result = $this->resource->testMergeUnlessStateIn(['full', 'table'], ['key' => 'value'], 'default_value');
277+
expect($result)->toBeInstanceOf(MergeValue::class);
278+
expect($result->data)->toBe('default_value');
279+
});
280+
281+
test('works with State enums in array', function () {
282+
$result = $this->resource->testMergeUnlessStateIn([State::Table, State::Minimal], ['key' => 'value']);
283+
expect($result)->toBeInstanceOf(MergeValue::class);
284+
});
285+
});
286+
287+
describe('magic method support', function () {
288+
test('whenState magic methods work correctly', function () {
289+
$result = $this->resource->whenStateFull('test_value');
290+
expect($result)->toBe('test_value');
291+
292+
$result = $this->resource->whenStateTable('test_value');
293+
expect($result)->toBeInstanceOf(MissingValue::class);
294+
});
295+
296+
test('unlessState magic methods work correctly', function () {
297+
$result = $this->resource->unlessStateFull('test_value');
298+
expect($result)->toBeInstanceOf(MissingValue::class);
299+
300+
$result = $this->resource->unlessStateTable('test_value');
301+
expect($result)->toBe('test_value');
302+
});
303+
304+
test('mergeWhenState magic methods work correctly', function () {
305+
$result = $this->resource->mergeWhenStateFull(['key' => 'value']);
306+
expect($result)->toBeInstanceOf(MergeValue::class);
307+
308+
$result = $this->resource->mergeWhenStateTable(['key' => 'value']);
309+
expect($result)->toBeInstanceOf(MissingValue::class);
310+
});
311+
312+
test('mergeUnlessState magic methods work correctly', function () {
313+
$result = $this->resource->mergeUnlessStateFull(['key' => 'value']);
314+
expect($result)->toBeInstanceOf(MissingValue::class);
315+
316+
$result = $this->resource->mergeUnlessStateTable(['key' => 'value']);
317+
expect($result)->toBeInstanceOf(MergeValue::class);
318+
});
319+
});
320+
321+
describe('edge cases', function () {
322+
test('empty state array in whenStateIn returns MissingValue', function () {
323+
$result = $this->resource->testWhenStateIn([], 'test_value');
324+
expect($result)->toBeInstanceOf(MissingValue::class);
325+
});
326+
327+
test('empty state array in unlessStateIn returns value', function () {
328+
$result = $this->resource->testUnlessStateIn([], 'test_value');
329+
expect($result)->toBe('test_value');
330+
});
331+
332+
test('empty state array in mergeWhenStateIn returns MissingValue', function () {
333+
$result = $this->resource->testMergeWhenStateIn([], ['key' => 'value']);
334+
expect($result)->toBeInstanceOf(MissingValue::class);
335+
});
336+
337+
test('empty state array in mergeUnlessStateIn returns MergeValue', function () {
338+
$result = $this->resource->testMergeUnlessStateIn([], ['key' => 'value']);
339+
expect($result)->toBeInstanceOf(MergeValue::class);
340+
});
341+
342+
test('null values are handled correctly', function () {
343+
$result = $this->resource->testWhenState('full', null);
344+
expect($result)->toBeNull();
345+
});
346+
347+
test('false values are handled correctly', function () {
348+
$result = $this->resource->testWhenState('full', false);
349+
expect($result)->toBeFalse();
350+
});
351+
352+
test('zero values are handled correctly', function () {
353+
$result = $this->resource->testWhenState('full', 0);
354+
expect($result)->toBe(0);
355+
});
356+
});

0 commit comments

Comments
 (0)