diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb index 30ec01e..12e7229 100644 --- a/app/controllers/tracks_controller.rb +++ b/app/controllers/tracks_controller.rb @@ -3,6 +3,22 @@ class TracksController < ApplicationController @track = Track.find params[:id] end + def new + @track = Track.new + end + + def create + @track = Track.new(:name => params[:track][:name]) + if params[:track][:file] + @track.uploaded_file = params[:track][:file] + end + if @track.save + redirect_to @track + else + render :new + end + end + def stream end end diff --git a/app/models/track.rb b/app/models/track.rb index 0fee495..96bac19 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -1,3 +1,17 @@ class Track < ActiveRecord::Base validates_presence_of :name + + after_create :save_file + + def uploaded_file=(file) + @file = file + end + + def save_file + if @file + File.open("#{Rails.root}/data/tracks/#{id}", 'w') do |f| + f.write @file.tempfile.read + end + end + end end diff --git a/app/views/playlists/index.html.haml b/app/views/playlists/index.html.haml index 86cc038..3f99cda 100644 --- a/app/views/playlists/index.html.haml +++ b/app/views/playlists/index.html.haml @@ -1,4 +1,5 @@ = link_to 'Create playlist', new_playlist_path += link_to 'Add a track', new_track_path %ul - @playlists.each do |p| %li diff --git a/app/views/tracks/new.html.haml b/app/views/tracks/new.html.haml new file mode 100644 index 0000000..9683a47 --- /dev/null +++ b/app/views/tracks/new.html.haml @@ -0,0 +1,6 @@ += form_for @track, :html => { :multipart => true } do |t| + = t.label :name + = t.text_field :name + = t.label :file + = t.file_field :file + = t.submit 'Upload' diff --git a/data/tracks/.gitkeep b/data/tracks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/features/data/test.mp3 b/features/data/test.mp3 new file mode 100644 index 0000000..7cdcb1f Binary files /dev/null and b/features/data/test.mp3 differ diff --git a/features/tracks.feature b/features/tracks.feature index ef39a10..0f8bf93 100644 --- a/features/tracks.feature +++ b/features/tracks.feature @@ -9,6 +9,14 @@ Feature: Tracks 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 playlists page + When I follow "Add a track" + And I fill in "Name" with "Mega song" + And I attach the file "features/data/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" diff --git a/spec/controllers/tracks_controller_spec.rb b/spec/controllers/tracks_controller_spec.rb index e983d44..45a9671 100644 --- a/spec/controllers/tracks_controller_spec.rb +++ b/spec/controllers/tracks_controller_spec.rb @@ -14,4 +14,58 @@ describe TracksController do assigns[:track].should == track end end + + describe 'GET new' do + it 'assigns a new track as @track' do + get :new + assigns[:track].should be_a_new(Track) + end + end + + describe 'POST create' do + let(:track) { mock_model(Track).as_null_object } + before { Track.stub(:new).and_return(track) } + + it 'creates a new track' do + Track.should_receive(:new). + with(:name => 'Mega song'). + and_return(track) + post :create, :track => valid_attributes + end + + it 'saves the track' do + track.should_receive(:save) + post :create, :track => {} + end + + it 'saves the file uploaded for the track' do + file = mock(Rack::Test::UploadedFile) + track.should_receive(:uploaded_file=).with(file) + post :create, :track => { :file => file } + end + + context 'when the track saves successfully' do + it 'redirects to the track page' do + post :create, :track => valid_attributes + response.should redirect_to(track) + end + end + + context 'when the track fails to save' do + before do + track.stub(:save).and_return(false) + end + + it 'assigns the track as @track' do + post :create, :track => {} + assigns[:track].should == track + end + + it 'renders the new template' do + post :create, :track => {} + response.should render_template('new') + end + end + + end end diff --git a/spec/fixtures/test.mp3 b/spec/fixtures/test.mp3 new file mode 100644 index 0000000..7cdcb1f Binary files /dev/null and b/spec/fixtures/test.mp3 differ diff --git a/spec/models/track_spec.rb b/spec/models/track_spec.rb index ada4475..6f66918 100644 --- a/spec/models/track_spec.rb +++ b/spec/models/track_spec.rb @@ -15,4 +15,24 @@ describe Track do it { should_not be_valid } end + + describe '#uploaded_file=' do + let(:track) { Track.new :name => 'Mega song' } + + it 'saves an uploaded file' do + filepath = "#{Rails.root}/spec/fixtures/test.mp3" + file = mock(Rack::Test::UploadedFile) + file.stub( + :tempfile => File.new(filepath), + :content_type => 'audio/mpeg' + ) + track.uploaded_file = file + track.save + File.read("#{Rails.root}/data/tracks/#{track.id.to_s}").should == File.read(filepath) + end + + after do + `rm -rf #{Rails.root}/data/tracks/*` + end + end end diff --git a/spec/views/playlists/index.html.haml_spec.rb b/spec/views/playlists/index.html.haml_spec.rb index af2db4c..084af6f 100644 --- a/spec/views/playlists/index.html.haml_spec.rb +++ b/spec/views/playlists/index.html.haml_spec.rb @@ -21,4 +21,9 @@ describe 'playlists/index.html.haml' do render rendered.should have_selector('a', :text => 'Electro') end + + it 'displays a link to create a new track' do + render + rendered.should have_selector('a', :text => 'Add a track') + end end diff --git a/spec/views/tracks/new.html.haml_spec.rb b/spec/views/tracks/new.html.haml_spec.rb new file mode 100644 index 0000000..de3e856 --- /dev/null +++ b/spec/views/tracks/new.html.haml_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe 'tracks/new.html.haml' do + let(:track) do + mock_model('Track').as_new_record.as_null_object + end + + before do + assign :track, track + end + + it 'renders a form to create a track' do + render + rendered.should have_selector("form[method=post][action='#{tracks_path}']") + rendered.should have_selector('input[type=submit]') + end + + it 'renders a text field with a label for the playlists name' do + track.stub(:name => 'Mega song') + render + rendered.should \ + have_selector("input[type=text][name='track[name]'][value='Mega song']") + rendered.should \ + have_selector('label[for=track_name]', :text => 'Name') + end + + it 'renders a file field with a label for the tracks file' do + render + rendered.should have_selector("form[enctype='multipart/form-data']") + rendered.should \ + have_selector("input[type=file][name='track[file]']") + rendered.should \ + have_selector('label[for=track_file]', :text => 'File') + end +end