Passed
Pull Request — master (#19)
by Kevin
03:46
created

ProxyTest::can_force_set_multiple_fields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 15
rs 9.9666
1
<?php
2
3
namespace Zenstruck\Foundry\Tests\Functional;
4
5
use Zenstruck\Foundry\Proxy;
6
use Zenstruck\Foundry\Tests\Fixtures\Entity\Category;
7
use Zenstruck\Foundry\Tests\Fixtures\Factories\CategoryFactory;
8
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactory;
9
use Zenstruck\Foundry\Tests\FunctionalTestCase;
10
11
/**
12
 * @author Kevin Bond <[email protected]>
13
 */
14
final class ProxyTest extends FunctionalTestCase
15
{
16
    /**
17
     * @test
18
     */
19
    public function can_assert_persisted(): void
20
    {
21
        $post = PostFactory::new()->create();
22
23
        $post->assertPersisted();
24
    }
25
26
    /**
27
     * @test
28
     */
29
    public function can_remove_and_assert_not_persisted(): void
30
    {
31
        $post = PostFactory::new()->create();
32
33
        $post->remove();
34
35
        $post->assertNotPersisted();
36
    }
37
38
    /**
39
     * @test
40
     */
41
    public function functions_are_passed_to_wrapped_object(): void
42
    {
43
        $post = PostFactory::new()->create(['title' => 'my title']);
44
45
        $this->assertSame('my title', $post->getTitle());
0 ignored issues
show
Bug introduced by
The method getTitle() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
        $this->assertSame('my title', $post->/** @scrutinizer ignore-call */ getTitle());
Loading history...
46
    }
47
48
    /**
49
     * @test
50
     */
51
    public function can_convert_to_string_if_wrapped_object_can(): void
52
    {
53
        $post = PostFactory::new()->create(['title' => 'my title']);
54
55
        $this->assertSame('my title', (string) $post);
56
    }
57
58
    /**
59
     * @test
60
     * @requires PHP >= 7.4
61
     */
62
    public function cannot_convert_to_string_if_underlying_object_cant(): void
63
    {
64
        $this->expectException(\RuntimeException::class);
65
        $this->expectExceptionMessage(\sprintf('Proxied object "%s" cannot be converted to a string.', Category::class));
66
67
        (string) CategoryFactory::new()->create();
68
    }
69
70
    /**
71
     * @test
72
     * @requires PHP < 7.4
73
     */
74
    public function on_php_versions_less_than_7_4_if_underlying_object_is_missing_to_string_proxy_to_string_returns_note(): void
75
    {
76
        $this->assertSame('(no __toString)', (string) CategoryFactory::new()->create());
77
    }
78
79
    /**
80
     * @test
81
     */
82
    public function can_refetch_object_if_object_manager_has_been_cleared(): void
83
    {
84
        $post = PostFactory::new()->create(['title' => 'my title']);
85
86
        self::$container->get('doctrine')->getManager()->clear();
87
88
        $this->assertSame('my title', $post->refresh()->getTitle());
89
    }
90
91
    /**
92
     * @test
93
     */
94
    public function exception_thrown_if_trying_to_refresh_deleted_object(): void
95
    {
96
        $post = PostFactory::new()->create();
97
98
        self::$container->get('doctrine')->getManager()->clear();
99
100
        PostFactory::repository()->truncate();
101
102
        $this->expectException(\RuntimeException::class);
103
        $this->expectExceptionMessage('The object no longer exists.');
104
105
        $post->refresh();
106
    }
107
108
    /**
109
     * @test
110
     */
111
    public function can_force_set_and_save(): void
112
    {
113
        $post = PostFactory::new()->create(['title' => 'old title']);
114
115
        $post->repository()->assertNotExists(['title' => 'new title']);
116
117
        $post->forceSet('title', 'new title')->save();
118
119
        $post->repository()->assertExists(['title' => 'new title']);
120
    }
121
122
    /**
123
     * @test
124
     */
125
    public function can_force_set_multiple_fields(): void
126
    {
127
        $post = PostFactory::new()->create(['title' => 'old title', 'body' => 'old body']);
128
129
        $this->assertSame('old title', $post->getTitle());
130
        $this->assertSame('old body', $post->getBody());
0 ignored issues
show
Bug introduced by
The method getBody() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
        $this->assertSame('old body', $post->/** @scrutinizer ignore-call */ getBody());
Loading history...
131
132
        $post
133
            ->forceSet('title', 'new title')
134
            ->forceSet('body', 'new body')
135
            ->save()
136
        ;
137
138
        $this->assertSame('new title', $post->getTitle());
139
        $this->assertSame('new body', $post->getBody());
140
    }
141
142
    /**
143
     * @test
144
     */
145
    public function demonstrate_setting_field_problem_with_auto_refreshing_enabled(): void
146
    {
147
        $post = PostFactory::new()->create(['title' => 'old title', 'body' => 'old body']);
148
149
        $this->assertSame('old title', $post->getTitle());
150
        $this->assertSame('old body', $post->getBody());
151
152
        $post
153
            ->enableAutoRefresh()
154
            ->forceSet('title', 'new title') // will not be saved because the following ->forceSet() refreshes the object
155
            ->forceSet('body', 'new body')
156
            ->save()
157
        ;
158
159
        $this->assertSame('old title', $post->getTitle());
160
        $this->assertSame('new body', $post->getBody());
161
    }
162
163
    /**
164
     * @test
165
     */
166
    public function force_set_all_solves_the_auto_refresh_problem(): void
167
    {
168
        $post = PostFactory::new()->create(['title' => 'old title', 'body' => 'old body']);
169
170
        $this->assertSame('old title', $post->getTitle());
171
        $this->assertSame('old body', $post->getBody());
172
173
        $post
174
            ->enableAutoRefresh()
175
            ->forceSetAll([
176
                'title' => 'new title',
177
                'body' => 'new body',
178
            ])
179
            ->save()
180
        ;
181
182
        $this->assertSame('new title', $post->getTitle());
183
        $this->assertSame('new body', $post->getBody());
184
    }
185
186
    /**
187
     * @test
188
     */
189
    public function without_auto_refresh_solves_the_auto_refresh_problem(): void
190
    {
191
        $post = PostFactory::new()->create(['title' => 'old title', 'body' => 'old body']);
192
193
        $this->assertSame('old title', $post->getTitle());
194
        $this->assertSame('old body', $post->getBody());
195
196
        $post
197
            ->enableAutoRefresh()
198
            ->withoutAutoRefresh(static function(Proxy $proxy) {
199
                $proxy
200
                    ->forceSet('title', 'new title')
201
                    ->forceSet('body', 'new body')
202
                ;
203
            })
204
            ->save()
205
        ;
206
207
        $this->assertSame('new title', $post->getTitle());
208
        $this->assertSame('new body', $post->getBody());
209
    }
210
211
    /**
212
     * @test
213
     */
214
    public function without_auto_refresh_does_not_enable_auto_refresh_if_it_was_disabled_originally(): void
215
    {
216
        $post = PostFactory::new()->create(['title' => 'old title', 'body' => 'old body']);
217
218
        $this->assertSame('old title', $post->getTitle());
219
        $this->assertSame('old body', $post->getBody());
220
221
        $post
222
            ->withoutAutoRefresh(static function(Proxy $proxy) {
223
                $proxy
224
                    ->forceSet('title', 'new title')
225
                    ->forceSet('body', 'new body')
226
                ;
227
            })
228
            ->forceSet('title', 'another new title')
229
            ->forceSet('body', 'another new body')
230
            ->save()
231
        ;
232
233
        $this->assertSame('another new title', $post->getTitle());
234
        $this->assertSame('another new body', $post->getBody());
235
    }
236
237
    /**
238
     * @test
239
     */
240
    public function without_auto_refresh_re_enables_if_enabled_originally(): void
241
    {
242
        $post = PostFactory::new()->create(['title' => 'old title', 'body' => 'old body']);
243
244
        $this->assertSame('old title', $post->getTitle());
245
        $this->assertSame('old body', $post->getBody());
246
247
        $post
248
            ->enableAutoRefresh()
249
            ->withoutAutoRefresh(static function(Proxy $proxy) {
250
                $proxy
251
                    ->forceSet('title', 'new title')
252
                    ->forceSet('body', 'new body')
253
                ;
254
            })
255
            ->save()
256
            ->forceSet('title', 'another new title') // will not be saved because the following ->forceSet() refreshes the object
257
            ->forceSet('body', 'another new body')
258
            ->save()
259
        ;
260
261
        $this->assertSame('new title', $post->getTitle());
262
        $this->assertSame('another new body', $post->getBody());
263
    }
264
}
265