diff --git a/spec/controllers/events_controller_spec.rb b/spec/controllers/events_controller_spec.rb index 24657d31..0070a119 100644 --- a/spec/controllers/events_controller_spec.rb +++ b/spec/controllers/events_controller_spec.rb @@ -356,7 +356,7 @@ expect(response).to redirect_to(events_url) end end - #this test is only for leagues + describe "GET League#schedule" do it "should generate schedule if not existing" do event = League.create! valid_league_attributes diff --git a/spec/factories/events.rb b/spec/factories/events.rb index 6fa869b3..f4d90fff 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -68,15 +68,6 @@ end end - factory :event_with_teams do - transient do - teams_count 5 - end - after(:create) do |event, evaluator| - FactoryBot.create_list(:team, evaluator.teams_count, events: [event]) - end - end - trait :fcfs do selection_type Event.selection_types[:fcfs] end diff --git a/spec/factories/leagues.rb b/spec/factories/leagues.rb index 7706c49f..8ab7ab56 100644 --- a/spec/factories/leagues.rb +++ b/spec/factories/leagues.rb @@ -2,10 +2,5 @@ factory :league, parent: :event, traits: [:has_dates], class: League do game_mode :round_robin gameday_duration 7 - - factory :league_with_teams, class: League, parent: :event_with_teams, traits: [:has_dates] do - game_mode :round_robin - gameday_duration 7 - end end end diff --git a/spec/factories/rankinglists.rb b/spec/factories/rankinglists.rb index aec81757..66038340 100644 --- a/spec/factories/rankinglists.rb +++ b/spec/factories/rankinglists.rb @@ -3,8 +3,5 @@ game_mode Rankinglist.game_modes.keys.sample initial_value 1.3 player_type Event.player_types[:single] - - factory :rankinglist_with_teams, class: "Rankinglist", parent: :event_with_teams do - end end end diff --git a/spec/factories/tournaments.rb b/spec/factories/tournaments.rb index 5d66d3d0..afed17f7 100644 --- a/spec/factories/tournaments.rb +++ b/spec/factories/tournaments.rb @@ -1,10 +1,5 @@ FactoryBot.define do factory :tournament, parent: :event, traits: [:has_dates], class: Tournament do game_mode :ko - - factory :tournament_with_teams, class: Tournament, parent: :event_with_teams, traits: [:has_dates] do - teams_count 4 - game_mode :ko - end end end diff --git a/spec/features/event/new_event_spec.rb b/spec/features/event/new_event_spec.rb index 0e25070e..8d85bc4f 100644 --- a/spec/features/event/new_event_spec.rb +++ b/spec/features/event/new_event_spec.rb @@ -1,6 +1,32 @@ require 'rails_helper' describe 'new event page', type: :feature do + + def fill_in_fields_with(fields = {}) + fields.each do |field_symbol, input| + fill_in Event.human_attribute_name(field_symbol), with: input + end + end + + def select_dropdowns_with(dropdowns = {}) + dropdowns.each do |dropdown, input| + select input, from: dropdown + end + end + + def has_input_fields(*fields) + fields.each do |field| + expect(page).to have_field(Event.human_attribute_name field) + end + end + + def has_content(fields) + fields.each do |field, content| + expect(page).to have_content(Event.human_attribute_name field) + expect(page).to have_content content + end + end + before(:each) do @user = FactoryBot.create :user sign_in @user @@ -10,90 +36,89 @@ let(:new_path) { new_league_path } # /new?type=league it 'should render without errors' do - visit new_path - end + visit new_path + end it 'should be possible to enter date conditions' do visit new_path - expect(page).to have_field(Event.human_attribute_name :deadline) - expect(page).to have_field(Event.human_attribute_name :startdate) - expect(page).to have_field(Event.human_attribute_name :enddate) + has_input_fields :deadline, :startdate, :enddate end it 'should have a field for league duration' do visit new_path - expect(page).to have_field('event_duration') + expect(page).to have_field 'event_duration' end - it 'should be possible to create a date conditions' do - visit new_path - fill_in Event.human_attribute_name(:name), with: 'name' - fill_in Event.human_attribute_name(:discipline), with: 'soccer' - select League.human_game_mode(:round_robin), from: Event.human_attribute_name(:game_mode) - select Event.human_player_type(:single), from: Event.human_attribute_name(:player_type) - fill_in Event.human_attribute_name(:max_teams), with: '5' + let(:league) { FactoryBot.build(:league) } + let(:valid_league_input_fields) { { name: league.name, + discipline: league.discipline, + max_teams: league.max_teams, + deadline: league.deadline, + startdate: league.startdate, + enddate: league.enddate, + gameday_duration: league.gameday_duration } } + let(:valid_league_dropdowns) { { Event.human_attribute_name(:game_mode) => League.human_game_mode(:round_robin), + Event.human_attribute_name(:player_type) => Event.human_player_type(:single) } } - fill_in Event.human_attribute_name(:deadline), with: Date.tomorrow.to_s - fill_in Event.human_attribute_name(:startdate), with: (Date.tomorrow + 2).to_s - fill_in Event.human_attribute_name(:enddate), with: (Date.tomorrow + 3).to_s - fill_in Event.human_attribute_name(:gameday_duration), with: '1' + it 'should be possible to create a league' do + visit new_path + fill_in_fields_with valid_league_input_fields + select_dropdowns_with valid_league_dropdowns find('input[type="submit"]').click + has_content valid_league_input_fields + has_content valid_league_dropdowns expect(page).to have_current_path(/.*\/leagues\/\d+/) - expect(page).to have_content(Date.tomorrow.to_s) - expect(page).to have_content((Date.tomorrow + 2).to_s) - expect(page).to have_content((Date.tomorrow + 3).to_s) end end - context "for ranking lists" do + context 'for ranking lists' do before :each do visit new_rankinglist_path end - it "should show a field for choosing the ranking metric" do + it 'should show a field for choosing the ranking metric' do expect(page).to have_field('rankinglist_game_mode') end - it "should show a field for choosing the initial value of the ranking metric" do + it 'should show a field for choosing the initial value of the ranking metric' do expect(page).to have_field('rankinglist_initial_value') end - it "should not show a field for defining a deadline" do + it 'should not show a field for defining a deadline' do expect(page).not_to have_field('event_deadline') end - it "should not show a field for defining a enddate " do + it 'should not show a field for defining a enddate ' do expect(page).not_to have_field('event_enddate') end - it "should not show a field for defining a startdate" do + it 'should not show a field for defining a startdate' do expect(page).not_to have_field('event_startdate') end - it "should not show a field for defining whether its a team or single player sport" do + it 'should not show a field for defining whether its a team or single player sport' do expect(page).not_to have_field('event_player_type') end - it "should not show a field for the duration" do + it 'should not show a field for the duration' do expect(page).not_to have_field('event_duration') end + let(:rankinglist) { FactoryBot.build :rankinglist } + let(:ranking_list_input_fields) { { name: rankinglist.name, discipline: rankinglist.discipline, + max_teams: rankinglist.max_teams, initial_value: rankinglist.initial_value } } - it "should be possible to create a rankinglist" do - rankinglist = FactoryBot.build :rankinglist - - fill_in Event.human_attribute_name(:name), with: rankinglist.name - fill_in Event.human_attribute_name(:discipline), with: rankinglist.discipline + it 'should be possible to create a rankinglist' do + fill_in_fields_with ranking_list_input_fields select Rankinglist.human_game_mode(:true_skill), from: Event.human_attribute_name(:game_mode) - fill_in Event.human_attribute_name(:max_teams), with: rankinglist.max_teams - fill_in Event.human_attribute_name(:initial_value), with: rankinglist.initial_value find('input[type="submit"]').click expect(page).to have_current_path(/.*\/rankinglists\/\d+/) + has_content ranking_list_input_fields.except(:initial_value) end end @@ -107,36 +132,34 @@ it 'should be possible to enter date conditions' do visit new_path - expect(page).to have_field(Event.human_attribute_name :deadline) - expect(page).to have_field(Event.human_attribute_name :startdate) - expect(page).to have_field(Event.human_attribute_name :enddate) + has_input_fields :deadline, :startdate, :enddate end - it 'should have a field for league duration' do + it 'should have a field for tournament duration' do visit new_path - expect(page).to have_field('event_duration') + expect(page).to have_field 'event_duration' end - it 'should be possible to create a date conditions' do + let(:tournament) { FactoryBot.build(:tournament) } + let(:valid_tournament_input_fields) { { name: tournament.name, + discipline: tournament.discipline, + max_teams: tournament.max_teams, + deadline: tournament.deadline, + startdate: tournament.startdate, + enddate: tournament.enddate } } + let(:valid_tournament_dropdowns) { { Event.human_attribute_name(:game_mode) => Tournament.human_game_mode(tournament.game_mode), + Event.human_attribute_name(:player_type) => Event.human_player_type(:single) } } + it 'should be possible to create a tournament' do visit new_path - fill_in Event.human_attribute_name(:name), with: 'name' - fill_in Event.human_attribute_name(:discipline), with: 'soccer' - select Tournament.human_game_mode(:ko), from: Event.human_attribute_name(:game_mode) - select Event.human_player_type(:single), from: Event.human_attribute_name(:player_type) - fill_in Event.human_attribute_name(:max_teams), with: '5' - - fill_in Event.human_attribute_name(:deadline), with: Date.tomorrow.to_s - fill_in Event.human_attribute_name(:startdate), with: (Date.tomorrow + 2).to_s - fill_in Event.human_attribute_name(:enddate), with: (Date.tomorrow + 3).to_s - + fill_in_fields_with valid_tournament_input_fields + select_dropdowns_with valid_tournament_dropdowns find('input[type="submit"]').click - expect(page).to have_current_path(/.*\/(events|tournaments|leagues)\/\d+/) - expect(page).to have_content(Date.tomorrow.to_s) - expect(page).to have_content((Date.tomorrow + 2).to_s) - expect(page).to have_content((Date.tomorrow + 3).to_s) + expect(page).to have_current_path(/.*\/tournaments\/\d+/) + has_content valid_tournament_input_fields + has_content valid_tournament_dropdowns end end end diff --git a/spec/models/actual_event_examples.rb b/spec/models/actual_event_examples.rb new file mode 100644 index 00000000..6581eed5 --- /dev/null +++ b/spec/models/actual_event_examples.rb @@ -0,0 +1,44 @@ +shared_examples 'an actual event' do |for_class: :event| + let(:event) { FactoryBot.build(for_class) } + it 'should not validate without selection_type' do + event.selection_type = nil + expect(event.valid?).to eq(false) + end + + it 'should have an attribute deadline' do + date = Date.tomorrow + expect(event.deadline).to eq date + + event.deadline = nil + expect(event).not_to be_valid + end + + it 'should have an attribute startdate' do + date = Date.current + 2 + expect(event.startdate).to eq date + + expect(event).to be_valid + event.startdate = nil + expect(event).not_to be_valid + end + + it 'should have an attribute enddate' do + date = Date.current + 3 + expect(event.enddate).to eq date + + expect(event).to be_valid + event.enddate = nil + expect(event).not_to be_valid + end + + it 'should not be possible to have an enddate, that is before the startdate' do + expect(event).to be_valid + event.enddate = Date.current + event.startdate = Date.current + 1 + expect(event).not_to be_valid + end + + it 'should be possible to get the duration in day of a event' do + expect(event.duration).to eq(2) + end +end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 900c4f05..11f6d501 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -23,62 +23,21 @@ describe 'Event model', type: :model do - let(:event) { FactoryBot.build(:league) } + let(:event) { FactoryBot.build(:event) } it 'should not validate without name' do - league = FactoryBot.build(:league, name: nil) - expect(league.valid?).to eq(false) + event = FactoryBot.build(:event, name: nil) + expect(event.valid?).to eq(false) end it 'should not validate without discipline' do - league = FactoryBot.build(:league, discipline: nil) - expect(league.valid?).to eq(false) + event = FactoryBot.build(:event, discipline: nil) + expect(event.valid?).to eq(false) end it 'should not validate without game_mode' do - league = FactoryBot.build(:league, game_mode: nil) - expect(league.valid?).to eq(false) - end - - it 'should not validate without selection_type' do - league = FactoryBot.build(:league, selection_type: nil) - expect(league.valid?).to eq(false) - end - - it 'should have an attribute deadline' do - date = Date.tomorrow - expect(event.deadline).to eq date - - event.deadline = nil - expect(event).not_to be_valid - end - - it 'should have an attribute startdate' do - date = Date.current + 2 - expect(event.startdate).to eq date - - expect(event).to be_valid - event.startdate = nil - expect(event).not_to be_valid - end - - it 'should have an attribute enddate' do - date = Date.current + 3 - expect(event.enddate).to eq date - - expect(event).to be_valid - event.enddate = nil - expect(event).not_to be_valid - end - - it 'should not be possible to have an enddate, that is before the startdate' do - expect(event).to be_valid - event.enddate = Date.current - expect(event).not_to be_valid - end - - it 'should be possible to get the duration in day of an event' do - expect(event.duration).to eq(2) + event = FactoryBot.build(:event, game_mode: nil) + expect(event.valid?).to eq(false) end it 'should only show active events' do @@ -105,8 +64,11 @@ expect(passed_deadline_event.deadline_has_passed?).to be true end - it "generate_Schedule? should raise a NotImplementedError" do + it 'generate_Schedule? should raise a NotImplementedError' do event = FactoryBot.build :event + # This is apparently not the correct way to implement an abstract method in ruby. + # (https://stackoverflow.com/a/2502835/8921181, http://ruby-doc.org/core-2.2.0/NotImplementedError.html) + # But it is the only way I know of right now to somewhat document that this has to be implemented by subclasses. expect { event.generate_schedule }.to raise_error NotImplementedError end end diff --git a/spec/models/league_spec.rb b/spec/models/league_spec.rb index 6e672065..a4e70e1c 100644 --- a/spec/models/league_spec.rb +++ b/spec/models/league_spec.rb @@ -20,6 +20,7 @@ # require 'rails_helper' +require 'models/actual_event_examples' describe 'League model', type: :model do @@ -29,6 +30,8 @@ expect(league).to be_valid end + it_should_behave_like 'an actual event', for_class: :league + describe 'gameday duration' do it 'should not validate without it' do league.gameday_duration = nil @@ -56,10 +59,10 @@ end end describe 'Generating league schedule with default values' do - let(:league) { league = FactoryBot.create(:league_with_teams) + let(:league) { league = FactoryBot.create(:league, :with_teams) league.game_mode = League.game_modes[:round_robin] league.generate_schedule - league} + league } let(:matches) { league.matches } let(:home_teams) { matches.map(&:team_home) } let(:away_teams) { matches.map(&:team_away) } @@ -95,13 +98,13 @@ end end - it "uses round robin if its selected" do + it 'uses round robin if its selected' do # simple round robin has n((n-1)/2) games expect(matches.length).to be league.teams.length * ((league.teams.length - 1) / 2) end - it "has double the matches if double round robin is selected" do - new_league = FactoryBot.create(:league_with_teams) + it 'has double the matches if double round robin is selected' do + new_league = FactoryBot.create(:league, :with_teams) new_league.game_mode = League.game_modes[:two_halfs] new_league.generate_schedule # double round robin has n(n-1) games diff --git a/spec/models/tournament_spec.rb b/spec/models/tournament_spec.rb index 84f23799..77827aa2 100644 --- a/spec/models/tournament_spec.rb +++ b/spec/models/tournament_spec.rb @@ -20,6 +20,7 @@ # require 'rails_helper' +require 'models/actual_event_examples' describe "Tournament model", type: :model do @@ -28,4 +29,6 @@ expect(tournament).to be_valid end + it_should_behave_like 'an actual event', for_class: :tournament + end diff --git a/spec/views/matches/show_tournament.html.erb_spec.rb b/spec/views/matches/show_tournament.html.erb_spec.rb index 7c42949d..b6e56d39 100644 --- a/spec/views/matches/show_tournament.html.erb_spec.rb +++ b/spec/views/matches/show_tournament.html.erb_spec.rb @@ -2,7 +2,7 @@ RSpec.describe "matches/show", type: :view do before(:each) do - @tournament = FactoryBot.create :tournament_with_teams + @tournament = FactoryBot.create :tournament, :with_teams @tournament.generate_schedule @match = assign(:match, @tournament.finale) end