parking_ticket 1.0.47 → 1.0.50

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/.vscode/settings.json +3 -0
  4. data/Gemfile +0 -15
  5. data/Gemfile.lock +72 -4
  6. data/Rakefile +2 -2
  7. data/bin/console +3 -3
  8. data/bin/tapioca +29 -0
  9. data/lib/clients/models/payment_method.rb +15 -0
  10. data/lib/clients/models/quote.rb +16 -0
  11. data/lib/clients/models/rate_option.rb +19 -0
  12. data/lib/clients/models/structuraly_comparable.rb +14 -0
  13. data/lib/clients/models/ticket.rb +19 -0
  14. data/lib/clients/models/vehicle.rb +17 -0
  15. data/lib/clients/pay_by_phone/adapter.rb +106 -50
  16. data/lib/clients/pay_by_phone/client.rb +101 -38
  17. data/lib/parking_ticket/configuration.rb +3 -0
  18. data/lib/parking_ticket/version.rb +2 -1
  19. data/lib/parking_ticket.rb +79 -54
  20. data/sorbet/config +4 -0
  21. data/sorbet/rbi/annotations/faraday.rbi +17 -0
  22. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  23. data/sorbet/rbi/annotations/webmock.rbi +9 -0
  24. data/sorbet/rbi/gems/addressable@2.8.1.rbi +2000 -0
  25. data/sorbet/rbi/gems/amazing_print@1.4.0.rbi +872 -0
  26. data/sorbet/rbi/gems/ast@2.4.2.rbi +584 -0
  27. data/sorbet/rbi/gems/crack@0.4.5.rbi +144 -0
  28. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +1079 -0
  29. data/sorbet/rbi/gems/faraday-net_http@3.0.2.rbi +146 -0
  30. data/sorbet/rbi/gems/faraday@2.7.2.rbi +2518 -0
  31. data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +350 -0
  32. data/sorbet/rbi/gems/json@2.6.3.rbi +1541 -0
  33. data/sorbet/rbi/gems/json_matchers@0.11.1.rbi +133 -0
  34. data/sorbet/rbi/gems/json_schema@0.21.0.rbi +1165 -0
  35. data/sorbet/rbi/gems/netrc@0.11.0.rbi +161 -0
  36. data/sorbet/rbi/gems/parallel@1.22.1.rbi +277 -0
  37. data/sorbet/rbi/gems/parser@3.2.2.0.rbi +7207 -0
  38. data/sorbet/rbi/gems/public_suffix@5.0.1.rbi +940 -0
  39. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +402 -0
  40. data/sorbet/rbi/gems/rake@13.0.6.rbi +2881 -0
  41. data/sorbet/rbi/gems/rbi@0.0.16.rbi +3008 -0
  42. data/sorbet/rbi/gems/regexp_parser@2.7.0.rbi +3600 -0
  43. data/sorbet/rbi/gems/rexml@3.2.5.rbi +4823 -0
  44. data/sorbet/rbi/gems/rspec-core@3.12.0.rbi +10826 -0
  45. data/sorbet/rbi/gems/rspec-expectations@3.12.1.rbi +8118 -0
  46. data/sorbet/rbi/gems/rspec-mocks@3.12.1.rbi +5300 -0
  47. data/sorbet/rbi/gems/rspec-support@3.12.0.rbi +1615 -0
  48. data/sorbet/rbi/gems/rspec@3.12.0.rbi +82 -0
  49. data/sorbet/rbi/gems/rubocop-ast@1.28.0.rbi +6985 -0
  50. data/sorbet/rbi/gems/rubocop-sorbet@0.7.0.rbi +1043 -0
  51. data/sorbet/rbi/gems/rubocop@1.48.1.rbi +54934 -0
  52. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1317 -0
  53. data/sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi +8 -0
  54. data/sorbet/rbi/gems/spoom@1.2.1.rbi +2503 -0
  55. data/sorbet/rbi/gems/tapioca@0.11.4.rbi +3212 -0
  56. data/sorbet/rbi/gems/thor@1.2.1.rbi +3956 -0
  57. data/sorbet/rbi/gems/unicode-display_width@2.4.2.rbi +65 -0
  58. data/sorbet/rbi/gems/unparser@0.6.7.rbi +4515 -0
  59. data/sorbet/rbi/gems/vcr@6.1.0.rbi +3023 -0
  60. data/sorbet/rbi/gems/webmock@3.18.1.rbi +1728 -0
  61. data/sorbet/rbi/gems/webrick@1.7.0.rbi +2584 -0
  62. data/sorbet/rbi/gems/yard-sorbet@0.8.0.rbi +441 -0
  63. data/sorbet/rbi/gems/yard@0.9.28.rbi +17802 -0
  64. data/sorbet/tapioca/config.yml +13 -0
  65. data/sorbet/tapioca/require.rb +4 -0
  66. metadata +241 -4
  67. data/lib/clients/adapter.rb +0 -75
@@ -1,21 +1,16 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
1
4
  require 'faraday'
5
+
2
6
  module ParkingTicket
3
7
  module Clients
4
8
  module PayByPhone
5
9
  class Client
10
+ extend T::Sig
6
11
  class << self
7
- def rate_options(token, account_id, zipcode, license_plate)
8
- connection(token).get("/parking/locations/#{zipcode}/rateOptions",
9
- {
10
- parkingAccountId: account_id,
11
- licensePlate: license_plate
12
- }).body
13
- end
14
-
15
- def vehicles(token)
16
- connection(token).get('/identity/profileservice/v1/members/vehicles/paybyphone').body
17
- end
18
-
12
+ extend T::Sig
13
+ sig { params(username: String, password: String).returns(Faraday::Response) }
19
14
  def auth(username, password)
20
15
  conn = Faraday.new('https://auth.paybyphoneapis.com') do |f|
21
16
  f.response :json
@@ -35,14 +30,41 @@ module ParkingTicket
35
30
  )
36
31
  end
37
32
 
33
+ sig { params(token: String, account_id: String, zipcode: String, license_plate: String).returns(Array) }
34
+ def rate_options(token, account_id, zipcode, license_plate)
35
+ connection(token).get("/parking/locations/#{zipcode}/rateOptions",
36
+ {
37
+ parkingAccountId: account_id,
38
+ licensePlate: license_plate
39
+ }).body
40
+ end
41
+
42
+ sig { params(token: String).returns(T::Array[T::Hash[String, T.untyped]]) }
43
+ def vehicles(token)
44
+ connection(token).get('/identity/profileservice/v1/members/vehicles/paybyphone').body
45
+ end
46
+
47
+ sig { params(token: String).returns(String) }
38
48
  def account_id(token)
39
49
  connection(token).get('/parking/accounts').body.dig(0, 'id')
40
50
  end
41
51
 
52
+ sig { params(token: String, account_id: String).returns(T::Array[T::Hash[String, T.untyped]]) }
42
53
  def running_tickets(token, account_id)
43
54
  connection(token).get("/parking/accounts/#{account_id}/sessions?periodType=Current").body
44
55
  end
45
56
 
57
+ sig do
58
+ params(
59
+ token: String,
60
+ account_id: String,
61
+ rate_option_id: String,
62
+ zipcode: String,
63
+ license_plate: String,
64
+ quantity: Integer,
65
+ time_unit: String
66
+ ).returns(T::Hash[String, T.untyped])
67
+ end
46
68
  def quote(token, account_id, rate_option_id, zipcode, license_plate, quantity, time_unit)
47
69
  connection(token).get(
48
70
  "/parking/accounts/#{account_id}/quote",
@@ -58,35 +80,50 @@ module ParkingTicket
58
80
  ).body
59
81
  end
60
82
 
61
- def new_ticket(token, account_id, license_plate:, zipcode:, rate_option_client_internal_id:, quantity:, time_unit:, quote_client_internal_id:, starts_on:, payment_method_id:)
83
+ sig do
84
+ params(
85
+ token: String,
86
+ account_id: String,
87
+ license_plate: String,
88
+ zipcode: String,
89
+ rate_option_client_internal_id: String,
90
+ quantity: Integer,
91
+ time_unit: String,
92
+ quote_client_internal_id: String,
93
+ starts_on: DateTime,
94
+ payment_method_id: T.nilable(String)
95
+ ).void
96
+ end
97
+ def new_ticket(token, account_id, license_plate:, zipcode:, rate_option_client_internal_id:, quantity:,
98
+ time_unit:, quote_client_internal_id:, starts_on:, payment_method_id:)
62
99
  base_data = {
63
- "expireTime": nil,
64
- "duration": {
65
- "quantity": quantity.to_s,
66
- "timeUnit": time_unit
100
+ expireTime: nil,
101
+ duration: {
102
+ quantity: quantity.to_s,
103
+ timeUnit: time_unit
67
104
  },
68
- "licensePlate": license_plate,
69
- "locationId": zipcode,
70
- "rateOptionId": rate_option_client_internal_id,
71
- "startTime": starts_on,
72
- "quoteId": quote_client_internal_id,
73
- "parkingAccountId": account_id
105
+ licensePlate: license_plate,
106
+ locationId: zipcode,
107
+ rateOptionId: rate_option_client_internal_id,
108
+ startTime: starts_on.to_s,
109
+ quoteId: quote_client_internal_id,
110
+ parkingAccountId: account_id
74
111
  }
75
112
 
76
113
  payment_data = {
77
- "paymentMethod": {
78
- "paymentMethodType": 'PaymentAccount',
79
- "payload": {
80
- "paymentAccountId": payment_method_id,
81
- "clientBrowserDetails": {
82
- "browserAcceptHeader": 'text/html',
83
- "browserColorDepth": '30',
84
- "browserJavaEnabled": 'false',
85
- "browserLanguage": 'fr-FR',
86
- "browserScreenHeight": '900',
87
- "browserScreenWidth": '1440',
88
- "browserTimeZone": '-60',
89
- "browserUserAgent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
114
+ paymentMethod: {
115
+ paymentMethodType: 'PaymentAccount',
116
+ payload: {
117
+ paymentAccountId: payment_method_id,
118
+ clientBrowserDetails: {
119
+ browserAcceptHeader: 'text/html',
120
+ browserColorDepth: '30',
121
+ browserJavaEnabled: 'false',
122
+ browserLanguage: 'fr-FR',
123
+ browserScreenHeight: '900',
124
+ browserScreenWidth: '1440',
125
+ browserTimeZone: '-60',
126
+ browserUserAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
90
127
  }
91
128
  }
92
129
  }
@@ -96,16 +133,18 @@ module ParkingTicket
96
133
 
97
134
  connection(token).post(
98
135
  "/parking/accounts/#{account_id}/sessions/",
99
- final_data.to_json
136
+ JSON.generate(final_data)
100
137
  ).body
101
138
  end
102
139
 
140
+ sig { params(token: String).returns(T::Hash[String, T::Array[T::Hash[String, T.untyped]]]) }
103
141
  def payment_methods(token)
104
142
  connection(token).get('/payment/v3/accounts').body
105
143
  end
106
144
 
107
145
  private
108
146
 
147
+ sig { params(token: String).returns(Faraday::Connection) }
109
148
  def connection(token)
110
149
  Faraday.new(
111
150
  url: 'https://consumer.paybyphoneapis.com',
@@ -124,27 +163,49 @@ module ParkingTicket
124
163
  @password = password
125
164
  end
126
165
 
166
+ sig { returns(T::Array[T::Hash[String, T.untyped]]) }
127
167
  def vehicles
128
168
  self.class.vehicles(token)
129
169
  end
130
170
 
171
+ sig { params(zipcode: String, license_plate: String).returns(T::Array[T::Hash[String, T.untyped]]) }
131
172
  def rate_options(zipcode, license_plate)
132
173
  self.class.rate_options(token, account_id, zipcode, license_plate)
133
174
  end
134
175
 
176
+ sig { returns(T::Array[T::Hash[String, T.untyped]]) }
135
177
  def running_tickets
136
178
  self.class.running_tickets(token, account_id)
137
179
  end
138
180
 
181
+ sig { returns(T::Hash[String, T::Array[T::Hash[String, T.untyped]]]) }
139
182
  def payment_methods
140
183
  self.class.payment_methods(token)
141
184
  end
142
185
 
186
+ sig do
187
+ params(rate_option_id: String, zipcode: String, license_plate: String, quantity: Integer,
188
+ time_unit: String).returns(T::Hash[String, T.untyped])
189
+ end
143
190
  def quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
144
191
  self.class.quote(token, account_id, rate_option_id, zipcode, license_plate, quantity, time_unit)
145
192
  end
146
193
 
147
- def new_ticket(license_plate:, zipcode:, rate_option_client_internal_id:, quantity:, time_unit:, quote_client_internal_id:, starts_on:, payment_method_id:)
194
+ sig do
195
+ params(
196
+ license_plate: String,
197
+ zipcode: String,
198
+ rate_option_client_internal_id: String,
199
+ quantity: Integer,
200
+ time_unit: String,
201
+ quote_client_internal_id: String,
202
+ starts_on: DateTime,
203
+ payment_method_id: T.nilable(String)
204
+ )
205
+ .void
206
+ end
207
+ def new_ticket(license_plate:, zipcode:, rate_option_client_internal_id:, quantity:, time_unit:,
208
+ quote_client_internal_id:, starts_on:, payment_method_id:)
148
209
  self.class.new_ticket(token, account_id,
149
210
  license_plate: license_plate,
150
211
  zipcode: zipcode,
@@ -158,10 +219,12 @@ module ParkingTicket
158
219
 
159
220
  private
160
221
 
222
+ sig { returns(String) }
161
223
  def token
162
224
  @token ||= self.class.auth(@username, @password).body['access_token']
163
225
  end
164
226
 
227
+ sig { returns(String) }
165
228
  def account_id
166
229
  @account_id ||= self.class.account_id(token)
167
230
  end
@@ -1,3 +1,6 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
1
4
  module ParkingTicket
2
5
  class Configuration
3
6
  def self.attr_required(*configuration_keys)
@@ -1,5 +1,6 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module ParkingTicket
4
- VERSION = '1.0.47'
5
+ VERSION = '1.0.50'
5
6
  end
@@ -1,73 +1,113 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
- require 'parking_ticket/configuration'
4
+ # requires
5
+ require 'date'
6
+
7
+ # sorbet
8
+ require 'sorbet-runtime'
9
+
10
+ # gem version
4
11
  require 'parking_ticket/version'
5
12
 
6
- # PayByPhone wrapper
7
- require 'clients/adapter'
8
- require 'clients/pay_by_phone/adapter'
13
+ # models
14
+ require 'clients/models/structuraly_comparable'
15
+ require 'clients/models/vehicle'
16
+ require 'clients/models/rate_option'
17
+ require 'clients/models/ticket'
18
+ require 'clients/models/payment_method'
19
+ require 'clients/models/quote'
20
+
21
+ # pay_by_phone_subclasses
9
22
  require 'clients/pay_by_phone/client'
23
+ require 'clients/pay_by_phone/adapter'
10
24
 
11
25
  module ParkingTicket
12
26
  class Base
27
+ extend T::Sig
13
28
  class << self
29
+ extend T::Sig
30
+
31
+ sig do
32
+ params(
33
+ adapter_name: String,
34
+ username: String,
35
+ password: String
36
+ )
37
+ .returns(T::Boolean)
38
+ end
14
39
  def valid_credentials?(adapter_name, username, password)
15
- adapter = Clients::PayByPhone::Adapter if adapter_name == 'pay_by_phone'
40
+ adapter_class = Clients::PayByPhone::Adapter if adapter_name == 'pay_by_phone'
16
41
  raise Error, 'EasyPark will be handled in the next major release' if adapter_name == 'easy_park'
17
- raise Error, "Unhandled adapter : #{adapter_name}" unless adapter
18
-
19
- adapter.valid_credentials?(username, password)
20
- end
42
+ raise Error, "Unhandled adapter : #{adapter_name}" unless adapter_class
21
43
 
22
- def config
23
- yield(self)
24
- end
25
-
26
- attr_accessor :ticket_format
27
-
28
- def format_ticket(ticket)
29
- return unless ticket_format
30
-
31
- ticket_format.each_with_object({}) do |element, acumulator|
32
- if element.is_a?(Hash)
33
- original_key = element.keys.first
34
- target_key = element.values.first
35
- acumulator[target_key] = ticket[original_key]
36
- else
37
- acumulator[element] = ticket[element]
38
- end
39
- end
44
+ adapter_class.valid_credentials?(username, password)
40
45
  end
41
46
  end
42
- attr_reader :configuration
43
47
 
44
48
  class Error < StandardError
45
49
  end
46
50
 
51
+ sig do
52
+ params(
53
+ adapter_name: String,
54
+ username: String,
55
+ password: String
56
+ )
57
+ .void
58
+ end
47
59
  def initialize(adapter_name, username, password)
48
- @adapter_name = adapter_name
49
60
  @username = username
50
61
  @password = password
62
+ @adapter = T.let(load_adapter!(adapter_name), ParkingTicket::Clients::PayByPhone::Adapter)
51
63
  end
52
64
 
65
+ sig { returns(T::Array[ParkingTicket::Clients::Models::Vehicle]) }
53
66
  def vehicles
54
- adapter.vehicles
67
+ @adapter.vehicles
55
68
  end
56
69
 
70
+ sig { params(zipcode: String, license_plate: String).returns(T::Array[ParkingTicket::Clients::Models::RateOption]) }
57
71
  def rate_options(zipcode, license_plate)
58
- adapter.rate_options(zipcode, license_plate)
72
+ @adapter.rate_options(zipcode, license_plate)
59
73
  end
60
74
 
75
+ sig { params(license_plate: String, zipcode: String).returns(T.nilable(ParkingTicket::Clients::Models::Ticket)) }
61
76
  def running_ticket(license_plate, zipcode)
62
- adapter.running_ticket(license_plate, zipcode)
77
+ @adapter.running_ticket(license_plate, zipcode)
63
78
  end
64
79
 
80
+ sig { returns(T::Array[ParkingTicket::Clients::Models::PaymentMethod]) }
65
81
  def payment_methods
66
- adapter.payment_methods
82
+ @adapter.payment_methods
67
83
  end
68
84
 
85
+ sig do
86
+ params(
87
+ rate_option_id: String,
88
+ zipcode: String,
89
+ license_plate: String,
90
+ quantity: Integer,
91
+ time_unit: String
92
+ )
93
+ .returns(ParkingTicket::Clients::Models::Quote)
94
+ end
95
+ def quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
96
+ @adapter.quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
97
+ end
98
+
99
+ sig do
100
+ params(
101
+ license_plate: String,
102
+ zipcode: String,
103
+ rate_option_client_internal_id: String,
104
+ quantity: Integer,
105
+ time_unit: String,
106
+ payment_method_id: T.nilable(String)
107
+ ).void
108
+ end
69
109
  def new_ticket(license_plate:, zipcode:, rate_option_client_internal_id:, quantity:, time_unit:, payment_method_id:)
70
- adapter.new_ticket(
110
+ @adapter.new_ticket(
71
111
  license_plate: license_plate,
72
112
  zipcode: zipcode,
73
113
  rate_option_client_internal_id: rate_option_client_internal_id,
@@ -77,29 +117,14 @@ module ParkingTicket
77
117
  )
78
118
  end
79
119
 
80
- def quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
81
- adapter.quote(rate_option_id, zipcode, license_plate, quantity, time_unit)
82
- end
83
-
84
120
  private
85
121
 
86
- def load_adapter!
87
- return prepare_pay_by_phone_adapter! if @adapter_name == 'pay_by_phone'
88
- return prepare_easy_park_adapter! if @adapter_name == 'easy_park'
89
-
90
- raise Error, "Unhandled adapter : #{@adapter_name}"
91
- end
92
-
93
- def prepare_pay_by_phone_adapter!
94
- Clients::PayByPhone::Adapter.new(@username, @password)
95
- end
96
-
97
- def prepare_easy_park_adapter!
98
- raise Error, 'EasyPark will be handled in the next major release'
99
- end
122
+ sig { params(adapter_name: String).returns(ParkingTicket::Clients::PayByPhone::Adapter) }
123
+ def load_adapter!(adapter_name)
124
+ return Clients::PayByPhone::Adapter.new(@username, @password) if adapter_name == 'pay_by_phone'
125
+ raise Error, 'EasyPark will be handled in the next major release' if adapter_name == 'easy_park'
100
126
 
101
- def adapter
102
- @adapter ||= load_adapter!
127
+ raise Error, "Unhandled adapter : #{adapter_name}"
103
128
  end
104
129
  end
105
130
  end
data/sorbet/config ADDED
@@ -0,0 +1,4 @@
1
+ --dir
2
+ .
3
+ --ignore=tmp/
4
+ --ignore=vendor/
@@ -0,0 +1,17 @@
1
+ # typed: strict
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This file was pulled from a central RBI files repository.
5
+ # Please run `bin/tapioca annotations` to update it.
6
+
7
+ module Faraday
8
+ class << self
9
+ sig { params(url: T.untyped, options: T::Hash[Symbol, T.untyped], block: T.nilable(T.proc.params(connection: Faraday::Connection).void)).returns(Faraday::Connection) }
10
+ def new(url = nil, options = {}, &block); end
11
+ end
12
+ end
13
+
14
+ class Faraday::Response
15
+ sig { returns(T::Boolean) }
16
+ def success?; end
17
+ end