From 639293e4ca8083ab15dc7a9324c59dcfbcc3f927 Mon Sep 17 00:00:00 2001 From: Thibault Jouan Date: Tue, 13 Sep 2011 23:47:59 +0000 Subject: [PATCH] Replace cucumber features by rails integration specs --- Gemfile | 1 - Gemfile.lock | 15 -- config/cucumber.yml | 8 - config/database.yml.sample | 3 - features/fixtures/test.mp3 | Bin 38444 -> 0 bytes features/home.feature | 22 -- features/playlists.feature | 29 --- features/sessions.feature | 17 -- features/step_definitions/playlists_step.rb | 12 -- features/step_definitions/sessions_step.rb | 35 ---- features/step_definitions/tracks_step.rb | 20 -- features/step_definitions/user_step.rb | 12 -- features/step_definitions/web_steps.rb | 211 -------------------- features/support/env.rb | 52 ----- features/support/paths.rb | 21 -- features/support/selectors.rb | 39 ---- features/tracks.feature | 27 --- features/user.feature | 16 -- lib/tasks/cucumber.rake | 65 ------ script/cucumber | 10 - spec/integration/home_spec.rb | 32 +++ spec/integration/playlists_spec.rb | 41 ++++ spec/integration/tracks_spec.rb | 44 ++++ spec/integration/user_sign_in_spec.rb | 20 ++ spec/integration/user_sign_up_spec.rb | 24 +++ spec/support/user_integration_helpers.rb | 9 + 26 files changed, 170 insertions(+), 615 deletions(-) delete mode 100644 config/cucumber.yml delete mode 100644 features/fixtures/test.mp3 delete mode 100644 features/home.feature delete mode 100644 features/playlists.feature delete mode 100644 features/sessions.feature delete mode 100644 features/step_definitions/playlists_step.rb delete mode 100644 features/step_definitions/sessions_step.rb delete mode 100644 features/step_definitions/tracks_step.rb delete mode 100644 features/step_definitions/user_step.rb delete mode 100644 features/step_definitions/web_steps.rb delete mode 100644 features/support/env.rb delete mode 100644 features/support/paths.rb delete mode 100644 features/support/selectors.rb delete mode 100644 features/tracks.feature delete mode 100644 features/user.feature delete mode 100644 lib/tasks/cucumber.rake delete mode 100755 script/cucumber create mode 100644 spec/integration/home_spec.rb create mode 100644 spec/integration/playlists_spec.rb create mode 100644 spec/integration/tracks_spec.rb create mode 100644 spec/integration/user_sign_in_spec.rb create mode 100644 spec/integration/user_sign_up_spec.rb create mode 100644 spec/support/user_integration_helpers.rb diff --git a/Gemfile b/Gemfile index 051b696..c0a02b2 100644 --- a/Gemfile +++ b/Gemfile @@ -10,7 +10,6 @@ gem 'bcrypt-ruby' group :development, :test do gem 'rspec-rails' - gem 'cucumber-rails' gem 'capybara' gem 'database_cleaner' gem 'factory_girl_rails' diff --git a/Gemfile.lock b/Gemfile.lock index dba9211..295518f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -40,16 +40,6 @@ GEM xpath (~> 0.1.4) childprocess (0.1.9) ffi (~> 1.0.6) - cucumber (1.0.0) - builder (>= 2.1.2) - diff-lcs (>= 1.1.2) - gherkin (~> 2.4.1) - json (>= 1.4.6) - term-ansicolor (>= 1.0.5) - cucumber-rails (1.0.2) - capybara (>= 1.0.0) - cucumber (~> 1.0.0) - nokogiri (>= 1.4.6) database_cleaner (0.6.7) diff-lcs (1.1.2) erubis (2.6.6) @@ -59,8 +49,6 @@ GEM factory_girl (~> 2.0.0) railties (>= 3.0.0) ffi (1.0.9) - gherkin (2.4.1) - json (>= 1.4.6) guard (0.6.3) thor (~> 0.14.6) guard-rspec (0.4.4) @@ -70,7 +58,6 @@ GEM spork (>= 0.8.4) haml (3.1.2) i18n (0.5.0) - json (1.5.3) json_pure (1.5.3) mail (2.2.19) activesupport (>= 2.3.6) @@ -124,7 +111,6 @@ GEM json_pure rubyzip spork (0.9.0.rc9) - term-ansicolor (1.0.5) thor (0.14.6) treetop (1.4.9) polyglot (>= 0.3.1) @@ -138,7 +124,6 @@ PLATFORMS DEPENDENCIES bcrypt-ruby capybara - cucumber-rails database_cleaner factory_girl_rails guard diff --git a/config/cucumber.yml b/config/cucumber.yml deleted file mode 100644 index 19b288d..0000000 --- a/config/cucumber.yml +++ /dev/null @@ -1,8 +0,0 @@ -<% -rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" -rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" -std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip" -%> -default: <%= std_opts %> features -wip: --tags @wip:3 --wip features -rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip diff --git a/config/database.yml.sample b/config/database.yml.sample index fc30582..43edc5a 100644 --- a/config/database.yml.sample +++ b/config/database.yml.sample @@ -15,6 +15,3 @@ test: &test production: <<: *common database: scube_production - -cucumber: - <<: *test diff --git a/features/fixtures/test.mp3 b/features/fixtures/test.mp3 deleted file mode 100644 index 7cdcb1f84f68ab856b884197278ee09c906165a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38444 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 diff --git a/features/home.feature b/features/home.feature deleted file mode 100644 index 36392e2..0000000 --- a/features/home.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Home - - So that I can use scube efficiently - As a listener - I want to access the main features and valuable content from the homepage - - Background: - Given I am signed in - - Scenario: Playlist access - Given a playlist named "Electro" - When I am on the home page - Then I should see "Electro" within "ul>li" - - Scenario: Last tracks added - Given the following tracks: - | name | created_at | - | Mega song 1 | 2011-07-27 19:13:42 | - | Mega song 2 | 2011-07-27 19:58:57 | - When I am on the home page - Then I should see "Mega song 2" within "ul>li:first-child" - And I should see "Mega song 1" within "ul>li:first-child+li" diff --git a/features/playlists.feature b/features/playlists.feature deleted file mode 100644 index daaba2e..0000000 --- a/features/playlists.feature +++ /dev/null @@ -1,29 +0,0 @@ -Feature: Playlists - - So that tracks can be grouped in lists - As a listener - I want to manage some playlists - - Background: - Given I am signed in - - Scenario: List playlists - Given a playlist named "Electro" - And a playlist named "Reggae" - When I am on the playlists page - Then I should see "Electro" and "Reggae" in a list - - Scenario: Create playlist - Given I am on the playlists page - When I follow "Create playlist" - And I fill in "Name" with "Electro" - And I press "Create" - Then I should see "Electro" in the list - - Scenario: Edit playlist - Given a playlist named "Electro" - And I am on the playlists page - When I follow "Electro" - And I fill in "Name" with "Rock" - And I press "Save" - Then I should see "Rock" in the list diff --git a/features/sessions.feature b/features/sessions.feature deleted file mode 100644 index 7e53be0..0000000 --- a/features/sessions.feature +++ /dev/null @@ -1,17 +0,0 @@ -Feature: Session - - So that I can manage my own content - As a listener - I want the application to require a valid authentication - - Scenario: Unauthenticated user - Given I am not signed in - When I go to the home page - Then I should be redirected to the sign in page - - Scenario: User authentication - Given I am not signed in - When I go to the home page - Then I should be redirected to the sign in page - When I submit valid credentials - Then I should be redirected to the home page diff --git a/features/step_definitions/playlists_step.rb b/features/step_definitions/playlists_step.rb deleted file mode 100644 index a7ff567..0000000 --- a/features/step_definitions/playlists_step.rb +++ /dev/null @@ -1,12 +0,0 @@ -Given /^a playlist named "([^"]*)"$/ do |name| - Factory.create(:playlist, :name => name) -end - -Then /^I should see "([^"]*)" and "([^"]*)" in a list$/ do |pl1, pl2| - Then "I should see \"#{pl1}\" within \"ul>li:first-child\"" - Then "I should see \"#{pl2}\" within \"ul>li:first-child+li\"" -end - -Then /^I should see "([^"]*)" in the list$/ do |playlist_name| - Then "I should see \"#{playlist_name}\" within \"ul>li\"" -end diff --git a/features/step_definitions/sessions_step.rb b/features/step_definitions/sessions_step.rb deleted file mode 100644 index 11de1f6..0000000 --- a/features/step_definitions/sessions_step.rb +++ /dev/null @@ -1,35 +0,0 @@ -Given /^I am not signed in$/ do - -end - -Given /^I am signed in$/ do - visit new_session_path - When "I submit valid credentials" -end - -Then /^I should be redirected to the sign in page$/ do - current_path.should == new_session_path -end - -Then /^I should be redirected to the home page$/ do - current_path.should == root_path -end - -When /^I submit valid credentials$/ do - user = Factory.create(:user) - fill_in('Email', :with => user.email) - fill_in('Password', :with => user.password) - click_button('Sign in') -end - -When /^I follow the sign up link$/ do - click_link('Sign up') -end - -When /^I fill in the sign up form$/ do - @user = Factory.build(:user) - fill_in('Email', :with => @user.email) - fill_in('Password', :with => @user.password) - fill_in('Password confirmation', :with => @user.password) - click_button('Sign up') -end diff --git a/features/step_definitions/tracks_step.rb b/features/step_definitions/tracks_step.rb deleted file mode 100644 index 74a3ee6..0000000 --- a/features/step_definitions/tracks_step.rb +++ /dev/null @@ -1,20 +0,0 @@ -Given /^a track named "([^"]*)"$/ do |name| - @track = Factory.create(:track, :name => name) - file = File.new("#{Rails.root}/features/fixtures/test.mp3") - @track.save_with_file(file, 'audio/mpeg') -end - -Given /^the following tracks:$/ do |table| - table.hashes.each do |h| - Factory.create(:track, h) - end -end - -Then /^I should see an audio player$/ do - page.should have_xpath '//audio' -end - -Then /^it should provide an audio stream for "([^"]*)"$/ do |name| - page.should have_xpath "//audio[@src='#{stream_track_path(@track)}']" - visit find('audio')[:src] -end diff --git a/features/step_definitions/user_step.rb b/features/step_definitions/user_step.rb deleted file mode 100644 index 732f722..0000000 --- a/features/step_definitions/user_step.rb +++ /dev/null @@ -1,12 +0,0 @@ -Given /^a user with "([^"]*)" email address exists$/ do |email| - Factory.create(:user, :email => email) -end - -When /^I register with "([^"]*)" email address$/ do |email| - visit new_user_path - user = Factory.build(:user) - fill_in('Email', :with => email) - fill_in('Password', :with => user.password) - fill_in('Password confirmation', :with => user.password) - click_button('Sign up') -end diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb deleted file mode 100644 index 456f5d2..0000000 --- a/features/step_definitions/web_steps.rb +++ /dev/null @@ -1,211 +0,0 @@ -# TL;DR: YOU SHOULD DELETE THIS FILE -# -# This file was generated by Cucumber-Rails and is only here to get you a head start -# These step definitions are thin wrappers around the Capybara/Webrat API that lets you -# visit pages, interact with widgets and make assertions about page content. -# -# If you use these step definitions as basis for your features you will quickly end up -# with features that are: -# -# * Hard to maintain -# * Verbose to read -# -# A much better approach is to write your own higher level step definitions, following -# the advice in the following blog posts: -# -# * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html -# * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/ -# * http://elabs.se/blog/15-you-re-cuking-it-wrong -# - - -require 'uri' -require 'cgi' -require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths")) -require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors")) - -module WithinHelpers - def with_scope(locator) - locator ? within(*selector_for(locator)) { yield } : yield - end -end -World(WithinHelpers) - -# Single-line step scoper -When /^(.*) within (.*[^:])$/ do |step, parent| - with_scope(parent) { When step } -end - -# Multi-line step scoper -When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string| - with_scope(parent) { When "#{step}:", table_or_string } -end - -Given /^(?:|I )am on (.+)$/ do |page_name| - visit path_to(page_name) -end - -When /^(?:|I )go to (.+)$/ do |page_name| - visit path_to(page_name) -end - -When /^(?:|I )press "([^"]*)"$/ do |button| - click_button(button) -end - -When /^(?:|I )follow "([^"]*)"$/ do |link| - click_link(link) -end - -When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value| - fill_in(field, :with => value) -end - -When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field| - fill_in(field, :with => value) -end - -# Use this to fill in an entire form with data from a table. Example: -# -# When I fill in the following: -# | Account Number | 5002 | -# | Expiry date | 2009-11-01 | -# | Note | Nice guy | -# | Wants Email? | | -# -# TODO: Add support for checkbox, select og option -# based on naming conventions. -# -When /^(?:|I )fill in the following:$/ do |fields| - fields.rows_hash.each do |name, value| - When %{I fill in "#{name}" with "#{value}"} - end -end - -When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field| - select(value, :from => field) -end - -When /^(?:|I )check "([^"]*)"$/ do |field| - check(field) -end - -When /^(?:|I )uncheck "([^"]*)"$/ do |field| - uncheck(field) -end - -When /^(?:|I )choose "([^"]*)"$/ do |field| - choose(field) -end - -When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field| - attach_file(field, File.expand_path(path)) -end - -Then /^(?:|I )should see "([^"]*)"$/ do |text| - if page.respond_to? :should - page.should have_content(text) - else - assert page.has_content?(text) - end -end - -Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp| - regexp = Regexp.new(regexp) - - if page.respond_to? :should - page.should have_xpath('//*', :text => regexp) - else - assert page.has_xpath?('//*', :text => regexp) - end -end - -Then /^(?:|I )should not see "([^"]*)"$/ do |text| - if page.respond_to? :should - page.should have_no_content(text) - else - assert page.has_no_content?(text) - end -end - -Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp| - regexp = Regexp.new(regexp) - - if page.respond_to? :should - page.should have_no_xpath('//*', :text => regexp) - else - assert page.has_no_xpath?('//*', :text => regexp) - end -end - -Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value| - with_scope(parent) do - field = find_field(field) - field_value = (field.tag_name == 'textarea') ? field.text : field.value - if field_value.respond_to? :should - field_value.should =~ /#{value}/ - else - assert_match(/#{value}/, field_value) - end - end -end - -Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value| - with_scope(parent) do - field = find_field(field) - field_value = (field.tag_name == 'textarea') ? field.text : field.value - if field_value.respond_to? :should_not - field_value.should_not =~ /#{value}/ - else - assert_no_match(/#{value}/, field_value) - end - end -end - -Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent| - with_scope(parent) do - field_checked = find_field(label)['checked'] - if field_checked.respond_to? :should - field_checked.should be_true - else - assert field_checked - end - end -end - -Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent| - with_scope(parent) do - field_checked = find_field(label)['checked'] - if field_checked.respond_to? :should - field_checked.should be_false - else - assert !field_checked - end - end -end - -Then /^(?:|I )should be on (.+)$/ do |page_name| - current_path = URI.parse(current_url).path - if current_path.respond_to? :should - current_path.should == path_to(page_name) - else - assert_equal path_to(page_name), current_path - end -end - -Then /^(?:|I )should have the following query string:$/ do |expected_pairs| - query = URI.parse(current_url).query - actual_params = query ? CGI.parse(query) : {} - expected_params = {} - expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')} - - if actual_params.respond_to? :should - actual_params.should == expected_params - else - assert_equal expected_params, actual_params - end -end - -Then /^show me the page$/ do - save_and_open_page -end diff --git a/features/support/env.rb b/features/support/env.rb deleted file mode 100644 index 9066d1b..0000000 --- a/features/support/env.rb +++ /dev/null @@ -1,52 +0,0 @@ -# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. -# It is recommended to regenerate this file in the future when you upgrade to a -# newer version of cucumber-rails. Consider adding your own code to a new file -# instead of editing this one. Cucumber will automatically load all features/**/*.rb -# files. - -require 'cucumber/rails' - -# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In -# order to ease the transition to Capybara we set the default here. If you'd -# prefer to use XPath just remove this line and adjust any selectors in your -# steps to use the XPath syntax. -Capybara.default_selector = :css - -# By default, any exception happening in your Rails application will bubble up -# to Cucumber so that your scenario will fail. This is a different from how -# your application behaves in the production environment, where an error page will -# be rendered instead. -# -# Sometimes we want to override this default behaviour and allow Rails to rescue -# exceptions and display an error page (just like when the app is running in production). -# Typical scenarios where you want to do this is when you test your error pages. -# There are two ways to allow Rails to rescue exceptions: -# -# 1) Tag your scenario (or feature) with @allow-rescue -# -# 2) Set the value below to true. Beware that doing this globally is not -# recommended as it will mask a lot of errors for you! -# -ActionController::Base.allow_rescue = false - -# Remove/comment out the lines below if your app doesn't have a database. -# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead. -begin - DatabaseCleaner.strategy = :transaction -rescue NameError - raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." -end - -# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios. -# See the DatabaseCleaner documentation for details. Example: -# -# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do -# DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]} -# end -# -# Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do -# DatabaseCleaner.strategy = :transaction -# end -# - -load "#{Rails.root.to_s}/db/schema.rb" diff --git a/features/support/paths.rb b/features/support/paths.rb deleted file mode 100644 index 6776229..0000000 --- a/features/support/paths.rb +++ /dev/null @@ -1,21 +0,0 @@ -module NavigationHelpers - def path_to(page_name) - case page_name - when /^the home\s?page$/ - '/' - when /^the track page for "([^\"]*)"$/ - track_path Track.find_by_name($1) - else - begin - page_name =~ /^the (.*) page$/ - path_components = $1.split(/\s+/) - self.send(path_components.push('path').join('_').to_sym) - rescue NoMethodError, ArgumentError - raise "Can't find mapping from \"#{page_name}\" to a path.\n" + - "Now, go and add a mapping in #{__FILE__}" - end - end - end -end - -World(NavigationHelpers) diff --git a/features/support/selectors.rb b/features/support/selectors.rb deleted file mode 100644 index 44e34a4..0000000 --- a/features/support/selectors.rb +++ /dev/null @@ -1,39 +0,0 @@ -module HtmlSelectorsHelpers - # Maps a name to a selector. Used primarily by the - # - # When /^(.+) within (.+)$/ do |step, scope| - # - # step definitions in web_steps.rb - # - def selector_for(locator) - case locator - - when "the page" - "html > body" - - # Add more mappings here. - # Here is an example that pulls values out of the Regexp: - # - # when /^the (notice|error|info) flash$/ - # ".flash.#{$1}" - - # You can also return an array to use a different selector - # type, like: - # - # when /the header/ - # [:xpath, "//header"] - - # This allows you to provide a quoted selector as the scope - # for "within" steps as was previously the default for the - # web steps: - when /^"(.+)"$/ - $1 - - else - raise "Can't find mapping from \"#{locator}\" to a selector.\n" + - "Now, go and add a mapping in #{__FILE__}" - end - end -end - -World(HtmlSelectorsHelpers) diff --git a/features/tracks.feature b/features/tracks.feature deleted file mode 100644 index 72642a6..0000000 --- a/features/tracks.feature +++ /dev/null @@ -1,27 +0,0 @@ -Feature: Tracks - - So that I can listen music - As a listener - I want to add, manage and listen some tracks - - Background: - Given I am signed in - - Scenario: Show track - Given a track named "Mega song" - When I go to the track page for "Mega song" - Then I should see "Mega song" within "h1" - - Scenario: Create track - Given I am on the home page - When I follow "Add a track" - And I fill in "Name" with "Mega song" - And I attach the file "features/fixtures/test.mp3" to "File" - And I press "Upload" - Then I should see "Mega song" within "h1" - - Scenario: Listen track - Given a track named "Mega song" - When I go to the track page for "Mega song" - Then I should see an audio player - And it should provide an audio stream for "Mega song" diff --git a/features/user.feature b/features/user.feature deleted file mode 100644 index f69edd0..0000000 --- a/features/user.feature +++ /dev/null @@ -1,16 +0,0 @@ -Feature: User - - So that I can use the application - As a visitor - I want to register - - Scenario: User registration - Given I go to the home page - When I follow the sign up link - And I fill in the sign up form - Then I should be redirected to the home page - - Scenario: User can't register twice with the same email address - Given a user with "unique@example.net" email address exists - When I register with "unique@example.net" email address - Then I should see "Email has already been taken" diff --git a/lib/tasks/cucumber.rake b/lib/tasks/cucumber.rake deleted file mode 100644 index 83f7947..0000000 --- a/lib/tasks/cucumber.rake +++ /dev/null @@ -1,65 +0,0 @@ -# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. -# It is recommended to regenerate this file in the future when you upgrade to a -# newer version of cucumber-rails. Consider adding your own code to a new file -# instead of editing this one. Cucumber will automatically load all features/**/*.rb -# files. - - -unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks - -vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first -$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil? - -begin - require 'cucumber/rake/task' - - namespace :cucumber do - Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t| - t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. - t.fork = true # You may get faster startup if you set this to false - t.profile = 'default' - end - - Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t| - t.binary = vendored_cucumber_bin - t.fork = true # You may get faster startup if you set this to false - t.profile = 'wip' - end - - Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t| - t.binary = vendored_cucumber_bin - t.fork = true # You may get faster startup if you set this to false - t.profile = 'rerun' - end - - desc 'Run all features' - task :all => [:ok, :wip] - - task :statsetup do - require 'rails/code_statistics' - ::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features') - ::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features') - end - end - desc 'Alias for cucumber:ok' - task :cucumber => 'cucumber:ok' - - task :default => :cucumber - - task :features => :cucumber do - STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***" - end - - # In case we don't have ActiveRecord, append a no-op task that we can depend upon. - task 'db:test:prepare' do - end - - task :stats => 'cucumber:statsetup' -rescue LoadError - desc 'cucumber rake task not available (cucumber not installed)' - task :cucumber do - abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' - end -end - -end diff --git a/script/cucumber b/script/cucumber deleted file mode 100755 index 7fa5c92..0000000 --- a/script/cucumber +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env ruby - -vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first -if vendored_cucumber_bin - load File.expand_path(vendored_cucumber_bin) -else - require 'rubygems' unless ENV['NO_RUBYGEMS'] - require 'cucumber' - load Cucumber::BINARY -end diff --git a/spec/integration/home_spec.rb b/spec/integration/home_spec.rb new file mode 100644 index 0000000..70a741f --- /dev/null +++ b/spec/integration/home_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +feature 'Home page' do + include UserIntegrationHelpers + + background do + sign_in + end + + scenario 'displays playlists' do + playlist = Factory.create(:playlist, :name => 'Electro') + + visit root_path + + page.should have_content('Electro') + end + + scenario 'displays last track added' do + Factory.create(:track, + :name => 'Mega song 1', + :created_at => '2011-07-27 19:13:42' + ) + Factory.create(:track, + :name => 'Mega song 2', + :created_at => '2011-07-27 19:58:57' + ) + + visit root_path + + page.body.should match(/Mega song 2.+Mega song 1/m) + end +end diff --git a/spec/integration/playlists_spec.rb b/spec/integration/playlists_spec.rb new file mode 100644 index 0000000..b4fee6b --- /dev/null +++ b/spec/integration/playlists_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +feature 'Playlists' do + include UserIntegrationHelpers + + background do + sign_in + end + + scenario 'lists playlists' do + Factory.create(:playlist, :name => 'Electro') + Factory.create(:playlist, :name => 'Reggae') + + visit playlists_path + + page.body.should match(/Electro.+Reggae/m) + end + + scenario 'creates playlist' do + visit playlists_path + + click_link 'Create playlist' + fill_in 'Name', :with => 'Electro' + click_button 'Create' + + current_path.should == playlists_path + page.should have_content('Electro') + end + + scenario 'edits playlist' do + Factory.create(:playlist, :name => 'Electro') + visit playlists_path + + click_link 'Electro' + fill_in 'Name', :with => 'Rock' + click_button 'Save' + + current_path.should == playlists_path + page.should have_content('Rock') + end +end diff --git a/spec/integration/tracks_spec.rb b/spec/integration/tracks_spec.rb new file mode 100644 index 0000000..f01779f --- /dev/null +++ b/spec/integration/tracks_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' + +feature 'Tracks' do + include UserIntegrationHelpers + + background do + sign_in + end + + scenario 'shows track' do + track = Factory.create(:track, :name => 'Mega song') + + visit track_path(track) + + page.should have_content('Mega song') + end + + scenario 'creates track' do + visit root_path + + click_link 'Add a track' + fill_in 'Name', :with => 'Mega song' + attach_file 'File', File.expand_path('spec/fixtures/test.mp3') + click_button 'Upload' + + current_path.should == track_path(Track.find(:first)) + page.should have_content('Mega song') + end + + scenario 'plays track' do + track = Factory.create(:track, :name => 'Mega song') + file = File.new("#{Rails.root}/spec/fixtures/test.mp3") + track.save_with_file(file, 'audio/mpeg') + + visit track_path(track) + + page.should have_xpath "//audio[@src='#{stream_track_path(track)}']" + visit find('audio')[:src] + end + + after do + `rm -f #{Rails.root}/data/tracks/*` + end +end diff --git a/spec/integration/user_sign_in_spec.rb b/spec/integration/user_sign_in_spec.rb new file mode 100644 index 0000000..badb00c --- /dev/null +++ b/spec/integration/user_sign_in_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +feature 'User sign in' do + scenario 'redirects to the home page when not signed in' do + visit root_path + + current_path.should == new_session_path + end + + scenario 'signs the user in' do + user = Factory.create(:user) + + visit new_session_path + fill_in 'Email', :with => user.email + fill_in 'Password', :with => user.password + click_button 'Sign in' + + current_path.should == root_path + end +end diff --git a/spec/integration/user_sign_up_spec.rb b/spec/integration/user_sign_up_spec.rb new file mode 100644 index 0000000..c32287d --- /dev/null +++ b/spec/integration/user_sign_up_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +feature 'User sign up' do + let(:user) { Factory.build(:user) } + + background do + visit new_user_path + fill_in 'Email', :with => user.email + fill_in 'Password', :with => user.password + fill_in 'Password confirmation', :with => user.password + end + + scenario 'creates the user' do + expect { + click_button 'Sign up' + }.to change(User, :count).by(1) + end + + scenario 'redirects to the home page' do + click_button 'Sign up' + + current_path.should == root_path + end +end diff --git a/spec/support/user_integration_helpers.rb b/spec/support/user_integration_helpers.rb new file mode 100644 index 0000000..d543934 --- /dev/null +++ b/spec/support/user_integration_helpers.rb @@ -0,0 +1,9 @@ +module UserIntegrationHelpers + def sign_in + user = Factory.create(:user) + visit new_session_path + fill_in 'Email', :with => user.email + fill_in 'Password', :with => user.password + click_button('Sign in') + end +end