diff --git a/app/controllers/playlists_controller.rb b/app/controllers/playlists_controller.rb new file mode 100644 index 0000000..f4a9bd0 --- /dev/null +++ b/app/controllers/playlists_controller.rb @@ -0,0 +1,18 @@ +class PlaylistsController < ApplicationController + def index + @playlists = Playlist.all + end + + def new + @playlist = Playlist.new + end + + def create + @playlist = Playlist.new params[:playlist] + if @playlist.save + redirect_to :action => 'index' + else + render :action => 'new' + end + end +end diff --git a/app/models/playlist.rb b/app/models/playlist.rb new file mode 100644 index 0000000..e8cf8d0 --- /dev/null +++ b/app/models/playlist.rb @@ -0,0 +1,3 @@ +class Playlist < ActiveRecord::Base + validates_presence_of :name +end diff --git a/app/views/playlists/index.html.haml b/app/views/playlists/index.html.haml new file mode 100644 index 0000000..dd883ca --- /dev/null +++ b/app/views/playlists/index.html.haml @@ -0,0 +1,4 @@ += link_to 'Create playlist', new_playlist_path +%ul + - @playlists.each do |p| + %li= p.name diff --git a/app/views/playlists/new.html.haml b/app/views/playlists/new.html.haml new file mode 100644 index 0000000..52e732d --- /dev/null +++ b/app/views/playlists/new.html.haml @@ -0,0 +1,4 @@ += form_for @playlist do |f| + = f.label :name + = f.text_field :name + = f.submit 'Create' diff --git a/config/routes.rb b/config/routes.rb index fdf2ad7..4d2483a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,58 +1,3 @@ Scube::Application.routes.draw do - # The priority is based upon order of creation: - # first created -> highest priority. - - # Sample of regular route: - # match 'products/:id' => 'catalog#view' - # Keep in mind you can assign values other than :controller and :action - - # Sample of named route: - # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase - # This route can be invoked with purchase_url(:id => product.id) - - # Sample resource route (maps HTTP verbs to controller actions automatically): - # resources :products - - # Sample resource route with options: - # resources :products do - # member do - # get 'short' - # post 'toggle' - # end - # - # collection do - # get 'sold' - # end - # end - - # Sample resource route with sub-resources: - # resources :products do - # resources :comments, :sales - # resource :seller - # end - - # Sample resource route with more complex sub-resources - # resources :products do - # resources :comments - # resources :sales do - # get 'recent', :on => :collection - # end - # end - - # Sample resource route within a namespace: - # namespace :admin do - # # Directs /admin/products/* to Admin::ProductsController - # # (app/controllers/admin/products_controller.rb) - # resources :products - # end - - # You can have the root of your site routed with "root" - # just remember to delete public/index.html. - # root :to => "welcome#index" - - # See how all your routes lay out with "rake routes" - - # This is a legacy wild controller route that's not recommended for RESTful applications. - # Note: This route will make all actions in every controller accessible via GET requests. - # match ':controller(/:action(/:id(.:format)))' + resources :playlists end diff --git a/db/migrate/20110711195337_create_playlists.rb b/db/migrate/20110711195337_create_playlists.rb new file mode 100644 index 0000000..5e94ab0 --- /dev/null +++ b/db/migrate/20110711195337_create_playlists.rb @@ -0,0 +1,13 @@ +class CreatePlaylists < ActiveRecord::Migration + def self.up + create_table :playlists do |t| + t.string :name + + t.timestamps + end + end + + def self.down + drop_table :playlists + end +end diff --git a/db/schema.rb b/db/schema.rb index 671c0da..5bd1f56 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,6 +10,12 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 0) do +ActiveRecord::Schema.define(:version => 20110711195337) do + + create_table "playlists", :force => true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end end diff --git a/features/playlists.feature b/features/playlists.feature new file mode 100644 index 0000000..9dbcda1 --- /dev/null +++ b/features/playlists.feature @@ -0,0 +1,18 @@ +Feature: Playlists + + So that tracks can be grouped in lists + As a listener + I want to manage some playlists + + Scenario: List playlists + Given Foo and Bar playlists + When I am on the playlists page + Then I should see "Foo" within "ul>li" + And I should see "Bar" within "ul>li+li" + + 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" within "ul>li" diff --git a/features/step_definitions/playlists_step.rb b/features/step_definitions/playlists_step.rb new file mode 100644 index 0000000..96ace99 --- /dev/null +++ b/features/step_definitions/playlists_step.rb @@ -0,0 +1,4 @@ +Given /^Foo and Bar playlists$/ do + @foo = Playlist.create!(:name => 'Foo') + @bar = Playlist.create!(:name => 'Bar') +end diff --git a/spec/controllers/playlists_controller_spec.rb b/spec/controllers/playlists_controller_spec.rb new file mode 100644 index 0000000..0ab28fa --- /dev/null +++ b/spec/controllers/playlists_controller_spec.rb @@ -0,0 +1,67 @@ +require 'spec_helper' + +describe PlaylistsController do + def valid_attributes + { + :name => 'Electro' + } + end + + describe "GET index" do + it 'assigns all playlists as @playlists' do + playlist = Playlist.create! valid_attributes + get :index + assigns[:playlists].should == [playlist] + end + end + + describe "GET new" do + it 'assigns a new playlist as @playlist' do + get :new + assigns[:playlist].should be_a_new(Playlist) + end + end + + describe "POST create" do + let(:playlist) { mock_model(Playlist).as_null_object } + + before do + Playlist.stub(:new).and_return(playlist) + end + + it 'creates a new playlist' do + Playlist.should_receive(:new). + with('name' => 'Electro'). + and_return(playlist) + post :create, :playlist => { 'name' => 'Electro' } + end + + it 'saves the playlist' do + playlist.should_receive(:save) + post :create + end + + context 'when the playlist saves successfully' do + it 'redirects to the playlists index' do + post :create + response.should redirect_to(:action => 'index') + end + end + + context 'when the playlist fails to save' do + before do + playlist.stub(:save).and_return(false) + end + + it 'assigns the playlist as @playlist' do + post :create + assigns[:playlist].should eq(playlist) + end + + it 'renders the new template' do + post :create + response.should render_template('new') + end + end + end +end diff --git a/spec/models/playlist_spec.rb b/spec/models/playlist_spec.rb new file mode 100644 index 0000000..9c58ac5 --- /dev/null +++ b/spec/models/playlist_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe Playlist do + subject { playlist } + let(:playlist) { Playlist.new :name => 'Electro' } + + context "with valid attributes" do + it { should be_valid } + end + + context "when name empty" do + before do + playlist.name = '' + end + + it { should_not be_valid } + end +end diff --git a/spec/views/playlists/index.html.haml_spec.rb b/spec/views/playlists/index.html.haml_spec.rb new file mode 100644 index 0000000..554607c --- /dev/null +++ b/spec/views/playlists/index.html.haml_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe 'playlists/index.html.haml' do + before do + assign :playlists, [ + double('Playlist', :name => 'Foo'), + double('Playlist', :name => 'Bar') + ] + end + + it 'displays a list of playlists' do + render + rendered.should have_selector('ul>li', :count => 2) + rendered.should have_selector('ul>li', :text => 'Foo') + rendered.should have_selector('ul>li+li', :text => 'Bar') + end + + it 'displays a link to create a new playlist' do + render + rendered.should have_selector('a', :text => 'Create playlist') + end +end diff --git a/spec/views/playlists/new.html.haml_spec.rb b/spec/views/playlists/new.html.haml_spec.rb new file mode 100644 index 0000000..bef3839 --- /dev/null +++ b/spec/views/playlists/new.html.haml_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe 'playlists/new.html.haml' do + let(:playlist) do + mock_model('Playlist').as_new_record.as_null_object + end + + before do + assign :playlist, playlist + end + + it 'renders a form to create a playlist' do + render + rendered.should have_selector("form[method=post][action='#{playlists_path}']") + rendered.should have_selector('input[type=submit]') + end + + it 'renders a text field with a label for the playlists name' do + playlist.stub(:name => 'Electro') + render + rendered.should \ + have_selector("input[type=text][name='playlist[name]'][value=Electro]") + rendered.should \ + have_selector("label[for=playlist_name]", :text => 'Name') + end +end