gillbus 0.17.6 → 0.22.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -1
  3. data/Gemfile +0 -4
  4. data/gillbus.gemspec +1 -1
  5. data/lib/gillbus/base_request.rb +2 -0
  6. data/lib/gillbus/base_response.rb +8 -4
  7. data/lib/gillbus/get_carriers.rb +13 -0
  8. data/lib/gillbus/get_required_fields.rb +1 -0
  9. data/lib/gillbus/get_trip_seats.rb +7 -0
  10. data/lib/gillbus/helpers/parser.rb +45 -11
  11. data/lib/gillbus/return_position.rb +2 -0
  12. data/lib/gillbus/return_position_forced.rb +16 -0
  13. data/lib/gillbus/search_nearby_trips.rb +39 -0
  14. data/lib/gillbus/search_trips.rb +20 -13
  15. data/lib/gillbus/structs/carrier.rb +11 -0
  16. data/lib/gillbus/structs/luggage.rb +19 -0
  17. data/lib/gillbus/structs/nearby_cities_trip.rb +61 -0
  18. data/lib/gillbus/structs/point.rb +2 -0
  19. data/lib/gillbus/structs/return_cause.rb +1 -1
  20. data/lib/gillbus/structs/seat.rb +1 -0
  21. data/lib/gillbus/structs/segment.rb +27 -0
  22. data/lib/gillbus/structs/tariff/return_cause.rb +8 -3
  23. data/lib/gillbus/structs/ticket.rb +29 -12
  24. data/lib/gillbus/structs/tickets_option.rb +29 -0
  25. data/lib/gillbus/structs/trip.rb +35 -0
  26. data/lib/gillbus/structs/trip_options.rb +82 -24
  27. data/lib/gillbus/structs/trip_service.rb +16 -1
  28. data/lib/gillbus/tickets_booking.rb +34 -0
  29. data/lib/gillbus/version.rb +1 -1
  30. data/lib/gillbus.rb +31 -3
  31. data/test/error_test.rb +1 -1
  32. data/test/find_order_test.rb +16 -0
  33. data/test/get_required_fields_test.rb +77 -0
  34. data/test/get_trip_seats_test.rb +36 -0
  35. data/test/get_trip_segments_test.rb +1 -0
  36. data/test/parse_trip_options_test.rb +92 -0
  37. data/test/parse_trip_test.rb +25 -0
  38. data/test/responses/findOrder.xml +8 -0
  39. data/test/responses/getRequiredFieldsWithOneLuggage.xml +28 -0
  40. data/test/responses/getRequiredFieldsWithTwoLuggageSegments.xml +40 -0
  41. data/test/responses/getRequiredFieldsWithoutLuggage.xml +23 -0
  42. data/test/responses/getTripSeats-back-seats.xml +1192 -0
  43. data/test/responses/getTripSeats-two-floors.xml +1122 -0
  44. data/test/responses/getTripSeats.xml +70 -0
  45. data/test/responses/legacy_trip.yml +120 -0
  46. data/test/responses/legacy_trip_2.yml +217 -0
  47. data/test/responses/searchTrips-full-carriers-info.xml +231 -0
  48. data/test/responses/searchTrips-new-options-format.xml +244 -0
  49. data/test/responses/searchTrips-prod.xml +5 -0
  50. data/test/responses/searchTrips-round-trip-offers.xml +2016 -0
  51. data/test/responses/searchTripsNearby.xml +707 -0
  52. data/test/responses/ticketsBooking.xml +1 -0
  53. data/test/search_nearby_trips_test.rb +18 -0
  54. data/test/search_trips_test.rb +93 -0
  55. data/test/tickets_booking_test.rb +63 -0
  56. metadata +49 -13
@@ -6,6 +6,10 @@ class Gillbus
6
6
  # => "393409381686201016"
7
7
  field :id
8
8
 
9
+ # Уникальный идентификатор
10
+ # => "20e4e7c8f5b75506b7447a108d362c0d"
11
+ field :static_trip_id
12
+
9
13
  # Идентификатор стороннего поставщика. 0 - gillbus
10
14
  # => "0"
11
15
  field :res_id
@@ -67,6 +71,24 @@ class Gillbus
67
71
  # => "RU \"ПЕТРОКОМ - АВТО ПЛЮС\" ООО"
68
72
  field :carrier_name
69
73
 
74
+ # => "RU \"Еременчук Е.А.\" ИП"
75
+ field :carrier_legal_name
76
+
77
+ # => "260802027265"
78
+ field :carrier_inn
79
+
80
+ # => "г СНТ Лилия, Московская, Наро-фоминский"
81
+ field :carrier_address_fact
82
+
83
+ # => "г СНТ Лилия, Московская, Наро-фоминский"
84
+ field :carrier_address_leg
85
+
86
+ # => "316265100057314"
87
+ field :carrier_egrul_egis
88
+
89
+ # => "2514411332"
90
+ field :carrier_ogrn
91
+
70
92
  # => "09:10"
71
93
  field :time_in_road, :time
72
94
 
@@ -139,6 +161,15 @@ class Gillbus
139
161
  # => "1100"
140
162
  field :total_cost, :money
141
163
 
164
+ # => "1300"
165
+ field :original_amount, :money
166
+
167
+ # => "200"
168
+ field :discount_value, :money
169
+
170
+ # => "13.57"
171
+ field :discount_percentage
172
+
142
173
  # => "false"
143
174
  field :fake_time_in_road, :bool
144
175
 
@@ -150,6 +181,9 @@ class Gillbus
150
181
  # => "643"
151
182
  field :currency_code
152
183
 
184
+ # => "1"
185
+ field :bus_floors_number, :int
186
+
153
187
  field :tariffs, [:tariff], key: 'TARIFF'
154
188
 
155
189
  field :points, [Point], key: 'POINT'
@@ -181,6 +215,7 @@ class Gillbus
181
215
  def self.parse(doc, instance: nil, parent: nil, options: {})
182
216
  instance = super
183
217
  instance.data = doc
218
+ instance.options = TripOptions.build_blank if instance.options.nil?
184
219
  instance
185
220
  end
186
221
  end
@@ -3,41 +3,99 @@ class Gillbus
3
3
  extend Fields
4
4
  include UpdateAttrs
5
5
 
6
- # услуги на рейсе (Wi-Fi, розетки и т.п.)
7
- field :services, [TripService], root: 'TRIP_SERVICES', key: 'TRIP_SERVICE'
6
+ # Услуги на рейсе (Wi-Fi, розетки и т.п.)
7
+ field :services, [TripService],
8
+ root: 'TRIP_SERVICES',
9
+ key: 'TRIP_SERVICE'
8
10
 
9
- # условия по багажу на рейсе
10
- field :luggage, [:string], root: 'LUGGAGE', key: 'ITEM'
11
+ # Условия по багажу на рейсе.
12
+ # Поддерживаются старый и новый форматы:
13
+ # <LUGGAGE>
14
+ # <ITEM>Text</ITEM>
15
+ # <LUGGAG ID="1">Text</LUGGAG>
16
+ # </LUGGAGE>
17
+ field :luggage, [:string],
18
+ root: 'LUGGAGE',
19
+ key: ['ITEM', 'LUGGAG']
11
20
 
12
- # условия рассадки на рейсе
13
- field :seating, [:string], root: 'SEATING', key: 'ITEM'
21
+ # Условия рассадки на рейсе.
22
+ # Поддерживаются старый и новый форматы:
23
+ # <SEATING>
24
+ # <ITEM>Text</ITEM>
25
+ # <SEATIN ID="1">Text</SEATIN>
26
+ # </SEATING>
27
+ field :seating, [:string],
28
+ root: 'SEATING',
29
+ key: ['ITEM', 'SEATIN']
14
30
 
15
- # информация о технических остановках
16
- field :technical_stops, [:string], root: 'TECHNICAL_STOP', key: 'ITEM'
31
+ # Информация о технических остановках.
32
+ # Поддерживаются старый и новый форматы:
33
+ # <TECHNICAL_STOP>
34
+ # <ITEM>Text</ITEM>
35
+ # <TECHNICAL_STO ID="1">Text</TECHNICAL_STO>
36
+ # </TECHNICAL_STOP>
37
+ field :technical_stops, [:string],
38
+ root: 'TECHNICAL_STOP',
39
+ key: ['ITEM', 'TECHNICAL_STO']
17
40
 
18
- # критичная информация о рейсе
19
- field :critical_info, [:string], root: 'CRITICAL_INFO', key: 'ITEM'
41
+ # Критичная информация о рейсе.
42
+ # Поддерживаются старый и новый форматы:
43
+ # <CRITICAL_INFO>
44
+ # <ITEM>Text</ITEM>
45
+ # <CRITICAL_INF ID="1">Text</CRITICAL_INF>
46
+ # </CRITICAL_INFO>
47
+ field :critical_info, [:string],
48
+ root: 'CRITICAL_INFO',
49
+ key: ['ITEM', 'CRITICAL_INF']
20
50
 
21
- # опции полученные от внешних ресурсов
22
- field :resource_options, [:string], root: 'RESOURCE_TRIP_OPTION', key: 'ITEM'
51
+ # Опции полученные от внешних ресурсов.
52
+ # Поддерживаются старый и новый форматы:
53
+ # <RESOURCE_TRIP_OPTION>
54
+ # <ITEM>Text</ITEM>
55
+ # <RESOURCE_TRIP_OPTIO ID="1">Text</RESOURCE_TRIP_OPTIO>
56
+ # </RESOURCE_TRIP_OPTION>
57
+ field :resource_options, [:string],
58
+ root: 'RESOURCE_TRIP_OPTION',
59
+ key: ['ITEM', 'RESOURCE_TRIP_OPTIO']
23
60
 
24
- # информация, отмеченная как "прочее"
25
- field :other, [:string], root: 'OTHER', key: 'ITEM'
61
+ # Информация, отмеченная как "прочее".
62
+ # Поддерживаются старый и новый форматы:
63
+ # <OTHER>
64
+ # <ITEM>Text</ITEM>
65
+ # <OTHE ID="1">Text</OTHE>
66
+ # </OTHER>
67
+ field :other, [:string],
68
+ root: 'OTHER',
69
+ key: ['ITEM', 'OTHE']
26
70
 
27
- # признак рекламируемого рейса, передается как <PROMO><ITEM>ADVERTISING</ITEM></PROMO>
28
- field :advertising, :adertising_bool, root: 'PROMO', key: 'ITEM'
71
+ # Поддерживаются старый и новый форматы:
72
+ # <PROMO>
73
+ # <ITEM>Text</ITEM>
74
+ # <PROM ID="1">Text</PROM>
75
+ # </PROMO>
76
+ field :promo, [:string],
77
+ root: 'PROMO',
78
+ key: ['ITEM', 'PROM']
29
79
 
30
- # признак рекомендованого рейса, передается как <PROMO><ITEM>BUSFOR_RECOMMEND</ITEM></PROMO>
31
- field :busfor_recommend, :recommend_bool, root: 'PROMO', key: 'ITEM'
80
+ # Опции, связанные с билетами.
81
+ field :tickets, [TicketsOption],
82
+ root: 'TICKETS',
83
+ key: 'TICKET'
32
84
 
33
- parser do # better not to let flag value out of this gem
34
- def adertising_bool(vals)
35
- vals.include?('ADVERTISING')
36
- end
85
+ def advertising
86
+ promo.include?('ADVERTISING')
87
+ end
88
+
89
+ def busfor_recommend
90
+ promo.include?('BUSFOR_RECOMMEND')
91
+ end
37
92
 
38
- def recommend_bool(vals)
39
- vals.include?('BUSFOR_RECOMMEND')
93
+ def self.build_blank
94
+ options = new
95
+ field_definitions.each do |name:, type:, key:, root:|
96
+ options.send(:"#{name}=", []) if type.is_a?(Array)
40
97
  end
98
+ options
41
99
  end
42
100
  end
43
101
  end
@@ -7,6 +7,21 @@ class Gillbus
7
7
  field :id, :int, key: 'ID'
8
8
 
9
9
  # название услуги в автобусе
10
- field :name, :string, key: '__content__'
10
+ field :name, :string, key: :__content__
11
+
12
+ def self.parse(doc, instance: nil, parent: nil, options: {})
13
+ instance = new
14
+ if doc.is_a?(Array)
15
+ raise ArgumentError, "Unable to parse TripService: #{doc.inspect}" unless doc.size == 2
16
+ instance.id = doc.first.fetch('ID').to_i
17
+ instance.name = doc.last
18
+ elsif doc.is_a?(Hash) #legacy data made with MultiXML
19
+ instance.id = doc.fetch('ID')
20
+ instance.name = doc.fetch('__content__')
21
+ else
22
+ raise ArgumentError, "Unable to parse TripService: #{doc.inspect}"
23
+ end
24
+ instance
25
+ end
11
26
  end
12
27
  end
@@ -64,6 +64,15 @@ class Gillbus
64
64
  # отправлять ли email с листом бронирования пользователю
65
65
  attr_accessor :send_to
66
66
 
67
+ # идентификатор пользователя в системе BBC
68
+ attr_accessor :user_uuid
69
+
70
+ # ref заказа
71
+ attr_accessor :external_id
72
+
73
+ # ссылка на короткий ЛК
74
+ attr_accessor :return_link
75
+
67
76
  def params
68
77
  pax = (passengers || []).map.with_index { |p, i| Passenger.new(p).params("passenger#{i}") }.reduce({}, :merge)
69
78
  compact(
@@ -76,6 +85,9 @@ class Gillbus
76
85
  note: note,
77
86
  ticketLocale: translated_locale(ticket_locale),
78
87
  sendTo: send_to,
88
+ extCustomerUUID: user_uuid,
89
+ externalID: external_id,
90
+ returnLink: return_link,
79
91
  **pax,
80
92
  )
81
93
  end
@@ -125,6 +137,7 @@ class Gillbus
125
137
  # :seaman_passport 6 - паспорт моряка
126
138
  # :birth_certificate 7 - свидетельство о рождении
127
139
  # :ussr_passport 8 - паспорт формы СССР
140
+ # :tax_id 9 - CPF для WL Бразилии
128
141
  attr_accessor :document_type
129
142
 
130
143
  # passenger0passport... passengerNpassport (обязательный для авиаперевозки)
@@ -147,11 +160,29 @@ class Gillbus
147
160
  # Величина скидки в валюте продажи для пассажира с порядковым номером 0…N.
148
161
  attr_accessor :discount
149
162
 
163
+ # passenger0baggageCount... passengerNbaggageCount (не обязательный)
164
+ # На рейс без сегментов
165
+ # Количество мест багажа для пассажира с порядковым номером 0...N.
166
+ attr_accessor :luggage
167
+
168
+ # passenger0segment0baggageCount... passengerNsegmentMbaggageCount
169
+ # На рейс с сегментами
170
+ # Количество мест багажа для пассажира 0...N на сегмент 0...M
171
+ attr_accessor :segments_luggage
150
172
 
151
173
  attr_accessor :insurance_id
152
174
  attr_accessor :insurance_cost
153
175
 
154
176
  def params(prefix = '')
177
+ # [0, 1] => {'segment0baggageCount' => 0, 'segment1baggageCount' => 1}
178
+ prepared_segments_luggage =
179
+ if segments_luggage
180
+ segments_luggage.map.with_index do |luggage_count, index|
181
+ ["segment#{index}baggageCount".to_sym, luggage_count]
182
+ end.to_h
183
+ else
184
+ {}
185
+ end
155
186
  compact(
156
187
  birthday: date(birthday),
157
188
  ISIC: isic,
@@ -168,6 +199,8 @@ class Gillbus
168
199
  discountValue: discount.to_f.to_s,
169
200
  insuranceId: insurance_id,
170
201
  insurance: insurance_cost,
202
+ baggageCount: luggage&.first, # luggage используется для односегментных
203
+ **prepared_segments_luggage,
171
204
  ).map { |k, v| [:"#{prefix}#{k}", v] }.to_h
172
205
  end
173
206
 
@@ -180,6 +213,7 @@ class Gillbus
180
213
  seaman_passport: 6,
181
214
  birth_certificate: 7,
182
215
  ussr_passport: 8,
216
+ tax_id: 9,
183
217
  }[value.try(:to_sym)]
184
218
  end
185
219
  end
@@ -1,3 +1,3 @@
1
1
  class Gillbus
2
- VERSION = '0.17.6'.freeze
2
+ VERSION = '0.22.9'.freeze
3
3
  end
data/lib/gillbus.rb CHANGED
@@ -25,15 +25,17 @@ class Gillbus
25
25
  request_class = klass::Request
26
26
  response_class = klass::Response
27
27
  request = request_class.new(*args)
28
- headers = { 'Cookie' => "JSESSIONID=#{session_id}" } if session_id
28
+ headers = {}
29
+ headers['Cookie'] = self.class.make_cookies(session_id) if session_id
30
+ headers['Accept-Encoding'] = 'gzip'
31
+ headers['Host'] = driver.host
29
32
  request_time_start = Time.now
30
33
  http_response = driver.public_send(request.method, request.path, request.params, headers)
31
34
  request_time_end = Time.now
32
35
  result = response_class.parse_string(http_response.body.force_encoding('utf-8'), timezone: timezone)
33
36
  cookie_string = http_response.headers['Set-Cookie']
34
37
  if cookie_string
35
- returned_session_id = CGI::Cookie.parse(cookie_string)['JSESSIONID'].first
36
- self.session_id = returned_session_id
38
+ self.session_id = self.class.make_session_id(CGI::Cookie.parse(cookie_string))
37
39
  end
38
40
  result.session_id = session_id
39
41
  result.request_time = request_time_end - request_time_start
@@ -41,12 +43,32 @@ class Gillbus
41
43
  end
42
44
  end
43
45
 
46
+ def self.make_cookies(session_id)
47
+ if session_id.include?('|')
48
+ session_id, gclb = session_id.split('|')
49
+ "JSESSIONID=#{session_id}; GCLB=#{gclb}"
50
+ else
51
+ "JSESSIONID=#{session_id}"
52
+ end
53
+ end
54
+
55
+ def self.make_session_id(parsed_cookies)
56
+ gclb = parsed_cookies['GCLB'].first
57
+ session_id = parsed_cookies['JSESSIONID'].first
58
+ if gclb.present?
59
+ [session_id, gclb].join('|')
60
+ else
61
+ session_id
62
+ end
63
+ end
64
+
44
65
  require 'monetize'
45
66
  require 'gillbus/helpers/fields'
46
67
  require 'gillbus/helpers/update_attrs'
47
68
  require 'gillbus/helpers/parser'
48
69
 
49
70
  require 'gillbus/structs/trip_service'
71
+ require 'gillbus/structs/tickets_option'
50
72
  require 'gillbus/structs/trip_options'
51
73
  require 'gillbus/structs/point'
52
74
  require 'gillbus/structs/tariff/return_cause'
@@ -63,6 +85,9 @@ class Gillbus
63
85
 
64
86
  require 'gillbus/structs/seat'
65
87
  require 'gillbus/structs/item'
88
+ require 'gillbus/structs/carrier'
89
+ require 'gillbus/structs/nearby_cities_trip'
90
+ require 'gillbus/structs/luggage'
66
91
 
67
92
  require 'gillbus/parse_error'
68
93
  require 'gillbus/base_request'
@@ -77,6 +102,7 @@ class Gillbus
77
102
  require 'gillbus/get_time_table'
78
103
  require 'gillbus/get_dates_new'
79
104
  require 'gillbus/search_trips'
105
+ require 'gillbus/search_nearby_trips'
80
106
  require 'gillbus/get_trips'
81
107
  require 'gillbus/get_trip_seats'
82
108
  require 'gillbus/get_bus_image'
@@ -94,4 +120,6 @@ class Gillbus
94
120
  require 'gillbus/get_order_status'
95
121
  require 'gillbus/logout'
96
122
  require 'gillbus/return_position'
123
+ require 'gillbus/return_position_forced'
124
+ require 'gillbus/get_carriers'
97
125
  end
data/test/error_test.rb CHANGED
@@ -22,7 +22,7 @@ class ErrorTest < Minitest::Test
22
22
 
23
23
  def test_malformed_errorness
24
24
  assert malformed_response.error?
25
- assert_equal "Malformed response: Not Terminated: text not terminated at 0:10", malformed_response.error_message
25
+ assert malformed_response.error_message.include?("Malformed response: invalid format")
26
26
  end
27
27
 
28
28
  def test_malformed_2_errorness
@@ -36,4 +36,20 @@ class FindOrderTest < Minitest::Test
36
36
  def test_comission_currency
37
37
  assert_equal(Money.new(51_55, 'RUB'), find_order2.tickets.last.commissions.last.value)
38
38
  end
39
+
40
+ def test_online_refund
41
+ assert_equal(true, find_order.tickets.first.is_online_refund)
42
+ end
43
+
44
+ def test_supplier_inn
45
+ assert_equal('3257025789', find_order.tickets.last.supplier_inn)
46
+ end
47
+
48
+ def test_supplier_name
49
+ assert_equal('"Клен 2" ООО', find_order.tickets.last.supplier_name)
50
+ end
51
+
52
+ def test_supplier_phone
53
+ assert_equal('+79065002926', find_order.tickets.last.supplier_phone)
54
+ end
39
55
  end
@@ -0,0 +1,77 @@
1
+ require 'test_helper'
2
+
3
+ class GetRequiredFieldsTest < Minitest::Test
4
+ def get_required_fields_without_luggage
5
+ response_xml = File.read('test/responses/getRequiredFieldsWithoutLuggage.xml')
6
+ Gillbus::GetRequiredFields::Response.parse_string(response_xml)
7
+ end
8
+
9
+ def get_required_fields_with_one_luggage
10
+ response_xml = File.read('test/responses/getRequiredFieldsWithOneLuggage.xml')
11
+ Gillbus::GetRequiredFields::Response.parse_string(response_xml)
12
+ end
13
+
14
+ def get_required_fields_with_two_luggage_segments
15
+ response_xml = File.read('test/responses/getRequiredFieldsWithTwoLuggageSegments.xml')
16
+ Gillbus::GetRequiredFields::Response.parse_string(response_xml)
17
+ end
18
+
19
+ def test_required_fields_without_luggage
20
+ result = get_required_fields_without_luggage
21
+
22
+ assert_nil result.luggage
23
+
24
+ dictionary = result.dictionary
25
+ assert_equal false, dictionary[:student_ticket]
26
+ assert_equal false, dictionary[:isic]
27
+ assert_equal false, dictionary[:tariff_short_name]
28
+ assert_equal false, dictionary[:tariff_cost]
29
+ assert_equal true, dictionary[:document_type]
30
+ assert_equal true, dictionary[:baggage_count]
31
+ assert_equal true, dictionary[:phone]
32
+ assert_equal true, dictionary[:mail]
33
+ assert_equal true, dictionary[:firstname]
34
+ assert_equal true, dictionary[:lastname]
35
+ assert_equal true, dictionary[:birthday]
36
+ assert_equal true, dictionary[:passport]
37
+ assert_equal true, dictionary[:citizenship]
38
+ assert_equal true, dictionary[:gender]
39
+ assert_equal true, dictionary[:visa]
40
+ assert_equal true, dictionary[:passdate]
41
+ assert_equal true, dictionary[:only_latin_symbols]
42
+ end
43
+
44
+ def test_required_fields_with_one_luggage
45
+ result = get_required_fields_with_one_luggage
46
+ luggage = result.luggage
47
+
48
+ assert_equal true, luggage.is_buy
49
+ assert_equal 50.5, luggage.luggage_tariff
50
+
51
+ assert_equal [], luggage.segments
52
+ assert_nil luggage.segment_number
53
+ end
54
+
55
+ def test_required_fields_with_two_luggage_segments
56
+ result = get_required_fields_with_two_luggage_segments
57
+ luggage = result.luggage
58
+
59
+ assert_nil luggage.is_buy
60
+ assert_nil luggage.luggage_tariff
61
+ assert_nil luggage.luggage_limit
62
+
63
+ assert_equal 2, luggage.segments.count
64
+ first_luggage_segment = luggage.segments[0]
65
+ second_luggage_segment = luggage.segments[1]
66
+
67
+ assert_equal 0, first_luggage_segment.segment_number
68
+ assert_equal true, first_luggage_segment.is_buy
69
+ assert_equal 70.7, first_luggage_segment.luggage_tariff
70
+ assert_equal 2, first_luggage_segment.luggage_limit
71
+
72
+ assert_equal 1, second_luggage_segment.segment_number
73
+ assert_equal false, second_luggage_segment.is_buy
74
+ assert_nil second_luggage_segment.luggage_tariff
75
+ assert_nil second_luggage_segment.luggage_limit
76
+ end
77
+ end
@@ -13,13 +13,25 @@ class GetTripSeatsTest < Minitest::Test
13
13
  Gillbus::GetTripSeats::Response.parse_string(File.read('test/responses/getTripSeats-one-empty-segment.xml'))
14
14
  end
15
15
 
16
+ def get_trip_seats_with_back_seats
17
+ Gillbus::GetTripSeats::Response.parse_string(File.read('test/responses/getTripSeats-back-seats.xml'))
18
+ end
19
+
20
+ def get_trip_seats_with_two_floors
21
+ Gillbus::GetTripSeats::Response.parse_string(File.read('test/responses/getTripSeats-two-floors.xml'))
22
+ end
23
+
16
24
  def test_seats
17
25
  seats = get_trip_seats.seats
18
26
  max_x = seats.map(&:x).max
19
27
  max_y = seats.map(&:y).max
28
+ max_z = seats.map(&:z).max
29
+ z_seats_count = seats.count(&:z)
20
30
  assert_equal(70, seats.size)
21
31
  assert_equal(4, max_y)
22
32
  assert_equal(13, max_x)
33
+ assert_equal(0, max_z)
34
+ assert_equal(seats.size, z_seats_count)
23
35
  end
24
36
 
25
37
  def test_seats_with_segments
@@ -36,4 +48,28 @@ class GetTripSeatsTest < Minitest::Test
36
48
  assert [], segments[0]
37
49
  assert_equal 80, segments[1].size
38
50
  end
51
+
52
+ def test_seats_with_back_seats
53
+ response = get_trip_seats_with_back_seats
54
+
55
+ assert_equal true, response.seats.count > 0
56
+ assert_equal true, response.back_seats.count > 0
57
+
58
+ back_seat = response.back_seats.first
59
+ assert_equal '4925214118', back_seat.id
60
+ assert_equal 'В1', back_seat.number
61
+ assert_equal 2, back_seat.type
62
+ assert_equal 0, back_seat.x
63
+ assert_equal 0, back_seat.y
64
+ end
65
+
66
+ def test_seats_with_back_seats_two_floors
67
+ seats = get_trip_seats_with_two_floors.seats
68
+ groupped_seats_by_floor = seats.group_by(&:z)
69
+ z0_seats_count = groupped_seats_by_floor[0]
70
+ z1_seats_count = groupped_seats_by_floor[1]
71
+
72
+ assert_equal true, z0_seats_count.count > 0
73
+ assert_equal true, z1_seats_count.count > 0
74
+ end
39
75
  end
@@ -13,5 +13,6 @@ class GetTripSegmentsTest < Minitest::Test
13
13
  assert_equal('Ж/Д вокзал Львів', points.first.name)
14
14
  assert_equal('Щецин', points.last.geography_name)
15
15
  assert_equal('Автовокзал', points.last.name)
16
+ assert_equal(1055, points.last.distance)
16
17
  end
17
18
  end
@@ -0,0 +1,92 @@
1
+ require 'test_helper'
2
+ require 'pry'
3
+
4
+ class ParseTripOptionsTest < Minitest::Test
5
+ def test_with_only_item
6
+ xml = <<~XML.strip
7
+ <DATA><TRIP><OPTIONS><CRITICAL_INFO>
8
+ <ITEM>Внимание! Ознакомьтесь со списком стран, въезд в которые ограничен в связи с коронавирусом &gt;&gt; https://busfor.com/ru/blog/covid-19-updates</ITEM>
9
+ </CRITICAL_INFO></OPTIONS></TRIP></DATA>
10
+ XML
11
+
12
+ subject = Gillbus::SearchTrips::Response.parse_string(xml).trips.first.options.critical_info
13
+
14
+ expected_result = [
15
+ "Внимание! Ознакомьтесь со списком стран, въезд в которые ограничен в связи с коронавирусом >> https://busfor.com/ru/blog/covid-19-updates",
16
+ ]
17
+
18
+ assert_equal expected_result, subject
19
+ end
20
+
21
+ def test_with_item_and_one_critical_inf
22
+ xml = <<~XML.strip
23
+ <DATA><TRIP><OPTIONS><CRITICAL_INFO>
24
+ <ITEM>Внимание! Ознакомьтесь со списком стран, въезд в которые ограничен в связи с коронавирусом &gt;&gt; https://busfor.com/ru/blog/covid-19-updates</ITEM>
25
+ <CRITICAL_INF ID="16">в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.</CRITICAL_INF>
26
+ </CRITICAL_INFO></OPTIONS></TRIP></DATA>
27
+ XML
28
+
29
+ subject = Gillbus::SearchTrips::Response.parse_string(xml).trips.first.options.critical_info
30
+
31
+ expected_result = [
32
+ "Внимание! Ознакомьтесь со списком стран, въезд в которые ограничен в связи с коронавирусом >> https://busfor.com/ru/blog/covid-19-updates",
33
+ "в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.",
34
+ ]
35
+
36
+ assert_equal expected_result, subject
37
+ end
38
+
39
+ def test_with_one_critical_inf
40
+ xml = <<~XML.strip
41
+ <DATA><TRIP><OPTIONS><CRITICAL_INFO>
42
+ <CRITICAL_INF ID="16">в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.</CRITICAL_INF>
43
+ </CRITICAL_INFO></OPTIONS></TRIP></DATA>
44
+ XML
45
+
46
+ subject = Gillbus::SearchTrips::Response.parse_string(xml).trips.first.options.critical_info
47
+
48
+ expected_result = [
49
+ "в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.",
50
+ ]
51
+
52
+ assert_equal expected_result, subject
53
+ end
54
+
55
+ def test_with_two_critical_inf
56
+ xml = <<~XML.strip
57
+ <DATA><TRIP><OPTIONS><CRITICAL_INFO>
58
+ <CRITICAL_INF ID="1">Всё будет хорошо</CRITICAL_INF>
59
+ <CRITICAL_INF ID="16">в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.</CRITICAL_INF>
60
+ </CRITICAL_INFO></OPTIONS></TRIP></DATA>
61
+ XML
62
+
63
+ subject = Gillbus::SearchTrips::Response.parse_string(xml).trips.first.options.critical_info
64
+
65
+ expected_result = [
66
+ "Всё будет хорошо",
67
+ "в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.",
68
+ ]
69
+
70
+ assert_equal expected_result, subject
71
+ end
72
+
73
+ def test_with_item_and_two_critical_inf
74
+ xml = <<~XML.strip
75
+ <DATA><TRIP><OPTIONS><CRITICAL_INFO>
76
+ <ITEM>Будьте внимательны, дорогие мои!</ITEM>
77
+ <CRITICAL_INF ID="1">Всё будет хорошо</CRITICAL_INF>
78
+ <CRITICAL_INF ID="16">в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.</CRITICAL_INF>
79
+ </CRITICAL_INFO></OPTIONS></TRIP></DATA>
80
+ XML
81
+
82
+ subject = Gillbus::SearchTrips::Response.parse_string(xml).trips.first.options.critical_info
83
+
84
+ expected_result = [
85
+ "Будьте внимательны, дорогие мои!",
86
+ "Всё будет хорошо",
87
+ "в связи с дорожными условиями, возможно отклонение в расписании движения в пределах 1час30.",
88
+ ]
89
+
90
+ assert_equal expected_result, subject
91
+ end
92
+ end
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ class ParseTripYAML < Minitest::Test
4
+ def test_content_1
5
+ response = Gillbus::Trip.parse(YAML.load(File.read('test/responses/legacy_trip.yml')))
6
+ expected_causes = [
7
+ 'Без потерь, более чем за 2 ч., до отправления рейса. Возвращается 100% стоимости тарифа. Ориентировочная сумма возврата 550',
8
+ 'Добровольно, менее чем за 2 ч., до отправления рейса. Удерживается при возврате: 15% тарифа. Ориентировочная сумма возврата 425',
9
+ 'Возврат маршрутной квитанции в случае опоздания к отправлению (стоимость не возвращается). Удерживается при возврате: 100% тарифа. Ориентировочная сумма возврата 0',
10
+ 'Возврат маршрутной квитанции по отмене отправления т/с, задержки отправления т/с более чем на час и непредставления пассажиру указанного в билете места. СРОК ОБРАЩЕНИЯ для возврата билета 24 часа с времени отправления. . Возвращается 100% стоимости билета. Ориентировочная сумма возврата 550'
11
+ ]
12
+
13
+ assert_equal true, response.tariffs.first.return_cause.first.lossless
14
+ assert_equal expected_causes, response.tariffs.first.return_cause.map(&:cause)
15
+ end
16
+
17
+ def test_content_2
18
+ response = Gillbus::Trip.parse(YAML.load(File.read('test/responses/legacy_trip_2.yml')))
19
+ assert_equal ["Принудительно, при отмене рейса. Ориентировочная сумма возврата 1044.95RUB",
20
+ "Добровільно ДБ 4, менш ніж за 10 хвилин до відправлення рейсу. Ориентировочная сумма возврата 574.72RUB",
21
+ "ДБ 3, не менш ніж за 10 хвилин до відправлення рейсу. Ориентировочная сумма возврата 679.21RUB",
22
+ "Добровольно, более чем за 2 ч., до отправления рейса. Ориентировочная сумма возврата 783.71RUB",
23
+ "не менше ніж за 24 години до відправлення рейсу. Ориентировочная сумма возврата 888.2RUB"], response.tariffs.first.return_cause.map(&:cause)
24
+ end
25
+ end