diff --git a/ruby/lib/jam_ruby/resque/scheduled/daily_job.rb b/ruby/lib/jam_ruby/resque/scheduled/daily_job.rb index 8dd28d3b6..485baad04 100644 --- a/ruby/lib/jam_ruby/resque/scheduled/daily_job.rb +++ b/ruby/lib/jam_ruby/resque/scheduled/daily_job.rb @@ -17,7 +17,7 @@ module JamRuby end def self.bounced_emails - if Rails.application.config.check_bounced_emails + if APP_CONFIG.check_bounced_emails start = GenericState.bounce_check_at if start.nil? diff --git a/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb b/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb index 505f97d85..8dc2eb3e6 100644 --- a/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/monthly_recurring_lesson_spec.rb @@ -62,7 +62,7 @@ describe "Monthly Recurring Lesson Flow" do booking.status.should eql LessonBooking::STATUS_REQUESTED ######### Teacher counters with new slot - teacher_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 14) + teacher_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 14, update_all: true) UserMailer.deliveries.clear lesson_session.counter({proposer: teacher_user, slot: teacher_countered_slot, message: 'Does this work?'}) booking.reload @@ -85,10 +85,9 @@ describe "Monthly Recurring Lesson Flow" do notification.student_directed.should eql true notification.purpose.should eql 'counter' notification.description.should eql NotificationTypes::LESSON_MESSAGE - notification.message.should eql "Instructor has proposed a different time for your lesson." ######### Student counters with new slot - student_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 16) + student_countered_slot = FactoryGirl.build(:lesson_booking_slot_single, hour: 16, update_all: true) UserMailer.deliveries.clear lesson_session.counter({proposer: user, slot: student_countered_slot, message: 'Does this work better?'}) lesson_session.errors.any?.should be false @@ -109,7 +108,6 @@ describe "Monthly Recurring Lesson Flow" do notification.student_directed.should eql false notification.purpose.should eql 'counter' notification.description.should eql NotificationTypes::LESSON_MESSAGE - notification.message.should eql "Student has proposed a different time for your lesson." ######## Teacher accepts slot UserMailer.deliveries.clear @@ -118,7 +116,7 @@ describe "Monthly Recurring Lesson Flow" do # puts del.inspect end # get acceptance emails, as well as 'your stuff is accepted' - UserMailer.deliveries.length.should eql 4 + UserMailer.deliveries.length.should eql 6 lesson_session.errors.any?.should be_false lesson_session.reload lesson_session.slot.should eql student_counter @@ -128,9 +126,9 @@ describe "Monthly Recurring Lesson Flow" do lesson_session.music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0) booking.status.should eql LessonBooking::STATUS_APPROVED - UserMailer.deliveries.length.should eql 4 + UserMailer.deliveries.length.should eql 6 chat = ChatMessage.unscoped.order(:created_at).last - chat.message.should eql 'Yeah I got this' + chat.message.should eql "Lesson Approved: 'Yeah I got this'" chat.channel.should eql ChatMessage::CHANNEL_LESSON chat.user.should eql teacher_user chat.target_user.should eql user @@ -139,7 +137,24 @@ describe "Monthly Recurring Lesson Flow" do notification.student_directed.should eql true notification.purpose.should eql 'accept' notification.description.should eql NotificationTypes::LESSON_MESSAGE - notification.message.should eql "Your lesson request is confirmed!" + + + # teacher & student get into session + start = lesson_session.scheduled_start + end_time = lesson_session.scheduled_start + (60 * lesson_session.duration) + uh2 = FactoryGirl.create(:music_session_user_history, user: teacher_user, history: lesson_session.music_session, created_at: start, session_removed_at: end_time) + # artificially end the session, which is covered by other background jobs + lesson_session.music_session.session_removed_at = end_time + lesson_session.music_session.save! + LessonSession.hourly_check + lesson_session.reload + lesson_session.analysed.should be_true + analysis = JSON.parse(lesson_session.analysis) + analysis["reason"].should eql LessonSessionAnalyser::STUDENT_FAULT + analysis["student"].should eql LessonSessionAnalyser::NO_SHOW + if lesson_session.billing_error_detail + puts "monthly recurring lesson flow #{lesson_session.billing_error_detail}" # this should not occur, but helps a great deal if a regression occurs and running all the tests + end # let user pay for it LessonBooking.hourly_check diff --git a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb index 24b85c2ad..fa408e64d 100644 --- a/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb +++ b/ruby/spec/jam_ruby/flows/normal_lesson_spec.rb @@ -235,7 +235,7 @@ describe "Normal Lesson Flow" do UserMailer.deliveries.length.should eql 2 # one for student, one for teacher TeacherPayment.count.should eql 0 - TeacherPayment.daily_check + TeacherPayment.hourly_check TeacherPayment.count.should eql 1 teacher_distribution.reload teacher_distribution.distributed.should be_true diff --git a/ruby/spec/support/utilities.rb b/ruby/spec/support/utilities.rb index ecd19635b..21c037c4c 100644 --- a/ruby/spec/support/utilities.rb +++ b/ruby/spec/support/utilities.rb @@ -290,6 +290,9 @@ def app_config 1 end + def check_bounced_emails + false + end def stripe { :publishable_key => 'pk_test_HLTvioRAxN3hr5fNfrztZeoX', diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js index c9ae84cd4..2df970203 100644 --- a/web/app/assets/javascripts/jam_rest.js +++ b/web/app/assets/javascripts/jam_rest.js @@ -2358,7 +2358,7 @@ return $.ajax({ type: "DELETE", - url: "/api/schools/" + id + '/invitations', + url: "/api/schools/" + id + '/invitations/' + options.invitation_id, dataType: "json", contentType: 'application/json' }); @@ -2370,7 +2370,7 @@ return $.ajax({ type: "POST", - url: "/api/schools/" + id + '/resend', + url: "/api/schools/" + id + '/invitations/' + options.invitation_id + '/resend', dataType: "json", contentType: 'application/json', data: JSON.stringify(options) @@ -2383,7 +2383,7 @@ return $.ajax({ type: "DELETE", - url: "/api/schools/" + id + '/students/' + options.user_id, + url: "/api/schools/" + id + '/students/' + options.student_id, dataType: "json", contentType: 'application/json' }); diff --git a/web/app/assets/javascripts/react-components/AccountSchoolScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/AccountSchoolScreen.js.jsx.coffee index c91bd6389..6d43f38ea 100644 --- a/web/app/assets/javascripts/react-components/AccountSchoolScreen.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/AccountSchoolScreen.js.jsx.coffee @@ -162,13 +162,12 @@ profileUtils = context.JK.ProfileUtils @app.layout.showDialog('invite-school-user', {d1: false}) resendInvitation: (id, e) -> e.preventDefault() - rest.deleteSchoolInvitation({ - id: - id: this.state.school.id, invitation_id: id + rest.resendSchoolInvitation({ + id: this.state.school.id, invitation_id: id }).done((response) => @resendInvitationDone(response)).fail((jqXHR) => @resendInvitationFail(jqXHR)) resendInvitationDone: (response) -> - @app.layout.notify({title: 'invitation resent', text: 'invitation was resent to ' + response.email}) + @app.layout.notify({title: 'invitation resent', text: 'Invitation was resent to ' + response.email}) resendInvitationFail: (jqXHR) -> @app.ajaxError(jqXHR) @@ -176,8 +175,7 @@ profileUtils = context.JK.ProfileUtils deleteInvitation: (id, e) -> e.preventDefault() rest.deleteSchoolInvitation({ - id: - id: this.state.school.id, invitation_id: id + id: this.state.school.id, invitation_id: id }).done((response) => @deleteInvitationDone(id, response)).fail((jqXHR) => @deleteInvitationFail(jqXHR)) deleteInvitationDone: (id, response) -> @@ -191,7 +189,7 @@ profileUtils = context.JK.ProfileUtils if isTeacher rest.deleteSchoolTeacher({id: this.state.school.id, teacher_id: id}).done((response) => @removeFromSchoolDone(response)).fail((jqXHR) => @removeFromSchoolFail(jqXHR)) else - rest.deleteSchoolStudent({id: this.state.school.id, student: id}).done((response) => @removeFromSchoolDone(response)).fail((jqXHR) => @removeFromSchoolFail(jqXHR)) + rest.deleteSchoolStudent({id: this.state.school.id, student_id: id}).done((response) => @removeFromSchoolDone(response)).fail((jqXHR) => @removeFromSchoolFail(jqXHR)) removeFromSchoolDone: (school) -> context.JK.Banner.showNotice("User removed", "User was removed from your school.") diff --git a/web/app/assets/javascripts/react-components/stores/SchoolStore.js.coffee b/web/app/assets/javascripts/react-components/stores/SchoolStore.js.coffee index de701e2ee..fd5a1785f 100644 --- a/web/app/assets/javascripts/react-components/stores/SchoolStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/SchoolStore.js.coffee @@ -46,10 +46,10 @@ rest = new context.JK.Rest() onDeleteInvitation: (id) -> if @studentInvitations? - @studentInvitations = @studentInvitations.filter(invitation) -> invitation.id isnt id + @studentInvitations = @studentInvitations.filter (invitation) -> invitation.id isnt id if @teacherInvitations? - @teacherInvitations.filter(invitation) -> invitation.id isnt id + @teacherInvitations = @teacherInvitations.filter (invitation) -> invitation.id isnt id @changed() diff --git a/web/app/assets/stylesheets/client/react-components/AccountSchoolScreen.css.scss b/web/app/assets/stylesheets/client/react-components/AccountSchoolScreen.css.scss index ebc4e0018..3e69ca14c 100644 --- a/web/app/assets/stylesheets/client/react-components/AccountSchoolScreen.css.scss +++ b/web/app/assets/stylesheets/client/react-components/AccountSchoolScreen.css.scss @@ -205,7 +205,7 @@ font-size:12px; min-height:40px; p { - font-size:14px; + font-size:12px; } } .teachers, .students { @@ -215,6 +215,9 @@ font-size:12px; margin-left:0; } + .school-invitation { + margin-bottom:20px; + } } .school-user { margin-bottom:20px; diff --git a/web/app/controllers/api_schools_controller.rb b/web/app/controllers/api_schools_controller.rb index dd32b9b9c..ace715949 100644 --- a/web/app/controllers/api_schools_controller.rb +++ b/web/app/controllers/api_schools_controller.rb @@ -72,7 +72,7 @@ class ApiSchoolsController < ApiController def remove_student user = User.find(params[:user_id]) - user.school_id = null + user.school_id = nil if !user.save respond_with user, status: :unprocessable_entity return @@ -80,10 +80,10 @@ class ApiSchoolsController < ApiController end def remove_teacher - teacher = Teacher.find(params[:teacher_id]) - teacher.school_id = null - if !teacher.save - respond_with teacher, status: :unprocessable_entity + teacher = User.find(params[:teacher_id]) + teacher.teacher.school_id = nil + if !teacher.teacher.save + respond_with teacher.teacher, status: :unprocessable_entity return end end diff --git a/web/config/routes.rb b/web/config/routes.rb index f1d874ee1..1b82d962b 100644 --- a/web/config/routes.rb +++ b/web/config/routes.rb @@ -702,7 +702,7 @@ SampleApp::Application.routes.draw do match '/schools/:id/filepicker_policy' => 'api_schools#generate_filepicker_policy', :via => :get match '/schools/:id/invitations' => 'api_school_invitations#index', :via => :get match '/schools/:id/invitations' => 'api_school_invitations#create', :via => :post - match '/schools/:id/invitations/:invitation_id' => 'api_school_invitations#resend', :via => :post + match '/schools/:id/invitations/:invitation_id/resend' => 'api_school_invitations#resend', :via => :post match '/schools/:id/invitations/:invitation_id' => 'api_school_invitations#delete', :via => :delete match '/schools/:id/students/:user_id' => 'api_schools#remove_student', :via => :delete match '/schools/:id/teachers/:teacher_id' => 'api_schools#remove_teacher', :via => :delete