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