Skip to content

Commit

Permalink
Implement Endpoints for Songs
Browse files Browse the repository at this point in the history
  • Loading branch information
BeRMaNyA committed Oct 31, 2013
1 parent 5a5ba86 commit 2c8b325
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -23,5 +23,5 @@ group :test do
end

gem 'thin'
gem 'kaminari'
gem 'will_paginate', '~> 3.0'
gem 'rabl'
6 changes: 2 additions & 4 deletions Gemfile.lock
Expand Up @@ -61,9 +61,6 @@ GEM
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.1)
kaminari (0.14.1)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
Expand Down Expand Up @@ -134,6 +131,7 @@ GEM
uglifier (2.3.0)
execjs (>= 0.3.0)
json (>= 1.8.0)
will_paginate (3.0.5)

PLATFORMS
ruby
Expand All @@ -145,7 +143,6 @@ DEPENDENCIES
factory_girl
faker
jquery-rails
kaminari
pg
rabl
rails (= 3.2.15)
Expand All @@ -154,3 +151,4 @@ DEPENDENCIES
shoulda-matchers
thin
uglifier (>= 1.0.3)
will_paginate (~> 3.0)
24 changes: 23 additions & 1 deletion app/controllers/songs_controller.rb
@@ -1,10 +1,32 @@
class SongsController < ApplicationController
# GET /songs
def songs
def index
@songs = Song.paginate(:per_page => 50, :page => params[:page])

respond_to do |format|
format.html
end
end

# GET /songs/on_sale
def on_sale
@songs = Song.on_sale.paginate(:per_page => 50, :page => params[:page])

respond_to do |format|
format.html
end
end

# POST /songs
def create
@song = Song.new(title: params[:title], artist: params[:artist], album: params[:album], price_in_cents: params[:price])

respond_to do |format|
if @song.save
format.html { render 'songs/song' }
else
format.html { render json: { errors: @song.errors }, status: :unprocessable_entity }
end
end
end
end
2 changes: 1 addition & 1 deletion app/models/bar.rb
Expand Up @@ -20,6 +20,6 @@ def generate_token
end

def downcase_name
self.name_downcased = self.name.downcase if self.name.present?
self.name_downcased = self.name.try(:downcase)
end
end
1 change: 1 addition & 0 deletions app/views/songs/base.rabl
@@ -0,0 +1 @@
attributes :id, :title, :artist, :album, :price
8 changes: 6 additions & 2 deletions app/views/songs/index.html.rabl
@@ -1,5 +1,9 @@
object false

child (@songs) do
extends "songs/song"
node(:pagination) do
pagination_hash(@songs)
end

child @songs, object_root: false do
extends "songs/base"
end
9 changes: 9 additions & 0 deletions app/views/songs/on_sale.html.rabl
@@ -0,0 +1,9 @@
object false

node(:pagination) do
pagination_hash(@songs)
end

child @songs, object_root: false do
extends "songs/base"
end
4 changes: 3 additions & 1 deletion app/views/songs/song.rabl
@@ -1 +1,3 @@
attributes :id, :title, :artist, :album, :price
object @song => ""

extends "songs/base"
102 changes: 102 additions & 0 deletions spec/controllers/songs_spec.rb
@@ -0,0 +1,102 @@
require 'spec_helper'

describe 'Songs API' do
context "failed request" do
subject { JSON.parse(last_response.body)['errors'] }

context "title, artist, album and price are not provided" do
it "responds with an error" do
post '/songs'
should have_key('title')
should have_key('artist')
should have_key('album')
should have_key('price_in_cents')
end
end

context "name is duplicated" do
it "respond with an error" do
song = FactoryGirl.create(:song)
post "/songs", { title: song.title, album: song.album, artist: song.artist, price: 100 }
should have_key('title')
end
end
end

context "successful request" do
subject { JSON.parse(last_response.body) }

it "returns a song record" do
post "/songs", { title: "Awesome Song", artist: "Berna", album: "Top Hits", price: 100 }
song = Song.last

subject['id'].should == song.id
subject['title'].should == song.title
subject['artist'].should == song.artist
subject['album'].should == song.album
subject['price'].should == song.price
end

context "returns a list of songs in the server" do
before do
Song.destroy_all
100.times.each do
song = FactoryGirl.create :song
end
end

let(:url) { "/songs" }

it "should paginate the first 50 songs" do
get url
subject.should have_key("pagination")
subject["pagination"]["total"].should == 100
subject["pagination"]["total_pages"].should == 2
subject["pagination"]["current_page"].should == 1
subject.should have_key("songs")
subject["songs"].count.should eql(50)
end

it "should paginate the second 50 songs" do
get url, { page: 2 }
subject.should have_key("pagination")
subject["pagination"]["total"].should == 100
subject["pagination"]["total_pages"].should == 2
subject["pagination"]["current_page"].should == 2
subject.should have_key("songs")
subject["songs"].count.should eql(50)
end
end

context "returns a list of songs on sale" do
before do
Song.destroy_all
100.times.each do
song = FactoryGirl.create :song, price_in_cents: 100
end
end

let(:url) { "/songs/on_sale" }

it "should paginate the first 50 songs on sale" do
get url
subject.should have_key("pagination")
subject["pagination"]["total"].should == 100
subject["pagination"]["total_pages"].should == 2
subject["pagination"]["current_page"].should == 1
subject.should have_key("songs")
subject["songs"].count.should eql(50)
end

it "should paginate the second 50 songs on sale" do
get url, { page: 2 }
subject.should have_key("pagination")
subject["pagination"]["total"].should == 100
subject["pagination"]["total_pages"].should == 2
subject["pagination"]["current_page"].should == 2
subject.should have_key("songs")
subject["songs"].count.should eql(50)
end
end
end
end
2 changes: 1 addition & 1 deletion spec/models/song_spec.rb
Expand Up @@ -2,7 +2,7 @@

describe Song do
before do
Bar.delete_all
Song.delete_all
end

it "must have a title" do
Expand Down

0 comments on commit 2c8b325

Please sign in to comment.