Skip to content

Instantly share code, notes, and snippets.

@luizhpcamargo
Last active February 21, 2018 17:28
Show Gist options
  • Save luizhpcamargo/ca6c9523a5021569dcfa5a4bb64630a9 to your computer and use it in GitHub Desktop.
Save luizhpcamargo/ca6c9523a5021569dcfa5a4bb64630a9 to your computer and use it in GitHub Desktop.
Event test
class Event < ApplicationRecord
TIME_STEP = 30.minutes
scope :openings, -> {where(kind: :opening)}
scope :appointments, -> {where(kind: :appointment)}
scope :filter_by_date, ->(beginning_date, end_date){where(starts_at: beginning_date..end_date)}
scope :weekly_events, -> {where(weekly_recurring: true)}
class << self
def availabilities(date = Date.today)
first_day = date.beginning_of_day
last_day = (date + 6.days).end_of_day
only_possible_openings(first_day, last_day)
end
def only_possible_openings(first_day, last_day)
opening_results = get_weekly_results(first_day,last_day)
appointements_results = slots_group(appointments.filter_by_date(first_day, last_day).to_a)
results = []
(first_day.to_i..last_day.to_i).step(1.day) do |date|
date = Time.zone.at(date).to_date
hash = {date: date, slots: opening_results[date] || []}
hash[:slots] -= appointements_results[date] if appointements_results[date].present?
results << hash
end
results
end
def get_weekly_results(first_day, last_day)
opening_results = openings.filter_by_date(first_day, last_day).to_a
Event.openings.weekly_events.where("starts_at < ?", first_day).each do |event|
number_of = ((first_day.to_f - event.starts_at.to_f)/1.week).ceil
weeks = number_of.weeks
opening_results << Event.new(starts_at: event.starts_at + weeks, ends_at: event.ends_at + weeks, kind: :opening) if number_of >= 1
end
slots_group(opening_results)
end
def slots_group(relation)
return {} if relation.empty?
slots_hash = {}
relation.select! do |event|
date = event.starts_at.to_date
slots_hash[date] ||= []
(event.starts_at.to_i..event.ends_at.to_i).step(TIME_STEP) do |date_time|
slots_hash[date] << Time.zone.at(date_time).strftime('%k:%M').strip
end
slots_hash[date].pop
end
slots_hash
end
end
end
require 'test_helper'
describe Event do
it "one simple test example" do
Event.create kind: 'opening', starts_at: DateTime.parse("2014-08-04 09:30"), ends_at: DateTime.parse("2014-08-04 12:30"), weekly_recurring: true
Event.create kind: 'appointment', starts_at: DateTime.parse("2014-08-11 10:30"), ends_at: DateTime.parse("2014-08-11 11:30")
availabilities = Event.availabilities DateTime.parse("2014-08-10")
assert_equal Date.new(2014, 8, 10), availabilities[0][:date]
assert_equal [], availabilities[0][:slots]
assert_equal Date.new(2014, 8, 11), availabilities[1][:date]
assert_equal ["9:30", "10:00", "11:30", "12:00"], availabilities[1][:slots]
assert_equal Date.new(2014, 8, 16), availabilities[6][:date]
assert_equal 7, availabilities.length
end
describe 'calls' do
before do
Event.create kind: :opening, starts_at: '2018-02-21 09:00', ends_at: '2018-02-21 12:30', weekly_recurring: true
Event.create kind: :opening, starts_at: '2018-02-22 08:00', ends_at: '2018-02-22 10:30'
Event.create kind: :opening, starts_at: '2018-02-23 08:30', ends_at: '2018-02-23 11:00'
Event.create kind: :appointment, starts_at: '2018-02-21 10:00', ends_at: '2018-02-21 10:30'
Event.create kind: :appointment, starts_at: '2018-02-22 09:00', ends_at: '2018-02-22 09:30'
Event.create kind: :appointment, starts_at: '2018-02-23 12:00', ends_at: '2018-02-23 13:00'
end
describe 'scopes' do
it '#openings' do
assert_equal 3, Event.openings.size
assert_equal 2, Event.openings.filter_by_date('2018-02-21 00:00', '2018-02-22 23:59').size
end
it '#appointments' do
assert_equal 3, Event.appointments.size
assert_equal 2, Event.appointments.filter_by_date('2018-02-22 00:00', '2018-02-23 23:59').size
end
it '#filter_by_date' do
assert_equal 4, Event.filter_by_date('2018-02-22 00:00', '2018-02-23 23:59').size
end
end
describe '#slots_group' do
it "right format" do
relation = Event.openings.filter_by_date('2018-02-21 00:00', '2018-02-21 23:59').to_a
assert_equal ["9:00", "9:30", "10:00", "10:30", "11:00", "11:30", "12:00"], Event.slots_group(relation).first[1]
end
end
describe '#availabilities' do
it do
availabilities = Event.availabilities('2018-02-21 00:00'.to_time)
assert_equal ["9:00", "9:30", "10:30", "11:00", "11:30", "12:00"], availabilities[0][:slots]
assert_equal Date.new(2018, 02, 21), availabilities[0][:date]
end
describe 'with weekly events' do
before do
Event.create kind: :appointment, starts_at: '2018-02-28 10:30', ends_at: '2018-02-28 11:30'
end
it do
availabilities = Event.availabilities('2018-02-27 00:00'.to_time)
assert_equal Date.new(2018, 02, 28), availabilities[1][:date]
assert_equal ["9:00", "9:30", "10:00", "11:30", "12:00"], availabilities[1][:slots]
end
it do
availabilities = Event.availabilities('2018-02-23 00:00'.to_time)
assert_equal Date.new(2018, 02, 28), availabilities[5][:date]
assert_equal ["9:00", "9:30", "10:00", "11:30", "12:00"], availabilities[5][:slots]
assert_equal availabilities.length, 7
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment