diff --git a/app/models/collection_weapon.rb b/app/models/collection_weapon.rb index 7399ed0..a9288cb 100644 --- a/app/models/collection_weapon.rb +++ b/app/models/collection_weapon.rb @@ -15,6 +15,7 @@ class CollectionWeapon < ApplicationRecord has_many :grid_weapons, dependent: :nullify before_destroy :orphan_grid_items + before_validation :set_default_exorcism_level, on: :create # Set defaults before validation so database defaults don't cause validation failures attribute :awakening_level, :integer, default: 1 @@ -174,4 +175,16 @@ class CollectionWeapon < ApplicationRecord def orphan_grid_items grid_weapons.update_all(orphaned: true, collection_weapon_id: nil) end + + ## + # Sets default exorcism_level to 1 for befoulment weapons if not provided. + # + # @return [void] + def set_default_exorcism_level + return unless weapon.present? + return unless exorcism_level.nil? + return unless weapon.weapon_series&.augment_type == 'befoulment' + + self.exorcism_level = 1 + end end \ No newline at end of file diff --git a/app/models/grid_weapon.rb b/app/models/grid_weapon.rb index b01b824..0dc9bac 100644 --- a/app/models/grid_weapon.rb +++ b/app/models/grid_weapon.rb @@ -56,6 +56,7 @@ class GridWeapon < ApplicationRecord validate :no_conflicts, on: :create before_save :assign_mainhand + before_validation :set_default_exorcism_level, on: :create ##### Amoeba configuration amoeba do @@ -245,4 +246,16 @@ class GridWeapon < ApplicationRecord def assign_mainhand self.mainhand = (position == -1) end + + ## + # Sets default exorcism_level to 1 for befoulment weapons if not provided. + # + # @return [void] + def set_default_exorcism_level + return unless weapon.present? + return unless exorcism_level.nil? + return unless weapon.weapon_series&.augment_type == 'befoulment' + + self.exorcism_level = 1 + end end diff --git a/db/data/20260104000002_populate_max_exorcism_level.rb b/db/data/20260104000002_populate_max_exorcism_level.rb new file mode 100644 index 0000000..dc3e0b4 --- /dev/null +++ b/db/data/20260104000002_populate_max_exorcism_level.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class PopulateMaxExorcismLevel < ActiveRecord::Migration[8.0] + def up + # Set max_exorcism_level = 5 for all weapons that belong to a series with befoulment augment type + updated = Weapon + .joins(:weapon_series) + .where(weapon_series: { augment_type: :befoulment }) + .update_all(max_exorcism_level: 5) + + puts " Updated #{updated} weapons with max_exorcism_level = 5" + end + + def down + Weapon + .joins(:weapon_series) + .where(weapon_series: { augment_type: :befoulment }) + .update_all(max_exorcism_level: nil) + end +end diff --git a/spec/requests/collection_weapons_controller_spec.rb b/spec/requests/collection_weapons_controller_spec.rb index 310cb80..ef93f93 100644 --- a/spec/requests/collection_weapons_controller_spec.rb +++ b/spec/requests/collection_weapons_controller_spec.rb @@ -279,4 +279,63 @@ RSpec.describe 'Collection Weapons API', type: :request do expect(response).to have_http_status(:not_found) end end + + describe 'default exorcism_level for befoulment weapons' do + let(:odiant_series) { create(:weapon_series, :odiant) } + let(:befoulment_weapon) { create(:weapon, weapon_series: odiant_series, max_exorcism_level: 5) } + let(:regular_weapon) { create(:weapon) } + + it 'sets exorcism_level to 1 when creating with befoulment weapon and no exorcism_level provided' do + attributes = { + collection_weapon: { + weapon_id: befoulment_weapon.id, + uncap_level: 3, + transcendence_step: 0 + } + } + + post '/api/v1/collection/weapons', params: attributes.to_json, headers: headers + + expect(response).to have_http_status(:created) + json = JSON.parse(response.body) + expect(json['exorcismLevel']).to eq(1) + end + + it 'respects provided exorcism_level for befoulment weapon' do + befoulment_modifier = create(:weapon_stat_modifier, :befoulment) + + attributes = { + collection_weapon: { + weapon_id: befoulment_weapon.id, + uncap_level: 3, + transcendence_step: 0, + exorcism_level: 3, + befoulment_modifier_id: befoulment_modifier.id, + befoulment_strength: 5.0 + } + } + + post '/api/v1/collection/weapons', params: attributes.to_json, headers: headers + + expect(response).to have_http_status(:created) + json = JSON.parse(response.body) + expect(json['exorcismLevel']).to eq(3) + end + + it 'does not set exorcism_level for non-befoulment weapons' do + attributes = { + collection_weapon: { + weapon_id: regular_weapon.id, + uncap_level: 3, + transcendence_step: 0 + } + } + + post '/api/v1/collection/weapons', params: attributes.to_json, headers: headers + + expect(response).to have_http_status(:created) + json = JSON.parse(response.body) + expect(json['exorcismLevel']).to be_nil + end + end end \ No newline at end of file diff --git a/spec/requests/grid_weapons_controller_spec.rb b/spec/requests/grid_weapons_controller_spec.rb index f1963f8..c5a4d95 100644 --- a/spec/requests/grid_weapons_controller_spec.rb +++ b/spec/requests/grid_weapons_controller_spec.rb @@ -345,6 +345,71 @@ RSpec.describe 'GridWeapons API', type: :request do end end + describe 'default exorcism_level for befoulment weapons' do + let(:odiant_series) { create(:weapon_series, :odiant) } + let(:befoulment_weapon) { create(:weapon, weapon_series: odiant_series, max_exorcism_level: 5) } + let(:regular_weapon) { create(:weapon) } + + it 'sets exorcism_level to 1 when creating with befoulment weapon and no exorcism_level provided' do + params = { + weapon: { + party_id: party.id, + weapon_id: befoulment_weapon.id, + position: 1, + uncap_level: 3, + transcendence_step: 0 + } + } + + post '/api/v1/grid_weapons', params: params.to_json, headers: headers + + expect(response).to have_http_status(:created) + json = JSON.parse(response.body) + expect(json['grid_weapon']['exorcismLevel']).to eq(1) + end + + it 'respects provided exorcism_level for befoulment weapon' do + befoulment_modifier = create(:weapon_stat_modifier, :befoulment) + + params = { + weapon: { + party_id: party.id, + weapon_id: befoulment_weapon.id, + position: 1, + uncap_level: 3, + transcendence_step: 0, + exorcism_level: 4, + befoulment_modifier_id: befoulment_modifier.id, + befoulment_strength: 5.0 + } + } + + post '/api/v1/grid_weapons', params: params.to_json, headers: headers + + expect(response).to have_http_status(:created) + json = JSON.parse(response.body) + expect(json['grid_weapon']['exorcismLevel']).to eq(4) + end + + it 'does not set exorcism_level for non-befoulment weapons' do + params = { + weapon: { + party_id: party.id, + weapon_id: regular_weapon.id, + position: 1, + uncap_level: 3, + transcendence_step: 0 + } + } + + post '/api/v1/grid_weapons', params: params.to_json, headers: headers + + expect(response).to have_http_status(:created) + json = JSON.parse(response.body) + expect(json['grid_weapon']['exorcismLevel']).to be_nil + end + end + # Debug hook: if any example fails and a response exists, print the error message. after(:each) do |example| if example.exception && defined?(response) && response.present?