Permalink
Browse files

Merge pull request #144 from stravid/chore/store-current-run

Pull Request: chore/store-current-run
  • Loading branch information...
2 parents aba52a1 + 977ca0d commit 110b77da80b2ca3141eeb6b5b3eb3629076b995a Dominik Guzei committed Apr 20, 2012
@@ -26,6 +26,17 @@ Play.GameController = Shared.BaseGameController.extend
@set 'carControlsEnabled', false
@isTouchMouseDown = false
+ @saveRaceTime() if Shared.User.current
+
+ saveRaceTime: ->
+ Shared.Run.createRecord
+ track: @track
+ time: @get 'raceTime'
+ user: Shared.User.current
+
+ Shared.ModelStore.commit()
+
+
onCarCrossedFinishLine: (->
car = @get 'car'
if car.get 'crossedFinishLine' then @finish()
@@ -0,0 +1,15 @@
+class Api::RunsController < ApplicationController
+ def create
+ return head :bad_request if params[:run].nil? || current_user.nil?
+
+ return head :bad_request if Track.find_by_id(params[:run][:track_id]).nil?
+
+ run = current_user.runs.new params[:run]
+
+ if run.save
+ render :json => run, :status => :created
+ else
+ head :error
+ end
+ end
+end
View
@@ -1,4 +1,6 @@
class Run < ActiveRecord::Base
belongs_to :user
belongs_to :track
+
+ validates :time, :numericality => { :only_integer => true, :greater_than => 0 }
end
@@ -0,0 +1,3 @@
+class RunSerializer < ActiveModel::Serializer
+ attributes :id, :time, :track_id, :user_id
+end
View
@@ -10,6 +10,7 @@
namespace :api do
resources :tracks, :only => [:index, :show, :create]
+ resources :runs, :only => [:create]
end
devise_scope :user do
@@ -0,0 +1,62 @@
+require 'spec_helper'
+
+describe Api::RunsController do
+
+ describe '#create' do
+
+ let(:track) { FactoryGirl.create :track }
+ let(:user) { FactoryGirl.create :user }
+
+ it 'should return a bad request error code when params hash does not contain a `run` key' do
+ post :create, :random_key => 'woot'
+
+ response.should be_bad_request
+ end
+
+ it 'should return a bad request error code when there is no current user' do
+ post :create, :run => { :time => 14442, :track_id => track.id }
+
+ response.should be_bad_request
+ end
+
+ it 'should create a run with passed parameters' do
+ sign_in user
+ time = 14442
+ post :create, :run => { :time => time, :track_id => track.id }
+
+ response.code.should eq '201'
+ Run.last.time.should eq time
+ Run.last.track_id.should eq track.id
+ Run.last.user_id.should eq user.id
+ end
+
+ it 'should serialize created run and return it as JSON' do
+ sign_in user
+ post :create, :run => { :time => 1337, :track_id => track.id }
+
+ created_run = Run.last
+
+ serializer = RunSerializer.new created_run, :root => 'run'
+ serialized_run = serializer.as_json
+
+ response.body.should == serialized_run.to_json
+ end
+
+ it 'should return a bad request error code if the track_id is invalid' do
+ sign_in user
+
+ post :create, :run => { :time => 1337, :track_id => Track.count + 1 }
+
+ response.should be_bad_request
+ end
+
+ it 'should return a server error when creating a run fails' do
+ sign_in user
+
+ post :create, :run => { :time => -42, :track_id => track.id }
+
+ response.should be_error
+ end
+ end
+
+end
View
@@ -11,5 +11,4 @@
sequence :invalid_raphael_path do |n|
"string#{n}"
end
-
end
View
@@ -1,6 +1,5 @@
-# Read about factories at https://github.com/thoughtbot/factory_girl
-
FactoryGirl.define do
factory :run do
+ time { Random.rand 10000 }
end
end
@@ -1,6 +1,8 @@
describe 'Play.GameController (unit)', ->
beforeEach ->
+ @xhr = sinon.useFakeXMLHttpRequest()
+
@carMock = mockEmberClass Shared.Car,
update: sinon.spy()
reset: sinon.spy()
@@ -14,6 +16,8 @@ describe 'Play.GameController (unit)', ->
car: @carMock
afterEach ->
+ @xhr.restore()
+
@carMock.restore()
@trackMock.restore()
@@ -63,6 +67,7 @@ describe 'Play.GameController (unit)', ->
beforeEach ->
@gameController.carControlsEnabled = true
@gameController.isTouchMouseDown = true
+ sinon.spy @gameController, 'saveRaceTime'
it 'should save timestamp', ->
@gameController.finish()
@@ -87,6 +92,19 @@ describe 'Play.GameController (unit)', ->
(expect @gameController.get 'isRaceFinished').toBe true
+ it 'should call saveRaceTime if Shared.User.current is present', ->
+ Shared.User.current = {}
+ @gameController.finish()
+
+ (expect @gameController.saveRaceTime).toHaveBeenCalled()
+
+ it 'should not call saveRaceTime if Shared.User.current is not present', ->
+ Shared.User.current = null
+ @gameController.finish()
+
+ (expect @gameController.saveRaceTime).not.toHaveBeenCalled()
+
+
describe 'observing crossed finish line property of car', ->
beforeEach ->
@@ -217,3 +235,28 @@ describe 'Play.GameController (unit)', ->
@gameController.destroy()
(expect @gameController.set).toHaveBeenCalledWith 'carControlsEnabled', false
+
+ describe 'saveRaceTime', ->
+
+ beforeEach ->
+ sinon.spy Shared.Run, 'createRecord'
+ sinon.spy Shared.ModelStore, 'commit'
+
+ afterEach ->
+ Shared.Run.createRecord.restore()
+ Shared.ModelStore.commit.restore()
+
+ it 'should create a new Run record', ->
+ time = 100
+ @gameController.set 'raceTime', time
+ @gameController.saveRaceTime()
+
+ (expect Shared.Run.createRecord).toHaveBeenCalledWithAnObjectLike
+ track: @trackMock
+ time: time
+ user: Shared.User.current
+
+ it 'should call commit on the ModelStore', ->
+ @gameController.saveRaceTime()
+
+ (expect Shared.ModelStore.commit).toHaveBeenCalled()
View
@@ -3,4 +3,7 @@
describe Run do
it { should belong_to :user }
it { should belong_to :track }
+ it { should validate_numericality_of :time }
+ it { should_not allow_value(-10).for :time }
+ it { should_not allow_value(10.1).for :time }
end
@@ -1,12 +1,12 @@
describe "Tracks" do
- it "routes /api/tracks to api::tracks#index" do
+ it "routes GET /api/tracks to api::tracks#index" do
{ :get => "/api/tracks" }.should route_to(
:controller => "api/tracks",
:action => "index"
)
end
- it "routes /api/tracks/:id to api::tracks#show with params" do
+ it "routes GET /api/tracks/:id to api::tracks#show with params" do
{ :get => "/api/tracks/1" }.should route_to(
:controller => "api/tracks",
:action => "show",
@@ -25,7 +25,7 @@
describe "Users" do
- it "routes post /api/users to devise::registrations#create" do
+ it "routes POST /api/users to devise::registrations#create" do
{ :post => "api/users" }.should route_to(
:controller => "devise/registrations",
:action => "create"
@@ -36,7 +36,7 @@
describe "Sessions" do
- it "routes post /api/sign_in to api::sessions#create" do
+ it "routes POST /api/sign_in to api::sessions#create" do
{ :post => "api/sign_in" }.should route_to(
:controller => "api/sessions",
:action => "create"
@@ -49,5 +49,15 @@
:action => "destroy"
)
end
+end
+
+describe "Runs" do
+
+ it "routes POST /api/runs to api::runs#create" do
+ { :post => "api/runs" }.should route_to(
+ :controller => "api/runs",
+ :action => "create"
+ )
+ end
end

0 comments on commit 110b77d

Please sign in to comment.