Completed
Pull Request — master (#912)
by
unknown
07:49
created

DatabaseHelperTest   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 1
dl 0
loc 200
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getHelper() 0 7 1
A testHelperInstance() 0 4 1
A getConnection() 0 4 1
A dsn() 0 4 1
A mysqlUserHasPrivilege() 0 4 1
B getMysqlVariableValue() 0 25 2
B getMysqlVariable() 0 37 3
B getTables() 0 36 1
A resolveTables() 0 19 1
A tearDown() 0 11 2
1
<?php
2
3
namespace N98\Util\Console\Helper;
4
5
use InvalidArgumentException;
6
use N98\Magento\Command\TestCase;
7
use RuntimeException;
8
9
/**
10
 * Class DatabaseHelperTest
11
 *
12
 * @covers  N98\Util\Console\Helper\DatabaseHelper
13
 */
14
class DatabaseHelperTest extends TestCase
15
{
16
    /**
17
     * @var array of functions to call on teardown
18
     * @see tearDown()
19
     */
20
    private $tearDownRestore = array();
21
22
    /**
23
     * @return DatabaseHelper
24
     */
25
    protected function getHelper()
26
    {
27
        $command = $this->getApplication()->find('db:info');
28
        $command->getHelperSet()->setCommand($command);
29
30
        return $command->getHelper('database');
31
    }
32
33
    /**
34
     * @test
35
     */
36
    public function testHelperInstance()
37
    {
38
        $this->assertInstanceOf('\N98\Util\Console\Helper\DatabaseHelper', $this->getHelper());
39
    }
40
41
    /**
42
     * @test
43
     */
44
    public function getConnection()
45
    {
46
        $this->assertInstanceOf('\PDO', $this->getHelper()->getConnection());
47
    }
48
49
    /**
50
     * @test
51
     */
52
    public function dsn()
53
    {
54
        $this->assertStringStartsWith('mysql:', $this->getHelper()->dsn());
55
    }
56
57
    /**
58
     * @test
59
     */
60
    public function mysqlUserHasPrivilege()
61
    {
62
        $this->assertTrue($this->getHelper()->mysqlUserHasPrivilege('SELECT'));
63
    }
64
65
    /**
66
     * @test
67
     */
68
    public function getMysqlVariableValue()
69
    {
70
        $helper = $this->getHelper();
71
72
        // verify (complex) return value with existing global variable
73
        $actual = $helper->getMysqlVariableValue('version');
74
75
        $this->assertInternalType('array', $actual);
76
        $this->assertCount(1, $actual);
77
        $key = '@@version';
78
        $this->assertArrayHasKey($key, $actual);
79
        $this->assertInternalType('string', $actual[$key]);
80
81
        // quoted
82
        $actual = $helper->getMysqlVariableValue('`version`');
83
        $this->assertEquals('@@`version`', key($actual));
84
85
        // non-existent global variable
86
        try {
87
            $helper->getMysqlVariableValue('nonexistent');
88
            $this->fail('An expected exception has not been thrown');
89
        } catch (RuntimeException $e) {
90
            $this->assertEquals("Failed to query mysql variable 'nonexistent'", $e->getMessage());
91
        }
92
    }
93
94
    /**
95
     * @test
96
     */
97
    public function getMysqlVariable()
98
    {
99
        $helper = $this->getHelper();
100
101
        // behaviour with existing global variable
102
        $actual = $helper->getMysqlVariable('version');
103
        $this->assertInternalType('string', $actual);
104
105
        // behavior with existent session variable (INTEGER)
106
        $helper->getConnection()->query('SET @existent = 14;');
107
        $actual = $helper->getMysqlVariable('existent', '@');
108
        $this->assertSame("14", $actual);
109
110
        // behavior with non-existent session variable
111
        $actual = $helper->getMysqlVariable('nonexistent', '@');
112
        $this->assertNull($actual);
113
114
        // behavior with non-existent global variable
115
        try {
116
            $helper->getMysqlVariable('nonexistent');
117
            $this->fail('An expected Exception has not been thrown');
118
        } catch (RuntimeException $e) {
119
            // test against the mysql error message
120
            $this->assertStringEndsWith("SQLSTATE[HY000]: 1193: Unknown system variable 'nonexistent'", $e->getMessage());
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
121
        }
122
123
        // invalid variable type
124
        try {
125
            $helper->getMysqlVariable('nonexistent', '@@@');
126
            $this->fail('An expected Exception has not been thrown');
127
        } catch (InvalidArgumentException $e) {
128
            // test against the mysql error message
129
            $this->assertEquals(
130
                'Invalid mysql variable type "@@@", must be "@@" (system) or "@" (session)', $e->getMessage()
131
            );
132
        }
133
    }
134
135
    /**
136
     * @test
137
     */
138
    public function getTables()
139
    {
140
        $helper = $this->getHelper();
141
142
        $tables = $helper->getTables();
143
        $this->assertInternalType('array', $tables);
144
        $this->assertContains('admin_user', $tables);
145
146
        $dbSettings = $helper->getDbSettings();
147
        $ro = new \ReflectionObject($dbSettings);
148
        $rp = $ro->getProperty('config');
149
        $rp->setAccessible(true);
150
151
        $config = $rp->getValue($dbSettings);
152
        $previous = $config['prefix'];
153
154
        $this->tearDownRestore[] = function () use ($rp, $dbSettings, $previous) {
155
            $config['prefix'] = $previous;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$config was never initialized. Although not strictly required by PHP, it is generally a good practice to add $config = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
156
            $rp->setValue($dbSettings, $config);
157
        };
158
159
        $config['prefix'] = $previous . 'core_';
160
        $rp->setValue($dbSettings, $config);
161
162
        $tables = $helper->getTables(null); // default value should be null-able and is false
163
        $this->assertInternalType('array', $tables);
164
        $this->assertNotContains('admin_user', $tables);
165
        $this->assertContains('core_store', $tables);
166
        $this->assertContains('core_website', $tables);
167
168
        $tables = $helper->getTables(true);
169
        $this->assertInternalType('array', $tables);
170
        $this->assertNotContains('admin_user', $tables);
171
        $this->assertContains('store', $tables);
172
        $this->assertContains('website', $tables);
173
    }
174
175
    /**
176
     * @test
177
     */
178
    public function resolveTables()
179
    {
180
        $tables = $this->getHelper()->resolveTables(array('catalog\_*'));
181
        $this->assertContains('catalog_product_entity', $tables);
182
        $this->assertNotContains('catalogrule', $tables);
183
184
        $definitions = array(
185
            'test123'  => array('tables'  => 'catalog\_*'),
186
            'dataflow' => array('tables' => 'dataflow_batch_import dataflow_batch_export'),
187
        );
188
189
        $tables = $this->getHelper()->resolveTables(
190
            array('@test123', '@dataflow'),
191
            $definitions
192
        );
193
        $this->assertContains('catalog_product_entity', $tables);
194
        $this->assertContains('dataflow_batch_import', $tables);
195
        $this->assertNotContains('catalogrule', $tables);
196
    }
197
198
    /**
199
     * Tears down the fixture, for example, close a network connection.
200
     * This method is called after a test is executed.
201
     */
202
    protected function tearDown()
203
    {
204
        foreach ($this->tearDownRestore as $restore) {
205
            $restore();
206
        }
207
208
        $restore = null;
0 ignored issues
show
Unused Code introduced by
$restore is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
209
        $this->tearDownRestore = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $tearDownRestore.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
210
211
        parent::tearDown();
212
    }
213
}
214