@@ -294,7 +294,7 @@ def initialize(message, original_exception = nil)
294
294
let ( :request_env ) {
295
295
Rack ::MockRequest . env_for ( "/__better_errors/#{ id } /variables" , input : StringIO . new ( JSON . dump ( request_body_data ) ) )
296
296
}
297
- let ( :request_body_data ) { { "index" : 0 } }
297
+ let ( :request_body_data ) { { "index" => 0 } }
298
298
let ( :json_body ) { JSON . parse ( body ) }
299
299
let ( :id ) { 'abcdefg' }
300
300
@@ -384,7 +384,131 @@ def initialize(message, original_exception = nil)
384
384
end
385
385
386
386
context 'when the body csrfToken does not match the CSRF token cookie' do
387
- let ( :request_body_data ) { { "index" : 0 , "csrfToken" : "csrfToken123" } }
387
+ let ( :request_body_data ) { { "index" => 0 , "csrfToken" => "csrfToken123" } }
388
+ before do
389
+ request_env [ "HTTP_COOKIE" ] = "BetterErrors-CSRF-Token=csrfToken456"
390
+ end
391
+
392
+ it 'returns a JSON error' do
393
+ expect ( json_body ) . to match (
394
+ 'error' => 'Invalid CSRF Token' ,
395
+ 'explanation' => /session might have been cleared/ ,
396
+ )
397
+ end
398
+ end
399
+
400
+ context 'when there is no CSRF token in the request' do
401
+ it 'returns a JSON error' do
402
+ expect ( json_body ) . to match (
403
+ 'error' => 'Invalid CSRF Token' ,
404
+ 'explanation' => /session might have been cleared/ ,
405
+ )
406
+ end
407
+ end
408
+ end
409
+ end
410
+ end
411
+
412
+ context "requesting eval for a specific frame" do
413
+ let ( :env ) { { } }
414
+ let ( :response_env ) {
415
+ app . call ( request_env )
416
+ }
417
+ let ( :request_env ) {
418
+ Rack ::MockRequest . env_for ( "/__better_errors/#{ id } /eval" , input : StringIO . new ( JSON . dump ( request_body_data ) ) )
419
+ }
420
+ let ( :request_body_data ) { { "index" => 0 , source : "do_a_thing" } }
421
+ let ( :json_body ) { JSON . parse ( body ) }
422
+ let ( :id ) { 'abcdefg' }
423
+
424
+ context 'when no errors have been recorded' do
425
+ it 'returns a JSON error' do
426
+ expect ( json_body ) . to match (
427
+ 'error' => 'No exception information available' ,
428
+ 'explanation' => /application has been restarted/ ,
429
+ )
430
+ end
431
+
432
+ context 'when Middleman is in use' do
433
+ let! ( :middleman ) { class_double ( "Middleman" ) . as_stubbed_const }
434
+ it 'returns a JSON error' do
435
+ expect ( json_body [ 'explanation' ] )
436
+ . to match ( /Middleman reloads all dependencies/ )
437
+ end
438
+ end
439
+
440
+ context 'when Shotgun is in use' do
441
+ let! ( :shotgun ) { class_double ( "Shotgun" ) . as_stubbed_const }
442
+
443
+ it 'returns a JSON error' do
444
+ expect ( json_body [ 'explanation' ] )
445
+ . to match ( /The shotgun gem/ )
446
+ end
447
+
448
+ context 'when Hanami is also in use' do
449
+ let! ( :hanami ) { class_double ( "Hanami" ) . as_stubbed_const }
450
+ it 'returns a JSON error' do
451
+ expect ( json_body [ 'explanation' ] )
452
+ . to match ( /--no-code-reloading/ )
453
+ end
454
+ end
455
+ end
456
+ end
457
+
458
+ context 'when an error has been recorded' do
459
+ let ( :error_page ) { ErrorPage . new ( exception , env ) }
460
+ before do
461
+ app . instance_variable_set ( '@error_page' , error_page )
462
+ end
463
+
464
+ context 'but it does not match the request' do
465
+ it 'returns a JSON error' do
466
+ expect ( json_body ) . to match (
467
+ 'error' => 'Session expired' ,
468
+ 'explanation' => /no longer available in memory/ ,
469
+ )
470
+ end
471
+ end
472
+
473
+ context 'and its ID matches the requested ID' do
474
+ let ( :id ) { error_page . id }
475
+
476
+ context 'when the body csrfToken matches the CSRF token cookie' do
477
+ let ( :request_body_data ) { { "index" => 0 , "csrfToken" => "csrfToken123" } }
478
+ before do
479
+ request_env [ "HTTP_COOKIE" ] = "BetterErrors-CSRF-Token=csrfToken123"
480
+ end
481
+
482
+ context 'when the Content-Type of the request is application/json' do
483
+ before do
484
+ request_env [ 'CONTENT_TYPE' ] = 'application/json'
485
+ end
486
+
487
+ it 'returns JSON containing the eval result' do
488
+ expect ( error_page ) . to receive ( :do_eval ) . and_return ( prompt : '#' , result : "much_stuff_here" )
489
+ expect ( json_body ) . to match (
490
+ 'prompt' => '#' ,
491
+ 'result' => 'much_stuff_here' ,
492
+ )
493
+ end
494
+ end
495
+
496
+ context 'when the Content-Type of the request is application/json' do
497
+ before do
498
+ request_env [ 'HTTP_CONTENT_TYPE' ] = 'application/json'
499
+ end
500
+
501
+ it 'returns a JSON error' do
502
+ expect ( json_body ) . to match (
503
+ 'error' => 'Request not acceptable' ,
504
+ 'explanation' => /did not match an acceptable content type/ ,
505
+ )
506
+ end
507
+ end
508
+ end
509
+
510
+ context 'when the body csrfToken does not match the CSRF token cookie' do
511
+ let ( :request_body_data ) { { "index" => 0 , "csrfToken" => "csrfToken123" } }
388
512
before do
389
513
request_env [ "HTTP_COOKIE" ] = "BetterErrors-CSRF-Token=csrfToken456"
390
514
end
@@ -408,5 +532,25 @@ def initialize(message, original_exception = nil)
408
532
end
409
533
end
410
534
end
535
+
536
+ context "requesting an invalid internal method" do
537
+ let ( :env ) { { } }
538
+ let ( :response_env ) {
539
+ app . call ( request_env )
540
+ }
541
+ let ( :request_env ) {
542
+ Rack ::MockRequest . env_for ( "/__better_errors/#{ id } /invalid" , input : StringIO . new ( JSON . dump ( request_body_data ) ) )
543
+ }
544
+ let ( :request_body_data ) { { "index" => 0 } }
545
+ let ( :json_body ) { JSON . parse ( body ) }
546
+ let ( :id ) { 'abcdefg' }
547
+
548
+ it 'returns a JSON error' do
549
+ expect ( json_body ) . to match (
550
+ 'error' => 'Not found' ,
551
+ 'explanation' => /recognized internal call/ ,
552
+ )
553
+ end
554
+ end
411
555
end
412
556
end
0 commit comments