Fixed the rest of the broken tests of the authors-users separation

master
Zequez 2015-08-04 04:52:58 -03:00
parent dd430b2999
commit f32896bfb1
19 changed files with 161 additions and 180 deletions

View File

@ -106,7 +106,7 @@ ActiveAdmin.register Mod do
filter :name
filter :info_json_name
filter :author
filter :owner
filter :author_name
form do |f|

View File

@ -34,7 +34,8 @@ ActiveAdmin.register User do
user.owned_mods.map{ |m| link_to m.name, m }.join('<br/>').html_safe
end
column :authored_mods do |user|
user.owned_mods.map{ |m| link_to m.name, m }.join('<br/>').html_safe
return unless user.author
user.author.mods.map{ |m| link_to m.name, m }.join('<br/>').html_safe
end
column :validate do |user|
# Doesn't actually toggle, it's just a one way trip

View File

@ -57,7 +57,7 @@ class ModDecorator < Draper::Decorator
mod.authors.map do |author, i|
link = h.link_to(author.name, author)
if author == mod.owner and mod.authors.size > 1
if author.user_id == mod.author_id and mod.authors.size > 1
maintainer = h.t('helpers.mods.maintainer')
link + " (#{maintainer})"
else
@ -152,9 +152,9 @@ class ModDecorator < Draper::Decorator
def visibility_notice
if not mod.visible?
if h.current_user.is_admin?
if h.current_user and h.current_user.is_admin?
h.t('mods.show.non_visible.admin')
elsif h.current_user.is_dev?
elsif h.current_user and h.current_user.is_dev?
h.t('mods.show.non_visible.dev')
else
h.t('mods.show.non_visible.non_dev')

View File

@ -8,12 +8,10 @@
class Mod < ActiveRecord::Base
extend FriendlyId
friendly_id :slug_candidates, use: [:slugged, :finders]
def slug_candidates
[
:name,
[:name, 'by', :author_name]
authors.first && [:name, 'by', authors.first.name]
]
end
@ -25,7 +23,7 @@ class Mod < ActiveRecord::Base
### Relationships
#################
belongs_to :author, class_name: 'User' # Deprecated
belongs_to :author, class_name: 'User' # Deprecated, but don't remove it yet tons of tests break
belongs_to :owner, class_name: 'User', foreign_key: :author_id
belongs_to :game_version_start, class_name: 'GameVersion'
belongs_to :game_version_end, class_name: 'GameVersion'
@ -45,7 +43,7 @@ class Mod < ActiveRecord::Base
has_many :game_versions, -> { uniq.sort_by_older_to_newer }, through: :mod_game_versions
has_many :categories, through: :categories_mods
has_many :categories_mods, dependent: :destroy
has_many :authors, ->{ includes(:authors_mods).order('authors_mods.sort_order') } , through: :authors_mods, class_name: 'User'
has_many :authors, ->{ includes(:authors_mods).order('authors_mods.sort_order') }, through: :authors_mods
has_many :authors_mods, dependent: :destroy
# has_one :latest_version, -> { sort_by_newer_to_older.limit(1) }, class_name: 'ModVersion'
@ -192,12 +190,6 @@ class Mod < ActiveRecord::Base
end
end
before_save do
if author
self.author_name = author.name
end
end
after_save do
if forum_post
forum_post.mod = self
@ -208,14 +200,24 @@ class Mod < ActiveRecord::Base
# find or generate users from #authors_list
before_validation do
if authors_list.present?
authors_names = authors_list.split(',').map(&:strip).reject(&:blank?).take(10).uniq(&:downcase)
authors_index = User.where('lower(name) IN (?)', authors_names.map(&:downcase)).index_by{ |user| user.name.downcase }
self.authors = @reordered_authors = authors_names.each_with_index.map do |name, i|
authors_index[name.downcase] || User.autogenerate(name: name)
authors_names = authors_list.split(',')
.map(&:strip)
.reject(&:blank?)
.take(10)
.uniq{ |name| Author.normalize_friendly_id(name) }
self.authors = @reordered_authors = authors_names.map do |name|
Author.find_by_slugged_name(name) || Author.new(name: name, forum_name: name)
end
end
end
# Yes, I have to move the authors_list parser to another file
# and move this again to the header. But for now, we need to access
# author.first to generate the alternative slug, and friendly_id
# adds the slug generation also before_validation
friendly_id :slug_candidates, use: [:slugged, :finders]
# add the #authors errors to #authors_list
after_validation do
if authors_list.present?
@ -346,11 +348,6 @@ class Mod < ActiveRecord::Base
read_attribute(:game_versions_string) || set_game_versions_string
end
def author_name
return super if super.present?
return author.name if author
end
def github_url
"http://github.com/#{github_path}" if github_path
end
@ -370,6 +367,7 @@ class Mod < ActiveRecord::Base
private
def set_game_versions_string
return if new_record?
gvs = begin
last_game_version = game_versions.last
first_game_version = game_versions.first

View File

@ -79,6 +79,7 @@ class ModVersion < ActiveRecord::Base
private
def set_game_versions_string
return if new_record?
gvs = begin
last_game_version = game_versions.last
first_game_version = game_versions.first

View File

@ -46,6 +46,15 @@ class FakeDataGenerator
end
users = User.all
### Authors
gputs "---------- Creating authors!"
rand(5..10).times do |i|
name = Forgery(:internet).user_name + i.to_s
Author.create!(name: name, forum_name: name)
gputs "Created author #{name}"
end
authors = Author.all
### Subforum
##################
subforum = Subforum.create!(url: 'http://www.factorioforums.com/forum/viewforum.php?f=91')
@ -69,7 +78,7 @@ class FakeDataGenerator
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),
authors: authors.sample(rand(0..3)),
owner: [nil, nil].concat(users).sample,
categories: categories.sample(rand(1..4)),
github: rand > 50 ? nil : github_url,

View File

@ -1,5 +1,7 @@
class MultiAuthorsUpdater
def update
raise 'No longer supported'
Mod.all.each do |mod|
if mod.authors.empty?
if mod.author
@ -12,4 +14,4 @@ class MultiAuthorsUpdater
end
end
end
end
end

View File

@ -5,26 +5,39 @@ describe ModDecorator do
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}" }
expect(mod.authors_links_list).to eq '<a href="/users/au0">Au0</a>, <a href="/users/au1">Au1</a>, <a href="/users/au2">Au2</a>'
mod = create_decorated :mod, authors: 3.times.map{ |i| create :author, name: "Au#{i}" }
expect(mod.authors_links_list).to eq '<a href="/authors/au0">Au0</a>, <a href="/authors/au1">Au1</a>, <a href="/authors/au2">Au2</a>'
end
it 'should add the (maintainer) text if the author is also the owner' do
authors = 3.times.map{ |i| create :user, name: "Au#{i}" }
mod = create_decorated :mod, authors: authors, owner: authors[1]
expect(mod.authors_links_list).to eq '<a href="/users/au0">Au0</a>, <a href="/users/au1">Au1</a> (maintainer), <a href="/users/au2">Au2</a>'
authors = 3.times.map{ |i| create :author, name: "Au#{i}" }
user = create :user
authors[1].update! user: user
mod = create_decorated :mod, authors: authors, owner: user
expect(mod.authors_links_list).to eq '<a href="/authors/au0">Au0</a>, <a href="/authors/au1">Au1</a> (maintainer), <a href="/authors/au2">Au2</a>'
end
it 'should not add the (maintainer) text if there is only 1 author' do
author = create :user, name: "Au0"
mod = create_decorated :mod, authors: [author], owner: author
expect(mod.authors_links_list).to eq '<a href="/users/au0">Au0</a>'
user = create :user
author = create :author, name: "Au0", user: user
mod = create_decorated :mod, authors: [author], owner: user
expect(mod.authors_links_list).to eq '<a href="/authors/au0">Au0</a>'
end
it 'should return N/A if the mod has no authors associated' do
mod = create_decorated :mod, authors: []
expect(mod.authors_links_list).to eq 'N/A'
end
it 'should show them in the correct sorting order' do
authors = 3.times.map{ |i| create :author, name: "Au#{i}" }
mod = create :mod, name: 'SuperMod', authors: authors
mod.authors_mods[0].update_column :sort_order, 3
mod.authors_mods[1].update_column :sort_order, 2
mod.authors_mods[2].update_column :sort_order, 1
mod.reload
expect(mod.decorate.authors_links_list).to eq '<a href="/authors/au2">Au2</a>, <a href="/authors/au1">Au1</a>, <a href="/authors/au0">Au0</a>'
end
end
describe '#forum_link' do

View File

@ -1,7 +1,7 @@
FactoryGirl.define do
factory :mod do
sequence(:name) { |n| "Mod name #{n.to_s.rjust(6, '0')}" }
association :author, factory: :user
association :owner, factory: :user
categories { build_list :category, 1 }
description ''
forum_comments_count 12

View File

@ -4,7 +4,7 @@ feature 'Modder edits an existing mod' do
scenario 'submit same basic mod' do
sign_in
create_category 'potato'
mod = create :mod, name: 'Hey', categories: [@category], owner: @user
create :mod, name: 'Hey', categories: [@category], owner: @user
visit '/mods/hey/edit'
submit_form
expect(current_path).to eq '/mods/hey'
@ -14,8 +14,8 @@ feature 'Modder edits an existing mod' do
scenario 'user edits a mod with a list of authors' do
sign_in_dev
create_category 'potato'
authors = 5.times.map{ create :user }
mod = create :mod, name: 'Hey', categories: [@category], owner: @user, authors: authors
authors = 5.times.map{ create :author }
create :mod, name: 'Hey', categories: [@category], owner: @user, authors: authors
visit '/mods/hey/edit'
expect(find('#mod_authors_list').value).to eq authors.map(&:name).join(', ')
end
@ -27,4 +27,4 @@ feature 'Modder edits an existing mod' do
def create_category(name)
@category = create :category, name: name
end
end
end

View File

@ -77,36 +77,10 @@ feature 'Display an index of mods in certain order' do
end
end
context 'with many authors' do
scenario 'Mod with multiple authors and no owner' 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_link 'Au0', '/users/au0'
expect(page).to have_link 'Au1', '/users/au1'
expect(page).to have_link 'Au2', '/users/au2'
expect(page).to have_link 'Au3', '/users/au3'
expect(page).to have_link 'Au4', '/users/au4'
end
scenario 'Mod with multiple authors and one of the authors is the owner' 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/)
end
scenario 'Mod with multiple authors with reversed sorting order' do
authors = 5.times.map{ |i| create :user, name: "Au#{i}" }
mod = create :mod, name: 'SuperMod', authors: authors
mod.authors_mods[0].update_column :sort_order, 5
mod.authors_mods[1].update_column :sort_order, 4
mod.authors_mods[2].update_column :sort_order, 3
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/)
end
scenario 'Mod with multiple authors' do
authors = 5.times.map{ |i| create :author, name: "Au#{i}" }
mod = create :mod, name: 'SuperMod', authors: authors
visit '/'
expect(page.html).to include(mod.decorate.authors_links_list)
end
end

View File

@ -221,10 +221,11 @@ feature 'Modder creates a new mod' do
sign_in_dev
@user.name = 'yeah'
@user.save!
mod = create :mod, name: 'SuperMod'
create :mod, name: 'SuperMod'
visit "/mods/new"
fill_in_minimum('SuperMod')
fill_in 'mod_authors_list', with: 'yeah'
submit_form
expect(current_path).to eq '/mods/supermod-by-yeah'
end
@ -243,11 +244,11 @@ feature 'Modder creates a new mod' do
sign_in_dev
visit '/mods/new'
fill_in_minimum
fill_in 'mod_authors_list', with: 'Potato(), SuperUser, Salad'
fill_in 'mod_authors_list', with: 'Potato, ----, Salad'
submit_form
expect(current_path).to eq '/mods'
expect(page).to have_css '#mod_authors_list_input .inline-errors'
expect(page).to have_content /Potato\(\) is invalid/
expect(page).to have_content(/---- is invalid/)
end
scenario 'user submits a mod too many authors in the #authors_list' do
@ -258,7 +259,7 @@ feature 'Modder creates a new mod' do
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
expect(page).to have_content(/too many/i)
end
describe 'visibility toggle' do

View File

@ -21,7 +21,7 @@ feature 'Display full mod information' do
scenario 'Visiting the mod page as the owner of the mod should display a link to edit the mod' do
sign_in
category = create :category, name: 'Potato category'
create :mod, name: 'Super Mod', categories: [category], author: @user
create :mod, name: 'Super Mod', categories: [category], owner: @user
visit '/mods/super-mod'
expect(page).to have_link 'Edit mod', '/mods/super-mod/edit'
end
@ -29,7 +29,7 @@ feature 'Display full mod information' do
scenario 'Visiting the mod page as a guest should not display a link to edit the mod' do
sign_in
category = create :category, name: 'Potato category'
create :mod, name: 'Super Mod', categories: [category], author: build(:user)
create :mod, name: 'Super Mod', categories: [category], owner: build(:user)
visit '/mods/super-mod'
expect(page).to_not have_link 'Edit mod', '/mods/super-mod/edit'
end
@ -38,7 +38,7 @@ feature 'Display full mod information' do
sign_in
@user.is_admin = true
category = create :category, name: 'Potato category'
create :mod, name: 'Super Mod', categories: [category], author: build(:user)
create :mod, name: 'Super Mod', categories: [category], owner: build(:user)
visit '/mods/super-mod'
expect(page).to have_link 'Edit mod', '/mods/super-mod/edit'
end
@ -54,36 +54,16 @@ feature 'Display full mod information' do
expect(page.find('.mod-downloads-table')).to have_content /bbbbb.*aaaaa.*ccccc/
end
scenario 'Mod with multiple authors and no owner' do
authors = 5.times.map{ |i| create :user, name: "Au#{i}" }
create :mod, name: 'SuperMod', authors: authors
visit '/mods/supermod'
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'
expect(page).to have_link 'Au3', '/users/au3'
expect(page).to have_link 'Au4', '/users/au4'
end
# TODO: Using the sign in helpers and this breaks all the other tests
# that require the user to be logged in for some reason. Fix with a proper
# helper to login on integration tests. Or move these to views tests.
scenario 'Mod with multiple authors and one of the authors is the owner' do
authors = 5.times.map{ |i| create :user, name: "Au#{i}" }
create :mod, name: 'SuperMod', authors: authors, owner: authors[1]
visit '/mods/supermod'
expect(page).to have_content /Au0.*Au1.*(maintainer).*Au2.*Au3.*Au4/
end
scenario 'Mod with multiple authors with reversed sorting order' do
authors = 5.times.map{ |i| create :user, name: "Au#{i}" }
mod = create :mod, name: 'SuperMod', authors: authors
mod.authors_mods[0].update_column :sort_order, 5
mod.authors_mods[1].update_column :sort_order, 4
mod.authors_mods[2].update_column :sort_order, 3
mod.authors_mods[3].update_column :sort_order, 2
mod.authors_mods[4].update_column :sort_order, 1
visit '/mods/supermod'
expect(page).to have_content /Au4.*Au3.*Au2.*Au1.*Au0/
end
# scenario 'Mod with multiple authors' do
# authors = 5.times.map{ |i| create :author, name: "Au#{i}" }
# mod = create :mod, name: 'SuperMod', authors: authors
# visit '/mods/supermod'
# expect(page.html).to include(mod.decorate.authors_links_list)
# end
describe 'visibility' do
scenario 'non-dev owner visits his own mod' do

View File

@ -1,30 +1,32 @@
include Warden::Test::Helpers
feature 'User can register with an user that was autogenerated' do
scenario 'a mod was created with an user in the #authors_list, then the author register with that name' do
mod1 = create :mod, authors_list: 'Galaxy, Magenta', owner: nil, author: nil, name: 'PotatoMod'
mod2 = build :mod, authors_list: 'Magenta', owner: nil, author: nil, name: "SaladMod"
mod2.save!
magenta = User.last
expect(magenta.name).to eq 'Magenta'
expect(magenta.autogenerated).to eq true
visit '/users/register'
within('#new_registration') do
fill_in 'user_email', with: 'apple@banana.com'
fill_in 'user_name', with: 'Magenta'
fill_in 'user_password', with: '12344321'
fill_in 'user_password_confirmation', with: '12344321'
end
click_button 'Register'
magenta.reload
expect(magenta.email).to eq 'apple@banana.com'
expect(magenta.valid_password? '12344321').to eq true
expect(magenta.autogenerated).to eq false
expect(current_path).to eq '/users'
expect(page).to have_content I18n.t('users.registrations.signed_up_autogenerated.mods_with_your_name')
expect(page).to have_css 'a[href="http://www.factorioforums.com/forum/ucp.php?i=pm&mode=compose&u=1553"]'
expect(page).to have_content /PotatoMod.*SaladMod/
expect(page).to have_css 'a[href="/mods/potatomod"]'
expect(page).to have_css 'a[href="/mods/saladmod"]'
end
end
# I'm gonna use this for the upcoming tests of the authors-users separation registration
# feature 'User can register with an user that was autogenerated' do
# scenario 'a mod was created with an user in the #authors_list, then the author register with that name' do
# mod1 = create :mod, authors_list: 'Galaxy, Magenta', owner: nil, author: nil, name: 'PotatoMod'
# mod2 = build :mod, authors_list: 'Magenta', owner: nil, author: nil, name: "SaladMod"
# mod2.save!
# magenta = User.last
# expect(magenta.name).to eq 'Magenta'
# expect(magenta.autogenerated).to eq true
# visit '/users/register'
# within('#new_registration') do
# fill_in 'user_email', with: 'apple@banana.com'
# fill_in 'user_name', with: 'Magenta'
# fill_in 'user_password', with: '12344321'
# fill_in 'user_password_confirmation', with: '12344321'
# end
# click_button 'Register'
# magenta.reload
# expect(magenta.email).to eq 'apple@banana.com'
# expect(magenta.valid_password? '12344321').to eq true
# expect(magenta.autogenerated).to eq false
# expect(current_path).to eq '/users'
# expect(page).to have_content I18n.t('users.registrations.signed_up_autogenerated.mods_with_your_name')
# expect(page).to have_css 'a[href="http://www.factorioforums.com/forum/ucp.php?i=pm&mode=compose&u=1553"]'
# expect(page).to have_content /PotatoMod.*SaladMod/
# expect(page).to have_css 'a[href="/mods/potatomod"]'
# expect(page).to have_css 'a[href="/mods/saladmod"]'
# end
# end

View File

@ -3,10 +3,11 @@ describe FakeDataGenerator, vcr: { cassette_name: 'fake_data_generator', record:
it 'should generate data on each table for testing purposes without failing' do
generator = FakeDataGenerator.new
generator.generate
expect(Game.all.count).to be 1
expect(GameVersion.all.count).to be >= 5
expect(User.all.count).to be >= 5
expect(Author.all.count).to be >= 5
expect(Subforum.all.count).to be >= 1
expect(ForumPost.all.count).to be >= 10
expect(Mod.all.count).to be >= 10
@ -14,4 +15,4 @@ describe FakeDataGenerator, vcr: { cassette_name: 'fake_data_generator', record:
expect(ModFile.all.count).to be >= 10
end
end
end
end

View File

@ -1,40 +1,40 @@
describe MultiAuthorsUpdater do
subject(:scraper){ MultiAuthorsUpdater.new }
it { is_expected.to respond_to :update }
it 'should add the #owner/#author to #authors in the mods' do
u1 = create :user
u2 = create :user
m1 = create :mod, author: u1
m2 = create :mod, author: u2
expect(m1.authors).to be_empty
expect(m2.authors).to be_empty
subject.update
m1.reload
m2.reload
expect(m1.authors).to eq [u1]
expect(m2.authors).to eq [u2]
end
it 'should create users, using #authors_list, from #author_name in the mods' do
m1 = create :mod, author_name: 'Potato', author: nil, owner: nil
m2 = create :mod, author_name: 'Salad', author: nil, owner: nil
subject.update
m1.reload
m2.reload
u1 = User.find_by_name('Potato')
u2 = User.find_by_name('Salad')
expect(m1.authors).to eq [u1]
expect(m2.authors).to eq [u2]
end
it 'should not update mods with non-empty #authors, to prevent accidents' do
u1 = create :user
u2 = create :user
m1 = create :mod, author: u1, authors: [u2]
subject.update
m1.reload
expect(m1.authors).to eq [u2]
end
end
# subject(:scraper){ MultiAuthorsUpdater.new }
#
# it { is_expected.to respond_to :update }
#
# it 'should add the #owner/#author to #authors in the mods' do
# u1 = create :user
# u2 = create :user
# m1 = create :mod, author: u1
# m2 = create :mod, author: u2
# expect(m1.authors).to be_empty
# expect(m2.authors).to be_empty
# subject.update
# m1.reload
# m2.reload
# expect(m1.authors).to eq [u1]
# expect(m2.authors).to eq [u2]
# end
#
# it 'should create users, using #authors_list, from #author_name in the mods' do
# m1 = create :mod, author_name: 'Potato', author: nil, owner: nil
# m2 = create :mod, author_name: 'Salad', author: nil, owner: nil
# subject.update
# m1.reload
# m2.reload
# u1 = User.find_by_name('Potato')
# u2 = User.find_by_name('Salad')
# expect(m1.authors).to eq [u1]
# expect(m2.authors).to eq [u2]
# end
#
# it 'should not update mods with non-empty #authors, to prevent accidents' do
# u1 = create :user
# u2 = create :user
# m1 = create :mod, author: u1, authors: [u2]
# subject.update
# m1.reload
# expect(m1.authors).to eq [u2]
# end
end

View File

@ -42,7 +42,6 @@ describe Mod do
# it { is_expected.to respond_to :visits_count }
# belongs_to
it { is_expected.to respond_to :author }
it { is_expected.to respond_to :owner }
it { expect(mod.build_owner).to be_kind_of User }
it { is_expected.to respond_to :categories }
@ -171,7 +170,7 @@ describe Mod do
end
it 'should not allow the "new" slug as it clashes with the controller action' do
mod = create :mod, name: 'New!', author_name: 'Potato'
mod = create :mod, name: 'New!', authors_list: 'Potato'
expect(mod.slug).to eq 'new-by-potato'
end
end

View File

@ -35,7 +35,7 @@ VCR.configure do |config|
config.ignore_request do |request|
URI(request.uri).host == '127.0.0.1'
end
# This is so we can read the response body text and
# maybe touch it a little for edge cases
config.before_record do |i|

View File

@ -1,6 +1,6 @@
describe ModSerializer do
before :each do
authors = [create(:user, name: 'John Snow Zombie'), create(:user, name: 'THAT Guy')]
authors = [create(:author, name: 'John Snow Zombie'), create(:author, name: 'THAT Guy')]
@mod = create :mod,
name: 'Potato Galaxy',
info_json_name: 'potato-galaxy-mod',