hensei-api/spec/requests/grid_characters_controller_spec.rb

213 lines
6.5 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'GridCharacters API', type: :request do
let(:user) { create(:user) }
let(:party) { create(:party, user: user, edit_key: 'secret') }
# Use canonical records seeded into your DB.
# For example, assume Rosamia (granblue_id "3040087000") and Seofon (granblue_id "3040036000")
let(:rosamia) { Character.find_by(granblue_id: '3040087000') }
let(:seofon) { Character.find_by(granblue_id: '3040036000') }
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',
'X-Edit-Key' => 'secret'
}
end
describe 'POST /api/v1/characters (create)' do
context 'when creating a grid character with a unique canonical character (e.g. Seofon)' do
let(:valid_params) do
{
character: {
party_id: party.id,
character_id: seofon.id,
position: 0,
uncap_level: 3,
transcendence_step: 0,
rings: [
{ modifier: 'A', strength: 1 },
{ modifier: 'B', strength: 2 }
]
}
}
end
it 'creates the grid character and returns status created' do
expect do
post '/api/v1/characters', params: valid_params.to_json, headers: headers
end.to change(GridCharacter, :count).by(1)
expect(response).to have_http_status(:created)
json_response = JSON.parse(response.body)
expect(json_response).to include('position' => 0)
end
end
context 'when attempting to add a duplicate canonical character (e.g. Rosamia)' do
before do
# Create an initial grid character for Rosamia.
GridCharacter.create!(
party_id: party.id,
character_id: rosamia.id,
position: 1,
uncap_level: 3,
transcendence_step: 0
)
end
let(:duplicate_params) do
{
character: {
party_id: party.id,
character_id: rosamia.id, # same canonical character
position: 2,
uncap_level: 3,
transcendence_step: 0
}
}
end
it 'detects the conflict and returns a conflict resolution view without adding a duplicate' do
# Here we simulate conflict resolution via the resolve endpoint.
expect do
post '/api/v1/characters/resolve',
params: { resolve: { position: 2, incoming: rosamia.id, conflicting: [GridCharacter.last.id] } }.to_json,
headers: headers
end.to change(GridCharacter, :count).by(0)
expect(response).to have_http_status(:created)
json_response = JSON.parse(response.body)
expect(json_response).to include('position' => 2)
end
end
end
describe 'PUT /api/v1/characters/:id (update)' do
before do
@grid_character = GridCharacter.create!(
party_id: party.id,
character_id: rosamia.id,
position: 1,
uncap_level: 3,
transcendence_step: 0
)
end
let(:update_params) do
{
character: {
id: @grid_character.id,
party_id: party.id,
character_id: rosamia.id,
position: 1,
uncap_level: 4,
transcendence_step: 0,
rings: [
{ modifier: 'C', strength: 3 }
]
}
}
end
it 'updates the grid character and returns the updated record' do
put "/api/v1/grid_characters/#{@grid_character.id}", params: update_params.to_json, headers: headers
expect(response).to have_http_status(:ok)
json_response = JSON.parse(response.body)
expect(json_response).to include('uncap_level' => 4)
end
end
describe 'POST /api/v1/characters/update_uncap (update uncap level)' do
context 'for a character that does NOT allow transcendence (e.g. Rosamia)' do
before do
@grid_character = GridCharacter.create!(
party_id: party.id,
character_id: rosamia.id,
position: 2,
uncap_level: 2,
transcendence_step: 0
)
end
let(:update_uncap_params) do
{
character: {
id: @grid_character.id,
party_id: party.id,
character_id: rosamia.id,
uncap_level: 3,
transcendence_step: 0
}
}
end
it 'caps the uncap level at 4 for a character with flb true' do
post '/api/v1/characters/update_uncap', params: update_uncap_params.to_json, headers: headers
expect(response).to have_http_status(:ok)
json_response = JSON.parse(response.body)
expect(json_response['grid_character']).to include('uncap_level' => 3)
end
end
context 'for a character that allows transcendence (e.g. Seofon)' do
before do
# For Seofon, the "transcendence" behavior is enabled by its ulb flag.
@grid_character = GridCharacter.create!(
party_id: party.id,
character_id: seofon.id,
position: 2,
uncap_level: 5,
transcendence_step: 0
)
end
let(:update_uncap_params) do
{
character: {
id: @grid_character.id,
party_id: party.id,
character_id: seofon.id,
uncap_level: 5,
transcendence_step: 1
}
}
end
it 'updates the uncap level to 6 when the character supports transcendence via ulb' do
post '/api/v1/characters/update_uncap', params: update_uncap_params.to_json, headers: headers
expect(response).to have_http_status(:ok)
json_response = JSON.parse(response.body)
expect(json_response['grid_character']).to include('uncap_level' => 5, 'transcendence_step' => 1)
end
end
end
describe 'DELETE /api/v1/characters (destroy)' do
before do
@grid_character = GridCharacter.create!(
party_id: party.id,
character_id: rosamia.id,
position: 4,
uncap_level: 3,
transcendence_step: 0
)
end
it 'destroys the grid character and returns a destroyed view' do
expect do
delete '/api/v1/characters', params: { id: @grid_character.id }.to_json, headers: headers
end.to change(GridCharacter, :count).by(-1)
expect(response).to have_http_status(:ok)
end
end
end