gillbus 0.17.6 → 0.22.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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