|
4 | 4 |
|
5 | 5 | use Illuminate\Support\Facades\Route; |
6 | 6 | use Laravel\Boost\Mcp\Tools\ListRoutes; |
7 | | -use Laravel\Mcp\Server\Tools\ToolResult; |
8 | 7 |
|
9 | 8 | beforeEach(function () { |
10 | 9 | Route::get('/admin/dashboard', function () { |
|
36 | 35 | $tool = new ListRoutes; |
37 | 36 | $result = $tool->handle([]); |
38 | 37 |
|
39 | | - expect($result)->toBeInstanceOf(ToolResult::class); |
40 | | - $data = $result->toArray(); |
41 | | - expect($data['isError'])->toBeFalse() |
42 | | - ->and($data['content'][0]['text'])->toBeString() |
43 | | - ->and($data['content'][0]['text'])->toContain('GET|HEAD') |
44 | | - ->and($data['content'][0]['text'])->toContain('admin.dashboard') |
45 | | - ->and($data['content'][0]['text'])->toContain('user.profile'); |
| 38 | + expect($result)->isToolResult() |
| 39 | + ->toolHasNoError() |
| 40 | + ->toolTextContains('GET|HEAD', 'admin.dashboard', 'user.profile'); |
46 | 41 | }); |
47 | 42 |
|
48 | 43 | test('it sanitizes name parameter wildcards and filters correctly', function () { |
49 | 44 | $tool = new ListRoutes; |
50 | 45 |
|
51 | 46 | $result = $tool->handle(['name' => '*admin*']); |
52 | | - $output = $result->toArray()['content'][0]['text']; |
53 | 47 |
|
54 | | - expect($result)->toBeInstanceOf(ToolResult::class) |
55 | | - ->and($result->toArray()['isError'])->toBeFalse() |
56 | | - ->and($output)->toContain('admin.dashboard') |
57 | | - ->and($output)->toContain('admin.users.store') |
58 | | - ->and($output)->not->toContain('user.profile') |
59 | | - ->and($output)->not->toContain('two-factor.enable'); |
| 48 | + expect($result)->isToolResult() |
| 49 | + ->toolHasNoError() |
| 50 | + ->toolTextContains('admin.dashboard', 'admin.users.store') |
| 51 | + ->and($result)->not->toolTextContains('user.profile', 'two-factor.enable'); |
60 | 52 |
|
61 | 53 | $result = $tool->handle(['name' => '*two-factor*']); |
62 | | - $output = $result->toArray()['content'][0]['text']; |
63 | 54 |
|
64 | | - expect($output)->toContain('two-factor.enable') |
65 | | - ->and($output)->not->toContain('admin.dashboard') |
66 | | - ->and($output)->not->toContain('user.profile'); |
| 55 | + expect($result)->toolTextContains('two-factor.enable') |
| 56 | + ->and($result)->not->toolTextContains('admin.dashboard', 'user.profile'); |
67 | 57 |
|
68 | 58 | $result = $tool->handle(['name' => '*api*']); |
69 | | - $output = $result->toArray()['content'][0]['text']; |
70 | 59 |
|
71 | | - expect($output)->toContain('api.posts.index') |
72 | | - ->and($output)->toContain('api.posts.update') |
73 | | - ->and($output)->not->toContain('admin.dashboard') |
74 | | - ->and($output)->not->toContain('user.profile'); |
| 60 | + expect($result)->toolTextContains('api.posts.index', 'api.posts.update') |
| 61 | + ->and($result)->not->toolTextContains('admin.dashboard', 'user.profile'); |
| 62 | + |
75 | 63 | }); |
76 | 64 |
|
77 | 65 | test('it sanitizes method parameter wildcards and filters correctly', function () { |
78 | 66 | $tool = new ListRoutes; |
79 | 67 |
|
80 | 68 | $result = $tool->handle(['method' => 'GET*POST']); |
81 | | - $output = $result->toArray()['content'][0]['text']; |
82 | 69 |
|
83 | | - expect($result->toArray()['isError'])->toBeFalse() |
84 | | - ->and($output)->toContain('ERROR Your application doesn\'t have any routes matching the given criteria.'); |
| 70 | + expect($result)->isToolResult() |
| 71 | + ->toolHasNoError() |
| 72 | + ->toolTextContains('ERROR Your application doesn\'t have any routes matching the given criteria.'); |
85 | 73 |
|
86 | 74 | $result = $tool->handle(['method' => '*GET*']); |
87 | | - $output = $result->toArray()['content'][0]['text']; |
88 | 75 |
|
89 | | - expect($output)->toContain('admin.dashboard') |
90 | | - ->and($output)->toContain('user.profile') |
91 | | - ->and($output)->toContain('api.posts.index') |
92 | | - ->and($output)->not->toContain('admin.users.store'); |
| 76 | + expect($result)->toolTextContains('admin.dashboard', 'user.profile', 'api.posts.index') |
| 77 | + ->and($result)->not->toolTextContains('admin.users.store'); |
93 | 78 |
|
94 | 79 | $result = $tool->handle(['method' => '*POST*']); |
95 | | - $output = $result->toArray()['content'][0]['text']; |
96 | 80 |
|
97 | | - expect($output)->toContain('admin.users.store') |
98 | | - ->and($output)->not->toContain('admin.dashboard'); |
| 81 | + expect($result)->toolTextContains('admin.users.store') |
| 82 | + ->and($result)->not->toolTextContains('admin.dashboard'); |
99 | 83 | }); |
100 | 84 |
|
101 | 85 | test('it handles edge cases and empty results correctly', function () { |
102 | 86 | $tool = new ListRoutes; |
103 | 87 |
|
104 | 88 | $result = $tool->handle(['name' => '*']); |
105 | | - expect($result)->toBeInstanceOf(ToolResult::class) |
106 | | - ->and($result->toArray()['isError'])->toBeFalse(); |
107 | 89 |
|
108 | | - $output = $result->toArray()['content'][0]['text']; |
109 | | - expect($output)->toContain('admin.dashboard') |
110 | | - ->and($output)->toContain('user.profile') |
111 | | - ->and($output)->toContain('two-factor.enable'); |
| 90 | + expect($result)->isToolResult() |
| 91 | + ->toolHasNoError() |
| 92 | + ->toolTextContains('admin.dashboard', 'user.profile', 'two-factor.enable'); |
112 | 93 |
|
113 | 94 | $result = $tool->handle(['name' => '*nonexistent*']); |
114 | | - $output = $result->toArray()['content'][0]['text']; |
115 | 95 |
|
116 | | - expect($output)->toContain('ERROR Your application doesn\'t have any routes matching the given criteria.'); |
| 96 | + expect($result)->toolTextContains('ERROR Your application doesn\'t have any routes matching the given criteria.'); |
117 | 97 |
|
118 | 98 | $result = $tool->handle(['name' => '']); |
119 | | - $output = $result->toArray()['content'][0]['text']; |
120 | 99 |
|
121 | | - expect($output)->toContain('admin.dashboard') |
122 | | - ->and($output)->toContain('user.profile'); |
| 100 | + expect($result)->toolTextContains('admin.dashboard', 'user.profile'); |
123 | 101 | }); |
124 | 102 |
|
125 | 103 | test('it handles multiple parameters with wildcard sanitization', function () { |
|
130 | 108 | 'method' => '*GET*', |
131 | 109 | ]); |
132 | 110 |
|
133 | | - $output = $result->toArray()['content'][0]['text']; |
134 | | - |
135 | | - expect($result->toArray()['isError'])->toBeFalse() |
136 | | - ->and($output)->toContain('admin.dashboard') |
137 | | - ->and($output)->not->toContain('admin.users.store') |
138 | | - ->and($output)->not->toContain('user.profile'); |
| 111 | + expect($result)->isToolResult() |
| 112 | + ->toolHasNoError() |
| 113 | + ->toolTextContains('admin.dashboard') |
| 114 | + ->and($result)->not->toolTextContains('admin.users.store', 'user.profile'); |
139 | 115 |
|
140 | 116 | $result = $tool->handle([ |
141 | 117 | 'name' => '*user*', |
142 | 118 | 'method' => '*POST*', |
143 | 119 | ]); |
144 | 120 |
|
145 | | - $output = $result->toArray()['content'][0]['text']; |
146 | | - |
147 | | - if (str_contains($output, 'admin.users.store')) { |
148 | | - expect($output)->toContain('admin.users.store'); |
149 | | - } else { |
150 | | - expect($output)->toContain('ERROR Your application doesn\'t have any routes matching the given criteria.'); |
151 | | - } |
| 121 | + expect($result)->toolTextContains('admin.users.store'); |
152 | 122 | }); |
153 | 123 |
|
154 | 124 | test('it handles the original problematic wildcard case', function () { |
155 | 125 | $tool = new ListRoutes; |
156 | 126 |
|
157 | | - $result = $tool->handle(['name' => '*/two-factor/']); |
158 | | - expect($result)->toBeInstanceOf(ToolResult::class) |
159 | | - ->and($result->toArray()['isError'])->toBeFalse(); |
| 127 | + $result = $tool->handle(['name' => '*two-factor*']); |
160 | 128 |
|
161 | | - $output = $result->toArray()['content'][0]['text']; |
162 | | - if (str_contains($output, 'two-factor.enable')) { |
163 | | - expect($output)->toContain('two-factor.enable'); |
164 | | - } else { |
165 | | - expect($output)->toContain('ERROR'); |
166 | | - } |
| 129 | + expect($result)->isToolResult() |
| 130 | + ->toolHasNoError() |
| 131 | + ->toolTextContains('two-factor.enable'); |
167 | 132 | }); |
0 commit comments