ticket_sales 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ class TestRoute < MiniTest::Unit::TestCase
4
+ def setup
5
+ @haskovo_sofia = TicketSales::Route.new 'Haskovo', 'Sofia', 230
6
+ @sofia_ruse = TicketSales::Route.new 'Sofia', 'Ruse', 400
7
+ @haskovo_ruse = TicketSales::Route.new 'Haskovo', 'Ruse', 630, ['Sofia']
8
+ @ruse_sofia = TicketSales::Route.new 'Ruse', 'Sofia', 400
9
+ @burgas_haskovo = TicketSales::Route.new 'Burgas', 'Haskovo', 240
10
+ end
11
+
12
+ # Tests
13
+
14
+ def test_make_a_direct_route
15
+ assert_equal 'Haskovo', @haskovo_sofia.from
16
+ assert_equal 'Sofia', @haskovo_sofia.to
17
+ assert_equal 230, @haskovo_sofia.distance
18
+ end
19
+
20
+ def test_make_a_indirect_route
21
+ assert_equal 'Haskovo', @haskovo_ruse.from
22
+ assert_equal 'Ruse', @haskovo_ruse.to
23
+ assert_equal 630, @haskovo_ruse.distance
24
+ assert @haskovo_ruse.stops.include?('Sofia')
25
+ end
26
+
27
+ def test_routes_can_be_combined
28
+ combined_route = @haskovo_sofia.combine @sofia_ruse
29
+
30
+ assert_equal 'Haskovo', combined_route.from
31
+ assert_equal 'Ruse', combined_route.to
32
+ assert_equal @haskovo_sofia.distance + @sofia_ruse.distance, combined_route.distance
33
+ assert combined_route.stops.include?('Sofia')
34
+ end
35
+
36
+ def test_combine_with_indirect_routes
37
+ combined_route = @burgas_haskovo.combine @haskovo_ruse
38
+
39
+ assert_equal 'Burgas', combined_route.from
40
+ assert_equal 'Ruse', combined_route.to
41
+ assert_equal @burgas_haskovo.distance + @haskovo_ruse.distance, combined_route.distance
42
+ assert ['Haskovo', 'Sofia'].all? { |stop| combined_route.stops.include?(stop) }
43
+ end
44
+
45
+ def test_combine_doesnt_work_with_incorrect_routes
46
+ assert_raises(RuntimeError) { @haskovo_sofia.combine @ruse_sofia }
47
+ assert_raises(RuntimeError) { @burgas_haskovo.combine @sofia_ruse }
48
+ assert_raises(RuntimeError) { @haskovo_ruse.combine @burgas_haskovo }
49
+ end
50
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+
3
+ class TestTicket < MiniTest::Unit::TestCase
4
+ def setup
5
+ @haskovo_sofia = TicketSales::Ticket.build 'Haskovo', 'Sofia', 230,Time.new(2013, 3, 3, 15),
6
+ Time.new(2013, 3, 3, 18), '20'.to_d, 'fast, class A, cheap'
7
+ @sofia_ruse = TicketSales::Ticket.build 'Sofia', 'Ruse', 400,Time.new(2013, 3, 3, 19),
8
+ Time.new(2013,3,4), '25'.to_d, 'long'
9
+ @ruse_burgas = TicketSales::Ticket.build 'Ruse', 'Burgas', 500, Time.new(2013, 3, 4, 5),
10
+ Time.new(2013, 3, 4, 13), '35'.to_d, ''
11
+ @burgas_moscow = TicketSales::Ticket.build 'Burgas', 'Moscow', 1900, Time.new(2013, 3, 4, 20),
12
+ Time.new(2013, 3, 4, 22), '120'.to_d, 'airplane'
13
+ end
14
+
15
+ # Tests
16
+
17
+ def test_ticket_build
18
+ london_moscow = TicketSales::Ticket.build 'London', 'Moscow', 1900, Time.new(2013, 3, 4, 20),
19
+ Time.new(2013, 3, 4, 22), '100'.to_d, 'airplane'
20
+
21
+ assert_equal 'London', london_moscow.from
22
+ assert_equal 'Moscow', london_moscow.to
23
+ assert_equal '100'.to_d, london_moscow.price
24
+ assert_equal 'airplane', london_moscow.features
25
+ assert_equal Time.new(2013, 3, 4, 20), london_moscow.departure_time
26
+ assert_equal Time.new(2013, 3, 4, 22), london_moscow.arrival_time
27
+ assert_equal '2'.to_d, london_moscow.travel_length
28
+ assert_equal 1900, london_moscow.distance
29
+ end
30
+
31
+ def test_combine_ticket
32
+ combined_ticket = @haskovo_sofia.combine @sofia_ruse
33
+
34
+ assert_equal @haskovo_sofia.from, combined_ticket.from
35
+ assert_equal @sofia_ruse.to, combined_ticket.to
36
+ assert_equal @haskovo_sofia.price + @sofia_ruse.price, combined_ticket.price
37
+ assert_equal @haskovo_sofia.features + ', ' + @sofia_ruse.features, combined_ticket.features
38
+ assert_equal @haskovo_sofia.departure_time, combined_ticket.departure_time
39
+ assert_equal @sofia_ruse.arrival_time, combined_ticket.arrival_time
40
+ assert_equal (@sofia_ruse.arrival_time - @haskovo_sofia.departure_time).to_d / 3600,
41
+ combined_ticket.travel_length
42
+
43
+ another = combined_ticket.combine @ruse_burgas
44
+
45
+ assert_equal @haskovo_sofia.from, another.from
46
+ assert_equal @ruse_burgas.to, another.to
47
+ assert_equal combined_ticket.price + @ruse_burgas.price, another.price
48
+ assert_equal combined_ticket.features + ', ' + @ruse_burgas.features, another.features
49
+ assert_equal @haskovo_sofia.departure_time, another.departure_time
50
+ assert_equal @ruse_burgas.arrival_time, another.arrival_time
51
+ assert_equal '22'.to_d, another.travel_length
52
+ end
53
+
54
+ def test_ticket_equality
55
+ assert @haskovo_sofia == TicketSales::Ticket.build('Haskovo', 'Sofia', 230,Time.new(2013, 3, 3, 15),
56
+ Time.new(2013, 3, 3, 18), '20'.to_d, 'fast, class A, cheap')
57
+ assert @sofia_ruse == TicketSales::Ticket.build('Sofia', 'Ruse', 400,Time.new(2013, 3, 3, 19),
58
+ Time.new(2013,3,4), '25'.to_d, 'long')
59
+ refute @ruse_burgas == TicketSales::Ticket.build('Ruse', 'Burgas', 500, Time.new(2013, 3, 4, 5),
60
+ Time.new(2013, 3, 4, 13), '37'.to_d, '')
61
+ end
62
+ end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class TestTravelTime < MiniTest::Unit::TestCase
4
+ def get_travel_time(departure, arrival)
5
+ TicketSales::TravelTime.new departure, arrival
6
+ end
7
+
8
+ # Tests
9
+
10
+ def test_time_interval
11
+ time = TicketSales::TimeInterval.new Time.new(2013, 1, 1, 14), Time.new(2013, 1, 1, 15)
12
+
13
+ assert_equal Time.new(2013, 1, 1, 14), time.start_time
14
+ assert_equal Time.new(2013, 1, 1, 15), time.end_time
15
+ assert_equal '1'.to_d, time.length
16
+ end
17
+
18
+ def test_time_interval_equality
19
+ a_hour = TicketSales::TimeInterval.new Time.new(2013, 1, 1, 14), Time.new(2013, 1, 1, 15)
20
+ equal_hour = TicketSales::TimeInterval.new Time.new(2013, 1, 1, 14), Time.new(2013, 1, 1, 15)
21
+
22
+ assert a_hour == equal_hour
23
+ refute a_hour == TicketSales::TimeInterval.new(Time.new(2013, 1, 1, 14), Time.new(2013, 1, 1, 15, 1))
24
+ end
25
+
26
+ def test_travel_time
27
+ travel = get_travel_time Time.new(2013, 1, 1, 14), Time.new(2013, 1, 1, 15)
28
+
29
+ assert_equal Time.new(2013, 1, 1, 14), travel.departure
30
+ assert_equal Time.new(2013, 1, 1, 15), travel.arrival
31
+ assert_equal '1'.to_d, get_travel_time(Time.new(2013, 1, 1, 14), Time.new(2013, 1, 1, 15)).length
32
+ assert_equal '0.5'.to_d, get_travel_time(Time.new(2013, 1, 1, 14), Time.new(2013, 1, 1, 14, 30)).length
33
+ end
34
+
35
+ def test_combined_time
36
+ travel = get_travel_time Time.new(2013, 2, 14, 8), Time.new(2013, 2, 14, 15)
37
+ next_travel = get_travel_time Time.new(2013, 2, 15, 15), Time.new(2013, 2, 15, 16)
38
+ combined = travel.combine next_travel
39
+
40
+ assert_equal travel.departure, combined.departure
41
+ assert_equal next_travel.arrival, combined.arrival
42
+ assert_equal (next_travel.arrival - travel.departure).to_d / 3600, combined.length
43
+ assert_equal '24'.to_d, combined.pauses_length
44
+ assert_equal Time.new(2013, 2, 14, 15), combined.pauses.first.start_time
45
+ assert_equal Time.new(2013, 2, 15, 15), combined.pauses.first.end_time
46
+ end
47
+
48
+ def test_travel_time_equality
49
+ travel = get_travel_time Time.new(2013, 2, 14, 8), Time.new(2013, 2, 14, 15)
50
+ second_travel = get_travel_time Time.new(2013, 2, 15, 15), Time.new(2013, 2, 15, 16)
51
+ third_travel = get_travel_time Time.new(2013, 2, 15, 17), Time.new(2013, 2, 15, 19)
52
+ combined = travel.combine(second_travel).combine(third_travel)
53
+ same_combined = travel.combine(second_travel.combine third_travel)
54
+
55
+ assert_equal combined, same_combined
56
+ end
57
+ end
@@ -0,0 +1,219 @@
1
+ require 'test_helper'
2
+
3
+ class TestTicketProperty < MiniTest::Unit::TestCase
4
+ def setup
5
+ @property = TicketSales::TicketProperty.new 12, TicketSales::Promotion::NoPromotion.new
6
+ @another_property = TicketSales::TicketProperty.new 10, TicketSales::Promotion.build(percent: 10)
7
+ end
8
+
9
+ def test_properties_can_be_accessed
10
+ assert_equal 12, @property.count
11
+ assert_kind_of TicketSales::Promotion::NoPromotion, @property.promotion
12
+ assert_equal 0, @property.bought_count
13
+
14
+ assert_equal 10, @another_property.count
15
+ assert_kind_of TicketSales::Promotion::PercentOff, @another_property.promotion
16
+ assert_equal 0, @property.bought_count
17
+ end
18
+
19
+ def test_decreasing_count_of_property
20
+ @property.decrease_count 5
21
+ assert_equal 7, @property.count
22
+ assert_equal 5, @property.bought_count
23
+ @property.decrease_count 5
24
+ assert_equal 10, @property.bought_count
25
+
26
+ @another_property.decrease_count 7
27
+ assert_equal 3, @another_property.count
28
+ assert_equal 7, @another_property.bought_count
29
+ @another_property.decrease_count 2
30
+ assert_equal 9, @another_property.bought_count
31
+ end
32
+ end
33
+
34
+ class TestTicketCenter < MiniTest::Unit::TestCase
35
+ def setup
36
+ @haskovo_sofia = TicketSales::Ticket.build 'Haskovo', 'Sofia', 230, Time.new(2013, 3, 3, 15),
37
+ Time.new(2013, 3, 3, 18), '15'.to_d, 'fast, class A, cheap'
38
+ @sofia_ruse = TicketSales::Ticket.build 'Sofia', 'Ruse', 400, Time.new(2013, 3, 3, 19),
39
+ Time.new(2013, 3, 4), '15'.to_d, 'long'
40
+ @ruse_burgas = TicketSales::Ticket.build 'Ruse', 'Burgas', 500, Time.new(2013, 3, 4, 5),
41
+ Time.new(2013, 3, 4, 13), '35'.to_d, ''
42
+ @user = TicketSales::User.new 'user', 'user@gmail.com', '50000'.to_d
43
+ @ticket_center = TicketSales::TicketCenter.new
44
+ end
45
+
46
+ # Tests
47
+
48
+ def test_adding_tickets
49
+ @ticket_center.add @haskovo_sofia
50
+ @ticket_center.add @sofia_ruse, 2
51
+ @ticket_center.add @ruse_burgas, 30, TicketSales::Promotion::build(amount: 10)
52
+ end
53
+
54
+ def test_available
55
+ @ticket_center.add @haskovo_sofia, 20
56
+
57
+ assert @ticket_center.available? @haskovo_sofia
58
+ refute @ticket_center.available? @ruse_burgas
59
+ refute @ticket_center.available? @sofia_ruse
60
+ end
61
+
62
+ def test_available_with_more_complex_tickets
63
+ @ticket_center.add @haskovo_sofia, 20
64
+ @ticket_center.add @ruse_burgas, 50, TicketSales::Promotion.build(percent: 10)
65
+ @ticket_center.add @sofia_ruse, 33
66
+
67
+ assert @ticket_center.available? @haskovo_sofia
68
+ assert @ticket_center.available? @ruse_burgas
69
+ assert @ticket_center.available? @sofia_ruse.combine(@ruse_burgas)
70
+ assert @ticket_center.available? @haskovo_sofia.combine(@sofia_ruse)
71
+ assert @ticket_center.available? @haskovo_sofia.combine(@sofia_ruse).combine(@ruse_burgas)
72
+ end
73
+
74
+ def test_available_working_correct_for_any_count
75
+ @ticket_center.add @haskovo_sofia, 20
76
+ @ticket_center.add @ruse_burgas, 50
77
+ @ticket_center.add @sofia_ruse, 33
78
+
79
+ assert @ticket_center.available? @haskovo_sofia, 3
80
+ assert @ticket_center.available? @haskovo_sofia, 19
81
+ assert @ticket_center.available? @haskovo_sofia, 20
82
+ refute @ticket_center.available? @haskovo_sofia, 21
83
+
84
+ assert @ticket_center.available? @sofia_ruse, 33
85
+ refute @ticket_center.available? @sofia_ruse, 34
86
+
87
+ assert @ticket_center.available? @ruse_burgas, 45
88
+ refute @ticket_center.available? @ruse_burgas, 51
89
+
90
+ haskovo_ruse = @haskovo_sofia.combine @sofia_ruse
91
+ assert @ticket_center.available? haskovo_ruse, 3
92
+ assert @ticket_center.available? haskovo_ruse, 19
93
+ assert @ticket_center.available? haskovo_ruse, 20
94
+ refute @ticket_center.available? haskovo_ruse, 21
95
+ refute @ticket_center.available? haskovo_ruse, 30
96
+
97
+ haskovo_burgas = haskovo_ruse.combine @ruse_burgas
98
+ assert @ticket_center.available? haskovo_burgas, 3
99
+ assert @ticket_center.available? haskovo_burgas, 19
100
+ assert @ticket_center.available? haskovo_burgas, 20
101
+ refute @ticket_center.available? haskovo_burgas, 21
102
+ refute @ticket_center.available? haskovo_burgas, 30
103
+
104
+ sofia_burgas = @sofia_ruse.combine @ruse_burgas
105
+ assert @ticket_center.available? @sofia_ruse, 33
106
+ refute @ticket_center.available? @sofia_ruse, 34
107
+ refute @ticket_center.available? @sofia_ruse, 45
108
+ end
109
+
110
+ def test_selling_tickets
111
+ @ticket_center.add @haskovo_sofia, 20
112
+ @ticket_center.add @ruse_burgas, 50
113
+
114
+ @ticket_center.sell @user, @ruse_burgas
115
+ @ticket_center.sell @user, @haskovo_sofia, 2
116
+ end
117
+
118
+ def test_selling_tickets_decreases_counts
119
+ @ticket_center.add @haskovo_sofia, 20
120
+ @ticket_center.add @ruse_burgas, 50
121
+ @ticket_center.add @sofia_ruse, 33
122
+
123
+ @ticket_center.sell @user, @ruse_burgas, 25
124
+ refute @ticket_center.available? @ruse_burgas, 26
125
+
126
+ @ticket_center.sell @user, @haskovo_sofia, 5
127
+ refute @ticket_center.available? @haskovo_sofia, 16
128
+ assert @ticket_center.available? @haskovo_sofia, 15
129
+
130
+ @ticket_center.sell @user, @sofia_ruse, 10
131
+ refute @ticket_center.available? @sofia_ruse, 24
132
+ assert @ticket_center.available? @sofia_ruse, 23
133
+ end
134
+
135
+ def test_selling_a_combined_ticket_decreases_counts
136
+ @ticket_center.add @haskovo_sofia, 20
137
+ @ticket_center.add @sofia_ruse, 33
138
+ @ticket_center.add @ruse_burgas, 50
139
+
140
+ haskovo_ruse = @haskovo_sofia.combine @sofia_ruse
141
+ @ticket_center.sell @user, haskovo_ruse, 5
142
+ refute @ticket_center.available? @haskovo_sofia, 16
143
+ assert @ticket_center.available? @haskovo_sofia, 15
144
+ refute @ticket_center.available? @sofia_ruse, 29
145
+ assert @ticket_center.available? @sofia_ruse, 28
146
+
147
+ haskovo_burgas = haskovo_ruse.combine @ruse_burgas
148
+ @ticket_center.sell @user, haskovo_burgas, 10
149
+ refute @ticket_center.available? @haskovo_sofia, 6
150
+ assert @ticket_center.available? @haskovo_sofia, 5
151
+ refute @ticket_center.available? @sofia_ruse, 19
152
+ assert @ticket_center.available? @sofia_ruse, 18
153
+ refute @ticket_center.available? @ruse_burgas, 41
154
+ assert @ticket_center.available? @ruse_burgas, 40
155
+ end
156
+
157
+ def test_sell_working_right_with_tickets_on_promotion
158
+ @ticket_center.add @haskovo_sofia, 20, TicketSales::Promotion.build(amount: 2.5)
159
+ @ticket_center.add @ruse_burgas, 50, TicketSales::Promotion.build(hundred_kilometers: 1)
160
+ @ticket_center.add @sofia_ruse, 33, TicketSales::Promotion.build(percent: 10)
161
+
162
+ balance_before_sale = @user.balance
163
+ @ticket_center.sell @user, @haskovo_sofia, 2
164
+ assert_equal '25'.to_d, balance_before_sale - @user.balance
165
+
166
+ balance_before_sale = @user.balance
167
+ @ticket_center.sell @user, @ruse_burgas
168
+ assert_equal '30'.to_d, balance_before_sale - @user.balance
169
+
170
+ balance_before_sale = @user.balance
171
+ @ticket_center.sell @user, @sofia_ruse
172
+ assert_equal '13.5'.to_d, balance_before_sale - @user.balance
173
+
174
+ balance_before_sale = @user.balance
175
+ @ticket_center.sell @user, @haskovo_sofia.combine(@sofia_ruse)
176
+ assert_equal '26'.to_d, balance_before_sale - @user.balance
177
+
178
+ balance_before_sale = @user.balance
179
+ @ticket_center.sell @user, @sofia_ruse.combine(@ruse_burgas)
180
+ assert_equal '43.5'.to_d, balance_before_sale - @user.balance
181
+
182
+ balance_before_sale = @user.balance
183
+ @ticket_center.sell @user, @haskovo_sofia.combine(@sofia_ruse).combine(@ruse_burgas)
184
+ assert_equal '56'.to_d, balance_before_sale - @user.balance
185
+ end
186
+
187
+ def test_sell_ticket_not_working_with_unavailable_tickets
188
+ @ticket_center.add @haskovo_sofia, 15
189
+
190
+ assert_raises(TicketSales::UnavailableTicket) { @ticket_center.sell @user, @sofia_ruse }
191
+ assert_raises(TicketSales::UnavailableTicket) { @ticket_center.sell @user, @ruse_burgas }
192
+ assert_raises(TicketSales::UnavailableTicket) { @ticket_center.sell @user, @haskovo_sofia, 16 }
193
+
194
+ @ticket_center.add @sofia_ruse, 20
195
+ haskovo_ruse = @haskovo_sofia.combine @sofia_ruse
196
+ assert_raises(TicketSales::UnavailableTicket) { @ticket_center.sell @user, haskovo_ruse, 16 }
197
+
198
+ @ticket_center.sell @user, haskovo_ruse, 10
199
+ assert @ticket_center.available? haskovo_ruse, 5
200
+ assert_raises(TicketSales::UnavailableTicket) { @ticket_center.sell @user, @haskovo_sofia, 6 }
201
+ assert_raises(TicketSales::UnavailableTicket) { @ticket_center.sell @user, haskovo_ruse, 6 }
202
+ end
203
+
204
+ def test_finding_most_bought_tickets
205
+ @ticket_center.add @haskovo_sofia, 20
206
+ @ticket_center.add @sofia_ruse, 25
207
+ @ticket_center.add @ruse_burgas, 30
208
+
209
+ @ticket_center.sell @user, @sofia_ruse, 5
210
+ assert_equal @sofia_ruse, @ticket_center.most_bought_tickets.first
211
+
212
+ @ticket_center.sell @user, @haskovo_sofia, 6
213
+ assert_equal [@haskovo_sofia, @sofia_ruse, @ruse_burgas], @ticket_center.most_bought_tickets
214
+
215
+ haskovo_burgas = @haskovo_sofia.combine(@sofia_ruse).combine @ruse_burgas
216
+ @ticket_center.sell @user, haskovo_burgas, 7
217
+ assert_equal [@haskovo_sofia, @sofia_ruse, @ruse_burgas], @ticket_center.most_bought_tickets
218
+ end
219
+ end
@@ -0,0 +1,150 @@
1
+ require 'test_helper'
2
+
3
+ class TestTicketList < MiniTest::Unit::TestCase
4
+ def setup
5
+ @haskovo_sofia = TicketSales::Ticket.build 'Haskovo', 'Sofia', 230, Time.new(2013, 3, 3, 15),
6
+ Time.new(2013, 3, 3, 18), '15'.to_d, 'fast, class A, cheap'
7
+ @sofia_ruse = TicketSales::Ticket.build 'Sofia', 'Ruse', 400, Time.new(2013, 3, 3, 19),
8
+ Time.new(2013, 3, 4), '15'.to_d, 'long'
9
+ @ruse_burgas = TicketSales::Ticket.build 'Ruse', 'Burgas', 500, Time.new(2013, 3, 4, 5),
10
+ Time.new(2013, 3, 4, 13), '35'.to_d, ''
11
+ @burgas_moscow = TicketSales::Ticket.build 'Burgas', 'Moscow', 1900, Time.new(2013, 3, 4, 20),
12
+ Time.new(2013, 3, 4, 22), '120'.to_d, 'airplane'
13
+ @moscow_kazan = TicketSales::Ticket.build 'Moscow', 'Kazan', 700, Time.new(2013, 3, 5, 8),
14
+ Time.new(2013, 3, 5, 9, 30), '50'.to_d, 'fast'
15
+ @london_sofia = TicketSales::Ticket.build 'London', 'Sofia', 2000, Time.new(2013, 3, 3, 12),
16
+ Time.new(2013, 3, 3, 15), '100'.to_d, ''
17
+ @plovdiv_sofia = TicketSales::Ticket.build 'Plovdiv', 'Sofia', 150, Time.new(2013, 3, 3, 17),
18
+ Time.new(2013, 3, 3, 19, 20), '10'.to_d, ''
19
+ @haskovo_ruse_direct = TicketSales::Ticket.build 'Haskovo', 'Ruse', 500, Time.new(2013, 3, 3, 15),
20
+ Time.new(2013, 3, 3, 22), '35'.to_d, ''
21
+ @list = TicketSales::TicketList.new
22
+ end
23
+
24
+ # Tests
25
+
26
+ def test_enumerable
27
+ assert [:map, :select, :inject, :all?, :any?, :include?].all? { |m| @list.respond_to? m }
28
+ end
29
+
30
+ def test_add_for_single_ticket
31
+ @list.add @haskovo_sofia
32
+ @list.add @ruse_burgas
33
+
34
+ assert_includes @list, @haskovo_sofia
35
+ assert_includes @list, @ruse_burgas
36
+ refute_includes @list, @sofia_ruse
37
+ end
38
+
39
+ def test_ticket_filter
40
+ @list.add @haskovo_sofia
41
+ @list.add @ruse_burgas
42
+
43
+ filtered_tickets = @list.filter(TicketSales::Criteria.from('Haskovo'))
44
+ assert filtered_tickets.all? { |ticket| ticket.from == 'Haskovo' }
45
+ end
46
+
47
+ def test_tickets_arriving_at_location_before_time
48
+ @list.add @haskovo_sofia
49
+ @list.add @plovdiv_sofia
50
+
51
+ assert_includes @list.tickets_arriving_at('Sofia', Time.new(2013, 3, 3, 18, 30)), @haskovo_sofia
52
+ refute_includes @list.tickets_arriving_at('Sofia', Time.new(2013, 3, 3, 18, 30)), @plovdiv_sofia
53
+ end
54
+
55
+ def test_tickets_departing_from_location_after_time
56
+ @list.add @haskovo_sofia
57
+ @list.add @haskovo_ruse_direct
58
+
59
+ assert_includes @list.tickets_departing_from('Haskovo', Time.new(2013, 3, 3, 14, 59)), @haskovo_sofia
60
+ assert_includes @list.tickets_departing_from('Haskovo', Time.new(2013, 3, 3, 14, 59)), @haskovo_ruse_direct
61
+ refute_includes @list.tickets_departing_from('Haskovo', Time.new(2013, 3, 3, 15, 01)), @haskovo_sofia
62
+ refute_includes @list.tickets_departing_from('Haskovo', Time.new(2013, 3, 3, 15, 01)), @haskovo_ruse_direct
63
+ end
64
+
65
+ def test_add_combines_routes
66
+ @list.add @haskovo_sofia
67
+ @list.add @sofia_ruse
68
+ haskovo_ruse = @haskovo_sofia.combine @sofia_ruse
69
+
70
+ assert_includes @list, haskovo_ruse
71
+ assert_equal 3, @list.tickets.size
72
+
73
+ @list.add @ruse_burgas
74
+ haskovo_burgas = @haskovo_sofia.combine(@sofia_ruse).combine @ruse_burgas
75
+ sofia_burgas = @sofia_ruse.combine @ruse_burgas
76
+
77
+ assert_includes @list, haskovo_burgas
78
+ assert_includes @list, sofia_burgas
79
+ assert_equal 6, @list.tickets.size
80
+
81
+ @list.add @moscow_kazan
82
+ @list.add @burgas_moscow
83
+
84
+ burgas_kazan = @burgas_moscow.combine @moscow_kazan
85
+ assert_includes @list, burgas_kazan
86
+
87
+ ruse_moscow = @ruse_burgas.combine @burgas_moscow
88
+ ruse_kazan = ruse_moscow.combine @moscow_kazan
89
+ assert_includes @list, ruse_moscow
90
+ assert_includes @list, ruse_kazan
91
+
92
+ sofia_moscow = @sofia_ruse.combine ruse_moscow
93
+ sofia_kazan = sofia_moscow.combine @moscow_kazan
94
+ assert_includes @list, sofia_moscow
95
+ assert_includes @list, sofia_kazan
96
+
97
+ haskovo_moscow = haskovo_burgas.combine @burgas_moscow
98
+ haskovo_kazan = haskovo_moscow.combine @moscow_kazan
99
+ assert_includes @list, haskovo_moscow
100
+ assert_includes @list, haskovo_kazan
101
+
102
+ @list.add @london_sofia
103
+ tickets_from_london = @list.filter TicketSales::Criteria.from('London')
104
+ can_be_reached = ['Sofia', 'Ruse', 'Burgas', 'Moscow', 'Kazan'].all? do |location|
105
+ tickets_from_london.map(&:to).include? location
106
+ end
107
+ assert can_be_reached
108
+ end
109
+
110
+ def test_add_not_including_incorrect_tickets
111
+ @list.add @sofia_ruse
112
+ @list.add @plovdiv_sofia
113
+ incorrect_ticket = @plovdiv_sofia.combine @sofia_ruse
114
+
115
+ refute_includes @list, incorrect_ticket
116
+ assert_equal 2, @list.tickets.size
117
+
118
+ haskovo_sofia = TicketSales::Ticket.build 'Haskovo', 'Sofia', 230, Time.new(2013, 3, 3, 15),
119
+ Time.new(2013, 3, 3, 19), '20'.to_d, 'fast, class A, cheap'
120
+ @list.add haskovo_sofia
121
+ incorrect_ticket = haskovo_sofia.combine @sofia_ruse
122
+
123
+ refute_includes @list, incorrect_ticket
124
+ assert_equal 3, @list.tickets.size
125
+ end
126
+
127
+ def test_ticket_search_from_to
128
+ @list.add @haskovo_ruse_direct
129
+ @list.add @haskovo_sofia
130
+ @list.add @sofia_ruse
131
+
132
+ tickets_from_haskovo_to_ruse = @list.get_tickets('Haskovo', 'Ruse')
133
+ assert_equal 2, tickets_from_haskovo_to_ruse.size
134
+ assert_includes tickets_from_haskovo_to_ruse, @haskovo_ruse_direct
135
+ assert_includes tickets_from_haskovo_to_ruse, @haskovo_sofia.combine(@sofia_ruse)
136
+ end
137
+
138
+ def test_ticket_search
139
+ @list.add @haskovo_ruse_direct
140
+ @list.add @haskovo_sofia
141
+ @list.add @sofia_ruse
142
+ ticket = @haskovo_sofia.combine @sofia_ruse
143
+
144
+ cheapest_ticket = @list.cheapest_ticket('Haskovo', 'Ruse')
145
+ assert_equal ticket, cheapest_ticket
146
+
147
+ fastest_ticket = @list.fastest_ticket('Haskovo', 'Ruse')
148
+ assert_equal @haskovo_ruse_direct, fastest_ticket
149
+ end
150
+ end