jam-cloud/ruby/spec/jam_ruby/models/lesson_session_analyser_spe...

313 lines
11 KiB
Ruby

=begin
require 'spec_helper'
describe LessonSessionAnalyser do
let(:user) { FactoryGirl.create(:user, remaining_test_drives: 1) }
let(:teacher) { FactoryGirl.create(:teacher_user) }
let(:start) { Time.now }
let(:lesson_booking_slot_single1) { FactoryGirl.build(:lesson_booking_slot_single) }
let(:lesson_booking_slot_single2) { FactoryGirl.build(:lesson_booking_slot_single) }
let(:lesson_booking_slot_recurring1) { FactoryGirl.build(:lesson_booking_slot_recurring) }
let(:lesson_booking_slot_recurring2) { FactoryGirl.build(:lesson_booking_slot_recurring) }
let(:valid_single_slots) { [lesson_booking_slot_single1, lesson_booking_slot_single2] }
let(:valid_recurring_slots) { [lesson_booking_slot_recurring1, lesson_booking_slot_recurring2] }
describe "analyse" do
after{
Timecop.return
}
it "neither show" do
lesson = testdrive_lesson(user, teacher)
music_session = lesson.music_session
Timecop.freeze((lesson.music_session.scheduled_start + lesson.duration * 60) + 1)
analysis = LessonSessionAnalyser.analyse(lesson)
analysis[:reason].should eql LessonSessionAnalyser::TEACHER_FAULT
analysis[:student].should eql nil
analysis[:bill].should be false
student = analysis[:student_analysis]
student[:joined_on_time].should be false
student[:joined_late].should be false
student[:waited_correctly].should be false
student[:initial_waiting_pct].should eql nil
student[:potential_waiting_time].should eql nil
together = analysis[:together_analysis]
together[:session_time].should eql 0
end
it "teacher joined on time, waited, student no show" do
lesson = testdrive_lesson(user, teacher)
music_session = lesson.music_session
# create some bogus, super-perfect teacher/student times
start = lesson.scheduled_start
end_time = lesson.scheduled_start + (60 * lesson.duration)
uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: music_session, created_at: start, session_removed_at: end_time)
Timecop.travel(end_time + 1)
analysis = LessonSessionAnalyser.analyse(lesson)
analysis[:reason].should eql LessonSessionAnalyser::STUDENT_FAULT
analysis[:student].should eql LessonSessionAnalyser::NO_SHOW
analysis[:bill].should be true
student = analysis[:student_analysis]
student[:joined_on_time].should be false
student[:joined_late].should be false
student[:waited_correctly].should be false
student[:initial_waiting_pct].should eql nil
student[:potential_waiting_time].should eql nil
together = analysis[:together_analysis]
together[:session_time].should eql 0
end
it "student joined 1 min before start time, is waiting for 12 minutes" do
lesson = testdrive_lesson(user, teacher)
music_session = lesson.music_session
# create some bogus, super-perfect teacher/student times
start = lesson.scheduled_start
end_time = lesson.scheduled_start + (60 * lesson.duration)
uh2 = FactoryGirl.create(:music_session_user_history, user: user, history: music_session, created_at: start - 60, session_removed_at: nil)
Timecop.freeze(start + 11 * 60)
analysis = LessonSessionAnalyser.analyse(lesson, true)
analysis[:reason].should eql LessonSessionAnalyser::TEACHER_FAULT
analysis[:teacher].should eql LessonSessionAnalyser::NO_SHOW
analysis[:student].should be_nil
analysis[:bill].should be false
student = analysis[:student_analysis]
student[:joined_on_time].should be true
student[:joined_late].should be false
student[:waited_correctly].should be true
student[:initial_waiting_pct].should eql 1.0
student[:potential_waiting_time].should eql 600.0
student[:session_time].should eql (11 * 60).to_f
together = analysis[:together_analysis]
together[:session_time].should eql 0
end
it "teacher joined on time, waited, student joined late" do
lesson = testdrive_lesson(user, teacher)
music_session = lesson.music_session
# create some bogus, super-perfect teacher/student times
start = lesson.scheduled_start
end_time = lesson.scheduled_start + (60 * lesson.duration)
late_start = start + (7 * 60)
uh1 = FactoryGirl.create(:music_session_user_history, user: user, history: music_session, created_at: late_start, session_removed_at: late_start + 4 * 60)
uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: music_session, created_at: start, session_removed_at: end_time)
Timecop.travel(end_time + 1)
analysis = LessonSessionAnalyser.analyse(lesson)
analysis[:reason].should eql LessonSessionAnalyser::STUDENT_FAULT
analysis[:student].should eql LessonSessionAnalyser::JOINED_LATE
analysis[:bill].should be true
student = analysis[:student_analysis]
student[:joined_on_time].should be false
student[:joined_late].should be true
student[:waited_correctly].should be false
student[:initial_waiting_pct].should eql nil
student[:potential_waiting_time].should eql nil
together = analysis[:together_analysis]
together[:session_time].should eql (4 * 60.to_f)
end
it "together 5 minutes" do
lesson = testdrive_lesson(user, teacher)
music_session = lesson.music_session
analysis = LessonSessionAnalyser.analyse(lesson)
analysis[:reason].should eql LessonSessionAnalyser::SESSION_ONGOING
# create some bogus, super-perfect teacher/student times
start = lesson.scheduled_start
end_time = lesson.scheduled_start + (60 * lesson.duration)
uh1 = FactoryGirl.create(:music_session_user_history, user: user, history: music_session, created_at: start, session_removed_at: end_time)
uh2 = FactoryGirl.create(:music_session_user_history, user: teacher, history: music_session, created_at: start, session_removed_at: end_time)
analysis = LessonSessionAnalyser.analyse(lesson)
analysis[:reason].should eql LessonSessionAnalyser::SESSION_ONGOING
Timecop.travel(end_time + 1)
analysis = LessonSessionAnalyser.analyse(lesson)
analysis[:reason].should eql LessonSessionAnalyser::SUCCESS
analysis[:bill].should be true
teacher = analysis[:teacher_analysis]
teacher[:joined_on_time].should be true
teacher[:waited_correctly].should be true
teacher[:initial_waiting_pct].should eql 1.0
teacher[:potential_waiting_time].should eql 600.0
together = analysis[:together_analysis]
together[:session_time].should eql 1800.0
end
end
describe "intersecting_ranges" do
let(:lesson) { testdrive_lesson(user, teacher) }
let(:music_session) { lesson.music_session }
it "empty" do
LessonSessionAnalyser.intersecting_ranges([], []).should eql []
end
it "one specified, other empty" do
uh1Begin = start
uh1End = start + 1
LessonSessionAnalyser.intersecting_ranges([], [Range.new(uh1Begin, uh1End)]).should eql []
LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], []).should eql []
end
it "both identical" do
uh1Begin = start
uh1End = start + 1
LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], [Range.new(uh1Begin, uh1End)]).should eql [Range.new(uh1Begin, uh1End)]
end
it "one intersect" do
uh1Begin = start
uh1End = start + 4
uh2Begin = start + 1
uh2End = start + 3
LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], [Range.new(uh2Begin, uh2End)]).should eql [Range.new(uh2Begin, uh2End)]
end
it "overlapping intersect" do
uh1Begin = start
uh1End = start + 4
uh2Begin = start + -1
uh2End = start + 2
uh3Begin = start + 3
uh3End = start + 5
LessonSessionAnalyser.intersecting_ranges([Range.new(uh2Begin, uh2End), Range.new(uh3Begin, uh3End)], [Range.new(uh1Begin, uh1End)]).should eql [Range.new(uh1Begin, uh2End), Range.new(uh3Begin, uh1End)]
end
it "no overlap" do
uh1Begin = start
uh1End = start + 4
uh2Begin = start + 5
uh2End = start + 6
LessonSessionAnalyser.intersecting_ranges([Range.new(uh1Begin, uh1End)], [Range.new(uh2Begin, uh2End)]).should eql []
end
end
describe "merge_overlapping_ranges" do
let(:lesson) { testdrive_lesson(user, teacher) }
let(:music_session) { lesson.music_session }
it "empty" do
LessonSessionAnalyser.merge_overlapping_ranges([]).should eql []
end
it "one item" do
uh1Begin = start
uh1End = start + 1
uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
ranges = LessonSessionAnalyser.time_ranges [uh1]
LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh1End)]
end
it "two identical items" do
uh1Begin = start
uh1End = start + 1
uh2Begin = uh1Begin
uh2End = uh1End
uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)
ranges = LessonSessionAnalyser.time_ranges [uh1, uh2]
LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh1End)]
end
it "two separate times" do
uh1Begin = start
uh1End = start + 1
uh2Begin = start + 3
uh2End = start + 5
uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)
ranges = LessonSessionAnalyser.time_ranges [uh1, uh2]
LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh1End), Range.new(uh2Begin, uh2End)]
end
it "two overlapping times" do
uh1Begin = start
uh1End = start + 1
uh2Begin = start + 0.5
uh2End = start + 5
uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)
ranges = LessonSessionAnalyser.time_ranges [uh1, uh2]
LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh2End)]
end
it "three overlapping times" do
uh1Begin = start
uh1End = start + 1
uh2Begin = start + 0.5
uh2End = start + 5
uh3Begin = start + 0.1
uh3End = start + 6
uh1 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh1Begin, session_removed_at: uh1End)
uh2 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh2Begin, session_removed_at: uh2End)
uh3 = FactoryGirl.build(:music_session_user_history, user: user, history: music_session, created_at: uh3Begin, session_removed_at: uh3End)
ranges = LessonSessionAnalyser.time_ranges [uh1, uh2, uh3]
LessonSessionAnalyser.merge_overlapping_ranges(ranges).should eql [Range.new(uh1Begin, uh3End)]
end
end
end
=end