diff --git a/.gitignore b/.gitignore index f0fa30c..923b697 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ db/*.sqlite3 log/*.log tmp/ +.sass-cache/ diff --git a/Gemfile b/Gemfile index e7241f1..2693995 100644 --- a/Gemfile +++ b/Gemfile @@ -7,10 +7,12 @@ gem "bundler" gem "carrierwave" gem "carrierwave-mongoid", require: "carrierwave/mongoid" gem "decent_exposure" -gem "haml" +gem "haml-rails" gem "jquery-rails" -gem "mongoid", git: "git://github.com/mongoid/mongoid.git" +gem "mongoid" gem "unicorn" +gem "simple_form" +gem "inherited_resources" group :assets do gem "sass-rails", "~> 3.1" @@ -25,3 +27,9 @@ group :development, :test do gem "spork", "~> 0.9.0.rc" gem "watchr" end + +group :test do + gem "database_cleaner" + gem "capybara" + gem "launchy" +end diff --git a/Gemfile.lock b/Gemfile.lock index 72d0472..ab48804 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,86 +1,105 @@ -GIT - remote: git://github.com/mongoid/mongoid.git - revision: f475489dd50c68b82570f3dafd4b1af8e9dc153a - specs: - mongoid (2.4.0) - activemodel (~> 3.1) - mongo (~> 1.4) - tzinfo (~> 0.3.22) - GEM remote: http://rubygems.org/ specs: - actionmailer (3.1.1) - actionpack (= 3.1.1) + actionmailer (3.1.3) + actionpack (= 3.1.3) mail (~> 2.3.0) - actionpack (3.1.1) - activemodel (= 3.1.1) - activesupport (= 3.1.1) + actionpack (3.1.3) + activemodel (= 3.1.3) + activesupport (= 3.1.3) builder (~> 3.0.0) erubis (~> 2.7.0) i18n (~> 0.6) - rack (~> 1.3.2) + rack (~> 1.3.5) rack-cache (~> 1.1) rack-mount (~> 0.8.2) rack-test (~> 0.6.1) - sprockets (~> 2.0.2) - activemodel (3.1.1) - activesupport (= 3.1.1) + sprockets (~> 2.0.3) + activemodel (3.1.3) + activesupport (= 3.1.3) builder (~> 3.0.0) i18n (~> 0.6) - activerecord (3.1.1) - activemodel (= 3.1.1) - activesupport (= 3.1.1) + activerecord (3.1.3) + activemodel (= 3.1.3) + activesupport (= 3.1.3) arel (~> 2.2.1) tzinfo (~> 0.3.29) - activeresource (3.1.1) - activemodel (= 3.1.1) - activesupport (= 3.1.1) - activesupport (3.1.1) + activeresource (3.1.3) + activemodel (= 3.1.3) + activesupport (= 3.1.3) + activesupport (3.1.3) multi_json (~> 1.0) + addressable (2.2.6) arel (2.2.1) - bson (1.4.0) - bson_ext (1.4.0) + bson (1.5.0) + bson_ext (1.5.0) builder (3.0.0) - carrierwave (0.5.7) + capybara (1.1.2) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (~> 2.0) + xpath (~> 0.1.4) + carrierwave (0.5.8) activesupport (~> 3.0) carrierwave-mongoid (0.1.3) carrierwave (>= 0.5.6) mongoid (~> 2.1) + childprocess (0.2.3) + ffi (~> 1.0.6) coffee-rails (3.1.1) coffee-script (>= 2.2.0) railties (~> 3.1.0) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.1.2) + coffee-script-source (1.1.3) + database_cleaner (0.7.0) decent_exposure (1.0.1) diff-lcs (1.1.3) erubis (2.7.0) execjs (1.2.9) multi_json (~> 1.0) fabrication (1.2.0) - haml (3.1.3) + ffi (1.0.11) + haml (3.1.4) + haml-rails (0.3.4) + actionpack (~> 3.0) + activesupport (~> 3.0) + haml (~> 3.0) + railties (~> 3.0) + has_scope (0.5.1) hike (1.2.1) i18n (0.6.0) - jquery-rails (1.0.16) + inherited_resources (1.3.0) + has_scope (~> 0.5.0) + responders (~> 0.6.0) + jquery-rails (1.0.19) railties (~> 3.0) thor (~> 0.14) - json (1.6.1) + json (1.6.2) kgio (2.6.0) + launchy (2.0.5) + addressable (~> 2.2.6) mail (2.3.0) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) metaclass (0.0.1) - mime-types (1.16) + mime-types (1.17.2) mocha (0.10.0) metaclass (~> 0.0.1) - mongo (1.4.0) - bson (= 1.4.0) - multi_json (1.0.3) - polyglot (0.3.2) - rack (1.3.4) + mongo (1.5.0) + bson (= 1.5.0) + mongoid (2.3.4) + activemodel (~> 3.1) + mongo (~> 1.3) + tzinfo (~> 0.3.22) + multi_json (1.0.4) + nokogiri (1.5.0) + polyglot (0.3.3) + rack (1.3.5) rack-cache (1.1) rack (>= 0.4) rack-mount (0.8.3) @@ -89,47 +108,56 @@ GEM rack rack-test (0.6.1) rack (>= 1.0) - rails (3.1.1) - actionmailer (= 3.1.1) - actionpack (= 3.1.1) - activerecord (= 3.1.1) - activeresource (= 3.1.1) - activesupport (= 3.1.1) + rails (3.1.3) + actionmailer (= 3.1.3) + actionpack (= 3.1.3) + activerecord (= 3.1.3) + activeresource (= 3.1.3) + activesupport (= 3.1.3) bundler (~> 1.0) - railties (= 3.1.1) - railties (3.1.1) - actionpack (= 3.1.1) - activesupport (= 3.1.1) + railties (= 3.1.3) + railties (3.1.3) + actionpack (= 3.1.3) + activesupport (= 3.1.3) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (~> 0.14.6) raindrops (0.8.0) - rake (0.9.2) - rdoc (3.10) + rake (0.9.2.2) + rdoc (3.11) json (~> 1.4) - rspec (2.6.0) - rspec-core (~> 2.6.0) - rspec-expectations (~> 2.6.0) - rspec-mocks (~> 2.6.0) - rspec-core (2.6.4) - rspec-expectations (2.6.0) + responders (0.6.4) + rspec (2.7.0) + rspec-core (~> 2.7.0) + rspec-expectations (~> 2.7.0) + rspec-mocks (~> 2.7.0) + rspec-core (2.7.1) + rspec-expectations (2.7.0) diff-lcs (~> 1.1.2) - rspec-mocks (2.6.0) - rspec-rails (2.6.1) + rspec-mocks (2.7.0) + rspec-rails (2.7.0) actionpack (~> 3.0) activesupport (~> 3.0) railties (~> 3.0) - rspec (~> 2.6.0) - sass (3.1.10) - sass-rails (3.1.4) + rspec (~> 2.7.0) + rubyzip (0.9.5) + sass (3.1.11) + sass-rails (3.1.5) actionpack (~> 3.1.0) railties (~> 3.1.0) - sass (>= 3.1.4) - sprockets (~> 2.0.0) + sass (~> 3.1.10) tilt (~> 1.3.2) + selenium-webdriver (2.14.0) + childprocess (>= 0.2.1) + ffi (~> 1.0.9) + multi_json (~> 1.0.4) + rubyzip + simple_form (1.5.2) + actionpack (~> 3.0) + activemodel (~> 3.0) spork (0.9.0.rc9) - sprockets (2.0.2) + sprockets (2.0.3) hike (~> 1.2) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) @@ -138,8 +166,8 @@ GEM treetop (1.4.10) polyglot polyglot (>= 0.3.1) - tzinfo (0.3.30) - uglifier (1.0.3) + tzinfo (0.3.31) + uglifier (1.1.0) execjs (>= 0.3.0) multi_json (>= 1.0.2) unicorn (4.1.1) @@ -147,6 +175,8 @@ GEM rack raindrops (~> 0.6) watchr (0.7) + xpath (0.1.4) + nokogiri (~> 1.3) PLATFORMS ruby @@ -154,18 +184,23 @@ PLATFORMS DEPENDENCIES bson_ext bundler + capybara carrierwave carrierwave-mongoid coffee-rails (~> 3.1) + database_cleaner decent_exposure fabrication - haml + haml-rails + inherited_resources jquery-rails + launchy mocha - mongoid! + mongoid rails (~> 3.1) rspec-rails sass-rails (~> 3.1) + simple_form spork (~> 0.9.0.rc) uglifier unicorn diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js new file mode 100644 index 0000000..e7fc432 --- /dev/null +++ b/app/assets/javascripts/application.js @@ -0,0 +1,4 @@ +//= require jquery +//= require jquery_ujs +//= require_self +//= require_tree . diff --git a/app/assets/javascripts/start.js b/app/assets/javascripts/start.js deleted file mode 100644 index dee720f..0000000 --- a/app/assets/javascripts/start.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place all the behaviors and hooks related to the matching controller here. -// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss new file mode 100644 index 0000000..4a80ac2 --- /dev/null +++ b/app/assets/stylesheets/application.css.scss @@ -0,0 +1,4 @@ +/* + = require_self + = require_tree . +*/ diff --git a/app/assets/stylesheets/start.css.scss b/app/assets/stylesheets/start.css.scss deleted file mode 100644 index ba95e21..0000000 --- a/app/assets/stylesheets/start.css.scss +++ /dev/null @@ -1,5 +0,0 @@ -/* - Place all the styles related to the matching controller here. - They will automatically be included in application.css. - You can use Sass (SCSS) here: http://sass-lang.com/ -*/ diff --git a/app/controllers/bands_controller.rb b/app/controllers/bands_controller.rb new file mode 100644 index 0000000..81d2fb0 --- /dev/null +++ b/app/controllers/bands_controller.rb @@ -0,0 +1,2 @@ +class BandsController < InheritedResources::Base +end diff --git a/app/controllers/shows_controller.rb b/app/controllers/shows_controller.rb new file mode 100644 index 0000000..551afc2 --- /dev/null +++ b/app/controllers/shows_controller.rb @@ -0,0 +1,3 @@ +class ShowsController < InheritedResources::Base + nested_belongs_to :band, :tour +end diff --git a/app/controllers/tours_controller.rb b/app/controllers/tours_controller.rb new file mode 100644 index 0000000..b62ece8 --- /dev/null +++ b/app/controllers/tours_controller.rb @@ -0,0 +1,3 @@ +class ToursController < InheritedResources::Base + belongs_to :band +end diff --git a/app/models/show.rb b/app/models/show.rb index 8a5f130..c5166a0 100644 --- a/app/models/show.rb +++ b/app/models/show.rb @@ -6,6 +6,7 @@ class Show embedded_in :tour embeds_one :venue, validate: false + accepts_nested_attributes_for :venue # Shows must be on a specific date, which includes a time. validates :date, presence: true diff --git a/app/views/bands/_form.html.haml b/app/views/bands/_form.html.haml new file mode 100644 index 0000000..4f6db47 --- /dev/null +++ b/app/views/bands/_form.html.haml @@ -0,0 +1,13 @@ += simple_form_for(@band) do |f| + = f.error_notification + + .inputs + = f.input :name + + = f.input :description + = f.input :formed_on + = f.input :location + = f.input :website + + .actions + = f.button :submit diff --git a/app/views/bands/edit.html.haml b/app/views/bands/edit.html.haml new file mode 100644 index 0000000..c787401 --- /dev/null +++ b/app/views/bands/edit.html.haml @@ -0,0 +1,8 @@ +- content_for(:title) do + Editing band + += render 'form' + += link_to 'Show', @band +\| += link_to 'Back', bands_path diff --git a/app/views/bands/index.html.haml b/app/views/bands/index.html.haml new file mode 100644 index 0000000..a74beab --- /dev/null +++ b/app/views/bands/index.html.haml @@ -0,0 +1,22 @@ +- content_for(:title) do + Listing bands + +%table + %tr + %th Name + %th Location + %th + %th + %th + + - @bands.each do |band| + %tr + %td= link_to band.name, band + %td= band.location + %td= link_to 'Show', band + %td= link_to 'Edit', edit_band_path(band) + %td= link_to 'Destroy', band, :confirm => 'Are you sure?', :method => :delete + +%br + += link_to 'New Band', new_band_path diff --git a/app/views/bands/new.html.haml b/app/views/bands/new.html.haml new file mode 100644 index 0000000..3735c38 --- /dev/null +++ b/app/views/bands/new.html.haml @@ -0,0 +1,6 @@ +- content_for(:title) do + New band + += render 'form' + += link_to 'Back', bands_path diff --git a/app/views/bands/show.html.haml b/app/views/bands/show.html.haml new file mode 100644 index 0000000..e99c4e1 --- /dev/null +++ b/app/views/bands/show.html.haml @@ -0,0 +1,19 @@ +- content_for(:title) do + Show #{@band.name} + +%p#notice= notice + +.bio + %h2 Bio + %p.description #{@band.description} + %p.formed_on Formed on #{@band.formed_on}. + %p.location Located in #{@band.location}. + %p.website Visit #{link_to @band.website, @band.website}. + +.tours + %h2 Tours + = link_to "Tours", band_tours_path(@band) + += link_to 'Edit', edit_band_path(@band) +\| += link_to 'Back', bands_path diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 7360f48..7f13986 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -3,4 +3,9 @@ %head %title = yield(:title) + = stylesheet_link_tag 'application' + = javascript_include_tag 'application' + = csrf_meta_tag %body + %h1= yield(:title) + = yield \ No newline at end of file diff --git a/app/views/shows/_form.html.haml b/app/views/shows/_form.html.haml new file mode 100644 index 0000000..258eee0 --- /dev/null +++ b/app/views/shows/_form.html.haml @@ -0,0 +1,18 @@ += simple_form_for([@band, @tour, @show]) do |f| + = f.error_notification + + .inputs + = f.input :date + = field_set_tag "Venue" do + = f.simple_fields_for :venue, @show.venue || Venue.new do |venue| + = venue.input :name + = venue.simple_fields_for :address, (@show.venue && @show.venue.address) || Address.new do |address| + = address.input :extra + = address.input :street + = address.input :postcode + = address.input :city + = address.input :state + = address.input :country, as: :string + + .actions + = f.button :submit diff --git a/app/views/shows/edit.html.haml b/app/views/shows/edit.html.haml new file mode 100644 index 0000000..0734b08 --- /dev/null +++ b/app/views/shows/edit.html.haml @@ -0,0 +1,8 @@ +- content_for(:title) do + Editing show + += render 'form' + += link_to 'Show', [@band, @tour, @show] +\| += link_to 'Back', band_tour_shows_path(@band, @tour) diff --git a/app/views/shows/index.html.haml b/app/views/shows/index.html.haml new file mode 100644 index 0000000..b718814 --- /dev/null +++ b/app/views/shows/index.html.haml @@ -0,0 +1,22 @@ +- content_for(:title) do + Listing shows + +%table + %tr + %th Date + %th Venue + %th City + %th + %th + + - @shows.each do |show| + %tr + %td= link_to show.date, [@band, @tour, show] + %td= show.venue.name + %td= show.venue.address.city + %td= link_to 'Edit', edit_band_tour_show_path(@band, @tour, show) + %td= link_to 'Destroy', [@band, @tour, show], :confirm => 'Are you sure?', :method => :delete + +%br + += link_to 'New Show', new_band_tour_show_path(@band, @tour) diff --git a/app/views/shows/new.html.haml b/app/views/shows/new.html.haml new file mode 100644 index 0000000..dd02474 --- /dev/null +++ b/app/views/shows/new.html.haml @@ -0,0 +1,6 @@ +- content_for(:title) do + New show + += render 'form' + += link_to 'Back', band_tour_shows_path(@band, @tour) diff --git a/app/views/shows/show.html.haml b/app/views/shows/show.html.haml new file mode 100644 index 0000000..089b679 --- /dev/null +++ b/app/views/shows/show.html.haml @@ -0,0 +1,25 @@ +- content_for(:title) do + Show on #{@show.date} of #{@show.tour.name} + +%p#notice= notice + +.venue + %h2 Venue + %p Name: #{@show.venue.name} + + .address{itemscope: true, itemtype: "http://data-vocabulary.org/Address"} + %h3 Address + %span #{@show.venue.address.extra} + %br + %span{itemprop: "street-address"} #{@show.venue.address.street} + %br + %span{itemprop: "postal-code"} #{@show.venue.address.postcode} + %span{itemprop: "locality"} #{@show.venue.address.city} + %br + %span{itemprop: "region"} #{@show.venue.address.state} + %br + %span{itemprop: "country-name"} #{@show.venue.address.country} + += link_to 'Edit', edit_band_tour_show_path(@band, @tour, @show) +\| += link_to 'Back', band_tour_shows_path(@band, @tour) diff --git a/app/views/start/index.html.haml b/app/views/start/index.html.haml index fa944db..1e4c6fd 100644 --- a/app/views/start/index.html.haml +++ b/app/views/start/index.html.haml @@ -1,2 +1,4 @@ - content_for(:title) do Echo: #{t("echo.start.title")} + += link_to 'Bands', bands_path diff --git a/app/views/tours/_form.html.haml b/app/views/tours/_form.html.haml new file mode 100644 index 0000000..33972bf --- /dev/null +++ b/app/views/tours/_form.html.haml @@ -0,0 +1,8 @@ += simple_form_for([@band, @tour]) do |f| + = f.error_notification + + .inputs + = f.input :name + + .actions + = f.button :submit diff --git a/app/views/tours/edit.html.haml b/app/views/tours/edit.html.haml new file mode 100644 index 0000000..c57e9f4 --- /dev/null +++ b/app/views/tours/edit.html.haml @@ -0,0 +1,8 @@ +- content_for(:title) do + Editing tour + += render 'form' + += link_to 'Show', [@band, @tour] +\| += link_to 'Back', band_tours_path(@band) diff --git a/app/views/tours/index.html.haml b/app/views/tours/index.html.haml new file mode 100644 index 0000000..4233ffb --- /dev/null +++ b/app/views/tours/index.html.haml @@ -0,0 +1,18 @@ +- content_for(:title) do + Listing tours of #{@band.name} + +%table + %tr + %th Name + %th + %th + + - @tours.each do |tour| + %tr + %td= link_to tour.name, [@band, tour] + %td= link_to 'Edit', edit_band_tour_path(@band, tour) + %td= link_to 'Destroy', [@band, tour], :confirm => 'Are you sure?', :method => :delete + +%br + += link_to 'New Tour', new_band_tour_path(@band) diff --git a/app/views/tours/new.html.haml b/app/views/tours/new.html.haml new file mode 100644 index 0000000..2068f9a --- /dev/null +++ b/app/views/tours/new.html.haml @@ -0,0 +1,6 @@ +- content_for(:title) do + New tour + += render 'form' + += link_to 'Back', band_tours_path(@band) diff --git a/app/views/tours/show.html.haml b/app/views/tours/show.html.haml new file mode 100644 index 0000000..c8ae801 --- /dev/null +++ b/app/views/tours/show.html.haml @@ -0,0 +1,12 @@ +- content_for(:title) do + Show #{@tour.name} + +%p#notice= notice + +.shows + %h2 Shows + = link_to "Shows", band_tour_shows_path(@band, @tour) + += link_to 'Edit', edit_band_tour_path(@band, @tour) +\| += link_to 'Back', band_tours_path(@band) diff --git a/config/application.rb b/config/application.rb index 07a0003..8ded7a7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -4,12 +4,20 @@ require "action_mailer/railtie" require "sprockets/railtie" -# If you have a Gemfile, require the gems listed there, including any gems -# you've limited to :test, :development, or :production. -Bundler.require(:default, Rails.env) if defined?(Bundler) +if defined?(Bundler) + # If you precompile assets before deploying to production, use this line + Bundler.require *Rails.groups(assets: %w(development test)) + # If you want your assets lazily compiled in production, use this line + # Bundler.require(:default, :assets, Rails.env) +end module Echo class Application < Rails::Application + # Enable the asset pipeline + config.assets.enabled = true + + # Version of your assets, change this if you want to expire all your assets + config.assets.version = '1.0' # Add additional load paths for your own custom dirs. config.autoload_paths += %W(#{config.root}/app/services) diff --git a/config/environments/development.rb b/config/environments/development.rb index 74e115d..99f4bf5 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -21,4 +21,10 @@ # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin + + # Do not compress assets + config.assets.compress = false + + # Expands the lines which load the assets + config.assets.debug = true end diff --git a/config/environments/production.rb b/config/environments/production.rb index 2ea78d5..d065126 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -34,6 +34,15 @@ # Enable serving of images, stylesheets, and javascripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" + # Compress JavaScript and CSS + config.assets.compress = true + + # Don't fallback to assets pipeline + config.assets.compile = false + + # Generate digests for assets URLs + config.assets.digest = true + # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false diff --git a/config/environments/test.rb b/config/environments/test.rb index e301977..bad881e 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -32,4 +32,11 @@ # Print deprecation notices to the stderr config.active_support.deprecation = :stderr + + # Configure static asset server for tests with Cache-Control for performance + config.serve_static_assets = true + config.static_cache_control = "public, max-age=3600" + + # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets + config.assets.allow_debugging = true end diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb new file mode 100644 index 0000000..553961b --- /dev/null +++ b/config/initializers/simple_form.rb @@ -0,0 +1,93 @@ +# Use this setup block to configure all options available in SimpleForm. +SimpleForm.setup do |config| + # Components used by the form builder to generate a complete input. You can remove + # any of them, change the order, or even add your own components to the stack. + # config.components = [ :placeholder, :label_input, :hint, :error ] + + # Default tag used on hints. + # config.hint_tag = :span + + # CSS class to add to all hint tags. + # config.hint_class = :hint + + # CSS class used on errors. + # config.error_class = :error + + # Default tag used on errors. + # config.error_tag = :span + + # Method used to tidy up errors. + # config.error_method = :first + + # Default tag used for error notification helper. + # config.error_notification_tag = :p + + # CSS class to add for error notification helper. + # config.error_notification_class = :error_notification + + # ID to add for error notification helper. + # config.error_notification_id = nil + + # You can wrap all inputs in a pre-defined tag. + # config.wrapper_tag = :div + + # CSS class to add to all wrapper tags. + # config.wrapper_class = :input + + # CSS class to add to the wrapper if the field has errors. + # config.wrapper_error_class = :field_with_errors + + # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none. + # config.collection_wrapper_tag = nil + + # You can wrap each item in a collection of radio/check boxes with a tag, defaulting to span. + # config.item_wrapper_tag = :span + + # Series of attempts to detect a default label method for collection. + # config.collection_label_methods = [ :to_label, :name, :title, :to_s ] + + # Series of attempts to detect a default value method for collection. + # config.collection_value_methods = [ :id, :to_s ] + + # How the label text should be generated altogether with the required text. + # config.label_text = lambda { |label, required| "#{required} #{label}" } + + # You can define the class to use on all labels. Default is nil. + # config.label_class = nil + + # You can define the class to use on all forms. Default is simple_form. + # config.form_class = :simple_form + + # Whether attributes are required by default (or not). Default is true. + # config.required_by_default = true + + # Tell browsers whether to use default HTML5 validations (novalidate option). + # Default is enabled. + # config.browser_validations = true + + # Determines whether HTML5 types (:email, :url, :search, :tel) and attributes + # (e.g. required) are used or not. True by default. + # Having this on in non-HTML5 compliant sites can cause odd behavior in + # HTML5-aware browsers such as Chrome. + # config.html5 = true + + # Custom mappings for input types. This should be a hash containing a regexp + # to match as key, and the input type that will be used when the field name + # matches the regexp as value. + # config.input_mappings = { /count/ => :integer } + + # Collection of methods to detect if a file type was given. + # config.file_methods = [ :mounted_as, :file?, :public_filename ] + + # Default priority for time_zone inputs. + # config.time_zone_priority = nil + + # Default priority for country inputs. + # config.country_priority = nil + + # Default size for text inputs. + # config.default_input_size = 50 + + # When false, do not use translations for labels, hints or placeholders. + # config.translate = true +end diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml new file mode 100644 index 0000000..409e265 --- /dev/null +++ b/config/locales/simple_form.en.yml @@ -0,0 +1,24 @@ +en: + simple_form: + "yes": 'Yes' + "no": 'No' + required: + text: 'required' + mark: '*' + # You can uncomment the line below if you need to overwrite the whole required html. + # When using html, text and mark won't be used. + # html: '*' + error_notification: + default_message: "Some errors were found, please take a look:" + # Labels and hints examples + # labels: + # password: 'Password' + # user: + # new: + # email: 'E-mail para efetuar o sign in.' + # edit: + # email: 'E-mail.' + # hints: + # username: 'User name to sign in.' + # password: 'No special characters, please.' + diff --git a/config/routes.rb b/config/routes.rb index f1d18ea..8629fa8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -50,6 +50,12 @@ # just remember to delete public/index.html. root :to => "start#index" + resources :bands do + resources :tours do + resources :shows + end + end + # See how all your routes lay out with "rake routes" # This is a legacy wild controller route that's not recommended for RESTful applications. diff --git a/lib/templates/haml/scaffold/_form.html.haml b/lib/templates/haml/scaffold/_form.html.haml new file mode 100644 index 0000000..bfe7fe6 --- /dev/null +++ b/lib/templates/haml/scaffold/_form.html.haml @@ -0,0 +1,10 @@ += simple_form_for(@<%= singular_table_name %>) do |f| + = f.error_notification + + .inputs + <%- attributes.each do |attribute| -%> + = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> + <%- end -%> + + .actions + = f.button :submit diff --git a/spec/requests/bands_spec.rb b/spec/requests/bands_spec.rb new file mode 100644 index 0000000..e776056 --- /dev/null +++ b/spec/requests/bands_spec.rb @@ -0,0 +1,170 @@ +# encoding: utf-8 +require 'spec_helper' + +describe "Bands" do + describe "GET /bands" do + describe "listing of bands" do + let!(:band) { Fabricate(:depeche_mode) } + + before(:each) do + visit root_path + click_link "Bands" + end + + it "band name" do + page.should have_link band.name, href: band_path(band) + end + + it "location of band" do + page.should have_content band.location + end + + it "edit and destroy links" do + page.should have_link "Edit", href: edit_band_path(band) + page.should have_link "Destroy", href: band_path(band) + end + end + end + + describe "GET /bands/new" do + before(:each) do + visit bands_path + click_link "New Band" + end + + it "shows form" do + page.should have_field "Name" + page.should have_field "Description" + page.should have_field "Formed on" + page.should have_field "Location" + page.should have_field "Website" + end + + it "creates band" do + fill_in "Name", with: "Franz Ferdinand" + fill_in "Description", with: "A Glasgow based post-punk revival band." + fill_in "Formed on", with: "01.01.2002" + fill_in "Location", with: "Glasgow, Scotland" + fill_in "Website", with: "http://www.franzferdinand.co.uk" + + click_button "Create Band" + + page.should have_content "Band was successfully created." + + page.should have_content "Franz Ferdinand" + page.should have_content "A Glasgow based post-punk revival band." + page.should have_content "2002-01-01" + page.should have_content "Glasgow, Scotland" + page.should have_link "http://www.franzferdinand.co.uk", href: "http://www.franzferdinand.co.uk" + end + end + + describe "GET /bands/1" do + let!(:band) { Fabricate(:depeche_mode) } + + before(:each) do + visit bands_path + click_link band.name + end + + it "band name" do + page.should have_content band.name + end + + it "description" do + page.should have_content band.description + end + + it "formed on" do + page.should have_content band.formed_on + end + + it "location" do + page.should have_content band.location + end + + it "website" do + page.should have_content band.website + end + end + + describe "GET /bands/1/edit" do + let!(:band) { Fabricate(:nine_inch_nails, formed_on: "1988-04-03", location: "Cleveland, Ohio, United States", website: "http://www.nin.com") } + + before(:each) do + visit band_path(band) + click_link "Edit" + end + + it "shows current data in form" do + page.should have_field "Name", with: band.name + page.should have_field "Description", with: band.description + page.should have_field "Formed on", with: band.formed_on.to_s + page.should have_field "Location", with: band.location + page.should have_field "Website", with: band.website + end + + describe "edit fields" do + it "name" do + fill_in "Name", with: "Franz Ferdinand" + + click_button "Update Band" + page.should have_content "Band was successfully updated." + + page.should have_content "Franz Ferdinand" + end + + it "description" do + fill_in "Description", with: "A Glasgow based post-punk revival band." + + click_button "Update Band" + page.should have_content "Band was successfully updated." + + page.should have_content "A Glasgow based post-punk revival band." + end + + it "formed on" do + fill_in "Formed on", with: "01.01.2002" + + click_button "Update Band" + page.should have_content "Band was successfully updated." + + page.should have_content "2002-01-01" + end + + it "location" do + fill_in "Location", with: "Glasgow, Scotland" + + click_button "Update Band" + page.should have_content "Band was successfully updated." + + page.should have_content "Glasgow, Scotland" + end + + it "website" do + fill_in "Website", with: "http://www.franzferdinand.co.uk" + + click_button "Update Band" + page.should have_content "Band was successfully updated." + + page.should have_link "http://www.franzferdinand.co.uk", href: "http://www.franzferdinand.co.uk" + end + end + end + + describe "POST /bands/1/destroy" do + let!(:band) { Fabricate(:nine_inch_nails) } + + it "destroys", js: true do + visit bands_path + + page.should have_link band.name + + handle_js_confirm do + click_link "Destroy" + end + + page.should_not have_link band.name + end + end +end diff --git a/spec/requests/shows_spec.rb b/spec/requests/shows_spec.rb new file mode 100644 index 0000000..d78d305 --- /dev/null +++ b/spec/requests/shows_spec.rb @@ -0,0 +1,226 @@ +# encoding: utf-8 +require 'spec_helper' + +describe "Shows" do + describe "GET /bands/1/tours/2/shows" do + describe "listing of shows" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour, shows: [Fabricate.build(:show, venue: Fabricate.build(:venue))])]) } + let(:tour) { band.tours.first } + let(:show) { tour.shows.first } + + before(:each) do + visit band_tour_path(band, tour) + click_link "Shows" + end + + it "name" do + page.should have_link show.date.to_s, href: band_tour_show_path(band, tour, show) + end + + it "venue name" do + page.should have_content show.venue.name + end + + it "city" do + page.should have_content show.venue.address.city + end + + it "edit and destroy links" do + page.should have_link "Edit", href: edit_band_tour_show_path(band, tour, show) + page.should have_link "Destroy", href: band_tour_show_path(band, tour, show) + end + end + end + + describe "GET /bands/1/tours/2/shows/new" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour)]) } + let(:tour) { band.tours.first } + + before(:each) do + visit band_tour_shows_path(band, tour) + click_link "New Show" + end + + it "shows form" do + page.should have_field "Date" + + within_fieldset("Venue") do + page.should have_field "Name" + end + end + + describe "creates show" do + it "date" do + fill_in "Date", with: "25.12.2010" + + click_button "Create Show" + + page.should have_content "Show was successfully created." + + page.should have_content "2010-12-25" + end + + it "venue name" do + fill_in "Date", with: "25.12.2010" + + within_fieldset("Venue") do + fill_in "Name", with: "Olympiastadion" + end + + click_button "Create Show" + + page.should have_content "Show was successfully created." + + page.should have_content "2010-12-25" + + within(".venue") do + page.should have_content "Olympiastadion" + end + end + + it "venue address" do + fill_in "Date", with: "25.12.2010" + + within_fieldset("Venue") do + fill_in "Name", with: "Olympiastadion" + + fill_in "Street", with: "Spiridon-Louis-Ring 21" + fill_in "Postcode", with: "80809" + fill_in "City", with: "München" + fill_in "State", with: "Bayern" + fill_in "Country", with: "Deutschland" + end + + click_button "Create Show" + + page.should have_content "Show was successfully created." + + page.should have_content "2010-12-25" + + within(".venue") do + page.should have_content "Olympiastadion" + + page.should have_content "Spiridon-Louis-Ring 21" + page.should have_content "80809" + page.should have_content "München" + page.should have_content "Bayern" + page.should have_content "Deutschland" + end + end + end + end + + describe "GET /bands/1/tours/2/shows/3" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour, shows: [Fabricate.build(:show, venue: Fabricate.build(:venue))])]) } + let(:tour) { band.tours.first } + let(:show) { tour.shows.first } + + before(:each) do + visit band_tour_shows_path(band, tour) + click_link show.date.to_s + end + + it "date" do + page.should have_content show.date.to_s + end + + it "venue name" do + within(".venue") do + page.should have_content show.venue.name + end + end + + it "venue address" do + within(".venue") do + page.should have_content show.venue.address.extra + page.should have_content show.venue.address.street + page.should have_content show.venue.address.postcode + page.should have_content show.venue.address.city + page.should have_content show.venue.address.state + page.should have_content show.venue.address.country + end + end + end + + describe "GET /bands/1/tours/2/shows/3/edit" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour, shows: [Fabricate.build(:show, venue: Fabricate.build(:venue))])]) } + let(:tour) { band.tours.first } + let(:show) { tour.shows.first } + + before(:each) do + visit band_tour_show_path(band, tour, show) + click_link "Edit" + end + + it "shows current data in form" do + page.should have_field "Date", with: show.date.to_s + + within_fieldset("Venue") do + page.should have_field "Name", with: show.venue.name + end + end + + describe "edit fields" do + it "date" do + fill_in "Date", with: "25.12.2010" + + click_button "Update Show" + page.should have_content "Show was successfully updated." + + page.should have_content "2010-12-25" + end + + it "venue name" do + within_fieldset("Venue") do + fill_in "Name", with: "Olympiastadion" + end + + click_button "Update Show" + page.should have_content "Show was successfully updated." + + within(".venue") do + page.should have_content "Olympiastadion" + end + end + + it "venue address" do + within_fieldset("Venue") do + fill_in "Street", with: "Spiridon-Louis-Ring 21" + fill_in "Postcode", with: "80809" + fill_in "City", with: "München" + fill_in "State", with: "Bayern" + fill_in "Country", with: "Deutschland" + end + + click_button "Update Show" + page.should have_content "Show was successfully updated." + + within(".venue") do + page.should have_content "Spiridon-Louis-Ring 21" + page.should have_content "80809" + page.should have_content "München" + page.should have_content "Bayern" + page.should have_content "Deutschland" + end + end + end + end + + describe "GET /bands/1/tours/2/shows/3/destroy" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour, shows: [Fabricate.build(:show, venue: Fabricate.build(:venue))])]) } + let(:tour) { band.tours.first } + let(:show) { tour.shows.first } + + it "destroys", js: true do + visit band_tour_shows_path(band, tour) + + page.should have_link show.date.to_s + + handle_js_confirm do + click_link "Destroy" + end + + page.should_not have_link show.date.to_s + end + end +end diff --git a/spec/requests/tours_spec.rb b/spec/requests/tours_spec.rb new file mode 100644 index 0000000..45f9e06 --- /dev/null +++ b/spec/requests/tours_spec.rb @@ -0,0 +1,104 @@ +# encoding: utf-8 +require 'spec_helper' + +describe "Tours" do + describe "GET /bands/1/tours" do + describe "listing of tours" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour)]) } + let(:tour) { band.tours.first } + + before(:each) do + visit band_path(band) + click_link "Tours" + end + + it "name" do + page.should have_link tour.name, href: band_tour_path(band, tour) + end + + it "edit and destroy links" do + page.should have_link "Edit", href: edit_band_tour_path(band, tour) + page.should have_link "Destroy", href: band_tour_path(band, tour) + end + end + end + + describe "GET /bands/1/tours/new" do + let!(:band) { Fabricate(:nine_inch_nails) } + + before(:each) do + visit band_tours_path(band) + click_link "New Tour" + end + + it "shows form" do + page.should have_field "Name" + end + + it "creates tour" do + fill_in "Name", with: "Self Destruct Tour" + + click_button "Create Tour" + + page.should have_content "Tour was successfully created." + + page.should have_content "Self Destruct Tour" + end + end + + describe "GET /bands/1/tours/2" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour)]) } + let(:tour) { band.tours.first } + + before(:each) do + visit band_tours_path(band) + click_link tour.name + end + + it "tour name" do + page.should have_content tour.name + end + end + + describe "GET /bands/1/tours/2/edit" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour)]) } + let(:tour) { band.tours.first } + + before(:each) do + visit band_tour_path(band, tour) + click_link "Edit" + end + + it "shows current data in form" do + page.should have_field "Name", with: tour.name + end + + describe "edit fields" do + it "name" do + fill_in "Name", with: "Self Destruct Tour" + + click_button "Update Tour" + page.should have_content "Tour was successfully updated." + + page.should have_content "Self Destruct Tour" + end + end + end + + describe "GET /bands/1/tours/2/destroy" do + let!(:band) { Fabricate(:nine_inch_nails, tours: [Fabricate.build(:tour)]) } + let(:tour) { band.tours.first } + + it "destroys", js: true do + visit band_tours_path(band) + + page.should have_link tour.name + + handle_js_confirm do + click_link "Destroy" + end + + page.should_not have_link tour.name + end + end +end diff --git a/spec/routing/bands_routing_spec.rb b/spec/routing/bands_routing_spec.rb new file mode 100644 index 0000000..23bde01 --- /dev/null +++ b/spec/routing/bands_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe BandsController do + describe "routing" do + + it "routes to #index" do + get("/bands").should route_to("bands#index") + end + + it "routes to #new" do + get("/bands/new").should route_to("bands#new") + end + + it "routes to #show" do + get("/bands/1").should route_to("bands#show", :id => "1") + end + + it "routes to #edit" do + get("/bands/1/edit").should route_to("bands#edit", :id => "1") + end + + it "routes to #create" do + post("/bands").should route_to("bands#create") + end + + it "routes to #update" do + put("/bands/1").should route_to("bands#update", :id => "1") + end + + it "routes to #destroy" do + delete("/bands/1").should route_to("bands#destroy", :id => "1") + end + + end +end diff --git a/spec/routing/shows_routing_spec.rb b/spec/routing/shows_routing_spec.rb new file mode 100644 index 0000000..3c3e604 --- /dev/null +++ b/spec/routing/shows_routing_spec.rb @@ -0,0 +1,34 @@ +require "spec_helper" + +describe ShowsController do + describe "routing" do + + it "routes to #index" do + get("/bands/1/tours/2/shows").should route_to("shows#index", band_id: "1", tour_id: "2") + end + + it "routes to #new" do + get("/bands/1/tours/2/shows/new").should route_to("shows#new", band_id: "1", tour_id: "2") + end + + it "routes to #show" do + get("/bands/1/tours/2/shows/3").should route_to("shows#show", band_id: "1", tour_id: "2", id: "3") + end + + it "routes to #edit" do + get("/bands/1/tours/2/shows/3/edit").should route_to("shows#edit", band_id: "1", tour_id: "2", id: "3") + end + + it "routes to #create" do + post("/bands/1/tours/2/shows").should route_to("shows#create", band_id: "1", tour_id: "2") + end + + it "routes to #update" do + put("/bands/1/tours/2/shows/3").should route_to("shows#update", band_id: "1", tour_id: "2", id: "3") + end + + it "routes to #destroy" do + delete("/bands/1/tours/2/shows/3").should route_to("shows#destroy", band_id: "1", tour_id: "2", id: "3") + end + end +end diff --git a/spec/routing/tours_routing_spec.rb b/spec/routing/tours_routing_spec.rb new file mode 100644 index 0000000..2c0ff0a --- /dev/null +++ b/spec/routing/tours_routing_spec.rb @@ -0,0 +1,34 @@ +require "spec_helper" + +describe ToursController do + describe "routing" do + + it "routes to #index" do + get("/bands/1/tours").should route_to("tours#index", band_id: "1") + end + + it "routes to #new" do + get("/bands/1/tours/new").should route_to("tours#new", band_id: "1") + end + + it "routes to #show" do + get("/bands/1/tours/2").should route_to("tours#show", band_id: "1", id: "2") + end + + it "routes to #edit" do + get("/bands/1/tours/2/edit").should route_to("tours#edit", band_id: "1", id: "2") + end + + it "routes to #create" do + post("/bands/1/tours").should route_to("tours#create", band_id: "1") + end + + it "routes to #update" do + put("/bands/1/tours/2").should route_to("tours#update", band_id: "1", id: "2") + end + + it "routes to #destroy" do + delete("/bands/1/tours/2").should route_to("tours#destroy", band_id: "1", id: "2") + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7147103..cede9a2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,6 +6,7 @@ Spork.prefork do require File.expand_path("../../config/environment", __FILE__) require "rspec/rails" + require 'capybara/rspec' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. @@ -16,11 +17,6 @@ RSpec.configure do |config| config.mock_with :mocha - # Clean up all collections before each spec runs. - config.before do - Mongoid.purge! - end - # This filter is here to stub out the Facebook and Twitter services # conveniently for each spec tagged with :following. config.filter_run_including(service: ->(value) { @@ -29,5 +25,18 @@ end return true }) + + config.before(:suite) do + DatabaseCleaner.strategy = :truncation + DatabaseCleaner.orm = "mongoid" + end + + config.before(:each) do + DatabaseCleaner.start + end + + config.after(:each) do + DatabaseCleaner.clean + end end end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb new file mode 100644 index 0000000..ea7ae8f --- /dev/null +++ b/spec/support/capybara.rb @@ -0,0 +1,9 @@ +# Confirms an JavaScript Alert box +# Source: https://github.com/thoughtbot/capybara-webkit/issues/84 +def handle_js_confirm(accept=true) + page.evaluate_script "window.original_confirm_function = window.confirm" + page.evaluate_script "window.confirm = function(msg) { return #{!!accept}; }" + yield +ensure + page.evaluate_script "window.confirm = window.original_confirm_function" +end \ No newline at end of file