Skip to content

Commit b40be54

Browse files
authored
feat: New tests (#22)
* fixed namespace for tests * style fix * style fix
1 parent 9a355a9 commit b40be54

File tree

16 files changed

+417
-204
lines changed

16 files changed

+417
-204
lines changed

composer.json

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,51 @@
11
{
2-
"name": "secretary/php",
3-
"description": "Monorepo for Secretary's PHP implementation",
4-
"type": "library",
5-
"require-dev": {
6-
"php": "^8.2",
7-
"ext-json": "*",
8-
"aws/aws-sdk-php": "^3.91",
9-
"google/cloud-secret-manager": "^2.2",
10-
"guzzlehttp/guzzle": "^7.0",
11-
"mockery/mockery": "^1.6.12",
12-
"phpunit/phpunit": "^10.5 || ^11.0 || ^12.0 || ^13.0",
13-
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0",
14-
"symfony/config": "^5.3 || ^6.0 || ^7.0 || ^8.0",
15-
"symfony/dependency-injection": "^5.0 || ^6.0 || ^7.0 || ^8.0",
16-
"symfony/framework-bundle": "^5.0 || ^6.0 || ^7.0 || ^8.0",
17-
"symfony/http-kernel": "^5.0 || ^6.0 || ^7.0 || ^8.0",
18-
"symfony/options-resolver": "^5.4 || ^6.0 || ^7.0 || ^8.0",
19-
"symfony/yaml": "^5.0 || ^6.0 || ^7.0 || ^8.0",
20-
"symplify/easy-coding-standard": "^12",
21-
"vimeo/psalm": "^5.26 || ^6.14.3"
22-
},
23-
"license": "MIT",
24-
"authors": [
25-
{
26-
"name": "Aaron Scherer",
27-
"email": "aequasi@gmail.com"
28-
}
29-
],
30-
"autoload": {
31-
"psr-4": {
32-
"Secretary\\": "src/Core",
33-
"Secretary\\Adapter\\": "src/Adapter",
34-
"Secretary\\Bundle\\": "src/Bundle"
35-
},
36-
"exclude-from-classmap": [
37-
"**/Tests/"
38-
]
39-
},
40-
"config": {
41-
"preferred-install": {
42-
"*": "dist"
43-
},
44-
"sort-packages": true
45-
},
46-
"scripts": {
47-
"ecs": "ecs check",
48-
"ecs:fix": "ecs check --fix",
49-
"psalm": "psalm --show-info"
50-
}
2+
"name": "secretary/php",
3+
"description": "Monorepo for Secretary's PHP implementation",
4+
"type": "library",
5+
"require-dev": {
6+
"php": "^8.2",
7+
"ext-json": "*",
8+
"aws/aws-sdk-php": "^3.91",
9+
"google/cloud-secret-manager": "^2.2",
10+
"guzzlehttp/guzzle": "^7.0",
11+
"mockery/mockery": "^1.6.12",
12+
"phpunit/phpunit": "^10.5 || ^11.0 || ^12.0 || ^13.0",
13+
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0",
14+
"symfony/config": "^5.3 || ^6.0 || ^7.0 || ^8.0",
15+
"symfony/dependency-injection": "^5.0 || ^6.0 || ^7.0 || ^8.0",
16+
"symfony/framework-bundle": "^5.0 || ^6.0 || ^7.0 || ^8.0",
17+
"symfony/http-kernel": "^5.0 || ^6.0 || ^7.0 || ^8.0",
18+
"symfony/options-resolver": "^5.4 || ^6.0 || ^7.0 || ^8.0",
19+
"symfony/yaml": "^5.0 || ^6.0 || ^7.0 || ^8.0",
20+
"symplify/easy-coding-standard": "^12",
21+
"vimeo/psalm": "^5.26 || ^6.14.3"
22+
},
23+
"license": "MIT",
24+
"authors": [
25+
{
26+
"name": "Aaron Scherer",
27+
"email": "aequasi@gmail.com"
28+
}
29+
],
30+
"autoload": {
31+
"psr-4": {
32+
"Secretary\\": "src/Core",
33+
"Secretary\\Adapter\\": "src/Adapter",
34+
"Secretary\\Bundle\\": "src/Bundle"
35+
},
36+
"exclude-from-classmap": [
37+
"**/Tests/"
38+
]
39+
},
40+
"config": {
41+
"preferred-install": {
42+
"*": "dist"
43+
},
44+
"sort-packages": true
45+
},
46+
"scripts": {
47+
"ecs": "ecs check",
48+
"ecs:fix": "ecs check --fix",
49+
"psalm": "psalm --show-info"
50+
}
5151
}

psalm.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<directory name="src" />
1212
<ignoreFiles>
1313
<directory name="vendor" />
14-
<directory name="src/Core/Tests" />
15-
<file name="src/Bundle/SecretaryBundle/Test.php" />
14+
<directory name="**/vendor" />
15+
<directory name="**/Tests" />
1616
</ignoreFiles>
1717
</projectFiles>
1818

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Tests export-ignore
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* @author Aaron Scherer <aequasi@gmail.com>
7+
* @date 2019
8+
* @license https://opensource.org/licenses/MIT
9+
*/
10+
11+
namespace Secretary\Tests;
12+
13+
use Aws\CommandInterface;
14+
use Aws\Result;
15+
use Aws\SecretsManager\Exception\SecretsManagerException;
16+
use Aws\SecretsManager\SecretsManagerClient;
17+
use Mockery\MockInterface;
18+
use PHPUnit\Framework\Attributes\CoversClass;
19+
use PHPUnit\Framework\TestCase;
20+
use Secretary\Adapter\AWS\SecretsManager\AWSSecretsManagerAdapter;
21+
use Secretary\Exception\SecretNotFoundException;
22+
use Secretary\Secret;
23+
24+
#[CoversClass(AWSSecretsManagerAdapter::class)]
25+
class AWSSecretsManagerAdapterTest extends TestCase
26+
{
27+
private AWSSecretsManagerAdapter $adapter;
28+
29+
private SecretsManagerClient|MockInterface $client;
30+
31+
protected function setUp(): void
32+
{
33+
parent::setUp();
34+
35+
$this->client = \Mockery::mock(SecretsManagerClient::class);
36+
$this->adapter = new AWSSecretsManagerAdapter([]);
37+
38+
$reflection = new \ReflectionProperty(AWSSecretsManagerAdapter::class, 'client');
39+
$reflection->setValue($this->adapter, $this->client);
40+
}
41+
42+
protected function tearDown(): void
43+
{
44+
\Mockery::close();
45+
parent::tearDown();
46+
}
47+
48+
public function testGetSecretWithStringValue(): void
49+
{
50+
$result = new Result(['SecretString' => 'my-secret-value']);
51+
52+
$this->client
53+
->shouldReceive('getSecretValue')
54+
->with(\Mockery::on(fn (array $opts) => $opts['SecretId'] === 'my/key'))
55+
->once()
56+
->andReturn($result);
57+
58+
$secret = $this->adapter->getSecret('my/key');
59+
60+
$this->assertInstanceOf(Secret::class, $secret);
61+
$this->assertEquals('my/key', $secret->getKey());
62+
$this->assertEquals('my-secret-value', $secret->getValue());
63+
}
64+
65+
public function testGetSecretWithJsonValue(): void
66+
{
67+
$jsonData = ['username' => 'admin', 'password' => 'secret123'];
68+
$result = new Result(['SecretString' => json_encode($jsonData)]);
69+
70+
$this->client
71+
->shouldReceive('getSecretValue')
72+
->with(\Mockery::on(fn (array $opts) => $opts['SecretId'] === 'db/credentials'))
73+
->once()
74+
->andReturn($result);
75+
76+
$secret = $this->adapter->getSecret('db/credentials');
77+
78+
$this->assertInstanceOf(Secret::class, $secret);
79+
$this->assertEquals('db/credentials', $secret->getKey());
80+
$this->assertEquals($jsonData, $secret->getValue());
81+
}
82+
83+
public function testGetSecretThrowsSecretNotFoundException(): void
84+
{
85+
$this->expectException(SecretNotFoundException::class);
86+
87+
$command = \Mockery::mock(CommandInterface::class);
88+
$exception = new SecretsManagerException(
89+
'Error',
90+
$command,
91+
['message' => "Secrets Manager can\u{2019}t find the specified secret"]
92+
);
93+
94+
$this->client
95+
->shouldReceive('getSecretValue')
96+
->once()
97+
->andThrow($exception);
98+
99+
$this->adapter->getSecret('nonexistent/key');
100+
}
101+
102+
public function testGetSecretRethrowsOtherExceptions(): void
103+
{
104+
$this->expectException(SecretsManagerException::class);
105+
106+
$command = \Mockery::mock(CommandInterface::class);
107+
$exception = new SecretsManagerException(
108+
'Access denied',
109+
$command,
110+
['message' => 'User is not authorized']
111+
);
112+
113+
$this->client
114+
->shouldReceive('getSecretValue')
115+
->once()
116+
->andThrow($exception);
117+
118+
$this->adapter->getSecret('forbidden/key');
119+
}
120+
121+
public function testPutSecretUpdatesExisting(): void
122+
{
123+
$secret = new Secret('my/key', 'my-value');
124+
125+
$this->client
126+
->shouldReceive('updateSecret')
127+
->with(\Mockery::on(function (array $opts) {
128+
return $opts['SecretId'] === 'my/key'
129+
&& $opts['SecretString'] === 'my-value';
130+
}))
131+
->once();
132+
133+
$result = $this->adapter->putSecret($secret);
134+
135+
$this->assertSame($secret, $result);
136+
}
137+
138+
public function testPutSecretCreatesWhenUpdateFails(): void
139+
{
140+
$secret = new Secret('new/key', 'new-value');
141+
142+
$this->client
143+
->shouldReceive('updateSecret')
144+
->once()
145+
->andThrow(new \Exception('Secret not found'));
146+
147+
$this->client
148+
->shouldReceive('createSecret')
149+
->with(\Mockery::on(function (array $opts) {
150+
return $opts['Name'] === 'new/key'
151+
&& $opts['SecretString'] === 'new-value';
152+
}))
153+
->once();
154+
155+
$result = $this->adapter->putSecret($secret);
156+
157+
$this->assertSame($secret, $result);
158+
}
159+
160+
public function testPutSecretWithArrayValue(): void
161+
{
162+
$value = ['user' => 'admin', 'pass' => 'secret'];
163+
$secret = new Secret('my/key', $value);
164+
165+
$this->client
166+
->shouldReceive('updateSecret')
167+
->with(\Mockery::on(function (array $opts) use ($value) {
168+
return $opts['SecretString'] === json_encode($value);
169+
}))
170+
->once();
171+
172+
$result = $this->adapter->putSecret($secret);
173+
174+
$this->assertSame($secret, $result);
175+
}
176+
177+
public function testDeleteSecretByKey(): void
178+
{
179+
$this->client
180+
->shouldReceive('deleteSecret')
181+
->with(\Mockery::on(fn (array $opts) => $opts['SecretId'] === 'my/key'))
182+
->once();
183+
184+
$this->adapter->deleteSecretByKey('my/key');
185+
186+
$this->assertTrue(true);
187+
}
188+
189+
public function testDeleteSecret(): void
190+
{
191+
$secret = new Secret('my/key', 'value');
192+
193+
$this->client
194+
->shouldReceive('deleteSecret')
195+
->with(\Mockery::on(fn (array $opts) => $opts['SecretId'] === 'my/key'))
196+
->once();
197+
198+
$this->adapter->deleteSecret($secret);
199+
200+
$this->assertTrue(true);
201+
}
202+
}
Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,33 @@
11
{
2-
"name": "secretary/aws-secrets-manager-adapter",
3-
"description": "AWS Secrets Manager Adapter for Secretary",
4-
"type": "library",
5-
"license": "MIT",
6-
"keywords": [
2+
"name": "secretary/aws-secrets-manager-adapter",
3+
"description": "AWS Secrets Manager Adapter for Secretary",
4+
"type": "library",
5+
"license": "MIT",
6+
"keywords": [
77
"secrets",
88
"aws",
99
"aws secrets manager",
1010
"secretary"
1111
],
12-
"authors": [
12+
"authors": [
1313
{
14-
"name": "Aaron Scherer",
14+
"name": "Aaron Scherer",
1515
"email": "aequasi@gmail.com"
1616
}
1717
],
1818
"minimum-stability": "stable",
19-
"require": {
19+
"require": {
2020
"php": "^8.2",
21-
"ext-json": "*",
21+
"ext-json": "*",
2222
"aws/aws-sdk-php": "^3.0",
23-
"secretary/core": "self.version"
23+
"secretary/core": "self.version"
2424
},
25-
"require-dev": {
26-
"phpunit/phpunit": "^10.5 || ^11.0",
27-
"mockery/mockery": "^1.6.12"
28-
},
29-
"autoload": {
25+
"autoload": {
3026
"psr-4": {
3127
"Secretary\\Adapter\\AWS\\SecretsManager\\": ""
32-
}
33-
},
34-
"autoload-dev": {
35-
"psr-4": {
36-
"Secretary\\Adapter\\AWS\\SecretsManager\\Tests\\": "Tests/"
37-
}
28+
},
29+
"exclude-from-classmap": [
30+
"/Tests/"
31+
]
3832
}
3933
}

src/Adapter/Cache/PSR16Cache/composer.json

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,9 @@
2121
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0",
2222
"secretary/core": "self.version"
2323
},
24-
"require-dev": {
25-
"phpunit/phpunit": "^10.5 || ^11.0",
26-
"mockery/mockery": "^1.6.12"
27-
},
2824
"autoload": {
2925
"psr-4": {
3026
"Secretary\\Adapter\\Cache\\PSR16Cache\\": ""
3127
}
32-
},
33-
"autoload-dev": {
34-
"psr-4": {
35-
"Secretary\\Adapter\\Cache\\PSR16Cache\\Tests\\": "tests/"
36-
}
3728
}
3829
}

0 commit comments

Comments
 (0)