Skip to content

Commit a9bbe55

Browse files
committed
wip: json first
1 parent b012ffe commit a9bbe55

File tree

2 files changed

+105
-11
lines changed

2 files changed

+105
-11
lines changed

src/Kernel/Support/MessageParser.php

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,20 @@ class MessageParser
1818
*/
1919
public static function parse(string $content): array
2020
{
21-
// Try XML format if content starts with '<'
22-
if (stripos($content, '<') === 0) {
23-
$parsed = Xml::parse($content);
21+
$content = trim($content);
2422

25-
if (is_array($parsed) && ! empty($parsed)) {
26-
/** @var array<string, mixed> $parsed */
27-
return $parsed;
28-
}
23+
// Try JSON format first
24+
$parsed = json_decode($content, true);
2925

30-
throw new BadRequestException('Failed to decode XML content.');
26+
if (json_last_error() === JSON_ERROR_NONE && is_array($parsed) && ! empty($parsed)) {
27+
/** @var array<string, mixed> $parsed */
28+
return $parsed;
3129
}
3230

33-
// Otherwise try JSON format
34-
$parsed = json_decode($content, true);
31+
// If JSON decode failed or result is not an array, try XML format
32+
$parsed = Xml::parse($content);
3533

36-
if (json_last_error() === JSON_ERROR_NONE && $content !== '' && is_array($parsed) && ! empty($parsed)) {
34+
if (is_array($parsed) && ! empty($parsed)) {
3735
/** @var array<string, mixed> $parsed */
3836
return $parsed;
3937
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EasyWeChat\Tests\Kernel\Support;
6+
7+
use EasyWeChat\Kernel\Exceptions\BadRequestException;
8+
use EasyWeChat\Kernel\Support\MessageParser;
9+
use EasyWeChat\Tests\TestCase;
10+
11+
class MessageParserTest extends TestCase
12+
{
13+
public function test_it_can_parse_json_content()
14+
{
15+
$content = '{"key":"value","number":123}';
16+
$result = MessageParser::parse($content);
17+
18+
$this->assertIsArray($result);
19+
$this->assertSame('value', $result['key']);
20+
$this->assertSame(123, $result['number']);
21+
}
22+
23+
public function test_it_can_parse_json_with_whitespace()
24+
{
25+
$content = " \n\t {\"key\":\"value\"} \n ";
26+
$result = MessageParser::parse($content);
27+
28+
$this->assertIsArray($result);
29+
$this->assertSame('value', $result['key']);
30+
}
31+
32+
public function test_it_falls_back_to_xml_when_json_decode_fails()
33+
{
34+
$content = '<xml><key>value</key><number>123</number></xml>';
35+
$result = MessageParser::parse($content);
36+
37+
$this->assertIsArray($result);
38+
$this->assertSame('value', $result['key']);
39+
$this->assertSame('123', $result['number']);
40+
}
41+
42+
public function test_it_falls_back_to_xml_when_json_is_not_array()
43+
{
44+
// JSON string (not an array) should fall back to XML
45+
// Since it's not valid XML either, it should throw exception
46+
$this->expectException(BadRequestException::class);
47+
MessageParser::parse('"just a string"');
48+
}
49+
50+
public function test_it_falls_back_to_xml_when_json_is_empty_array()
51+
{
52+
// Empty JSON array should fall back to XML
53+
// Since empty array is not valid XML, it should throw exception
54+
$this->expectException(BadRequestException::class);
55+
MessageParser::parse('[]');
56+
}
57+
58+
public function test_it_falls_back_to_xml_when_json_is_not_array_but_xml_is_valid()
59+
{
60+
// JSON that parses to a string (not array) should fall back to XML
61+
// If the content is also valid XML, it should parse as XML
62+
$content = '<xml><key>value</key></xml>';
63+
$result = MessageParser::parse($content);
64+
65+
$this->assertIsArray($result);
66+
$this->assertSame('value', $result['key']);
67+
}
68+
69+
public function test_it_throws_exception_when_both_json_and_xml_fail()
70+
{
71+
$this->expectException(BadRequestException::class);
72+
$this->expectExceptionMessage('Failed to decode content. Content must be valid XML or JSON.');
73+
74+
MessageParser::parse('invalid content');
75+
}
76+
77+
public function test_it_prioritizes_json_over_xml()
78+
{
79+
// Content that could be both valid JSON and valid XML
80+
// JSON should be parsed first
81+
$content = '{"xml":"value"}';
82+
$result = MessageParser::parse($content);
83+
84+
$this->assertIsArray($result);
85+
$this->assertSame('value', $result['xml']);
86+
}
87+
88+
public function test_it_can_parse_xml_with_whitespace()
89+
{
90+
$content = " \n <xml><key>value</key></xml> \n ";
91+
$result = MessageParser::parse($content);
92+
93+
$this->assertIsArray($result);
94+
$this->assertSame('value', $result['key']);
95+
}
96+
}

0 commit comments

Comments
 (0)