- Add page_size helper method to read from X-Per-Page header - Set min (1) and max (100) bounds for page sizes - Update all paginated endpoints to use dynamic page size - Maintain backward compatibility with default sizes
154 lines
No EOL
4.4 KiB
Ruby
154 lines
No EOL
4.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
RSpec.describe 'Drag Drop API', type: :request do
|
|
# Create minimal test data without relying on seeds
|
|
let(:user) { User.create!(username: 'testuser', email: 'test@example.com') }
|
|
|
|
let(:party) do
|
|
Party.create!(
|
|
user: user,
|
|
name: 'Test Party',
|
|
raid_id: nil,
|
|
element: 0,
|
|
visibility: 'public'
|
|
)
|
|
end
|
|
|
|
let(:access_token) do
|
|
Doorkeeper::AccessToken.create!(
|
|
resource_owner_id: user.id,
|
|
expires_in: 30.days,
|
|
scopes: 'public'
|
|
)
|
|
end
|
|
|
|
let(:headers) do
|
|
{
|
|
'Authorization' => "Bearer #{access_token.token}",
|
|
'Content-Type' => 'application/json'
|
|
}
|
|
end
|
|
|
|
describe 'GridWeapon endpoints' do
|
|
# Create minimal weapon for testing
|
|
let(:weapon) { Weapon.create!(name_en: 'Test Weapon', element: 0, granblue_id: 'test-001') }
|
|
let!(:grid_weapon1) do
|
|
GridWeapon.create!(
|
|
party: party,
|
|
weapon: weapon,
|
|
position: 0,
|
|
uncap_level: 3,
|
|
transcendence_step: 0
|
|
)
|
|
end
|
|
|
|
describe 'PUT /api/v1/parties/:party_id/grid_weapons/:id/position' do
|
|
it 'updates position when valid' do
|
|
put "/api/v1/parties/#{party.id}/grid_weapons/#{grid_weapon1.id}/position",
|
|
params: { position: 3 }.to_json,
|
|
headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(grid_weapon1.reload.position).to eq(3)
|
|
end
|
|
|
|
it 'returns error for invalid position' do
|
|
put "/api/v1/parties/#{party.id}/grid_weapons/#{grid_weapon1.id}/position",
|
|
params: { position: 20 }.to_json,
|
|
headers: headers
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
end
|
|
end
|
|
|
|
describe 'POST /api/v1/parties/:party_id/grid_weapons/swap' do
|
|
let!(:grid_weapon2) do
|
|
GridWeapon.create!(
|
|
party: party,
|
|
weapon: weapon,
|
|
position: 2,
|
|
uncap_level: 3,
|
|
transcendence_step: 0
|
|
)
|
|
end
|
|
|
|
it 'swaps positions of two weapons' do
|
|
post "/api/v1/parties/#{party.id}/grid_weapons/swap",
|
|
params: { source_id: grid_weapon1.id, target_id: grid_weapon2.id }.to_json,
|
|
headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(grid_weapon1.reload.position).to eq(2)
|
|
expect(grid_weapon2.reload.position).to eq(0)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'Batch Grid Update' do
|
|
let(:weapon) { Weapon.create!(name_en: 'Test Weapon', element: 0, granblue_id: 'test-002') }
|
|
let!(:grid_weapon) do
|
|
GridWeapon.create!(
|
|
party: party,
|
|
weapon: weapon,
|
|
position: 0,
|
|
uncap_level: 3,
|
|
transcendence_step: 0
|
|
)
|
|
end
|
|
|
|
describe 'POST /api/v1/parties/:id/grid_update' do
|
|
it 'performs move operation' do
|
|
operations = [
|
|
{ type: 'move', entity: 'weapon', id: grid_weapon.id, position: 4 }
|
|
]
|
|
|
|
post "/api/v1/parties/#{party.id}/grid_update",
|
|
params: { operations: operations }.to_json,
|
|
headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
json = JSON.parse(response.body)
|
|
expect(json['operations_applied']).to eq(1)
|
|
expect(grid_weapon.reload.position).to eq(4)
|
|
end
|
|
|
|
it 'validates operations before executing' do
|
|
operations = [
|
|
{ type: 'invalid', entity: 'weapon', id: grid_weapon.id }
|
|
]
|
|
|
|
post "/api/v1/parties/#{party.id}/grid_update",
|
|
params: { operations: operations }.to_json,
|
|
headers: headers
|
|
|
|
expect(response).to have_http_status(:unprocessable_entity)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'Authorization' do
|
|
let(:other_user) { User.create!(username: 'other', email: 'other@example.com') }
|
|
let(:other_party) { Party.create!(user: other_user, name: 'Other Party') }
|
|
let(:weapon) { Weapon.create!(name_en: 'Test Weapon', element: 0, granblue_id: 'test-003') }
|
|
let!(:other_weapon) do
|
|
GridWeapon.create!(
|
|
party: other_party,
|
|
weapon: weapon,
|
|
position: 0,
|
|
uncap_level: 3,
|
|
transcendence_step: 0
|
|
)
|
|
end
|
|
|
|
it 'denies access to other users party' do
|
|
put "/api/v1/parties/#{other_party.id}/grid_weapons/#{other_weapon.id}/position",
|
|
params: { position: 3 }.to_json,
|
|
headers: headers
|
|
|
|
expect(response).to have_http_status(:unauthorized)
|
|
end
|
|
end
|
|
end |