ruby-lokalise-api 2.8.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODE_OF_CONDUCT.md +1 -1
  3. data/.github/CONTRIBUTING.md +2 -2
  4. data/CHANGELOG.md +46 -0
  5. data/Gemfile +2 -0
  6. data/README.md +293 -178
  7. data/Rakefile +6 -1
  8. data/lib/ruby-lokalise-api.rb +4 -0
  9. data/lib/ruby-lokalise-api/client.rb +18 -4
  10. data/lib/ruby-lokalise-api/collections/base.rb +6 -2
  11. data/lib/ruby-lokalise-api/collections/branch.rb +3 -1
  12. data/lib/ruby-lokalise-api/collections/contributor.rb +2 -0
  13. data/lib/ruby-lokalise-api/collections/custom_translation_status.rb +3 -1
  14. data/lib/ruby-lokalise-api/collections/file.rb +2 -0
  15. data/lib/ruby-lokalise-api/collections/key.rb +2 -0
  16. data/lib/ruby-lokalise-api/collections/key_comment.rb +2 -0
  17. data/lib/ruby-lokalise-api/collections/order.rb +2 -0
  18. data/lib/ruby-lokalise-api/collections/payment_card.rb +2 -0
  19. data/lib/ruby-lokalise-api/collections/project.rb +2 -0
  20. data/lib/ruby-lokalise-api/collections/project_comment.rb +2 -0
  21. data/lib/ruby-lokalise-api/collections/project_language.rb +2 -0
  22. data/lib/ruby-lokalise-api/collections/queued_process.rb +15 -0
  23. data/lib/ruby-lokalise-api/collections/screenshot.rb +2 -0
  24. data/lib/ruby-lokalise-api/collections/snapshot.rb +2 -0
  25. data/lib/ruby-lokalise-api/collections/system_language.rb +2 -0
  26. data/lib/ruby-lokalise-api/collections/task.rb +2 -0
  27. data/lib/ruby-lokalise-api/collections/team.rb +2 -0
  28. data/lib/ruby-lokalise-api/collections/team_user.rb +2 -0
  29. data/lib/ruby-lokalise-api/collections/team_user_group.rb +3 -1
  30. data/lib/ruby-lokalise-api/collections/translation.rb +2 -0
  31. data/lib/ruby-lokalise-api/collections/translation_provider.rb +2 -0
  32. data/lib/ruby-lokalise-api/collections/webhook.rb +2 -0
  33. data/lib/ruby-lokalise-api/connection.rb +3 -1
  34. data/lib/ruby-lokalise-api/data/attributes.json +28 -13
  35. data/lib/ruby-lokalise-api/error.rb +2 -0
  36. data/lib/ruby-lokalise-api/json_handler.rb +4 -0
  37. data/lib/ruby-lokalise-api/request.rb +10 -1
  38. data/lib/ruby-lokalise-api/resources/base.rb +53 -21
  39. data/lib/ruby-lokalise-api/resources/branch.rb +3 -1
  40. data/lib/ruby-lokalise-api/resources/contributor.rb +4 -2
  41. data/lib/ruby-lokalise-api/resources/custom_translation_status.rb +4 -2
  42. data/lib/ruby-lokalise-api/resources/file.rb +5 -1
  43. data/lib/ruby-lokalise-api/resources/key.rb +3 -1
  44. data/lib/ruby-lokalise-api/resources/key_comment.rb +5 -3
  45. data/lib/ruby-lokalise-api/resources/order.rb +4 -0
  46. data/lib/ruby-lokalise-api/resources/payment_card.rb +3 -1
  47. data/lib/ruby-lokalise-api/resources/project.rb +3 -1
  48. data/lib/ruby-lokalise-api/resources/project_comment.rb +3 -1
  49. data/lib/ruby-lokalise-api/resources/project_language.rb +5 -3
  50. data/lib/ruby-lokalise-api/resources/queued_process.rb +18 -0
  51. data/lib/ruby-lokalise-api/resources/screenshot.rb +3 -1
  52. data/lib/ruby-lokalise-api/resources/snapshot.rb +5 -1
  53. data/lib/ruby-lokalise-api/resources/system_language.rb +3 -1
  54. data/lib/ruby-lokalise-api/resources/task.rb +3 -1
  55. data/lib/ruby-lokalise-api/resources/team.rb +2 -0
  56. data/lib/ruby-lokalise-api/resources/team_user.rb +4 -2
  57. data/lib/ruby-lokalise-api/resources/team_user_group.rb +6 -3
  58. data/lib/ruby-lokalise-api/resources/translation.rb +3 -1
  59. data/lib/ruby-lokalise-api/resources/translation_provider.rb +5 -0
  60. data/lib/ruby-lokalise-api/resources/webhook.rb +13 -3
  61. data/lib/ruby-lokalise-api/rest/branches.rb +2 -0
  62. data/lib/ruby-lokalise-api/rest/comments.rb +7 -5
  63. data/lib/ruby-lokalise-api/rest/contributors.rb +7 -5
  64. data/lib/ruby-lokalise-api/rest/custom_translation_statuses.rb +8 -6
  65. data/lib/ruby-lokalise-api/rest/files.rb +5 -3
  66. data/lib/ruby-lokalise-api/rest/keys.rb +9 -7
  67. data/lib/ruby-lokalise-api/rest/languages.rb +8 -6
  68. data/lib/ruby-lokalise-api/rest/orders.rb +2 -0
  69. data/lib/ruby-lokalise-api/rest/payment_cards.rb +5 -3
  70. data/lib/ruby-lokalise-api/rest/projects.rb +8 -6
  71. data/lib/ruby-lokalise-api/rest/queued_processes.rb +26 -0
  72. data/lib/ruby-lokalise-api/rest/screenshots.rb +7 -5
  73. data/lib/ruby-lokalise-api/rest/snapshots.rb +6 -4
  74. data/lib/ruby-lokalise-api/rest/tasks.rb +7 -5
  75. data/lib/ruby-lokalise-api/rest/team_user_group.rb +6 -4
  76. data/lib/ruby-lokalise-api/rest/team_users.rb +6 -4
  77. data/lib/ruby-lokalise-api/rest/teams.rb +3 -1
  78. data/lib/ruby-lokalise-api/rest/translation_providers.rb +4 -2
  79. data/lib/ruby-lokalise-api/rest/translations.rb +5 -3
  80. data/lib/ruby-lokalise-api/rest/webhooks.rb +18 -5
  81. data/lib/ruby-lokalise-api/utils/attribute_helpers.rb +2 -0
  82. data/lib/ruby-lokalise-api/utils/endpoint_helpers.rb +2 -0
  83. data/lib/ruby-lokalise-api/utils/string_utils.rb +2 -0
  84. data/lib/ruby-lokalise-api/version.rb +3 -1
  85. data/ruby-lokalise-api.gemspec +9 -5
  86. data/spec/lib/ruby-lokalise-api/connection_spec.rb +10 -7
  87. data/spec/lib/ruby-lokalise-api/custom_json_parser_spec.rb +9 -5
  88. data/spec/lib/ruby-lokalise-api/error_spec.rb +15 -4
  89. data/spec/lib/ruby-lokalise-api/rest/branches_spec.rb +19 -5
  90. data/spec/lib/ruby-lokalise-api/rest/comments_spec.rb +19 -5
  91. data/spec/lib/ruby-lokalise-api/rest/contributors_spec.rb +18 -4
  92. data/spec/lib/ruby-lokalise-api/rest/custom_translation_statuses_spec.rb +18 -4
  93. data/spec/lib/ruby-lokalise-api/rest/files_spec.rb +21 -11
  94. data/spec/lib/ruby-lokalise-api/rest/keys_spec.rb +46 -26
  95. data/spec/lib/ruby-lokalise-api/rest/languages_spec.rb +20 -6
  96. data/spec/lib/ruby-lokalise-api/rest/orders_spec.rb +16 -2
  97. data/spec/lib/ruby-lokalise-api/rest/payment_cards_spec.rb +21 -5
  98. data/spec/lib/ruby-lokalise-api/rest/projects_spec.rb +18 -4
  99. data/spec/lib/ruby-lokalise-api/rest/queued_processes_spec.rb +57 -0
  100. data/spec/lib/ruby-lokalise-api/rest/screenshots_spec.rb +18 -4
  101. data/spec/lib/ruby-lokalise-api/rest/snapshots_spec.rb +31 -4
  102. data/spec/lib/ruby-lokalise-api/rest/tasks_spec.rb +18 -4
  103. data/spec/lib/ruby-lokalise-api/rest/team_user_groups_spec.rb +92 -6
  104. data/spec/lib/ruby-lokalise-api/rest/team_users_spec.rb +19 -4
  105. data/spec/lib/ruby-lokalise-api/rest/teams_spec.rb +2 -0
  106. data/spec/lib/ruby-lokalise-api/rest/translation_providers_spec.rb +9 -2
  107. data/spec/lib/ruby-lokalise-api/rest/translations_spec.rb +20 -6
  108. data/spec/lib/ruby-lokalise-api/rest/webhooks_spec.rb +54 -2
  109. data/spec/lib/ruby-lokalise-api/utils/snakecase_spec.rb +2 -0
  110. data/spec/lib/ruby-lokalise-api_spec.rb +12 -9
  111. data/spec/spec_helper.rb +8 -1
  112. data/spec/support/test_client.rb +2 -0
  113. data/spec/support/vcr.rb +2 -0
  114. metadata +59 -12
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake'
2
4
 
3
5
  begin
@@ -13,4 +15,7 @@ require 'rspec/core/rake_task'
13
15
  RSpec::Core::RakeTask.new(:spec)
14
16
 
15
17
  require 'rubocop/rake_task'
16
- RuboCop::RakeTask.new
18
+ RuboCop::RakeTask.new do |task|
19
+ task.requires << 'rubocop-performance'
20
+ task.requires << 'rubocop-rspec'
21
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'yaml'
3
5
  require 'addressable'
@@ -15,6 +17,7 @@ require 'ruby-lokalise-api/resources/base'
15
17
  require 'ruby-lokalise-api/resources/branch'
16
18
  require 'ruby-lokalise-api/resources/project'
17
19
  require 'ruby-lokalise-api/resources/project_language'
20
+ require 'ruby-lokalise-api/resources/queued_process'
18
21
  require 'ruby-lokalise-api/resources/key_comment'
19
22
  require 'ruby-lokalise-api/resources/contributor'
20
23
  require 'ruby-lokalise-api/resources/file'
@@ -41,6 +44,7 @@ require 'ruby-lokalise-api/collections/team'
41
44
  require 'ruby-lokalise-api/collections/system_language'
42
45
  require 'ruby-lokalise-api/collections/project_language'
43
46
  require 'ruby-lokalise-api/collections/project_comment'
47
+ require 'ruby-lokalise-api/collections/queued_process'
44
48
  require 'ruby-lokalise-api/collections/key_comment'
45
49
  require 'ruby-lokalise-api/collections/key'
46
50
  require 'ruby-lokalise-api/collections/contributor'
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'ruby-lokalise-api/rest/branches'
2
4
  require 'ruby-lokalise-api/rest/languages'
3
5
  require 'ruby-lokalise-api/rest/teams'
4
6
  require 'ruby-lokalise-api/rest/projects'
7
+ require 'ruby-lokalise-api/rest/queued_processes'
5
8
  require 'ruby-lokalise-api/rest/comments'
6
9
  require 'ruby-lokalise-api/rest/keys'
7
10
  require 'ruby-lokalise-api/rest/contributors'
@@ -25,14 +28,25 @@ module Lokalise
25
28
 
26
29
  def initialize(token, params = {})
27
30
  @token = token
28
- @timeout = params.fetch(:timeout) { nil }
29
- @open_timeout = params.fetch(:open_timeout) { nil }
31
+ @timeout = params.fetch(:timeout, nil)
32
+ @open_timeout = params.fetch(:open_timeout, nil)
30
33
  end
31
34
 
32
- def construct_request(klass, method, endpoint_ids, params = {}, object_key = nil)
35
+ # rubocop:disable Metrics/ParameterLists
36
+ # Constructs request to perform the specified action
37
+ # @param klass The actual class to call the method upon
38
+ # @param method [Symbol] The method to call (:new, :update, :create etc)
39
+ # @param endpoint_ids [Array, Hash] IDs that are used to generate the proper path to the endpoint
40
+ # @param params [Array, Hash] Request parameters
41
+ # @param object_key [String, Symbol] Key that should be used to wrap parameters into
42
+ # @param initial_ids [Array] IDs that should be used to generate base endpoint path. The base path is used for method chaining
43
+ def construct_request(klass, method, endpoint_ids, params = {}, object_key = nil, initial_ids = nil)
33
44
  path = klass.endpoint(*endpoint_ids)
34
- klass.send method, self, path, format_params(params, object_key)
45
+ formatted_params = format_params(params, object_key)
46
+ formatted_params[:_initial_path] = klass.endpoint(*initial_ids) if initial_ids
47
+ klass.send method, self, path, formatted_params
35
48
  end
49
+ # rubocop:enable Metrics/ParameterLists
36
50
 
37
51
  # Converts `params` to hash with arrays under the `object_key` key.
38
52
  # Used in bulk operations
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Base
@@ -7,7 +9,7 @@ module Lokalise
7
9
  extend Lokalise::Utils::EndpointHelpers
8
10
 
9
11
  attr_reader :total_pages, :total_results, :results_per_page, :current_page, :collection,
10
- :project_id, :team_id, :request_params, :client, :path
12
+ :project_id, :team_id, :request_params, :client, :path, :branch, :user_id
11
13
 
12
14
  # Initializes a new collection based on the response
13
15
  #
@@ -17,9 +19,11 @@ module Lokalise
17
19
  def initialize(response, params = {})
18
20
  produce_collection_for response
19
21
  populate_pagination_data_for response
20
- # Project and team id may not be present in some cases
22
+ # Project, team id, user id, and branch may not be present in some cases
21
23
  @project_id = response['content']['project_id']
22
24
  @team_id = response['content']['team_id']
25
+ @user_id = response['content']['user_id']
26
+ @branch = response['content']['branch']
23
27
  @request_params = params
24
28
  @client = response['client']
25
29
  @path = response['path']
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Branch < Base
4
- DATA_KEY_PLURAL = 'Branches'.freeze
6
+ DATA_KEY_PLURAL = 'Branches'
5
7
 
6
8
  class << self
7
9
  def endpoint(project_id, *_args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Contributor < Base
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class CustomTranslationStatus < Base
4
- DATA_KEY_PLURAL = 'CustomTranslationStatuses'.freeze
6
+ DATA_KEY_PLURAL = 'CustomTranslationStatuses'
5
7
 
6
8
  class << self
7
9
  def endpoint(project_id, *_args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class File < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Key < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class KeyComment < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Order < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class PaymentCard < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Project < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class ProjectComment < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class ProjectLanguage < Base
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lokalise
4
+ module Collections
5
+ class QueuedProcess < Base
6
+ DATA_KEY_PLURAL = 'Processes'
7
+
8
+ class << self
9
+ def endpoint(project_id, *_args)
10
+ path_from projects: [project_id, 'processes']
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Screenshot < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Snapshot < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class SystemLanguage < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Task < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Team < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class TeamUser < Base
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class TeamUserGroup < Base
4
- DATA_KEY = 'UserGroup'.freeze
6
+ DATA_KEY = 'UserGroup'
5
7
 
6
8
  class << self
7
9
  def endpoint(team_id, *_args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Translation < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class TranslationProvider < Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Collections
3
5
  class Webhook < Base
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Connection
3
- BASE_URL = 'https://api.lokalise.co/api2/'.freeze
5
+ BASE_URL = 'https://api.lokalise.com/api2/'
4
6
 
5
7
  def connection(client)
6
8
  options = {
@@ -21,11 +21,11 @@
21
21
  "email",
22
22
  "fullname",
23
23
  "created_at",
24
+ "created_at_timestamp",
24
25
  "is_admin",
25
26
  "is_reviewer",
26
27
  "languages",
27
- "admin_rights",
28
- "created_at_timestamp"
28
+ "admin_rights"
29
29
  ],
30
30
  "custom_translation_status": [
31
31
  "status_id",
@@ -39,6 +39,7 @@
39
39
  "key": [
40
40
  "key_id",
41
41
  "created_at",
42
+ "created_at_timestamp",
42
43
  "key_name",
43
44
  "filenames",
44
45
  "description",
@@ -55,7 +56,10 @@
55
56
  "base_words",
56
57
  "char_limit",
57
58
  "custom_attributes",
58
- "created_at_timestamp"
59
+ "modified_at",
60
+ "modified_at_timestamp",
61
+ "translations_modified_at",
62
+ "translations_modified_at_timestamp"
59
63
  ],
60
64
  "language": [
61
65
  "lang_id",
@@ -70,6 +74,7 @@
70
74
  "card_id",
71
75
  "status",
72
76
  "created_at",
77
+ "created_at_timestamp",
73
78
  "created_by",
74
79
  "created_by_email",
75
80
  "source_language_iso",
@@ -81,8 +86,7 @@
81
86
  "translation_tier",
82
87
  "translation_tier_name",
83
88
  "briefing",
84
- "total",
85
- "created_at_timestamp"
89
+ "total"
86
90
  ],
87
91
  "payment_card": [
88
92
  "card_id",
@@ -96,15 +100,26 @@
96
100
  "name",
97
101
  "description",
98
102
  "created_at",
103
+ "created_at_timestamp",
99
104
  "created_by",
100
105
  "created_by_email",
101
106
  "team_id",
102
- "created_at_timestamp",
103
107
  "base_language_id",
104
108
  "base_language_iso",
105
109
  "settings",
106
110
  "statistics"
107
111
  ],
112
+ "queued_process": [
113
+ "process_id",
114
+ "type",
115
+ "status",
116
+ "message",
117
+ "created_by",
118
+ "created_by_email",
119
+ "created_at",
120
+ "created_at_timestamp",
121
+ "details"
122
+ ],
108
123
  "screenshot": [
109
124
  "screenshot_id",
110
125
  "key_ids",
@@ -121,9 +136,9 @@
121
136
  "snapshot_id",
122
137
  "title",
123
138
  "created_at",
139
+ "created_at_timestamp",
124
140
  "created_by",
125
- "created_by_email",
126
- "created_at_timestamp"
141
+ "created_by_email"
127
142
  ],
128
143
  "task": [
129
144
  "task_id",
@@ -157,18 +172,18 @@
157
172
  "team_id",
158
173
  "name",
159
174
  "created_at",
175
+ "created_at_timestamp",
160
176
  "plan",
161
177
  "quota_usage",
162
- "quota_allowed",
163
- "created_at_timestamp"
178
+ "quota_allowed"
164
179
  ],
165
180
  "team_user": [
166
181
  "user_id",
167
182
  "email",
168
183
  "fullname",
169
184
  "created_at",
170
- "role",
171
- "created_at_timestamp"
185
+ "created_at_timestamp",
186
+ "role"
172
187
  ],
173
188
  "team_user_group": [
174
189
  "group_id",
@@ -211,4 +226,4 @@
211
226
  "events",
212
227
  "event_lang_map"
213
228
  ]
214
- }
229
+ }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  class Error < StandardError
3
5
  ClientError = Class.new(self)
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
1
5
  module Lokalise
2
6
  module JsonHandler
3
7
  # JSON custom parser. Uses built-in JSON by default but can be overridden to any other parser
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Lokalise
2
4
  module Request
3
5
  include Lokalise::Connection
@@ -27,6 +29,13 @@ module Lokalise
27
29
  )
28
30
  end
29
31
 
32
+ def patch(path, client, params = {})
33
+ respond_with(
34
+ connection(client).patch(prepare(path), params.any? ? custom_dump(params) : nil),
35
+ client
36
+ )
37
+ end
38
+
30
39
  def delete(path, client, params = {})
31
40
  respond_with(
32
41
  # Rubocop tries to replace `delete` with `gsub` but that's a different method here!
@@ -43,7 +52,7 @@ module Lokalise
43
52
 
44
53
  # Get rid of double slashes in the `path`, leading and trailing slash
45
54
  def prepare(path)
46
- path.gsub(%r{\A/}, '').gsub(%r{//}, '/').gsub(%r{/+\z}, '')
55
+ path.delete_prefix('/').gsub(%r{//}, '/').gsub(%r{/+\z}, '')
47
56
  end
48
57
 
49
58
  def respond_with(response, client)