VRFS-82 band invitation development

This commit is contained in:
Brian Smith 2012-11-24 13:23:13 -05:00
parent 54924bd322
commit 5197f85219
10 changed files with 408 additions and 71 deletions

View File

@ -115,6 +115,7 @@ class ApiBandsController < ApplicationController
params[:public],
params[:description],
params[:id],
params[:id],
true)
if @recording.errors.nil? || @recording.errors.size == 0
@ -129,7 +130,24 @@ class ApiBandsController < ApplicationController
end
def recording_destroy
# TODO: ensure current_user is band member
@recording = Recording.find(params[:recording_id])
@recording.delete
respond_with responder: ApiResponder, :status => 204
end
###################### INVITATIONS ######################
def invitation_index
# verify current_user is member of Band
@band = Band.find_by_id(params[:id])
unless @band.users.exists? current_user
raise PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
end
@invitations = BandInvitation.find_by_band_id(@band.id)
end
def invitation_create
end
end

View File

@ -26,6 +26,13 @@ class ApiController < ApplicationController
else
raise exception
end
end
protected
def auth_user(id)
if current_user.id != id
#respond_with "You do not have permissions to perform this action.", responder: ApiResponder, :status => 403
raise PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
end
end
end

View File

@ -84,7 +84,7 @@ class ApiUsersController < ApiController
def delete
@user = User.find(params[:id])
@user.destroy # required to make 'tire' integration work
respond_with @user, responder: ApiResponder
respond_with responder: ApiResponder, :status => 204
end
###################### FOLLOWERS ########################
@ -119,7 +119,7 @@ class ApiUsersController < ApiController
def following_destroy
auth_user(params[:id])
User.delete_user_following(params[:user_id], params[:id])
respond_with responder: ApiResponder
respond_with responder: ApiResponder, :status => 204
end
###################### RECORDINGS #######################
@ -205,8 +205,9 @@ class ApiUsersController < ApiController
def recording_destroy
auth_user(params[:id])
recording = Recording.find(params[:recording_id])
recording.delete
@recording = Recording.find(params[:recording_id])
@recording.delete
respond_with responder: ApiResponder, :status => 204
#Recording.delete(params[:recording_id], params[:id], false)
end
@ -229,7 +230,7 @@ class ApiUsersController < ApiController
def favorite_destroy
auth_user(params[:id])
User.delete_favorite(params[:id], params[:recording_id])
respond_with responder: ApiResponder
respond_with responder: ApiResponder, :status => 204
end
###################### FRIENDS ##########################
@ -285,7 +286,7 @@ class ApiUsersController < ApiController
auth_user(params[:id])
# clean up both records representing this "friendship"
JamRuby::Friendship.delete_all "(user_id = '#{params[:id]}' AND friend_id = '#{params[:friend_id]}') OR (user_id = '#{params[:friend_id]}' AND friend_id = '#{params[:id]}')"
respond_with responder: ApiResponder
respond_with responder: ApiResponder, :status => 204
end
###################### AUTHENTICATION ###################
@ -304,7 +305,7 @@ class ApiUsersController < ApiController
sign_out
render :json => { :success => true }, :status => 200
end
=begin
protected
def auth_user(id)
if current_user.id != id
@ -312,4 +313,5 @@ class ApiUsersController < ApiController
raise PermissionError, "You do not have permissions to perform this action."
end
end
=end
end

View File

@ -60,9 +60,9 @@ SampleApp::Application.routes.draw do
# friend requests
match '/users/:id/friend_requests' => 'api_users#friend_request_index', :via => :get
match '/friend_requests/:id' => 'api_users#friend_request_show', :via => :get, :as => 'api_friend_request_detail'
match '/friend_requests' => 'api_users#friend_request_create', :via => :post
match '/friend_requests/:id' => 'api_users#friend_request_update', :via => :put
match '/users/:id/friend_requests/:friend_request_id' => 'api_users#friend_request_show', :via => :get, :as => 'api_friend_request_detail'
match '/users/:id/friend_requests' => 'api_users#friend_request_create', :via => :post
match '/users/:id/friend_requests/:friend_request_id' => 'api_users#friend_request_update', :via => :post
# friends
match '/users/:id/friends' => 'api_users#friend_index', :via => :get
@ -84,6 +84,11 @@ SampleApp::Application.routes.draw do
match '/users/:id/recordings/:recording_id' => 'api_users#recording_update', :via => :post
match '/users/:id/recordings/:recording_id' => 'api_users#recording_destroy', :via => :delete
# user band invitations (NOT DONE)
match '/users/:id/band_invitations' => 'api_users#band_invitation_index', :via => :get
match '/users/:id/band_invitations/:invitation_id' => 'api_users#band_invitation_show', :via => :get, :as => 'api_band_invitation_detail'
match '/users/:id/band_invitations/:band_invitation_id' => 'api_users#band_invitation_update', :via => :post
# favorites
match '/users/:id/favorites' => 'api_users#favorite_index', :via => :get, :as => 'api_favorite_index'
match '/users/:id/favorites' => 'api_users#favorite_create', :via => :post
@ -95,6 +100,11 @@ SampleApp::Application.routes.draw do
match '/bands' => 'api_bands#create', :via => :post
match '/bands/:id' => 'api_bands#update', :via => :post
# band members (NOT DONE)
match '/bands/:id/musicians' => 'api_bands#musician_index', :via => :get
match '/bands/:id/musicians' => 'api_bands#musician_create', :via => :post
match '/bands/:id/musicians/:user_id' => 'api_bands#musician_destroy', :via => :delete
# band followers
match '/bands/:id/followers' => 'api_bands#follower_index', :via => :get
@ -105,6 +115,10 @@ SampleApp::Application.routes.draw do
match '/bands/:id/recordings/:recording_id' => 'api_bands#recording_update', :via => :post
match '/bands/:id/recordings/:recording_id' => 'api_bands#recording_destroy', :via => :delete
# band invitations (NOT DONE)
match '/bands/:id/invitations' => 'api_bands#invitation_index', :via => :get
match '/bands/:id/invitations' => 'api_bands#invitation_create', :via => :post
# invitations
match '/invitations/:id' => 'api_invitations#show', :via => :get, :as => 'api_invitation_detail'
match '/invitations/:id' => 'api_invitations#delete', :via => :delete

View File

@ -11,10 +11,96 @@ describe "Band API", :type => :api do
let(:user) { FactoryGirl.create(:user) }
let(:fan) { FactoryGirl.create(:fan) }
it "should allow musician to create band" do
def login(email, password, http_code, success)
# login as fan
post '/api/auth_session.json', { :email => email, :password => password }.to_json, "CONTENT_TYPE" => 'application/json'
last_response.status.should == http_code
JSON.parse(last_response.body).should == { "success" => success }
end
it "should not allow fan to create band" do
context "when logged in as musician" do
it "should allow band creation" do
# ensure creator is member and admin of band
end
end
context "when logged in as musician who is in Band A" do
context "who is band admin" do
it "should allow user to send invitation" do
end
end
context "who is not band admin" do
it "should not allow user to send invitation" do
end
end
it "should allow user to update attributes of band A" do
end
it "should allow user to create invitation to band A" do
end
it "should allow user to create recording for band A" do
end
it "should allow user to update recording of band A" do
end
it "should allow user to delete recording of Band A" do
end
it "should allow user to view public recording of Band A" do
end
it "should allow user to view private recording of Band A" do
end
it "should allow user to see invitation list of band A" do
end
end
context "when logged in as musician who is not in band A" do
it "should not allow user to update attributes of band A" do
end
it "should not allow user to create invitation for band A" do
end
it "should not allow user to create recording for band A" do
end
it "should not allow user to update recording of band A" do
end
it "should not allow user to delete recording of Band A" do
end
it "should allow user to view public recording of Band A" do
end
it "should not allow user to view private recording of Band A" do
end
it "should not allow user to see invitation list of band A" do
end
end
context "when logged in as band invitation recipient" do
it "should allow acceptance of invitation" do
# ensure recipient is now member of band
end
it "should allow declining of invitation" do
end
end
context "when logged in as fan" do
it "should not allow band creation" do
end
it "should not allow band invitation creation" do
end
end
end
end

View File

@ -9,6 +9,7 @@ describe "User API", :type => :api do
describe "profile" do
let(:user) { FactoryGirl.create(:user) }
let(:fan) { FactoryGirl.create(:fan) }
let(:band) { FactoryGirl.create(:band) }
before(:each) do
UserMailer.deliveries.clear
@ -21,7 +22,99 @@ describe "User API", :type => :api do
JSON.parse(last_response.body).should == { "success" => success }
end
context "unauthenticated user" do
########################## FOLLOWINGS / FOLLOWERS #########################
def create_user_following(authenticated_user, source_user, target_user)
login(authenticated_user.email, authenticated_user.password, 200, true)
post "/api/users/#{source_user.id}/followings.json", { :user_id => target_user.id }.to_json, "CONTENT_TYPE" => 'application/json'
return last_response
end
def get_user_followings(authenticated_user, source_user)
login(authenticated_user.email, authenticated_user.password, 200, true)
get "/api/users/#{source_user.id}/followings.json"
return last_response
end
def get_user_followers(authenticated_user, source_user)
login(authenticated_user.email, authenticated_user.password, 200, true)
get "/api/users/#{source_user.id}/followers.json"
return last_response
end
def delete_user_following(authenticated_user, source_user, target_user)
login(authenticated_user.email, authenticated_user.password, 200, true)
delete "/api/users/#{source_user.id}/followings/#{target_user.id}.json"
return last_response
end
def create_band_following(authenticated_user, source_user, target_band)
login(authenticated_user.email, authenticated_user.password, 200, true)
post "/api/users/#{source_user.id}/followings.json", { :band_id => target_band.id }.to_json, "CONTENT_TYPE" => 'application/json'
return last_response
end
def get_band_followings(authenticated_user, source_user)
login(authenticated_user.email, authenticated_user.password, 200, true)
get "/api/users/#{source_user.id}/band_followings.json"
return last_response
end
def get_band_followers(authenticated_user, source_band)
login(authenticated_user.email, authenticated_user.password, 200, true)
get "/api/bands/#{source_band.id}/followers.json"
return last_response
end
########################## RECORDINGS #########################
def create_user_recording(authenticated_user, source_user, description, public)
login(authenticated_user.email, authenticated_user.password, 200, true)
post "/api/users/#{source_user.id}/recordings.json", { :description => description, :public => public }.to_json, "CONTENT_TYPE" => 'application/json'
return last_response
end
def update_user_recording(authenticated_user, source_user, recording_id, description, public)
login(authenticated_user.email, authenticated_user.password, 200, true)
post "/api/users/#{source_user.id}/recordings/#{recording_id}.json", { :description => description, :public => public }.to_json, "CONTENT_TYPE" => 'application/json'
return last_response
end
def get_user_recordings(authenticated_user, source_user)
login(authenticated_user.email, authenticated_user.password, 200, true)
get "/api/users/#{source_user.id}/recordings.json"
return last_response
end
def get_user_recording(authenticated_user, source_user, recording_id)
login(authenticated_user.email, authenticated_user.password, 200, true)
get "/api/users/#{source_user.id}/recordings/#{recording_id}.json"
return last_response
end
def delete_user_recording(authenticated_user, source_user, recording_id)
login(authenticated_user.email, authenticated_user.password, 200, true)
delete "/api/users/#{source_user.id}/recordings/#{recording_id}.json"
return last_response
end
########################## FAVORITES #########################
def create_favorite(authenticated_user, source_user, recording_id)
login(authenticated_user.email, authenticated_user.password, 200, true)
post "/api/users/#{source_user.id}/favorites.json", { :recording_id => recording_id }.to_json, "CONTENT_TYPE" => 'application/json'
return last_response
end
def get_favorites(authenticated_user, source_user)
login(authenticated_user.email, authenticated_user.password, 200, true)
get "/api/users/#{source_user.id}/favorites.json"
return last_response
end
def delete_favorite(authenticated_user, source_user, recording_id)
login(authenticated_user.email, authenticated_user.password, 200, true)
delete "/api/users/#{source_user.id}/favorites/#{recording_id}.json"
end
context "when accessing as unauthenticated user" do
it "should allow successful login" do
# can't access most apis; not logged in yet!'
@ -54,16 +147,8 @@ describe "User API", :type => :api do
end
end
context "authenticated user" do
context "when accessing as authenticated user" do
# log in a valid user
=begin
before do
puts "logging in"
post '/sessions', "session[email]" => fan.email, "session[password]" => fan.password
rack_mock_session.cookie_jar["remember_token"].should == fan.remember_token
end
=end
it "should allow user updates" do
# login as fan
@ -86,21 +171,18 @@ describe "User API", :type => :api do
it "should allow user to follow user" do
# create user following
login(user.email, user.password, 200, true)
post "/api/users/#{user.id}/followings.json", { :user_id => fan.id }.to_json, "CONTENT_TYPE" => 'application/json'
last_response = create_user_following(user, user, fan)
last_response.status.should == 201
# get following
login(user.email, user.password, 200, true)
get "/api/users/#{user.id}/followings.json"
# get followings
last_response = get_user_followings(user, user)
last_response.status.should == 200
followings = JSON.parse(last_response.body)
followings.size.should == 1
followings[0]["user_id"].should == fan.id
# get followers for other side of above following (fan)
login(fan.email, fan.password, 200, true)
get "/api/users/#{fan.id}/followers.json"
last_response = get_user_followers(fan, fan)
last_response.status.should == 200
followers = JSON.parse(last_response.body)
followers.size.should == 1
@ -109,93 +191,188 @@ describe "User API", :type => :api do
it "should allow user to follow band" do
# create band following
login(user.email, user.password, 200, true)
band = FactoryGirl.create(:band)
post "/api/users/#{user.id}/followings.json", { :band_id => band.id }.to_json, "CONTENT_TYPE" => 'application/json'
last_response = create_band_following(user, user, band)
last_response.status.should == 201
# get following
login(user.email, user.password, 200, true)
get "/api/users/#{user.id}/band_followings.json"
# get band followings
last_response = get_band_followings(user, user)
last_response.status.should == 200
followings = JSON.parse(last_response.body)
followings.size.should == 1
followings[0]["band_id"].should == band.id
# get followers for band
login(user.email, user.password, 200, true)
get "/api/bands/#{band.id}/followers.json"
last_response = get_band_followers(user, band)
last_response.status.should == 200
followers = JSON.parse(last_response.body)
followers.size.should == 1
followers[0]["user_id"].should == user.id
# delete followings
end
it "should not allow user to create following for another user" do
login(user.email, user.password, 200, true)
post "/api/users/10/followings.json", { :user_id => fan.id }.to_json, "CONTENT_TYPE" => 'application/json'
dummy_user = FactoryGirl.create(:user)
last_response = create_user_following(user, dummy_user, fan)
last_response.status.should == 403
end
it "should allow user to delete following" do
last_response = create_user_following(user, user, fan)
last_response.status.should == 201
# get followings
last_response = get_user_followings(user, user)
last_response.status.should == 200
followings = JSON.parse(last_response.body)
followings.size.should == 1
followings[0]["user_id"].should == fan.id
# delete following
last_response = delete_user_following(user, user, fan)
last_response.status.should == 204
# get followings
last_response = get_user_followings(user, user)
last_response.status.should == 200
followings = JSON.parse(last_response.body)
followings.size.should == 0
end
it "should not allow user to delete following of another user" do
# create user following
last_response = create_user_following(user, user, fan)
last_response.status.should == 201
# get followings
last_response = get_user_followings(user, user)
last_response.status.should == 200
followings = JSON.parse(last_response.body)
followings.size.should == 1
followings[0]["user_id"].should == fan.id
# attempt to delete following of another user
last_response = delete_user_following(fan, user, fan)
last_response.status.should == 403
# get followings
last_response = get_user_followings(user, user)
last_response.status.should == 200
followings = JSON.parse(last_response.body)
followings.size.should == 1
end
it "should allow musician to create recordings" do
# create public recording
login(user.email, user.password, 200, true)
post "/api/users/#{user.id}/recordings.json", { :description => "My Recording", :public => true }.to_json, "CONTENT_TYPE" => 'application/json'
public_description = "My Public Recording"
last_response = create_user_recording(user, user, public_description, true)
last_response.status.should == 201
recording = JSON.parse(last_response.body)
recording["description"].should == "My Recording"
recording["description"].should == public_description
recording["public"].should == true
# create private recording
login(user.email, user.password, 200, true)
post "/api/users/#{user.id}/recordings.json", { :description => "My Recording 2", :public => false }.to_json, "CONTENT_TYPE" => 'application/json'
private_description = "My Private Recording"
last_response = create_user_recording(user, user, private_description, false)
last_response.status.should == 201
private_recording = JSON.parse(last_response.body)
private_recording["description"].should == private_description
private_recording["public"].should == false
# get all recordings as creator
login(user.email, user.password, 200, true)
get "/api/users/#{user.id}/recordings.json"
# update the second recording's description and public flag
last_response = update_user_recording(user, user, private_recording["id"], "My Recording 3", true)
last_response.status.should == 200
recordings = JSON.parse(last_response.body)
recordings.size.should == 2
recording = JSON.parse(last_response.body)
recording["description"].should == "My Recording 3"
recording["public"].should == true
# get all recordings as non-creator
login(fan.email, fan.password, 200, true)
get "/api/users/#{user.id}/recordings.json"
# retrieve the recording details again to ensure the change took effect
last_response = get_user_recording(user, user, recording["id"])
last_response.status.should == 200
recordings = JSON.parse(last_response.body)
recordings.size.should == 1
# attempt to get the private recording
login(fan.email, fan.password, 200, true)
get "/api/users/#{user.id}/recordings/#{private_recording["id"]}.json"
last_response.status.should == 403
recording = JSON.parse(last_response.body)
recording["description"].should == "My Recording 3"
recording["public"].should == true
end
it "should not allow fan to create recordings" do
login(fan.email, fan.password, 200, true)
post "/api/users/#{fan.id}/recordings.json", { :description => "My Recording", :public => true }.to_json, "CONTENT_TYPE" => 'application/json'
last_response = create_user_recording(fan, fan, "Fan Recording", true)
last_response.status.should == 403
end
it "should allow creator to see public and private recordings in list" do
# create public recording
public_description = "My Public Recording"
last_response = create_user_recording(user, user, public_description, true)
last_response.status.should == 201
# create private recording
private_description = "My Private Recording"
last_response = create_user_recording(user, user, private_description, false)
last_response.status.should == 201
# get all recordings as creator
last_response = get_user_recordings(user, user)
recordings = JSON.parse(last_response.body)
recordings.size.should == 2
end
it "should allow creator to see private recording details" do
# create private recording
private_description = "My Private Recording"
last_response = create_user_recording(user, user, private_description, false)
last_response.status.should == 201
private_recording = JSON.parse(last_response.body)
private_recording["description"].should == private_description
private_recording["public"].should == false
# attempt to get the private recording as non-creator
last_response = get_user_recording(user, user, private_recording["id"])
last_response.status.should == 200
end
it "should not allow non-creator to see private recordings in list" do
# create public recording
public_description = "My Public Recording"
last_response = create_user_recording(user, user, public_description, true)
last_response.status.should == 201
# create private recording
private_description = "My Private Recording"
last_response = create_user_recording(user, user, private_description, false)
last_response.status.should == 201
# get all recordings as non-creator
last_response = get_user_recordings(fan, user)
recordings = JSON.parse(last_response.body)
recordings.size.should == 1
recordings[0]["description"].should == public_description
recordings[0]["public"].should == true
end
it "should not allow non-creator to see private recording details" do
# create private recording
private_description = "My Private Recording"
last_response = create_user_recording(user, user, private_description, false)
last_response.status.should == 201
private_recording = JSON.parse(last_response.body)
private_recording["description"].should == private_description
private_recording["public"].should == false
# attempt to get the private recording as non-creator
last_response = get_user_recording(fan, user, private_recording["id"])
last_response.status.should == 403
end
it "should allow user to create favorites" do
# create recording first
login(user.email, user.password, 200, true)
post "/api/users/#{user.id}/recordings.json", { :description => "My Recording", :public => true }.to_json, "CONTENT_TYPE" => 'application/json'
last_response = create_user_recording(user, user, "My Recording", true)
last_response.status.should == 201
recording = JSON.parse(last_response.body)
# add favorite
login(user.email, user.password, 200, true)
post "/api/users/#{user.id}/favorites.json", { :recording_id => recording["id"] }.to_json, "CONTENT_TYPE" => 'application/json'
last_response = create_favorite(fan, fan, recording["id"])
last_response.status.should == 201
login(user.email, user.password, 200, true)
get "/api/users/#{user.id}/favorites.json"
# get favorites
last_response = get_favorites(fan, fan)
last_response.status.should == 200
favorites = JSON.parse(last_response.body)
favorites.size.should == 1
@ -205,9 +382,42 @@ describe "User API", :type => :api do
end
it "should not allow user to create favorite for another user" do
# create recording first
last_response = create_user_recording(user, user, "My Recording", true)
last_response.status.should == 201
recording = JSON.parse(last_response.body)
# attempt to add favorite for another user
last_response = create_favorite(fan, user, recording["id"])
last_response.status.should == 403
end
it "should allow user to delete favorites" do
# create recording first
last_response = create_user_recording(user, user, "My Recording", true)
last_response.status.should == 201
recording = JSON.parse(last_response.body)
# delete favorite
last_response = delete_favorite(user, user, recording["id"])
last_response.status.should == 204
# get favorites
last_response = get_favorites(user, user)
last_response.status.should == 200
favorites = JSON.parse(last_response.body)
favorites.size.should == 0
end
it "should not allow user to delete another user's favorites" do
# create recording first
last_response = create_user_recording(user, user, "My Recording", true)
last_response.status.should == 201
recording = JSON.parse(last_response.body)
# attempt to delete favorite as non-creator
last_response = delete_favorite(fan, user, recording["id"])
last_response.status.should == 403
end
it "should allow user to send friend request" do