parking_ticket 1.0.46 → 1.0.49

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 (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 +107 -53
  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,
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.46'
5
+ VERSION = '1.0.49'
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