1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
RSpec.describe Calendar, :type => :model do
it { should belong_to(:organisation) }
it { is_expected.to validate_presence_of(:organisation) }
it { is_expected.to validate_presence_of(:name) }
describe '#to_time_table' do
let(:calendar) { create(:calendar, int_day_types: Calendar::MONDAY | Calendar::SUNDAY, date_ranges: [Date.today...(Date.today + 1.month)]) }
it 'should convert calendar to an instance of Chouette::TimeTable' do
time_table = calendar.convert_to_time_table
expect(time_table).to be_an_instance_of(Chouette::TimeTable)
expect(time_table.int_day_types).to eq calendar.int_day_types
expect(time_table.periods[0].period_start).to eq(calendar.periods[0].begin)
expect(time_table.periods[0].period_end).to eq(calendar.periods[0].end)
expect(time_table.dates.map(&:date)).to match_array(calendar.dates)
end
end
describe 'application days' do
let(:calendar) { create(:calendar) }
it "should default to all days" do
%w(monday tuesday wednesday thursday friday saturday sunday).each do |day|
expect(calendar.send(day)).to be_truthy
end
end
end
describe 'validations' do
it 'validates that dates and date_ranges do not overlap' do
expect(build(:calendar, dates: [Date.today.beginning_of_week], date_ranges: [Date.today.beginning_of_week..Date.today])).to_not be_valid
end
it 'validates that dates and date_ranges do not overlap but allow for days not in the list' do
expect(build(:calendar, dates: [Date.today.beginning_of_week - 1.week], date_ranges: [(Date.today.beginning_of_week - 1.week)..Date.today], int_day_types: Calendar::THURSDAY)).to be_valid
end
it 'validates that there are no duplicates in dates' do
expect(build(:calendar, dates: [Date.yesterday, Date.yesterday], date_ranges: [Date.today..Date.tomorrow])).to_not be_valid
end
end
describe 'before_validation' do
let(:calendar) { create(:calendar, date_ranges: []) }
it 'shoud fill date_ranges with date ranges' do
expected_range = Date.today..Date.tomorrow
calendar.date_ranges << expected_range
calendar.valid?
expect(calendar.date_ranges.map { |period| period.begin..period.end }).to eq([expected_range])
end
end
describe "Update state" do
def calendar_to_state calendar
calendar.slice('id').tap do |item|
item['comment'] = calendar.name
item['day_types'] = "Di,Lu,Ma,Me,Je,Ve,Sa"
item['current_month'] = calendar.month_inspect(Date.today.beginning_of_month)
item['current_periode_range'] = Date.today.beginning_of_month.to_s
item['time_table_periods'] = calendar.periods.map{|p| {'id': p.id, 'period_start': p.period_start.to_s, 'period_end': p.period_end.to_s}}
end
end
subject(:calendar){ create :calendar }
let(:state) { calendar_to_state subject }
it 'should update time table periods association' do
period = state['time_table_periods'].first
period['period_start'] = (Date.today - 1.month).to_s
period['period_end'] = (Date.today + 1.month).to_s
subject.state_update_periods state['time_table_periods']
['period_end', 'period_start'].each do |prop|
expect(subject.reload.periods.first.send(prop).to_s).to eq(period[prop])
end
end
it 'should create time table periods association' do
state['time_table_periods'] << {
'id' => false,
'period_start' => (Date.today + 1.year).to_s,
'period_end' => (Date.today + 2.year).to_s
}
expect {
subject.state_update_periods state['time_table_periods']
}.to change {subject.periods.count}.by(1)
expect(state['time_table_periods'].last['id']).to eq subject.reload.periods.last.id
end
it 'should delete time table periods association' do
state['time_table_periods'].first['deleted'] = true
expect {
subject.state_update_periods state['time_table_periods']
}.to change {subject.periods.count}.by(-1)
end
it 'should update name' do
state['comment'] = "Edited timetable name"
subject.state_update state
expect(subject.reload.name).to eq state['comment']
end
it 'should update day_types' do
state['day_types'] = "Di,Lu,Je,Ma"
subject.state_update state
expect(subject.reload.valid_days).to include(7, 1, 4, 2)
expect(subject.reload.valid_days).not_to include(3, 5, 6)
end
it 'should delete date if date is set to neither include or excluded date' do
updated = state['current_month'].map do |day|
day['include_date'] = false if day['include_date']
end
expect {
subject.state_update state
}.to change {subject.dates.count}.by(-updated.compact.count)
end
it 'should update date if date is set to excluded date' do
updated = state['current_month'].map do |day|
next unless day['include_date']
day['include_date'] = false
day['excluded_date'] = true
end
subject.state_update state
expect(subject.reload.excluded_days.count).to eq (updated.compact.count)
end
it 'should create new include date' do
day = state['current_month'].find{|d| !d['excluded_date'] && !d['include_date'] }
date = Date.parse(day['date'])
day['include_date'] = true
expect(subject.included_days).not_to include(date)
expect {
subject.state_update state
}.to change {subject.dates.count}.by(1)
expect(subject.reload.included_days).to include(date)
end
it 'should create new exclude date' do
day = state['current_month'].find{|d| !d['excluded_date'] && !d['include_date']}
date = Date.parse(day['date'])
day['excluded_date'] = true
expect(subject.excluded_days).not_to include(date)
expect {
subject.state_update state
}.to change {subject.all_dates.count}.by(1)
expect(subject.reload.excluded_days).to include(date)
end
end
end
|