Emi Matchu
e65634d8bc
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!)
409 lines
17 KiB
Ruby
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
|