@@ -166,96 +166,6 @@ def app
166166 end
167167 end
168168
169- describe "/tidewave/shell" do
170- def parse_binary_response ( body )
171- chunks = [ ]
172- offset = 0
173-
174- while offset < body . bytesize
175- type = body . getbyte ( offset )
176- length = body [ offset + 1 , 4 ] . unpack1 ( "N" )
177- data = body [ offset + 5 , length ]
178- chunks << { type : type , data : data }
179- offset += 5 + length
180- end
181-
182- chunks
183- end
184-
185- it "executes simple command and returns output with status" do
186- body = { command : "echo 'hello world'" }
187- post "/tidewave/shell" , JSON . generate ( body )
188- expect ( last_response . status ) . to eq ( 200 )
189-
190- chunks = parse_binary_response ( last_response . body )
191- expect ( chunks . length ) . to eq ( 2 )
192-
193- # First chunk should be stdout data
194- expect ( chunks [ 0 ] [ :type ] ) . to eq ( 0 )
195- expect ( chunks [ 0 ] [ :data ] ) . to eq ( "hello world\n " )
196-
197- # Second chunk should be status
198- expect ( chunks [ 1 ] [ :type ] ) . to eq ( 1 )
199- status_data = JSON . parse ( chunks [ 1 ] [ :data ] )
200- expect ( status_data [ "status" ] ) . to eq ( 0 )
201- end
202-
203- it "handles command with non-zero exit status" do
204- body = { command : "exit 42" }
205- post "/tidewave/shell" , JSON . generate ( body )
206- expect ( last_response . status ) . to eq ( 200 )
207-
208- chunks = parse_binary_response ( last_response . body )
209- expect ( chunks . length ) . to eq ( 1 )
210-
211- # Should only have status chunk
212- expect ( chunks [ 0 ] [ :type ] ) . to eq ( 1 )
213- status_data = JSON . parse ( chunks [ 0 ] [ :data ] )
214- expect ( status_data [ "status" ] ) . to eq ( 42 )
215- end
216-
217- it "handles multiline commands" do
218- body = {
219- command : "echo 'line 1'\n echo 'line 2'"
220- }
221- post "/tidewave/shell" , JSON . generate ( body )
222- expect ( last_response . status ) . to eq ( 200 )
223-
224- chunks = parse_binary_response ( last_response . body )
225-
226- # The shell command outputs both lines together
227- expect ( chunks . length ) . to eq ( 2 )
228-
229- # First chunk should be stdout data with both lines
230- expect ( chunks [ 0 ] [ :type ] ) . to eq ( 0 )
231- expect ( chunks [ 0 ] [ :data ] ) . to eq ( "line 1\n line 2\n " )
232-
233- # Second chunk should be status
234- expect ( chunks [ 1 ] [ :type ] ) . to eq ( 1 )
235- status_data = JSON . parse ( chunks [ 1 ] [ :data ] )
236- expect ( status_data [ "status" ] ) . to eq ( 0 )
237- end
238-
239- it "returns 400 for empty command body" do
240- post "/tidewave/shell" , ""
241- expect ( last_response . status ) . to eq ( 400 )
242- expect ( last_response . body ) . to include ( "Command body is required" )
243- end
244-
245- it "returns 400 for invalid JSON" do
246- post "/tidewave/shell" , "not json"
247- expect ( last_response . status ) . to eq ( 400 )
248- expect ( last_response . body ) . to include ( "Invalid JSON in request body" )
249- end
250-
251- it "returns 400 for missing command field" do
252- body = { other_field : "value" }
253- post "/tidewave/shell" , JSON . generate ( body )
254- expect ( last_response . status ) . to eq ( 400 )
255- expect ( last_response . body ) . to include ( "Command field is required" )
256- end
257- end
258-
259169 describe "edge cases" do
260170 it "handles trailing slashes" do
261171 get "/tidewave/"
0 commit comments