Implement track/stream

* Add Streamer class
* Use FactoryGirl for factories
* Add sha256 field to tracks
* Add mime_type field to tracks
This commit is contained in:
Thibault Jouan
2011-07-23 16:30:51 +00:00
parent 47fa969617
commit 2f6a447416
18 changed files with 166 additions and 51 deletions

View File

@@ -9,6 +9,25 @@ describe TracksController do
end
end
describe 'GET stream' do
let(:track) { Factory.create(:track) }
it 'streams the requested track' do
get :stream, :id => track.id.to_s
response.should be_success
end
it 'creates a streamer instance' do
Streamer.should_receive(:new).with(track.filepath)
get :stream, :id => track.id.to_s
end
it 'returns the track mime-type as content-type' do
get :stream, :id => track.id.to_s
response.content_type.should == track.mime_type
end
end
describe 'GET new' do
it 'assigns a new track as @track' do
get :new
@@ -18,48 +37,52 @@ describe TracksController do
describe 'POST create' do
let(:track) { mock_model(Track).as_null_object }
let(:file) {
file = mock(Rack::Test::UploadedFile)
file.stub(:tempfile => File.new("#{Rails.root}/spec/fixtures/test.mp3"))
file.stub(:content_type => 'audio/ogg')
file
}
before { Track.stub(:new).and_return(track) }
it 'creates a new track' do
attributes = Factory.attributes_for(:track)
Track.should_receive(:new).
with(Factory.attributes_for(:track)).
with({:name => attributes[:name]}).
and_return(track)
post :create, :track => Factory.attributes_for(:track)
post :create, :track => {
:name => attributes[:name],
:file => file
}
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)
it 'saves the track with a file' do
track.should_receive(:save_with_file).
with(file.tempfile, 'audio/ogg')
post :create, :track => { :file => file }
end
context 'when the track saves successfully' do
it 'redirects to the track page' do
post :create, :track => Factory.attributes_for(:track)
post :create, :track => { :file => file }
response.should redirect_to(track)
end
end
context 'when the track fails to save' do
before do
track.stub(:save).and_return(false)
track.stub(:save_with_file).and_return(false)
end
it 'assigns the track as @track' do
post :create, :track => {}
post :create, :track => { :file => file }
assigns[:track].should == track
end
it 'renders the new template' do
post :create, :track => {}
post :create, :track => { :file => file }
response.should render_template('new')
end
end
end
end

BIN
spec/data/test.mp3 Normal file

Binary file not shown.

View File

@@ -5,5 +5,7 @@ FactoryGirl.define do
factory :track do
name 'Mega song'
mime_type 'audio/ogg'
sha256 '94a5486a69a7261da350c57f9e5a1eaa789e08752cfc56a1989976a6ad82f7a8'
end
end

19
spec/lib/streamer_spec.rb Normal file
View File

@@ -0,0 +1,19 @@
require 'spec_helper'
describe Streamer do
describe '#each' do
let(:stream) { Streamer.new("#{Rails.root}/spec/fixtures/test.mp3") }
it 'returns file content' do
chunks = ''
stream.each { |c| chunks << c }
chunks.should == File.read("#{Rails.root}/spec/fixtures/test.mp3")
end
it 'returns content in multiple chunks' do
count = 0
stream.each { count += 1 }
count.should be >= 2
end
end
end

View File

@@ -9,30 +9,51 @@ describe Track do
end
context 'when name empty' do
before do
track.name = ''
end
before { track.name = '' }
it { should_not be_valid }
end
describe '#uploaded_file=' do
let(:track) { Track.new :name => 'Mega song' }
context 'when mime_type empty' do
before { track.mime_type = '' }
it { should_not be_valid }
end
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)
context 'when sha256 empty' do
before { track.sha256 = '' }
it { should_not be_valid }
end
describe '#filepath' do
it 'returns the path to the track file' do
track.filepath.should == "#{Rails.root}/data/tracks/#{track.sha256}"
end
end
describe '#save_with_file' do
let(:file) { File.new("#{Rails.root}/spec/fixtures/test.mp3") }
it 'calls save' do
Track.any_instance.should_receive(:save!)
track.save_with_file(file, 'audio/ogg')
end
it 'saves the file content' do
track.save_with_file(file, 'audio/ogg')
File.read(track.filepath).should == File.read(file.path)
end
it 'saves the file SHA256 digest' do
track.save_with_file(file, 'audio/ogg')
track.sha256.should == Digest::SHA256.file(file.path).hexdigest
end
it 'saves the file mime type' do
track.save_with_file(file, 'audio/mpeg')
track.mime_type.should == 'audio/mpeg'
end
after do
`rm -rf #{Rails.root}/data/tracks/*`
`rm -f #{Rails.root}/data/tracks/*`
end
end
end

View File

@@ -20,6 +20,16 @@ describe 'tracks/show.html.haml' do
rendered.should have_selector('audio[src]')
end
it 'provides controls' do
render
rendered.should have_selector('audio[controls]')
end
it 'has autoplay activated' do
render
rendered.should have_selector('audio[autoplay]')
end
it 'displays a text fallback for UA without support' do
render
rendered.should have_selector('audio',