Add more test cases and logic changes

This commit is contained in:
Seth Call 2021-02-21 15:07:31 -06:00
parent e8d74a119c
commit 03fab14ef3
5 changed files with 204 additions and 24 deletions

View File

@ -168,13 +168,13 @@ module JamRuby
num_participants = music_session.users.count
puts "NUM PARTICIPANTS BEFORE JOIN #{num_participants}"
subscription_rules = self.user.subscription_rules(dynamic_definitions = false)
max_players = subscription_rules[:max_players]
if !max_players.nil?
if num_participants >= max_players
errors.add(:music_session, ValidationMessages::PLAN_PROHIBIT_MAX_PLAYERS)
# temporarily disable enforcement of this per David's request due to high support volume
#errors.add(:music_session, ValidationMessages::PLAN_PROHIBIT_MAX_PLAYERS)
end
end

View File

@ -61,17 +61,27 @@ module JamRuby
# end
#take duration that this user session was with other
#
# use this as a base: https://wiki.postgresql.org/wiki/Range_aggregation
# But the 'intervals' table from that example is instead our own 'compute intersections' from this msuh and all others in the same session not of the same user ID
def duration_minutes
created_at_db = self.created_at.utc.strftime '%Y-%m-%d %H:%M:%S'
session_removed_at_db = self.session_removed_at.utc.strftime '%Y-%m-%d %H:%M:%S'
query = <<-SQL
select sum(upper(diff) - lower(diff)) as duration
FROM (
SELECT tsrange(created_at, session_removed_at, '[]') * tsrange('#{self.created_at.strftime '%Y-%m-%d %H:%M:%S'}', '#{self.session_removed_at.strftime '%Y-%m-%d %H:%M:%S'}', '[]') AS diff
FROM music_sessions_user_history
WHERE music_session_id = '#{self.music_session_id}'
AND id <> '#{self.id}'
) AS derivedTable
SELECT sum(e - s) as duration
FROM
(SELECT min(s) as s, max(e) as e
FROM (SELECT s, e,
MAX(new_start) OVER (ORDER BY s,e) AS left_edge
FROM
(SELECT s, e, CASE WHEN s < max(le) OVER (ORDER BY s,e) THEN null ELSE s END AS new_start
FROM (SELECT s, e, lag(e) OVER (ORDER BY s,e) AS le FROM
(SELECT UPPER(diff) as e, LOWER(diff) as s FROM (SELECT tsrange(created_at, COALESCE(session_removed_at, '#{session_removed_at_db}'), '[]') * tsrange('#{created_at_db}', '#{session_removed_at_db}', '[]') AS diff
FROM music_sessions_user_history
WHERE music_session_id = '#{self.music_session_id}'
AND created_at <= '#{session_removed_at_db}'
AND (user_id <> '#{self.user_id}')) AS intervals) as tah
) s1) s2) s3
GROUP BY left_edge) as cleaned
SQL
result = ActiveRecord::Base.connection.exec_query(query)
duration = result.cast_values[0]
@ -109,9 +119,11 @@ SQL
if self.session_removed_at.nil?
self.session_removed_at = Time.now
end
self.max_concurrent_connections = determine_max_concurrent
self.update_attributes(:session_removed_at => self.session_removed_at, :max_concurrent_connections => self.max_concurrent_connections)
self.update_remaining_play_time
if self.max_concurrent_connections.nil?
self.max_concurrent_connections = determine_max_concurrent
self.update_attributes(:session_removed_at => self.session_removed_at, :max_concurrent_connections => self.max_concurrent_connections)
self.update_remaining_play_time
end
end
# update the users monthly play time

View File

@ -2872,6 +2872,10 @@ module JamRuby
SubscriptionDefinitions.rules(self.subscription_plan_code)[:has_support]
end
def reset_playtime
self.used_month_play_time = 0
end
def subscription_rules(dynamic_definitions = true)
rules = SubscriptionDefinitions.rules(self.subscription_plan_code)
if dynamic_definitions

View File

@ -360,7 +360,7 @@ module JamRuby
end
end
current_user.reset_playtime
current_user.save(validate: false)
rescue => e
puts "Could not create subscription for user #{current_user.email}. #{e}"
@ -604,6 +604,7 @@ module JamRuby
if user.subscription_plan_code != user.desired_plan_code
puts "they are back! get them back into their desired plan #{user.email}"
if !SubscriptionDefinitions.is_downgrade(user.desired_plan_code, user.subscription_plan_code)
user.reset_playtime
user.subscription_plan_code = user.desired_plan_code
user.subscription_plan_code_set_at = DateTime.now
user.subscription_sync_code = 'good_standing_repaired'

View File

@ -3,6 +3,7 @@ require 'spec_helper'
describe MusicSessionUserHistory do
let(:some_user) { FactoryGirl.create(:user) }
let(:some_other_user) { FactoryGirl.create(:user) }
let(:music_session) { FactoryGirl.create(:active_music_session_no_user_history) }
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator) }
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user) }
@ -104,8 +105,12 @@ describe MusicSessionUserHistory do
user_history2.created_at = user_history1.created_at - 1
user_history2.session_removed_at = user_history1.created_at + 2
#user_history1.save.should be_true
user_history2.save.should be_true
expect(user_history1.session_removed_at).to be > user_history1.created_at
expect(user_history2.session_removed_at).to be > user_history2.created_at
user_history1.reload
user_history2.reload
user_history1.end_history
@ -123,6 +128,7 @@ describe MusicSessionUserHistory do
user_history1.reload
user_history2.reload
user_history1.end_history
user_history1.max_concurrent_connections.should == 2
@ -205,38 +211,32 @@ describe MusicSessionUserHistory do
describe "duration_minutes" do
it "returns zero when history2 ends before history1 starts" do
user_history1.session_removed_at = user_history1.created_at + 5
user_history2.created_at = user_history1.created_at - 2
user_history2.session_removed_at = user_history1.created_at - 1
user_history2.save.should be_true
user_history1.reload
user_history2.reload
user_history1.end_history
expect(user_history1.duration_minutes).to eq 0
end
it "returns zero when history2 starts after history1 ends" do
user_history1.session_removed_at = user_history1.created_at + 5
user_history2.created_at = user_history1.session_removed_at + 1
user_history2.session_removed_at = user_history1.session_removed_at + 2
user_history2.save.should be_true
user_history1.reload
user_history2.reload
user_history1.end_history
#user_history1.max_concurrent_connections.should == 1
expect(user_history1.duration_minutes).to eq 0
end
@ -256,6 +256,29 @@ describe MusicSessionUserHistory do
expect(user_history1.duration_minutes).to eq 2
end
it "returns overlapped time when history2 is within bounds of history1 -- idempotent" do
#pending
user_history1.session_removed_at = user_history1.created_at + 3*60
user_history2.created_at = user_history1.created_at + 1*60
user_history2.session_removed_at = user_history1.created_at + 3*60
user_history1.save.should be_true
user_history2.save.should be_true
user_history1.reload
user_history2.reload
user_history1.end_history
expect(user_history1.duration_minutes).to eq 2
music_session.creator.reload
expect(music_session.creator.used_month_play_time).to eq (2 * 60)
# call it a second tiem
user_history1.end_history
expect(user_history1.duration_minutes).to eq 2
music_session.creator.reload
expect(music_session.creator.used_month_play_time).to eq (2 * 60)
end
it "returns overlapped time when history2 begings before history1 start and terminates before history1 end" do
user_history1.session_removed_at = user_history1.created_at + 3*60
user_history2.created_at = user_history1.created_at - 1*60
@ -283,8 +306,148 @@ describe MusicSessionUserHistory do
user_history1.end_history
expect(user_history1.duration_minutes).to eq 2
end
it "same user in same session does not rack up time" do
same_user_history = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator)
user_history1.session_removed_at = user_history1.created_at + 3*60
same_user_history.created_at = user_history1.created_at + 1*60
same_user_history.session_removed_at = user_history1.created_at + 4*60
expect(user_history1.save).to eq true
expect(same_user_history.save).to eq true
user_history1.end_history
expect(user_history1.duration_minutes).to eq 0
end
it "3rd user has no bearing on accumulated time if same overlapping as 2nd user" do
user_history1.session_removed_at = user_history1.created_at + 3*60
user_history2.created_at = user_history1.created_at + 1*60
user_history2.session_removed_at = user_history1.created_at + 4*60
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_other_user)
user_history3.created_at = user_history1.created_at + 1*60
user_history3.session_removed_at = user_history1.created_at + 4*60
expect(user_history1.save).to eq true
expect(user_history2.save).to eq true
expect(user_history3.save).to eq true
user_history1.end_history
expect(user_history1.duration_minutes).to eq 2
end
it "3rd user has some bearing on accumulated time if different overlapping as 2nd user" do
user_history1.session_removed_at = user_history1.created_at + 7*60
user_history2.created_at = user_history1.created_at + 1*60
user_history2.session_removed_at = user_history1.created_at + 3*60
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_other_user)
user_history3.created_at = user_history1.created_at + 2*60
user_history3.session_removed_at = user_history1.created_at + 4*60
expect(user_history1.save).to eq true
expect(user_history2.save).to eq true
expect(user_history3.save).to eq true
user_history1.end_history
expect(user_history1.duration_minutes).to eq 3
end
it "two users where 1st guy leaves last, and no save of that record" do
user_history1.session_removed_at = user_history1.created_at + 7*60
user_history2.created_at = user_history1.created_at - 1*60
user_history2.session_removed_at = user_history1.created_at + 3*60
expect(user_history2.save).to eq true
user_history1.end_history
expect(user_history1.duration_minutes).to eq 3
end
it "two users where users all leaves, but then come back to same session 2x" do
user_history1.session_removed_at = user_history1.created_at + 7*60
user_history2.created_at = user_history1.created_at - 1*60
user_history2.session_removed_at = user_history1.created_at + 3*60
expect(user_history2.save).to eq true
user_history1.end_history
# validate duration minutes works
expect(user_history1.duration_minutes).to eq 3
expect(music_session.creator.used_month_play_time).to be_nil
music_session.creator.reload
# and validate that the users rolling monthly play time is tracked correctly
expect(music_session.creator.used_month_play_time).to eq 3 * 60 # this field tracks per second
expect(music_session.creator.used_current_month).to eq (User.current_month)
# COME BACK INTO SAME SESSION LATER
user_history1_returns = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator)
user_history2_returns = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user)
user_history1_returns.created_at = user_history1.created_at + 8*60
user_history1_returns.session_removed_at = user_history1.created_at + 16*60
user_history2_returns.created_at = user_history1.created_at + 7*60
user_history2_returns.session_removed_at = user_history1.created_at + 12*60
expect(user_history1_returns.save).to eq true
expect(user_history2_returns.save).to eq true
user_history1_returns.end_history
expect(user_history1_returns.duration_minutes).to eq 4
expect(music_session.creator.used_month_play_time).to eq 3 * 60
music_session.creator.reload
# validate that the users rolling monthly play time is still tracked correctly
expect(music_session.creator.used_month_play_time).to eq (3 + 4) * 60 # 3 minutes + 4 minutes should be 7
# AND COME BACK ONCE MORE
user_history1_returns2 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator)
user_history2_returns2 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user)
user_history1_returns2.created_at = user_history1.created_at + 20*60
user_history1_returns2.session_removed_at = user_history1.created_at + 25*60
user_history2_returns2.created_at = user_history1.created_at + 21*60
user_history2_returns2.session_removed_at = user_history1.created_at + 22*60
expect(user_history1_returns2.save).to eq true
expect(user_history2_returns2.save).to eq true
user_history1_returns2.end_history
expect(user_history1_returns2.duration_minutes).to eq 1
expect(music_session.creator.used_month_play_time).to eq (3 + 4) * 60
music_session.creator.reload
# validate that the users rolling monthly play time is still tracked correctly
expect(music_session.creator.used_month_play_time).to eq (3 + 4 + 1) * 60
end
it "a null session_removed of other substituted with the msuh's session_removed" do
user_history1.session_removed_at = user_history1.created_at + 7*60
user_history2.created_at = user_history1.created_at + 1*60
user_history2.session_removed_at = nil
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_other_user)
user_history3.created_at = user_history1.created_at + 2*60
user_history3.session_removed_at = nil
expect(user_history1.save).to eq true
expect(user_history2.save).to eq true
expect(user_history3.save).to eq true
user_history1.end_history
expect(user_history1.duration_minutes).to eq 6
end
end
end