diff --git a/app/assets/stylesheets/mods/index.sass b/app/assets/stylesheets/mods/index.sass
index 70a853e..2146745 100644
--- a/app/assets/stylesheets/mods/index.sass
+++ b/app/assets/stylesheets/mods/index.sass
@@ -6,7 +6,7 @@ $mods-list-size: 12-$filter-size
background: none
border-radius: none
padding: 0
-
+
.query-info-box
+span($mods-list-size omega of 12)
margin-bottom: rhythm()
@@ -139,12 +139,12 @@ $mods-list-size: 12-$filter-size
padding: space()
text-align: right
+nowrap
-
+
&-tag
display: block
position: relative
padding-right: 20px
-
+
&-label
position: relative
display: block
@@ -157,7 +157,7 @@ $mods-list-size: 12-$filter-size
overflow: visible
display: inline
z-index: 3
-
+
.fa
position: absolute
top: 3px // Sorry, magic pixel
@@ -172,9 +172,10 @@ $mods-list-size: 12-$filter-size
bottom: space()
right: space()
z-index: 999
-
+
+ &.mod-install-button
+ bottom: rhythm(1.6) // THE HORROR. No vertical rhythm compliant!
+
// Add some spacing when the download button is shown
& + .mod-info-tag
- margin-bottom: rhythm(1)
-
-
\ No newline at end of file
+ margin-bottom: rhythm(2.5)
diff --git a/app/assets/stylesheets/mods/show.sass b/app/assets/stylesheets/mods/show.sass
index 5c9f6b4..9a6dbbc 100644
--- a/app/assets/stylesheets/mods/show.sass
+++ b/app/assets/stylesheets/mods/show.sass
@@ -52,6 +52,7 @@
.btn-download
float: right
+ margin-left: space()
margin-top: rhythm(1, $font-x-larger)
> a
+font-x-larger
@@ -81,4 +82,4 @@
display: block
margin-top: -160px
width: 100%
- height: 1600px
\ No newline at end of file
+ height: 1600px
diff --git a/app/controllers/mods_controller.rb b/app/controllers/mods_controller.rb
index d95cbc5..b6b8ca7 100644
--- a/app/controllers/mods_controller.rb
+++ b/app/controllers/mods_controller.rb
@@ -1,6 +1,6 @@
class ModsController < ApplicationController
load_and_authorize_resource
-
+
respond_to :html, :json, only: [:index, :show]
def index
@@ -11,6 +11,11 @@ class ModsController < ApplicationController
.visible
.page(params[:page]).per(20)
+ if params[:names].present?
+ @mods = @mods.filter_by_names(params[:names])
+ end
+
+ # This #to_sym is not a DDoS concern since the value is constrained in the router
@sort = params[:sort].to_sym
case @sort
when :alpha
@@ -27,7 +32,7 @@ class ModsController < ApplicationController
@mods = @mods.sort_by_alpha
end
- unless params[:v].blank?
+ if params[:v].present?
@game_version = GameVersion.find_by_number(params[:v])
if @game_version
@mods = @mods.filter_by_game_version @game_version
@@ -36,14 +41,14 @@ class ModsController < ApplicationController
end
end
- unless params[:q].blank?
+ if params[:q].present?
@query = params[:q][0..30]
@mods = @mods.filter_by_search_query(@query)
end
-
+
@uncategorized_mods_total_count = @mods.total_count
@all_mods_count = Mod.count
- if params[:category_id]
+ if params[:category_id].present?
@category = Category.find_by_slug params[:category_id]
if @category
@mods = @mods.filter_by_category @category
@@ -54,9 +59,9 @@ class ModsController < ApplicationController
@game_versions = GameVersion.sort_by_newer_to_older
@categories = Category.order_by_mods_count.order_by_name
-
+
@mods = @mods.decorate
-
+
respond_with @mods
end
@@ -115,6 +120,8 @@ class ModsController < ApplicationController
:summary,
:imgur,
:authors_list,
+ :contact,
+ :info_json_name,
category_ids: [],
versions_attributes: [
:id,
@@ -135,20 +142,20 @@ class ModsController < ApplicationController
(permitted << :author_id) if can? :set_owner, Mod
(permitted << :visible) if can? :set_visibility, Mod
(permitted << :slug) if can? :set_slug, Mod
-
+
permitted_params = params.require(:mod).permit(*permitted)
if cannot?(:set_owner, Mod) and current_user
permitted_params.merge! author_id: current_user.id
end
-
+
if cannot?(:set_visibility, Mod)
permitted_params.merge! visible: false
end
-
+
permitted_params
end
-
+
def fill_with_forum_post_data(mod, mod_version, mod_file)
if params[:forum_post_id]
forum_post = ForumPost.find params[:forum_post_id]
@@ -188,4 +195,4 @@ class ModsController < ApplicationController
# else
# nil
# end
-end
\ No newline at end of file
+end
diff --git a/app/decorators/mod_decorator.rb b/app/decorators/mod_decorator.rb
index 0087c81..173781d 100644
--- a/app/decorators/mod_decorator.rb
+++ b/app/decorators/mod_decorator.rb
@@ -1,5 +1,5 @@
class ModDecorator < Draper::Decorator
- delegate :id, :name, :forum_url, :subforum_url
+ delegate :id, :name, :forum_url, :subforum_url, :as_json
def authors_count; mod.authors.size end
@@ -7,7 +7,7 @@ class ModDecorator < Draper::Decorator
return na if mod.game_versions_string.blank?
"v" + mod.game_versions_string
end
-
+
def forum_link_title
if mod.subforum_url.present?
h.t('mods.decorator.forum_link_title.subforum')
@@ -17,7 +17,7 @@ class ModDecorator < Draper::Decorator
h.t('mods.decorator.forum_link_title.vague')
end
end
-
+
def forum_link(length = :short) # or :long
if mod.subforum_url.present?
subforum_link = h.link_to h.t('mods.decorator.forum_link.subforum.subforum'), mod.subforum_url
@@ -36,22 +36,22 @@ class ModDecorator < Draper::Decorator
na
end
end
-
+
def last_version_date
return na unless last_version_date_available?
last_version.released_at.to_s(:rfc822)
end
-
+
def last_version_date_time_tag
return na unless last_version_date_available?
h.date_time_tag(last_version.released_at)
end
-
+
def first_version_date_time_tag
return na unless last_version_date_available?
h.date_time_tag(last_version.released_at)
end
-
+
def authors_links_list
return na if mod.authors.empty?
@@ -65,17 +65,17 @@ class ModDecorator < Draper::Decorator
end
end.join(', ').html_safe
end
-
+
def categories_links
mod.categories.map{ |cat| category_tag_link(cat) }.join.html_safe
end
-
+
def img(size)
h.tag :img,
src: img_url(size),
title: (h.t('helpers.no_image_available') if !mod.imgur)
end
-
+
def img_link(size = :large_thumbnail)
if ( url = mod.imgur(:normal) )
h.link_to img(size), url
@@ -83,51 +83,51 @@ class ModDecorator < Draper::Decorator
img(size) # Image missing
end
end
-
+
def title_link
h.link_to(mod.name, mod) +
(h.link_to h.t('mods.decorator.admin_edit'), [:edit, mod] if h.can? :edit, mod)
end
-
+
def edit_link
if h.can? :edit, mod
h.link_to h.t('mods.decorator.edit_mod'), [:edit, mod], class: 'edit-link'
end
end
-
+
def pretty_summary
h.simple_format mod.summary
end
-
+
def first_release_info
return na unless mod.versions.first
h.release_info(mod.versions.first)
end
-
+
def last_release_info
return na unless mod.versions.last
h.release_info(mod.versions.last)
end
-
+
def github_link
return na unless mod.github
h.link_to mod.github_url, mod.github_url
end
-
+
def forum_iframe_title
text = if mod.subforum_url.present?
h.t('.mod_subforum')
else
h.t('.mod_forum_post')
end
-
+
(text + ' ' + forum_link(:long)).html_safe
end
-
+
def preferred_forum_url
mod.subforum_url.presence || mod.forum_url
end
-
+
def visibility_notice
if not mod.visible?
if h.current_user.is_admin?
@@ -139,18 +139,22 @@ class ModDecorator < Draper::Decorator
end
end
end
-
+
+ def install_protocol_url
+ "factoriomods://#{Base64.encode64(mod.to_json)}"
+ end
+
### Download button
###################
-
+
def last_version_has_downloads?
last_version and last_version.has_files?
end
-
+
def first_available_download_url
last_version.files.first.available_url
end
-
+
def download_files(number = nil)
result = []
selected_versions = number ? mod.versions.last(number) : mod.versions
@@ -165,13 +169,13 @@ class ModDecorator < Draper::Decorator
end
result
end
-
+
def more_downloads_link(number = nil)
if mod.versions.size > number
h.content_tag :li, h.link_to(h.t('mods.decorator.more_versions'), h.mod_path(mod, anchor: 'download'))
end
end
-
+
def has_versions?
mod.versions.size > 0
end
@@ -179,32 +183,32 @@ class ModDecorator < Draper::Decorator
def has_files?
mod.files.size > 0
end
-
+
### Private helpers
###################
-
+
private
-
+
def last_version
mod.versions[0]
end
-
+
def forum_views
mod.forum_post.views_count
end
-
+
def forum_comments
mod.forum_post.comments_count
end
-
+
def na
@na ||= h.t('helpers.not_available')
end
-
+
def last_version_date_available?
last_version.present? and last_version.released_at.present?
end
-
+
def category_tag_link(category)
h.link_to h.category_filter_url(category), class: 'tag' do
h.content_tag(:i, '', class: category.icon_class) + ' ' + category.name
@@ -214,4 +218,4 @@ class ModDecorator < Draper::Decorator
def img_url(size)
mod.imgur(size).presence || h.missing_img_url(size)
end
-end
\ No newline at end of file
+end
diff --git a/app/models/mod.rb b/app/models/mod.rb
index a31b547..998f4ad 100644
--- a/app/models/mod.rb
+++ b/app/models/mod.rb
@@ -71,6 +71,11 @@ class Mod < ActiveRecord::Base
where('mods.name ILIKE ? OR mods.summary ILIKE ? OR mods.description ILIKE ?', "%#{query}%", "%#{query}%", "%#{query}%")
end
+ scope :filter_by_names, ->(names_list) do
+ names = names_list.split(',').map(&:strip)
+ where(info_json_name: names)
+ end
+
# def self.filter_by_search_query(query)
# s1 = s2 = s3 = self
@@ -161,6 +166,7 @@ class Mod < ActiveRecord::Base
validates :forum_url, allow_blank: true, format: { with: /\Ahttps?:\/\/.*\Z/ }
validates :summary, length: { maximum: 1000 }
validates :slug, uniqueness: true
+ validates :info_json_name, presence: true # we shouldn't validate uniqueness though
# #categories.count limit
validate do
@@ -274,6 +280,36 @@ class Mod < ActiveRecord::Base
@authors_list ||= authors.map(&:name).join(', ')
end
+ # We should eventually rename the mod attributes to match the ones in the API,
+ # we use these different attributes to roughly match the ones used in
+ # the mods info.json files
+ def as_json(options = {})
+ {
+ title: name,
+ name: info_json_name,
+ url: Rails.application.routes.url_helpers.mod_url(self), # Eww
+ description: summary,
+ homepage: official_url,
+ contact: contact,
+ authors: authors.map(&:name),
+ releases: versions.map do |version|
+ {
+ version: version.number,
+ released_at: version.released_at,
+ game_versions: version.game_versions_string.split('-'), # Ideally we should load the #game_versions
+ dependencies: [],
+ files: version.files.map do |file|
+ {
+ name: file.name,
+ url: file.download_url,
+ mirror: file.attachment.present? ? file.attachment.url : ''
+ }
+ end
+ }
+ end
+ }
+ end
+
private
def set_game_versions_string
diff --git a/app/models/mod_version.rb b/app/models/mod_version.rb
index 93ca15a..9502da7 100644
--- a/app/models/mod_version.rb
+++ b/app/models/mod_version.rb
@@ -65,11 +65,7 @@ class ModVersion < ActiveRecord::Base
#################
def game_versions_string
- if precise_game_versions_string.blank?
- read_attribute(:game_versions_string) || set_game_versions_string
- else
- precise_game_versions_string
- end
+ read_attribute(:game_versions_string) || set_game_versions_string
end
def to_label
diff --git a/app/views/mods/_download_button.html.haml b/app/views/mods/_download_button.html.haml
index 90be0bd..9b4e742 100644
--- a/app/views/mods/_download_button.html.haml
+++ b/app/views/mods/_download_button.html.haml
@@ -1,7 +1,11 @@
- if mod.last_version_has_downloads?
+ .mod-install-button.btn.btn-download{title: t('.install.title')}
+ %a{href: mod.install_protocol_url}
+ = icon 'download'
+ = t(".install.#{params[:action]}")
.mod-download-button.btn.btn-download
%a{href: mod.first_available_download_url}
- = icon 'download'
+ = icon 'cloud-download'
= t('.download')
%ul.btn-download-versions
- mod.download_files(2) do |version, file|
@@ -12,4 +16,4 @@
\/
%span(title='Mod version')= version.number
%span(title='Mod file name')= file.name
- = mod.more_downloads_link(2)
\ No newline at end of file
+ = mod.more_downloads_link(2)
diff --git a/app/views/mods/new.html.haml b/app/views/mods/new.html.haml
index fd5cc74..8dcf7df 100644
--- a/app/views/mods/new.html.haml
+++ b/app/views/mods/new.html.haml
@@ -9,12 +9,14 @@
= semantic_form_for @mod do |f|
= f.inputs do
= f.input :name
+ = f.input :info_json_name
= f.input :slug if can? :set_slug, @mod
= f.input :categories, as: :categories_select
= f.input :owner if can? :set_owner, @mod
= f.input :authors_list, as: :multi_datalist, collection: @existing_authors_names, placeholder: @existing_authors_names.sample(4).push('etc').join(', ')
= f.input :github
= f.input :official_url
+ = f.input :contact
= f.input :forum_url
= f.input :forum_subforum_url
= f.input :imgur
@@ -32,4 +34,4 @@
= f.action :submit
- if @mod.forum_url.present?
.mod-forum
- %iframe.mod-forum-iframe{src: @mod.forum_url}
\ No newline at end of file
+ %iframe.mod-forum-iframe{src: @mod.forum_url}
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 143f035..edcfe75 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -40,4 +40,5 @@ Rails.application.configure do
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
+ Rails.application.routes.default_url_options[:host] = 'localhost:3000'
end
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 632a483..cecd2ca 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -36,4 +36,6 @@ Rails.application.configure do
# Raises error for missing translations
config.action_view.raise_on_missing_translations = true
+
+ Rails.application.routes.default_url_options[:host] = 'localhost:3000'
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 5465547..1d82c6e 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -50,6 +50,9 @@ en:
formtastic:
labels:
mod:
+ name: Title
+ info_json_name: Name
+ contact: Contact information
forum_url: 'Forum post URL'
official_url: 'Official URL'
media_links_string: 'Pictures or gifs links'
@@ -65,6 +68,8 @@ en:
hints:
mod:
+ info_json_name: The name in info.json
+ contact: How to get with you
description: Markdown
media_links_string: 'Imgur.com URLs of pictures of animated gifs. Maximum: 6 links.'
forum_subforum_url: Big mods have their own subforum
@@ -74,4 +79,4 @@ en:
placeholders:
mod:
- authors_list: 'Author1, Author2, Author3, etc'
\ No newline at end of file
+ authors_list: 'Author1, Author2, Author3, etc'
diff --git a/config/locales/mods.en.yml b/config/locales/mods.en.yml
index ccd2023..5feabef 100644
--- a/config/locales/mods.en.yml
+++ b/config/locales/mods.en.yml
@@ -66,6 +66,10 @@ en:
download_button:
download: Download
+ install:
+ title: Install with the Factorio Mod Manager, or any mod manager that can read the protocol
+ show: Install with FMM
+ index: Install
filter_bar:
any_game_version: Any Factorio version
@@ -89,4 +93,4 @@ en:
short: "%{views}V / %{comments}C"
vague:
long: On the Factorio forums
- short: Forum
\ No newline at end of file
+ short: Forum
diff --git a/config/routes.rb b/config/routes.rb
index d2e2183..a616a35 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -72,4 +72,4 @@ Rails.application.routes.draw do
get '/how-to-make' => 'static#how_to_make', as: :how_to_make_static
root to: 'mods#index', sort: 'most_recent'
-end
\ No newline at end of file
+end
diff --git a/db/migrate/20150727151824_add_contact_and_info_json_name_to_mods.rb b/db/migrate/20150727151824_add_contact_and_info_json_name_to_mods.rb
new file mode 100644
index 0000000..07e7690
--- /dev/null
+++ b/db/migrate/20150727151824_add_contact_and_info_json_name_to_mods.rb
@@ -0,0 +1,6 @@
+class AddContactAndInfoJsonNameToMods < ActiveRecord::Migration
+ def change
+ add_column :mods, :contact, :string, default: '', null: false
+ add_column :mods, :info_json_name, :string, default: '', null: false
+ end
+end
diff --git a/db/migrate/20150727221452_add_info_json_name_index.rb b/db/migrate/20150727221452_add_info_json_name_index.rb
new file mode 100644
index 0000000..6e0feff
--- /dev/null
+++ b/db/migrate/20150727221452_add_info_json_name_index.rb
@@ -0,0 +1,5 @@
+class AddInfoJsonNameIndex < ActiveRecord::Migration
+ def change
+ add_index :mods, :info_json_name
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 195ddb2..c7ba4be 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150724155022) do
+ActiveRecord::Schema.define(version: 20150727221452) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -213,11 +213,14 @@ ActiveRecord::Schema.define(version: 20150724155022) do
t.integer "last_version_id"
t.datetime "last_release_date"
t.boolean "visible", default: true, null: false
+ t.string "contact", default: "", null: false
+ t.string "info_json_name", default: "", null: false
end
add_index "mods", ["author_id"], name: "index_mods_on_author_id", using: :btree
add_index "mods", ["category_id"], name: "index_mods_on_category_id", using: :btree
add_index "mods", ["forum_post_id"], name: "index_mods_on_forum_post_id", using: :btree
+ add_index "mods", ["info_json_name"], name: "index_mods_on_info_json_name", using: :btree
add_index "mods", ["last_version_id"], name: "index_mods_on_last_version_id", using: :btree
add_index "mods", ["slug"], name: "index_mods_on_slug", unique: true, using: :btree
diff --git a/lib/fake_data_generator.rb b/lib/fake_data_generator.rb
index 54ccce2..cf52975 100644
--- a/lib/fake_data_generator.rb
+++ b/lib/fake_data_generator.rb
@@ -11,7 +11,7 @@ class FakeDataGenerator
Category.create! name: Forgery(:lorem_ipsum).words(1, random: true) + i.to_s
end
end
-
+
### Game
##################
begin
@@ -45,7 +45,7 @@ class FakeDataGenerator
gputs "Created user #{user.name} #{user.email}"
end
users = User.all
-
+
### Subforum
##################
subforum = Subforum.create!(url: 'http://www.factorioforums.com/forum/viewforum.php?f=91')
@@ -68,6 +68,7 @@ class FakeDataGenerator
rand(30..50).times do |i|
github_url = Forgery(:lorem_ipsum).words(1, random: true) + '/' + Forgery(:lorem_ipsum).words(1, random: true)
mod = Mod.create! name: Forgery(:lorem_ipsum).words(rand(3..6), random: true),
+ info_json_name: Forgery(:lorem_ipsum).words(rand(1..2), random: true),
authors: users.sample(8),
owner: [nil, nil].concat(users).sample,
categories: categories.sample(rand(1..4)),
@@ -118,4 +119,4 @@ class FakeDataGenerator
end
end
end
-end
\ No newline at end of file
+end
diff --git a/spec/controllers/mods_controller_spec.rb b/spec/controllers/mods_controller_spec.rb
index 8962f25..733dd1c 100644
--- a/spec/controllers/mods_controller_spec.rb
+++ b/spec/controllers/mods_controller_spec.rb
@@ -27,11 +27,11 @@ describe ModsController, type: :controller do
get 'index', options
end
- describe "get_index" do
+ describe 'GET index' do
context 'pagination, 25 mods' do
it 'should load the first 20 mods on the first page' do
first_page_mods = 20.times.map{ create :mod }
- second_page_mods = 5.times.map{ create :mod }
+ 5.times.map{ create :mod }
get_index sort: :alpha
expect(response).to be_success
expect(response).to render_template 'index'
@@ -39,7 +39,7 @@ describe ModsController, type: :controller do
end
it 'should load the last 5 mods on the second page' do
- first_page_mods = 20.times.map{ create :mod }
+ 20.times.map{ create :mod }
second_page_mods = 5.times.map{ create :mod }
get_index sort: :alpha, page: 2
expect(response).to be_success
@@ -141,9 +141,9 @@ describe ModsController, type: :controller do
gv1 = create :game_version, number: '1.1.x'
gv2 = create :game_version, number: '1.2.x'
gv3 = create :game_version, number: '1.3.x'
- mv1 = create :mod_version, game_versions: [gv1, gv2], mod: @m1
- mv2 = create :mod_version, game_versions: [gv2, gv3], mod: @m2
- mv3 = create :mod_version, game_versions: [gv3], mod: @m3
+ create :mod_version, game_versions: [gv1, gv2], mod: @m1
+ create :mod_version, game_versions: [gv2, gv3], mod: @m2
+ create :mod_version, game_versions: [gv3], mod: @m3
end
context 'version 1.1.x' do
@@ -171,7 +171,7 @@ describe ModsController, type: :controller do
end
end
end
-
+
context 'some mods non-visible' do
it 'should not load them' do
mods[0].update! visible: false
@@ -182,9 +182,33 @@ describe ModsController, type: :controller do
expect(assigns(:mods)).to match_array mods
end
end
+
+ context 'searching for specific mods in an API-wise way' do
+ before :each do
+ @category = create :category
+ @mods = []
+ @mods << create(:mod, name: 'ccc', info_json_name: 'banana', categories: [@category])
+ @mods << create(:mod, name: 'bbb', info_json_name: 'potato')
+ @mods << create(:mod, name: 'aaa', info_json_name: 'cabbage', categories: [@category])
+ @mods << create(:mod, name: 'ddd', info_json_name: 'watermelon')
+ @mods << create(:mod, name: 'kkk', info_json_name: 'orange')
+ @mods << create(:mod, name: 'zzz', info_json_name: 'pomegranate')
+ @mods << create(:mod, name: 'yyy', info_json_name: 'machine-gun')
+ end
+
+ it 'should get the correct list of mods' do
+ get_index names: 'banana,orange,machine-gun'
+ expect(assigns(:mods)).to match_array [@mods[0], @mods[4], @mods[6]]
+ end
+
+ it 'should with the other filter' do
+ get_index names: 'banana,cabbage,machine-gun', category_id: @category.to_param, sort: :alpha
+ expect(assigns(:mods)).to eq [@mods[2], @mods[0]]
+ end
+ end
end
- describe "GET 'show'" do
+ describe 'GET show' do
context 'finds the mod' do
before(:each) { get 'show', category_id: mod.categories.first.to_param, id: mod.to_param }
@@ -199,12 +223,12 @@ describe ModsController, type: :controller do
it { expect(response.status).to eq 404 }
end
end
-
- describe 'POST create' do
+
+ describe 'POST create' do
def submit_basic(extra_params = {})
- post :create, mod: {name: 'SuperMod', category_ids: [create(:category).id]}.merge(extra_params)
+ post :create, mod: {name: 'SuperMod', info_json_name: 'supermod', category_ids: [create(:category).id]}.merge(extra_params)
end
-
+
def submit_blank(params = {})
post :create, params
end
@@ -215,21 +239,21 @@ describe ModsController, type: :controller do
expect(response).to have_http_status :bad_request
end
end
-
+
context 'guest user (not registered)' do
it 'should not allow it at all 401' do
submit_blank mod: {name: 'SuperMod'}
expect(response).to have_http_status :unauthorized
end
end
-
+
context 'user is registered' do
it 'should allow it to create a mod' do
sign_in create :user
submit_basic
expect(response).to have_http_status :redirect
end
-
+
it 'should not allow it set #visible #owner or #slug' do
first_user = create :user
second_user = create :user
@@ -242,7 +266,7 @@ describe ModsController, type: :controller do
expect(mod.slug).to eq 'supermod'
end
end
-
+
context 'user is a developer' do
it 'should allow it set #visible but not #owner or #slug' do
first_user = create :dev_user
@@ -255,15 +279,15 @@ describe ModsController, type: :controller do
expect(mod.owner).to eq first_user
expect(mod.slug).to eq 'supermod'
end
-
+
it 'should also allow it to set visibility to false' do
sign_in create(:dev_user)
submit_basic visible: false
expect(Mod.first.visible).to eq false
end
end
-
-
+
+
context 'user is an admin' do
it 'should allow it set #visible, #owner or #slug' do
first_user = create :admin_user
@@ -276,7 +300,7 @@ describe ModsController, type: :controller do
expect(mod.owner).to eq second_user
expect(mod.slug).to eq 'rsarsarsa'
end
-
+
it 'should also be able to allow those values to be default' do
sign_in create(:admin_user)
submit_basic visible: false, author_id: nil, slug: ''
@@ -287,7 +311,7 @@ describe ModsController, type: :controller do
end
end
-
+
describe "PATCH update" do
def submit_basic(mod, extra_params = {})
put :update, id: mod.id, mod: extra_params
@@ -302,7 +326,7 @@ describe ModsController, type: :controller do
expect(response).to have_http_status :bad_request
end
end
-
+
context 'guest user (not registered)' do
it 'should not allow it at all 401' do
mod = create :mod
@@ -310,7 +334,7 @@ describe ModsController, type: :controller do
expect(response).to have_http_status :unauthorized
end
end
-
+
context 'user is registered' do
it "should allow it to update a it's own mod" do
user = create :user
@@ -319,7 +343,7 @@ describe ModsController, type: :controller do
submit_basic mod, name: mod.name
expect(response).to have_http_status :redirect
end
-
+
it "should not allow it to update someone elses mod" do
user = create :user
mod = create :mod, owner: (create :user)
@@ -327,7 +351,7 @@ describe ModsController, type: :controller do
submit_basic mod
expect(response).to have_http_status :unauthorized
end
-
+
it 'should not allow it set #visible #owner or #slug' do
first_user = create :user
second_user = create :user
@@ -341,7 +365,7 @@ describe ModsController, type: :controller do
expect(mod.slug).to eq mod.slug
end
end
-
+
context 'user is a developer' do
it 'should allow it set #visible but not #owner or #slug' do
first_user = create :dev_user
@@ -355,7 +379,7 @@ describe ModsController, type: :controller do
expect(mod.owner).to eq first_user
expect(mod.slug).to eq mod.slug
end
-
+
it 'should not allow it to update someone elses mod' do
first_user = create :dev_user
second_user = create :user
@@ -364,7 +388,7 @@ describe ModsController, type: :controller do
submit_basic mod, visible: true, author_id: second_user.id, slug: 'rsarsarsa'
expect(response).to have_http_status :unauthorized
end
-
+
it 'should not allow it to update a mod without owner' do
first_user = create :dev_user
mod = create :mod, owner: nil
@@ -372,7 +396,7 @@ describe ModsController, type: :controller do
submit_basic mod, visible: true, author_id: first_user.id, slug: 'rsarsarsa'
expect(response).to have_http_status :unauthorized
end
-
+
it 'should also allow it to set visibility to false' do
user = create(:dev_user)
sign_in user
@@ -381,7 +405,7 @@ describe ModsController, type: :controller do
expect(Mod.first.visible).to eq false
end
end
-
+
context 'user is an admin' do
it 'should allow it set #visible, #owner or #slug' do
first_user = create :admin_user
@@ -395,7 +419,7 @@ describe ModsController, type: :controller do
expect(mod.owner).to eq second_user
expect(mod.slug).to eq 'rsarsarsa'
end
-
+
it 'should also be able to allow those values to be default' do
user = create(:admin_user)
mod = create :mod, owner: user
@@ -405,7 +429,7 @@ describe ModsController, type: :controller do
expect(Mod.first.owner).to eq nil
expect(Mod.first.slug).to eq mod.slug
end
-
+
it 'should also allow it to modify a mod with any owner' do
first_user = create :admin_user
second_user = create :user
@@ -418,7 +442,7 @@ describe ModsController, type: :controller do
expect(mod.owner).to eq second_user
expect(mod.slug).to eq 'rsarsarsa'
end
-
+
it 'should not allow it to update a mod without owner' do
first_user = create :admin_user
second_user = create :user
diff --git a/spec/decorators/mod_decorator_spec.rb b/spec/decorators/mod_decorator_spec.rb
index 34bc6be..edba168 100644
--- a/spec/decorators/mod_decorator_spec.rb
+++ b/spec/decorators/mod_decorator_spec.rb
@@ -4,7 +4,7 @@ describe ModDecorator do
def create_decorated(*args)
create(*args).decorate
end
-
+
describe '#authors_links_list' do
it 'should return a comma separated authors list links' do
mod = create_decorated :mod, authors: 3.times.map{ |i| create :user, name: "Au#{i}" }
@@ -28,32 +28,32 @@ describe ModDecorator do
expect(mod.authors_links_list).to eq 'N/A'
end
end
-
+
describe '#forum_link' do
context 'only has forum post URL' do
it 'should only have the forum URL' do
mod = create_decorated :mod, forum_url: 'http://potato.com'
expect(URI.extract(mod.forum_link)).to eq ['http://potato.com']
end
-
+
it 'should only have the forum URL, with empty string subforum_url' do
mod = create_decorated :mod, forum_url: 'http://potato.com', subforum_url: ''
expect(URI.extract(mod.forum_link)).to eq ['http://potato.com']
end
end
-
+
context 'has only the subforum URL' do
it 'should link to the subforum' do
mod = create_decorated :mod, subforum_url: 'http://cabbage.com'
expect(URI.extract(mod.forum_link)).to eq ['http://cabbage.com']
end
-
+
it 'should link to the subforum, with empty string forum post URL' do
mod = create_decorated :mod, subforum_url: 'http://cabbage.com', forum_url: ''
expect(URI.extract(mod.forum_link)).to eq ['http://cabbage.com']
end
end
-
+
context 'has both the subforum and the forum post URL' do
it 'should link to both' do
mod = create_decorated :mod, forum_url: 'http://potato.com', subforum_url: 'http://cabbage.com'
@@ -61,7 +61,7 @@ describe ModDecorator do
end
end
end
-
+
describe '#has_versions?' do
it 'should return false if the mod has no versions' do
mod = create_decorated :mod, versions: []
@@ -86,9 +86,18 @@ describe ModDecorator do
mod = build :mod, versions: []
mod.save!
mod_version = create :mod_version, mod: mod
- mod_file = create :mod_file, mod_version: mod_version
+ create :mod_file, mod_version: mod_version
mod = Mod.first.decorate
expect(mod.has_files?).to eq true
end
end
-end
\ No newline at end of file
+
+ describe '#install_protocol_url' do
+ it 'should return the factoriomods:// protocol with the JSON-encoded mod' do
+ include ActionView::Helpers::TextHelper
+ mod = create(:mod).decorate
+ encoded_json = Base64.encode64 mod.to_json
+ expect(mod.install_protocol_url).to eq "factoriomods://#{encoded_json}"
+ end
+ end
+end
diff --git a/spec/factories/mod_factories.rb b/spec/factories/mod_factories.rb
index fef9b00..37b3f54 100644
--- a/spec/factories/mod_factories.rb
+++ b/spec/factories/mod_factories.rb
@@ -6,6 +6,7 @@ FactoryGirl.define do
description ''
forum_comments_count 12
downloads_count 15
+ sequence(:info_json_name) { |n| "mod-name-#{n}" }
end
factory :category do
@@ -39,4 +40,4 @@ FactoryGirl.define do
factory :game do
sequence(:name) { |n| "GameName #{n}#{n}" }
end
-end
\ No newline at end of file
+end
diff --git a/spec/features/mods_index_spec.rb b/spec/features/mods_index_spec.rb
index afbd133..1f05409 100644
--- a/spec/features/mods_index_spec.rb
+++ b/spec/features/mods_index_spec.rb
@@ -43,7 +43,7 @@ feature 'Display an index of mods in certain order' do
visit '/most-popular'
expect(mod_names).to eq %w{SuperMod6 superMod0 SuperMod2 SuperMod4 superMod3}
end
-
+
scenario 'some mods are not visible' do
@mods[2].update! visible: false
@mods[4].update! visible: false
@@ -68,7 +68,7 @@ feature 'Display an index of mods in certain order' do
end
end
end
-
+
# Test those examples for both HTML and JSON
context 'when requesting HTML' do
it_behaves_like 'mod index' do
@@ -77,11 +77,11 @@ feature 'Display an index of mods in certain order' do
end
end
end
-
+
context 'when requesting JSON', driver: :rack_test_json do
it_behaves_like 'mod index' do
def mod_names
- JSON.parse(last_response).map { |hash| hash["name"] }
+ JSON.parse(last_response).map { |hash| hash["title"] }
end
end
end
@@ -91,7 +91,7 @@ feature 'Display an index of mods in certain order' do
authors = 5.times.map{ |i| create :user, name: "Au#{i}" }
create :mod, name: 'SuperMod', authors: authors
visit '/'
- expect(page).to have_content /Au0.*Au1.*Au2.*Au3.*Au4/
+ expect(page).to have_content(/Au0.*Au1.*Au2.*Au3.*Au4/)
expect(page).to have_link 'Au0', '/users/au0'
expect(page).to have_link 'Au1', '/users/au1'
expect(page).to have_link 'Au2', '/users/au2'
@@ -103,7 +103,7 @@ feature 'Display an index of mods in certain order' do
authors = 5.times.map{ |i| create :user, name: "Au#{i}" }
create :mod, name: 'SuperMod', authors: authors, owner: authors[1]
visit '/'
- expect(page).to have_content /Au0.*Au1.*(maintainer).*Au2.*Au3.*Au4/
+ expect(page).to have_content(/Au0.*Au1.*(maintainer).*Au2.*Au3.*Au4/)
end
scenario 'Mod with multiple authors with reversed sorting order' do
@@ -115,7 +115,7 @@ feature 'Display an index of mods in certain order' do
mod.authors_mods[3].update_column :sort_order, 2
mod.authors_mods[4].update_column :sort_order, 1
visit '/'
- expect(page).to have_content /Au4.*Au3.*Au2.*Au1.*Au0/
+ expect(page).to have_content(/Au4.*Au3.*Au2.*Au1.*Au0/)
end
end
end
diff --git a/spec/features/mods_new_spec.rb b/spec/features/mods_new_spec.rb
index c44c333..b0585db 100644
--- a/spec/features/mods_new_spec.rb
+++ b/spec/features/mods_new_spec.rb
@@ -12,8 +12,8 @@ feature 'Modder creates a new mod' do
expect(page.status_code).to eq 401
end
-
-
+
+
scenario 'non-dev user visits the new mod page' do
sign_in
visit '/mods/new'
@@ -25,16 +25,16 @@ feature 'Modder creates a new mod' do
scenario 'dev user visits new mod page' do
sign_in_dev
visit '/mods/new'
-
+
expect(page.status_code).to eq 200
expect(page).to have_content 'Create new mod'
end
-
-
+
+
scenario 'admin user visits new mod page' do
sign_in_admin
visit '/mods/new'
-
+
expect(page.status_code).to eq 200
expect(page).to have_content 'Create new mod'
end
@@ -53,13 +53,12 @@ feature 'Modder creates a new mod' do
scenario 'user submits a barebones form' do
sign_in_dev
visit '/mods/new'
- fill_in 'mod_name', with: 'Super Mod'
- select 'Terrain', from: 'Categories'
- fill_in_first_version_and_file
+ fill_in_minimum 'Super Mod'
submit_form
expect(current_path).to eq '/mods/super-mod'
mod = Mod.first
expect(mod.name).to eq 'Super Mod'
+ expect(mod.info_json_name).to eq 'super mod'
expect(mod.categories).to match_array [@category]
expect(mod.author).to eq @user
end
@@ -67,8 +66,7 @@ feature 'Modder creates a new mod' do
scenario 'user submits a form without any mod version', js: true do
sign_in_dev
visit '/mods/new'
- fill_in 'mod_name', with: 'Super Mod'
- select 'Terrain', from: 'Categories'
+ fill_in_no_versions_minimum 'Super Mod'
first('.remove_fields').click
submit_form
expect(current_path).to eq '/mods/super-mod'
@@ -85,6 +83,7 @@ feature 'Modder creates a new mod' do
sign_in_dev
visit '/mods/new'
fill_in 'mod_name', with: 'ModName'
+ fill_in 'mod_info_json_name', with: 'mod-name'
9.times{ |i| select "Cat#{i}", from: 'Categories' }
fill_in_first_version_and_file
submit_form
@@ -97,6 +96,7 @@ feature 'Modder creates a new mod' do
sign_in_dev
visit '/mods/new'
fill_in 'mod_name', with: 'ModName'
+ fill_in 'mod_info_json_name', with: 'mod-name'
7.times{ |i| select "Cat#{i}", from: 'Categories' }
fill_in_first_version_and_file
submit_form
@@ -125,8 +125,7 @@ feature 'Modder creates a new mod' do
scenario 'user submits a mod with a mod_version with a perfectly fine number' do
sign_in_dev
visit '/mods/new'
- fill_in 'mod_name', with: 'ModName'
- select 'Terrain', from: 'Categories'
+ fill_in_no_versions_minimum 'ModName'
within('.mod-version:nth-child(1)') do
fill_in 'Number', with: '1.2.3_5-potato'
fill_in 'Release day', with: 3.weeks.ago
@@ -142,17 +141,16 @@ feature 'Modder creates a new mod' do
scenario 'user submits a mod with all the data but no versions' do
sign_in_dev
visit '/mods/new'
- fill_in 'mod_name', with: 'Mah super mod'
- select 'Terrain', from: 'Categories'
+ fill_in_minimum 'SuperMod'
fill_in 'Github', with: 'http://github.com/factorio-mods/mah-super-mod'
fill_in 'Forum post URL', with: 'http://www.factorioforums.com/forum/viewtopic.php?f=14&t=5971&sid=1786856d6a687e92f6a12ad9425aeb9e'
fill_in 'Official URL', with: 'http://www.factorioforums.com/'
fill_in 'Summary', with: 'This is a small mod for testing'
- fill_in_first_version_and_file
submit_form
- expect(current_path).to eq '/mods/mah-super-mod'
+ expect(current_path).to eq '/mods/supermod'
mod = Mod.first
- expect(mod.name).to eq 'Mah super mod'
+ expect(mod.name).to eq 'SuperMod'
+ expect(mod.info_json_name).to eq 'supermod'
expect(mod.categories).to match_array [Category.first]
expect(mod.github).to eq 'factorio-mods/mah-super-mod'
expect(mod.forum_url).to eq 'http://www.factorioforums.com/forum/viewtopic.php?f=14&t=5971&sid=1786856d6a687e92f6a12ad9425aeb9e'
@@ -168,11 +166,10 @@ feature 'Modder creates a new mod' do
create :game_version, number: '1.2.x'
attachment = File.new(Rails.root.join('spec', 'fixtures', 'test.zip'))
visit '/mods/new'
- fill_in 'mod_name', with: 'Valid mod name'
- select 'Terrain', from: 'Categories'
+ fill_in_no_versions_minimum
within('.mod-version:nth-child(1)') do
fill_in 'Number', with: '123'
- fill_in 'Release day', with: '2014-11-09'
+ fill_in 'Release day', with: '2014-11-09'
select '1.1.x', from: 'Game versions'
select '1.2.x', from: 'Game versions'
click_link 'Add file'
@@ -182,8 +179,8 @@ feature 'Modder creates a new mod' do
end
submit_form
mod = Mod.first
- expect(current_path).to eq '/mods/valid-mod-name'
- expect(page).to have_content 'Valid mod name'
+ expect(current_path).to eq '/mods/supermod'
+ expect(page).to have_content 'SuperMod'
expect(mod.versions[0].number).to eq '123'
expect(mod.versions[0].released_at).to eq Time.zone.parse('2014-11-09')
expect(mod.versions[0].game_versions[0].number).to eq '1.1.x'
@@ -194,10 +191,8 @@ feature 'Modder creates a new mod' do
scenario 'admin user submits a mod selecting an owner' do
sign_in_admin
visit '/mods/new'
- fill_in 'mod_name', with: 'Mod Name'
- select 'Terrain', from: 'Categories'
+ fill_in_minimum 'Mod Name'
fill_in 'mod_authors_list', with: 'MangoDev'
- fill_in_first_version_and_file
submit_form
mod = Mod.first
expect(current_path).to eq '/mods/mod-name'
@@ -230,9 +225,7 @@ feature 'Modder creates a new mod' do
mod = create :mod, name: 'SuperMod'
visit "/mods/new"
- fill_in 'mod_name', with: 'SuperMod'
- select 'Terrain', from: 'Categories'
- fill_in_first_version_and_file
+ fill_in_minimum('SuperMod')
submit_form
expect(current_path).to eq '/mods/supermod-by-yeah'
end
@@ -240,10 +233,8 @@ feature 'Modder creates a new mod' do
scenario 'user submits a mod with valid names in the #authors_list' do
sign_in_dev
visit '/mods/new'
- fill_in 'mod_name', with: 'SuperMod'
- select 'Terrain', from: 'Categories'
+ fill_in_minimum
fill_in 'mod_authors_list', with: 'Potato, SuperUser, Salad'
- fill_in_first_version_and_file
submit_form
expect(current_path).to eq '/mods/supermod'
expect(Mod.first.authors.map(&:name)).to eq %w{Potato SuperUser Salad}
@@ -252,10 +243,8 @@ feature 'Modder creates a new mod' do
scenario 'user submits a mod with invalid names in the #authors_list' do
sign_in_dev
visit '/mods/new'
- fill_in 'mod_name', with: 'SuperMod'
- select 'Terrain', from: 'Categories'
+ fill_in_minimum
fill_in 'mod_authors_list', with: 'Potato(), SuperUser, Salad'
- fill_in_first_version_and_file
submit_form
expect(current_path).to eq '/mods'
expect(page).to have_css '#mod_authors_list_input .inline-errors'
@@ -265,16 +254,14 @@ feature 'Modder creates a new mod' do
scenario 'user submits a mod too many authors in the #authors_list' do
sign_in_dev
visit '/mods/new'
- fill_in 'mod_name', with: 'SuperMod'
- select 'Terrain', from: 'Categories'
+ fill_in_minimum
fill_in 'mod_authors_list', with: 'Potato, SuperUser, Salad, Tururu, Papapa, Aaaaa, Bbbbb, Ccccc, Ddddd'
- fill_in_first_version_and_file
submit_form
expect(current_path).to eq '/mods'
expect(page).to have_css '#mod_authors_list_input .inline-errors'
expect(page).to have_content /too many/i
end
-
+
describe 'visibility toggle' do
scenario 'should be hidden for non-dev, and false' do
sign_in
@@ -284,7 +271,7 @@ feature 'Modder creates a new mod' do
submit_form
expect(Mod.first.visible).to eq false
end
-
+
shared_examples 'admin or dev' do
scenario 'should be visible and ON by default' do
sign_in_admin_or_dev
@@ -295,7 +282,7 @@ feature 'Modder creates a new mod' do
submit_form
expect(Mod.first.visible).to eq true
end
-
+
scenario 'should be visible it should be changeable' do
sign_in_admin_or_dev
visit '/mods/new'
@@ -307,19 +294,19 @@ feature 'Modder creates a new mod' do
expect(Mod.first.visible).to eq false
end
end
-
+
context 'dev user' do
it_behaves_like 'admin or dev' do
let(:sign_in_admin_or_dev){ sign_in_dev }
end
end
-
+
context 'admin user' do
it_behaves_like 'admin or dev' do
let(:sign_in_admin_or_dev){ sign_in_admin }
end
end
-
+
# context 'dev or admin submits a mod' do
# scenario 'should be visible and ON by default' do
# sign_in_dev
@@ -330,7 +317,7 @@ feature 'Modder creates a new mod' do
# submit_form
# expect(Mod.first.visible).to eq true
# end
-
+
# scenario 'should be visible it should be changeable' do
# sign_in_dev
# visit '/mods/new'
@@ -342,8 +329,8 @@ feature 'Modder creates a new mod' do
# expect(Mod.first.visible).to eq false
# end
# end
-
-
+
+
# scenario 'should be visible if an admin visits mods#new, and it should be ON by default' do
# sign_in
# visit '/mods/new'
@@ -354,13 +341,18 @@ feature 'Modder creates a new mod' do
# expect(Mod.first.visible).to eq true
# end
end
-
- def fill_in_minimum
- fill_in 'mod_name', with: 'SuperMod'
- select 'Terrain', from: 'Categories'
+
+ def fill_in_minimum(*name)
+ fill_in_no_versions_minimum(*name)
fill_in_first_version_and_file
end
+ def fill_in_no_versions_minimum(name = 'SuperMod')
+ fill_in 'mod_name', with: name
+ fill_in 'mod_info_json_name', with: name.downcase
+ select 'Terrain', from: 'Categories'
+ end
+
def fill_in_first_version_and_file
attachment = File.new(Rails.root.join('spec', 'fixtures', 'test.zip'))
within('.mod-version:nth-child(1)') do
@@ -379,4 +371,4 @@ feature 'Modder creates a new mod' do
def create_category(name)
@category = create :category, name: name
end
-end
\ No newline at end of file
+end
diff --git a/spec/features/the_game_version_string_should_be_updated_after_editing_a_mod_spec.rb b/spec/features/the_game_version_string_should_be_updated_after_editing_a_mod_spec.rb
index e5c8357..69730b9 100644
--- a/spec/features/the_game_version_string_should_be_updated_after_editing_a_mod_spec.rb
+++ b/spec/features/the_game_version_string_should_be_updated_after_editing_a_mod_spec.rb
@@ -7,25 +7,26 @@ feature 'The goddamn game version string should be updated after editing a mod'
string is the correct one, but then you mods#edit the mod and you reduce the Factorio
versions of the mod_version that is compatible with, then you look at mods#show again and
the string should be updated' do
- cat1 = create :category, name: 'CategoryOne'
+ create :category, name: 'CategoryOne'
gv1 = create :game_version, number: '0.10', sort_order: 1
gv2 = create :game_version, number: '0.11', sort_order: 2
sign_in_admin
visit '/mods/new'
- nfind('mod[name]').set 'This Bug, Man'
- nfind(:select, 'mod[category_ids][]').select 'CategoryOne'
- nfind('mod[authors_list]').set 'Whatever'
- nfind('mod[versions_attributes][0][number]').set '1.2.3'
- nfind('mod[versions_attributes][0][released_at]').set '2015-01-01'
- nfind(:select, 'mod[versions_attributes][0][game_version_ids][]').select '0.10'
- nfind(:select, 'mod[versions_attributes][0][game_version_ids][]').select '0.11'
- nfind('mod[versions_attributes][0][files_attributes][0][download_url]').set 'http://potato.com'
- nfind('commit').click()
+ fill_in 'mod_name', with: 'This Bug, Man'
+ fill_in 'mod_info_json_name', with: 'this-bug'
+ select 'CategoryOne', from: 'mod_category_ids'
+ fill_in 'mod_authors_list', with: 'Whatever'
+ fill_in 'mod_versions_attributes_0_number', with: '1.2.3'
+ fill_in 'mod_versions_attributes_0_released_at', with: '2015-01-01'
+ select '0.10', from: 'mod_versions_attributes_0_game_version_ids'
+ select '0.11', from: 'mod_versions_attributes_0_game_version_ids'
+ fill_in 'mod_versions_attributes_0_files_attributes_0_download_url', with: 'http://potato.com'
+ find('#mod_submit_action input').click()
expect(current_path).to eq '/mods/this-bug-man'
expect(page).to have_content '0.10-0.11'
click_link 'Edit mod'
- nfind(:select, 'mod[versions_attributes][0][game_version_ids][]').unselect '0.10'
- nfind('commit').click()
+ unselect '0.10', from: 'mod_versions_attributes_0_game_version_ids'
+ find('#mod_submit_action input').click()
expect(ModGameVersion.all.size).to eq 1
expect(Mod.first.versions.first.game_versions).to match_array [gv2]
expect(Mod.first.game_versions_string).to eq '0.11'
@@ -33,4 +34,4 @@ feature 'The goddamn game version string should be updated after editing a mod'
# doesn't actually destroys the game version
expect(GameVersion.all).to match_array [gv1, gv2]
end
-end
\ No newline at end of file
+end
diff --git a/spec/models/mod_spec.rb b/spec/models/mod_spec.rb
index d8808da..5b32ada 100644
--- a/spec/models/mod_spec.rb
+++ b/spec/models/mod_spec.rb
@@ -152,6 +152,11 @@ RSpec.describe Mod, :type => :model do
mod = build :mod, authors: authors
expect(mod).to be_valid
end
+
+ it 'should be invalid without #info_json_name' do
+ mod = build :mod, info_json_name: ''
+ expect(mod).to be_invalid
+ end
end
describe '#author_name' do
@@ -476,6 +481,32 @@ RSpec.describe Mod, :type => :model do
end
describe 'scopes' do
+ describe '.filter_by_names' do
+ it 'should return a list of mods by #info_json_name' do
+ mods = []
+ mods.push create :mod, info_json_name: 'potato'
+ create :mod, info_json_name: 'potato-2'
+ mods.push create :mod, info_json_name: 'banana-stream'
+ create :mod, info_json_name: 'i love this keyboard'
+ mods.push create :mod, info_json_name: 'Atom by github rocks'
+ found = Mod.filter_by_names 'potato,banana-stream, Atom by github rocks'
+ expect(found).to match_array mods
+ end
+
+ it 'should be case sensitive' do
+ create :mod, info_json_name: 'potato'
+ mod = create :mod, info_json_name: 'PoTaTo'
+ expect(Mod.filter_by_names('PoTaTo')).to match_array [mod]
+ end
+
+ it 'should return all the mods with the same #info_json_name' do
+ mod1 = create :mod, info_json_name: 'potato'
+ mod2 = create :mod, info_json_name: 'potato'
+ create :mod, info_json_name: 'banana'
+ expect(Mod.filter_by_names('potato')).to match_array [mod1, mod2]
+ end
+ end
+
describe '.filter_by_category' do
it 'should filter results by category' do
mod1 = create(:mod)
@@ -709,4 +740,99 @@ RSpec.describe Mod, :type => :model do
end
end
end
+
+ describe '#as_json' do
+ it 'should return the public API structure' do
+ authors = [create(:user, name: 'John Snow Zombie'), create(:user, name: 'THAT Guy')]
+ mod = create :mod,
+ name: 'Potato Galaxy',
+ info_json_name: 'potato-galaxy-mod',
+ authors: authors,
+ contact: 'Send a homing pigeon to Castle Black',
+ official_url: 'http://castleblack.com',
+ summary: 'This mod adds the ability to farm potatoes on Factorio.'
+
+ gv1 = create :game_version, number: '0.10.x'
+ gv2 = create :game_version, number: '0.11.x'
+ gv3 = create :game_version, number: '0.12.x'
+
+ one_month_ago = 1.month.ago
+ two_weeks_ago = 2.weeks.ago
+ one_week_ago = 1.week.ago
+ create :mod_version,
+ number: '1.2.1',
+ released_at: one_month_ago,
+ game_versions: [gv1],
+ mod: mod,
+ files: [
+ build(:mod_file, name: '', download_url: 'http://thepotatoexperience.com/1.2.1', attachment: nil)
+ ]
+ create :mod_version,
+ number: '1.2.2',
+ released_at: two_weeks_ago,
+ game_versions: [gv2, gv3],
+ mod: mod,
+ files: [
+ build(:mod_file, name: 'win', download_url: 'http://thepotatoexperience.com/1.2.2', attachment: nil),
+ build(:mod_file, name: 'mac', download_url: 'http://thepotatoexperience.com/1.2.2', attachment: nil)
+ ]
+ mv3 = create :mod_version,
+ number: '1.2.3',
+ released_at: one_week_ago,
+ game_versions: [gv3],
+ mod: mod,
+ files: [
+ build(:mod_file,
+ name: '',
+ download_url: 'http://thepotatoexperience.com/1.2.3',
+ attachment: File.new(Rails.root.join('spec', 'fixtures', 'test.zip'))
+ )
+ ]
+
+ expect(mod.as_json).to eq({
+ title: 'Potato Galaxy',
+ name: 'potato-galaxy-mod',
+ url: 'http://localhost:3000/mods/potato-galaxy',
+ description: 'This mod adds the ability to farm potatoes on Factorio.',
+ homepage: 'http://castleblack.com',
+ contact: 'Send a homing pigeon to Castle Black',
+ authors: ['John Snow Zombie', 'THAT Guy'],
+ releases: [
+ {
+ version: '1.2.3',
+ released_at: one_week_ago,
+ game_versions: ['0.12.x'],
+ dependencies: [],
+ files: [
+ {
+ name: '',
+ url: 'http://thepotatoexperience.com/1.2.3',
+ mirror: mv3.files.first.attachment.url
+ }
+ ]
+ },
+ {
+ version: '1.2.2',
+ released_at: two_weeks_ago,
+ game_versions: ['0.11.x', '0.12.x'],
+ dependencies: [],
+ files: [
+ { name: 'mac', url: 'http://thepotatoexperience.com/1.2.2', mirror: '' },
+ { name: 'win', url: 'http://thepotatoexperience.com/1.2.2', mirror: '' }
+ ]
+ },
+ {
+ version: '1.2.1',
+ released_at: one_month_ago,
+ game_versions: ['0.10.x'],
+ dependencies: [],
+ files: [
+ { name: '', url: 'http://thepotatoexperience.com/1.2.1', mirror: '' }
+ ]
+ }
+ ]
+ })
+
+ end
+ end
end