diff --git a/app/models/mod.rb b/app/models/mod.rb index c46e1f2..e742a00 100644 --- a/app/models/mod.rb +++ b/app/models/mod.rb @@ -19,7 +19,7 @@ def self.all end def self.fetch_all # :nodoc: - firestore.col("mods").get.filter_map do |mod| + mods = firestore.col("mods").get.filter_map do |mod| new( author: mod.data[:author], compatibility: mod.data[:compatibility], @@ -34,7 +34,9 @@ def self.fetch_all # :nodoc: created_at: mod.create_time, updated_at: mod.update_time ) - end.sort_by(&:name) + end + + mods.uniq { |mod| [mod.name.downcase, mod.author_slug] }.sort_by(&:name) end private_class_method :fetch_all @@ -54,23 +56,28 @@ def zip? files.key?(:zip) end + def exmod? + files.key?(:exmod) + end + def exmodz? files.key?(:exmodz) end # Determines which file types can be downloaded from the index page - # Priority: pak > zip > exmodz (most common/compatible format first) + # Priority: pak > zip > exmodz > exmod (most common/compatible format first) def preferred_type return :pak if pak? return :zip if zip? return :exmodz if exmodz? + return :exmod if exmod? nil end # Determines which file types can be downloaded from the show page def download_types - file_types.map(&:to_sym) & %i[pak zip exmodz] + file_types.map(&:to_sym) & %i[pak zip exmodz exmod] end def file_types diff --git a/app/views/mods/show.html.erb b/app/views/mods/show.html.erb index dc53185..683b292 100644 --- a/app/views/mods/show.html.erb +++ b/app/views/mods/show.html.erb @@ -23,7 +23,7 @@
- <% if @mod.exmodz? %> + <% if @mod.exmodz? || @mod.exmod? %> This Mod includes an EXMOD formatted file, which doesn't need updates each week.
We recommend you use a Mod Manager to install this mod <% end %> diff --git a/spec/models/mod_spec.rb b/spec/models/mod_spec.rb index 29e080f..85181f1 100644 --- a/spec/models/mod_spec.rb +++ b/spec/models/mod_spec.rb @@ -11,8 +11,8 @@ create_time: Time.now.utc, update_time: Time.now.utc, data: { - name: Faker::App.name, - author: Faker::App.author, + name: "Alpha Mod", + author: "Author One", description: Faker::Lorem.sentence, version: Faker::App.version, compatibility: "w#{Random.rand(1..5)}", @@ -23,9 +23,23 @@ end let(:mod) { build :mod } + # Builds a Firestore document snapshot double with the given name and author + def firestore_doc(name: Faker::App.name, author: Faker::App.author) + instance_double(Google::Cloud::Firestore::DocumentSnapshot, + document_id: SecureRandom.uuid, + create_time: Time.now.utc, + update_time: Time.now.utc, + data: { + name: name, author: author, description: Faker::Lorem.sentence, + version: Faker::App.version, compatibility: "w#{Random.rand(1..5)}", + files: { zip: Faker::Internet.url }, + imageURL: Faker::Internet.url, readmeURL: Faker::Internet.url + }) + end + before do allow(Google::Cloud::Firestore).to receive(:new).and_return(firestore_client) - allow(firestore_collection).to receive(:get).and_return(Array.new(2, mod_firestore_obj)) + allow(firestore_collection).to receive(:get).and_return([mod_firestore_obj, firestore_doc(name: "Beta Mod", author: "Author Two")]) allow(firestore_client).to receive(:col).with("mods").and_return(firestore_collection) end @@ -51,6 +65,14 @@ it "returns all mods" do expect(described_class.all.count).to eq(2) end + + it "deduplicates mods with the same name and author" do + duplicate = firestore_doc(name: "Alpha Mod", author: "Author One") + unique = firestore_doc(name: "Beta Mod", author: "Author Two") + allow(firestore_collection).to receive(:get).and_return([mod_firestore_obj, duplicate, unique]) + + expect(described_class.all.count).to eq(2) + end end context "when the readme_url is present" do @@ -174,7 +196,7 @@ end end - %i[pak zip exmodz].each do |file_type| + %i[pak zip exmod exmodz].each do |file_type| describe "##{file_type}?" do context "when given a #{file_type} object" do before { mod.files = { file_type.to_sym => Faker::Internet.url } } @@ -227,7 +249,7 @@ before { mod.files = { exmod: Faker::Internet.url } } it "returns the preferred type" do - expect(mod.preferred_type).to be_nil + expect(mod.preferred_type).to eq(:exmod) end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 51a1614..6d61b76 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -13,6 +13,8 @@ require "rspec/rails" RSpec.configure do |config| + config.include ActiveSupport::Testing::TimeHelpers + config.before(:each, type: :request) do host! "localhost" end