Skip to content

Commit ec620b1

Browse files
authored
[FEATURE] Basic Test Improvements (#2)
* Test improvements and GitHub Actions improvements * Updated .gitattributes * Conflict with known bad versions of `tightenco/collect`
1 parent 400436f commit ec620b1

8 files changed

+179
-17
lines changed

.gitattributes

+15-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1-
.gitattributes export-ignore
2-
.gitignore export-ignore
3-
.php_cs.dist export-ignore
4-
phpunit.xml.dist export-ignore
5-
/Resources/doc export-ignore
6-
/Tests export-ignore
1+
* text=auto
2+
3+
/.github export-ignore
4+
.editorconfig export-ignore
5+
.gitattributes export-ignore
6+
.gitignore export-ignore
7+
.php_cs.dist export-ignore
8+
.whitesource export-ignore
9+
/Resources/doc export-ignore
10+
/Tests export-ignore
11+
docker-compose.yml export-ignore
12+
phpcs.xml.dist export-ignore
13+
phpstan.neon.dist export-ignore
14+
phpunit.xml.dist export-ignore
15+
psalm.xml.dist export-ignore

.github/workflows/continuous-integration.yml

+23-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
name: "Continuous Integration"
77

8-
on: [push, pull_request]
8+
on:
9+
push:
10+
pull_request:
11+
# Run the CI tasks weekly to catch any potential dependency regressions.
12+
schedule:
13+
- cron: '0 0 * * 1'
914

1015
jobs:
1116
phpunit:
@@ -43,11 +48,22 @@ jobs:
4348
composer-flags: "--ignore-platform-reqs"
4449
symfony-require: "5.2.*"
4550

51+
services:
52+
ldap:
53+
image: bitnami/openldap
54+
ports:
55+
- 3389:3389
56+
env:
57+
LDAP_ADMIN_USERNAME: admin
58+
LDAP_ADMIN_PASSWORD: a_great_password
59+
LDAP_ROOT: dc=local,dc=com
60+
LDAP_PORT_NUMBER: 3389
61+
LDAP_USERS: a
62+
LDAP_PASSWORDS: a
63+
4664
steps:
4765
- name: "Checkout"
4866
uses: "actions/checkout@v2"
49-
with:
50-
fetch-depth: 2
5167

5268
- name: "Install PHP with PCOV"
5369
uses: "shivammathur/setup-php@v2"
@@ -64,8 +80,10 @@ jobs:
6480
uses: "actions/cache@v2"
6581
with:
6682
path: "~/.composer/cache"
67-
key: "php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}-composer-locked-${{ hashFiles('composer.lock') }}"
68-
restore-keys: "php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}-composer-locked-"
83+
key: php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}-composer-locked-${{ hashFiles('composer.lock') }}
84+
restore-keys: |
85+
php-${{ matrix.php-version }}-symfony-${{ matrix.symfony-require }}-composer-locked-
86+
php-${{ matrix.php-version }}-
6987
7088
- name: "Install dependencies with composer"
7189
env:

Tests/DependencyInjection/Iter8LdapRecordExtensionTest.php

+72-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77
use InvalidArgumentException;
88
use Iter8\Bundle\LdapRecordBundle\DependencyInjection\Iter8LdapRecordExtension;
9-
use PHPUnit\Framework\TestCase;
9+
use Iter8\Bundle\LdapRecordBundle\Tests\TestCase;
10+
use LdapRecord\Connection;
11+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1012
use Symfony\Component\DependencyInjection\ContainerBuilder;
13+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
1114

1215
class Iter8LdapRecordExtensionTest extends TestCase
1316
{
@@ -22,14 +25,80 @@ public function test_cannot_configure_tls_and_ssl_for_connection(): void
2225
$extension->load([array_merge($this->baseConfig(), ['use_ssl' => true, 'use_tls' => true])], $container);
2326
}
2427

28+
public function test_load_empty_configuration(): void
29+
{
30+
$this->expectException(InvalidConfigurationException::class);
31+
32+
$container = $this->createContainer();
33+
$container->registerExtension(new Iter8LdapRecordExtension());
34+
$container->loadFromExtension('iter8_ldap_record');
35+
$container->compile();
36+
}
37+
38+
public function test_load_valid_configuration(): void
39+
{
40+
$container = $this->createContainer();
41+
$container->registerExtension(new Iter8LdapRecordExtension());
42+
$container->loadFromExtension('iter8_ldap_record', $this->baseConfig());
43+
$container->compile();
44+
45+
self::assertTrue($container->getDefinition('iter8_ldap_record.connection')->isPublic());
46+
}
47+
48+
public function test_is_connected_with_auto_connect_disabled(): void
49+
{
50+
$this->getLdapConfig();
51+
52+
$container = $this->createContainer();
53+
$container->registerExtension(new Iter8LdapRecordExtension());
54+
$container->loadFromExtension('iter8_ldap_record', $this->baseConfig());
55+
$container->compile();
56+
57+
/** @var Connection $connection */
58+
$connection = $container->get('iter8_ldap_record.connection');
59+
60+
self::assertFalse($connection->isConnected());
61+
}
62+
63+
public function test_is_connected_with_auto_connect_enabled(): void
64+
{
65+
$this->getLdapConfig();
66+
67+
$config = array_merge(
68+
$this->baseConfig(),
69+
['auto_connect' => true]
70+
);
71+
72+
$container = $this->createContainer();
73+
$container->registerExtension(new Iter8LdapRecordExtension());
74+
$container->loadFromExtension('iter8_ldap_record', $config);
75+
$container->compile();
76+
77+
/** @var Connection $connection */
78+
$connection = $container->get('iter8_ldap_record.connection');
79+
80+
self::assertTrue($connection->isConnected());
81+
}
82+
2583
private function baseConfig(): array
2684
{
2785
return [
28-
'hosts' => ['example_host.local'],
86+
'hosts' => ['localhost'],
2987
'base_dn' => 'dc=local,dc=com',
3088
'username' => 'cn=admin,dc=local,dc=com',
3189
'password' => 'a_great_password',
32-
'auto_connect' => true,
90+
'port' => 3389,
3391
];
3492
}
93+
94+
private function createContainer(): ContainerBuilder
95+
{
96+
return new ContainerBuilder(new ParameterBag([
97+
'kernel.cache_dir' => __DIR__,
98+
'kernel.project_dir' => __DIR__,
99+
'kernel.charset' => 'UTF-8',
100+
'kernel.debug' => false,
101+
'kernel.bundles' => ['Iter8LdapRecordBundle' => true],
102+
]));
103+
}
35104
}

Tests/TestCase.php

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Iter8\Bundle\LdapRecordBundle\Tests;
6+
7+
use PHPUnit\Framework\TestCase as PHPUnitTestCase;
8+
9+
class TestCase extends PHPUnitTestCase
10+
{
11+
protected function getLdapConfig(): array
12+
{
13+
/** @var resource|null $h */
14+
$h = @ldap_connect((string) getenv('LDAP_HOST'), (int) getenv('LDAP_PORT'));
15+
@ldap_set_option($h, \LDAP_OPT_PROTOCOL_VERSION, 3);
16+
17+
if (!\is_resource($h) || !@ldap_bind($h)) {
18+
self::markTestSkipped('No server is listening on LDAP_HOST:LDAP_PORT');
19+
}
20+
21+
ldap_unbind($h);
22+
23+
return [
24+
'host' => getenv('LDAP_HOST'),
25+
'port' => getenv('LDAP_PORT'),
26+
];
27+
}
28+
}

composer.json

+19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
},
1515
"require": {
1616
"php": "^7.2 || ^8.0",
17+
"ext-ldap": "*",
1718
"directorytree/ldaprecord": "^2.0",
1819
"symfony/framework-bundle": "^4.4 || ^5.0"
1920
},
@@ -35,6 +36,9 @@
3536
"preferred-install": "dist",
3637
"sort-packages": true
3738
},
39+
"conflict": {
40+
"tightenco/collect": "<5.6"
41+
},
3842
"autoload": {
3943
"psr-4": {
4044
"Iter8\\Bundle\\LdapRecordBundle\\": ""
@@ -47,5 +51,20 @@
4751
"psr-4": {
4852
"": "Tests/DependencyInjection"
4953
}
54+
},
55+
"scripts": {
56+
"ci": [
57+
"@phpcs",
58+
"@phpunit",
59+
"@phpstan",
60+
"@psalm"
61+
],
62+
"csf": "php-cs-fixer fix",
63+
"csf-dry": "@csf --dry-run",
64+
"phpcs": "phpcs",
65+
"phpstan": "phpstan analyze",
66+
"phpstan-max": "@phpstan --level=max",
67+
"phpunit": "phpunit",
68+
"psalm": "psalm --show-info=true"
5069
}
5170
}

docker-compose.yml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: '2'
2+
3+
services:
4+
ldap:
5+
image: bitnami/openldap
6+
ports:
7+
- 3389:3389
8+
environment:
9+
- LDAP_ADMIN_USERNAME=admin
10+
- LDAP_ADMIN_PASSWORD=a_great_password
11+
- LDAP_USERS=a
12+
- LDAP_PASSWORDS=a
13+
- LDAP_ROOT=dc=local,dc=com
14+
- LDAP_PORT_NUMBER=3389

phpcs.xml.dist

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<exclude name="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceEqualOperator.RequiredNullCoalesceEqualOperator"/> <!-- PHP 7.4 required-->
2525
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint"/> <!-- PHP 7.4 required-->
2626
<exclude name="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFallbackGlobalName"/>
27+
<exclude name="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName"/>
2728

2829
<!-- As per: https://symfony.com/doc/current/contributing/code/standards.html#structure -->
2930
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/>
@@ -39,6 +40,10 @@
3940
<exclude-pattern>Tests</exclude-pattern>
4041
</rule>
4142

43+
<rule ref="SlevomatCodingStandard.PHP.RequireExplicitAssertion.RequiredExplicitAssertion">
44+
<exclude-pattern>Tests</exclude-pattern>
45+
</rule>
46+
4247
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification">
4348
<exclude-pattern>Tests</exclude-pattern>
4449
</rule>

phpstan.neon.dist

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ parameters:
55
checkMissingIterableValueType: false
66
checkGenericClassInNonGenericObjectType: false
77
paths:
8-
- ./DependencyInjection
9-
- ./Tests
8+
- %currentWorkingDirectory%/DependencyInjection
9+
- %currentWorkingDirectory%/Tests
1010
ignoreErrors:
1111
-
1212
message: '#.*NodeDefinition::children.*#'
13-
path: ./DependencyInjection
13+
path: %currentWorkingDirectory%/DependencyInjection
1414
includes:
1515
- vendor/phpstan/phpstan-strict-rules/rules.neon
1616
- vendor/phpstan/phpstan-phpunit/extension.neon

0 commit comments

Comments
 (0)