test: Add comprehensive server response tests

- Add HTML response tests for missions index (checks mission cards rendered)
- Add game page tests (checks game container and config injection)
- Add API endpoint tests:
  * scenario endpoint returns JSON scenario data
  * bootstrap endpoint returns complete game state
  * sync_state endpoint updates player position
  * unlock endpoint validates and rejects invalid attempts
  * inventory endpoint adds items to player inventory
- Fix inventory API to use action_type instead of reserved 'action' param

All 23 tests passing with 64 assertions verifying server returns correct data!
This commit is contained in:
Z. Cliffe Schreuders
2025-11-21 15:27:54 +00:00
parent e18950c6d7
commit 4764f5881e
5 changed files with 937 additions and 2 deletions

View File

@@ -78,10 +78,10 @@ module BreakEscape
def inventory
authorize @game if defined?(Pundit)
action = params[:action]
action_type = params[:action_type] || params[:actionType]
item = params[:item]
case action
case action_type
when 'add'
@game.add_inventory_item!(item.to_unsafe_h)
render json: { success: true, inventory: @game.player_state['inventory'] }

View File

@@ -0,0 +1,118 @@
require 'test_helper'
module BreakEscape
class GamesControllerTest < ActionDispatch::IntegrationTest
include Engine.routes.url_helpers
setup do
@mission = break_escape_missions(:ceo_exfil)
@player = break_escape_demo_users(:test_user)
@game = Game.create!(
mission: @mission,
player: @player,
scenario_data: { "startRoom" => "reception", "rooms" => {} },
player_state: {
"currentRoom" => "reception",
"unlockedRooms" => ["reception"],
"unlockedObjects" => [],
"inventory" => [],
"encounteredNPCs" => [],
"globalVariables" => {},
"biometricSamples" => [],
"biometricUnlocks" => [],
"bluetoothDevices" => [],
"notes" => [],
"health" => 100
}
)
end
test "should show game" do
get game_url(@game)
assert_response :success
end
test "show should return HTML with game container" do
get game_url(@game)
assert_response :success
assert_select '#break-escape-game'
assert_match /window\.breakEscapeConfig/, response.body
end
test "show should inject game configuration" do
get game_url(@game)
assert_response :success
# Check that config is in the page
assert_match /gameId.*#{@game.id}/, response.body
assert_match /apiBasePath/, response.body
assert_match /csrfToken/, response.body
end
test "scenario endpoint should return JSON" do
get scenario_game_url(@game)
assert_response :success
assert_equal 'application/json', @response.media_type
json = JSON.parse(@response.body)
assert json['startRoom']
assert json['rooms']
end
test "bootstrap endpoint should return game state" do
get bootstrap_game_url(@game)
assert_response :success
assert_equal 'application/json', @response.media_type
json = JSON.parse(@response.body)
assert_equal @game.id, json['gameId']
assert_equal 'reception', json['startRoom']
assert json['playerState']
assert_equal 'reception', json['playerState']['currentRoom']
assert_includes json['playerState']['unlockedRooms'], 'reception'
assert_equal 100, json['playerState']['health']
end
test "sync_state should update player state" do
put sync_state_game_url(@game), params: {
currentRoom: 'office'
}
assert_response :success
json = JSON.parse(@response.body)
assert json['success']
@game.reload
assert_equal 'office', @game.player_state['currentRoom']
end
test "unlock endpoint should reject invalid attempts" do
post unlock_game_url(@game), params: {
targetType: 'room',
targetId: 'office',
attempt: 'wrong_code',
method: 'keypad'
}
assert_response :unprocessable_entity
json = JSON.parse(@response.body)
assert_equal false, json['success']
assert_equal 'Invalid attempt', json['message']
end
test "inventory endpoint should add items" do
post inventory_game_url(@game), params: {
action_type: 'add',
item: { type: 'key', name: 'Test Key', id: 'test_key' }
}
assert_response :success
json = JSON.parse(@response.body)
assert json['success']
assert_equal 1, json['inventory'].length
@game.reload
assert_equal 1, @game.player_state['inventory'].length
end
end
end

View File

@@ -9,10 +9,36 @@ module BreakEscape
assert_response :success
end
test "index should return HTML with mission list" do
get missions_url
assert_response :success
assert_select 'h1', text: /BreakEscape/
assert_select '.mission-card', minimum: 1
end
test "index should display published missions" do
get missions_url
assert_response :success
# Should show published mission
assert_select '.mission-title', text: break_escape_missions(:ceo_exfil).display_name
end
test "should show published mission" do
mission = break_escape_missions(:ceo_exfil)
get mission_url(mission)
assert_response :redirect # Redirects to game
end
test "should create game and redirect when showing mission" do
mission = break_escape_missions(:ceo_exfil)
assert_difference 'Game.count', 1 do
get mission_url(mission)
end
assert_response :redirect
assert_match /\/games\/\d+/, @response.location
end
end
end

File diff suppressed because one or more lines are too long

Binary file not shown.