Passed
Pull Request — master (#2)
by Samuel
01:59 queued 21s
created

ClientTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
dl 0
loc 11
c 1
b 0
f 0
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
4
namespace Elmage\TextNg\Test\Unit;
5
6
use Elmage\TextNg\Authentication\ApiKeyAuthentication;
7
use Elmage\TextNg\Client;
8
use Elmage\TextNg\Configuration;
9
use Elmage\TextNg\Enum\DeliveryReportReq;
10
use Elmage\TextNg\Enum\Param;
11
use Elmage\TextNg\Enum\Route;
12
use Elmage\TextNg\Exception\InvalidParamException;
13
use Elmage\TextNg\Exception\SendingLimitException;
14
use Elmage\TextNg\HttpClient;
15
use Elmage\TextNg\Test\TestCase;
16
use GuzzleHttp\Psr7\Response;
17
use PHPUnit\Framework\MockObject\MockObject;
18
use Psr\Http\Message\ResponseInterface;
19
use Psr\Http\Message\StreamInterface;
20
21
class ClientTest extends TestCase
22
{
23
    /** @var MockObject|HttpClient */
24
    private $http;
25
26
    /** @var Client */
27
    private $client;
28
29
    public static function setUpBeforeClass(): void
30
    {
31
        date_default_timezone_set('Africa/Lagos');
32
    }
33
34
    protected function setUp(): void
35
    {
36
        $this->http = $this->getMockBuilder(HttpClient::class)
37
            ->disableOriginalConstructor()
38
            ->getMock();
39
40
        $this->http->expects($this->any())
41
            ->method('getSender')
42
            ->willReturn('Test');
43
44
        $this->client = new Client($this->http);
45
    }
46
47
    protected function tearDown(): void
48
    {
49
        $this->http = null;
50
        $this->client = null;
51
    }
52
53
    public function testGetBalance()
54
    {
55
        $this->http->expects($this->any())
56
            ->method('get')
57
            ->with('/smsbalance/', [Param::CHECK_BALANCE => 1])
58
            ->willReturn($this->getMockResponse('{"D":{"details":[{"key":"TEST_KEY","unitsbalance":"20","time":"2000-01-01 01:10:15","status":"successful"}]}}'));
59
60
        $actual = $this->client->getBalance();
61
        $this->assertIsArray($actual, "Array expected, got " . gettype($actual));
62
63
        $keys = ["unitsbalance", "time", "status"];
64
        foreach ($keys as $key) {
65
            $this->assertArrayHasKey($key, $actual, "Expected array to contain {$key}");
66
        }
67
68
        $this->assertArrayNotHasKey(Param::API_KEY, $actual, "Array should not contain API key.");
69
    }
70
71
    /**
72
     * @dataProvider provideFortestSendSMS
73
     */
74
    public function testSendSMS(int $route, string $phone, string $message, string $sender, string $bypasscode)
75
    {
76
        $this->http->expects($this->any())
77
            ->method('post')
78
            ->with('/pushsms/', [
79
                Param::ROUTE => $route,
80
                Param::PHONE => $phone,
81
                Param::MESSAGE => $message,
82
                Param::SENDER => $sender,
83
                Param::BYPASSCODE => $bypasscode
84
            ])
85
            ->willReturn($this->getMockResponse('5 units used|| Status:Successful|| Route:5|| Type:single number|| Reference:4567ygfrthyi'));
86
87
        $actual = $this->client->sendOTP($route, $phone, $message, $bypasscode);
88
89
        $this->assertIsArray($actual, "Array expected, got " . gettype($actual));
90
91
        $keys = ["units_used", "status", "type", "reference", "route"];
92
93
        foreach ($keys as $key) {
94
            $this->assertArrayHasKey($key, $actual, "Expected array to contain {$key}");
95
        }
96
    }
97
98
    public function provideFortestSendSMS(): array
99
    {
100
        return [
101
            //route phone     message          sender  bypasscode
102
            [3, '0806754345', "Otp is 675543", "Test", "2345678909"],
103
            [4, '0806754345', "Otp is 675543", "Test", "2345678909"],
104
            [5, '0806754345', "Otp is 675543", "Test", "2345678909"],
105
            [6, '0806754345', "Otp is 675543", "Test", "2345678909"],
106
        ];
107
    }
108
109
    public function testSendSMSErrorCase()
110
    {
111
        $this->http->expects($this->any())
112
            ->method('post')
113
            ->with('/pushsms/', [
114
                Param::ROUTE => Route::RECOMMENDED,
115
                Param::PHONE => "0806",
116
                Param::MESSAGE => "TEST",
117
                Param::SENDER => "Test",
118
                Param::BYPASSCODE => "test"
119
            ])
120
            ->willReturn($this->getMockResponse('ERROR insufficient units'));
121
122
        $actual = $this->client->sendSMS(Route::RECOMMENDED, ["0806"], "TEST", "test");
123
124
        $this->assertIsArray($actual, "Array expected, got " . gettype($actual));
125
126
        $keys = ["status", "message"];
127
        foreach ($keys as $key) {
128
            $this->assertArrayHasKey($key, $actual, "Expected array to contain {$key}");
129
        }
130
    }
131
132
    public function testSendSMSThrowsInvalidParamExceptions()
133
    {
134
        $this->expectException(InvalidParamException::class);
135
        $this->client->sendSMS(7, ["0806709"], "Sample Message", "088776");
136
    }
137
138
139
    public function testSendSMSThrowsSendingLimitExceptions()
140
    {
141
        $this->expectException(SendingLimitException::class);
142
        $this->client->sendSMS(Route::RECOMMENDED, range(100, 100500), "Sample Message", "088776");
143
    }
144
145
    public function testGetDeliveryReport()
146
    {
147
        $ref = "9837092678";
148
149
        $this->http->expects($this->any())
150
            ->method('get')
151
            ->with('/deliveryreport/', [
152
                Param::USED_ROUTE => Route::RECOMMENDED,
153
                Param::REFERENCE => $ref,
154
                Param::REQ => DeliveryReportReq::ALL
155
            ])
156
            ->willReturn($this->getMockResponse(
157
                '{"D":{"details":[{"number":"234XXXXXXXXX","status":"DELIVERED","track_id":"xxxxxxxxxx"},
158
                {"number":"234XXXXXXXXX","status":"DELIVRD","track_id":"xxxxxxxxxx"},
159
                {"number":"234XXXXXXXXX","status":"SENT-VIA-BYPASS","track_id":"xxxxxxxxxx"},
160
                {"number":"234XXXXXXXXX","status":"SENT-BUT-PENDING","track_id":"xxxxxxxxxx"},
161
                {"number":"234XXXXXXXXX","status":"BLOCKED","track_id":"xxxxxxxxxx"}]}}'
162
            ));
163
164
        $actual = $this->client->getDeliveryReport($ref, DeliveryReportReq::ALL, Route::RECOMMENDED);
165
166
        $this->assertIsArray($actual, "Array expected, got " . gettype($actual));
167
        $this->assertArrayHasKey("data", $actual, "Expected array to contain 'details'");
168
169
        $this->assertIsArray($actual['data'], "Array expected, got " . gettype($actual['data']));
170
171
        $test_data = $actual['data'][0];
172
        $keys = ["number", "status", "track_id"];
173
174
        foreach ($keys as $key) {
175
            $this->assertArrayHasKey($key, $test_data, "Expected array item to contain {$key}");
176
        }
177
178
        $this->expectException(InvalidParamException::class);
179
        $this->client->getDeliveryReport($ref, DeliveryReportReq::ALL, 10);
180
    }
181
182
183
    public function testCreateMethod()
184
    {
185
        $config = new Configuration(new ApiKeyAuthentication("TEST"), "Test");
186
        $client = Client::create($config);
187
188
        $this->assertInstanceOf(Client::class, $client);
189
        $this->assertInstanceOf(HttpClient::class, $client->getHttpClient());
190
191
        $client->setSender("Test2");
192
193
        $this->assertEquals("Test2", $client->getHttpClient()->getSender());
194
    }
195
    /*------------------------------------------------------------------------------
196
    | PRIVATE METHODS
197
    /*------------------------------------------------------------------------------*/
198
199
200
    /**
201
     * @param $data
202
     * @return MockObject|ResponseInterface
203
     */
204
    private function getMockResponse($data)
205
    {
206
        $response = $this->createMock(ResponseInterface::class);
207
        $stream = $this->createMock(StreamInterface::class);
208
209
        if (is_array($data)) {
210
            $data = json_encode((object)$data);
211
        }
212
213
        $response->expects($this->any())
214
            ->method('getBody')
215
            ->willReturn($stream);
216
        $stream->expects($this->any())
217
            ->method('__toString')
218
            ->willReturn($data);
219
220
        return $response;
221
    }
222
}
223