Skip to content

Instantly share code, notes, and snippets.

@mrgenixus
Last active September 18, 2015 19:10
Show Gist options
  • Select an option

  • Save mrgenixus/08e36b254cfd3d7f8cbe to your computer and use it in GitHub Desktop.

Select an option

Save mrgenixus/08e36b254cfd3d7f8cbe to your computer and use it in GitHub Desktop.
Refactor Booking Page
module BookingFeatureHelpers
def fill_in_booking_attributes inputs = {}
attrs = booking_attributes.merge user_attributes
attrs.merge! inputs
attrs = attrs.with_indifferent_access
[:name, :email, :phone_number, :number_of_people].each do |field|
if attrs[field].present?
find("[name*=#{field.to_s}]").set attrs[field]
end
end
if attrs['stripe_token'].present?
first("[name=\"booking[stripe_token]\"]", visible: false).set attrs['stripe_token']
end
choose attrs[:contact_method].to_s.humanize
end
def make_booking success=true
unless first("[name=\"booking[stripe_token]\"]", visible: false).value.nil?
raise "You must mock stripe" unless StripeMock.state == 'local'
end
click_on "Make Booking"
if success
expect(page).to have_content "Booking REQUEST made successfully"
else
expect(page).not_to have_content "Booking REQUEST made successfully"
end
end
def select_tour hotel, tour
HotelTour.find_or_create_by(hotel: hotel, tour: tour)
visit public_hotel_tours_path(hotel)
expect(page).to have_content tour.name
within(:xpath, "//div[h4[a[contains(.,'#{tour.name}')]]]") do
click_on tour.name
end
expect(page).to have_content "Book #{tour.name.titleize}"
end
def confirm_booking booking, confirmation_scope=nil
click_on "Logout"
visit new_booking_confirmations_path(booking, confirmation_scope||:tour_company, :confirmation)
sign_in_immediately
click_on "Confirm"
expect(page).to have_content "Booking successfully confirmed for #{confirmation_scope.to_s.gsub('_', ' ') || 'tour_company'}"
end
def decline_booking booking, confirmation_scope=nil
click_on "Logout"
visit new_booking_confirmations_path(booking, confirmation_scope||:tour_company, :rejection)
sign_in_immediately
click_on "Decline"
expect(page).to have_content "Booking successfully declined for #{confirmation_scope.to_s.gsub('_', ' ') || 'tour_company'}"
end
module ClassMethods
def define_booking_attributes *args, &block
let(:booking_attributes) { attributes_for :booking, *args }
let(:user_attributes) do
if current_user
current_user.as_json.with_indifferent_access
else
attributes_for :user
end
end
if block_given?
before do
block.call *([booking_attributes, user_attributes].slice block.arity)
end
end
end
end
def self.included(base)
base.extend(ClassMethods)
end
end
module BasicPage
attr_accessor :page
delegate :choose, :fill_in, :click_on, to: :page
def initialize page, options={}
@page = page
end
def fields= attributes={}
attributes.slice(*@page_fields).each_with_index do |key, value|
self.send("#{key}=", value)
end
end
def self.included subject
subject.extend ClassMethods
subject.define_instance_variable :page_fields, []
end
module ClassMethods
protected
#factory-generated method_factory method
make_field_method_method :radio_button do |name|
select_radio_button name
end
#method_factory factories
def make_field_method_method name, &block
define_method "#{name}_method" do |name|
@page_fields << name
define_method :name, &block
end
end
# method factories
def text_field_method name
@page_fields << name
define_method "#{name}=" do |value|
fill_text_field name, value
end
end
def text_field_methods *names
names.each(&method(:text_field_method))
end
def hidden_field_method name
@page_fields << name
define_method name do |value|
fill_hidden_field name, value
end
end
def submit_button label
define_method :submit! do
yield if block_given?
click_on label
end
end
# delegate methods
def fill_hidden_field key, value
first("[name=\"booking[#{key}]\"]", visible: false).set value
end
def select_radio_button key, value
choose value.to_s.humanize
end
def fill_text_field key, value
find("[name*=#{key.to_s}]").set value
end
end
end
class BookingPage
include BasicPage
def initialize (page, options={})
super
HotelTour.find_or_create_by(options)
visit new_booking_path(options.values_at(:hotel, :tour))
end
text_field_methods :name, :phone_number, :number_of_people, :email
radio_button_method :contact_method
hidden_field_method :stripe_token
submit_button "Make Booking" do
unless first("[name=\"booking[stripe_token]\"]", visible: false).value.nil?
raise "You must mock stripe" unless StripeMock.state == 'local'
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment