Issues (41)

tests/OfxParser/ParserTest.php (3 issues)

1
<?php declare(strict_types=1);
2
3
namespace OfxParserTest;
4
5
use PHPUnit\Framework\TestCase;
6
use OfxParser\Parser;
7
8
/**
9
 * @covers OfxParser\Parser
10
 */
11
final class ParserTest extends TestCase
12
{
13
    public function testCreditCardStatementTransactionsAreLoaded(): void
14
    {
15
        $parser = new Parser();
16
        $ofx = $parser->loadFromFile(__DIR__ . '/../fixtures/ofxdata-credit-card.ofx');
17
18
        $account = reset($ofx->bankAccounts);
19
        self::assertSame('1234567891234567', (string)$account->accountNumber);
20
    }
21
22
    public function testParseHeader(): void
23
    {
24
        $parser = new Parser();
25
        $ofx = $parser->loadFromFile(__DIR__ . '/../fixtures/ofxdata.ofx');
26
27
        $header = [
28
            'OFXHEADER' => '100',
29
            'DATA' => 'OFXSGML',
30
            'VERSION' => '103',
31
            'SECURITY' => 'NONE',
32
            'ENCODING' => 'USASCII',
33
            'CHARSET' => '1252',
34
            'COMPRESSION' => 'NONE',
35
            'OLDFILEUID' => 'NONE',
36
            'NEWFILEUID' => 'NONE',
37
        ];
38
39
        self::assertEquals($header, $ofx->header);
40
    }
41
42
    public function testParseXMLHeader(): void
43
    {
44
        $parser = new Parser();
45
        $ofx = $parser->loadFromFile(__DIR__ . '/../fixtures/ofxdata-xml.ofx');
46
47
        $header = [
48
            'OFXHEADER' => '200',
49
            'VERSION' => '200',
50
            'SECURITY' => 'NONE',
51
            'OLDFILEUID' => 'NONE',
52
            'NEWFILEUID' => 'NONE',
53
        ];
54
55
        self::assertSame($header, $ofx->header);
56
    }
57
58
    public function testXmlLoadStringThrowsExceptionWithInvalidXml()
59
    {
60
        $invalidXml = '<invalid xml>';
61
62
        $method = new \ReflectionMethod(Parser::class, 'xmlLoadString');
63
        $method->setAccessible(true);
64
65
        try {
66
            $method->invoke(new Parser(), $invalidXml);
67
        } catch (\Exception $e) {
68
            if (stripos($e->getMessage(), 'Failed to parse OFX') !== false) {
69
                $this->assertTrue(true);
70
                return true;
71
            }
72
73
            throw $e;
74
        } catch (\Throwable $e) {
75
            if (stripos($e->getMessage(), 'Failed to parse OFX') !== false) {
76
                $this->assertTrue(true);
77
                return true;
78
            }
79
80
            throw $e;
81
        }
82
83
        self::fail('Method xmlLoadString did not raise an expected exception parsing an invalid XML string');
84
    }
85
86
    public function testXmlLoadStringLoadsValidXml(): void
87
    {
88
        $validXml = '<fooRoot><foo>bar</foo></fooRoot>';
89
90
        $method = new \ReflectionMethod(Parser::class, 'xmlLoadString');
91
        $method->setAccessible(true);
92
93
        $xml = $method->invoke(new Parser(), $validXml);
94
95
        self::assertInstanceOf(\SimpleXMLElement::class, $xml);
96
        self::assertSame('bar', (string)$xml->foo);
97
    }
98
99
    /**
100
     * @return array<int, array<string>>
101
     */
102
    public function closeUnclosedXmlTagsProvider(): array
103
    {
104
        return [
105
            ['<SOMETHING>', '<SOMETHING>'],
106
            ['<SOMETHING>foo</SOMETHING>', '<SOMETHING>foo'],
107
            ['<SOMETHING>foo</SOMETHING>', '<SOMETHING>foo</SOMETHING>'],
108
            ['<BANKID>XXXXX</BANKID>', '<BANKID>XXXXX</BANKID>'],
109
            ['<ACCTID>XXXXXXXXXXX</ACCTID>', '<ACCTID>XXXXXXXXXXX</ACCTID>'],
110
            ['<ACCTID>-198.98</ACCTID>', '<ACCTID>-198.98</ACCTID>'],
111
            ['<ACCTID>-198.98</ACCTID>', '<ACCTID>-198.98'],
112
            ['<MEMO></MEMO>', '<MEMO>'],
113
        ];
114
    }
115
116
    /**
117
     * @dataProvider closeUnclosedXmlTagsProvider
118
     * @param $expected
119
     * @param $input
120
     */
121
    public function testCloseUnclosedXmlTags(string $expected, string $input): void
122
    {
123
        $method = new \ReflectionMethod(Parser::class, 'closeUnclosedXmlTags');
124
        $method->setAccessible(true);
125
126
        $parser = new Parser();
127
128
        self::assertEquals($expected, $method->invoke($parser, $input));
129
    }
130
131
    /**
132
     * @return array<int, array<string>>
133
     */
134
    public function convertSgmlToXmlProvider(): array
135
    {
136
        return [
137
            [<<<HERE
138
<SOMETHING>
139
    <FOO>bar
140
    <BAZ>bat</BAZ>
141
</SOMETHING>
142
HERE
143
        , <<<HERE
144
<SOMETHING>
145
<FOO>bar</FOO>
146
<BAZ>bat</BAZ>
147
</SOMETHING>
148
HERE
149
            ], [<<<HERE
150
<BANKACCTFROM>
151
<BANKID>XXXXX</BANKID>
152
<BRANCHID>XXXXX</BRANCHID>
153
<ACCTID>XXXXXXXXXXX</ACCTID>
154
<ACCTTYPE>CHECKING</ACCTTYPE>
155
</BANKACCTFROM>
156
HERE
157
                ,<<<HERE
158
<BANKACCTFROM>
159
<BANKID>XXXXX</BANKID>
160
<BRANCHID>XXXXX</BRANCHID>
161
<ACCTID>XXXXXXXXXXX</ACCTID>
162
<ACCTTYPE>CHECKING</ACCTTYPE>
163
</BANKACCTFROM>
164
HERE
165
            ],[<<<HERE
166
<SOMETHING>
167
    <FOO>bar & restaurant
168
    <BAZ>bat</BAZ>
169
</SOMETHING>
170
HERE
171
        , <<<HERE
172
<SOMETHING>
173
<FOO>bar &amp; restaurant</FOO>
174
<BAZ>bat</BAZ>
175
</SOMETHING>
176
HERE
177
            ],
178
        ];
179
    }
180
181
    /**
182
     * @dataProvider convertSgmlToXmlProvider
183
     */
184
    public function testConvertSgmlToXml($sgml, $expected): void
185
    {
186
        $method = new \ReflectionMethod(Parser::class, 'convertSgmlToXml');
187
        $method->setAccessible(true);
188
189
        self::assertEquals($expected, $method->invoke(new Parser, $sgml));
190
    }
191
192
    public function testLoadFromFileWhenFileDoesNotExist(): void
193
    {
194
        $this->expectException(\InvalidArgumentException::class);
195
196
        $parser = new Parser();
197
        $parser->loadFromFile('a non-existent file');
198
    }
199
200
    /**
201
     * @dataProvider loadFromStringProvider
202
     */
203
    public function testLoadFromFileWhenFileDoesExist(string $filename): void
204
    {
205
        if (!file_exists($filename)) {
206
            self::markTestSkipped('Could not find data file, cannot test loadFromFile method fully');
207
        }
208
209
        /** @var Parser|\PHPUnit_Framework_MockObject_MockObject $parser */
210
        $parser = $this->getMockBuilder(Parser::class)
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated: https://github.com/sebastianbergmann/phpunit/pull/3687 ( Ignorable by Annotation )

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

210
        $parser = /** @scrutinizer ignore-deprecated */ $this->getMockBuilder(Parser::class)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
211
                         ->setMethods(['loadFromString'])
212
                         ->getMock();
213
        $parser->expects(self::once())->method('loadFromString');
0 ignored issues
show
The method expects() does not exist on OfxParser\Parser. ( Ignorable by Annotation )

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

213
        $parser->/** @scrutinizer ignore-call */ 
214
                 expects(self::once())->method('loadFromString');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
214
        $parser->loadFromFile($filename);
215
    }
216
217
    /**
218
     * @return array
219
     */
220
    public function loadFromStringProvider(): array
221
    {
222
        return [
223
            'ofxdata.ofx' => [dirname(__DIR__).'/fixtures/ofxdata.ofx'],
224
            'ofxdata-oneline.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-oneline.ofx'],
225
            'ofxdata-cmfr.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-cmfr.ofx'],
226
            'ofxdata-bb.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-bb.ofx'],
227
            'ofxdata-bb-two-stmtrs.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-bb-two-stmtrs.ofx'],
228
            'ofxdata-credit-card.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-credit-card.ofx'],
229
            'ofxdata-bpbfc.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-bpbfc.ofx'],
230
            'ofxdata-memoWithQuotes.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-memoWithQuotes.ofx'],
231
            'ofxdata-emptyDateTime.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-emptyDateTime.ofx'],
232
            'ofxdata-memoWithAmpersand.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-memoWithAmpersand.ofx'],
233
            'ofxdata-banking-xml200.ofx' => [dirname(__DIR__).'/fixtures/ofxdata-banking-xml200.ofx'],
234
        ];
235
    }
236
237
    /**
238
     * @param string $filename
239
     * @throws \Exception
240
     * @dataProvider loadFromStringProvider
241
     */
242
    public function testLoadFromString($filename)
243
    {
244
        if (!file_exists($filename)) {
245
            self::markTestSkipped('Could not find data file, cannot test loadFromString method fully');
246
        }
247
248
        $content = file_get_contents($filename);
249
250
        $parser = new Parser();
251
252
        try {
253
            $parser->loadFromString($content);
254
        } catch (\Exception $e) {
255
            throw $e;
256
        }
257
258
        $this->assertTrue(true);
259
    }
260
261
    public function testXmlLoadStringWithSelfClosingTag()
262
    {
263
        $parser = new Parser();
264
265
        try {
266
            $ofx = $parser->loadFromFile(__DIR__ . '/../fixtures/ofxdata-selfclose.ofx');
0 ignored issues
show
The assignment to $ofx is dead and can be removed.
Loading history...
267
        } catch (\RuntimeException $e) {
268
            if (stripos($e->getMessage(), 'Failed to parse OFX') !== false) {
269
                self::assertTrue(false, 'Xml with invalid self closing tag');
270
            }
271
        }
272
273
        self::assertTrue(true);
274
    }
275
}
276