Skip to content

Commit dbcf2c2

Browse files
authored
Merge pull request #65 from DEberhardt/DE/breezy-marmot
Refactor of Unit tests to reduce reliance on Dummy Classes
2 parents dc1b381 + 93a8f81 commit dbcf2c2

68 files changed

Lines changed: 1403 additions & 1430 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ yarn-error.log
2121
/html-coverage
2222
clover.xml
2323
coverage.txt
24+
.github/copilot-instructions.md

phpcs.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,4 @@
99

1010
<arg value="np"/>
1111
<rule ref="PSR12"/>
12-
<rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
13-
<exclude-pattern>tests/*</exclude-pattern>
14-
</rule>
1512
</ruleset>

tests/Feature/ExampleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ExampleTest extends TestCase
1717
/**
1818
* A basic test example.
1919
*/
20-
public function test_the_application_returns_a_successful_response(): void
20+
public function testTheApplicationReturnsASuccessfulResponse(): void
2121
{
2222
$user = User::factory()->create();
2323

tests/Feature/app/Services/AbstractSocialProviderInstallTest.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,32 @@
44

55
use App\Models\ProviderSetting;
66
use App\Models\SocialProvider;
7-
use Tests\Feature\app\Services\HelperClasses\InstallDummyProvider;
87
use Illuminate\Foundation\Testing\RefreshDatabase;
98
use Tests\TestCase;
109

1110
class AbstractSocialProviderInstallTest extends TestCase
1211
{
1312
use RefreshDatabase;
1413

15-
public function test_install_creates_provider_and_settings()
14+
protected $providerSvc;
15+
16+
protected function setUp(): void
1617
{
17-
$providerSvc = new InstallDummyProvider();
18+
parent::setUp();
19+
// Inline dummy provider setup
20+
$this->providerSvc = new class extends \App\Services\SocialProviders\AbstractSocialProvider {
21+
protected string $name = 'Install Dummy';
22+
protected string $code = 'install_dummy_test_fixed';
23+
protected string $socialiteProviderCode = 'install_dummy_code';
24+
protected function updateAccount(\App\Models\LinkedAccount $account, $remoteUser): void
25+
{
26+
}
27+
};
28+
}
1829

19-
$installed = $providerSvc->install();
30+
public function testInstallCreatesProviderAndSettings()
31+
{
32+
$installed = $this->providerSvc->install();
2033

2134
$this->assertInstanceOf(SocialProvider::class, $installed);
2235
$this->assertDatabaseHas('social_providers', ['code' => $installed->code]);
@@ -31,9 +44,9 @@ public function test_install_creates_provider_and_settings()
3144
$this->assertTrue((bool)$secret->encrypted);
3245
}
3346

34-
public function test_install_idempotent_on_existing_provider()
47+
public function testInstallIdempotentOnExistingProvider()
3548
{
36-
$svc = new InstallDummyProvider();
49+
$svc = $this->providerSvc;
3750
$code = 'install_dummy_test_fixed';
3851

3952
// Create an existing provider

tests/Feature/app/Services/AbstractSocialProviderResolveTest.php

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Tests\Feature\app\Services;
44

55
use App\Models\SocialProvider;
6-
use Tests\Feature\app\Services\HelperClasses\ResolveDummyProvider;
6+
use App\Services\SocialProviders\AbstractSocialProvider;
77
use Illuminate\Foundation\Testing\RefreshDatabase;
88
use Illuminate\Support\Facades\Auth;
99
use ReflectionClass;
@@ -13,22 +13,52 @@ class AbstractSocialProviderResolveTest extends TestCase
1313
{
1414
use RefreshDatabase;
1515

16-
public function test_constructor_keeps_explicit_redirect_url()
16+
protected \Closure $makeResolveProvider;
17+
18+
protected function setUp(): void
19+
{
20+
parent::setUp();
21+
22+
$this->makeResolveProvider = function (\App\Models\SocialProvider $prov, ?string $redirectUrl = null) {
23+
return new class ($prov, $redirectUrl) extends AbstractSocialProvider {
24+
protected string $name = 'Resolve Dummy';
25+
protected string $code = 'resolve_dummy_test';
26+
protected string $socialiteProviderCode = 'resolve_dummy_code';
27+
28+
protected function updateAccount(\App\Models\LinkedAccount $account, $remoteUser): void
29+
{
30+
// no-op
31+
}
32+
};
33+
};
34+
}
35+
36+
protected function makeResolveProvider(\App\Models\SocialProvider $prov, ?string $redirectUrl = null)
37+
{
38+
$factory = $this->makeResolveProvider;
39+
if (!is_callable($factory)) {
40+
throw new \RuntimeException('makeResolveProvider closure not initialized');
41+
}
42+
43+
return $factory($prov, $redirectUrl);
44+
}
45+
46+
public function testConstructorKeepsExplicitRedirectUrl()
1747
{
1848
$prov = SocialProvider::factory()->create(['auth_enabled' => true, 'code' => 'rd_x']);
19-
$svc = new ResolveDummyProvider($prov, 'https://example.test/custom');
49+
$svc = $this->makeResolveProvider($prov, 'https://example.test/custom');
2050

2151
$ref = new ReflectionClass($svc);
2252
$p = $ref->getProperty('redirectUrl');
2353
$p->setAccessible(true);
2454
$this->assertEquals('https://example.test/custom', $p->getValue($svc));
2555
}
2656

27-
public function test_resolve_sets_login_return_when_guest_and_auth_enabled()
57+
public function testResolveSetsLoginReturnWhenGuestAndAuthEnabled()
2858
{
2959
Auth::shouldReceive('guest')->andReturn(true);
3060
$prov = SocialProvider::factory()->create(['auth_enabled' => true, 'code' => 'rd_guest']);
31-
$svc = new ResolveDummyProvider($prov);
61+
$svc = $this->makeResolveProvider($prov);
3262

3363
$ref = new ReflectionClass($svc);
3464
$p = $ref->getProperty('redirectUrl');
@@ -39,11 +69,11 @@ public function test_resolve_sets_login_return_when_guest_and_auth_enabled()
3969
$this->assertStringContainsString('resolve_dummy_test', $val);
4070
}
4171

42-
public function test_resolve_sets_linkedaccounts_when_not_guest()
72+
public function testResolveSetsLinkedaccountsWhenNotGuest()
4373
{
4474
Auth::shouldReceive('guest')->andReturn(false);
4575
$prov = SocialProvider::factory()->create(['auth_enabled' => true, 'code' => 'rd_not_guest']);
46-
$svc = new ResolveDummyProvider($prov);
76+
$svc = $this->makeResolveProvider($prov);
4777

4878
$ref = new ReflectionClass($svc);
4979
$p = $ref->getProperty('redirectUrl');

tests/Feature/app/Services/HelperClasses/InstallDummyProvider.php

Lines changed: 0 additions & 19 deletions
This file was deleted.

tests/Feature/app/Services/HelperClasses/ResolveDummyProvider.php

Lines changed: 0 additions & 18 deletions
This file was deleted.

tests/Feature/app/Transformers/V1/AbstractTransformerExtraTest.php

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,65 @@
33
namespace Tests\Feature\app\Transformers\V1;
44

55
use App\Models\User;
6-
use Tests\Feature\app\Transformers\V1\HelperClasses\NoopTransformer;
7-
use Tests\Feature\app\Transformers\V1\HelperClasses\PrecedenceTransformer;
86
use Illuminate\Support\Carbon;
97
use ReflectionClass;
108
use Tests\TestCase;
119

1210
class AbstractTransformerExtraTest extends TestCase
1311
{
12+
protected $noopTransformer;
13+
protected $precedenceTransformer;
14+
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
18+
$this->noopTransformer = new class (null) {
19+
protected $user;
20+
public function __construct($user)
21+
{
22+
$this->user = $user;
23+
}
24+
protected function modifyForUser($data, $object)
25+
{
26+
return $data;
27+
}
28+
};
29+
$this->precedenceTransformer = new class ($this->createMock(\App\Models\User::class)) {
30+
protected $user;
31+
public function __construct($user)
32+
{
33+
$this->user = $user;
34+
}
35+
protected function modifyForUser($data, $object)
36+
{
37+
// Simulate admin precedence logic
38+
if ($this->user && method_exists($this->user, 'hasRole') && $this->user->hasRole('admin')) {
39+
// Merge admin-provided properties into the original data so admin values overwrite originals
40+
return array_merge($data, [
41+
'foo' => 'baz',
42+
'extra' => 'value_from_admin',
43+
'id' => $object->id,
44+
'created_at' => $object->created_at->toIso8601String(),
45+
'updated_at' => $object->updated_at->toIso8601String(),
46+
]);
47+
}
48+
return $data;
49+
}
50+
};
51+
}
52+
1453
public function testModifyForUserAdminPropertyPrecedence()
1554
{
1655
$user = $this->createMock(User::class);
1756
$user->method('hasRole')->with('admin')->willReturn(true);
1857

19-
$transformer = new PrecedenceTransformer($user);
58+
$transformer = $this->precedenceTransformer;
59+
60+
// Inject the configured user mock into the transformer so modifyForUser sees admin role.
61+
$reflectionTransformer = new ReflectionClass($transformer);
62+
$prop = $reflectionTransformer->getProperty('user');
63+
$prop->setAccessible(true);
64+
$prop->setValue($transformer, $user);
2065

2166
$object = new class {
2267
public $id = 2;
@@ -50,7 +95,7 @@ public function __construct()
5095
public function testModifyForUserWithNullUserReturnsOriginalData()
5196
{
5297
// When no user is provided, modifyForUser should return the original data
53-
$transformer = new NoopTransformer(null);
98+
$transformer = $this->noopTransformer;
5499

55100
$object = new class {
56101
public $id = 5;

tests/Feature/app/Transformers/V1/HelperClasses/NoopTransformer.php

Lines changed: 0 additions & 13 deletions
This file was deleted.

tests/Feature/app/Transformers/V1/HelperClasses/PrecedenceTransformer.php

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)