SesSdkTransportFactoryTest   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 100
c 0
b 0
f 0
dl 0
loc 200
rs 10
wmc 13

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getFactory() 0 3 1
A testCreate() 0 18 1
A testSupports() 0 5 1
A supportsProvider() 0 20 1
A testUnsupportedSchemeException() 0 10 2
A createProvider() 0 64 1
A createCredentialsResolver() 0 6 1
A getClient() 0 3 1
A getLogger() 0 3 1
A getDispatcher() 0 3 1
A createConfig() 0 6 1
A unsupportedSchemeProvider() 0 5 1
1
<?php
2
3
/*
4
 * This file is part of the badams/symfony-amazon-sdk-mailer package.
5
 *
6
 * (c) Byron Adams <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
use Aws\Credentials\Credentials;
13
use Badams\AmazonMailerSdk\SesSdkTransport;
14
use Badams\AmazonMailerSdk\SesSdkTransportFactory;
15
use GuzzleHttp\Promise\Promise;
16
use PHPUnit\Framework\TestCase;
17
use Psr\Log\LoggerInterface;
18
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
19
use Symfony\Component\Mailer\Transport\Dsn;
20
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
21
use Symfony\Component\Mailer\Transport\TransportInterface;
22
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
23
use Symfony\Contracts\HttpClient\HttpClientInterface;
24
25
class SesSdkTransportFactoryTest extends TestCase
26
{
27
    protected const USER = 'USER';
28
    protected const PASSWORD = 'PASS';
29
    protected const ENV_USER = 'ENV_USER';
30
    protected const ENV_PASSWORD = 'ENV_PASS';
31
    protected const INSTANCE_USER = 'INSTANCE_USER';
32
    protected const INSTANCE_PASSWORD = 'INSTANCE_PASS';
33
    protected const ECS_USER = 'ECS_USER';
34
    protected const ECS_PASSWORD = 'ECS_USER';
35
    protected const DEFAULT_USER = 'DEFAULT_USER';
36
    protected const DEFAULT_PASSWORD = 'DEFAULT_PASS';
37
38
    public function getFactory(): TransportFactoryInterface
39
    {
40
        return new SesSdkTransportFactory($this->getDispatcher(), $this->getClient(), $this->getLogger());
41
    }
42
43
    /**
44
     * @dataProvider createProvider
45
     * @param Dsn $dsn
46
     * @param TransportInterface $transport
47
     */
48
    public function testCreate(Dsn $dsn, TransportInterface $transport): void
49
    {
50
        $credentialsProviderMock = \Mockery::mock('overload:\Aws\Credentials\CredentialProvider');
51
        $credentialsProviderMock->allows([
52
            'fromCredentials' => $this->createCredentialsResolver(self::USER, self::PASSWORD),
53
            'env' => $this->createCredentialsResolver(self::ENV_USER, self::ENV_PASSWORD),
54
            'instanceProfile' => $this->createCredentialsResolver(self::INSTANCE_USER, self::INSTANCE_PASSWORD),
55
            'ecsCredentials' => $this->createCredentialsResolver(self::ECS_USER, self::ECS_PASSWORD),
56
            'defaultProvider' => $this->createCredentialsResolver(self::DEFAULT_USER, self::DEFAULT_PASSWORD),
57
        ]);
58
59
        $factory = $this->getFactory();
60
        $instance = $factory->create($dsn);
61
        $this->assertEquals($transport, $instance);
62
        $this->assertEquals((string)$transport, (string)$instance);
63
        $this->assertStringMatchesFormat($dsn->getScheme() . '://%S' . $dsn->getHost() . '%S', (string)$transport);
64
65
        \Mockery::close();
66
    }
67
68
69
    /**
70
     * @dataProvider supportsProvider
71
     */
72
    public function testSupports(Dsn $dsn, bool $supports): void
73
    {
74
        $factory = $this->getFactory();
75
76
        $this->assertSame($supports, $factory->supports($dsn));
77
    }
78
79
    /**
80
     * @dataProvider unsupportedSchemeProvider
81
     */
82
    public function testUnsupportedSchemeException(Dsn $dsn, string $message = null): void
83
    {
84
        $factory = $this->getFactory();
85
86
        $this->expectException(UnsupportedSchemeException::class);
87
        if (null !== $message) {
88
            $this->expectExceptionMessage($message);
89
        }
90
91
        $factory->create($dsn);
92
    }
93
94
95
    public function supportsProvider(): iterable
96
    {
97
        yield [
98
            new Dsn('ses+sdk', 'default'),
99
            true,
100
        ];
101
102
        yield [
103
            new Dsn('ses+https', 'default'),
104
            false,
105
        ];
106
107
        yield [
108
            new Dsn('ses+api', 'default'),
109
            false,
110
        ];
111
112
        yield [
113
            new Dsn('ses+smtp', 'default'),
114
            false,
115
        ];
116
    }
117
118
    public function createProvider(): iterable
119
    {
120
        $dispatcher = $this->getDispatcher();
121
        $logger = $this->getLogger();
122
123
        yield [
124
            new Dsn('ses+sdk', 'us-west-1', self::USER, self::PASSWORD),
125
            new SesSdkTransport(
126
                $this->createConfig(self::USER, self::PASSWORD,'us-west-1'),
127
                $dispatcher,
128
                $logger
129
            ),
130
        ];
131
132
        yield [
133
            new Dsn('ses+sdk', 'ap-south-2', null, null, null, [
134
                'credentials' => 'env',
135
            ]),
136
            new SesSdkTransport(
137
                $this->createConfig(self::ENV_USER, self::ENV_PASSWORD, 'ap-south-2'),
138
                $dispatcher,
139
                $logger
140
            ),
141
        ];
142
143
        yield [
144
            new Dsn('ses+sdk', 'ap-south-2', null, null, null, [
145
                'credentials' => 'instance',
146
            ]),
147
            new SesSdkTransport(
148
                $this->createConfig(self::INSTANCE_USER, self::INSTANCE_PASSWORD, 'ap-south-2'),
149
                $dispatcher,
150
                $logger
151
            ),
152
        ];
153
154
        yield [
155
            new Dsn('ses+sdk', 'eu-west-1', null, null, null, ['credentials' => 'ecs']),
156
            new SesSdkTransport(
157
                $this->createConfig(self::ECS_USER, self::ECS_PASSWORD,'eu-west-1'),
158
                $dispatcher,
159
                $logger
160
            ),
161
        ];
162
163
        yield [
164
            new Dsn('ses+sdk', 'eu-west-1', null, null, null),
165
            new SesSdkTransport(
166
                $this->createConfig(self::DEFAULT_USER, self::DEFAULT_PASSWORD,'eu-west-1'),
167
                $dispatcher,
168
                $logger
169
            ),
170
        ];
171
172
        yield [
173
            new Dsn('ses+sdk', 'ap-south-2', null, null, null, [
174
                'ConfigurationSetName' => 'TestConfigSet',
175
            ]),
176
            new SesSdkTransport(
177
                $this->createConfig(self::DEFAULT_USER, self::DEFAULT_PASSWORD, 'ap-south-2', [
178
                    'ConfigurationSetName' => 'TestConfigSet'
179
                ]),
180
                $dispatcher,
181
                $logger
182
            ),
183
        ];
184
    }
185
186
    public function unsupportedSchemeProvider(): iterable
187
    {
188
        yield [
189
            new Dsn('foobar', 'default', self::USER, self::PASSWORD),
190
            'The "foobar" scheme is not supported.',
191
        ];
192
    }
193
194
    private function createConfig($key, $secret, $region, $options = [])
195
    {
196
        return new \Badams\AmazonMailerSdk\SesSdkTransportConfig(
197
            $this->createCredentialsResolver($key, $secret),
198
            $region,
199
            $options
200
        );
201
    }
202
203
    private function createCredentialsResolver($key, $secret)
204
    {
205
        return function () use ($key, $secret) {
206
            $promise = new Promise();
207
            $promise->resolve(new Credentials($key, $secret));
208
            return $promise;
209
        };
210
    }
211
212
    protected function getDispatcher(): EventDispatcherInterface
213
    {
214
        return $this->dispatcher ?? $this->dispatcher = $this->createMock(EventDispatcherInterface::class);
0 ignored issues
show
Bug Best Practice introduced by
The property dispatcher does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug Best Practice introduced by
The expression return $this->dispatcher...atcherInterface::class) could return the type PHPUnit\Framework\MockObject\MockObject which is incompatible with the type-hinted return Symfony\Contracts\EventD...ventDispatcherInterface. Consider adding an additional type-check to rule them out.
Loading history...
215
    }
216
217
    protected function getClient(): HttpClientInterface
218
    {
219
        return $this->client ?? $this->client = $this->createMock(HttpClientInterface::class);
0 ignored issues
show
Bug Best Practice introduced by
The property client does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug Best Practice introduced by
The expression return $this->client ?? ...ClientInterface::class) could return the type PHPUnit\Framework\MockObject\MockObject which is incompatible with the type-hinted return Symfony\Contracts\HttpClient\HttpClientInterface. Consider adding an additional type-check to rule them out.
Loading history...
220
    }
221
222
    protected function getLogger(): LoggerInterface
223
    {
224
        return $this->logger ?? $this->logger = $this->createMock(LoggerInterface::class);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->logger ?? ...LoggerInterface::class) could return the type PHPUnit\Framework\MockObject\MockObject which is incompatible with the type-hinted return Psr\Log\LoggerInterface. Consider adding an additional type-check to rule them out.
Loading history...
Bug Best Practice introduced by
The property logger does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
225
    }
226
}