hensei-api/spec/requests/collection_artifacts_controller_spec.rb

318 lines
11 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Collection Artifacts API', type: :request do
let(:user) { create(:user) }
let(:other_user) { create(:user) }
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
let(:artifact) { create(:artifact) }
let(:quirk_artifact) { create(:artifact, :quirk) }
before do
# Seed required artifact skills for validation
ArtifactSkill.find_or_create_by!(skill_group: :group_i, modifier: 1) do |s|
s.name_en = 'ATK'
s.name_jp = '攻撃力'
s.base_values = [1320, 1440, 1560, 1680, 1800]
s.growth = 300.0
s.polarity = :positive
end
ArtifactSkill.find_or_create_by!(skill_group: :group_i, modifier: 2) do |s|
s.name_en = 'HP'
s.name_jp = 'HP'
s.base_values = [660, 720, 780, 840, 900]
s.growth = 150.0
s.polarity = :positive
end
ArtifactSkill.find_or_create_by!(skill_group: :group_ii, modifier: 1) do |s|
s.name_en = 'C.A. DMG'
s.name_jp = '奥義ダメ'
s.base_values = [13.2, 14.4, 15.6, 16.8, 18.0]
s.growth = 3.0
s.polarity = :positive
end
ArtifactSkill.find_or_create_by!(skill_group: :group_iii, modifier: 1) do |s|
s.name_en = 'Chain Burst DMG'
s.name_jp = 'チェインダメ'
s.base_values = [6, 7, 8, 9, 10]
s.growth = 2.5
s.polarity = :positive
end
ArtifactSkill.clear_cache!
end
describe 'GET /api/v1/users/:user_id/collection/artifacts' do
let!(:collection_artifact1) { create(:collection_artifact, user: user, artifact: artifact) }
let!(:collection_artifact2) { create(:collection_artifact, user: user, element: :water) }
let!(:other_user_artifact) { create(:collection_artifact, user: other_user) }
it "returns the user's collection artifacts" do
get "/api/v1/users/#{user.id}/collection/artifacts", headers: headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json['artifacts'].length).to eq(2)
end
it 'supports pagination' do
get "/api/v1/users/#{user.id}/collection/artifacts", params: { page: 1, limit: 1 }, headers: headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json['artifacts'].length).to eq(1)
expect(json['meta']['total_pages']).to be >= 2
end
it 'filters by artifact_id' do
get "/api/v1/users/#{user.id}/collection/artifacts", params: { artifact_id: artifact.id }, headers: headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json['artifacts'].length).to eq(1)
end
it 'filters by element' do
get "/api/v1/users/#{user.id}/collection/artifacts", params: { element: 'water' }, headers: headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json['artifacts'].all? { |a| a['element'] == 'water' }).to be true
end
it 'returns unauthorized without authentication' do
other_user.update!(collection_visibility: 'private')
get "/api/v1/users/#{other_user.id}/collection/artifacts"
expect(response).to have_http_status(:unauthorized)
end
end
describe 'GET /api/v1/users/:user_id/collection/artifacts/:id' do
let!(:collection_artifact) { create(:collection_artifact, user: user, artifact: artifact) }
it 'returns the collection artifact' do
get "/api/v1/users/#{user.id}/collection/artifacts/#{collection_artifact.id}", headers: headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json['id']).to eq(collection_artifact.id)
expect(json['artifact']['id']).to eq(artifact.id)
end
end
describe 'POST /api/v1/collection/artifacts' do
let(:valid_attributes) do
{
collection_artifact: {
artifact_id: artifact.id,
element: 'fire',
level: 1,
skill1: { modifier: 1, strength: 1800, level: 1 },
skill2: { modifier: 2, strength: 900, level: 1 },
skill3: { modifier: 1, strength: 18.0, level: 1 },
skill4: { modifier: 1, strength: 10, level: 1 }
}
}
end
it 'creates a new collection artifact' do
expect do
post '/api/v1/collection/artifacts', params: valid_attributes.to_json, headers: headers
end.to change(CollectionArtifact, :count).by(1)
expect(response).to have_http_status(:created)
json = JSON.parse(response.body)
expect(json['artifact']['id']).to eq(artifact.id)
expect(json['element']).to eq('fire')
end
it 'allows multiple copies of the same artifact' do
create(:collection_artifact, user: user, artifact: artifact)
expect do
post '/api/v1/collection/artifacts', params: valid_attributes.to_json, headers: headers
end.to change(CollectionArtifact, :count).by(1)
expect(response).to have_http_status(:created)
end
it 'creates artifact with nickname' do
attributes_with_nickname = valid_attributes.deep_merge(
collection_artifact: { nickname: 'My Best Artifact' }
)
post '/api/v1/collection/artifacts', params: attributes_with_nickname.to_json, headers: headers
expect(response).to have_http_status(:created)
json = JSON.parse(response.body)
expect(json['nickname']).to eq('My Best Artifact')
end
it 'creates quirk artifact with proficiency' do
quirk_attributes = {
collection_artifact: {
artifact_id: quirk_artifact.id,
element: 'dark',
proficiency: 'staff',
level: 1,
skill1: {},
skill2: {},
skill3: {},
skill4: {}
}
}
post '/api/v1/collection/artifacts', params: quirk_attributes.to_json, headers: headers
expect(response).to have_http_status(:created)
json = JSON.parse(response.body)
expect(json['proficiency']).to eq('staff')
end
it 'returns error when skill1 and skill2 have same modifier' do
invalid_attributes = valid_attributes.deep_merge(
collection_artifact: {
skill1: { modifier: 1, strength: 1800, level: 1 },
skill2: { modifier: 1, strength: 1800, level: 1 }
}
)
post '/api/v1/collection/artifacts', params: invalid_attributes.to_json, headers: headers
expect(response).to have_http_status(:unprocessable_entity)
json = JSON.parse(response.body)
expect(json['errors'].to_s).to include('cannot have the same modifier')
end
it 'returns unauthorized without authentication' do
post '/api/v1/collection/artifacts', params: valid_attributes.to_json
expect(response).to have_http_status(:unauthorized)
end
end
describe 'PUT /api/v1/collection/artifacts/:id' do
let!(:collection_artifact) { create(:collection_artifact, user: user, artifact: artifact, level: 1) }
it 'updates the collection artifact' do
update_attributes = {
collection_artifact: {
nickname: 'Updated Name',
element: 'water'
}
}
put "/api/v1/collection/artifacts/#{collection_artifact.id}",
params: update_attributes.to_json, headers: headers
expect(response).to have_http_status(:ok)
json = JSON.parse(response.body)
expect(json['nickname']).to eq('Updated Name')
expect(json['element']).to eq('water')
end
it 'returns not found for other user\'s artifact' do
other_collection = create(:collection_artifact, user: other_user)
put "/api/v1/collection/artifacts/#{other_collection.id}",
params: { collection_artifact: { nickname: 'Hack' } }.to_json, headers: headers
expect(response).to have_http_status(:not_found)
end
end
describe 'DELETE /api/v1/collection/artifacts/:id' do
let!(:collection_artifact) { create(:collection_artifact, user: user, artifact: artifact) }
it 'deletes the collection artifact' do
expect do
delete "/api/v1/collection/artifacts/#{collection_artifact.id}", headers: headers
end.to change(CollectionArtifact, :count).by(-1)
expect(response).to have_http_status(:no_content)
end
it 'returns not found for other user\'s artifact' do
other_collection = create(:collection_artifact, user: other_user)
expect do
delete "/api/v1/collection/artifacts/#{other_collection.id}", headers: headers
end.not_to change(CollectionArtifact, :count)
expect(response).to have_http_status(:not_found)
end
end
describe 'POST /api/v1/collection/artifacts/batch' do
let(:artifact2) { create(:artifact, :dagger) }
it 'creates multiple collection artifacts' do
batch_attributes = {
collection_artifacts: [
{
artifact_id: artifact.id,
element: 'fire',
level: 1,
skill1: { modifier: 1, strength: 1800, level: 1 },
skill2: { modifier: 2, strength: 900, level: 1 },
skill3: { modifier: 1, strength: 18.0, level: 1 },
skill4: { modifier: 1, strength: 10, level: 1 }
},
{
artifact_id: artifact2.id,
element: 'water',
level: 1,
skill1: { modifier: 1, strength: 1800, level: 1 },
skill2: { modifier: 2, strength: 900, level: 1 },
skill3: { modifier: 1, strength: 18.0, level: 1 },
skill4: { modifier: 1, strength: 10, level: 1 }
}
]
}
expect do
post '/api/v1/collection/artifacts/batch', params: batch_attributes.to_json, headers: headers
end.to change(CollectionArtifact, :count).by(2)
expect(response).to have_http_status(:created)
json = JSON.parse(response.body)
expect(json['meta']['created']).to eq(2)
expect(json['meta']['errors']).to be_empty
end
it 'returns multi_status when some items fail' do
batch_attributes = {
collection_artifacts: [
{
artifact_id: artifact.id,
element: 'fire',
level: 1,
skill1: { modifier: 1, strength: 1800, level: 1 },
skill2: { modifier: 2, strength: 900, level: 1 },
skill3: { modifier: 1, strength: 18.0, level: 1 },
skill4: { modifier: 1, strength: 10, level: 1 }
},
{
artifact_id: artifact.id,
element: 'invalid_element', # Invalid
level: 1
}
]
}
post '/api/v1/collection/artifacts/batch', params: batch_attributes.to_json, headers: headers
expect(response).to have_http_status(:multi_status)
json = JSON.parse(response.body)
expect(json['meta']['created']).to eq(1)
expect(json['meta']['errors'].length).to eq(1)
end
end
end