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 & 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
|
|||||||
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
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. ![]() |
|||||||
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
|
|||||||
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 |
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.