Merge branch 'invitations'
This commit is contained in:
commit
6925eb89c3
|
|
@ -0,0 +1,31 @@
|
|||
class ApiController < ApplicationController
|
||||
|
||||
@@log = Logging.logger[ApiController]
|
||||
|
||||
# define common error handlers
|
||||
rescue_from 'JamRuby::StateError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/state_error.rabl", :status => 500
|
||||
end
|
||||
rescue_from 'JamRuby::JamArgrumentError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/jam_argument_error", :status => 500
|
||||
end
|
||||
rescue_from 'JamRuby::PermissionError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/permission_error", :status => 500
|
||||
end
|
||||
rescue_from 'ActiveRecord::RecordNotFound' do |exception|
|
||||
@@log.debug(exception)
|
||||
render :json => { :errors => { :resource => ["record not found"] } }, :status => 404
|
||||
end
|
||||
rescue_from 'PG::Error' do |exception|
|
||||
@@log.debug(exception)
|
||||
if exception.to_s.include? "duplicate key value violates unique constraint"
|
||||
render :json => { :errors => { :resource => ["resource already exists"] } }, :status => 409 # 409 = conflict
|
||||
else
|
||||
raise exception
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
class ApiInvitationsController < ApiController
|
||||
|
||||
# have to be signed in currently to see this screen
|
||||
before_filter :signed_in_user
|
||||
|
||||
respond_to :json
|
||||
|
||||
def initialize
|
||||
@mq_router = MQRouter.new
|
||||
@message_factory = MessageFactory.new
|
||||
|
||||
end
|
||||
|
||||
def index
|
||||
conditions = {}
|
||||
sender_id = params[:sender]
|
||||
receiver_id = params[:receiver]
|
||||
|
||||
if !sender_id.nil?
|
||||
if current_user.id != sender_id
|
||||
raise PermissionError, "You can only ask for your own sent invitations"
|
||||
end
|
||||
|
||||
@invitations = Invitation.where(:sender_id => current_user.id)
|
||||
elsif !receiver_id.nil?
|
||||
if current_user.id != receiver_id
|
||||
raise PermissionError, "You can only ask for your own received invitations"
|
||||
end
|
||||
|
||||
@invitations = Invitation.where(:receiver_id => current_user.id)
|
||||
else
|
||||
# default to invitations you've received
|
||||
@invitations = Invitation.where(:receiver_id => current_user.id)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
music_session = MusicSession.find(params[:music_session])
|
||||
receiver = User.find(params[:receiver])
|
||||
sender = current_user
|
||||
|
||||
@invitation = Invitation.new
|
||||
@invitation.music_session = music_session
|
||||
@invitation.sender = sender
|
||||
@invitation.receiver = receiver
|
||||
|
||||
@invitation.save
|
||||
|
||||
unless @invitation.errors.any?
|
||||
invitation_notification = @message_factory.session_invitation(receiver.id, @invitation.id)
|
||||
@mq_router.publish_to_user(receiver.id, invitation_notification)
|
||||
end
|
||||
|
||||
if @invitation.errors.any?
|
||||
# we have to do this because api_invitation_detail_url will fail with a bad @invitation
|
||||
response.status = :unprocessable_entity
|
||||
respond_with @invitation
|
||||
else
|
||||
respond_with @invitation, :responder => ApiResponder, :location => api_invitation_detail_url(@invitation)
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@invitation = Invitation.find(params[:id], :conditions => ["receiver_id = ? or sender_id = ?", current_user.id, current_user.id])
|
||||
end
|
||||
|
||||
def delete
|
||||
@invitation = Invitation.find(params[:id], :conditions => ["receiver_id = ? or sender_id = ?", current_user.id, current_user.id])
|
||||
@invitation.delete
|
||||
|
||||
respond_with @invitation, responder => ApiResponder
|
||||
end
|
||||
end
|
||||
|
|
@ -1,23 +1,5 @@
|
|||
class ApiMusicSessionsController < ApplicationController
|
||||
|
||||
# TODO: roll these into a base ApiController class?s
|
||||
rescue_from 'JamRuby::StateError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/state_error.rabl", :status => 500
|
||||
end
|
||||
rescue_from 'JamRuby::JamArgrumentError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/jam_argument_error.rabl", :status => 500
|
||||
end
|
||||
rescue_from 'JamRuby::PermissionError' do |exception|
|
||||
@exception = exception
|
||||
render "errors/permission_error.rabl", :status => 500
|
||||
end
|
||||
|
||||
rescue_from 'ActiveRecord::RecordNotFound' do |exception|
|
||||
render :json => {:message => exception.message}, :status => 404
|
||||
end
|
||||
|
||||
class ApiMusicSessionsController < ApiController
|
||||
|
||||
# have to be signed in currently to see this screen
|
||||
before_filter :signed_in_user
|
||||
|
||||
|
|
@ -66,7 +48,7 @@ class ApiMusicSessionsController < ApplicationController
|
|||
end
|
||||
|
||||
if @music_session.errors.any?
|
||||
# we have to do this because api_session_detail_url will fail with a bad @music_session (or something like it)
|
||||
# we have to do this because api_session_detail_url will fail with a bad @music_session
|
||||
response.status = :unprocessable_entity
|
||||
respond_with @music_session
|
||||
else
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
object @invitation
|
||||
|
||||
extends "api_invitations/invitation"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
object @invitations
|
||||
|
||||
extends "api_invitations/invitation"
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
object @invitation
|
||||
|
||||
attributes :id
|
||||
|
||||
child(:sender => :sender) {
|
||||
attributes :id, :name
|
||||
}
|
||||
|
||||
child(:receiver => :receiver) {
|
||||
attributes :id, :name
|
||||
}
|
||||
|
||||
child(:music_session) {
|
||||
attributes :id, :description
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
object @invitation
|
||||
|
||||
extends "api_invitations/invitation"
|
||||
|
|
@ -52,5 +52,11 @@ SampleApp::Application.routes.draw do
|
|||
# friends
|
||||
match '/users/:id/friends' => 'api_users#friend_index', :via => :get
|
||||
match '/users/:id/friends/:friend_id' => 'api_users#friend_destroy', :via => :delete
|
||||
|
||||
# invitations
|
||||
match '/invitations/:id' => 'api_invitations#show', :via => :get, :as => 'api_invitation_detail'
|
||||
match '/invitations/:id' => 'api_invitations#delete', :via => :delete
|
||||
match '/invitations' => 'api_invitations#index', :via => :get
|
||||
match '/invitations' => 'api_invitations#create', :via => :post
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,8 +10,19 @@ FactoryGirl.define do
|
|||
end
|
||||
end
|
||||
|
||||
factory :music_session, :class => JamRuby::MusicSession do
|
||||
sequence(:description) { |n| "Music Session #{n}" }
|
||||
end
|
||||
|
||||
factory :connection, :class => JamRuby::Connection do
|
||||
sequence(:client_id) { |n| "Client#{n}" }
|
||||
end
|
||||
|
||||
factory :friendship, :class => JamRuby::Friendship do
|
||||
|
||||
end
|
||||
|
||||
factory :invitation, :class => JamRuby::Invitation do
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "Invitation API ", :type => :api do
|
||||
|
||||
include Rack::Test::Methods
|
||||
|
||||
subject { page }
|
||||
|
||||
describe "profile page" do
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
before do
|
||||
#sign_in user
|
||||
MusicSession.delete_all
|
||||
|
||||
post '/sessions', "session[email]" => user.email, "session[password]" => user.password
|
||||
rack_mock_session.cookie_jar["remember_token"].should == user.remember_token
|
||||
end
|
||||
|
||||
it "list no invitations" do
|
||||
get '/api/invitations.json'
|
||||
last_response.body.should eql('[]')
|
||||
end
|
||||
|
||||
it "invitation requires receiver" do
|
||||
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user)
|
||||
connection = FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
|
||||
post '/api/invitations.json', {:music_session => music_session.id}
|
||||
last_response.status.should eql(404)
|
||||
end
|
||||
|
||||
it "invitation can only be sent if you belong to the music session and to friends" do
|
||||
|
||||
other_user = FactoryGirl.create(:user) # in the music session
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => other_user)
|
||||
connection = FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
|
||||
|
||||
post '/api/invitations.json', {:music_session => music_session.id, :receiver => other_user.id}
|
||||
last_response.status.should eql(422)
|
||||
response = JSON.parse(last_response.body)
|
||||
response["errors"].should_not == nil
|
||||
response["errors"]["music_session"][0].should == Invitation::MEMBERSHIP_REQUIRED_OF_MUSIC_SESSION
|
||||
response["errors"]["receiver"][0].should == Invitation::FRIENDSHIP_REQUIRED_VALIDATION_ERROR
|
||||
end
|
||||
|
||||
it "should create a invitation" do
|
||||
other_user = FactoryGirl.create(:user) # in the music session
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => other_user)
|
||||
FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
|
||||
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
|
||||
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
|
||||
|
||||
post '/api/invitations.json', {:music_session => music_session.id, :receiver => other_user.id}.to_json, "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(201)
|
||||
|
||||
# and verify that the response is the same as if we use the GET api
|
||||
response1 = JSON.parse(last_response.body)
|
||||
get "/api/invitations/#{response1["id"]}.json"
|
||||
response1.should == JSON.parse(last_response.body)
|
||||
end
|
||||
|
||||
it "should list invitations" do
|
||||
other_user = FactoryGirl.create(:user) # in the music session
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => other_user)
|
||||
FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
|
||||
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
|
||||
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
|
||||
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
|
||||
|
||||
# see that there are no invitations sent to us
|
||||
get '/api/invitations.json'
|
||||
response = JSON.parse(last_response.body)
|
||||
response.should == []
|
||||
|
||||
# then check that there is one invitation sent by us
|
||||
get '/api/invitations.json?sender=' + user.id
|
||||
response = JSON.parse(last_response.body)
|
||||
response.length.should == 1
|
||||
response[0]["id"].should == invitation.id
|
||||
|
||||
# create an invitation the other way
|
||||
invitation = FactoryGirl.create(:invitation, :sender => other_user, :receiver => user, :music_session => music_session)
|
||||
# see that there is one invitations sent to us
|
||||
get '/api/invitations.json'
|
||||
response = JSON.parse(last_response.body)
|
||||
response.length.should == 1
|
||||
response[0]["id"].should == invitation.id
|
||||
end
|
||||
|
||||
it "should return a already-created error message and 409 response" do
|
||||
|
||||
other_user = FactoryGirl.create(:user) # in the music session
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => other_user)
|
||||
FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
|
||||
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
|
||||
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
|
||||
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
|
||||
|
||||
post '/api/invitations.json', {:music_session => music_session.id, :receiver => other_user.id}.to_json, "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(409)
|
||||
response = JSON.parse(last_response.body)
|
||||
response["errors"]["resource"][0].should == "resource already exists"
|
||||
|
||||
end
|
||||
|
||||
it "should delete" do
|
||||
|
||||
other_user = FactoryGirl.create(:user) # in the music session
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => other_user)
|
||||
FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
|
||||
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
|
||||
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
|
||||
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
|
||||
|
||||
# refind the invitation to make sure the db serves it up
|
||||
Invitation.find_by_id(invitation.id).should_not == nil
|
||||
|
||||
delete "/api/invitations/#{invitation.id}.json", "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(204)
|
||||
|
||||
# and then verify that the invitation is gone
|
||||
Invitation.find_by_id(invitation.id).should == nil
|
||||
end
|
||||
|
||||
it "should delete by deletion of music session" do
|
||||
|
||||
other_user = FactoryGirl.create(:user) # in the music session
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => other_user)
|
||||
FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
|
||||
FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => other_user)
|
||||
FactoryGirl.create(:friendship, :user => other_user, :friend => user)
|
||||
invitation = FactoryGirl.create(:invitation, :sender => user, :receiver => other_user, :music_session => music_session)
|
||||
|
||||
# refind the invitation to make sure the db serves it up
|
||||
Invitation.find_by_id(invitation.id).should_not == nil
|
||||
|
||||
delete "/api/sessions/#{music_session.id}.json", "CONTENT_TYPE" => 'application/json'
|
||||
last_response.status.should eql(204)
|
||||
|
||||
# and then verify that the invitation is gone
|
||||
Invitation.find_by_id(invitation.id).should == nil
|
||||
end
|
||||
|
||||
it "should not allow query of invitations not belonging to current user" do
|
||||
|
||||
other_user = FactoryGirl.create(:user) # in the music session
|
||||
other_user2 = FactoryGirl.create(:user) # in the music session
|
||||
# starting condition; valid session and current user is already in it
|
||||
music_session = FactoryGirl.create(:music_session, :creator => other_user)
|
||||
FactoryGirl.create(:connection, :user => other_user, :music_session => music_session)
|
||||
FactoryGirl.create(:connection, :user => other_user2, :music_session => music_session)
|
||||
FactoryGirl.create(:friendship, :user => other_user2, :friend => other_user)
|
||||
FactoryGirl.create(:friendship, :user => other_user, :friend => other_user2)
|
||||
invitation = FactoryGirl.create(:invitation, :sender => other_user2, :receiver => other_user, :music_session => music_session)
|
||||
|
||||
|
||||
# then check that there is one invitation sent by us
|
||||
get '/api/invitations.json?sender=' + other_user.id
|
||||
last_response.status.should eql(500)
|
||||
response = JSON.parse(last_response.body)
|
||||
response.should == {"message" => "You can only ask for your own sent invitations","type" => "PermissionError"}
|
||||
|
||||
# also check that a fetch by id doesn't work
|
||||
get "/api/invitations/#{invitation.id}"
|
||||
last_response.status.should eql(404)
|
||||
|
||||
# and that delete by id doesn't work
|
||||
delete "/api/invitations/#{invitation.id}"
|
||||
last_response.status.should eql(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue