diff --git a/admin/Gemfile b/admin/Gemfile index 74f6a2125..5ec8a3411 100644 --- a/admin/Gemfile +++ b/admin/Gemfile @@ -37,7 +37,6 @@ gem 'bootstrap-will_paginate', '0.0.6' gem 'carrierwave', '0.9.0' gem 'carrierwave_direct' gem 'uuidtools', '2.1.2' -gem 'bcrypt-ruby', '3.0.1' gem 'jquery-rails' # , '2.3.0' # pinned because jquery-ui-rails was split from jquery-rails, but activeadmin doesn't support this gem yet gem 'jquery-ui-rails' gem 'rails3-jquery-autocomplete' diff --git a/admin/app/views/admin/recordings/_form.html.haml b/admin/app/views/admin/recordings/_form.html.haml index 880f26823..2c1bb2ce0 100644 --- a/admin/app/views/admin/recordings/_form.html.haml +++ b/admin/app/views/admin/recordings/_form.html.haml @@ -26,6 +26,8 @@ = f.input :band, :as => :autocomplete, :url => autocomplete_band_name_admin_bands_path, :input_html => { :id => "jam_ruby_recording_band", :name => "", :id_element => "#jam_ruby_recording_band_id" } = f.input :band_id, :as => :hidden, :input_html => { :name => "jam_ruby_recording[band_id]" } + = f.input :duration, :hint => 'how long the recording is (in seconds)' + = f.semantic_fields_for :recorded_tracks do |recorded_track, index| = render 'recorded_track_fields', f: recorded_track .links diff --git a/db/manifest b/db/manifest index def0d818f..6d546452d 100755 --- a/db/manifest +++ b/db/manifest @@ -113,4 +113,5 @@ feed_use_recording.sql feed_autoincrement_primary_key.sql music_sessions_plays.sql plays_likes_counters.sql -add_upright_bass.sql \ No newline at end of file +add_upright_bass.sql +music_session_history_public.sql \ No newline at end of file diff --git a/db/up/music_session_history_public.sql b/db/up/music_session_history_public.sql new file mode 100644 index 000000000..cbff9b62a --- /dev/null +++ b/db/up/music_session_history_public.sql @@ -0,0 +1 @@ +ALTER TABLE music_sessions_history ADD COLUMN fan_access BOOLEAN NOT NULL; \ No newline at end of file diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index 6997821b9..973ed5efe 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -57,6 +57,7 @@ require "jam_ruby/models/feedback" require "jam_ruby/models/feedback_observer" require "jam_ruby/models/max_mind_geo" require "jam_ruby/models/max_mind_isp" +require "jam_ruby/models/band_genre" require "jam_ruby/models/genre" require "jam_ruby/models/user" require "jam_ruby/models/user_observer" diff --git a/ruby/lib/jam_ruby/constants/limits.rb b/ruby/lib/jam_ruby/constants/limits.rb index 52e2036f1..a0932a389 100644 --- a/ruby/lib/jam_ruby/constants/limits.rb +++ b/ruby/lib/jam_ruby/constants/limits.rb @@ -1,5 +1,9 @@ module Limits + # session genres + MIN_GENRES_PER_SESSION = 1 + MAX_GENRES_PER_SESSION = 3 + # band genres MIN_GENRES_PER_BAND = 1 MAX_GENRES_PER_BAND = 3 diff --git a/ruby/lib/jam_ruby/constants/validation_messages.rb b/ruby/lib/jam_ruby/constants/validation_messages.rb index 8c2b8d3df..4a308798b 100644 --- a/ruby/lib/jam_ruby/constants/validation_messages.rb +++ b/ruby/lib/jam_ruby/constants/validation_messages.rb @@ -20,8 +20,13 @@ module ValidationMessages SESSION_NOT_FOUND = "Session not found." # genres - GENRE_LIMIT_EXCEEDED = "No more than 1 genre is allowed." - GENRE_MINIMUM_NOT_MET = "At least 1 genre is required." + RECORDING_GENRE_LIMIT_EXCEEDED = "No more than 1 genre is allowed." + BAND_GENRE_LIMIT_EXCEEDED = "No more than 3 genres are allowed." + SESSION_GENRE_LIMIT_EXCEEDED = "No more than 3 genres are allowed." + + RECORDING_GENRE_MINIMUM_NOT_MET = "At least 1 genre is required." + BAND_GENRE_MINIMUM_NOT_MET = "At least 1 genre is required." + SESSION_GENRE_MINIMUM_NOT_MET = "At least 1 genre is required." # instruments INSTRUMENT_LIMIT_EXCEEDED = "No more than 5 instruments are allowed." diff --git a/ruby/lib/jam_ruby/models/band.rb b/ruby/lib/jam_ruby/models/band.rb index 88d97bc14..ea14cabe5 100644 --- a/ruby/lib/jam_ruby/models/band.rb +++ b/ruby/lib/jam_ruby/models/band.rb @@ -5,13 +5,20 @@ module JamRuby :country, :original_fpfile_photo, :cropped_fpfile_photo, :cropped_large_fpfile_photo, :cropped_s3_path_photo, :cropped_large_s3_path_photo, :crop_selection_photo, :photo_url, :large_photo_url - attr_accessor :updating_photo + attr_accessor :updating_photo, :skip_location_validation self.primary_key = 'id' before_save :stringify_photo_info , :if => :updating_photo + validates :biography, no_profanity: true, presence:true + validates :name, presence: true + validates :country, presence: true, :unless => :skip_location_validation + validates :state, presence: true, :unless => :skip_location_validation + validates :city, presence: true, :unless => :skip_location_validation + validate :validate_photo_info - validates :biography, no_profanity: true + validate :require_at_least_one_genre + validate :limit_max_genres before_save :check_lat_lng before_save :check_website_url @@ -21,7 +28,8 @@ module JamRuby has_many :users, :through => :band_musicians, :class_name => "JamRuby::User" # genres - has_and_belongs_to_many :genres, :class_name => "JamRuby::Genre", :join_table => "bands_genres" + has_many :band_genres, class_name: "JamRuby::BandGenre" + has_many :genres, class_name: "JamRuby::Genre", :through => :band_genres # recordings has_many :recordings, :class_name => "JamRuby::Recording", :foreign_key => "band_id" @@ -59,8 +67,7 @@ module JamRuby end def recent_history - recordings = ClaimedRecording.joins(:recording) - .where(:recordings => {:band_id => "#{self.id}"}) + recordings = Recording.where(:band_id => self.id) .order('created_at DESC') .limit(10) @@ -123,74 +130,52 @@ module JamRuby return recordings end + def self.build_band(user, params) + + id = params[:id] + + # ensure person creating this Band is a Musician + unless user.musician? + raise PermissionError, "must be a musician" + end + + band = id.blank? ? Band.new : Band.find(id) + + # ensure user updating Band details is a Band member + unless band.new_record? || band.users.exists?(user) + raise PermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR + end + + band.name = params[:name] if params.has_key?(:name) + band.website = params[:website] if params.has_key?(:website) + band.biography = params[:biography] if params.has_key?(:biography) + band.city = params[:city] if params.has_key?(:city) + band.state = params[:state] if params.has_key?(:state) + band.country = params[:country] if params.has_key?(:country) + band.photo_url = params[:photo_url] if params.has_key?(:photo_url) + band.logo_url = params[:logo_url] if params.has_key?(:logo_url) + + if params.has_key?(:genres) && params[:genres] + # loop through each genre in the array and save to the db + genres = [] + params[:genres].each { |genre_id| genres << Genre.find(genre_id) } + band.genres = genres + end + + + band + end + # helper method for creating / updating a Band - def self.save(id, name, website, biography, city, state, country, genres, user_id, photo_url, logo_url) - user = User.find(user_id) + def self.save(user, params) + band = build_band(user, params) - # new band - if id.blank? - - # ensure person creating this Band is a Musician - unless user.musician? - raise JamRuby::PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR - end - - validate_genres(genres, false) - band = Band.new() - - # band update - else - validate_genres(genres, true) - band = Band.find(id) - - # ensure user updating Band details is a Band member - unless band.users.exists? user - raise PermissionError, ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR - end + if band.save + # add the creator as the admin + BandMusician.create(:band_id => band.id, :user_id => user.id, :admin => true) if params[:id].blank? end - # name - band.name = name unless name.nil? - - # website - band.website = website unless website.nil? - - # biography - band.biography = biography unless biography.nil? - - # city - band.city = city unless city.nil? - - # state - band.state = state unless state.nil? - - # country - band.country = country unless country.nil? - - # photo url - band.photo_url = photo_url unless photo_url.nil? - - # logo url - band.logo_url = logo_url unless logo_url.nil? - - # band.updated_at = Time.now.getutc - band.save! - band.reload - - # genres - unless genres.nil? - ActiveRecord::Base.transaction do - # delete all genres for this band first - band.genres.delete_all if id.present? - # loop through each genre in the array and save to the db - genres.each { |genre_id| band.genres << Genre.find(genre_id) } - end - end - - # add the creator as the admin - BandMusician.create(:band_id => band.id, :user_id => user_id, :admin => true) if id.blank? - - return band + band end def escape_filename(path) @@ -274,21 +259,16 @@ module JamRuby end private - def self.validate_genres(genres, is_nil_ok) - if is_nil_ok && genres.nil? - return + + def require_at_least_one_genre + if self.genres.size < Limits::MIN_GENRES_PER_BAND + errors.add(:genres, ValidationMessages::BAND_GENRE_MINIMUM_NOT_MET) end + end - if genres.nil? - raise JamRuby::JamArgumentError, ValidationMessages::GENRE_MINIMUM_NOT_MET - else - if genres.size < Limits::MIN_GENRES_PER_BAND - raise JamRuby::JamArgumentError, ValidationMessages::GENRE_MINIMUM_NOT_MET - end - - if genres.size > Limits::MAX_GENRES_PER_BAND - raise JamRuby::JamArgumentError, ValidationMessages::GENRE_LIMIT_EXCEEDED - end + def limit_max_genres + if self.genres.size > Limits::MAX_GENRES_PER_BAND + errors.add(:genres, ValidationMessages::BAND_GENRE_LIMIT_EXCEEDED) end end diff --git a/ruby/lib/jam_ruby/models/band_genre.rb b/ruby/lib/jam_ruby/models/band_genre.rb new file mode 100644 index 000000000..9bd4051d4 --- /dev/null +++ b/ruby/lib/jam_ruby/models/band_genre.rb @@ -0,0 +1,11 @@ +module JamRuby + class BandGenre < ActiveRecord::Base + + self.table_name = "bands_genres" + + self.primary_key = 'id' + + belongs_to :user, class_name: "JamRuby::User" + belongs_to :genre, class_name: "JamRuby::Genre" + end +end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/feed.rb b/ruby/lib/jam_ruby/models/feed.rb index fd930102f..43f31c430 100644 --- a/ruby/lib/jam_ruby/models/feed.rb +++ b/ruby/lib/jam_ruby/models/feed.rb @@ -7,10 +7,10 @@ module JamRuby FIXNUM_MAX = (2**(0.size * 8 -2) -1) SORT_TYPES = ['date', 'plays', 'likes'] - TIME_RANGES = ['today', 'week', 'month', 'all'] - TYPE_FILTERS = ['session', 'recording', 'all'] + TIME_RANGES = { "today" => 1 , "week" => 7, "month" => 30, "all" => 0} + TYPE_FILTERS = ['music_session_history', 'recording', 'all'] - def self.index(params = {}) + def self.index(user, params = {}) limit = params[:limit] limit ||= 20 limit = limit.to_i @@ -20,7 +20,7 @@ module JamRuby sort ||= 'date' raise "not valid sort #{sort}" unless SORT_TYPES.include?(sort) - start = params[:start] + start = params[:start].presence if sort == 'date' start ||= FIXNUM_MAX else @@ -30,18 +30,24 @@ module JamRuby time_range = params[:time_range] time_range ||= 'month' - raise "not valid time_range #{time_range}" unless TIME_RANGES.include?(time_range) + raise "not valid time_range #{time_range}" unless TIME_RANGES.has_key?(time_range) type_filter = params[:type] type_filter ||= 'all' raise "not valid type #{type_filter}" unless TYPE_FILTERS.include?(type_filter) - query = Feed.includes([:recording]).includes([:music_session_history]).limit(limit) + target_user = params[:user] + target_band = params[:band] + + #query = Feed.includes([:recording]).includes([:music_session_history]).limit(limit) + query = Feed.joins("LEFT OUTER JOIN recordings ON recordings.id = feeds.recording_id") + .joins("LEFT OUTER JOIN music_sessions_history ON music_sessions_history.id = feeds.music_session_id") + .limit(limit) # handle sort if sort == 'date' - query = query.where("id < #{start}") - query = query.order('id DESC') + query = query.where("feeds.id < #{start}") + query = query.order('feeds.id DESC') elsif sort == 'plays' query = query.offset(start) query = query.order("COALESCE(recordings.play_count, music_sessions_history.play_count) DESC ") @@ -53,14 +59,71 @@ module JamRuby end # handle time range + days = TIME_RANGES[time_range] + if days > 0 + query = query.where("feeds.created_at > NOW() - '#{days} day'::INTERVAL") + end # handle type filters - if type_filter == 'session' - query = query.where('music_session_id is not NULL') + if type_filter == 'music_session_history' + query = query.where('feeds.music_session_id is not NULL') elsif type_filter == 'recording' - query = query.where('recording_id is not NULL') + query = query.where('feeds.recording_id is not NULL') end + + if target_user + + if target_user != user.id + require_public_recordings = "claimed_recordings.is_public = TRUE AND" + require_public_sessions = "music_sessions_history.fan_access = TRUE AND" + end + + query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND #{require_public_recordings} (claimed_recordings.user_id = '#{target_user}' OR (recordings.band_id IN (SELECT band_id FROM bands_musicians where user_id='#{target_user}')))") + query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions_history.id = music_sessions_user_history.music_session_id AND #{require_public_sessions} music_sessions_user_history.user_id = '#{target_user}'") + query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions_history.id") + if sort == 'plays' + query = query.group("COALESCE(recordings.play_count, music_sessions_history.play_count)") + elsif sort == 'likes' + query = query.group("COALESCE(recordings.like_count, music_sessions_history.like_count)") + end + query = query.where('recordings.id is NULL OR claimed_recordings.id IS NOT NULL') + query = query.where('music_sessions_history.id is NULL OR music_sessions_user_history.id IS NOT NULL') + + elsif target_band + + unless Band.find(target_band).users.include?(user) + require_public_recordings = "claimed_recordings.is_public = TRUE AND" + require_public_sessions = "music_sessions_history.fan_access = TRUE AND" + end + + query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND #{require_public_recordings} recordings.band_id = '#{target_band}'") + query = query.where("music_sessions_history IS NULL OR #{require_public_sessions} music_sessions_history.band_id = '#{target_band}'") + query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions_history.id") + if sort == 'plays' + query = query.group("COALESCE(recordings.play_count, music_sessions_history.play_count)") + elsif sort == 'likes' + query = query.group("COALESCE(recordings.like_count, music_sessions_history.like_count)") + end + query = query.where('recordings.id is NULL OR claimed_recordings.id IS NOT NULL') + #query = query.where('music_sessions_history.id is NULL OR music_sessions_user_history.id IS NOT NULL') + else + query = query.joins('LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.is_public = TRUE') + query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions_history.id = music_sessions_user_history.music_session_id AND music_sessions_history.fan_access = TRUE") + query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions_history.id") + if sort == 'plays' + query = query.group("COALESCE(recordings.play_count, music_sessions_history.play_count)") + elsif sort == 'likes' + query = query.group("COALESCE(recordings.like_count, music_sessions_history.like_count)") + end + query = query.where('recordings.id is NULL OR claimed_recordings.is_public = TRUE') + query = query.where('music_sessions_history.id is NULL OR music_sessions_user_history.id IS NOT NULL') + end + + + + + if query.length == 0 [query, nil] elsif query.length < limit diff --git a/ruby/lib/jam_ruby/models/genre.rb b/ruby/lib/jam_ruby/models/genre.rb index 45776c59f..18fef77b8 100644 --- a/ruby/lib/jam_ruby/models/genre.rb +++ b/ruby/lib/jam_ruby/models/genre.rb @@ -4,7 +4,8 @@ module JamRuby self.primary_key = 'id' # bands - has_and_belongs_to_many :bands, :class_name => "JamRuby::Band", :join_table => "bands_genres" + has_many :band_genres, class_name: "JamRuby::BandGenre" + has_many :bands, class_name: "JamRuby::Band", :through => :band_genres # genres has_and_belongs_to_many :recordings, :class_name => "JamRuby::Recording", :join_table => "recordings_genres" diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index 57ebcee50..c32e2650e 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -24,7 +24,7 @@ module JamRuby has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session belongs_to :band, :inverse_of => :music_sessions, :class_name => "JamRuby::Band", :foreign_key => "band_id" - after_save :require_at_least_one_genre, :limit_max_genres + after_save :require_at_least_one_genre, :limit_max_genres, :sync_music_session_history after_destroy do |obj| JamRuby::MusicSessionHistory.removed_music_session(obj.id) @@ -264,18 +264,22 @@ module JamRuby def require_at_least_one_genre unless skip_genre_validation - if self.genres.count < Limits::MIN_GENRES_PER_RECORDING - errors.add(:genres, ValidationMessages::GENRE_MINIMUM_NOT_MET) + if self.genres.count < Limits::MIN_GENRES_PER_SESSION + errors.add(:genres, ValidationMessages::SESSION_GENRE_MINIMUM_NOT_MET) end end end def limit_max_genres unless skip_genre_validation - if self.genres.count > Limits::MAX_GENRES_PER_RECORDING - errors.add(:genres, ValidationMessages::GENRE_LIMIT_EXCEEDED) + if self.genres.count > Limits::MAX_GENRES_PER_SESSION + errors.add(:genres, ValidationMessages::SESSION_GENRE_LIMIT_EXCEEDED) end end end + + def sync_music_session_history + MusicSessionHistory.save(self) + end end end diff --git a/ruby/lib/jam_ruby/models/music_session_history.rb b/ruby/lib/jam_ruby/models/music_session_history.rb index 29be1f4e1..852f73f3f 100644 --- a/ruby/lib/jam_ruby/models/music_session_history.rb +++ b/ruby/lib/jam_ruby/models/music_session_history.rb @@ -19,7 +19,7 @@ module JamRuby :class_name => 'JamRuby::MusicSession', :foreign_key => 'music_session_id') - has_many :music_session_user_histories, :class_name => "JamRuby::MusicSessionUserHistory", :foreign_key => "music_session_id" + has_many :music_session_user_histories, :class_name => "JamRuby::MusicSessionUserHistory", :foreign_key => "music_session_id", :dependent => :delete_all has_many :comments, :class_name => "JamRuby::MusicSessionComment", :foreign_key => "music_session_id" has_many :likes, :class_name => "JamRuby::MusicSessionLiker", :foreign_key => "session_id" has_many :plays, :class_name => "JamRuby::MusicSessionPlay", :foreign_key => "music_session_id" @@ -43,7 +43,6 @@ module JamRuby self.comments.size end - def tracks tracks = [] self.music_session_user_histories.each do |msuh| @@ -128,6 +127,7 @@ module JamRuby session_history.user_id = music_session.creator.id session_history.band_id = music_session.band.id unless music_session.band.nil? session_history.genres = music_session.genres.map { |g| g.id }.join SEPARATOR + session_history.fan_access = music_session.fan_access session_history.save! end diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index 19ddd357b..8fc666e0f 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -3,7 +3,7 @@ module JamRuby self.primary_key = 'id' - attr_accessible :owner, :owner_id, :band, :band_id, :recorded_tracks_attributes, :mixes_attributes, :claimed_recordings_attributes, :name, :description, :genre, :is_public, :is_downloadable, as: :admin + attr_accessible :owner, :owner_id, :band, :band_id, :recorded_tracks_attributes, :mixes_attributes, :claimed_recordings_attributes, :name, :description, :genre, :is_public, :is_downloadable, :duration, as: :admin has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :recording, :foreign_key => 'recording_id', :dependent => :destroy has_many :users, :through => :recorded_tracks, :class_name => "JamRuby::User" diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 1c4f49700..7ff867717 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -275,8 +275,7 @@ module JamRuby end def recent_history - recordings = ClaimedRecording.joins(:recording) - .where(:recordings => {:owner_id => "#{self.id}"}) + recordings = Recording.where(:owner_id => self.id) .order('created_at DESC') .limit(10) diff --git a/ruby/spec/factories.rb b/ruby/spec/factories.rb index 9868bf2e5..8f277cd51 100644 --- a/ruby/spec/factories.rb +++ b/ruby/spec/factories.rb @@ -14,12 +14,17 @@ FactoryGirl.define do musician true terms_of_service true + #u.association :musician_instrument, factory: :musician_instrument, user: u before(:create) do |user| user.musician_instruments << FactoryGirl.build(:musician_instrument, user: user) end + factory :fan do + musician false + end + factory :admin do admin true end @@ -45,7 +50,7 @@ FactoryGirl.define do factory :music_session do after(:create) { |session| - MusicSessionHistory.save(session) + FactoryGirl.create(:music_session_user_history, :history => session.music_session_history, :user => session.creator) } factory :music_session_with_mount do @@ -61,6 +66,7 @@ FactoryGirl.define do music_session nil end + fan_access true music_session_id { music_session.id } description { music_session.description } user_id { music_session.user_id } @@ -101,6 +107,9 @@ FactoryGirl.define do city "Apex" state "NC" country "US" + before(:create) { |band| + band.genres << Genre.first + } end factory :genre, :class => JamRuby::Genre do diff --git a/ruby/spec/jam_ruby/connection_manager_spec.rb b/ruby/spec/jam_ruby/connection_manager_spec.rb index dc093a0cb..99bc51a4e 100644 --- a/ruby/spec/jam_ruby/connection_manager_spec.rb +++ b/ruby/spec/jam_ruby/connection_manager_spec.rb @@ -23,7 +23,7 @@ describe ConnectionManager do description = "some session" @conn.exec("INSERT INTO music_sessions (user_id, description, musician_access, approval_required, fan_chat, fan_access) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id", [user_id, description, options[:musician_access], options[:approval_required], options[:fan_chat], options[:fan_access]]) do |result| session_id = result.getvalue(0, 0) - @conn.exec("INSERT INTO music_sessions_history (music_session_id, description, user_id) VALUES ($1, $2, $3)", [session_id, description, user_id]) + @conn.exec("INSERT INTO music_sessions_history (music_session_id, description, user_id, fan_access) VALUES ($1, $2, $3, $4)", [session_id, description, user_id, true]) return session_id end end diff --git a/ruby/spec/jam_ruby/models/band_location_spec.rb b/ruby/spec/jam_ruby/models/band_location_spec.rb index fae562a53..e70fd09fd 100644 --- a/ruby/spec/jam_ruby/models/band_location_spec.rb +++ b/ruby/spec/jam_ruby/models/band_location_spec.rb @@ -2,6 +2,11 @@ require 'spec_helper' describe Band do + before(:all) do + MaxMindIsp.delete_all + MaxMindGeo.delete_all + end + before do @geocode1 = FactoryGirl.create(:geocoder) @geocode2 = FactoryGirl.create(:geocoder) @@ -27,7 +32,8 @@ describe Band do describe "without location data" do it "should have nil lat/lng values without address" do - @band.update_attributes({ :city => nil, + @band.skip_location_validation = true + @band.update_attributes({ :city => nil, :state => nil, :country => nil, }) diff --git a/ruby/spec/jam_ruby/models/band_search_spec.rb b/ruby/spec/jam_ruby/models/band_search_spec.rb index 5d693ba5f..2f885138f 100644 --- a/ruby/spec/jam_ruby/models/band_search_spec.rb +++ b/ruby/spec/jam_ruby/models/band_search_spec.rb @@ -3,12 +3,24 @@ require 'spec_helper' describe User do let(:user) { FactoryGirl.create(:user) } + let(:band) { FactoryGirl.create(:band, name: "Example Band") } + let(:band_params) { + { + name: "The Band", + biography: "Biography", + city: 'Austin', + state: 'TX', + country: 'US', + genres: ['country'] + } + } before(:each) do @geocode1 = FactoryGirl.create(:geocoder) @geocode2 = FactoryGirl.create(:geocoder) @user = FactoryGirl.create(:user) - @band = Band.save(nil, "Example Band", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) + band.touch + end @@ -16,43 +28,43 @@ describe User do ws = Search.band_search("Example Band").results ws.length.should == 1 band_result = ws[0] - band_result.name.should == @band.name - band_result.id.should == @band.id - band_result.location.should == @band.location + band_result.name.should == band.name + band_result.id.should == band.id + band_result.location.should == band.location end it "should allow search of one band with partial matches" do ws = Search.band_search("Ex").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id ws = Search.band_search("Exa").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id ws = Search.band_search("Exam").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id ws = Search.band_search("Examp").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id ws = Search.band_search("Exampl").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id ws = Search.band_search("Example").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id ws = Search.band_search("Ba").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id ws = Search.band_search("Ban").results ws.length.should == 1 - ws[0].id.should == @band.id + ws[0].id.should == band.id end it "should not match mid-word searchs" do @@ -67,9 +79,9 @@ describe User do ws = Search.band_search("Example Band").results ws.length.should == 1 band_result = ws[0] - band_result.id.should == @band.id + band_result.id.should == band.id - @band.destroy # delete doesn't work; you have to use destroy. + band.destroy # delete doesn't work; you have to use destroy. ws = Search.band_search("Example Band").results ws.length.should == 0 @@ -79,10 +91,10 @@ describe User do ws = Search.band_search("Example Band").results ws.length.should == 1 band_result = ws[0] - band_result.id.should == @band.id + band_result.id.should == band.id - @band.name = "bonus-stuff" - @band.save + band.name = "bonus-stuff" + band.save ws = Search.band_search("Example Band").results ws.length.should == 0 @@ -90,25 +102,25 @@ describe User do ws = Search.band_search("Bonus").results ws.length.should == 1 band_result = ws[0] - band_result.id.should == @band.id + band_result.id.should == band.id band_result.name.should == "bonus-stuff" end it "should tokenize correctly" do - @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) + band2 = FactoryGirl.create(:band, name: 'Peach pit') ws = Search.band_search("pea").results ws.length.should == 1 user_result = ws[0] - user_result.id.should == @band2.id + user_result.id.should == band2.id end it "should not return anything with a 1 character search" do - @band2 = Band.save(nil, "Peach pit", "www.bands.com", "zomg we rock", "Apex", "NC", "US", ["hip hop"], user.id, nil, nil) + band2 = FactoryGirl.create(:band, name: 'Peach pit') ws = Search.band_search("pe").results ws.length.should == 1 user_result = ws[0] - user_result.id.should == @band2.id + user_result.id.should == band2.id ws = Search.band_search("p").results ws.length.should == 0 diff --git a/ruby/spec/jam_ruby/models/band_spec.rb b/ruby/spec/jam_ruby/models/band_spec.rb index 3f1c1c289..25f2b4bb1 100644 --- a/ruby/spec/jam_ruby/models/band_spec.rb +++ b/ruby/spec/jam_ruby/models/band_spec.rb @@ -2,7 +2,21 @@ require 'spec_helper' describe Band do - let(:band) { FactoryGirl.create(:band) } + let(:user) { FactoryGirl.create(:user) } + let(:user2) { FactoryGirl.create(:user) } + let(:fan) { FactoryGirl.create(:fan) } + let(:band) { FactoryGirl.create(:band) } + let(:new_band) { FactoryGirl.build(:band) } + let(:band_params) { + { + name: "The Band", + biography: "Biography", + city: 'Austin', + state: 'TX', + country: 'US', + genres: ['country'] + } + } describe 'website update' do it 'should have http prefix on website url' do @@ -12,4 +26,65 @@ describe Band do end end + describe 'band validations' do + it "minimum genres" do + new_band.save.should be_false + new_band.errors[:genres].should == [ValidationMessages::BAND_GENRE_MINIMUM_NOT_MET] + end + + it "maximum genres" do + new_band.genres = Genre.limit(4) + new_band.save.should be_false + new_band.errors[:genres].should == [ValidationMessages::BAND_GENRE_LIMIT_EXCEEDED] + end + end + + describe "save" do + it "can succeed" do + band = Band.save(user, band_params) + band.errors.any?.should be_false + band.name.should == band_params[:name] + band.biography.should == band_params[:biography] + band.genres.should == [Genre.find(band_params[:genres][0])] + band.city.should == band_params[:city] + band.state.should == band_params[:state] + band.country.should == band_params[:country] + end + + it "ensures user is a musician" do + expect{ Band.save(fan, band_params) }.to raise_error("must be a musician") + end + + it "can update" do + band = Band.save(user, band_params) + band.errors.any?.should be_false + band_params[:id] = band.id + band_params[:name] = "changed name" + band = Band.save(user, band_params) + band.errors.any?.should be_false + Band.find(band.id).name.should == band_params[:name] + end + + it "stops non-members from updating" do + band = Band.save(user, band_params) + band.errors.any?.should be_false + band_params[:id] = band.id + band_params[:name] = "changed name" + expect{ Band.save(user2, band_params) }.to raise_error(ValidationMessages::USER_NOT_BAND_MEMBER_VALIDATION_ERROR) + end + end + + describe "validate" do + it "can pass" do + band = Band.build_band(user, band_params) + band.valid?.should be_true + end + + it "can fail" do + band_params[:name] = nil + band = Band.build_band(user, band_params) + band.valid?.should be_false + band.errors[:name].should == ["can't be blank"] + end + end end diff --git a/ruby/spec/jam_ruby/models/feed_spec.rb b/ruby/spec/jam_ruby/models/feed_spec.rb index 13cb877b6..7ec9a5f79 100644 --- a/ruby/spec/jam_ruby/models/feed_spec.rb +++ b/ruby/spec/jam_ruby/models/feed_spec.rb @@ -6,16 +6,18 @@ describe Feed do let (:user2) { FactoryGirl.create(:user) } let (:user3) { FactoryGirl.create(:user) } let (:user4) { FactoryGirl.create(:user) } + let (:band) { FactoryGirl.create(:band) } it "no result" do - feeds, start = Feed.index() + feeds, start = Feed.index(user1) feeds.length.should == 0 end it "one claimed recording" do claimed_recording = FactoryGirl.create(:claimed_recording) + MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording MusicSessionHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording - feeds, start = Feed.index() + feeds, start = Feed.index(user1) feeds.length.should == 1 feeds[0].recording == claimed_recording.recording end @@ -25,27 +27,38 @@ describe Feed do second_track = FactoryGirl.create(:recorded_track, recording: recording) recording.recorded_tracks << second_track FactoryGirl.create(:claimed_recording, recording: recording, user: second_track.user) + MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording MusicSessionHistory.delete_all # verify the mess above only made one recording Recording.count.should == 1 - feeds, start = Feed.index + feeds, start = Feed.index(user1) feeds.length.should == 1 end it "one music session" do music_session = FactoryGirl.create(:music_session) - feeds, start = Feed.index + feeds, start = Feed.index(user1) feeds.length.should == 1 feeds[0].music_session_history == music_session.music_session_history end + it "does not return a recording with no claimed recordings" do + recording = FactoryGirl.create(:recording) + MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording + MusicSessionHistory.delete_all + + + feeds, start = Feed.index(user1) + feeds.length.should == 0 + end + describe "sorting" do it "sorts by index (date) DESC" do claimed_recording = FactoryGirl.create(:claimed_recording) - feeds, start = Feed.index + feeds, start = Feed.index(user1) feeds.length.should == 2 feeds[0].recording.should == claimed_recording.recording feeds[1].music_session_history.should == claimed_recording.recording.music_session.music_session_history @@ -57,13 +70,13 @@ describe Feed do FactoryGirl.create(:recording_play, recording: claimed_recording1.recording, user:claimed_recording1.user) - feeds, start = Feed.index(:sort => 'plays') + feeds, start = Feed.index(user1, :sort => 'plays') feeds.length.should == 4 FactoryGirl.create(:recording_play, recording: claimed_recording2.recording, user:claimed_recording1.user) FactoryGirl.create(:recording_play, recording: claimed_recording2.recording, user:claimed_recording2.user) - feeds, start = Feed.index(:sort => 'plays') + feeds, start = Feed.index(user1, :sort => 'plays') feeds.length.should == 4 feeds[0].recording.should == claimed_recording2.recording feeds[1].recording.should == claimed_recording1.recording @@ -73,7 +86,7 @@ describe Feed do FactoryGirl.create(:music_session_play, music_session: claimed_recording1.recording.music_session.music_session_history, user: user3) - feeds, start = Feed.index(:sort => 'plays') + feeds, start = Feed.index(user1, :sort => 'plays') feeds.length.should == 4 feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history feeds[1].recording.should == claimed_recording2.recording @@ -86,13 +99,13 @@ describe Feed do FactoryGirl.create(:recording_like, recording: claimed_recording1.recording, user:claimed_recording1.user) - feeds, start = Feed.index(:sort => 'likes') + feeds, start = Feed.index(user1, :sort => 'likes') feeds.length.should == 4 FactoryGirl.create(:recording_like, recording: claimed_recording2.recording, user:claimed_recording1.user) FactoryGirl.create(:recording_like, recording: claimed_recording2.recording, user:claimed_recording2.user) - feeds, start = Feed.index(:sort => 'likes') + feeds, start = Feed.index(user1, :sort => 'likes') feeds.length.should == 4 feeds[0].recording.should == claimed_recording2.recording feeds[1].recording.should == claimed_recording1.recording @@ -101,7 +114,7 @@ describe Feed do FactoryGirl.create(:music_session_like, music_session_history: claimed_recording1.recording.music_session.music_session_history, user: user2) FactoryGirl.create(:music_session_like, music_session_history: claimed_recording1.recording.music_session.music_session_history, user: user3) - feeds, start = Feed.index(:sort => 'likes') + feeds, start = Feed.index(user1, :sort => 'likes') feeds.length.should == 4 feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history feeds[1].recording.should == claimed_recording2.recording @@ -114,7 +127,7 @@ describe Feed do # creates both recording and history record in feed claimed_recording1 = FactoryGirl.create(:claimed_recording) - feeds, start = Feed.index(:type => 'session') + feeds, start = Feed.index(user1, :type => 'music_session_history') feeds.length.should == 1 feeds[0].music_session_history == claimed_recording1.recording.music_session.music_session_history end @@ -123,27 +136,78 @@ describe Feed do # creates both recording and history record in feed claimed_recording1 = FactoryGirl.create(:claimed_recording) - feeds, start = Feed.index(:type => 'session') + feeds, start = Feed.index(user1, :type => 'music_session_history') feeds.length.should == 1 feeds[0].music_session_history == claimed_recording1.recording.music_session.music_session_history end end + + describe "time ranges" do + it "month" do + # creates both recording and history record in feed + claimed_recording1 = FactoryGirl.create(:claimed_recording) + + # move the feed entry created for the recording back more than a months ago + claimed_recording1.recording.feed.created_at = 32.days.ago + claimed_recording1.recording.feed.save! + + feeds, start = Feed.index(user1, :type => 'recording') + feeds.length.should == 0 + end + + it "day" do + # creates both recording and history record in feed + claimed_recording1 = FactoryGirl.create(:claimed_recording) + + # move the feed entry created for the recording back more than a months ago + claimed_recording1.recording.feed.created_at = 25.hours.ago + claimed_recording1.recording.feed.save! + + feeds, start = Feed.index(user1, :type => 'recording', time_range: 'today') + feeds.length.should == 0 + end + + it "week" do + # creates both recording and history record in feed + claimed_recording1 = FactoryGirl.create(:claimed_recording) + + # move the feed entry created for the recording back more than a months ago + claimed_recording1.recording.feed.created_at = 8.days.ago + claimed_recording1.recording.feed.save! + + feeds, start = Feed.index(user1, :type => 'recording', time_range: 'week') + feeds.length.should == 0 + end + + it "all" do + # creates both recording and history record in feed + claimed_recording1 = FactoryGirl.create(:claimed_recording) + + # move the feed entry created for the recording back more than a months ago + claimed_recording1.recording.feed.created_at = 700.days.ago + claimed_recording1.recording.feed.save! + + feeds, start = Feed.index(user1, :type => 'recording', time_range: 'all') + feeds.length.should == 1 + end + end + describe "pagination" do it "supports date pagination" do claimed_recording = FactoryGirl.create(:claimed_recording) options = {limit: 1} - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 1 feeds[0].recording.should == claimed_recording.recording options[:start] = start - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 1 feeds[0].music_session_history.should == claimed_recording.recording.music_session.music_session_history options[:start] = start - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 0 start.should be_nil end @@ -154,17 +218,17 @@ describe Feed do FactoryGirl.create(:music_session_like, music_session_history: claimed_recording1.recording.music_session.music_session_history, user: user1) options = {limit: 1, sort: 'likes'} - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 1 feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history options[:start] = start - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 1 feeds[0].recording.should == claimed_recording1.recording options[:start] = start - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 0 start.should be_nil end @@ -175,21 +239,221 @@ describe Feed do FactoryGirl.create(:music_session_play, music_session: claimed_recording1.recording.music_session.music_session_history, user: user1) options = {limit: 1, sort: 'plays'} - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 1 feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history options[:start] = start - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 1 feeds[0].recording.should == claimed_recording1.recording options[:start] = start - feeds, start = Feed.index(options) + feeds, start = Feed.index(user1, options) feeds.length.should == 0 start.should be_nil end - end + describe "public feed" do + it "only public" do + claimed_recording1 = FactoryGirl.create(:claimed_recording) + claimed_recording1.is_public = false + claimed_recording1.save! + + feeds, start = Feed.index(claimed_recording1.user) + feeds.length.should == 1 + + claimed_recording1.recording.music_session.fan_access = false + claimed_recording1.recording.music_session.save! + + feeds, start = Feed.index(claimed_recording1.user) + feeds.length.should == 0 + end + end + + describe "band feeds" do + it "does show other band's stuff in this feed" do + other_band = FactoryGirl.create(:band) + music_session = FactoryGirl.create(:music_session, band: other_band) + FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user1) + + claimed_recording1 = FactoryGirl.create(:claimed_recording) + claimed_recording1.is_public = true + claimed_recording1.recording.band = other_band + claimed_recording1.recording.save! + claimed_recording1.save! + + feeds, start = Feed.index(user1, band: band.id) + feeds.length.should == 0 + end + + it "shows public recordings to you and to others" do + user1.bands << band + user1.save! + music_session = FactoryGirl.create(:music_session, band: band) + music_session.music_session_history.fan_access.should be_true + + feeds, start = Feed.index(user1, band: band.id) + feeds.length.should == 1 + feeds[0].music_session_history.should == music_session.music_session_history + + feeds, start = Feed.index(user2, band: band.id) + feeds.length.should == 1 + feeds[0].music_session_history.should == music_session.music_session_history + end + + it "shows private sessions to you, not to others" do + user1.bands << band + user1.save! + music_session = FactoryGirl.create(:music_session, band: band, fan_access: false) + music_session.music_session_history.fan_access.should be_false + + feeds, start = Feed.index(user1, band: band.id) + feeds.length.should == 1 + feeds[0].music_session_history.should == music_session.music_session_history + feeds[0].music_session_history.fan_access.should be_false + + + feeds, start = Feed.index(user2, band: band.id) + feeds.length.should == 0 + end + + it "shows public recordings to you and to others" do + claimed_recording1 = FactoryGirl.create(:claimed_recording) + claimed_recording1.is_public = true + claimed_recording1.recording.band = band + claimed_recording1.recording.save! + claimed_recording1.save! + + feeds, start = Feed.index(claimed_recording1.user, band: band.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1.recording + + feeds, start = Feed.index(user1, band: band.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1.recording + end + + it "shows private recordings to you, not to others" do + claimed_recording1 = FactoryGirl.create(:claimed_recording) + claimed_recording1.is_public = false + claimed_recording1.recording.band = band + claimed_recording1.recording.save! + claimed_recording1.save! + + claimed_recording1.user.bands << band + claimed_recording1.user.save! + + feeds, start = Feed.index(claimed_recording1.user, band: band.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1.recording + + feeds, start = Feed.index(user1, band: band.id) + feeds.length.should == 0 + end + end + + describe "user feeds" do + it "does not show stuff from other people" do + music_session = FactoryGirl.create(:music_session) + FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user2) + + claimed_recording1 = FactoryGirl.create(:claimed_recording) + claimed_recording1.is_public = true + claimed_recording1.save! + + feeds, start = Feed.index(user1, user: user1.id) + feeds.length.should == 0 + end + + it "shows public sessions to you and to others" do + music_session = FactoryGirl.create(:music_session) + FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user1) + + feeds, start = Feed.index(user1, user: user1.id) + feeds.length.should == 1 + feeds[0].music_session_history.should == music_session.music_session_history + + feeds, start = Feed.index(user2, user: user1.id) + feeds.length.should == 1 + feeds[0].music_session_history.should == music_session.music_session_history + end + + + it "shows private sessions to you, not to others" do + music_session = FactoryGirl.create(:music_session, fan_access: false) + music_session.music_session_history.fan_access.should be_false + FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user1) + + feeds, start = Feed.index(user1, user: user1.id) + feeds.length.should == 1 + feeds[0].music_session_history.should == music_session.music_session_history + feeds[0].music_session_history.fan_access.should be_false + + + feeds, start = Feed.index(user2, user: user1.id) + feeds.length.should == 0 + end + + it "shows public recordings to you and to others" do + claimed_recording1 = FactoryGirl.create(:claimed_recording) + claimed_recording1.is_public = true + claimed_recording1.save! + + feeds, start = Feed.index(claimed_recording1.user, user: claimed_recording1.user.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1.recording + + feeds, start = Feed.index(user1, user: claimed_recording1.user.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1.recording + end + + it "shows private recordings to you, not to others" do + claimed_recording1 = FactoryGirl.create(:claimed_recording) + claimed_recording1.is_public = false + claimed_recording1.save! + + feeds, start = Feed.index(claimed_recording1.user, user: claimed_recording1.user.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1.recording + + feeds, start = Feed.index(user1, user: claimed_recording1.user.id) + feeds.length.should == 0 + end + + it "shows band recordings to you even though you did not claim a recording" do + user1.bands << band + user1.save! + user2.bands << band + user2.save! + + claimed_recording1 = FactoryGirl.create(:claimed_recording, user: user2) + claimed_recording1.is_public = true + claimed_recording1.recording.band = band + claimed_recording1.recording.save! + claimed_recording1.save! + + feeds, start = Feed.index(user1, user: user1.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1 .recording + + # make it private; should still be available + claimed_recording1.is_public = false + claimed_recording1.save! + + feeds, start = Feed.index(user1, user: user1.id) + feeds.length.should == 1 + feeds[0].recording.should == claimed_recording1 .recording + + # take user1 out of the band; shouldn't be able to see it + user1.bands.delete_all + + feeds, start = Feed.index(user1, user: user1.id) + feeds.length.should == 0 + end + end + + end diff --git a/ruby/spec/jam_ruby/models/music_session_history_spec.rb b/ruby/spec/jam_ruby/models/music_session_history_spec.rb index 183e9f6c4..0a66ec69b 100644 --- a/ruby/spec/jam_ruby/models/music_session_history_spec.rb +++ b/ruby/spec/jam_ruby/models/music_session_history_spec.rb @@ -4,18 +4,17 @@ describe MusicSessionHistory do let(:some_user) { FactoryGirl.create(:user) } let(:music_session) { FactoryGirl.create(:music_session_no_history) } - let(:history) { FactoryGirl.create(:music_session_history, :music_session => music_session) } - let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => history, :user => music_session.creator) } - let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => history, :user => some_user) } + let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => music_session.creator) } + let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => some_user) } it "create" do - history.description.should eql(music_session.description) + music_session.music_session_history.description.should eql(music_session.description) end it "unique users" do user_history1.should_not be_nil user_history2.should_not be_nil - users = history.unique_users + users = music_session.music_session_history.unique_users users.length.should eql(2) diff --git a/ruby/spec/jam_ruby/models/music_sessions_user_history_spec.rb b/ruby/spec/jam_ruby/models/music_sessions_user_history_spec.rb index b6c719151..3d7713b86 100644 --- a/ruby/spec/jam_ruby/models/music_sessions_user_history_spec.rb +++ b/ruby/spec/jam_ruby/models/music_sessions_user_history_spec.rb @@ -4,9 +4,8 @@ describe MusicSessionUserHistory do let(:some_user) { FactoryGirl.create(:user) } let(:music_session) { FactoryGirl.create(:music_session_no_history) } - let(:history) { FactoryGirl.create(:music_session_history, :music_session => music_session) } - let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => history, :user => music_session.creator) } - let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => history, :user => some_user) } + let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => music_session.creator) } + let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => some_user) } describe "create" do it {user_history1.music_session_id.should == music_session.id } @@ -78,7 +77,7 @@ describe MusicSessionUserHistory do end it "two histories with same user within bounds of history1" do - user_history3 = FactoryGirl.create(:music_session_user_history, :history => history, :user => some_user) + user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => some_user) # if user2 comes and goes 2 times while user one is there, it shouldn't be a false 3 user_history1.session_removed_at = user_history1.created_at + 5 @@ -99,7 +98,7 @@ describe MusicSessionUserHistory do it "two histories with different user within bounds of history1" do third_user = FactoryGirl.create(:user); - user_history3 = FactoryGirl.create(:music_session_user_history, :history => history, :user => third_user) + user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => third_user) # if user2 comes and goes 2 times while user one is there, it shouldn't be a false 3 user_history1.session_removed_at = user_history1.created_at + 5 @@ -120,7 +119,7 @@ describe MusicSessionUserHistory do it "two overlapping histories with different user within bounds of history1" do third_user = FactoryGirl.create(:user); - user_history3 = FactoryGirl.create(:music_session_user_history, :history => history, :user => third_user) + user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => third_user) # if user2 comes and goes 2 times while user one is there, it shouldn't be a false 3 user_history1.session_removed_at = user_history1.created_at + 5 diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb index 8b747ead5..60f32513b 100644 --- a/ruby/spec/spec_helper.rb +++ b/ruby/spec/spec_helper.rb @@ -61,6 +61,7 @@ Spork.prefork do # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| + config.color_enabled = true config.treat_symbols_as_metadata_keys_with_true_values = true config.run_all_when_everything_filtered = true config.filter_run :focus diff --git a/web/Gemfile b/web/Gemfile index 195f731f8..5048d1b00 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -55,7 +55,6 @@ gem 'fog' gem 'haml-rails' gem 'unf' #optional fog dependency gem 'devise', '>= 1.1.2' -#gem 'thin' # the presence of this gem on mac seems to prevent normal startup of rails. gem 'postgres-copy' #group :libv8 do # gem 'libv8', "~> 3.11.8" diff --git a/web/app/assets/images/content/icon_instrument_piano24.png b/web/app/assets/images/content/icon_instrument_piano24.png new file mode 100644 index 000000000..6f5761df9 Binary files /dev/null and b/web/app/assets/images/content/icon_instrument_piano24.png differ diff --git a/web/app/assets/images/content/icon_instrument_piano45.png b/web/app/assets/images/content/icon_instrument_piano45.png new file mode 100644 index 000000000..5d44d4420 Binary files /dev/null and b/web/app/assets/images/content/icon_instrument_piano45.png differ diff --git a/web/app/assets/images/content/icon_instrument_upright_bass24.png b/web/app/assets/images/content/icon_instrument_upright_bass24.png new file mode 100644 index 000000000..c054f32ad Binary files /dev/null and b/web/app/assets/images/content/icon_instrument_upright_bass24.png differ diff --git a/web/app/assets/images/content/icon_instrument_upright_bass45.png b/web/app/assets/images/content/icon_instrument_upright_bass45.png new file mode 100644 index 000000000..7c2b8e1d1 Binary files /dev/null and b/web/app/assets/images/content/icon_instrument_upright_bass45.png differ diff --git a/web/app/assets/images/shared/icon_piano_256.png b/web/app/assets/images/shared/icon_piano_256.png new file mode 100644 index 000000000..b2f63670f Binary files /dev/null and b/web/app/assets/images/shared/icon_piano_256.png differ diff --git a/web/app/assets/images/shared/icon_upright_bass_256.png b/web/app/assets/images/shared/icon_upright_bass_256.png new file mode 100644 index 000000000..c5373a215 Binary files /dev/null and b/web/app/assets/images/shared/icon_upright_bass_256.png differ diff --git a/web/app/assets/javascripts/bandProfile.js b/web/app/assets/javascripts/bandProfile.js index cdb49ae8b..20ff38afc 100644 --- a/web/app/assets/javascripts/bandProfile.js +++ b/web/app/assets/javascripts/bandProfile.js @@ -16,9 +16,20 @@ } function afterShow(data) { - resetForm(); - events(); - renderActive(); + + // hide until we know if 'isMember' + $("#btn-follow-band").hide(); + $("#btn-edit-band-profile").hide(); + + resetForm(); + events(); + determineMembership() + .done(function() { + renderActive(); + }) + .fail(function(jqXHR) { + app.notifyServerError(jqXHR, "Unable to talk to server") + }) } function resetForm() { @@ -128,6 +139,16 @@ // refreshes the currently active tab function renderActive() { + + if (isMember) { + $("#btn-follow-band").hide(); + $("#btn-edit-band-profile").show(); + } + else { + $("#btn-follow-band").show(); + $("#btn-edit-band-profile").hide(); + } + if ($('#band-profile-about-link').hasClass('active')) { renderAbout(); } @@ -161,7 +182,6 @@ rest.getBand(bandId) .done(function(response) { band = response; - setIsMember(); if (band) { // name $('#band-profile-name').html(band.name); @@ -379,47 +399,37 @@ } } - // TODO: refactor // checks if person viewing the profile is also a band member - function setIsMember() { + function determineMembership() { var url = "/api/bands/" + bandId + "/musicians"; - $.ajax({ + return $.ajax({ type: "GET", dataType: "json", url: url, - async: false, processData:false, - success: function(response) { - $.each(response, function(index, val) { - if (val.id === context.JK.currentUserId) { - isMember = true; - } - }); - }, error: app.ajaxError - }); + }) + .done(function(response) { + isMember = false; + $.each(response, function(index, val) { + if (val.id === context.JK.currentUserId) { + isMember = true; + } + }); + }) } // events for main screen function events() { // wire up panel clicks - $('#band-profile-about-link').click(renderAbout); - $('#band-profile-history-link').click(renderHistory); - $('#band-profile-members-link').click(renderMembers); - $('#band-profile-social-link').click(renderSocial); + $('#band-profile-about-link').unbind('click').click(renderAbout); + $('#band-profile-history-link').unbind('click').click(renderHistory); + $('#band-profile-members-link').unbind('click').click(renderMembers); + $('#band-profile-social-link').unbind('click').click(renderSocial); - if (isMember) { - $("#btn-follow-band").hide(); - $("#btn-edit-band-profile").show(); - } - else { - $("#btn-follow-band").show(); - $("#btn-edit-band-profile").hide(); - } - - $("#btn-edit-band-profile").click(function() { - $('div[layout-id="band/setup"] .hdn-band-id').val(bandId); - context.location = "/client#/band/setup"; + $("#btn-edit-band-profile").unbind('click').click(function() { + //$('div[layout-id="band/setup"] .hdn-band-id').val(bandId); + context.location = "/client#/band/setup/" + bandId; return false; }); } diff --git a/web/app/assets/javascripts/band_setup.js b/web/app/assets/javascripts/band_setup.js index 79d25bcb1..875f31f41 100644 --- a/web/app/assets/javascripts/band_setup.js +++ b/web/app/assets/javascripts/band_setup.js @@ -21,45 +21,43 @@ var nilOptionText = 'n/a'; var bandId = ''; + function is_new_record() { + return bandId.length == 0; + } + + function removeErrors() { + $('#band-setup-form .error-text').remove() + $('#band-setup-form .error').removeClass("error") + + } + function resetForm() { + removeErrors(); + // name $("#band-name").val(''); - var $tdName = $("#tdBandName"); - $tdName.find('.error-text').remove(); - $tdName.removeClass("error"); // country $("#band-country").empty(); $("#band-country").val(''); - var $tdCountry = $("#tdBandCountry"); - $tdCountry.find('.error-text').remove(); - $tdCountry.removeClass("error"); // region $("#band-region").empty(); $("#band-region").val(''); - var $tdRegion = $("#tdBandRegion"); - $tdRegion.find('.error-text').remove(); - $tdRegion.removeClass("error"); // city $("#band-city").empty(); $("#band-city").val(''); - var $tdCity = $("#tdBandCity"); - $tdCity.find('.error-text').remove(); - $tdCity.removeClass("error"); // description $("#band-biography").val(''); - var $tdBiography = $("#tdBandBiography"); - $tdBiography.find('.error-text').remove(); - $tdBiography.removeClass("error"); + + // website + $('#band-website').val(''); resetGenres(); - $("#hdn-band-id").val(''); - $("#band-setup-step-1").show(); $("#band-setup-step-2").hide(); @@ -75,8 +73,6 @@ }); var $tdGenres = $("#tdBandGenres"); - $tdGenres.find('.error-text').remove(); - $tdGenres.removeClass("error"); } function getSelectedGenres() { @@ -90,96 +86,32 @@ } function validateGeneralInfo() { - var isValid = true; + removeErrors(); - // name - var $name = $("#band-name"); - var $tdName = $("#tdBandName"); - var name = $.trim($name.val()); - if (name.length === 0) { - $tdName.find('.error-text').remove(); - $tdName.addClass("error"); - $name.after("