Issues (22)

tests/UtilsTest.php (6 issues)

1
<?php
2
3
namespace Lifeboat\Tests;
4
5
use Lifeboat\CurlResponse;
6
use Lifeboat\Exceptions\InvalidArgumentException;
7
use Lifeboat\Utils\ArrayLib;
8
use Lifeboat\Utils\Curl;
9
use Lifeboat\Utils\URL;
10
use Lifeboat\Utils\Utils;
11
use PHPUnit\Framework\TestCase;
0 ignored issues
show
This use statement conflicts with another class in this namespace, Lifeboat\Tests\TestCase. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
12
13
/**
14
 * Class UtilsTest
15
 * @package Lifeboat\Tests
16
 */
17
class UtilsTest extends TestCase {
18
19
    /**
20
     * @test
21
     * @covers \Lifeboat\Utils\ArrayLib::is_associative
22
     */
23
    public function test_is_associative_array()
24
    {
25
        $this->assertEquals(true, ArrayLib::is_associative(['a' => 1]));
26
        $this->assertEquals(false, ArrayLib::is_associative([1,2,3]));
27
        $this->assertEquals(false, ArrayLib::is_associative([]));
28
29
        try {
30
            ArrayLib::is_associative(new \stdClass());
0 ignored issues
show
new stdClass() of type stdClass is incompatible with the type array expected by parameter $array of Lifeboat\Utils\ArrayLib::is_associative(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

30
            ArrayLib::is_associative(/** @scrutinizer ignore-type */ new \stdClass());
Loading history...
31
            $this->fail('ArrayLib::is_associative should not accept non array parameters');
32
        } catch (\TypeError $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
33
34
        try {
35
            ArrayLib::is_associative('123');
0 ignored issues
show
'123' of type string is incompatible with the type array expected by parameter $array of Lifeboat\Utils\ArrayLib::is_associative(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

35
            ArrayLib::is_associative(/** @scrutinizer ignore-type */ '123');
Loading history...
36
            $this->fail('ArrayLib::is_associative should not accept non array parameters');
37
        } catch (\TypeError $e) {
38
            // Error should be thrown
39
        }
40
    }
41
42
    /**
43
     * @test
44
     * @covers \Lifeboat\Utils\URL::is_absolute_url
45
     */
46
    public function test_is_absolute()
47
    {
48
        $this->assertFalse(URL::is_absolute_url('/'));
49
        $this->assertFalse(URL::is_absolute_url('/123'));
50
        $this->assertFalse(URL::is_absolute_url('/123?a'));
51
        $this->assertFalse(URL::is_absolute_url('local.test/123?a'));
52
        $this->assertFalse(URL::is_absolute_url('/#'));
53
54
        $this->assertTrue(URL::is_absolute_url('://local.test'));
55
        $this->assertTrue(URL::is_absolute_url('https://local.test'));
56
        $this->assertTrue(URL::is_absolute_url('https://local.test/'));
57
        $this->assertTrue(URL::is_absolute_url('https://local.test?a'));
58
        $this->assertTrue(URL::is_absolute_url('https://local.test/?a'));
59
        $this->assertTrue(URL::is_absolute_url('https://local.test/#'));
60
        $this->assertTrue(URL::is_absolute_url('https://local.test#'));
61
        $this->assertTrue(URL::is_absolute_url('https://user:[email protected]#'));
62
    }
63
64
    /**
65
     * @test
66
     * @covers \Lifeboat\Utils\URL::setGetVar
67
     */
68
    public function test_set_get_var()
69
    {
70
        $rel_path = '/path';
71
        $this->assertEquals($rel_path . '?var=1', URL::setGetVar('var', 1, $rel_path));
72
73
        $rel_path_t = '/path/';
74
        $this->assertEquals($rel_path_t . '?var=1', URL::setGetVar('var', 1, $rel_path_t));
75
76
        $absolute = 'https://test.com';
77
        $this->assertEquals($absolute . '?var=1', URL::setGetVar('var', 1, $absolute));
78
79
        $absolute_t = 'https://test.com/';
80
        $this->assertEquals($absolute_t . '?var=1', URL::setGetVar('var', 1, $absolute_t));
81
    }
82
83
    /**
84
     * @test
85
     * @covers \Lifeboat\Utils\Utils::create_random_string
86
     */
87
    public function test_create_random_string()
88
    {
89
        // Test the length of the generated string
90
        $this->assertTrue(strlen(Utils::create_random_string()) === 24);
91
92
        // Test that only the supplied characters are used
93
        $this->assertTrue(intval(Utils::create_random_string(2, '123456789')) > 0);
94
95
        // Test the randomness
96
        $generated = [];
97
        while (count($generated) < 100000) $generated[] = Utils::create_random_string();
98
        $count  = count($generated);
99
        $unique = count(array_unique($generated));
100
        $random = 100 - ((100 / $count) * $unique);
101
102
        // Less than 2% repeat
103
        $this->assertTrue($random < 2);
104
    }
105
106
    /**
107
     * @test
108
     * @covers \Lifeboat\Utils\Curl::__construct
109
     * @covers \Lifeboat\Utils\Curl::getURL
110
     * @covers \Lifeboat\Utils\Curl::setURL
111
     * @covers \Lifeboat\Utils\Curl::addDataParam
112
     * @covers \Lifeboat\Utils\Curl::getDataParams
113
     * @covers \Lifeboat\Utils\Curl::addHeader
114
     * @covers \Lifeboat\Utils\Curl::getHeaders
115
     * @covers \Lifeboat\Utils\Curl::removeHeader
116
     * @covers \Lifeboat\Utils\Curl::isFileUpload
117
     * @covers \Lifeboat\Utils\Curl::setIsFileUpload
118
     * @covers \Lifeboat\Utils\Curl::removeDataParam
119
     */
120
    public function test_curl_construct()
121
    {
122
        $params     = ['a' => 1];
123
        $headers    = ['header' => 'value'];
124
        $curl       = new Curl('/url', $params, $headers);
125
126
        // Remove the default headers
127
        $curl->removeHeader('Content-Type');
128
        $curl->removeHeader('X-Requested-By');
129
130
        $this->assertEquals('/url', $curl->getURL());
131
        $this->assertEquals($headers, $curl->getHeaders());
132
        $this->assertEquals($params, $curl->getDataParams());
133
134
        $curl->removeDataParam('a');
135
        $this->assertEquals([], $curl->getDataParams());
136
137
        $this->assertFalse($curl->isFileUpload());
138
        $curl->setIsFileUpload(true);
139
        $this->assertTrue($curl->isFileUpload());
140
141
        $headers_set = $curl->getHeaders();
142
        if (!array_key_exists('Content-Type', $headers_set) ||
143
            $headers_set['Content-Type'] !== 'multipart/form-data') {
144
            $this->fail('Curl::setIsFileUpload() did not set the correct headers');
145
        }
146
147
        try {
148
            new Curl('/url', '123', 'abc');
0 ignored issues
show
'123' of type string is incompatible with the type array expected by parameter $data of Lifeboat\Utils\Curl::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

148
            new Curl('/url', /** @scrutinizer ignore-type */ '123', 'abc');
Loading history...
'abc' of type string is incompatible with the type array expected by parameter $headers of Lifeboat\Utils\Curl::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

148
            new Curl('/url', '123', /** @scrutinizer ignore-type */ 'abc');
Loading history...
149
            $this->fail('Curl::__construct parameters 2 and 3 should of type array only');
150
        } catch (\TypeError $e) {
151
            // Error should be thrown
152
        }
153
    }
154
155
    /**
156
     * @test
157
     * @covers \Lifeboat\Utils\Curl::setMethod
158
     * @covers \Lifeboat\Utils\Curl::getMethod
159
     */
160
    public function test_set_curl_method()
161
    {
162
        $curl = new Curl('/');
163
164
        $this->assertEquals('GET', $curl->getMethod());
165
166
        // Set method should be case insensitive
167
        $curl->setMethod('pOsT');
168
        $this->assertEquals('POST', $curl->getMethod());
169
170
        try {
171
            $curl->setMethod('GET');
172
            $curl->setMethod('POST');
173
            $curl->setMethod('PUT');
174
            $curl->setMethod('DELETE');
175
        } catch (InvalidArgumentException $e) {
176
            $this->fail('Curl::setMethod should accept GET,POST,PUT,DELETE');
177
        }
178
179
        try {
180
            $curl->setMethod('X');
181
            $this->fail('Curl::setMethod should only accept valid HTTP methods');
182
        } catch (InvalidArgumentException $e) {
183
            // Error should be thrown
184
        }
185
    }
186
187
    /**
188
     * @test
189
     *
190
     * @covers \Lifeboat\CurlResponse::__construct
191
     * @covers \Lifeboat\CurlResponse::getRaw
192
     * @covers \Lifeboat\CurlResponse::getHTTPCode
193
     * @covers \Lifeboat\CurlResponse::isValid
194
     * @covers \Lifeboat\CurlResponse::isJSON
195
     * @covers \Lifeboat\CurlResponse::getError
196
     * @covers \Lifeboat\CurlResponse::getErrors
197
     * @covers \Lifeboat\CurlResponse::getJSON
198
     */
199
    public function test_curl_response()
200
    {
201
        // Non-JSON
202
        $response = new CurlResponse(204, 'No Content');
203
        $this->assertEquals('No Content', $response->getRaw());
204
        $this->assertEquals(204, $response->getHTTPCode());
205
        $this->assertTrue($response->isValid());
206
        $this->assertFalse($response->isJSON());
207
208
        // JSON
209
        $json = new CurlResponse(400, '{"errors":[{"error":"xxx"}]}');
210
        $this->assertFalse($json->isValid());
211
        $this->assertTrue($json->isJSON());
212
        $this->assertEquals([['error' => 'xxx']], $json->getErrors());
213
        $this->assertEquals(['errors' => [['error' => 'xxx']]], $json->getJSON());
214
        $this->assertEquals('xxx', $json->getError());
215
    }
216
}
217