update tests and factories for weapon_stat_modifier fks
This commit is contained in:
parent
4d87d113dc
commit
abc30c151b
11 changed files with 291 additions and 62 deletions
|
|
@ -41,26 +41,6 @@ module Processors
|
||||||
class WeaponProcessor < BaseProcessor
|
class WeaponProcessor < BaseProcessor
|
||||||
TRANSCENDENCE_LEVELS = [200, 210, 220, 230, 240, 250].freeze
|
TRANSCENDENCE_LEVELS = [200, 210, 220, 230, 240, 250].freeze
|
||||||
|
|
||||||
# Mapping from in‑game AX skill IDs (as strings) to our internal modifier values.
|
|
||||||
AX_MAPPING = {
|
|
||||||
'1588' => 2,
|
|
||||||
'1589' => 0,
|
|
||||||
'1590' => 1,
|
|
||||||
'1591' => 3,
|
|
||||||
'1592' => 4,
|
|
||||||
'1593' => 9,
|
|
||||||
'1594' => 13,
|
|
||||||
'1595' => 10,
|
|
||||||
'1596' => 5,
|
|
||||||
'1597' => 6,
|
|
||||||
'1599' => 8,
|
|
||||||
'1600' => 12,
|
|
||||||
'1601' => 11,
|
|
||||||
'1719' => 15,
|
|
||||||
'1720' => 16,
|
|
||||||
'1721' => 17,
|
|
||||||
'1722' => 14
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
# KEY_MAPPING maps the raw key value (as a string) to a canonical range or value.
|
# KEY_MAPPING maps the raw key value (as a string) to a canonical range or value.
|
||||||
# For example, in our test we want a raw key "10001" to be interpreted as any key whose
|
# For example, in our test we want a raw key "10001" to be interpreted as any key whose
|
||||||
|
|
@ -331,7 +311,8 @@ module Processors
|
||||||
# Processes AX (augment) skill data.
|
# Processes AX (augment) skill data.
|
||||||
#
|
#
|
||||||
# The deck stores AX skills in an array of arrays under "augment_skill_info".
|
# The deck stores AX skills in an array of arrays under "augment_skill_info".
|
||||||
# This method flattens the data and assigns each skill’s modifier and strength.
|
# This method flattens the data and assigns each skill's modifier and strength.
|
||||||
|
# Modifiers are now looked up by game_skill_id in the weapon_stat_modifiers table.
|
||||||
#
|
#
|
||||||
# @param grid_weapon [GridWeapon] the grid weapon record being built.
|
# @param grid_weapon [GridWeapon] the grid weapon record being built.
|
||||||
# @param ax_skill_info [Array] the raw AX skill info.
|
# @param ax_skill_info [Array] the raw AX skill info.
|
||||||
|
|
@ -340,14 +321,59 @@ module Processors
|
||||||
# Flatten the nested array structure.
|
# Flatten the nested array structure.
|
||||||
ax_skills = ax_skill_info.flatten
|
ax_skills = ax_skill_info.flatten
|
||||||
ax_skills.each_with_index do |ax, idx|
|
ax_skills.each_with_index do |ax, idx|
|
||||||
ax_id = ax['skill_id'].to_s
|
break if idx >= 2 # Only 2 AX skill slots
|
||||||
ax_mod = AX_MAPPING[ax_id] || ax_id.to_i
|
|
||||||
strength = ax['effect_value'].to_s.gsub(/[+%]/, '').to_i
|
game_skill_id = ax['skill_id'].to_i
|
||||||
grid_weapon["ax_modifier#{idx + 1}"] = ax_mod
|
modifier = find_modifier_by_game_skill_id(game_skill_id)
|
||||||
|
|
||||||
|
unless modifier
|
||||||
|
Rails.logger.warn(
|
||||||
|
"[WeaponProcessor] Unknown augment skill_id=#{game_skill_id} " \
|
||||||
|
"icon=#{ax['augment_skill_icon_image']}"
|
||||||
|
)
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
strength = parse_augment_strength(ax['effect_value'], ax['show_value'])
|
||||||
|
grid_weapon["ax_modifier#{idx + 1}_id"] = modifier.id
|
||||||
grid_weapon["ax_strength#{idx + 1}"] = strength
|
grid_weapon["ax_strength#{idx + 1}"] = strength
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Finds a WeaponStatModifier by its game_skill_id.
|
||||||
|
# Uses memoization to cache lookups.
|
||||||
|
#
|
||||||
|
# @param game_skill_id [Integer] the game's skill ID.
|
||||||
|
# @return [WeaponStatModifier, nil]
|
||||||
|
def find_modifier_by_game_skill_id(game_skill_id)
|
||||||
|
@modifier_cache ||= {}
|
||||||
|
@modifier_cache[game_skill_id] ||= WeaponStatModifier.find_by(game_skill_id: game_skill_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Parses the strength value from effect_value or show_value.
|
||||||
|
#
|
||||||
|
# @param effect_value [String, nil] the effect_value field.
|
||||||
|
# @param show_value [String, nil] the show_value field.
|
||||||
|
# @return [Float, nil]
|
||||||
|
def parse_augment_strength(effect_value, show_value)
|
||||||
|
if effect_value.present?
|
||||||
|
# Handle "1_3" format (seems to be "tier_value")
|
||||||
|
if effect_value.to_s.include?('_')
|
||||||
|
return effect_value.to_s.split('_').last.to_f
|
||||||
|
end
|
||||||
|
return effect_value.to_f if effect_value.to_s.match?(/\A[\d.]+\z/)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Try show_value (e.g., "3%")
|
||||||
|
if show_value.present?
|
||||||
|
return show_value.to_s.gsub('%', '').to_f
|
||||||
|
end
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Maps the in‑game awakening data (stored under "arousal") to our Awakening record.
|
# Maps the in‑game awakening data (stored under "arousal") to our Awakening record.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,36 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
||||||
|
# Old AX_MAPPING from WeaponProcessor: game_skill_id (string) => internal_value (integer)
|
||||||
|
# We need the reverse: internal_value => game_skill_id
|
||||||
|
OLD_INTERNAL_TO_GAME_SKILL_ID = {
|
||||||
|
2 => 1588, # HP
|
||||||
|
0 => 1589, # ATK
|
||||||
|
1 => 1590, # DEF
|
||||||
|
3 => 1591, # C.A. DMG
|
||||||
|
4 => 1592, # Multiattack Rate
|
||||||
|
9 => 1593, # Debuff Resistance
|
||||||
|
13 => 1594, # Elemental ATK
|
||||||
|
10 => 1595, # Healing
|
||||||
|
5 => 1596, # Double Attack Rate
|
||||||
|
6 => 1597, # Triple Attack Rate
|
||||||
|
8 => 1599, # C.A. DMG Cap
|
||||||
|
12 => 1600, # Stamina
|
||||||
|
11 => 1601, # Enmity
|
||||||
|
15 => 1719, # Supplemental Skill DMG
|
||||||
|
16 => 1720, # Supplemental C.A. DMG
|
||||||
|
17 => 1721, # Elemental DMG Reduction
|
||||||
|
14 => 1722 # Normal ATK DMG Cap
|
||||||
|
}.freeze
|
||||||
|
|
||||||
def up
|
def up
|
||||||
# Build lookup cache: game_skill_id -> weapon_stat_modifier.id
|
# Build lookup cache: game_skill_id -> weapon_stat_modifier.id
|
||||||
modifier_lookup = WeaponStatModifier.pluck(:game_skill_id, :id).to_h
|
modifier_by_game_skill_id = WeaponStatModifier.pluck(:game_skill_id, :id).to_h
|
||||||
|
|
||||||
# Migrate CollectionWeapon ax_modifier1
|
# Migrate CollectionWeapon ax_modifier1
|
||||||
CollectionWeapon.where.not(ax_modifier1: nil).find_each do |cw|
|
CollectionWeapon.where.not(ax_modifier1: nil).find_each do |cw|
|
||||||
modifier_id = modifier_lookup[cw.ax_modifier1]
|
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[cw.ax_modifier1]
|
||||||
|
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||||
if modifier_id
|
if modifier_id
|
||||||
cw.update_columns(ax_modifier1_ref_id: modifier_id)
|
cw.update_columns(ax_modifier1_ref_id: modifier_id)
|
||||||
else
|
else
|
||||||
|
|
@ -17,7 +40,8 @@ class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
||||||
|
|
||||||
# Migrate CollectionWeapon ax_modifier2
|
# Migrate CollectionWeapon ax_modifier2
|
||||||
CollectionWeapon.where.not(ax_modifier2: nil).find_each do |cw|
|
CollectionWeapon.where.not(ax_modifier2: nil).find_each do |cw|
|
||||||
modifier_id = modifier_lookup[cw.ax_modifier2]
|
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[cw.ax_modifier2]
|
||||||
|
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||||
if modifier_id
|
if modifier_id
|
||||||
cw.update_columns(ax_modifier2_ref_id: modifier_id)
|
cw.update_columns(ax_modifier2_ref_id: modifier_id)
|
||||||
else
|
else
|
||||||
|
|
@ -27,7 +51,8 @@ class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
||||||
|
|
||||||
# Migrate GridWeapon ax_modifier1
|
# Migrate GridWeapon ax_modifier1
|
||||||
GridWeapon.where.not(ax_modifier1: nil).find_each do |gw|
|
GridWeapon.where.not(ax_modifier1: nil).find_each do |gw|
|
||||||
modifier_id = modifier_lookup[gw.ax_modifier1]
|
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[gw.ax_modifier1]
|
||||||
|
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||||
if modifier_id
|
if modifier_id
|
||||||
gw.update_columns(ax_modifier1_ref_id: modifier_id)
|
gw.update_columns(ax_modifier1_ref_id: modifier_id)
|
||||||
else
|
else
|
||||||
|
|
@ -37,7 +62,8 @@ class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
||||||
|
|
||||||
# Migrate GridWeapon ax_modifier2
|
# Migrate GridWeapon ax_modifier2
|
||||||
GridWeapon.where.not(ax_modifier2: nil).find_each do |gw|
|
GridWeapon.where.not(ax_modifier2: nil).find_each do |gw|
|
||||||
modifier_id = modifier_lookup[gw.ax_modifier2]
|
game_skill_id = OLD_INTERNAL_TO_GAME_SKILL_ID[gw.ax_modifier2]
|
||||||
|
modifier_id = game_skill_id ? modifier_by_game_skill_id[game_skill_id] : nil
|
||||||
if modifier_id
|
if modifier_id
|
||||||
gw.update_columns(ax_modifier2_ref_id: modifier_id)
|
gw.update_columns(ax_modifier2_ref_id: modifier_id)
|
||||||
else
|
else
|
||||||
|
|
@ -47,18 +73,24 @@ class MigrateAxModifiersToFk < ActiveRecord::Migration[8.0]
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
# Reverse: copy FK back to integer columns
|
# Build reverse lookup: game_skill_id -> old internal value
|
||||||
|
game_skill_id_to_internal = OLD_INTERNAL_TO_GAME_SKILL_ID.invert
|
||||||
|
|
||||||
|
# Reverse: copy FK back to integer columns using old internal values
|
||||||
WeaponStatModifier.find_each do |modifier|
|
WeaponStatModifier.find_each do |modifier|
|
||||||
next unless modifier.game_skill_id
|
next unless modifier.game_skill_id
|
||||||
|
|
||||||
|
internal_value = game_skill_id_to_internal[modifier.game_skill_id]
|
||||||
|
next unless internal_value
|
||||||
|
|
||||||
CollectionWeapon.where(ax_modifier1_ref_id: modifier.id)
|
CollectionWeapon.where(ax_modifier1_ref_id: modifier.id)
|
||||||
.update_all(ax_modifier1: modifier.game_skill_id)
|
.update_all(ax_modifier1: internal_value)
|
||||||
CollectionWeapon.where(ax_modifier2_ref_id: modifier.id)
|
CollectionWeapon.where(ax_modifier2_ref_id: modifier.id)
|
||||||
.update_all(ax_modifier2: modifier.game_skill_id)
|
.update_all(ax_modifier2: internal_value)
|
||||||
GridWeapon.where(ax_modifier1_ref_id: modifier.id)
|
GridWeapon.where(ax_modifier1_ref_id: modifier.id)
|
||||||
.update_all(ax_modifier1: modifier.game_skill_id)
|
.update_all(ax_modifier1: internal_value)
|
||||||
GridWeapon.where(ax_modifier2_ref_id: modifier.id)
|
GridWeapon.where(ax_modifier2_ref_id: modifier.id)
|
||||||
.update_all(ax_modifier2: modifier.game_skill_id)
|
.update_all(ax_modifier2: internal_value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,17 @@ FactoryBot.define do
|
||||||
awakening_level { 1 }
|
awakening_level { 1 }
|
||||||
element { nil } # Only used for element-changeable weapons
|
element { nil } # Only used for element-changeable weapons
|
||||||
|
|
||||||
# AX skills
|
# AX skills (FK to weapon_stat_modifiers)
|
||||||
ax_modifier1 { nil }
|
ax_modifier1 { nil }
|
||||||
ax_strength1 { nil }
|
ax_strength1 { nil }
|
||||||
ax_modifier2 { nil }
|
ax_modifier2 { nil }
|
||||||
ax_strength2 { nil }
|
ax_strength2 { nil }
|
||||||
|
|
||||||
|
# Befoulment (FK to weapon_stat_modifiers)
|
||||||
|
befoulment_modifier { nil }
|
||||||
|
befoulment_strength { nil }
|
||||||
|
exorcism_level { 0 }
|
||||||
|
|
||||||
# Weapon keys
|
# Weapon keys
|
||||||
weapon_key1 { nil }
|
weapon_key1 { nil }
|
||||||
weapon_key2 { nil }
|
weapon_key2 { nil }
|
||||||
|
|
@ -75,10 +80,24 @@ FactoryBot.define do
|
||||||
|
|
||||||
# Trait for AX weapon with skills
|
# Trait for AX weapon with skills
|
||||||
trait :with_ax do
|
trait :with_ax do
|
||||||
ax_modifier1 { 1 } # Attack modifier
|
|
||||||
ax_strength1 { 3.5 }
|
ax_strength1 { 3.5 }
|
||||||
ax_modifier2 { 2 } # HP modifier
|
|
||||||
ax_strength2 { 10.0 }
|
ax_strength2 { 10.0 }
|
||||||
|
after(:build) do |collection_weapon|
|
||||||
|
collection_weapon.ax_modifier1 = WeaponStatModifier.find_by(slug: 'ax_atk') ||
|
||||||
|
FactoryBot.create(:weapon_stat_modifier, :ax_atk)
|
||||||
|
collection_weapon.ax_modifier2 = WeaponStatModifier.find_by(slug: 'ax_hp') ||
|
||||||
|
FactoryBot.create(:weapon_stat_modifier, :ax_hp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Trait for Odiant weapon with befoulment
|
||||||
|
trait :with_befoulment do
|
||||||
|
befoulment_strength { 23.0 }
|
||||||
|
exorcism_level { 2 }
|
||||||
|
after(:build) do |collection_weapon|
|
||||||
|
collection_weapon.befoulment_modifier = WeaponStatModifier.find_by(slug: 'befoul_def_down') ||
|
||||||
|
FactoryBot.create(:weapon_stat_modifier, :befoul_def_down)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Trait for element-changed weapon (Revans weapons)
|
# Trait for element-changed weapon (Revans weapons)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,39 @@ FactoryBot.define do
|
||||||
transcendence_step { 0 }
|
transcendence_step { 0 }
|
||||||
mainhand { false }
|
mainhand { false }
|
||||||
|
|
||||||
|
# AX skills (FK to weapon_stat_modifiers)
|
||||||
|
ax_modifier1 { nil }
|
||||||
|
ax_strength1 { nil }
|
||||||
|
ax_modifier2 { nil }
|
||||||
|
ax_strength2 { nil }
|
||||||
|
|
||||||
|
# Befoulment (FK to weapon_stat_modifiers)
|
||||||
|
befoulment_modifier { nil }
|
||||||
|
befoulment_strength { nil }
|
||||||
|
exorcism_level { 0 }
|
||||||
|
|
||||||
# Optional associations for weapon keys and awakening are left as nil by default.
|
# Optional associations for weapon keys and awakening are left as nil by default.
|
||||||
|
|
||||||
|
# Trait for AX weapon with skills
|
||||||
|
trait :with_ax do
|
||||||
|
ax_strength1 { 3.5 }
|
||||||
|
ax_strength2 { 10.0 }
|
||||||
|
after(:build) do |grid_weapon|
|
||||||
|
grid_weapon.ax_modifier1 = WeaponStatModifier.find_by(slug: 'ax_atk') ||
|
||||||
|
FactoryBot.create(:weapon_stat_modifier, :ax_atk)
|
||||||
|
grid_weapon.ax_modifier2 = WeaponStatModifier.find_by(slug: 'ax_hp') ||
|
||||||
|
FactoryBot.create(:weapon_stat_modifier, :ax_hp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Trait for Odiant weapon with befoulment
|
||||||
|
trait :with_befoulment do
|
||||||
|
befoulment_strength { 23.0 }
|
||||||
|
exorcism_level { 2 }
|
||||||
|
after(:build) do |grid_weapon|
|
||||||
|
grid_weapon.befoulment_modifier = WeaponStatModifier.find_by(slug: 'befoul_def_down') ||
|
||||||
|
FactoryBot.create(:weapon_stat_modifier, :befoul_def_down)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ FactoryBot.define do
|
||||||
element_changeable { false }
|
element_changeable { false }
|
||||||
has_weapon_keys { false }
|
has_weapon_keys { false }
|
||||||
has_awakening { false }
|
has_awakening { false }
|
||||||
has_ax_skills { false }
|
augment_type { :none }
|
||||||
|
|
||||||
trait :gacha do
|
trait :gacha do
|
||||||
slug { 'gacha' }
|
slug { 'gacha' }
|
||||||
|
|
@ -96,5 +96,21 @@ FactoryBot.define do
|
||||||
trait :with_weapon_keys do
|
trait :with_weapon_keys do
|
||||||
has_weapon_keys { true }
|
has_weapon_keys { true }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :with_ax_skills do
|
||||||
|
augment_type { :ax }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :with_befoulments do
|
||||||
|
augment_type { :befoulment }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :odiant do
|
||||||
|
slug { 'odiant' }
|
||||||
|
name_en { 'Odiant' }
|
||||||
|
name_jp { '禁禍武器' }
|
||||||
|
order { 50 }
|
||||||
|
augment_type { :befoulment }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
47
spec/factories/weapon_stat_modifiers.rb
Normal file
47
spec/factories/weapon_stat_modifiers.rb
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :weapon_stat_modifier do
|
||||||
|
sequence(:slug) { |n| "ax-modifier-#{n}" }
|
||||||
|
sequence(:name_en) { |n| "AX Modifier #{n}" }
|
||||||
|
category { 'ax' }
|
||||||
|
polarity { 1 }
|
||||||
|
|
||||||
|
trait :ax_atk do
|
||||||
|
slug { 'ax_atk' }
|
||||||
|
name_en { 'ATK' }
|
||||||
|
category { 'ax' }
|
||||||
|
stat { 'atk' }
|
||||||
|
polarity { 1 }
|
||||||
|
suffix { '%' }
|
||||||
|
game_skill_id { 1589 }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :ax_hp do
|
||||||
|
slug { 'ax_hp' }
|
||||||
|
name_en { 'HP' }
|
||||||
|
category { 'ax' }
|
||||||
|
stat { 'hp' }
|
||||||
|
polarity { 1 }
|
||||||
|
suffix { '%' }
|
||||||
|
game_skill_id { 1588 }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :befoulment do
|
||||||
|
sequence(:slug) { |n| "befoul-modifier-#{n}" }
|
||||||
|
sequence(:name_en) { |n| "Befoulment #{n}" }
|
||||||
|
category { 'befoulment' }
|
||||||
|
polarity { -1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :befoul_def_down do
|
||||||
|
slug { 'befoul_def_down' }
|
||||||
|
name_en { 'DEF Down' }
|
||||||
|
category { 'befoulment' }
|
||||||
|
stat { 'def' }
|
||||||
|
polarity { -1 }
|
||||||
|
suffix { '%' }
|
||||||
|
game_skill_id { 2880 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -76,9 +76,14 @@ RSpec.describe CollectionWeapon, type: :model do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'AX skill validations' do
|
describe 'AX skill validations' do
|
||||||
|
let(:ax_modifier) do
|
||||||
|
WeaponStatModifier.find_by(slug: 'ax_atk') ||
|
||||||
|
create(:weapon_stat_modifier, :ax_atk)
|
||||||
|
end
|
||||||
|
|
||||||
context 'when AX skill has only modifier' do
|
context 'when AX skill has only modifier' do
|
||||||
it 'is invalid' do
|
it 'is invalid' do
|
||||||
collection_weapon = build(:collection_weapon, ax_modifier1: 1, ax_strength1: nil)
|
collection_weapon = build(:collection_weapon, ax_modifier1: ax_modifier, ax_strength1: nil)
|
||||||
expect(collection_weapon).not_to be_valid
|
expect(collection_weapon).not_to be_valid
|
||||||
expect(collection_weapon.errors[:base]).to include('AX skill 1 must have both modifier and strength')
|
expect(collection_weapon.errors[:base]).to include('AX skill 1 must have both modifier and strength')
|
||||||
end
|
end
|
||||||
|
|
@ -94,7 +99,7 @@ RSpec.describe CollectionWeapon, type: :model do
|
||||||
|
|
||||||
context 'when AX skill has both modifier and strength' do
|
context 'when AX skill has both modifier and strength' do
|
||||||
it 'is valid' do
|
it 'is valid' do
|
||||||
collection_weapon = build(:collection_weapon, ax_modifier1: 1, ax_strength1: 3.5)
|
collection_weapon = build(:collection_weapon, ax_modifier1: ax_modifier, ax_strength1: 3.5)
|
||||||
expect(collection_weapon).to be_valid
|
expect(collection_weapon).to be_valid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -215,9 +220,11 @@ RSpec.describe CollectionWeapon, type: :model do
|
||||||
ax_weapon = create(:collection_weapon, :with_ax)
|
ax_weapon = create(:collection_weapon, :with_ax)
|
||||||
|
|
||||||
aggregate_failures do
|
aggregate_failures do
|
||||||
expect(ax_weapon.ax_modifier1).to eq(1)
|
expect(ax_weapon.ax_modifier1).to be_a(WeaponStatModifier)
|
||||||
|
expect(ax_weapon.ax_modifier1.slug).to eq('ax_atk')
|
||||||
expect(ax_weapon.ax_strength1).to eq(3.5)
|
expect(ax_weapon.ax_strength1).to eq(3.5)
|
||||||
expect(ax_weapon.ax_modifier2).to eq(2)
|
expect(ax_weapon.ax_modifier2).to be_a(WeaponStatModifier)
|
||||||
|
expect(ax_weapon.ax_modifier2.slug).to eq('ax_hp')
|
||||||
expect(ax_weapon.ax_strength2).to eq(10.0)
|
expect(ax_weapon.ax_strength2).to eq(10.0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -162,11 +162,16 @@ RSpec.describe 'Collection Weapons API', type: :request do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates weapon with AX skills' do
|
it 'creates weapon with AX skills' do
|
||||||
|
ax_atk = WeaponStatModifier.find_by(slug: 'ax_atk') ||
|
||||||
|
create(:weapon_stat_modifier, :ax_atk)
|
||||||
|
ax_hp = WeaponStatModifier.find_by(slug: 'ax_hp') ||
|
||||||
|
create(:weapon_stat_modifier, :ax_hp)
|
||||||
|
|
||||||
ax_attributes = valid_attributes.deep_merge(
|
ax_attributes = valid_attributes.deep_merge(
|
||||||
collection_weapon: {
|
collection_weapon: {
|
||||||
ax_modifier1: 1,
|
ax_modifier1_id: ax_atk.id,
|
||||||
ax_strength1: 3.5,
|
ax_strength1: 3.5,
|
||||||
ax_modifier2: 2,
|
ax_modifier2_id: ax_hp.id,
|
||||||
ax_strength2: 2.0
|
ax_strength2: 2.0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -176,14 +181,17 @@ RSpec.describe 'Collection Weapons API', type: :request do
|
||||||
expect(response).to have_http_status(:created)
|
expect(response).to have_http_status(:created)
|
||||||
json = JSON.parse(response.body)
|
json = JSON.parse(response.body)
|
||||||
expect(json['ax']).to be_present
|
expect(json['ax']).to be_present
|
||||||
expect(json['ax'].first['modifier']).to eq(1)
|
expect(json['ax'].first['modifier']['slug']).to eq('ax_atk')
|
||||||
expect(json['ax'].first['strength']).to eq(3.5)
|
expect(json['ax'].first['strength']).to eq(3.5)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns error with incomplete AX skills' do
|
it 'returns error with incomplete AX skills' do
|
||||||
|
ax_atk = WeaponStatModifier.find_by(slug: 'ax_atk') ||
|
||||||
|
create(:weapon_stat_modifier, :ax_atk)
|
||||||
|
|
||||||
invalid_ax = valid_attributes.deep_merge(
|
invalid_ax = valid_attributes.deep_merge(
|
||||||
collection_weapon: {
|
collection_weapon: {
|
||||||
ax_modifier1: 1
|
ax_modifier1_id: ax_atk.id
|
||||||
# Missing ax_strength1
|
# Missing ax_strength1
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -105,8 +105,8 @@ RSpec.describe 'GridWeapons API', type: :request do
|
||||||
weapon_key1_id: nil,
|
weapon_key1_id: nil,
|
||||||
weapon_key2_id: nil,
|
weapon_key2_id: nil,
|
||||||
weapon_key3_id: nil,
|
weapon_key3_id: nil,
|
||||||
ax_modifier1: nil,
|
ax_modifier1_id: nil,
|
||||||
ax_modifier2: nil,
|
ax_modifier2_id: nil,
|
||||||
ax_strength1: nil,
|
ax_strength1: nil,
|
||||||
ax_strength2: nil,
|
ax_strength2: nil,
|
||||||
awakening_id: nil,
|
awakening_id: nil,
|
||||||
|
|
@ -197,8 +197,8 @@ RSpec.describe 'GridWeapons API', type: :request do
|
||||||
weapon_key1_id: nil,
|
weapon_key1_id: nil,
|
||||||
weapon_key2_id: nil,
|
weapon_key2_id: nil,
|
||||||
weapon_key3_id: nil,
|
weapon_key3_id: nil,
|
||||||
ax_modifier1: nil,
|
ax_modifier1_id: nil,
|
||||||
ax_modifier2: nil,
|
ax_modifier2_id: nil,
|
||||||
ax_strength1: nil,
|
ax_strength1: nil,
|
||||||
ax_strength2: nil,
|
ax_strength2: nil,
|
||||||
awakening_id: nil,
|
awakening_id: nil,
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,25 @@ RSpec.describe Processors::WeaponProcessor, type: :model do
|
||||||
|
|
||||||
describe '#process_weapon_ax' do
|
describe '#process_weapon_ax' do
|
||||||
let(:grid_weapon) { build(:grid_weapon, party: party) }
|
let(:grid_weapon) { build(:grid_weapon, party: party) }
|
||||||
it 'flattens nested augment_skill_info and assigns ax_modifier and ax_strength' do
|
|
||||||
|
let!(:ax_hp_modifier) do
|
||||||
|
WeaponStatModifier.find_by(slug: 'ax_hp') ||
|
||||||
|
create(:weapon_stat_modifier, :ax_hp)
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:ax_ca_dmg_modifier) do
|
||||||
|
WeaponStatModifier.find_by(slug: 'ax_ca_dmg') ||
|
||||||
|
create(:weapon_stat_modifier,
|
||||||
|
slug: 'ax_ca_dmg',
|
||||||
|
name_en: 'C.A. DMG',
|
||||||
|
category: 'ax',
|
||||||
|
stat: 'ca_dmg',
|
||||||
|
polarity: 1,
|
||||||
|
suffix: '%',
|
||||||
|
game_skill_id: 1591)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'flattens nested augment_skill_info and assigns ax_modifier_id and ax_strength' do
|
||||||
ax_skill_info = [
|
ax_skill_info = [
|
||||||
[
|
[
|
||||||
{ 'skill_id' => '1588', 'effect_value' => '3', 'show_value' => '3%' },
|
{ 'skill_id' => '1588', 'effect_value' => '3', 'show_value' => '3%' },
|
||||||
|
|
@ -48,10 +66,10 @@ RSpec.describe Processors::WeaponProcessor, type: :model do
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
processor.send(:process_weapon_ax, grid_weapon, ax_skill_info)
|
processor.send(:process_weapon_ax, grid_weapon, ax_skill_info)
|
||||||
expect(grid_weapon.ax_modifier1).to eq(2) # from 1588 → 2
|
expect(grid_weapon.ax_modifier1).to eq(ax_hp_modifier)
|
||||||
expect(grid_weapon.ax_strength1).to eq(3)
|
expect(grid_weapon.ax_strength1).to eq(3.0)
|
||||||
expect(grid_weapon.ax_modifier2).to eq(3) # from 1591 → 3
|
expect(grid_weapon.ax_modifier2).to eq(ax_ca_dmg_modifier)
|
||||||
expect(grid_weapon.ax_strength2).to eq(5)
|
expect(grid_weapon.ax_strength2).to eq(5.0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,29 @@ RSpec.describe WeaponImportService, type: :service do
|
||||||
create(:awakening, :for_weapon, slug: 'weapon-heal', name_en: 'Healing')
|
create(:awakening, :for_weapon, slug: 'weapon-heal', name_en: 'Healing')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Create weapon stat modifiers for AX skill tests
|
||||||
|
let!(:ax_atk_modifier) do
|
||||||
|
WeaponStatModifier.find_by(slug: 'ax_atk') ||
|
||||||
|
create(:weapon_stat_modifier, :ax_atk)
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:ax_hp_modifier) do
|
||||||
|
WeaponStatModifier.find_by(slug: 'ax_hp') ||
|
||||||
|
create(:weapon_stat_modifier, :ax_hp)
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:ax_ca_dmg_modifier) do
|
||||||
|
WeaponStatModifier.find_by(slug: 'ax_ca_dmg') ||
|
||||||
|
create(:weapon_stat_modifier,
|
||||||
|
slug: 'ax_ca_dmg',
|
||||||
|
name_en: 'C.A. DMG',
|
||||||
|
category: 'ax',
|
||||||
|
stat: 'ca_dmg',
|
||||||
|
polarity: 1,
|
||||||
|
suffix: '%',
|
||||||
|
game_skill_id: 1591)
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
standard_weapon
|
standard_weapon
|
||||||
transcendable_weapon
|
transcendable_weapon
|
||||||
|
|
@ -279,12 +302,12 @@ RSpec.describe WeaponImportService, type: :service do
|
||||||
'augment_skill_info' => [
|
'augment_skill_info' => [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
'skill_id' => 1,
|
'skill_id' => 1589, # ATK modifier
|
||||||
'effect_value' => '7',
|
'effect_value' => '7',
|
||||||
'show_value' => '7%'
|
'show_value' => '7%'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'skill_id' => 2,
|
'skill_id' => 1588, # HP modifier
|
||||||
'effect_value' => '2_4',
|
'effect_value' => '2_4',
|
||||||
'show_value' => '4%'
|
'show_value' => '4%'
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +325,7 @@ RSpec.describe WeaponImportService, type: :service do
|
||||||
result = service.import
|
result = service.import
|
||||||
|
|
||||||
weapon = result.created.first
|
weapon = result.created.first
|
||||||
expect(weapon.ax_modifier1).to eq(1)
|
expect(weapon.ax_modifier1).to eq(ax_atk_modifier)
|
||||||
expect(weapon.ax_strength1).to eq(7.0)
|
expect(weapon.ax_strength1).to eq(7.0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -311,7 +334,7 @@ RSpec.describe WeaponImportService, type: :service do
|
||||||
result = service.import
|
result = service.import
|
||||||
|
|
||||||
weapon = result.created.first
|
weapon = result.created.first
|
||||||
expect(weapon.ax_modifier2).to eq(2)
|
expect(weapon.ax_modifier2).to eq(ax_hp_modifier)
|
||||||
expect(weapon.ax_strength2).to eq(4.0)
|
expect(weapon.ax_strength2).to eq(4.0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -329,7 +352,7 @@ RSpec.describe WeaponImportService, type: :service do
|
||||||
'augment_skill_info' => [
|
'augment_skill_info' => [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
'skill_id' => 3,
|
'skill_id' => 1591, # C.A. DMG modifier
|
||||||
'effect_value' => nil,
|
'effect_value' => nil,
|
||||||
'show_value' => '5.5%'
|
'show_value' => '5.5%'
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +370,7 @@ RSpec.describe WeaponImportService, type: :service do
|
||||||
result = service.import
|
result = service.import
|
||||||
|
|
||||||
weapon = result.created.first
|
weapon = result.created.first
|
||||||
expect(weapon.ax_modifier1).to eq(3)
|
expect(weapon.ax_modifier1).to eq(ax_ca_dmg_modifier)
|
||||||
expect(weapon.ax_strength1).to eq(5.5)
|
expect(weapon.ax_strength1).to eq(5.5)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue