diff --git a/db/manifest b/db/manifest
index f9df5d1fe..6de316f20 100755
--- a/db/manifest
+++ b/db/manifest
@@ -343,4 +343,5 @@ teacher_progression.sql
teacher_complete.sql
lessons.sql
lessons_unread_messages.sql
-track_school_signups.sql
\ No newline at end of file
+track_school_signups.sql
+add_test_drive_types.sql
\ No newline at end of file
diff --git a/db/up/add_test_drive_types.sql b/db/up/add_test_drive_types.sql
new file mode 100644
index 000000000..01584db3d
--- /dev/null
+++ b/db/up/add_test_drive_types.sql
@@ -0,0 +1,4 @@
+INSERT INTO lesson_package_types (id, name, description, package_type, price) VALUES ('test-drive-2', 'Test Drive (2)', 'Two reduced-price lessons which you can use to find that ideal teacher.', 'test-drive-2', 29.99);
+INSERT INTO lesson_package_types (id, name, description, package_type, price) VALUES ('test-drive-1', 'Test Drive (1)', 'One reduced-price lessons which you can use to find that ideal teacher.', 'test-drive-1', 15.99);
+UPDATE lesson_package_types set name = 'Test Drive (4)', package_type = 'test-drive-4' WHERE id = 'test-drive';
+ALTER TABLE users ADD COLUMN lesson_package_type_id VARCHAR(64) REFERENCES lesson_package_types(id);
\ No newline at end of file
diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_welcome_message.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_welcome_message.text.erb
index aa851747f..0cff2ed3e 100644
--- a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_welcome_message.text.erb
+++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/student_welcome_message.text.erb
@@ -18,7 +18,7 @@ TestDrive lets you take 4 full lessons (30 minutes each) from 4 different teache
teacher for you. Finding the right teacher is the single most important determinant of success in your lessons. Would
you marry the first person you ever dated? No? Same here. Pick 4 teachers who look great, and then see who you click
with. It's a phenomenal value, and then you can stick with the best teacher for you.
-Click this link to sign up now for TestDrive (https://www.jamkazam.com/client#/jamclass/book-lesson/purchase_test-drive).
+Click this link to sign up now for TestDrive (https://www.jamkazam.com/client#/jamclass/test-drive-selection).
Then you can book 4 TestDrive lessons to get rolling.
2. Set Up Your Gear
diff --git a/ruby/lib/jam_ruby/models/lesson_booking.rb b/ruby/lib/jam_ruby/models/lesson_booking.rb
index b42d72be9..206bacb6a 100644
--- a/ruby/lib/jam_ruby/models/lesson_booking.rb
+++ b/ruby/lib/jam_ruby/models/lesson_booking.rb
@@ -410,11 +410,26 @@ module JamRuby
self.save
end
+ def resolved_test_drive_package
+ result = nil
+ purchase = student.most_recent_test_drive_purchase
+ if purchase
+ # for lessons already packaged
+ result = purchase.lesson_package_type
+ else
+ # for unbooked lessons
+ result = student.desired_package
+ end
+ if result.nil?
+ result = LessonPackageType.test_drive_4
+ end
+ result
+ end
def lesson_package_type
if is_single_free?
LessonPackageType.single_free
elsif is_test_drive?
- LessonPackageType.test_drive
+ resolved_test_drive_package
elsif is_normal?
LessonPackageType.single
end
@@ -451,7 +466,7 @@ module JamRuby
if is_single_free?
0
elsif is_test_drive?
- LessonPackageType.test_drive.price
+ resolved_test_drive_package.price
elsif is_normal?
teacher.teacher.booking_price(lesson_length, payment_style != PAYMENT_STYLE_MONTHLY)
end
diff --git a/ruby/lib/jam_ruby/models/lesson_package_purchase.rb b/ruby/lib/jam_ruby/models/lesson_package_purchase.rb
index 7662a2632..33e28f395 100644
--- a/ruby/lib/jam_ruby/models/lesson_package_purchase.rb
+++ b/ruby/lib/jam_ruby/models/lesson_package_purchase.rb
@@ -26,7 +26,7 @@ module JamRuby
def validate_test_drive
if user
- if !user.can_buy_test_drive?
+ if lesson_package_type.is_test_drive? && !user.can_buy_test_drive?
errors.add(:user, "can not buy test drive right now because you have already purchased it within the last year")
end
end
@@ -42,7 +42,7 @@ module JamRuby
def add_test_drives
if self.lesson_package_type.is_test_drive?
- new_test_drives = user.remaining_test_drives + 4
+ new_test_drives = user.remaining_test_drives + lesson_package_type.test_drive_count
User.where(id: user.id).update_all(remaining_test_drives: new_test_drives)
user.remaining_test_drives = new_test_drives
end
@@ -79,7 +79,7 @@ module JamRuby
end
if lesson_booking
- purchase.lesson_package_type = lesson_booking.lesson_package_type
+ purchase.lesson_package_type = lesson_package_type ? lesson_package_type : lesson_booking.lesson_package_type
purchase.price = lesson_booking.booked_price if purchase.price.nil?
else
purchase.lesson_package_type = lesson_package_type
diff --git a/ruby/lib/jam_ruby/models/lesson_package_type.rb b/ruby/lib/jam_ruby/models/lesson_package_type.rb
index d60aaa14a..d151e1355 100644
--- a/ruby/lib/jam_ruby/models/lesson_package_type.rb
+++ b/ruby/lib/jam_ruby/models/lesson_package_type.rb
@@ -7,21 +7,29 @@ module JamRuby
PRODUCT_TYPE = 'LessonPackageType'
SINGLE_FREE = 'single-free'
- TEST_DRIVE = 'test-drive'
+ TEST_DRIVE_4 = 'test-drive'
+ TEST_DRIVE_2 = 'test-drive-2'
+ TEST_DRIVE_1 = 'test-drive-1'
SINGLE = 'single'
LESSON_PACKAGE_TYPES =
[
SINGLE_FREE,
- TEST_DRIVE,
+ TEST_DRIVE_4,
+ TEST_DRIVE_2,
+ TEST_DRIVE_1,
SINGLE
]
+ has_many :user_desired_packages, class_name: "JamRuby::User", :foreign_key => "lesson_package_type_id", inverse_of: :desired_package
validates :name, presence: true
validates :description, presence: true
validates :price, presence: true
validates :package_type, presence: true, inclusion: {in: LESSON_PACKAGE_TYPES}
+ def self.test_drive_package_ids
+ [TEST_DRIVE_4, TEST_DRIVE_2, TEST_DRIVE_1]
+ end
def self.monthly
LessonPackageType.find(MONTHLY)
end
@@ -30,8 +38,16 @@ module JamRuby
LessonPackageType.find(SINGLE_FREE)
end
- def self.test_drive
- LessonPackageType.find(TEST_DRIVE)
+ def self.test_drive_4
+ LessonPackageType.find(TEST_DRIVE_4)
+ end
+
+ def self.test_drive_2
+ LessonPackageType.find(TEST_DRIVE_2)
+ end
+
+ def self.test_drive_1
+ LessonPackageType.find(TEST_DRIVE_1)
end
def self.single
@@ -42,17 +58,21 @@ module JamRuby
if is_single_free?
0
elsif is_test_drive?
- LessonPackageType.test_drive.price
+ 10.00
elsif is_normal?
lesson_booking.booked_price #teacher.teacher.booking_price(lesson_booking.lesson_length, lesson_booking.payment_style == LessonBooking::PAYMENT_STYLE_SINGLE)
end
end
+ def test_drive_count
+ package_type["test-drive-".length, 1].to_i
+ end
+
def description(lesson_booking)
if is_single_free?
"Single Free Lesson"
elsif is_test_drive?
- "Test Drive"
+ "Test Drive (#{test_drive_count})"
elsif is_normal?
if lesson_booking.recurring
"Recurring #{lesson_booking.payment_style == LessonBooking::PAYMENT_STYLE_WEEKLY ? "Weekly" : "Monthly"} #{lesson_booking.lesson_length}m"
@@ -71,7 +91,7 @@ module JamRuby
end
def is_test_drive?
- id == TEST_DRIVE
+ id.start_with?('test-drive')
end
def is_normal?
@@ -86,8 +106,12 @@ module JamRuby
def plan_code
if package_type == SINGLE_FREE
"lesson-package-single-free"
- elsif package_type == TEST_DRIVE
- "lesson-package-test-drive"
+ elsif package_type == 'test-drive-4'
+ "lesson-package-test-drive-4"
+ elsif package_type == TEST_DRIVE_2
+ "lesson-package-test-drive-2"
+ elsif package_type == TEST_DRIVE_1
+ "lesson-package-test-drive-1"
elsif package_type == SINGLE
"lesson-package-single"
else
diff --git a/ruby/lib/jam_ruby/models/sale.rb b/ruby/lib/jam_ruby/models/sale.rb
index 5cbd4f9d7..d3827ed84 100644
--- a/ruby/lib/jam_ruby/models/sale.rb
+++ b/ruby/lib/jam_ruby/models/sale.rb
@@ -208,8 +208,8 @@ module JamRuby
free && non_free
end
- def self.purchase_test_drive(current_user, booking = nil)
- self.purchase_lesson(current_user, booking, LessonPackageType.test_drive)
+ def self.purchase_test_drive(current_user, lesson_package_type, booking = nil)
+ self.purchase_lesson(current_user, booking, lesson_package_type)
end
def self.purchase_normal(current_user, booking)
@@ -273,6 +273,7 @@ module JamRuby
purchase = LessonPackagePurchase.create(current_user, lesson_booking, lesson_package_type) if purchase.nil?
if purchase.errors.any?
+ puts "purchase errors #{purchase.errors.inspect}"
price_info = {}
price_info[:purchase] = purchase
return price_info
diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb
index 849828f8f..08c985e9c 100644
--- a/ruby/lib/jam_ruby/models/user.rb
+++ b/ruby/lib/jam_ruby/models/user.rb
@@ -51,7 +51,7 @@ module JamRuby
has_many :user_authorizations, :class_name => "JamRuby::UserAuthorization"
has_many :reviews, :class_name => "JamRuby::Review"
- has_one :review_summary, :class_name => "JamRuby::ReviewSummary"
+ has_one :review_summary, :class_name => "JamRuby::ReviewSummary"
# calendars (for scheduling NOT in music_session)
has_many :calendars, :class_name => "JamRuby::Calendar"
@@ -71,7 +71,7 @@ module JamRuby
has_many :band_musicians, :class_name => "JamRuby::BandMusician"
has_many :bands, :through => :band_musicians, :class_name => "JamRuby::Band"
has_one :teacher, :class_name => "JamRuby::Teacher"
-
+
# genres
has_many :genre_players, as: :player, class_name: "JamRuby::GenrePlayer", dependent: :destroy
has_many :genres, through: :genre_players, class_name: "JamRuby::Genre"
@@ -176,6 +176,7 @@ module JamRuby
has_many :teacher_lesson_bookings, :class_name => "JamRuby::LessonBooking", :foreign_key => "teacher_id", inverse_of: :teacher
has_many :teacher_distributions, :class_name => "JamRuby::TeacherDistribution", :foreign_key => "teacher_id", inverse_of: :teacher
has_many :teacher_payments, :class_name => "JamRuby::TeacherPayment", :foreign_key => "teacher_id", inverse_of: :teacher
+ belongs_to :desired_package, :class_name => "JamRuby::LessonPackageType", :foreign_key => "lesson_package_type_id", inverse_of: :user_desired_packages # used to hold whether user last wanted test drive 4/2/1
# Shopping carts
has_many :shopping_carts, :class_name => "JamRuby::ShoppingCart"
@@ -260,6 +261,7 @@ module JamRuby
teacher.update_profile_pct
end
end
+
def user_progression_fields
@user_progression_fields ||= Set.new ["first_downloaded_client_at", "first_ran_client_at", "first_music_session_at", "first_real_music_session_at", "first_good_music_session_at", "first_certified_gear_at", "first_invited_at", "first_friended_at", "first_recording_at", "first_social_promoted_at", "first_played_jamtrack_at"]
end
@@ -1127,7 +1129,7 @@ module JamRuby
user.school_id = school_id
elsif user.is_a_teacher
school = School.find_by_id(school_id)
- school_name = school ? school.name : 'a music school'
+ school_name = school ? school.name : 'a music school'
user.teacher = Teacher.build_teacher(user, validate_introduction: true, biography: "Teaches for #{school_name}", school_id: school_id)
end
else
@@ -1320,7 +1322,6 @@ module JamRuby
end if affiliate_referral_id.present?
-
if user.is_a_student
UserMailer.student_welcome_message(user).deliver
end
@@ -1897,7 +1898,7 @@ module JamRuby
end
def can_buy_test_drive?
- lesson_purchases.where(lesson_package_type_id: LessonPackageType.test_drive.id).where('created_at > ?', APP_CONFIG.test_drive_wait_period_year.years.ago).count == 0
+ lesson_purchases.where('lesson_package_type_id in (?)', LessonPackageType.test_drive_package_ids).where('created_at > ?', APP_CONFIG.test_drive_wait_period_year.years.ago).count == 0
end
def has_test_drives?
@@ -1946,6 +1947,7 @@ module JamRuby
customer
end
+
def card_approved(token, zip, booking_id)
approved_booking = nil
@@ -1993,6 +1995,7 @@ module JamRuby
normal = nil
intent = nil
purchase = nil
+ lesson_package_type = nil
User.transaction do
if params[:name].present?
@@ -2004,16 +2007,29 @@ module JamRuby
booking = card_approved(params[:token], params[:zip], params[:booking_id])
if params[:test_drive]
self.reload
- result = Sale.purchase_test_drive(self, booking)
+ if booking
+ lesson_package_type = booking.resolved_test_drive_package
+ end
+ if lesson_package_type.nil?
+ lesson_package_type = LessonPackageType.test_drive_4
+ end
+
+
+ result = Sale.purchase_test_drive(self, lesson_package_type, booking)
test_drive = result[:sale]
purchase = result[:purchase]
+
+ if booking && !purchase.errors.any?
+ # the booking would not have a lesson_package_purchase associated yet, so let's associate it
+ booking.lesson_sessions.update_all(lesson_package_purchase_id: purchase.id)
+ end
elsif params[:normal]
self.reload
end
end
- {lesson: booking, test_drive: test_drive, purchase: purchase}
+ {lesson: booking, test_drive: test_drive, purchase: purchase, lesson_package_type: lesson_package_type}
end
def requested_test_drive(teacher = nil)
@@ -2033,7 +2049,7 @@ module JamRuby
end
def most_recent_test_drive_purchase
- lesson_purchases.where(lesson_package_type_id: LessonPackageType.test_drive.id).order('created_at desc').first
+ lesson_purchases.where('lesson_package_type_id in (?)', [LessonPackageType.test_drive_package_ids]).order('created_at desc').first
end
def test_drive_succeeded(lesson_session)
diff --git a/ruby/spec/factories.rb b/ruby/spec/factories.rb
index 73c0a9fad..636414916 100644
--- a/ruby/spec/factories.rb
+++ b/ruby/spec/factories.rb
@@ -980,7 +980,7 @@ FactoryGirl.define do
price 30.00
factory :test_drive_purchase do
- lesson_package_type { JamRuby::LessonPackageType.test_drive }
+ lesson_package_type { JamRuby::LessonPackageType.test_drive_4 }
association :lesson_booking, factory: :lesson_booking
price 49.99
end
diff --git a/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb b/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb
index 2fca45714..6bc88f745 100644
--- a/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb
+++ b/ruby/spec/jam_ruby/flows/testdrive_lesson_spec.rb
@@ -20,6 +20,9 @@ describe "TestDrive Lesson Flow" do
it "works" do
+ user.desired_package = LessonPackageType.test_drive_2
+ user.save!
+
# user has no test drives, no credit card on file, but attempts to book a lesson
booking = LessonBooking.book_test_drive(user, teacher_user, valid_single_slots, "Hey I've heard of you before.")
booking.errors.any?.should be_false
@@ -28,20 +31,24 @@ describe "TestDrive Lesson Flow" do
booking.card_presumed_ok.should be_false
booking.should eql user.unprocessed_test_drive
booking.sent_notices.should be_false
+
user.reload
user.remaining_test_drives.should eql 0
########## Need validate their credit card
token = create_stripe_token
- result = user.payment_update({token: token, zip: '78759', test_drive: true})
- user.reload
- user.remaining_test_drives.should eql 3
+ result = user.payment_update({token: token, zip: '78759', test_drive: true, booking_id: booking.id})
booking = result[:lesson]
- lesson = booking.lesson_sessions[0]
- test_drive = result[:test_drive]
booking.errors.any?.should be_false
+ lesson = booking.lesson_sessions[0]
+
lesson.errors.any?.should be_false
+ test_drive = result[:test_drive]
test_drive.errors.any?.should be_false
+
+ user.reload
+ user.remaining_test_drives.should eql 1
+
booking.card_presumed_ok.should be_true
booking.sent_notices.should be_true
lesson.music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
@@ -49,20 +56,20 @@ describe "TestDrive Lesson Flow" do
test_drive.stripe_charge_id.should_not be_nil
- test_drive.recurly_tax_in_cents.should be 412
- test_drive.recurly_total_in_cents.should eql 4999 + 412
- test_drive.recurly_subtotal_in_cents.should eql 4999
+ test_drive.recurly_tax_in_cents.should be 247
+ test_drive.recurly_total_in_cents.should eql 2999 + 247
+ test_drive.recurly_subtotal_in_cents.should eql 2999
test_drive.recurly_currency.should eql 'USD'
line_item = test_drive.sale_line_items[0]
line_item.quantity.should eql 1
line_item.product_type.should eql SaleLineItem::LESSON
- line_item.product_id.should eq LessonPackageType.test_drive.id
+ line_item.product_id.should eq LessonPackageType.test_drive_2.id
user.reload
user.stripe_customer_id.should_not be nil
user.lesson_purchases.length.should eql 1
- user.remaining_test_drives.should eql 3
+ user.remaining_test_drives.should eql 1
lesson_purchase = user.lesson_purchases[0]
- lesson_purchase.price.should eql 49.99
+ lesson_purchase.price.should eql 29.99
lesson_purchase.lesson_package_type.is_test_drive?.should eql true
customer = Stripe::Customer.retrieve(user.stripe_customer_id)
@@ -173,11 +180,11 @@ describe "TestDrive Lesson Flow" do
lesson_session.billing_error_reason.should be_nil
lesson_session.sent_notices.should be true
purchase = lesson_session.lesson_package_purchase
- purchase.should_not be nil
- purchase.price_in_cents.should eql 4999
+ purchase.should_not be_nil
+ purchase.price_in_cents.should eql 2999
purchase.lesson_package_type.is_test_drive?.should be true
user.reload
- user.remaining_test_drives.should eql 3
+ user.remaining_test_drives.should eql 1
UserMailer.deliveries.length.should eql 2 # one for student, one for teacher
teacher_distribution = lesson_session.teacher_distribution
diff --git a/ruby/spec/jam_ruby/models/sale_spec.rb b/ruby/spec/jam_ruby/models/sale_spec.rb
index bc278b7e2..c00c8f5f6 100644
--- a/ruby/spec/jam_ruby/models/sale_spec.rb
+++ b/ruby/spec/jam_ruby/models/sale_spec.rb
@@ -731,7 +731,7 @@ describe Sale do
line_item = sale.sale_line_items[0]
line_item.quantity.should eql 1
line_item.product_type.should eql SaleLineItem::LESSON
- line_item.product_id.should eq LessonPackageType.test_drive.id
+ line_item.product_id.should eq LessonPackageType.test_drive_4.id
user.reload
user.stripe_customer_id.should_not be nil
@@ -778,7 +778,7 @@ describe Sale do
line_item = sale.sale_line_items[0]
line_item.quantity.should eql 1
line_item.product_type.should eql SaleLineItem::LESSON
- line_item.product_id.should eq LessonPackageType.test_drive.id
+ line_item.product_id.should eq LessonPackageType.test_drive_4.id
user.reload
@@ -819,7 +819,7 @@ describe Sale do
line_item = sale.sale_line_items[0]
line_item.quantity.should eql 1
line_item.product_type.should eql SaleLineItem::LESSON
- line_item.product_id.should eq LessonPackageType.test_drive.id
+ line_item.product_id.should eq LessonPackageType.test_drive_4.id
end
it "will reject second test drive purchase" do
diff --git a/ruby/spec/support/lesson_session.rb b/ruby/spec/support/lesson_session.rb
index 401dad8f4..1e13a3e15 100644
--- a/ruby/spec/support/lesson_session.rb
+++ b/ruby/spec/support/lesson_session.rb
@@ -33,7 +33,7 @@ def testdrive_lesson(user, teacher, slots = nil)
booking.card_presumed_ok.should be_true
if user.most_recent_test_drive_purchase.nil?
- LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive)
+ LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4)
end
lesson.accept({message: 'Yeah I got this', slot: slots[0]})
@@ -66,7 +66,7 @@ def normal_lesson(user, teacher, slots = nil)
booking.card_presumed_ok.should be_true
#if user.most_recent_test_drive_purchase.nil?
- # LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive)
+ # LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4)
#end
lesson.accept({message: 'Yeah I got this', slot: slots[0]})
diff --git a/web/app/assets/javascripts/helpBubbleHelper.js b/web/app/assets/javascripts/helpBubbleHelper.js
index 11de7b8cb..9c61d67eb 100644
--- a/web/app/assets/javascripts/helpBubbleHelper.js
+++ b/web/app/assets/javascripts/helpBubbleHelper.js
@@ -161,21 +161,37 @@
return context.JK.prodBubble($element, 'teacher-profile', {}, bigHelpDarkOptions({spikeGirth:0, spikeLength: 0, duration:10000, offsetParent:$offsetParent, width:385, positions:['top', 'right', 'bottom']}))
}
- helpBubble.showUseRemainingTestDrives = function($element, $offsetParent) {
- return context.JK.onceBubble($element, 'side-remaining-test-drives', {}, {offsetParent:$offsetParent, width:260, positions:['right'], postShow: function(container) {
+ helpBubble.showUseRemainingTestDrives = function($element, $offsetParent, user, callback) {
+ return context.JK.onceBubble($element, 'side-remaining-test-drives', user, {offsetParent:$offsetParent, width:260, positions:['right'], postShow: function(container) {
+ var $bookNow = $('a.book-now')
+ $bookNow.off('click').on('click', function(e) {
+ e.preventDefault()
+ callback()
+ return false;
+ })
}})
}
- helpBubble.showBuyTestDrive = function($element, $offsetParent) {
- return context.JK.onceBubble($element, 'side-buy-test-drive', {}, {offsetParent:$offsetParent, width:260, positions:['right'], postShow: function(container) {
-
+ helpBubble.showBuyTestDrive = function($element, $offsetParent, user, callback) {
+ return context.JK.onceBubble($element, 'side-buy-test-drive', user, {offsetParent:$offsetParent, width:260, positions:['right'], postShow: function(container) {
+ var $bookNow = $('a.book-now')
+ $bookNow.off('click').on('click', function(e) {
+ e.preventDefault()
+ callback()
+ return false;
+ })
}})
}
- helpBubble.showBuyNormalLesson = function($element, $offsetParent) {
- return context.JK.onceBubble($element, 'side-buy-normal-lesson', {}, {offsetParent:$offsetParent, width:260, positions:['right'], postShow: function(container) {
-
+ helpBubble.showBuyNormalLesson = function($element, $offsetParent, user, callback) {
+ return context.JK.onceBubble($element, 'side-buy-normal-lesson', user, {offsetParent:$offsetParent, width:260, positions:['right'], postShow: function(container) {
+ var $bookNow = $('a.book-now')
+ $bookNow.off('click').on('click', function(e) {
+ e.preventDefault()
+ callback()
+ return false;
+ })
}})
}
})(window, jQuery);
\ No newline at end of file
diff --git a/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee b/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee
index b92db6176..e16c0126d 100644
--- a/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/BookLesson.js.jsx.coffee
@@ -62,7 +62,7 @@ UserStore = context.UserStore
@state.type == 'normal'
isTestDrive: () ->
- @state.type == 'test-drive'
+ @state.type?.indexOf('test-drive') == 0
parseId:(id) ->
if !id?
@@ -79,7 +79,6 @@ UserStore = context.UserStore
@resetErrors()
beforeShow: (e) ->
- logger.debug("BookLesson: beforeShow", e.id)
afterShow: (e) ->
logger.debug("BookLesson: afterShow", e.id)
@@ -268,9 +267,6 @@ UserStore = context.UserStore
onCancel: (e) ->
e.preventDefault()
- isTestDrive: () ->
- @state.type == 'test-drive'
-
isNormal: () ->
@state.type == 'normal'
@@ -314,11 +310,12 @@ UserStore = context.UserStore
results
render: () ->
+ teacher = @state.teacher
+
photo_url = teacher?.photo_url
if !photo_url?
photo_url = '/assets/shared/avatar_generic.png'
- teacher = @state.teacher
if teacher?
name = `
{teacher.name}
`
@@ -446,6 +443,39 @@ UserStore = context.UserStore
BOOK TESTDRIVE LESSON
`
+ testDriveCredits = 1
+
+ if this.state.user.lesson_package_type_id == 'test-drive'
+ testDriveCredits = 4
+ else if this.state.user.lesson_package_type_id == 'test-drive-1'
+ testDriveCredits = 1
+ else if this.state.user.lesson_package_type_id == 'test-drive-2'
+ testDriveCredits = 2
+
+ if this.state.user.remaining_test_drives > 0
+ testDriveBookingInfo = `
+
+
You are booking a single 30-minute TestDrive session.
+
+
You currently have {testDriveLessons} available. If you need to cancel, you must cancel at least 24 hours before the lesson is scheduled to start, or you will be charged 1 TestDrive lesson credit.
+
+
+
+
`
+ else
+ testDriveBookingInfo = `
+
+
You are booking a single 30-minute TestDrive session.
+
+
Once payment is entered on the next screen, the teacher will be notified, and this lesson will then use 1 of {testDriveCredits} TestDrive credits. If you need to cancel, you must cancel at least 24 hours before the lesson is scheduled to start, or you will be charged 1 TestDrive lesson credit.
+
+
+
+
`
+
+
columnLeft = `
{header}
{slots}
@@ -468,15 +498,7 @@ UserStore = context.UserStore
{name}
-
-
You are purchasing a single 30-minute TestDrive session.
-
-
You currently have {testDriveLessons} available. If you need to cancel, you must cancel at least 24 hours before the lesson is scheduled to start, or you will be charged 1 TestDrive lesson credit.
-
-
-
-
+ {testDriveBookingInfo}
`
else if @isNormal()
diff --git a/web/app/assets/javascripts/react-components/LessonPayment.js.jsx.coffee b/web/app/assets/javascripts/react-components/LessonPayment.js.jsx.coffee
index 590d151c5..00369f633 100644
--- a/web/app/assets/javascripts/react-components/LessonPayment.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/LessonPayment.js.jsx.coffee
@@ -272,29 +272,58 @@ UserStore = context.UserStore
window.UserActions.refresh()
# if the response has a lesson, take them there
- if response.lesson?.id?
+ if response.test_drive?
+ # ok, they bought a package
+ if response.lesson_package_type?
+ # always of form test-drive-#
+ prefixLength = "test-drive-".length
+ packageLength = response.lesson_package_type.package_type.length
+
+ logger.debug("prefix: " + prefixLength.toString())
+ logger.debug("package: " + packageLength.toString())
+ testDriveCount = response.lesson_package_type.package_type.substring(prefixLength, packageLength)
+
+ logger.debug("testDriveCount: " + testDriveCount)
+
+ if response.test_drive?.teacher_id
+ teacher_id = response.test_drive.teacher_id
+ if testDriveCount == 1
+ text = "You have purchased a TestDrive credit and have used it to request a JamClass with #{@state.teacher.name}. The teacher has received your request and should respond shortly."
+ else
+ text = "You have purchased #{testDriveCount} TestDrive credits and have used 1 credit it to request a JamClass with #{@state.teacher.name}. The teacher has received your request and should respond shortly."
+ location = "/client#/jamclass"
+ else
+ if @state.teacher?.id
+
+ # the user bought the testdrive, and there is a teacher of interest in context (but no booking)
+ if testDriveCount == 1
+ text = "You now have 1 TestDrive credit. We've taken you to the lesson booking screen for the teacher you initially showed interest in."
+ location = "/client#/jamclass/book-lesson/test-drive_" + teacher_id
+ else
+ text = "You now have #{testDriveCount} TestDrive credits that you can take with #{testDriveCount} different teachers. We've taken you to the lesson booking screen for the teacher you initially showed interest in."
+ location = "/client#/jamclass/book-lesson/test-drive_" + teacher_id
+ else
+ # the user bought test drive, but 'cold' , i.e., no teacher in context
+ if testDriveCount == 1
+ text = "You now have 1 TestDrive credit. We've taken you to the Teacher Search screen, so you can search for teachers right for you."
+ location = "/client#/teachers/search"
+ else
+ text = "You now have #{testDriveCount} TestDrive credits that you can take with #{testDriveCount} different teachers. We've taken you to the Teacher Search screen, so you can search for teachers right for you."
+ location = "/client#/teachers/search"
+
+ context.JK.Banner.showNotice("Test Drive Purchased",text)
+ window.location = location
+ else
+ context.JK.Banner.showNotice("Something Went Wrong", "Please email support@jamkazam.com and indicate that your attempt to buy a TestDrive failed")
+ window.location = "/client#/jamclass/"
+
+ else if response.lesson?.id?
context.JK.Banner.showNotice("Lesson Requested","The teacher has been notified of your lesson request, and should respond soon. We've taken you automatically to the page for this request, and sent an email to you with a link here as well. All communication with the teacher will show up on this page and in email.")
url = "/client#/jamclass/lesson-booking/" + response.lesson.id
url = "/client#/jamclass"
window.location.href = url
- else if response.test_drive?
-
- if response.test_drive?.teacher_id
- teacher_id = response.test_drive.teacher_id
- else if @state.teacher?.id
- teacher_id = @state.teacher.id
-
- if teacher_id?
- text = "You now have 4 lessons that you can take with 4 different teachers. We've taken you automatically to the lesson booking screen for the teacher you initially showed interest in."
- location = "/client#/profile/teacher/" + teacher_id
- location = "/client#/jamclass/book-lesson/test-drive_" + teacher_id
- else
- text = "You now have 4 lessons that you can take with 4 different teachers. We've taken you automatically to the Teacher Search screen, so you can search for teachers right for you."
- location = "/client#/teachers/search"
- context.JK.Banner.showNotice("Test Drive Purchased",text)
- window.location = location
else
window.location = "/client#/teachers/search"
diff --git a/web/app/assets/javascripts/react-components/TeacherProfile.js.jsx.coffee b/web/app/assets/javascripts/react-components/TeacherProfile.js.jsx.coffee
index 4eaf73839..bed688d7b 100644
--- a/web/app/assets/javascripts/react-components/TeacherProfile.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/TeacherProfile.js.jsx.coffee
@@ -27,6 +27,7 @@ proficiencyDescriptionMap = {
@TeacherProfile = React.createClass({
mixins: [
+ PostProcessorMixin,
Reflux.listenTo(AppStore, "onAppInit"),
Reflux.listenTo(UserStore, "onUserChanged"),
Reflux.listenTo(SubjectStore, "onSubjectsChanged"),
@@ -89,12 +90,18 @@ proficiencyDescriptionMap = {
userDetailDone: (response) ->
if response.id == @state.userId
+ console.log("teacher markup", response)
+ @postProcessUser(response)
@setState({user: response, isSelf: response.id == context.JK.currentUserId})
else
logger.debug("ignoring userDetailDone", response.id, @state.userId)
- if @visible
- @showSideBubble()
+ @showSideBubbleWhenReady()
+
+ showSideBubbleWhenReady: () ->
+ if @user? && @state.user?
+ if @visible
+ @showSideBubble()
beforeHide: (e) ->
@visible = false
@@ -130,18 +137,22 @@ proficiencyDescriptionMap = {
@screen.btOff()
showUseRemainingTestDrivesBubble: ( ) ->
- console.log("Ok showUseRemainingTestDrivesBubble")
- context.JK.HelpBubbleHelper.showUseRemainingTestDrives(@screen, @screen)
+ context.JK.HelpBubbleHelper.showUseRemainingTestDrives(@screen, @screen, @user, (() => @useRemainingTestDrives()))
showBuyTestDriveBubble: () ->
- console.log("ok showBuyTestDriveBubble")
- context.JK.HelpBubbleHelper.showBuyTestDrive(@screen, @screen)
+ context.JK.HelpBubbleHelper.showBuyTestDrive(@screen, @screen, @user, (() => @buyTestDrive()))
showBuyNormalLessonBubble: () ->
- console.log("OK showBuyNormalLessonBubble")
- context.JK.HelpBubbleHelper.showBuyNormalLesson(@screen, @screen)
+ context.JK.HelpBubbleHelper.showBuyNormalLesson(@screen, @screen, @state.user, (() => @buyNormalLesson()))
+
+ useRemainingTestDrives: () ->
+ window.location.href = "/client#/jamclass/book-lesson/test-drive_#{@state.user.id}"
+ buyTestDrive: () ->
+ window.location.href = "/client#/jamclass/test-drive-selection/#{@state.user.id}"
+ buyNormalLesson: () ->
+ window.location.href = "/client#/jamclass/book-lesson/normal_#{@state.user.id}"
getInitialState: () ->
{
@@ -157,6 +168,7 @@ proficiencyDescriptionMap = {
onUserChanged: (userState) ->
@user = userState?.user
+ @showSideBubbleWhenReady()
editProfile: (selected, e) ->
e.preventDefault()
diff --git a/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee
index 0ef216da7..b6a5c93f5 100644
--- a/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/TeacherSearchScreen.js.jsx.coffee
@@ -27,7 +27,7 @@ ProfileActions = @ProfileActions
refreshing: false
getInitialState: () ->
- {searchOptions: {}, results: []}
+ {searchOptions: {}, results: [], user: null}
onAppInit: (@app) ->
@app.bindScreen('teachers/search', {beforeShow: @beforeShow, afterShow: @afterShow, afterHide: @afterHide})
@@ -59,6 +59,7 @@ ProfileActions = @ProfileActions
@setState(results)
onUserChanged: (@user) ->
+ @setState({user: @user?.user})
#onTeacherSearchChanged: (options) ->
# if @visible
@@ -119,7 +120,8 @@ ProfileActions = @ProfileActions
.done((response) =>
if response.remaining_test_drives == 0 && response['can_buy_test_drive?']
logger.debug("TeacherSearchScreen: user offered test drive")
- @app.layout.showDialog('try-test-drive', {d1: user.teacher.id})
+ #@app.layout.showDialog('try-test-drive', {d1: user.teacher.id})
+ window.location.href = '/client#/jamclass/test-drive-selection/' + user.id
else if response.remaining_test_drives > 0
if response.booked_with_teacher && !context.JK.currentUserAdmin
logger.debug("TeacherSearchScreen: teacher already test-drived")
@@ -130,6 +132,7 @@ ProfileActions = @ProfileActions
logger.debug("TeacherSearchScreen: user being sent to book a lesson")
window.location.href = '/client#/jamclass/book-lesson/test-drive_' + user.id
+ #window.location.href = '/client#/jamclass/test-drive-selection/' + user.id
else
# user has no remaining test drives and can't buy any
logger.debug("TeacherSearchScreen: test drive all done")
@@ -230,6 +233,11 @@ ProfileActions = @ProfileActions
if !bio?
bio = 'No bio'
+ console.log("@state.sur : #{@state.user.remaining_test_drives}, #{@state.user['can_buy_test_drive?']}")
+ if !@state.user? || @state.user.remaining_test_drives > 0 || @state.user['can_buy_test_drive?']
+ bookTestDriveBtn = `BOOK TESTDRIVE LESSON `
+ else
+ bookSingleBtn = `BOOK LESSON `
resultsJsx.push(`
@@ -246,8 +254,8 @@ ProfileActions = @ProfileActions
diff --git a/web/app/assets/javascripts/react-components/TestDriveSelectionScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/TestDriveSelectionScreen.js.jsx.coffee
new file mode 100644
index 000000000..8a240d9a9
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/TestDriveSelectionScreen.js.jsx.coffee
@@ -0,0 +1,174 @@
+context = window
+rest = context.JK.Rest()
+logger = context.JK.logger
+
+UserStore = context.UserStore
+
+@TestDriveSelection = React.createClass({
+
+ mixins: [
+ Reflux.listenTo(AppStore, "onAppInit"),
+ Reflux.listenTo(UserStore, "onUserChanged")
+ ]
+
+ onAppInit: (@app) ->
+ @app.bindScreen('jamclass/test-drive-selection',
+ {afterShow: @afterShow, beforeHide: @beforeHide, navName: 'TestDrive Selection'})
+
+ onUserChanged: (userState) ->
+ @setState({user: userState?.user})
+
+ beforeHide: (e) ->
+
+
+ afterShow: (e) ->
+ logger.debug("TestDriveSelection: afterShow", e.id)
+
+ parsed = @parseId(e.id)
+
+ id = parsed.id
+
+ if id? && id != 'none' && id != 'default'
+ @setState({teacherId: id, teacher: null})
+ else
+ @setState({teacherId: null, teacher: null})
+
+ rest.getUserDetail({
+ id: id,
+ show_teacher: true
+ }).done((response) => @userDetailDone(response)).fail(@app.ajaxError)
+
+ parseId: (id) ->
+ if !id?
+ {id: null}
+ else
+ {id: id}
+
+ userDetailDone: (response) ->
+ if response.id == @state.teacherId
+ @setState({teacher: response, isSelf: response.id == context.JK.currentUserId})
+ else
+ logger.debug("TestDriveSelection: ignoring teacher details", response.id, @state.teacherId)
+
+ getInitialState: () ->
+ {
+ user: null,
+ teacher: null,
+ teacherId: null,
+ }
+
+ packageSelect: (packageType, e) ->
+ e.preventDefault()
+
+ console.log("test-drive-#{packageType}")
+ rest.updateUser({desired_package: "test-drive-#{packageType}"}).done((response) => @packageSelectedDone(response)).fail((jqXHR) => @packageSelectedFail(jqXHR))
+
+
+ packageSelectedFail: (jqXHR) ->
+ console.log("package selected fail: " + jqXHR.responseText)
+ @app.ajaxError(jqXHR)
+
+ packageSelectedDone:(response) ->
+
+ url = "/client#/jamclass/book-lesson/test-drive"
+
+ console.log("TEACHER", JSON.stringify(@state.teacher))
+ if @state.teacher?
+ url += '_' + @state.teacher.id
+ else
+ url = "/client#/jamclass/lesson-payment/test-drive"
+
+ window.location.href = url
+
+ avatar: (name = 'your choice', photo_url = '/assets/shared/avatar_generic.png') ->
+ `
+
+
+
+
`
+ render: () ->
+ teacher_name = @state.teacher?.name
+ photo_url = @state.teacher?.photo_url
+ if !photo_url?
+ photo_url = '/assets/shared/avatar_generic.png'
+
+ `
+
+
+
+
+
+
MOST POPULAR
+
+
+ {this.avatar(teacher_name, photo_url)}
+ {this.avatar()}
+ {this.avatar()}
+ {this.avatar()}
+
+
+ GET 4 LESSONS WITH 4 DIFFERENT TEACHERS FOR JUST $12.50 EACH
+
+
+ You wouldn't marry the first person you date - right? Choosing the right teacher is the most important
+ thing you can do to ensure success and become a better musician. Try 4 different teachers. Then pick the
+ one
+ who is best for YOU!
+
+
+
+
SELECT
+
+
Just $49.99!
+
+
+
+
+
+
GREAT VALUE
+
+
+ {this.avatar(teacher_name, photo_url)}
+ {this.avatar()}
+
+
+ GET 2 LESSONS FOR THE PRICE OF 1
+
+
+ Want to try more than one teacher, but 4 is too many for you? Try two lessons with two different
+ teachers for the price of one lesson.
+ A great value, and a good way to find an excellent teacher!
+
+
+
+
SELECT
+
+
Just $29.99!
+
+
+
+
+
I'M SURE
+
+
+ {this.avatar(teacher_name, photo_url)}
+
+
+ GET 1 HALF-PRICE LESSON TO GET STARTED
+
+
+ Are you confident you've found the best teacher for you? Then book your first lesson at a terrific
+ value, and get your first lesson scheduled to start learning more today!
+
+
+
+
+
SELECT
+
+
Just $14.99!
+
+
+
+
+
`
+})
\ No newline at end of file
diff --git a/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee b/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee
index 1c77ab5d1..1b75d8d98 100644
--- a/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee
+++ b/web/app/assets/javascripts/react-components/mixins/PostProcessorMixin.js.coffee
@@ -19,7 +19,6 @@ teacherActions = window.JK.Actions.Teacher
lesson.isAdmin = context.JK.currentUserAdmin
lesson.cardNotOk = !lesson.lesson_booking.card_presumed_ok
- console.log("lesson.isAdmin",lesson.isAdmin )
if (lesson.status == 'requested' || lesson.status == 'countered')
lesson.isRequested = true
if lesson.cardNotOk
@@ -56,4 +55,40 @@ teacherActions = window.JK.Actions.Teacher
user.musician_profile = '/client#/profile/' + user.id
user.best_profile = user.musician_profile
+ if user.is_a_teacher
+ cheapest_lesson_stmt = '(no pricing set yet)'
+ lowestPrice = null
+ lowestDuration = null
+ single = true
+ enabledMinutes = []
+ for minutes in [30, 45, 60, 90, 120]
+ duration_enabled = user.teacher["lesson_duration_#{minutes}"]
+
+ if duration_enabled
+ enabledMinutes.push(minutes)
+ if user.teacher.prices_per_lesson
+ for minutes in enabledMinutes
+ lesson_price = user.teacher["price_per_lesson_#{minutes}_cents"]
+ if lesson_price?
+ if !lowestPrice? || lesson_price < lowestPrice
+ lowestPrice = lesson_price
+ single = true
+ lowestDuration = minutes
+ for minutes in enabledMinutes
+ lesson_price = user.teacher["price_per_month_#{minutes}_cents"]
+ if lesson_price?
+ if !lowestPrice? || (lesson_price / 4) < lowestPrice
+ lowestPrice = lesson_price / 4
+ single = false
+ lowestDuration = minutes
+
+ if lowestPrice?
+ if single
+ # lowest price appears to be a single lesson
+ cheapest_lesson_stmt = "$#{lowestPrice / 100} for #{lowestDuration} minutes"
+ else
+ # lowest price appears to be a monthly recurring lesson
+ cheapest_lesson_stmt = "$#{Math.round(lowestPrice * 4) / 100} per month"
+
+ user.cheapest_lesson_stmt = cheapest_lesson_stmt
}
\ No newline at end of file
diff --git a/web/app/assets/javascripts/utils.js b/web/app/assets/javascripts/utils.js
index 87dd50dbc..ec6bb6cf6 100644
--- a/web/app/assets/javascripts/utils.js
+++ b/web/app/assets/javascripts/utils.js
@@ -143,8 +143,13 @@
options = {};
}
+ var originalPostShow = options.postShow;
options.postShow = function(container) {
context.JK.popExternalLinks($(container))
+
+ if (originalPostShow) {
+ originalPostShow(container);
+ }
}
diff --git a/web/app/assets/stylesheets/client/common.css.scss b/web/app/assets/stylesheets/client/common.css.scss
index d3a9974f4..c7f836220 100644
--- a/web/app/assets/stylesheets/client/common.css.scss
+++ b/web/app/assets/stylesheets/client/common.css.scss
@@ -64,22 +64,6 @@ $labelFontSize: 12px;
}
-select {
-
- border: 0 !important; /*Removes border*/
- -webkit-appearance: none; /*Removes default chrome and safari style*/
- -moz-appearance: none; /* Removes Default Firefox style*/
- appearance: none;
- background: url('/assets/down_arrow_black_pad.png') no-repeat; /*Adds background-image*/
- background-position: right center; /*Position of the background-image*/
- text-indent: 0.01px; /* Removes default arrow from firefox*/
- text-overflow: ""; /*Removes default arrow from firefox*/
- cursor: pointer;
- padding-right:20px;
- &::-ms-expand {
- display: none;
- }
-}
@mixin border_box_sizing {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
diff --git a/web/app/assets/stylesheets/client/help.css.scss b/web/app/assets/stylesheets/client/help.css.scss
index f29cd263e..ec34250dd 100644
--- a/web/app/assets/stylesheets/client/help.css.scss
+++ b/web/app/assets/stylesheets/client/help.css.scss
@@ -99,6 +99,7 @@ body.jam, body.web, .dialog{
}
p {
margin:.8em 1em;
+ line-height:120%;
}
.book-now {
width:100px;
diff --git a/web/app/assets/stylesheets/client/jamkazam.css.scss b/web/app/assets/stylesheets/client/jamkazam.css.scss
index 9d2577e84..8b972af82 100644
--- a/web/app/assets/stylesheets/client/jamkazam.css.scss
+++ b/web/app/assets/stylesheets/client/jamkazam.css.scss
@@ -76,8 +76,21 @@ a.arrow-down {
}
select {
- padding:3px;
- font-size:15px;
+
+ border: 0 !important; /*Removes border*/
+ -webkit-appearance: none; /*Removes default chrome and safari style*/
+ -moz-appearance: none; /* Removes Default Firefox style*/
+ appearance: none;
+ background: #C5C5C5 url('/assets/down_arrow_black_pad.png') no-repeat; /*Adds background-image*/
+ background-position: right center; /*Position of the background-image*/
+ text-indent: 0.01px; /* Removes default arrow from firefox*/
+ text-overflow: ""; /*Removes default arrow from firefox*/
+ cursor: pointer;
+ padding:3px 20px 3px 3px;
+ &::-ms-expand {
+ display: none;
+ }
+ font-size:15px;
border-radius: 6px;
}
diff --git a/web/app/assets/stylesheets/client/react-components/LessonBooking.css.scss b/web/app/assets/stylesheets/client/react-components/LessonBooking.css.scss
index 6e5b1ddcb..fbed0c14d 100644
--- a/web/app/assets/stylesheets/client/react-components/LessonBooking.css.scss
+++ b/web/app/assets/stylesheets/client/react-components/LessonBooking.css.scss
@@ -16,6 +16,20 @@
.column-left {
float:left;
padding-right:20px;
+
+ .slot.slot-2 {
+ border-style: solid;
+ border-width: 1px 0 0 0;
+ border-color: #cccccc;
+ padding-top: 20px;
+ }
+
+ .description {
+ border-style: solid;
+ border-width: 1px 0 0 0;
+ border-color: #cccccc;
+ padding-top: 20px;
+ }
}
.column-right {
float:right;
@@ -56,7 +70,7 @@
textarea {
width:100%;
@include border_box_sizing;
- height:125px;
+ height:75px;
}
.field {
display:inline-block;
@@ -99,7 +113,7 @@
}
.jamclass-policies {
text-align:center;
- margin-top:-20px;
+ margin-top:-10px;
}
.actions {
margin-left:-3px;
@@ -138,7 +152,7 @@
width:80%;
}
}
- select.hour {
- margin-left:20px;
+ select.am_pm {
+ margin-left:13px;
}
}
diff --git a/web/app/assets/stylesheets/client/react-components/TestDriveSelectionScreen.css.scss b/web/app/assets/stylesheets/client/react-components/TestDriveSelectionScreen.css.scss
new file mode 100644
index 000000000..39d459f10
--- /dev/null
+++ b/web/app/assets/stylesheets/client/react-components/TestDriveSelectionScreen.css.scss
@@ -0,0 +1,164 @@
+@import "client/common";
+
+
+$fluid-break: 1335px;
+@mixin layout-small {
+ @media (max-width: #{$fluid-break - 1px}) {
+ @content;
+ }
+}
+
+@mixin layout-normal {
+ @media (min-width: #{$fluid-break}) {
+ @content;
+ }
+}
+
+
+#test-drive-selection {
+
+
+
+ div[data-react-class="TestDriveSelection"] {
+ height: 100%;
+ }
+ .content-body-scroller {
+ height: 100%;
+ padding: 30px;
+ @include border_box_sizing;
+ }
+
+ h2 {
+ font-size: 24px;
+ font-weight: 700;
+ margin-bottom: 20px !important;
+ display: inline-block;
+ }
+
+ .test-drive-selection-wrapper {
+ float:left;
+ text-align:center;
+ width:31%;
+
+ &.select-4 {
+
+ }
+ &.select-2 {
+ margin:0 3.5%;
+ }
+ &.select-1 {
+
+ }
+ }
+ .test-drive-selection {
+ display:inline-block;
+ border-radius:10px;
+ border-width:1px;
+ border-color:$ColorScreenPrimary;
+ border-style:solid;
+ margin-bottom:15px;
+
+ @media (max-width: 1180px) {
+ min-height:360px;
+ }
+ @media (min-width: 1181px) {
+ min-height:340px;
+ }
+ @media (min-width: 1450px) {
+ min-height:305px;
+ }
+ }
+
+ a.select-package {
+ margin-bottom:15px;
+ max-width: 140px;
+ width: 100%;
+ }
+
+ .price-notice {
+ color:white;
+ font-size:16px;
+ }
+
+ .td-header {
+ height:45px;
+ color:white;
+ text-align:center;
+ font-size:24px;
+ line-height: 45px;
+ vertical-align: middle;
+ background-color:$ColorScreenPrimary;
+
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+
+ @media (max-width: 1130px) {
+ font-size:16px;
+ }
+ }
+ .td-content {
+ @include border-box_sizing;
+ padding:10px;
+ width:100%;
+
+ }
+
+ .avatars {
+ margin-bottom:20px;
+ }
+ .td-msg {
+ margin-bottom:20px;
+
+ @media (max-width: 1400px) {
+ min-height:42px;
+ }
+ }
+ .td-desc {
+ line-height:120%;
+ color:$ColorTextTypical;
+ }
+
+ .avatar-header {
+ display:inline-block;
+ }
+ .avatar {
+ display:inline-block;
+ padding:1px;
+ width:48px;
+ height:48px;
+ background-color:#ed4818;
+ margin:10px 8px 0 0;
+ -webkit-border-radius:24px;
+ -moz-border-radius:24px;
+ border-radius:24px;
+ float:none;
+
+ @include layout-small {
+ width:32px;
+ height:32px;
+ -webkit-border-radius:16px;
+ -moz-border-radius:16px;
+ border-radius:16px;
+ margin:10px 6px 0 0;
+ }
+ }
+ .avatar img {
+ width: 48px;
+ height: 48px;
+ -webkit-border-radius:24px;
+ -moz-border-radius:24px;
+ border-radius:24px;
+ @include layout-small {
+ width:32px;
+ height:32px;
+ -webkit-border-radius:16px;
+ -moz-border-radius:16px;
+ border-radius:16px;
+ }
+ }
+ .selection-area {
+ width:100%;
+ padding-top:20px;
+ }
+
+}
\ No newline at end of file
diff --git a/web/app/controllers/api_stripe_controller.rb b/web/app/controllers/api_stripe_controller.rb
index 9501141a5..72eec53c6 100644
--- a/web/app/controllers/api_stripe_controller.rb
+++ b/web/app/controllers/api_stripe_controller.rb
@@ -14,6 +14,7 @@ class ApiStripeController < ApiController
@lesson = data[:lesson]
@test_drive = data[:test_drive]
@normal = data[:normal]
+ @lesson_package_type = data[:lesson_package_type]
end
end
diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb
index a6b43b1e3..74077b465 100644
--- a/web/app/controllers/api_users_controller.rb
+++ b/web/app/controllers/api_users_controller.rb
@@ -1,6 +1,5 @@
require 'sanitize'
-class
-ApiUsersController < ApiController
+class ApiUsersController < ApiController
before_filter :api_signed_in_user, :except => [:create, :calendar, :show, :signup_confirm, :auth_session_create, :complete, :finalize_update_email, :isp_scoring, :add_play, :crash_dump, :validate_data, :google_auth, :user_event]
before_filter :auth_user, :only => [:session_settings_show, :session_history_index, :session_user_history_index, :update, :delete, :authorizations, :test_drive_status,
@@ -178,6 +177,7 @@ ApiUsersController < ApiController
@user.is_a_student = params[:student] if params.has_key?(:student)
@user.is_a_teacher = params[:teacher] if params.has_key?(:teacher)
@user.school_interest = !!params[:school_interest]
+ @user.desired_package = LessonPackageType.find_by_package_type!(params[:desired_package]) if params.has_key?(:desired_package)
@user.save
if @user.errors.any?
diff --git a/web/app/views/api_stripe/store.rabl b/web/app/views/api_stripe/store.rabl
index 953850168..27e32132a 100644
--- a/web/app/views/api_stripe/store.rabl
+++ b/web/app/views/api_stripe/store.rabl
@@ -9,16 +9,21 @@ end
if @test_drive
node :test_drive do |lesson|
- attributes :teacher_id
+ {teacher_id: @test_drive.id}
end
end
if @normal
node :normal do |lesson|
- attributes :teacher_id
+ {teacher_id: @normal.teacher_id}
+ end
+end
+
+if @lesson_package_type
+ node :lesson_package_type do |lesson_package_type|
+ {package_type: @lesson_package_type.package_type}
end
end
-
diff --git a/web/app/views/api_users/show.rabl b/web/app/views/api_users/show.rabl
index d9df9fd03..5cf41f03e 100644
--- a/web/app/views/api_users/show.rabl
+++ b/web/app/views/api_users/show.rabl
@@ -28,7 +28,7 @@ end
# give back more info if the user being fetched is yourself
if current_user && @user == current_user
- attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :show_whats_next_count, :subscribe_email, :auth_twitter, :new_notifications, :sales_count, :reuse_card, :purchased_jamtracks_count, :first_downloaded_client_at, :created_at, :first_opened_jamtrack_web_player, :gifted_jamtracks, :has_redeemable_jamtrack, :remaining, :has_stored_credit_card?, :remaining_test_drives, :can_buy_test_drive?
+ attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :show_whats_next_count, :subscribe_email, :auth_twitter, :new_notifications, :sales_count, :reuse_card, :purchased_jamtracks_count, :first_downloaded_client_at, :created_at, :first_opened_jamtrack_web_player, :gifted_jamtracks, :has_redeemable_jamtrack, :remaining, :has_stored_credit_card?, :remaining_test_drives, :can_buy_test_drive?, :lesson_package_type_id
node :owned_school_id do |user|
user.owned_school.id if user.owned_school
diff --git a/web/app/views/clients/_help.html.slim b/web/app/views/clients/_help.html.slim
index ad30e8b0c..cdaacd3d8 100644
--- a/web/app/views/clients/_help.html.slim
+++ b/web/app/views/clients/_help.html.slim
@@ -403,6 +403,7 @@ script type="text/template" id="template-help-teacher-profile"
script type="text/template" id="template-help-side-remaining-test-drives"
.side-remaining-test-drives
+ h2 Book TestDrive Lesson
p You currently have {{data.remaining_test_drives}} TestDrive lesson credits available.
a.book-now.button-orange BOOK NOW!
@@ -418,7 +419,7 @@ script type="text/template" id="template-help-side-buy-test-drive"
script type="text/template" id="template-help-side-buy-normal-lesson"
.side-buy-normal-lesson
h2 Book Lesson
- p Lessons with {{data.first_name}} start at just ${{data.cheapest_lesson_stmt}}.
+ p Lessons with {{data.first_name}} start at just {{data.cheapest_lesson_stmt}}.
a.book-now.button-orange BOOK NOW!
p Or call us at
p 877-376-8742 (877-37-MUSIC)
diff --git a/web/app/views/clients/index.html.erb b/web/app/views/clients/index.html.erb
index 297594f77..05f278e03 100644
--- a/web/app/views/clients/index.html.erb
+++ b/web/app/views/clients/index.html.erb
@@ -50,6 +50,7 @@
<%= render "clients/jamclass/lesson_payment" %>
<%= render "clients/jamclass/lesson_session" %>
<%= render "clients/jamclass/lesson_booking" %>
+<%= render "clients/jamclass/test_drive_selection" %>
<%= render "clients/jamclass/jamclass_student" %>
<%= render "users/feed_music_session_ajax" %>
<%= render "users/feed_recording_ajax" %>
diff --git a/web/app/views/clients/jamclass/_lesson_booking.html.slim b/web/app/views/clients/jamclass/_lesson_booking.html.slim
index b483b4fc0..a50e244be 100644
--- a/web/app/views/clients/jamclass/_lesson_booking.html.slim
+++ b/web/app/views/clients/jamclass/_lesson_booking.html.slim
@@ -1,7 +1,7 @@
#lesson-booking.screen.secondary layout="screen" layout-id="jamclass/lesson-booking" layout-arg="id"
.content-head
.content-icon
- = image_tag "content/icon_account.png", :size => "27x20"
+ = image_tag "content/icon_musicians.png", :size => "20x20"
h1
| jamclass
= render "screen_navigation"
diff --git a/web/app/views/clients/jamclass/_test_drive_selection.html.slim b/web/app/views/clients/jamclass/_test_drive_selection.html.slim
new file mode 100644
index 000000000..5108e3f2b
--- /dev/null
+++ b/web/app/views/clients/jamclass/_test_drive_selection.html.slim
@@ -0,0 +1,10 @@
+#test-drive-selection.screen.secondary layout="screen" layout-id="jamclass/test-drive-selection" layout-arg="id"
+ .content-head
+ .content-icon
+ = image_tag "content/icon_musicians.png", :size => "20x20"
+ h1
+ | jamclass
+ = render "screen_navigation"
+ .content-body
+ = react_component 'TestDriveSelection', {}
+
diff --git a/web/lib/tasks/lesson.rake b/web/lib/tasks/lesson.rake
index 92da6d0e2..a2963c3ab 100644
--- a/web/lib/tasks/lesson.rake
+++ b/web/lib/tasks/lesson.rake
@@ -71,7 +71,7 @@ namespace :lessons do
lesson = booking.lesson_sessions[0]
if user.most_recent_test_drive_purchase.nil?
- LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive)
+ LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4)
end
#lesson.accept({message: 'Yeah I got this', slot: slots[0]})
diff --git a/web/spec/factories.rb b/web/spec/factories.rb
index 5e2fcfb62..3c7b09c4a 100644
--- a/web/spec/factories.rb
+++ b/web/spec/factories.rb
@@ -950,7 +950,7 @@ FactoryGirl.define do
price 30.00
factory :test_drive_purchase do
- lesson_package_type { JamRuby::LessonPackageType.test_drive }
+ lesson_package_type { JamRuby::LessonPackageType.test_drive_4 }
association :lesson_booking, factory: :lesson_booking
price 49.99
end
diff --git a/web/spec/features/book_monthly_recurring_lesson_spec.rb b/web/spec/features/book_monthly_recurring_lesson_spec.rb
index 5b9987014..81e9b718d 100644
--- a/web/spec/features/book_monthly_recurring_lesson_spec.rb
+++ b/web/spec/features/book_monthly_recurring_lesson_spec.rb
@@ -7,6 +7,7 @@ describe "Book Monthly Recurring Lesson", :js => true, :type => :feature, :capyb
let(:user) { FactoryGirl.create(:user, traditional_band: true,paid_sessions: true, paid_sessions_hourly_rate: 1, paid_sessions_daily_rate:1 ) }
let(:teacher_user) {FactoryGirl.create(:teacher_user, first_name: "Teacher1", ready_for_session_at: Time.now)}
let(:teacher_user2) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
+ let(:teacher_user3) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
after(:each) do
Timecop.return
@@ -23,7 +24,12 @@ describe "Book Monthly Recurring Lesson", :js => true, :type => :feature, :capyb
UserMailer.deliveries.clear
emulate_client
- sign_in_poltergeist user
+ # create an old test drive and fakely use up all the credits so that we can book the lesson
+ Timecop.travel(Date.new(2016, 03, 01))
+ testdrive_lesson(user, teacher_user3)
+ user.remaining_test_drives = 0
+ user.save!
+ user.reload
teacher_user.teacher.ready_for_session_at = Time.now
@@ -38,10 +44,11 @@ describe "Book Monthly Recurring Lesson", :js => true, :type => :feature, :capyb
it "succeeds" do
- visit "/client#/teachers/search"
+ Timecop.travel(Date.new(2016, 04, 01))
- # let's do a time half-way into the month, so we can prove some pro-rating
- Timecop.travel(Date.new(2016, 04, 15))
+ sign_in_poltergeist user
+
+ visit "/client#/teachers/search"
find('.teacher-search-result[data-teacher-id="' + teacher_user.id + '"] .try-normal').trigger(:click)
@@ -61,32 +68,35 @@ describe "Book Monthly Recurring Lesson", :js => true, :type => :feature, :capyb
find('a.book-lesson-btn', text: 'BOOK LESSON').trigger(:click)
- find('h2', text: 'enter payment info for lesson')
+ #find('h2', text: 'enter payment info for lesson')
- user.student_lesson_bookings.count.should eql 1
- lesson_booking = user.student_lesson_bookings.first
- lesson_booking.is_requested?.should be_true
- lesson_booking.card_presumed_ok.should be_false
- lesson_booking.recurring.should be true
- lesson_booking.is_monthly_payment?.should be true
- fill_in 'card-number', with: '4111111111111111'
- fill_in 'expiration', with: '11/2016'
- fill_in 'cvv', with: '111'
- fill_in 'zip', with: '78759'
+ #fill_in 'card-number', with: '4111111111111111'
+ #fill_in 'expiration', with: '11/2016'
+ #fill_in 'cvv', with: '111'
+ #fill_in 'zip', with: '78759'
- find('.purchase-btn').trigger(:click)
+ #find('.purchase-btn').trigger(:click)
# we tell user they have test drive purchased, and take them to the teacher screen
find('#banner h1', text: 'Lesson Requested')
# dismiss banner
find('a.button-orange', text:'CLOSE').trigger(:click)
+
+ user.student_lesson_bookings.count.should eql 2
+ lesson_booking = user.student_lesson_bookings.order(:created_at).last
+ lesson_booking.is_requested?.should be_true
+ lesson_booking.card_presumed_ok.should be_true
+ lesson_booking.recurring.should be true
+ lesson_booking.is_monthly_payment?.should be true
+
+
lesson_booking = LessonBooking.where(teacher_id: teacher_user).first
lesson_booking.should_not be_nil
lesson_session = LessonSession.where(teacher_id: teacher_user).first
lesson_session.teacher.should eql teacher_user
- lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id).first
+ lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id, teacher_id: teacher_user.id).first
lesson_package_purchase.should be_nil
user.reload
user.remaining_test_drives.should eql 0
@@ -150,7 +160,7 @@ describe "Book Monthly Recurring Lesson", :js => true, :type => :feature, :capyb
lesson_booking.recurring.should be false
LessonSession.where(teacher_id: teacher_user2).count.should eql 1
- lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id).first
+ lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id, teacher_id: teacher_user.id).first
lesson_package_purchase.should be_nil
user.reload
user.remaining_test_drives.should eql 0
@@ -176,13 +186,13 @@ describe "Book Monthly Recurring Lesson", :js => true, :type => :feature, :capyb
lesson_session1.billed.should eql false
lesson_session1.success.should be_true
- user.lesson_purchases.count.should eql 0
+ user.lesson_purchases.count.should eql 1
LessonBooking.hourly_check
user.reload
- lesson_package_purchase = user.lesson_purchases.count.should eql 1
- lesson_package_purchase = user.lesson_purchases.first
+ lesson_package_purchase = user.lesson_purchases.count.should eql 2
+ lesson_package_purchase = user.lesson_purchases.where(teacher_id: teacher_user.id).last
teacher_distribution = lesson_package_purchase.teacher_distribution
teacher_distribution.amount_in_cents.should eql 3000 / 2
teacher_distribution.ready.should be_true
diff --git a/web/spec/features/book_recurring_lesson_spec.rb b/web/spec/features/book_recurring_lesson_spec.rb
index 038689ca4..511af9d2b 100644
--- a/web/spec/features/book_recurring_lesson_spec.rb
+++ b/web/spec/features/book_recurring_lesson_spec.rb
@@ -7,6 +7,7 @@ describe "Book Single Recurring Lesson", :js => true, :type => :feature, :capyba
let(:user) { FactoryGirl.create(:user, traditional_band: true,paid_sessions: true, paid_sessions_hourly_rate: 1, paid_sessions_daily_rate:1 ) }
let(:teacher_user) {FactoryGirl.create(:teacher_user, first_name: "Teacher1", ready_for_session_at: Time.now)}
let(:teacher_user2) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
+ let(:teacher_user3) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
after(:each) do
Timecop.return
@@ -23,8 +24,17 @@ describe "Book Single Recurring Lesson", :js => true, :type => :feature, :capyba
UserMailer.deliveries.clear
emulate_client
- sign_in_poltergeist user
+ # create an old test drive and fakely use up all the credits so that we can book the lesson
+ Timecop.travel(Date.new(2016, 03, 01))
+ testdrive_lesson(user, teacher_user3)
+ user.remaining_test_drives = 0
+ user.save!
+ user.reload
+ teacher_user.teacher.ready_for_session_at = Time.now
+ teacher_user.teacher.save!
+ teacher_user.teacher.price_per_lesson_60_cents.should eql 3000
+ Teacher.index(user, {})[:query].count.should eql 1
teacher_user.teacher.ready_for_session_at = Time.now
teacher_user.teacher.save!
@@ -38,10 +48,13 @@ describe "Book Single Recurring Lesson", :js => true, :type => :feature, :capyba
it "succeeds" do
- visit "/client#/teachers/search"
Timecop.travel(Date.new(2016, 04, 01))
+ sign_in_poltergeist user
+
+ visit "/client#/teachers/search"
+
find('.teacher-search-result[data-teacher-id="' + teacher_user.id + '"] .try-normal').trigger(:click)
@@ -60,32 +73,35 @@ describe "Book Single Recurring Lesson", :js => true, :type => :feature, :capyba
find('a.book-lesson-btn', text: 'BOOK LESSON').trigger(:click)
- find('h2', text: 'enter payment info for lesson')
+ # find('h2', text: 'enter payment info for lesson')
- user.student_lesson_bookings.count.should eql 1
- lesson_booking = user.student_lesson_bookings.first
- lesson_booking.is_requested?.should be_true
- lesson_booking.card_presumed_ok.should be_false
- lesson_booking.recurring.should be true
- lesson_booking.is_monthly_payment?.should be false
- fill_in 'card-number', with: '4111111111111111'
- fill_in 'expiration', with: '11/2016'
- fill_in 'cvv', with: '111'
- fill_in 'zip', with: '78759'
+ #fill_in 'card-number', with: '4111111111111111'
+ #fill_in 'expiration', with: '11/2016'
+ #fill_in 'cvv', with: '111'
+ #fill_in 'zip', with: '78759'
- find('.purchase-btn').trigger(:click)
+ #find('.purchase-btn').trigger(:click)
# we tell user they have test drive purchased, and take them to the teacher screen
find('#banner h1', text: 'Lesson Requested')
# dismiss banner
find('a.button-orange', text:'CLOSE').trigger(:click)
+
+
+ user.student_lesson_bookings.count.should eql 2
+ lesson_booking = user.student_lesson_bookings.order(:created_at).last
+ lesson_booking.is_requested?.should be_true
+ lesson_booking.card_presumed_ok.should be_true
+ lesson_booking.recurring.should be true
+ lesson_booking.is_monthly_payment?.should be false
+
lesson_booking = LessonBooking.where(teacher_id: teacher_user).first
lesson_booking.should_not be_nil
lesson_session = LessonSession.where(teacher_id: teacher_user).first
lesson_session.teacher.should eql teacher_user
- lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id).first
+ lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id, teacher_id: teacher_user.id).first
lesson_package_purchase.should be_nil
user.reload
user.remaining_test_drives.should eql 0
@@ -149,7 +165,7 @@ describe "Book Single Recurring Lesson", :js => true, :type => :feature, :capyba
lesson_booking.recurring.should be false
LessonSession.where(teacher_id: teacher_user2).count.should eql 1
- lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id).first
+ lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id, teacher_id: teacher_user.id).first
lesson_package_purchase.should be_nil
user.reload
user.remaining_test_drives.should eql 0
@@ -175,7 +191,7 @@ describe "Book Single Recurring Lesson", :js => true, :type => :feature, :capyba
lesson_session1.billed.should eql true
lesson_session1.success.should be_true
lesson_session1.lesson_payment_charge.billed.should be_true
- lesson_session1.lesson_payment_charge.amount_in_cents.should eql 3000
+ lesson_session1.lesson_payment_charge.amount_in_cents.should eql (3000 + (3000 * 0.0825).round)
lesson_session1.lesson_payment_charge.fee_in_cents.should eql 0
lesson_session1.lesson_payment_charge.stripe_charge_id.should_not be_nil
lesson_session1.lesson_payment_charge.post_processed.should be_true
diff --git a/web/spec/features/book_single_lesson_spec.rb b/web/spec/features/book_single_lesson_spec.rb
index 9914eeea6..608e8afc8 100644
--- a/web/spec/features/book_single_lesson_spec.rb
+++ b/web/spec/features/book_single_lesson_spec.rb
@@ -7,6 +7,7 @@ describe "Single Lesson", :js => true, :type => :feature, :capybara_feature => t
let(:user) { FactoryGirl.create(:user, traditional_band: true,paid_sessions: true, paid_sessions_hourly_rate: 1, paid_sessions_daily_rate:1 ) }
let(:teacher_user) {FactoryGirl.create(:teacher_user, first_name: "Teacher1", ready_for_session_at: Time.now)}
let(:teacher_user2) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
+ let(:teacher_user3) {FactoryGirl.create(:teacher_user, ready_for_session_at: Time.now)}
before(:each) do
@@ -17,14 +18,16 @@ describe "Single Lesson", :js => true, :type => :feature, :capybara_feature => t
UserMailer.deliveries.clear
emulate_client
+ # create an old test drive and fakely use up all the credits so that we can book the lesson
+ Timecop.travel(Date.new(2016, 03, 01))
+ testdrive_lesson(user, teacher_user3)
+ user.remaining_test_drives = 0
+ user.save!
+ user.reload
sign_in_poltergeist user
-
-
teacher_user.teacher.ready_for_session_at = Time.now
teacher_user.teacher.save!
-
teacher_user.teacher.price_per_lesson_60_cents.should eql 3000
-
Teacher.index(user, {})[:query].count.should eql 1
@@ -62,33 +65,35 @@ describe "Single Lesson", :js => true, :type => :feature, :capybara_feature => t
#find('h2', text: 'your lesson has been requested')
- find('h2', text: 'enter payment info for lesson')
-
- user.student_lesson_bookings.count.should eql 1
- lesson_booking = user.student_lesson_bookings.first
- lesson_booking.is_requested?.should be_true
- lesson_booking.card_presumed_ok.should be_false
- lesson_booking.recurring.should be false
+ #find('h2', text: 'enter payment info for lesson')
+ #fill_in 'card-number', with: '4111111111111111'
+ #fill_in 'expiration', with: '11/2016'
+ #fill_in 'cvv', with: '111'
+ #fill_in 'zip', with: '78759'
- fill_in 'card-number', with: '4111111111111111'
- fill_in 'expiration', with: '11/2016'
- fill_in 'cvv', with: '111'
- fill_in 'zip', with: '78759'
-
- find('.purchase-btn').trigger(:click)
+ #find('.purchase-btn').trigger(:click)
# we tell user they have test drive purchased, and take them to the teacher screen
find('#banner h1', text: 'Lesson Requested')
# dismiss banner
find('a.button-orange', text:'CLOSE').trigger(:click)
- lesson_booking = LessonBooking.where(teacher_id: teacher_user).first
+
+ user.student_lesson_bookings.count.should eql 2 # this single one, and the test drive created in the before section of the test
+ lesson_booking = user.student_lesson_bookings.order(:created_at).last
+ lesson_booking.is_requested?.should be_true
+ lesson_booking.card_presumed_ok.should be_true
+ lesson_booking.recurring.should be false
+
+
+
+ lesson_booking = LessonBooking.where(teacher_id: teacher_user).order(:created_at).last
lesson_booking.should_not be_nil
- lesson_session = LessonSession.where(teacher_id: teacher_user).first
+ lesson_session = LessonSession.where(teacher_id: teacher_user).order(:created_at).last
lesson_session.teacher.should eql teacher_user
- lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id).first
+ lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id, teacher_id: teacher_user.id).order(:created_at).first
lesson_package_purchase.should be_nil
user.reload
user.remaining_test_drives.should eql 0
@@ -151,7 +156,7 @@ describe "Single Lesson", :js => true, :type => :feature, :capybara_feature => t
lesson_session.teacher.should eql teacher_user2
lesson_session2 = lesson_session
- lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id).first
+ lesson_package_purchase = LessonPackagePurchase.where(user_id: user.id, teacher_id: teacher_user.id).order(:created_at).first
lesson_package_purchase.should be_nil
user.reload
user.remaining_test_drives.should eql 0
@@ -167,9 +172,9 @@ describe "Single Lesson", :js => true, :type => :feature, :capybara_feature => t
lesson_session1.analysed.should be_true
analysis = JSON.parse(lesson_session1.analysis)
analysis["reason"].should eql LessonSessionAnalyser::SUCCESS
- lesson_session1.billing_attempts.should be_true
- lesson_session1.billed.should eql true
lesson_session1.success.should be_true
+ lesson_session1.billing_attempts.should eql 1
+ lesson_session1.billed.should eql true
LessonBooking.hourly_check
diff --git a/web/spec/features/book_test_drive_spec.rb b/web/spec/features/book_test_drive_spec.rb
index 2dd9906fb..2082a5842 100644
--- a/web/spec/features/book_test_drive_spec.rb
+++ b/web/spec/features/book_test_drive_spec.rb
@@ -37,18 +37,20 @@ describe "Test Drive", :js => true, :type => :feature, :capybara_feature => true
find('.teacher-search-result[data-teacher-id="' + teacher_user.id + '"] .try-test-drive').trigger(:click)
+ # no longer true
# TryTestDriveDialog shows
- find('.purchase-testdrive-now').trigger(:click)
+ #find('.purchase-testdrive-now').trigger(:click)
- fill_in 'card-number', with: '4111111111111111'
- fill_in 'expiration', with: '11/2016'
- fill_in 'cvv', with: '111'
- fill_in 'zip', with: '78759'
+ select_test_drive(4)
- find('.purchase-btn').trigger(:click)
+ fill_out_single_lesson
+
+ fill_out_payment
# we tell user they have test drive purchased, and take them to the teacher screen
find('#banner h1', text: 'Test Drive Purchased')
+ find('#banner .dialog-inner', text: "You have purchased #{4} TestDrive credits and have used 1 credit it to request a JamClass with #{teacher_user.name}")
+
# dismiss banner
find('a.button-orange', text:'CLOSE').trigger(:click)
@@ -58,35 +60,12 @@ describe "Test Drive", :js => true, :type => :feature, :capybara_feature => true
lesson_package_purchase.lesson_package_type.is_test_drive?.should be_true
lesson_package_purchase.lesson_payment_charge.should_not be_nil
user.reload
- user.remaining_test_drives.should eql 4
+ user.remaining_test_drives.should eql 3
#lesson_package_purchase.amount_charged.should eql 49.99
user.sales.count.should eql 1
sale = user.sales.first
sale.recurly_total_in_cents.should eql 5411
- # the spec says take them back to search; there is some wasted effort here by the student; they have to click the teacher 2x. Ok?
- find('.teacher-search-result[data-teacher-id="' + teacher_user.id + '"] .try-test-drive').trigger(:click)
-
- find('h2', text: 'book testdrive lesson')
- find('.booking-info', text: '4 TestDrive lesson credits')
-
- # book the lesson
- fill_in "slot-1-date", with: "Sun Apr 17 2016"
- #find('.slot.slot-1 input.hasDatepicker').trigger(:click)
- # click 4-6
- find('td a', text: '17').trigger(:click)
-
- #find('.slot.slot-2 input.hasDatepicker').trigger(:click)
- # click 4-7
- fill_in "slot-2-date", with: "Mon Apr 18 2016"
- find('td a', text: '18').trigger(:click)
-
- fill_in 'user-description', with: 'abc def dog neck'
-
- sleep 3
-
-
- find('a.book-lesson-btn', text: 'BOOK TESTDRIVE LESSON').trigger(:click)
find('h2', text: 'my lessons')
@@ -112,8 +91,6 @@ describe "Test Drive", :js => true, :type => :feature, :capybara_feature => true
find('h2', text: 'book testdrive lesson')
find('.booking-info', text: '3 TestDrive lesson credits')
- # dismiss banner
- find('a.button-orange', text:'CLOSE').trigger(:click)
# approve by teacher:
teacher_approve(lesson_session1)
diff --git a/web/spec/support/lessons.rb b/web/spec/support/lessons.rb
index ce0d4e9ac..375b93b40 100644
--- a/web/spec/support/lessons.rb
+++ b/web/spec/support/lessons.rb
@@ -28,4 +28,90 @@ def teacher_approve(lesson_session)
find('.schedule.button-orange').trigger(:click)
visit "/client#/jamclass"
find('tr[data-lesson-session-id="' + lesson_session.id + '"] .displayStatusColumn', text: 'Scheduled')
-end
\ No newline at end of file
+end
+
+def fill_out_single_lesson
+
+ find('h2', text: 'book testdrive lesson')
+ find('.booking-info', text: 'If you need to cancel')
+
+ # book the lesson
+ fill_in "slot-1-date", with: "Sun Apr 17 2016"
+ #find('.slot.slot-1 input.hasDatepicker').trigger(:click)
+ # click 4-6
+ find('td a', text: '17').trigger(:click)
+
+ #find('.slot.slot-2 input.hasDatepicker').trigger(:click)
+ # click 4-7
+ fill_in "slot-2-date", with: "Mon Apr 18 2016"
+ find('td a', text: '18').trigger(:click)
+
+ fill_in 'user-description', with: 'abc def dog neck'
+
+ sleep 3
+
+
+ find('a.book-lesson-btn', text: 'BOOK TESTDRIVE LESSON').trigger(:click)
+
+end
+
+def fill_out_payment
+
+ fill_in 'card-number', with: '4111111111111111'
+ fill_in 'expiration', with: '11/2016'
+ fill_in 'cvv', with: '111'
+ fill_in 'zip', with: '78759'
+
+ find('.purchase-btn').trigger(:click)
+end
+
+def select_test_drive(count = 4)
+ find(".button-orange.select-#{count}").trigger(:click)
+end
+
+def create_stripe_token(exp_month = 2017)
+ Stripe::Token.create(
+ :card => {
+ :number => "4111111111111111",
+ :exp_month => 2,
+ :exp_year => exp_month,
+ :cvc => "314"
+ },
+ ).id
+end
+
+
+def testdrive_lesson(user, teacher, slots = nil)
+
+ if slots.nil?
+ slots = []
+ slots << FactoryGirl.build(:lesson_booking_slot_single)
+ slots << FactoryGirl.build(:lesson_booking_slot_single)
+ end
+
+ if !user.stored_credit_card
+ token = create_stripe_token
+ user.payment_update({token: token, zip: '78759'})
+ user.save!
+ user.stored_credit_card.should be_true
+ end
+
+
+ booking = LessonBooking.book_test_drive(user, teacher, slots, "Hey I've heard of you before.")
+ #puts "BOOKING #{booking.errors.inspect}"
+ booking.errors.any?.should be_false
+ lesson = booking.lesson_sessions[0]
+ booking.card_presumed_ok.should be_true
+
+ if user.most_recent_test_drive_purchase.nil?
+ LessonPackagePurchase.create(user, booking, LessonPackageType.test_drive_4)
+ end
+
+ lesson.accept({message: 'Yeah I got this', slot: slots[0]})
+ lesson.errors.any?.should be_false
+ lesson.reload
+ lesson.slot.should eql slots[0]
+ lesson.status.should eql LessonSession::STATUS_APPROVED
+
+ lesson
+end