diff --git a/app/controllers/api/sounds_controller.rb b/app/controllers/api/sounds_controller.rb index 6c0913c..67a6821 100644 --- a/app/controllers/api/sounds_controller.rb +++ b/app/controllers/api/sounds_controller.rb @@ -1,6 +1,6 @@ module API class SoundsController < ApplicationController - skip_before_filter :json_filter!, only: :show + skip_before_filter :json_filter!, only: %i[show create] before_action :set_sound, only: :show @@ -8,6 +8,15 @@ module API send_file @sound.path, type: @sound.mime_type end + def create + @sound = Sound.new(sound_params) + if @sound.save + render :show, status: :created, location: api_sound_path(@sound) + else + render json: @sound.errors, status: :unprocessable_entity + end + end + private @@ -17,5 +26,9 @@ module API when /\A\h+\z/ then Sound.find_by_sha256!(params[:id]) end end + + def sound_params + params.require(:sound).permit :file + end end end diff --git a/config/routes.rb b/config/routes.rb index c098212..62e5d48 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,7 +7,7 @@ Rails.application.routes.draw do match '*all', to: 'application#cor_preflight', via: :options resources :playlists, only: %i[index show create update destroy] resources :sessions, only: :create - resources :sounds, only: :show + resources :sounds, only: %i[show create] resources :tracks, only: %i[index show] match '*all', to: 'application#not_found', via: :all end diff --git a/spec/integration/api/sounds_spec.rb b/spec/integration/api/sounds_spec.rb index ab1d7a3..3e6f460 100644 --- a/spec/integration/api/sounds_spec.rb +++ b/spec/integration/api/sounds_spec.rb @@ -1,4 +1,6 @@ describe 'API sounds' do + subject { response } + before { api_sign_in } describe 'sound show' do @@ -6,7 +8,6 @@ describe 'API sounds' do let(:request_method) { :get } let(:request_path) { api_sound_path(sound) } let(:request_show) { send request_method, request_path } - subject { response } before { request_show } @@ -36,4 +37,41 @@ describe 'API sounds' do it { is_expected.to have_http_status 200 } end end + + describe 'sounds create' do + let(:file) { attributes_for(:sound)[:file] } + let(:upload) { fixture_file_upload file.path, file.content_type } + let(:sound) { { file: upload } } + + before { post api_sounds_path, sound: sound } + + it { is_expected.to have_http_status 201 } + + it 'creates the sound' do + get response.location + expect(response.body).to eq File.read(file.path, mode: 'rb') + end + + it 'returns the sound' do + expect(json).to match( + sound: { + id: an_instance_of(Fixnum), + sha256: /\A\h+\z/, + mime_type: 'audio/mpeg' + } + ) + end + + context 'when sound is invalid' do + let(:sound) { { file: nil } } + + it { is_expected.to have_http_status 422 } + + it 'returns errors' do + expect(json :any).to include( + sha256: [an_instance_of(String)] + ) + end + end + end end