impress/spec/models/pet_spec.rb
Emi Matchu e65634d8bc Set up tests for Majal_Kita and its alt style
Not actually touching alt style yet, just the very basic stuff about
how alt style can cause loading to fail in certain extremely rare cases
(specifically, if it's our first time seeing the underlying
color/species combo too, which… isn't gonna happen irl on DTI for a long
time if ever, I would guess, but hey!)
2024-10-25 14:47:51 -07:00

409 lines
17 KiB
Ruby

require 'rails_helper'
require_relative '../support/mocks/custom_pets'
require_relative '../support/matchers/a_record_matching'
RSpec.describe Pet, type: :model do
fixtures :colors, :species, :zones
context ".load" do
context "for thyassa, the Purple Chia" do
subject(:pet) { Pet.load "thyassa" }
it("is named thyassa") { expect(pet.name).to eq("thyassa") }
it("has no items") { expect(pet.items).to be_empty }
describe "its pet type" do
subject(:pet_type) { pet.pet_type }
it("is new and unsaved") { should be_new_record }
it("is Purple") { expect(pet_type.color).to eq Color.find_by_name!("purple") }
it("is a Chia") { expect(pet_type.species).to eq Species.find_by_name!("chia") }
it("has the standard Chia body") { expect(pet_type.body_id).to eq 212 }
it("uses the pet's image hash") { expect(pet_type.image_hash).to eq "m:thyass" }
it("is saved when saving the pet") { pet.save!; should be_persisted }
end
describe "its pet state" do
subject(:pet_state) { pet.pet_state }
it("is new and unsaved") { should be_new_record }
it("belongs to the pet's pet type") { expect(pet_state.pet_type).to eq pet.pet_type }
it("isn't labeled yet") { expect(pet_state.pose).to eq "UNKNOWN" }
it("is saved when saving the pet") { pet.save!; should be_persisted }
describe "its biology assets" do
# TODO: I wish biology assets were set up before saving.
# Once we change this, we can un-mark some tests as pending.
before { pet.save! }
subject(:biology_assets) { pet_state.swf_assets }
let(:asset_ids) { biology_assets.map(&:remote_id) }
they("are all new") do
pending("Currently, pets must be saved before assets are assigned.")
should all be_new_record
end
they("match the expected IDs") do
expect(asset_ids).to contain_exactly(10083, 11613, 14187, 14189)
end
they("are saved when saving the pet") { pet.save!; should all be_persisted }
they("have the expected asset metadata") do
expect(pet_state.swf_assets).to contain_exactly(
a_record_matching(
type: "biology",
remote_id: 10083,
zone_id: 37,
url: "https://images.neopets.com/cp/bio/swf/000/000/010/10083_8a1111a13f.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/010/10083_8a1111a13f/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
type: "biology",
remote_id: 11613,
zone_id: 15,
url: "https://images.neopets.com/cp/bio/swf/000/000/011/11613_f7d8d377ab.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/011/11613_f7d8d377ab/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
type: "biology",
remote_id: 14187,
zone_id: 34,
url: "https://images.neopets.com/cp/bio/swf/000/000/014/14187_0e65c2082f.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/014/14187_0e65c2082f/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
type: "biology",
remote_id: 14189,
zone_id: 33,
url: "https://images.neopets.com/cp/bio/swf/000/000/014/14189_102e4991e9.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/014/14189_102e4991e9/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
)
)
end
end
end
context "when modeled a second time" do
before { pet.save! }
subject!(:new_pet) { Pet.load("thyassa") }
describe "its pet type" do
subject(:pet_type) { new_pet.pet_type }
it("already exists") { should be_persisted }
it("is the same as before") { should eq pet.pet_type }
it "is not changed when saving the pet" do
expect { new_pet.save! }.not_to change { pet_type.attributes }
end
end
describe "its pet state" do
subject(:pet_state) { new_pet.pet_state }
it("already exists") { should be_persisted }
it("is the same as before") { should eq pet.pet_state }
it "is not changed when saving the pet" do
expect { new_pet.save! }.not_to change { pet_state.attributes }
end
end
describe "its biology assets" do
subject(:biology_assets) { new_pet.pet_state.swf_assets }
they("already exist") { should all be_persisted }
they("are the same as before") { should eq pet.pet_state.swf_assets }
they("are not changed when saving the pet") do
expect { new_pet.save! }.not_to change { biology_assets.map(&:attributes) }
end
end
end
context "when modeled again, but happy" do
before { pet.save! }
subject(:new_pet) { Pet.load("thyassa:happy") }
describe "its pet type" do
subject(:pet_type) { new_pet.pet_type }
it("already exists") { should be_persisted }
it("is the same as before") { should eq pet.pet_type }
it "is not changed when saving the pet" do
expect { new_pet.save! }.not_to change { pet_type.attributes }
end
end
describe "its pet state" do
subject(:pet_state) { new_pet.pet_state }
it("is new and unsaved") { should be_new_record }
it("belongs to the same pet type") { expect(pet_state.pet_type).to eq pet.pet_type }
it("isn't labeled yet") { expect(pet_state.pose).to eq "UNKNOWN" }
it("is saved when saving the pet") { new_pet.save!; should be_persisted }
describe "its biology assets" do
# TODO: I wish biology assets were set up before saving.
# Once we change this, we can un-mark some tests as pending.
before { new_pet.save! }
subject(:biology_assets) { pet_state.swf_assets }
let(:asset_ids) { biology_assets.map(&:remote_id) }
they("are partially new, partially existing") do
pending("Currently, pets must be saved before assets are assigned.")
fail # TODO: Write this test once we have the ability to see it pass!
end
they("match the expected IDs") do
expect(asset_ids).to contain_exactly(10083, 11613, 10448, 10451)
end
they("are saved when saving the pet") { new_pet.save!; should all be_persisted }
they("have the expected asset metadata") do
expect(pet_state.swf_assets).to contain_exactly(
a_record_matching(
type: "biology",
remote_id: 10083,
zone_id: 37,
url: "https://images.neopets.com/cp/bio/swf/000/000/010/10083_8a1111a13f.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/010/10083_8a1111a13f/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
type: "biology",
remote_id: 11613,
zone_id: 15,
url: "https://images.neopets.com/cp/bio/swf/000/000/011/11613_f7d8d377ab.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/011/11613_f7d8d377ab/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
type: "biology",
remote_id: 10448,
zone_id: 34,
url: "https://images.neopets.com/cp/bio/swf/000/000/010/10448_0b238e79e2.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/010/10448_0b238e79e2/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
type: "biology",
remote_id: 10451,
zone_id: 33,
url: "https://images.neopets.com/cp/bio/swf/000/000/010/10451_cd4a8a8e47.swf",
manifest_url: "https://images.neopets.com/cp/bio/data/000/000/010/10451_cd4a8a8e47/manifest.json",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
)
)
end
end
end
end
end
context "for matts_bat, a pet with basic items" do
subject(:pet) { Pet.load("matts_bat") }
# We do simpler checks for biology, and trust the Thyassa case to cover it.
it("is named matts_bat") { expect(pet.name).to eq "matts_bat" }
it("is a Striped Blumaroo") { expect(pet.pet_type.human_name).to eq "Striped Blumaroo" }
describe "its biology assets" do
# TODO: I wish biology assets were set up before saving.
# Once we change this, we can un-mark some tests as pending.
before { pet.save! }
subject(:biology_assets) { pet.pet_state.swf_assets }
let(:asset_ids) { biology_assets.map(&:remote_id) }
they("are all new") do
pending("Currently, pets must be saved before assets are assigned.")
should all be_new_record
end
they("match the expected IDs") do
expect(asset_ids).to contain_exactly(331, 332, 333, 23760, 23411)
end
they("are saved when saving the pet") { pet.save!; should all be_persisted }
end
describe "its items" do
subject(:items) { pet.items }
let(:item_ids) { items.map(&:id) }
they("are all new") { should all be_new_record }
they("match the expected IDs") do
expect(item_ids).to contain_exactly(39552, 53874, 71706)
end
they("are saved when saving the pet") { pet.save! ; should all be_persisted }
they("have the expected item metadata") do
should contain_exactly(
a_record_matching(
id: 39552,
name: "Springy Eye Glasses",
description: "Hey, keep your eyes in your head!",
thumbnail_url: "https://images.neopets.com/items/mall_springyeyeglasses.gif",
category: "Clothes",
type: "Clothes",
rarity: "Artifact",
rarity_index: 500,
price: 0,
weight_lbs: 1,
species_support_ids: "3",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
id: 53874,
name: "404 Shirt",
description: "When Neopets is down, the shirt comes on!",
thumbnail_url: "https://images.neopets.com/items/clo_404_shirt.gif",
category: "Clothes",
type: "Clothes",
rarity: "Rare",
rarity_index: 88,
price: 1701,
weight_lbs: 1,
species_support_ids: "3",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
a_record_matching(
id: 71706,
name: "On the Roof Background",
description: "Who is that on the roof?! Could it be...?",
thumbnail_url: "https://images.neopets.com/items/gif_roof_onthe_fg.gif",
category: "Special",
type: "Mystical Surroundings",
rarity: "Special",
rarity_index: 101,
price: 0,
weight_lbs: 1,
species_support_ids: "",
zones_restrict: "0000000000000000000000000000000000000000000000000000",
),
)
end
end
context "its item assets" do
# TODO: I wish item assets were set up before saving.
# Once we change this, we can un-mark some tests as pending.
before { pet.save! }
let(:assets_by_item) { pet.items.to_h { |item| [item.id, item.swf_assets.to_a] } }
subject(:item_assets) { assets_by_item.values.flatten(1) }
let(:asset_ids) { item_assets.map(&:remote_id) }
they("are all new") do
pending("Currently, pets must be saved before assets are assigned.")
should all be_new_record
end
they("match the expected IDs") do
expect(asset_ids).to contain_exactly(16933, 108567, 410722)
end
they("are saved when saving the pet") { pet.save! ; should all be_persisted }
they("match the expected metadata") do
expect(assets_by_item).to match(
39552 => a_collection_containing_exactly(
a_record_matching(
type: "object",
remote_id: 16933,
zone_id: 35,
url: "https://images.neopets.com/cp/items/swf/000/000/016/16933_0833353c4f.swf",
manifest_url: "https://images.neopets.com/cp/items/data/000/000/016/16933_0833353c4f/manifest.json?v=1706",
zones_restrict: "",
)
),
53874 => a_collection_containing_exactly(
a_record_matching(
type: "object",
remote_id: 108567,
zone_id: 23,
url: "https://images.neopets.com/cp/items/swf/000/000/108/108567_ee88141325.swf",
manifest_url: "https://images.neopets.com/cp/items/data/000/000/108/108567_ee88141325/manifest.json?v=1706",
zones_restrict: "",
)
),
71706 => a_collection_containing_exactly(
a_record_matching(
type: "object",
remote_id: 410722,
zone_id: 3,
url: "https://images.neopets.com/cp/items/swf/000/000/410/410722_3bcd2f5e11.swf",
manifest_url: "https://images.neopets.com/cp/items/data/000/000/410/410722_3bcd2f5e11/manifest.json?v=1706",
zones_restrict: "",
)
),
)
end
end
context "when modeled a second time" do
before { pet.save! }
subject!(:new_pet) { Pet.load("matts_bat") }
describe "its pet type" do
subject(:pet_type) { new_pet.pet_type }
it("already exists") { should be_persisted }
it("is the same as before") { should eq pet.pet_type }
it "is not changed when saving the pet" do
expect { new_pet.save! }.not_to change { pet_type.attributes }
end
end
describe "its pet state" do
subject(:pet_state) { new_pet.pet_state }
it("already exists") { should be_persisted }
it("is the same as before") { should eq pet.pet_state }
it "is not changed when saving the pet" do
expect { new_pet.save! }.not_to change { pet_state.attributes }
end
end
describe "its biology assets" do
subject(:biology_assets) { new_pet.pet_state.swf_assets }
they("already exist") { should all be_persisted }
they("are the same as before") { should eq pet.pet_state.swf_assets }
they("are not changed when saving the pet") do
expect { new_pet.save! }.not_to change { biology_assets.map(&:attributes) }
end
end
describe "its items" do
subject(:items) { new_pet.items }
they("already exist") { should all be_persisted }
they("are the same as before") { should eq pet.items }
they("are not changed when saving the pet") do
expect { new_pet.save! }.not_to change { items.map(&:attributes) }
end
end
describe "its item assets" do
subject(:item_assets) { new_pet.items.map(&:swf_assets).flatten(1) }
they("already exist") { should all be_persisted }
they("are the same as before") { should eq pet.items.map(&:swf_assets).flatten(1) }
they("are not changed when saving the pet") do
expect { new_pet.save! }.not_to change { item_assets.map(&:attributes) }
end
end
end
end
context "for Majal_Kita, the Nostalgic Robot Jetsam (modded to be Blue as its base)" do
it("fails to load without an existing Blue Jetsam, " +
"because the biology data is incomplete") do
expect { Pet.load("Majal_Kita") }.to raise_error(Pet::UnexpectedDataFormat)
end
context "with a Blue Jetsam already modeled" do
before { Pet.load("Blue_Jetsam").save! }
it("loads without raising an error") do
expect { Pet.load("Majal_Kita") }.not_to raise_error
end
end
end
end
end