mirror of
https://github.com/fspc/BikeShed-1.git
synced 2026-09-16 08:31:36 -04:00
git init
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
Feature: Create a team
|
||||
In order to gather my friends to participate in a hunt
|
||||
As a user
|
||||
I want to create a team
|
||||
|
||||
Background:
|
||||
Given a user "test@example.com" with password "password"
|
||||
When I login with email "test@example.com" and password "password"
|
||||
And I go to create a new team
|
||||
|
||||
Scenario: View the create a team form
|
||||
Then I should see the create a team form
|
||||
|
||||
Scenario: Errors on form are displayed
|
||||
When I submit the new team form
|
||||
Then I should see an error message about the team name
|
||||
|
||||
Scenario: Created team is in list
|
||||
When I fill out the team form with team name "Happy Trackers"
|
||||
And I submit the new team form
|
||||
And I go to the team list
|
||||
Then I should see "Happy Trackers" in the team list
|
||||
|
||||
Scenario: Create a private team
|
||||
When I fill out the team form with team name "Happy Trackers"
|
||||
And I check the box to make my team private
|
||||
And I submit the new team form
|
||||
And I go to the team list
|
||||
Then the team list should be:
|
||||
| Happy Trackers* |
|
||||
@@ -0,0 +1,34 @@
|
||||
Feature: List teams
|
||||
In order to see the teams
|
||||
As a user
|
||||
I want to see them sorted by name and paginated
|
||||
|
||||
Background:
|
||||
Given a user "test@example.com" with password "password"
|
||||
When I login with email "test@example.com" and password "password"
|
||||
|
||||
Scenario: Team list paginated to 15
|
||||
Given 20 teams exist
|
||||
And I go to the team list
|
||||
Then I should see 15 teams in the team list
|
||||
When I go to the next page
|
||||
Then I should see 5 teams in the team list
|
||||
|
||||
Scenario: Team list should be alphabetical by name
|
||||
Given the following teams exist:
|
||||
| name |
|
||||
| Bad |
|
||||
| Car |
|
||||
| Art |
|
||||
| Door |
|
||||
| ear |
|
||||
| apple |
|
||||
And I go to the team list
|
||||
Then the team list should be:
|
||||
| apple |
|
||||
| Art |
|
||||
| Bad |
|
||||
| Car |
|
||||
| Door |
|
||||
| ear |
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
step "show me the page" do
|
||||
save_and_open_page
|
||||
end
|
||||
|
||||
step "I click the link :link_text" do |link_text|
|
||||
page.click_link link_text
|
||||
end
|
||||
|
||||
step "I click the button :button_text" do |button_text|
|
||||
page.click_button button_text
|
||||
end
|
||||
|
||||
step "I fill out the form with :model :field_name :field_value" do |model, field_name, field_value|
|
||||
page.fill_in "#{model}_#{field_name}", :with => field_value
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
FactoryGirl.factories.each do |factory|
|
||||
factory.compile
|
||||
factory.human_names.each do |human_name|
|
||||
step "the following #{human_name} exists:" do |table|
|
||||
table.hashes.each do |human_hash|
|
||||
attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
|
||||
FactoryGirl.create(factory.name, attributes)
|
||||
end
|
||||
end
|
||||
|
||||
step "the following #{human_name.pluralize} exist:" do |table|
|
||||
table.hashes.each do |human_hash|
|
||||
attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
|
||||
FactoryGirl.create(factory.name, attributes)
|
||||
end
|
||||
end
|
||||
|
||||
step "a(n) #{human_name} exists" do
|
||||
FactoryGirl.create(factory.name)
|
||||
end
|
||||
|
||||
step ":count #{human_name.pluralize} exist" do |count|
|
||||
FactoryGirl.create_list(factory.name, count.to_i)
|
||||
end
|
||||
|
||||
if factory.build_class.respond_to?(:columns)
|
||||
factory.build_class.columns.each do |column|
|
||||
name = column.respond_to?(:name) ? column.name : column.to_s
|
||||
human_column_name = name.downcase.gsub('_', ' ')
|
||||
step "a(n) #{human_name} exists with a(n) #{human_column_name} of :value" do |value|
|
||||
FactoryGirl.create(factory.name, name => value)
|
||||
end
|
||||
|
||||
step ":count #{human_name.pluralize} exist with a(n) #{human_column_name} of :value" do |count, value|
|
||||
FactoryGirl.create_list(factory.name, count.to_i, name => value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
step "I login with email :email and password :password" do |email, password|
|
||||
visit new_user_session_path
|
||||
fill_in 'Email', :with => email
|
||||
fill_in 'Password', :with => password
|
||||
click_button 'Sign in'
|
||||
page.should have_content("Signed in successfully.")
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
step "I go to the next page" do
|
||||
page.find('.pagination li.next a').click
|
||||
end
|
||||
@@ -0,0 +1,72 @@
|
||||
step "I go to create a new team" do
|
||||
visit new_team_path
|
||||
end
|
||||
|
||||
step 'I go to the team list' do
|
||||
visit teams_path
|
||||
end
|
||||
|
||||
step "I should see the create a team form" do
|
||||
page.should have_field 'Name'
|
||||
page.should have_field 'Max members', :with => '16'
|
||||
end
|
||||
|
||||
step "I submit the new team form" do
|
||||
page.find('form#new_team').find('input[type=submit]').click
|
||||
end
|
||||
|
||||
step "I fill out the team form with team name :team_name" do |team_name|
|
||||
page.fill_in 'Name', :with => team_name
|
||||
end
|
||||
|
||||
step "I check the box to make my team private" do
|
||||
page.check "Private team?"
|
||||
end
|
||||
|
||||
step 'I should see an error message about the team name' do
|
||||
within 'form#new_team' do
|
||||
page.should have_content "can't be blank"
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see :team_name in the team list' do |team_name|
|
||||
within '.teams' do
|
||||
page.should have_content(team_name)
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see :count teams in the team list' do |count|
|
||||
within '.teams' do
|
||||
page.all('h3.team').count.should == count.to_i
|
||||
end
|
||||
end
|
||||
|
||||
step 'the team list should be:' do |table|
|
||||
within '.teams' do
|
||||
actual = page.all('h3.team').collect { |h3| [h3.text] }
|
||||
table.raw.should == actual
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should have the option of joining the team' do
|
||||
page.should have_button 'Join team'
|
||||
end
|
||||
|
||||
step 'I should not have the option of joining the team' do
|
||||
page.should have_no_button 'Join team'
|
||||
end
|
||||
|
||||
step ':user_email should be in the team member list' do |user_email|
|
||||
user = User.find_by_email(user_email)
|
||||
assert user, "Could not find user by email: #{user_email}"
|
||||
within '.members' do
|
||||
page.should have_content user.to_s
|
||||
end
|
||||
end
|
||||
|
||||
step ':user_email captains the team :team_name' do |user_email, team_name|
|
||||
user = User.find_by_email(user_email)
|
||||
assert user, "Could not find user by email: #{user_email}"
|
||||
FactoryGirl.create(:team, :name => team_name, :captain => user)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
step "a user :email with password :password" do |email, password|
|
||||
FactoryGirl.create(:user, :email => email, :password => password)
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe MapsController do
|
||||
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
FactoryGirl.define do
|
||||
factory :user do
|
||||
sequence(:email) { |n| "user_#{n}@example.com" }
|
||||
password 'password'
|
||||
password_confirmation { password }
|
||||
first_name 'Michael'
|
||||
last_name 'Scott'
|
||||
end
|
||||
|
||||
# factory :team do
|
||||
# sequence(:name) { |n| "mash it #{n} times" }
|
||||
# association :captain, :factory => :user
|
||||
# end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
# Read about factories at https://github.com/thoughtbot/factory_girl
|
||||
|
||||
FactoryGirl.define do
|
||||
factory :map do
|
||||
name "MyString"
|
||||
creator_id ""
|
||||
max_teams ""
|
||||
max_members ""
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe TeamMembership do
|
||||
describe 'membership validations' do
|
||||
let(:team) { create(:team) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
describe 'should require user and team' do
|
||||
it { should have(1).error_on(:user) }
|
||||
it { should have(1).error_on(:team) }
|
||||
end
|
||||
|
||||
it 'should only allow a user to be a member once' do
|
||||
TeamMembership.create(:user => user, :team => team)
|
||||
second = TeamMembership.create(:user => user, :team => team)
|
||||
second.should be_invalid
|
||||
end
|
||||
|
||||
it 'should not allow a captain to become a member' do
|
||||
membership = TeamMembership.create(:user => team.captain, :team => team)
|
||||
membership.should be_invalid
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Team do
|
||||
it 'should have a size of 16 by default' do
|
||||
subject.max_members.should == 16
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { should have(2).error_on(:name) }
|
||||
|
||||
context 'name' do
|
||||
it 'should require atleast 3 characters' do
|
||||
subject.name = 'hi'
|
||||
subject.should have(1).error_on(:name)
|
||||
end
|
||||
it 'should not allow blank' do
|
||||
subject.name = ''
|
||||
subject.should have(2).error_on(:name)
|
||||
end
|
||||
it 'should not allow duplicated' do
|
||||
team = FactoryGirl.create(:team)
|
||||
subject.name = team.name
|
||||
subject.should have(1).error_on(:name)
|
||||
end
|
||||
end
|
||||
|
||||
context 'max_members' do
|
||||
it 'should not let it be 0' do
|
||||
subject.max_members = 0
|
||||
subject.should have(1).error_on(:max_members)
|
||||
end
|
||||
|
||||
it 'should not let it be left empty' do
|
||||
subject.max_members = ''
|
||||
subject.should have(2).error_on(:max_members)
|
||||
end
|
||||
end
|
||||
|
||||
context 'captain' do
|
||||
it 'should require a captain' do
|
||||
subject.should have(1).error_on(:captain)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe User do
|
||||
describe 'validations' do
|
||||
it { should have(1).error_on(:first_name) }
|
||||
it { should have(1).error_on(:last_name) }
|
||||
end
|
||||
|
||||
# describe 'is a member of team' do
|
||||
# let(:user) { create(:user) }
|
||||
# let(:team) { create(:team) }
|
||||
# subject { user.is_a_member_of?(team) }
|
||||
|
||||
# context 'it not a member of the team' do
|
||||
# it { should be_false }
|
||||
# end
|
||||
|
||||
# context 'is a member of the team already' do
|
||||
# before { user.teams << team }
|
||||
# it { should be_true }
|
||||
# end
|
||||
|
||||
# context 'is the captain of the team' do
|
||||
# let(:team) { create(:team, :captain => user) }
|
||||
# it { should be_true }
|
||||
# end
|
||||
# end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe "New User Registrations" do
|
||||
it 'should have a link to sign up on the homepage' do
|
||||
visit root_path
|
||||
page.should have_link 'Register'
|
||||
click_link 'Register'
|
||||
current_path.should == new_user_registration_path
|
||||
end
|
||||
|
||||
context 'registration page' do
|
||||
before do
|
||||
visit new_user_registration_path
|
||||
end
|
||||
it 'should have the additional user fields on the registration page' do
|
||||
page.should have_field 'First name'
|
||||
page.should have_field 'Last name'
|
||||
page.should have_field 'Nickname'
|
||||
page.should have_field 'Email'
|
||||
page.should have_field 'Password'
|
||||
page.should have_field 'Password confirmation'
|
||||
page.should have_button 'Sign up'
|
||||
end
|
||||
|
||||
context 'required non-devise fields' do
|
||||
before do
|
||||
fill_in 'Email', :with => 'FF@example.com'
|
||||
fill_in 'Password', :with => 'password'
|
||||
fill_in 'Password confirmation', :with => 'password'
|
||||
end
|
||||
|
||||
it 'should require first name' do
|
||||
fill_in 'Last name', :with => 'Footer'
|
||||
click_button 'Sign up'
|
||||
page.should have_content "First name can't be blank"
|
||||
end
|
||||
|
||||
it 'should require last name' do
|
||||
fill_in 'First name', :with => 'Frank'
|
||||
click_button 'Sign up'
|
||||
page.should have_content "Last name can't be blank"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
require 'rubygems'
|
||||
require 'spork'
|
||||
require 'rails'
|
||||
#uncomment the following line to use spork with the debugger
|
||||
#require 'spork/ext/ruby-debug'
|
||||
|
||||
Spork.prefork do
|
||||
# Loading more in this block will cause your tests to run faster. However,
|
||||
# if you change any configuration or code from libraries loaded here, you'll
|
||||
# need to restart spork for it take effect.
|
||||
|
||||
#Needed for Devise gem. Delay loading of loading of User model in routes.rb
|
||||
Spork.trap_method(Rails::Application::RoutesReloader, :reload!)
|
||||
|
||||
|
||||
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
||||
ENV["RAILS_ENV"] ||= 'test'
|
||||
require File.expand_path("../../config/environment", __FILE__)
|
||||
require 'rspec/rails'
|
||||
require 'rspec/autorun'
|
||||
require 'capybara/rspec'
|
||||
require 'turnip/capybara'
|
||||
|
||||
# Requires supporting ruby files with custom matchers and macros, etc,
|
||||
# in spec/support/ and its subdirectories.
|
||||
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
||||
|
||||
RSpec.configure do |config|
|
||||
# ## Mock Framework
|
||||
#
|
||||
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
||||
#
|
||||
# config.mock_with :mocha
|
||||
# config.mock_with :flexmock
|
||||
# config.mock_with :rr
|
||||
|
||||
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
||||
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
||||
|
||||
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
||||
# examples within a transaction, remove the following line or assign false
|
||||
# instead of true.
|
||||
config.use_transactional_fixtures = false
|
||||
|
||||
config.before(:suite) do
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
DatabaseCleaner.clean_with :truncation
|
||||
end
|
||||
|
||||
config.before(:each) do
|
||||
if Capybara.current_driver == Capybara.javascript_driver
|
||||
DatabaseCleaner.strategy = :truncation
|
||||
else
|
||||
DatabaseCleaner.strategy = :transaction
|
||||
end
|
||||
DatabaseCleaner.start
|
||||
end
|
||||
|
||||
config.after(:each) do
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
# If true, the base class of anonymous controllers will be inferred
|
||||
# automatically. This will be the default behavior in future versions of
|
||||
# rspec-rails.
|
||||
config.infer_base_class_for_anonymous_controllers = false
|
||||
config.include FactoryGirlStepHelpers
|
||||
config.include FactoryGirl::Syntax::Methods
|
||||
|
||||
#allows :focus tag to only run specific tests
|
||||
config.treat_symbols_as_metadata_keys_with_true_values = true
|
||||
config.filter_run :focus => true
|
||||
config.run_all_when_everything_filtered = true
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Spork.each_run do
|
||||
# This code will be run each time you run your specs.
|
||||
|
||||
#Reload Factories
|
||||
#FYI make sure that Factories use strings instead of class constants
|
||||
FactoryGirl.reload
|
||||
end
|
||||
|
||||
# --- Instructions ---
|
||||
# Sort the contents of this file into a Spork.prefork and a Spork.each_run
|
||||
# block.
|
||||
#
|
||||
# The Spork.prefork block is run only once when the spork server is started.
|
||||
# You typically want to place most of your (slow) initializer code in here, in
|
||||
# particular, require'ing any 3rd-party gems that you don't normally modify
|
||||
# during development.
|
||||
#
|
||||
# The Spork.each_run block is run each time you run your specs. In case you
|
||||
# need to load files that tend to change during development, require them here.
|
||||
# With Rails, your application modules are loaded automatically, so sometimes
|
||||
# this block can remain empty.
|
||||
#
|
||||
# Note: You can modify files loaded *from* the Spork.each_run block without
|
||||
# restarting the spork server. However, this file itself will not be reloaded,
|
||||
# so if you change any of the code inside the each_run block, you still need to
|
||||
# restart the server. In general, if you have non-trivial code in this file,
|
||||
# it's advisable to move it into a separate file so you can easily edit it
|
||||
# without restarting spork. (For example, with RSpec, you could move
|
||||
# non-trivial code into a file spec/support/my_helper.rb, making sure that the
|
||||
# spec/support/* files are require'd from inside the each_run block.)
|
||||
#
|
||||
# Any code that is left outside the two blocks will be run during preforking
|
||||
# *and* during each_run -- that's probably not what you want.
|
||||
#
|
||||
# These instructions should self-destruct in 10 seconds. If they don't, feel
|
||||
# free to delete them.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
module FactoryGirlStepHelpers
|
||||
def convert_human_hash_to_attribute_hash(human_hash, associations = [])
|
||||
HumanHashToAttributeHash.new(human_hash, associations).attributes
|
||||
end
|
||||
|
||||
class HumanHashToAttributeHash
|
||||
attr_reader :associations
|
||||
|
||||
def initialize(human_hash, associations)
|
||||
@human_hash = human_hash
|
||||
@associations = associations
|
||||
end
|
||||
|
||||
def attributes(strategy = CreateAttributes)
|
||||
@human_hash.inject({}) do |attribute_hash, (human_key, value)|
|
||||
attributes = strategy.new(self, *process_key_value(human_key, value))
|
||||
attribute_hash.merge({ attributes.key => attributes.value })
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_key_value(key, value)
|
||||
value = value.strip if value.is_a?(String)
|
||||
[key.downcase.gsub(' ', '_').to_sym, value]
|
||||
end
|
||||
|
||||
class AssociationManager
|
||||
def initialize(human_hash_to_attributes_hash, key, value)
|
||||
@human_hash_to_attributes_hash = human_hash_to_attributes_hash
|
||||
@key = key
|
||||
@value = value
|
||||
end
|
||||
|
||||
def association
|
||||
@human_hash_to_attributes_hash.associations.detect {|association| association.name == @key }
|
||||
end
|
||||
|
||||
def association_instance
|
||||
return unless association
|
||||
|
||||
if attributes_hash = nested_attribute_hash
|
||||
factory.build_class.first(:conditions => attributes_hash.attributes(FindAttributes)) or
|
||||
FactoryGirl.create(association.factory, attributes_hash.attributes)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory
|
||||
FactoryGirl.factory_by_name(association.factory)
|
||||
end
|
||||
|
||||
def nested_attribute_hash
|
||||
attribute, value = @value.split(':', 2)
|
||||
return if value.blank?
|
||||
|
||||
HumanHashToAttributeHash.new({ attribute => value }, factory.associations)
|
||||
end
|
||||
end
|
||||
|
||||
class AttributeStrategy
|
||||
attr_reader :key, :value, :association_manager
|
||||
|
||||
def initialize(human_hash_to_attributes_hash, key, value)
|
||||
@association_manager = AssociationManager.new(human_hash_to_attributes_hash, key, value)
|
||||
@key = key
|
||||
@value = value
|
||||
end
|
||||
end
|
||||
|
||||
class FindAttributes < AttributeStrategy
|
||||
def initialize(human_hash_to_attributes_hash, key, value)
|
||||
super
|
||||
|
||||
if association_manager.association
|
||||
@key = "#{@key}_id"
|
||||
@value = association_manager.association_instance.try(:id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class CreateAttributes < AttributeStrategy
|
||||
def initialize(human_hash_to_attributes_hash, key, value)
|
||||
super
|
||||
|
||||
if association_manager.association
|
||||
@value = association_manager.association_instance
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user