* VRFS-1160 - favorites REST API done
This commit is contained in:
parent
061c74f8c6
commit
aab902e8cf
|
|
@ -114,4 +114,5 @@ feed_autoincrement_primary_key.sql
|
|||
music_sessions_plays.sql
|
||||
plays_likes_counters.sql
|
||||
add_upright_bass.sql
|
||||
music_session_history_public.sql
|
||||
music_session_history_public.sql
|
||||
track_claimed_recording.sql
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE recordings_likers ADD COLUMN claimed_recording_id VARCHAR(64) NOT NULL REFERENCES claimed_recordings(id);
|
||||
ALTER TABLE recordings_plays ADD COLUMN claimed_recording_id VARCHAR(64) NOT NULL REFERENCES claimed_recordings(id);
|
||||
ALTER TABLE recordings_likers ADD COLUMN favorite BOOLEAN NOT NULL DEFAULT TRUE;
|
||||
|
|
@ -3,13 +3,14 @@ module JamRuby
|
|||
|
||||
attr_accessible :name, :description, :is_public, :is_downloadable, :genre_id, :recording_id, :user_id, as: :admin
|
||||
|
||||
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings, :foreign_key => 'recording_id'
|
||||
belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings
|
||||
belongs_to :genre, :class_name => "JamRuby::Genre"
|
||||
has_many :recorded_tracks, :through => :recording, :class_name => "JamRuby::RecordedTrack"
|
||||
has_many :playing_sessions, :class_name => "JamRuby::MusicSession"
|
||||
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
|
||||
|
||||
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings, :foreign_key => 'recording_id'
|
||||
belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings
|
||||
belongs_to :genre, :class_name => "JamRuby::Genre"
|
||||
has_many :recorded_tracks, :through => :recording, :class_name => "JamRuby::RecordedTrack"
|
||||
has_many :playing_sessions, :class_name => "JamRuby::MusicSession"
|
||||
has_many :likes, :class_name => "JamRuby::RecordingLiker", :foreign_key => "claimed_recording_id"
|
||||
has_many :plays, :class_name => "JamRuby::RecordingPlay", :foreign_key => "claimed_recording_id"
|
||||
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
|
||||
|
||||
validates :name, no_profanity: true, length: {minimum: 3, maximum: 64}, presence: true
|
||||
validates :description, no_profanity: true, length: {maximum: 8000}
|
||||
|
|
@ -23,6 +24,7 @@ module JamRuby
|
|||
before_create :generate_share_token
|
||||
|
||||
SHARE_TOKEN_LENGTH = 8
|
||||
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
|
||||
|
||||
|
||||
def user_belongs_to_recording
|
||||
|
|
@ -72,6 +74,50 @@ module JamRuby
|
|||
token.gsub(/[^0-9A-Za-z]/, '')
|
||||
end
|
||||
|
||||
# right now, the only thing that is brought back is ClaimedRecordings, and you can only query your own favorites
|
||||
def self.index_favorites(user, params = {})
|
||||
limit = params[:limit]
|
||||
limit ||= 20
|
||||
limit = limit.to_i
|
||||
|
||||
# validate sort
|
||||
sort = params[:sort]
|
||||
sort ||= 'date'
|
||||
raise "not valid sort #{sort}" unless sort == "date"
|
||||
|
||||
start = params[:start].presence
|
||||
start ||= 0
|
||||
start = start.to_i
|
||||
|
||||
|
||||
type_filter = params[:type]
|
||||
type_filter ||= 'claimed_recording'
|
||||
raise "not valid type #{type_filter}" unless type_filter == "claimed_recording"
|
||||
|
||||
target_user = params[:user]
|
||||
|
||||
raise PermissionError, "must specify current user" unless user
|
||||
raise "user must be specified" unless target_user
|
||||
|
||||
if target_user != user.id
|
||||
raise PermissionError, "unable to view another user's favorites"
|
||||
end
|
||||
|
||||
query = ClaimedRecording.limit(limit).order('created_at DESC').offset(start)
|
||||
query = query.joins(:likes)
|
||||
query = query.where('favorite = true')
|
||||
query = query.where("recordings_likers.liker_id = '#{target_user}'")
|
||||
query = query.where("claimed_recordings.is_public = TRUE OR claimed_recordings.user_id = '#{target_user}'")
|
||||
|
||||
if query.length == 0
|
||||
[query, nil]
|
||||
elsif query.length < limit
|
||||
[query, nil]
|
||||
else
|
||||
[query, start + limit]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_share_token
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ module JamRuby
|
|||
before_save :sanitize_active_admin
|
||||
before_create :add_to_feed
|
||||
|
||||
|
||||
def add_to_feed
|
||||
feed = Feed.new
|
||||
feed.recording = self
|
||||
|
|
@ -311,26 +310,6 @@ module JamRuby
|
|||
save
|
||||
end
|
||||
|
||||
=begin
|
||||
# This is no longer remotely right.
|
||||
def self.search(query, options = { :limit => 10 })
|
||||
|
||||
# only issue search if at least 2 characters are specified
|
||||
if query.nil? || query.length < 2
|
||||
return []
|
||||
end
|
||||
|
||||
# create 'anded' statement
|
||||
query = Search.create_tsquery(query)
|
||||
|
||||
if query.nil? || query.length == 0
|
||||
return []
|
||||
end
|
||||
|
||||
return Recording.where("description_tsv @@ to_tsquery('jamenglish', ?)", query).limit(options[:limit])
|
||||
end
|
||||
=end
|
||||
|
||||
private
|
||||
def self.validate_user_is_band_member(user, band)
|
||||
unless band.users.exists? user
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ module JamRuby
|
|||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id", :counter_cache => :like_count
|
||||
belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id"
|
||||
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "liker_id"
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ module JamRuby
|
|||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id", :counter_cache => :play_count
|
||||
belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id"
|
||||
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "player_id"
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -125,4 +125,91 @@ describe ClaimedRecording do
|
|||
instance.remove_non_alpha_num("JDnfHsimMQ").should == 'JDnfHsimMQ'
|
||||
end
|
||||
end
|
||||
|
||||
describe "favorite_index" do
|
||||
|
||||
let(:other_user) { FactoryGirl.create(:user) }
|
||||
|
||||
it "returns nothing" do
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
|
||||
favorites.length.should == 0
|
||||
start.should be_nil
|
||||
end
|
||||
|
||||
it "angry when no user specified" do
|
||||
expect { ClaimedRecording.index_favorites(@user, user:other_user ) }.to raise_error "unable to view another user's favorites"
|
||||
end
|
||||
|
||||
it "user must be specified" do
|
||||
expect { ClaimedRecording.index_favorites(@user) }.to raise_error "user must be specified"
|
||||
end
|
||||
|
||||
it "finds favorite claimed_recording if true, not if false" do
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording, user: @user)
|
||||
|
||||
like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
|
||||
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
|
||||
favorites.length.should == 1
|
||||
start.should be_nil
|
||||
|
||||
like.favorite = false
|
||||
like.save!
|
||||
|
||||
# remove from favorites
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
|
||||
favorites.length.should == 0
|
||||
start.should be_nil
|
||||
end
|
||||
|
||||
it "finds others public claimed recordings" do
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording, user: other_user)
|
||||
|
||||
like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
|
||||
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
|
||||
favorites.length.should == 1
|
||||
start.should be_nil
|
||||
end
|
||||
|
||||
it "can find others private claimed recordings" do
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording, user: other_user)
|
||||
|
||||
like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: false)
|
||||
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
|
||||
favorites.length.should == 0
|
||||
start.should be_nil
|
||||
end
|
||||
|
||||
it "can find own private claimed recordings" do
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording, user: @user)
|
||||
|
||||
like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
|
||||
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
|
||||
favorites.length.should == 1
|
||||
start.should be_nil
|
||||
end
|
||||
|
||||
it "pagination" do
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording, user: @user)
|
||||
claimed_recording2 = FactoryGirl.create(:claimed_recording, user: @user)
|
||||
|
||||
like1 = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
|
||||
like2 = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording2, recording: claimed_recording2.recording, favorite: true)
|
||||
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id, limit:1)
|
||||
favorites.length.should == 1
|
||||
start.should_not be_nil
|
||||
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id, limit:1, start: start)
|
||||
favorites.length.should == 1
|
||||
start.should_not be_nil
|
||||
|
||||
favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id, limit:1, start: start)
|
||||
favorites.length.should == 0
|
||||
start.should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
var recordingHtml = context.JK.fillTemplate(template, {
|
||||
recordingId: recording.id,
|
||||
claimedRecordingId: claimedRecording.id
|
||||
name: claimedRecording.name,
|
||||
genre: claimedRecording.genre_id.toUpperCase(),
|
||||
created_at: context.JK.formatDateTime(recording.created_at),
|
||||
|
|
|
|||
|
|
@ -83,21 +83,21 @@
|
|||
});
|
||||
}
|
||||
|
||||
function addRecordingLike(recordingId, userId) {
|
||||
function addRecordingLike(recordingId, claimedRecordingId, userId) {
|
||||
return $.ajax({
|
||||
url: '/api/recordings/' + recordingId + "/likes",
|
||||
type: "POST",
|
||||
data : JSON.stringify({"user_id": userId}),
|
||||
data : JSON.stringify({user_id: userId, claimed_recording: claimedRecordingId}),
|
||||
dataType : 'json',
|
||||
contentType: 'application/json'
|
||||
});
|
||||
}
|
||||
|
||||
function addRecordingPlay(recordingId, userId) {
|
||||
function addRecordingPlay(recordingId, claimedRecordingId, userId) {
|
||||
return $.ajax({
|
||||
url: '/api/recordings/' + recordingId + "/plays",
|
||||
type: "POST",
|
||||
data : JSON.stringify({"user_id": userId}),
|
||||
data : JSON.stringify({user_id: userId, claimed_recording: claimedRecordingId}),
|
||||
dataType : 'json',
|
||||
contentType: 'application/json'
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
var $scope = $(".landing-details");
|
||||
|
||||
function like() {
|
||||
rest.addRecordingLike(recordingId, JK.currentUserId)
|
||||
rest.addRecordingLike(recordingId, claimedRecordingId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnLikeCount").html(parseInt($("#spnLikeCount").text()) + 1);
|
||||
$("#btnLike", $scope).unbind("click");
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
}
|
||||
|
||||
function play() {
|
||||
rest.addRecordingPlay(recordingId, JK.currentUserId)
|
||||
rest.addRecordingPlay(recordingId, claimedRecordingId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnPlayCount", $scope).html(parseInt($("#spnPlayCount").text()) + 1);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
class ApiFavoritesController < ApiController
|
||||
|
||||
respond_to :json
|
||||
|
||||
before_filter :api_signed_in_user
|
||||
|
||||
def index
|
||||
@claimed_recordings, @next = ClaimedRecording.index_favorites(current_user,
|
||||
start: params[:since],
|
||||
limit: params[:limit],
|
||||
sort: params[:sort],
|
||||
type: params[:type],
|
||||
user: params[:user])
|
||||
|
||||
render "api_favorites/index", :layout => nil
|
||||
end
|
||||
end
|
||||
|
|
@ -121,6 +121,8 @@ class ApiRecordingsController < ApiController
|
|||
liker = RecordingLiker.new
|
||||
liker.recording_id = params[:id]
|
||||
liker.liker_id = params[:user_id]
|
||||
liker.claimed_recording_id = params[:claimed_recording_id]
|
||||
liker.favorite = true
|
||||
liker.ip_address = request.remote_ip
|
||||
liker.save
|
||||
|
||||
|
|
@ -142,6 +144,7 @@ class ApiRecordingsController < ApiController
|
|||
play = RecordingPlay.new
|
||||
play.recording_id = params[:id]
|
||||
play.player_id = params[:user_id]
|
||||
play.claimed_recording_id = params[:claimed_recording_id]
|
||||
play.ip_address = request.remote_ip
|
||||
play.save
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
node :next do |page|
|
||||
@next
|
||||
end
|
||||
|
||||
node :entries do |page|
|
||||
partial "api_claimed_recordings/show", object: @claimed_recordings
|
||||
end
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
{musicians}
|
||||
</table><br />
|
||||
<div align="center">
|
||||
<div class="left"><a id="btnLike" onclick="addRecordingLike('{recordingId}');" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a id="btnLike" onclick="addRecordingLike('{recordingId}', '{claimedRecordingId}');" class="button-orange">LIKE</a></div>
|
||||
<div style="display:none;" class="left"><a id="btnComment" class="button-orange">COMMENT</a></div>
|
||||
<div class="left"><a id="btnShare" layout-link="share-dialog" class="button-orange">SHARE</a></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -345,6 +345,9 @@ SampleApp::Application.routes.draw do
|
|||
|
||||
# feed
|
||||
match '/feeds' => 'api_feeds#index', :via => :get
|
||||
|
||||
# favorites
|
||||
match '/favorites' => 'api_favorites#index', :via => :get
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ApiFavoritesController do
|
||||
render_views
|
||||
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
let(:user2) { FactoryGirl.create(:user) }
|
||||
let(:band) { FactoryGirl.create(:band) }
|
||||
let(:music_session) {FactoryGirl.create(:music_session, creator: user) }
|
||||
let(:claimed_recording) {FactoryGirl.create(:claimed_recording) }
|
||||
|
||||
before(:each) do
|
||||
ClaimedRecording.delete_all
|
||||
controller.current_user = nil
|
||||
end
|
||||
|
||||
|
||||
it "insists on login" do
|
||||
get :index
|
||||
response.status.should == 403
|
||||
end
|
||||
|
||||
it "requires user param" do
|
||||
controller.current_user = user
|
||||
expect { get :index }.to raise_error "user must be specified"
|
||||
end
|
||||
|
||||
it "can return nothing" do
|
||||
controller.current_user = user
|
||||
get :index, { user: user}
|
||||
|
||||
json = JSON.parse(response.body, :symbolize_names => true)
|
||||
json[:entries].length.should == 0
|
||||
json[:since].should be_nil
|
||||
end
|
||||
|
||||
it "returns one thing" do
|
||||
claimed_recording.touch
|
||||
like = FactoryGirl.create(:recording_like, user: user, claimed_recording: claimed_recording, recording: claimed_recording.recording, favorite: true)
|
||||
|
||||
controller.current_user = user
|
||||
get :index, { user: user}
|
||||
|
||||
json = JSON.parse(response.body, :symbolize_names => true)
|
||||
json[:entries].length.should == 1
|
||||
json[:since].should be_nil
|
||||
end
|
||||
end
|
||||
|
|
@ -352,4 +352,20 @@ FactoryGirl.define do
|
|||
sequence(:token) { |n| "token-#{n}"}
|
||||
token_expires_at Time.now
|
||||
end
|
||||
|
||||
factory :recording_play, :class => JamRuby::RecordingPlay do
|
||||
|
||||
end
|
||||
|
||||
factory :music_session_play, :class => JamRuby::MusicSessionPlay do
|
||||
|
||||
end
|
||||
|
||||
factory :recording_like, :class => JamRuby::RecordingLiker do
|
||||
|
||||
end
|
||||
|
||||
factory :music_session_like, :class => JamRuby::MusicSessionLiker do
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,19 +19,37 @@ db_config = YAML::load(File.open('config/database.yml'))["test"]
|
|||
# initialize ActiveRecord's db connection\
|
||||
SpecDb::recreate_database(db_config)
|
||||
ActiveRecord::Base.establish_connection(YAML::load(File.open('config/database.yml'))["test"])
|
||||
#puts "0"
|
||||
require 'jam_ruby'
|
||||
|
||||
# uncomment this to see active record logs
|
||||
# ActiveRecord::Base.logger = Logger.new(STDOUT) if defined?(ActiveRecord::Base)
|
||||
|
||||
#puts "1"
|
||||
|
||||
include JamRuby
|
||||
|
||||
#puts "2"
|
||||
# put ActionMailer into test mode
|
||||
ActionMailer::Base.delivery_method = :test
|
||||
|
||||
#puts "3"
|
||||
RecordedTrack.observers.disable :all # only a few tests want this observer active
|
||||
|
||||
#puts "4"
|
||||
# a way to kill tests if they aren't running. capybara is hanging intermittently, I think
|
||||
|
||||
tests_started = false
|
||||
|
||||
#Thread.new {
|
||||
# puts "thread statring"
|
||||
# sleep 30
|
||||
# puts "thread waking"
|
||||
# unless tests_started
|
||||
|
||||
# exit 20
|
||||
# end
|
||||
#}
|
||||
|
||||
Spork.prefork do
|
||||
# Loading more in this block will cause your tests to run faster. However,
|
||||
|
|
@ -105,11 +123,10 @@ Spork.prefork do
|
|||
config.include Requests::FeatureHelpers, type: :feature
|
||||
|
||||
config.before(:suite) do
|
||||
|
||||
tests_started = true
|
||||
end
|
||||
|
||||
config.before(:all) do
|
||||
|
||||
end
|
||||
|
||||
config.before(:each) do
|
||||
|
|
|
|||
Loading…
Reference in New Issue