diff --git a/lib/scalingo/api/client.rb b/lib/scalingo/api/client.rb index a7ba304..e2df212 100644 --- a/lib/scalingo/api/client.rb +++ b/lib/scalingo/api/client.rb @@ -47,9 +47,7 @@ def self.register_handler!(method_name, klass) def inspect str = %(<#{self.class}:0x#{object_id.to_s(16)} url:"#{@url}" methods:) - methods = self.class.instance_methods - Scalingo::API::Client.instance_methods - str << methods.to_s - + str << self.class.instance_methods(false).to_s str << ">" str end diff --git a/lib/scalingo/api/endpoint.rb b/lib/scalingo/api/endpoint.rb index 5698a23..ca729af 100644 --- a/lib/scalingo/api/endpoint.rb +++ b/lib/scalingo/api/endpoint.rb @@ -1,3 +1,4 @@ +require "addressable/template" require "forwardable" module Scalingo @@ -6,6 +7,32 @@ class Endpoint extend Forwardable attr_reader :client + # Add a handler for a given endpoint + %i[get post put patch delete].each do |method| + # @example + # class Example < API::Endpoint + # get :all, "some-endpoint/{id}/subthings{?query*}", optional: [:query] + # post :create, "some-endpoint", root_key: :subthing + # end + define_singleton_method(method) do |name, path, **default_attrs, &default_block| + # @example + # endpoint = Example.new + # endpoint.all(id: "1", query: {page: 1}) + # endpoint.create(name: "thing") + define_method(name) do |**runtime_attrs, &runtime_block| + params = {**default_attrs, **runtime_attrs} + + request(method, path, **params) do |req| + default_block&.call(req, params) + runtime_block&.call(req, params) + end + end + end + + # Those methods are not meant to be used outside of a class definition + private_class_method method + end + def initialize(client) @client = client end @@ -13,12 +40,56 @@ def initialize(client) def_delegator :client, :connection def_delegator :client, :database_connection + # Perform a request to the API + def request(method, path, body: nil, root_key: nil, connected: true, basic: nil, dry_run: false, **params, &block) + # path can be an URI template + # see https://github.com/sporkmonger/addressable?tab=readme-ov-file#uri-templates + # see https://www.rfc-editor.org/rfc/rfc6570.txt + template = Addressable::Template.new(path) + + # If the template has keys, we need to expand it with the params + if template.keys.present? + # We assume every variable in the template is required + expected_keys = Set.new(template.keys.map(&:to_sym)) + # ... but we can opt out by specifying :optional when performing the request or in the endpoint definition + expected_keys -= params[:optional] if params[:optional].present? + + # if any required key is missing, raise an error with the missing keys, + # as if it was a regular keyword argument that was not supplied + if expected_keys.present? + received_keys = Set.new(params.keys.map(&:to_sym)) + + unless received_keys.superset?(expected_keys) + missings = (expected_keys - received_keys).map { |item| sprintf("%p", item) }.join(" ") + raise ArgumentError, "missing keyword: #{missings}" + end + end + + # Now, we can expand the template with the supplied params + actual_path = template.expand(params).to_s + else + # Otherwise, it's not a template but a string to be used as it is + actual_path = path + end + + # we nest the given body under the root_key if it's present + request_body = body + request_body = {root_key => body} if request_body && root_key + + # We can use the client in either connected or unconnected mode + conn = connected ? client.authenticated_connection : client.unauthenticated_connection + + # We can specify basic auth credentials if needed + conn.request :authorization, :basic, basic[:user], basic[:password] if basic.present? + + # Finally, perform the request + conn.public_send(method, actual_path, request_body, &block) + end + def inspect str = %(<#{self.class}:0x#{object_id.to_s(16)} base_url:"#{@client.url}" endpoints:) - methods = self.class.instance_methods - Scalingo::API::Endpoint.instance_methods - - str << methods.to_s + str << self.class.instance_methods(false).to_s str << ">" str end diff --git a/lib/scalingo/auth/keys.rb b/lib/scalingo/auth/keys.rb index 64f6449..836b332 100644 --- a/lib/scalingo/auth/keys.rb +++ b/lib/scalingo/auth/keys.rb @@ -2,48 +2,9 @@ module Scalingo class Auth::Keys < API::Endpoint - def all(headers = nil, &block) - data = nil - - connection.get( - "keys", - data, - headers, - &block - ) - end - - def show(id, headers = nil, &block) - data = nil - - connection.get( - "keys/#{id}", - data, - headers, - &block - ) - end - - def create(payload, headers = nil, &block) - data = {key: payload} - - connection.post( - "keys", - data, - headers, - &block - ) - end - - def destroy(id, headers = nil, &block) - data = nil - - connection.delete( - "keys/#{id}", - data, - headers, - &block - ) - end + get :all, "keys" + get :show, "keys/{id}" + post :create, "keys", root_key: :key + delete :destroy, "keys/{id}" end end diff --git a/lib/scalingo/auth/scm_integrations.rb b/lib/scalingo/auth/scm_integrations.rb index 224aa85..f78abef 100644 --- a/lib/scalingo/auth/scm_integrations.rb +++ b/lib/scalingo/auth/scm_integrations.rb @@ -2,48 +2,9 @@ module Scalingo class Auth::ScmIntegrations < API::Endpoint - def all(headers = nil, &block) - data = nil - - connection.get( - "scm_integrations", - data, - headers, - &block - ) - end - - def show(id, headers = nil, &block) - data = nil - - connection.get( - "scm_integrations/#{id}", - data, - headers, - &block - ) - end - - def create(payload, headers = nil, &block) - data = {scm_integration: payload} - - connection.post( - "scm_integrations", - data, - headers, - &block - ) - end - - def destroy(id, headers = nil, &block) - data = nil - - connection.delete( - "scm_integrations/#{id}", - data, - headers, - &block - ) - end + get :all, "scm_integrations" + get :show, "scm_integrations/{id}" + post :create, "scm_integrations", root_key: :scm_integration + delete :destroy, "scm_integrations/{id}" end end diff --git a/lib/scalingo/auth/tokens.rb b/lib/scalingo/auth/tokens.rb index f3cc5a0..5da8bfe 100644 --- a/lib/scalingo/auth/tokens.rb +++ b/lib/scalingo/auth/tokens.rb @@ -2,67 +2,10 @@ module Scalingo class Auth::Tokens < API::Endpoint - def exchange(token, headers = nil, &block) - data = nil - - authorization = Faraday::Utils.basic_header_from("", token) - - request_headers = { - Faraday::Request::Authorization::KEY => authorization - } - - request_headers.update(headers) if headers - - client.unauthenticated_connection.post( - "tokens/exchange", - data, - request_headers, - &block - ) - end - - def all(headers = nil, &block) - data = nil - - connection.get( - "tokens", - data, - headers, - &block - ) - end - - def create(payload, headers = nil, &block) - data = {token: payload} - - connection.post( - "tokens", - data, - headers, - &block - ) - end - - def renew(id, headers = nil, &block) - data = nil - - connection.patch( - "tokens/#{id}/renew", - data, - headers, - &block - ) - end - - def destroy(id, headers = nil, &block) - data = nil - - connection.delete( - "tokens/#{id}", - data, - headers, - &block - ) - end + post :exchange, "tokens/exchange", connected: false + get :all, "tokens" + post :create, "tokens", root_key: :token + patch :renew, "tokens/{id}/renew" + delete :destroy, "tokens/{id}" end end diff --git a/lib/scalingo/auth/two_factor_auth.rb b/lib/scalingo/auth/two_factor_auth.rb index ae5e7b3..fb2c2f1 100644 --- a/lib/scalingo/auth/two_factor_auth.rb +++ b/lib/scalingo/auth/two_factor_auth.rb @@ -2,52 +2,9 @@ module Scalingo class Auth::TwoFactorAuth < API::Endpoint - TOTP_PROVIDER = "totp" - DEFAULT_PROVIDER = TOTP_PROVIDER - SUPPORTED_PROVIDERS = [TOTP_PROVIDER] - - def status(headers = nil, &block) - data = nil - - connection.get( - "client/tfa", - data, - headers, - &block - ) - end - - def initiate(provider = DEFAULT_PROVIDER, headers = nil, &block) - data = {tfa: {provider: provider}} - - connection.post( - "client/tfa", - data, - headers, - &block - ) - end - - def validate(attempt, headers = nil, &block) - data = {tfa: {attempt: attempt}} - - connection.post( - "client/tfa/validate", - data, - headers, - &block - ) - end - - def disable(headers = nil, &block) - data = nil - - connection.delete( - "client/tfa", - data, - headers, - &block - ) - end + get :status, "client/tfa" + post :initiate, "client/tfa", root_key: :tfa + post :validate, "client/tfa/validate", root_key: :tfa + delete :disable, "client/tfa" end end diff --git a/lib/scalingo/auth/user.rb b/lib/scalingo/auth/user.rb index 7557788..ac9ba68 100644 --- a/lib/scalingo/auth/user.rb +++ b/lib/scalingo/auth/user.rb @@ -2,37 +2,8 @@ module Scalingo class Auth::User < API::Endpoint - def self(headers = nil, &block) - data = nil - - connection.get( - "users/self", - data, - headers, - &block - ) - end - - def update(payload, headers = nil, &block) - data = {user: payload} - - connection.put( - "users/account", - data, - headers, - &block - ) - end - - def stop_free_trial(headers = nil, &block) - data = nil - - connection.post( - "users/stop_free_trial", - data, - headers, - &block - ) - end + get :self, "users/self" + put :update, "users/account", root_key: :user + post :stop_free_trial, "users/stop_free_trial" end end diff --git a/lib/scalingo/billing/profile.rb b/lib/scalingo/billing/profile.rb index 362f3ba..8e21252 100644 --- a/lib/scalingo/billing/profile.rb +++ b/lib/scalingo/billing/profile.rb @@ -2,38 +2,9 @@ module Scalingo class Billing::Profile < API::Endpoint - def show(headers = nil, &block) - data = nil - - connection.get( - "profile", - data, - headers, - &block - ) - end - - def create(payload = {}, headers = nil, &block) - data = {profile: payload} - - connection.post( - "profiles", - data, - headers, - &block - ) - end - - def update(id, payload = {}, headers = nil, &block) - data = {profile: payload} - - connection.put( - "profiles/#{id}", - data, - headers, - &block - ) - end + get :show, "profile" + post :create, "profiles", root_key: :profile + put :update, "profiles/{id}", root_key: :profile alias_method :self, :show end diff --git a/lib/scalingo/core_client.rb b/lib/scalingo/core_client.rb index 1a38eb4..90c6e51 100644 --- a/lib/scalingo/core_client.rb +++ b/lib/scalingo/core_client.rb @@ -60,7 +60,7 @@ def authenticate_with(access_token: nil, bearer_token: nil, expires_at: nil) if access_token expiration = Time.now + config.exchanged_token_validity - response = auth.tokens.exchange(access_token) + response = auth.tokens.exchange(basic: {password: access_token}) if response.success? self.token = BearerToken.new( diff --git a/lib/scalingo/regional/addons.rb b/lib/scalingo/regional/addons.rb index dbf1165..325314a 100644 --- a/lib/scalingo/regional/addons.rb +++ b/lib/scalingo/regional/addons.rb @@ -2,118 +2,28 @@ module Scalingo class Regional::Addons < API::Endpoint - def for(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/addons", - data, - headers, - &block - ) - end - - def find(app_id, addon_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/addons/#{addon_id}", - data, - headers, - &block - ) - end - - def provision(app_id, payload = {}, headers = nil, &block) - data = {addon: payload} - - connection.post( - "apps/#{app_id}/addons", - data, - headers, - &block - ) - end - - def update(app_id, addon_id, payload = {}, headers = nil, &block) - data = {addon: payload} - - connection.patch( - "apps/#{app_id}/addons/#{addon_id}", - data, - headers, - &block - ) - end - - def destroy(app_id, addon_id, headers = nil, &block) - data = nil - - connection.delete( - "apps/#{app_id}/addons/#{addon_id}", - data, - headers, - &block - ) - end - - def sso(app_id, addon_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/addons/#{addon_id}/sso", - data, - headers, - &block - ) - end - - def authenticate!(app_id, addon_id, headers = nil, &block) - response = token(app_id, addon_id, headers, &block) + get :for, "apps/{app_id}/addons" + get :find, "apps/{app_id}/addons/{id}" + post :provision, "apps/{app_id}/addons", root_key: :addon + patch :update, "apps/{app_id}/addons/{id}", root_key: :addon + delete :destroy, "apps/{app_id}/addons/{id}" + get :sso, "apps/{app_id}/addons/{id}/sso" + post :token, "apps/{app_id}/addons/{id}/token" + get :categories, "addon_categories", connected: false + get :providers, "addon_providers", connected: false + + def authenticate!(**params, &block) + response = token(**params, &block) return response unless response.status == 200 - token = response.body[:token] client.token_holder.authenticate_database_with_bearer_token( - addon_id, - token, + params[:id], + response.body[:token], expires_at: Time.now + 1.hour, raise_on_expired_token: client.config.raise_on_expired_token ) response end - - def token(app_id, addon_id, headers = nil, &block) - data = nil - - connection.post( - "apps/#{app_id}/addons/#{addon_id}/token", - data, - headers, - &block - ) - end - - def categories(headers = nil, &block) - data = nil - - connection(fallback_to_guest: true).get( - "addon_categories", - data, - headers, - &block - ) - end - - def providers(headers = nil, &block) - data = nil - - connection(fallback_to_guest: true).get( - "addon_providers", - data, - headers, - &block - ) - end end end diff --git a/lib/scalingo/regional/apps.rb b/lib/scalingo/regional/apps.rb index bae29bd..7349e1c 100644 --- a/lib/scalingo/regional/apps.rb +++ b/lib/scalingo/regional/apps.rb @@ -2,92 +2,16 @@ module Scalingo class Regional::Apps < API::Endpoint - def all(headers = nil, &block) - data = nil - - connection.get( - "apps", - data, - headers, - &block - ) - end - - def find(id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{id}", - data, - headers, - &block - ) - end - - def create(payload = {}, headers = nil, &block) - data = {app: payload} - - dry_run = !!(payload[:dry_run] || payload["dry_run"]) - - request_headers = {} - request_headers["X-Dry-Run"] = "true" if dry_run - request_headers.update(headers) if headers - - connection.post( - "apps", - data, - request_headers, - &block - ) - end - - def update(id, payload = {}, headers = nil, &block) - data = {app: payload} - - connection.patch( - "apps/#{id}", - data, - headers, - &block - ) - end - - def logs_url(id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{id}/logs", - data, - headers, - &block - ) - end - - def destroy(id, payload = {}, headers = nil, &block) - connection.delete( - "apps/#{id}", - payload, - headers, - &block - ) - end - - def rename(id, payload = {}, headers = nil, &block) - connection.post( - "apps/#{id}/rename", - payload, - headers, - &block - ) - end - - def transfer(id, payload = {}, headers = nil, &block) - connection.patch( - "apps/#{id}", - payload, - headers, - &block - ) + get :all, "apps" + get :find, "apps/{id}" + get :logs_url, "apps/{id}/logs" + post :rename, "apps/{id}/rename" + patch :update, "apps/{id}", root_key: :app + patch :transfer, "apps/{id}" + delete :destroy, "apps/{id}" + + post :create, "apps", root_key: :app do |req, params| + req.headers["X-Dry-Run"] = "true" if params[:dry_run] end end end diff --git a/lib/scalingo/regional/autoscalers.rb b/lib/scalingo/regional/autoscalers.rb index 046c338..75d51e7 100644 --- a/lib/scalingo/regional/autoscalers.rb +++ b/lib/scalingo/regional/autoscalers.rb @@ -2,59 +2,10 @@ module Scalingo class Regional::Autoscalers < API::Endpoint - def for(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/autoscalers", - data, - headers, - &block - ) - end - - def find(app_id, autoscaler_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/autoscalers/#{autoscaler_id}", - data, - headers, - &block - ) - end - - def create(app_id, payload = {}, headers = nil, &block) - data = {autoscaler: payload} - - connection.post( - "apps/#{app_id}/autoscalers", - data, - headers, - &block - ) - end - - def update(app_id, autoscaler_id, payload = {}, headers = nil, &block) - data = {autoscaler: payload} - - connection.patch( - "apps/#{app_id}/autoscalers/#{autoscaler_id}", - data, - headers, - &block - ) - end - - def destroy(app_id, autoscaler_id, headers = nil, &block) - data = nil - - connection.delete( - "apps/#{app_id}/autoscalers/#{autoscaler_id}", - data, - headers, - &block - ) - end + get :for, "apps/{app_id}/autoscalers" + get :find, "apps/{app_id}/autoscalers/{id}" + post :create, "apps/{app_id}/autoscalers", root_key: :autoscaler + patch :update, "apps/{app_id}/autoscalers/{id}", root_key: :autoscaler + delete :destroy, "apps/{app_id}/autoscalers/{id}" end end diff --git a/lib/scalingo/regional/collaborators.rb b/lib/scalingo/regional/collaborators.rb index 92307f0..315654f 100644 --- a/lib/scalingo/regional/collaborators.rb +++ b/lib/scalingo/regional/collaborators.rb @@ -2,48 +2,9 @@ module Scalingo class Regional::Collaborators < API::Endpoint - def for(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/collaborators", - data, - headers, - &block - ) - end - - def destroy(app_id, collaborator_id, headers = nil, &block) - data = nil - - connection.delete( - "apps/#{app_id}/collaborators/#{collaborator_id}", - data, - headers, - &block - ) - end - - def invite(app_id, payload = {}, headers = nil, &block) - data = {collaborator: payload} - - connection.post( - "apps/#{app_id}/collaborators", - data, - headers, - &block - ) - end - - def accept(token, headers = nil, &block) - data = {token: token} - - connection.get( - "apps/collaboration", - data, - headers, - &block - ) - end + get :for, "apps/{app_id}/collaborators" + get :accept, "apps/collaboration", root_key: "token" + post :invite, "apps/{app_id}/collaborators", root_key: "collaborator" + delete :destroy, "apps/{app_id}/collaborators/{id}" end end diff --git a/lib/scalingo/regional/containers.rb b/lib/scalingo/regional/containers.rb index f1e1954..ef2d534 100644 --- a/lib/scalingo/regional/containers.rb +++ b/lib/scalingo/regional/containers.rb @@ -2,48 +2,9 @@ module Scalingo class Regional::Containers < API::Endpoint - def for(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/containers", - data, - headers, - &block - ) - end - - def scale(app_id, formation, headers = nil, &block) - data = {containers: formation} - - connection.post( - "apps/#{app_id}/scale", - data, - headers, - &block - ) - end - - def restart(app_id, scope = [], headers = nil, &block) - data = {scope: scope} - - connection.post( - "apps/#{app_id}/restart", - data, - headers, - &block - ) - end - - def sizes(headers = nil, &block) - data = nil - - connection(fallback_to_guest: true).get( - "features/container_sizes", - data, - headers, - &block - ) - end + get :for, "apps/{app_id}/containers" + post :scale, "apps/{app_id}/scale", root_key: :containers + post :restart, "apps/{app_id}/restart", root_key: :scope + get :sizes, "features/container_sizes" end end diff --git a/lib/scalingo/regional/deployments.rb b/lib/scalingo/regional/deployments.rb index 6605585..e455fc0 100644 --- a/lib/scalingo/regional/deployments.rb +++ b/lib/scalingo/regional/deployments.rb @@ -2,37 +2,8 @@ module Scalingo class Regional::Deployments < API::Endpoint - def for(app_id, payload = {}, headers = nil, &block) - data = payload.compact - - connection.get( - "apps/#{app_id}/deployments", - data, - headers, - &block - ) - end - - def find(app_id, deployment_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/deployments/#{deployment_id}", - data, - headers, - &block - ) - end - - def logs(app_id, deployment_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/deployments/#{deployment_id}/output", - data, - headers, - &block - ) - end + get :for, "apps/{app_id}/deployments{?query*}", optional: [:query] + get :find, "apps/{app_id}/deployments/{id}" + get :logs, "apps/{app_id}/deployments/{id}/output" end end diff --git a/lib/scalingo/regional/domains.rb b/lib/scalingo/regional/domains.rb index c97d660..8cbb1fa 100644 --- a/lib/scalingo/regional/domains.rb +++ b/lib/scalingo/regional/domains.rb @@ -2,59 +2,10 @@ module Scalingo class Regional::Domains < API::Endpoint - def for(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/domains", - data, - headers, - &block - ) - end - - def find(app_id, domain_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/domains/#{domain_id}", - data, - headers, - &block - ) - end - - def create(app_id, payload = {}, headers = nil, &block) - data = {domain: payload} - - connection.post( - "apps/#{app_id}/domains", - data, - headers, - &block - ) - end - - def update(app_id, domain_id, payload = {}, headers = nil, &block) - data = {domain: payload} - - connection.patch( - "apps/#{app_id}/domains/#{domain_id}", - data, - headers, - &block - ) - end - - def destroy(app_id, domain_id, headers = nil, &block) - data = nil - - connection.delete( - "apps/#{app_id}/domains/#{domain_id}", - data, - headers, - &block - ) - end + get :for, "apps/{app_id}/domains" + get :find, "apps/{app_id}/domains/{id}" + post :create, "apps/{app_id}/domains", root_key: :domain + patch :update, "apps/{app_id}/domains/{id}", root_key: :domain + delete :destroy, "apps/{app_id}/domains/{id}" end end diff --git a/lib/scalingo/regional/environment.rb b/lib/scalingo/regional/environment.rb index d9b0774..c57bd27 100644 --- a/lib/scalingo/regional/environment.rb +++ b/lib/scalingo/regional/environment.rb @@ -2,70 +2,11 @@ module Scalingo class Regional::Environment < API::Endpoint - def for(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/variables", - data, - headers, - &block - ) - end - - def create(app_id, payload = {}, headers = nil, &block) - data = {variable: payload} - - connection.post( - "apps/#{app_id}/variables", - data, - headers, - &block - ) - end - - def update(app_id, variable_id, value, headers = nil, &block) - data = {variable: {value: value}} - - connection.patch( - "apps/#{app_id}/variables/#{variable_id}", - data, - headers, - &block - ) - end - - def destroy(app_id, variable_id, headers = nil, &block) - data = nil - - connection.delete( - "apps/#{app_id}/variables/#{variable_id}", - data, - headers, - &block - ) - end - - def bulk_update(app_id, variables, headers = nil, &block) - data = {variables: variables} - - connection.put( - "apps/#{app_id}/variables", - data, - headers, - &block - ) - end - - def bulk_destroy(app_id, variable_ids, headers = nil, &block) - data = {variable_ids: variable_ids} - - connection.delete( - "apps/#{app_id}/variables", - data, - headers, - &block - ) - end + get :for, "apps/{app_id}/variables" + post :create, "apps/{app_id}/variables", root_key: :variable + patch :update, "apps/{app_id}/variables/{id}", root_key: :variable + put :bulk_update, "apps/{app_id}/variables", root_key: :variables + delete :destroy, "apps/{app_id}/variables/{id}" + delete :bulk_destroy, "apps/{app_id}/variables", root_key: :variable_ids end end diff --git a/lib/scalingo/regional/events.rb b/lib/scalingo/regional/events.rb index 582879c..3dd6900 100644 --- a/lib/scalingo/regional/events.rb +++ b/lib/scalingo/regional/events.rb @@ -1,47 +1,8 @@ module Scalingo class Regional::Events < API::Endpoint - def all(payload = {}, headers = nil, &block) - data = payload.compact - - connection.get( - "events", - data, - headers, - &block - ) - end - - def for(app_id, payload = {}, headers = nil, &block) - data = payload.compact - - connection.get( - "apps/#{app_id}/events", - data, - headers, - &block - ) - end - - def types(headers = nil, &block) - data = nil - - connection(fallback_to_guest: true).get( - "event_types", - data, - headers, - &block - ) - end - - def categories(headers = nil, &block) - data = nil - - connection(fallback_to_guest: true).get( - "event_categories", - data, - headers, - &block - ) - end + get :all, "events{?query*}", optional: [:query] + get :for, "apps/{app_id}/events{?query*}", optional: [:query] + get :types, "event_types" + get :categories, "event_categories" end end diff --git a/lib/scalingo/regional/logs.rb b/lib/scalingo/regional/logs.rb index a7ad752..61e2739 100644 --- a/lib/scalingo/regional/logs.rb +++ b/lib/scalingo/regional/logs.rb @@ -1,34 +1,21 @@ module Scalingo class Regional::Logs < API::Endpoint - def get(url, payload = {}, headers = nil, &block) - data = payload.compact + get :archives, "apps/{app_id}/logs_archives" - connection(fallback_to_guest: true).get( - url, - data, - headers, - &block - ) - end - - def archives(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/logs_archives", - data, - headers, - &block - ) + def get(url, **params, &block) + request(:get, url, **params) do |req| + block&.call(req, params) + req.params[:n] = params[:n] if params[:n].present? + end end ## Helper method to avoid having to manually chain two operations - def for(app_id, payload = {}, headers = nil, &block) - logs_response = scalingo.apps.logs_url(app_id) + def for(**params, &block) + logs_response = scalingo.apps.logs_url(**params) return logs_response unless logs_response.success? - get(logs_response.body, payload, headers, &block) + get(logs_response.body, **params, &block) end end end diff --git a/lib/scalingo/regional/metrics.rb b/lib/scalingo/regional/metrics.rb index 3b2169a..890f411 100644 --- a/lib/scalingo/regional/metrics.rb +++ b/lib/scalingo/regional/metrics.rb @@ -4,35 +4,7 @@ module Scalingo class Regional::Metrics < API::Endpoint - def for(app_id, payload = {}, headers = nil, &block) - payload = payload.with_indifferent_access - data = payload.except(:metric, :container_type, :container_index).compact - - metric = payload[:metric] - url = "apps/#{app_id}/stats/#{metric}" - - if payload[:container_type] - url = "#{url}/#{payload[:container_type]}" - url = "#{url}/#{payload[:container_index]}" if payload[:container_index] - end - - connection.get( - url, - data, - headers, - &block - ) - end - - def types(headers = nil, &block) - data = nil - - connection(fallback_to_guest: true).get( - "features/metrics", - data, - headers, - &block - ) - end + get :types, "/features/metrics" + get :for, "/apps/{app_id}/stats/{metric}{/container_type}{/container_index}", optional: [:container_type, :container_index] end end diff --git a/lib/scalingo/regional/notifiers.rb b/lib/scalingo/regional/notifiers.rb index 0dc8ffa..abc4d6b 100644 --- a/lib/scalingo/regional/notifiers.rb +++ b/lib/scalingo/regional/notifiers.rb @@ -2,81 +2,12 @@ module Scalingo class Regional::Notifiers < API::Endpoint - def for(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/notifiers", - data, - headers, - &block - ) - end - - def find(app_id, notifier_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/notifiers/#{notifier_id}", - data, - headers, - &block - ) - end - - def create(app_id, payload = {}, headers = nil, &block) - data = {notifier: payload} - - connection.post( - "apps/#{app_id}/notifiers", - data, - headers, - &block - ) - end - - def update(app_id, notifier_id, payload = {}, headers = nil, &block) - data = {notifier: payload} - - connection.patch( - "apps/#{app_id}/notifiers/#{notifier_id}", - data, - headers, - &block - ) - end - - def destroy(app_id, notifier_id, headers = nil, &block) - data = nil - - connection.delete( - "apps/#{app_id}/notifiers/#{notifier_id}", - data, - headers, - &block - ) - end - - def test(app_id, notifier_id, headers = nil, &block) - data = nil - - connection.post( - "apps/#{app_id}/notifiers/#{notifier_id}/test", - data, - headers, - &block - ) - end - - def platforms(headers = nil, &block) - data = nil - - connection(fallback_to_guest: true).get( - "notification_platforms", - data, - headers, - &block - ) - end + get :platforms, "/notification_platforms" + get :for, "/apps/{app_id}/notifiers" + get :find, "/apps/{app_id}/notifiers/{id}" + post :create, "/apps/{app_id}/notifiers", root_key: :notifier + post :test, "/apps/{app_id}/notifiers/{id}/test" + patch :update, "/apps/{app_id}/notifiers/{id}", root_key: :notifier + delete :destroy, "/apps/{app_id}/notifiers/{id}" end end diff --git a/lib/scalingo/regional/operations.rb b/lib/scalingo/regional/operations.rb index 15ef6c1..98198ab 100644 --- a/lib/scalingo/regional/operations.rb +++ b/lib/scalingo/regional/operations.rb @@ -2,23 +2,12 @@ module Scalingo class Regional::Operations < API::Endpoint - def find(app_id, operation_id, headers = nil, &block) - get( - "apps/#{app_id}/operations/#{operation_id}", - headers, - &block - ) - end - - def get(url, headers = nil, &block) - data = nil + get :find, "/apps/{app_id}/operations/{id}" - connection.get( - url, - data, - headers, - &block - ) + def get(url, **params, &block) + request(:get, url, **params) do |req| + block&.call(req, params) + end end end end diff --git a/lib/scalingo/regional/scm_repo_links.rb b/lib/scalingo/regional/scm_repo_links.rb index deb9443..4f5050a 100644 --- a/lib/scalingo/regional/scm_repo_links.rb +++ b/lib/scalingo/regional/scm_repo_links.rb @@ -2,92 +2,13 @@ module Scalingo class Regional::ScmRepoLinks < API::Endpoint - def show(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/scm_repo_link", - data, - headers, - &block - ) - end - - def create(app_id, payload = {}, headers = nil, &block) - data = {scm_repo_link: payload} - - connection.post( - "apps/#{app_id}/scm_repo_link", - data, - headers, - &block - ) - end - - def update(app_id, payload = {}, headers = nil, &block) - data = {scm_repo_link: payload} - - connection.patch( - "apps/#{app_id}/scm_repo_link", - data, - headers, - &block - ) - end - - def destroy(app_id, headers = nil, &block) - data = nil - - connection.delete( - "apps/#{app_id}/scm_repo_link", - data, - headers, - &block - ) - end - - def deploy(app_id, branch, headers = nil, &block) - data = {branch: branch} - - connection.post( - "apps/#{app_id}/scm_repo_link/manual_deploy", - data, - headers, - &block - ) - end - - def review_app(review_app, pull_request_id, headers = nil, &block) - data = {pull_request_id: pull_request_id} - - connection.post( - "apps/#{app_id}/scm_repo_link/manual_review_app", - data, - headers, - &block - ) - end - - def branches(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/scm_repo_link/branches", - data, - headers, - &block - ) - end - - def pulls(app_id, headers = nil, &block) - data = nil - - connection.get( - "apps/#{app_id}/scm_repo_link/pulls", - data, - headers, - &block - ) - end + get :show, "/apps/{app_id}/scm_repo_link" + get :branches, "/apps/{app_id}/scm_repo_link/branches" + get :pulls, "/apps/{app_id}/scm_repo_link/pulls" + post :create, "/apps/{app_id}/scm_repo_link", root_key: :scm_repo_link + post :deploy, "/apps/{app_id}/scm_repo_link/manual_deploy" + post :review_app, "/apps/{app_id}/scm_repo_link/manual_review_app" + patch :update, "/apps/{app_id}/scm_repo_link", root_key: :scm_repo_link + delete :destroy, "/apps/{app_id}/scm_repo_link" end end diff --git a/lib/scalingo/regional_database/backups.rb b/lib/scalingo/regional_database/backups.rb index 4ccafc1..59d3780 100644 --- a/lib/scalingo/regional_database/backups.rb +++ b/lib/scalingo/regional_database/backups.rb @@ -2,37 +2,8 @@ module Scalingo class RegionalDatabase::Backups < API::Endpoint - def create(addon_id, headers = nil, &block) - data = nil - - database_connection(addon_id).post( - "databases/#{addon_id}/backups", - data, - headers, - &block - ) - end - - def for(addon_id, headers = nil, &block) - data = nil - - database_connection(addon_id).get( - "databases/#{addon_id}/backups", - data, - headers, - &block - ) - end - - def archive(addon_id, backup_id, headers = nil, &block) - data = nil - - database_connection(addon_id).get( - "databases/#{addon_id}/backups/#{backup_id}/archive", - data, - headers, - &block - ) - end + get :for, "databases/{addon_id}/backups" + get :archive, "databases/{addon_id}/backups/{id}/archive" + post :create, "databases/{addon_id}/backups" end end diff --git a/lib/scalingo/regional_database/databases.rb b/lib/scalingo/regional_database/databases.rb index f2d0ddb..00fdfe6 100644 --- a/lib/scalingo/regional_database/databases.rb +++ b/lib/scalingo/regional_database/databases.rb @@ -2,26 +2,7 @@ module Scalingo class RegionalDatabase::Databases < API::Endpoint - def find(id, headers = nil, &block) - data = nil - - database_connection(id).get( - "databases/#{id}", - data, - headers, - &block - ) - end - - def upgrade(id, headers = nil, &block) - data = nil - - database_connection(id).post( - "databases/#{id}/upgrade", - data, - headers, - &block - ) - end + get :find, "databases/{id}" + post :upgrade, "databases/{id}/upgrade" end end diff --git a/samples/auth/two_factor_auth/_meta.json b/samples/auth/two_factor_auth/_meta.json index 52ea5d4..7fa8a6e 100644 --- a/samples/auth/two_factor_auth/_meta.json +++ b/samples/auth/two_factor_auth/_meta.json @@ -1,10 +1,11 @@ { "attempt": null, "initiate": { - "invalid": "wrong-provider" + "valid": {"provider": "totp"}, + "invalid": {"provider": "wrong-provider"} }, "validate": { - "valid": "975037", - "invalid": "wrong-attempt" + "valid": {"attempt": "975037"}, + "invalid": {"attempt": "wrong-attempt"} } -} \ No newline at end of file +} diff --git a/samples/billing/profile/create-400.json b/samples/billing/profile/create-400.json index 5e823fe..f4710a1 100644 --- a/samples/billing/profile/create-400.json +++ b/samples/billing/profile/create-400.json @@ -3,12 +3,7 @@ "method": "post", "request": { "headers": { - "Authorization": "Bearer the-bearer-token", - "Content-Type": "application/json" - }, - "json_body": { - "profile": { - } + "Authorization": "Bearer the-bearer-token" } }, "response": { @@ -24,4 +19,4 @@ "error": "profile is required" } } -} \ No newline at end of file +} diff --git a/samples/regional/apps/create-201-dry-run.json b/samples/regional/apps/create-201-dry-run.json new file mode 100644 index 0000000..afe75b8 --- /dev/null +++ b/samples/regional/apps/create-201-dry-run.json @@ -0,0 +1,67 @@ +{ + "path": "/apps", + "method": "post", + "request": { + "headers": { + "Authorization": "Bearer the-bearer-token", + "Content-Type": "application/json", + "X-Dry-Run": "true" + }, + "json_body": { + "app": { + "name": "some-example-app" + } + } + }, + "response": { + "status": 201, + "headers": { + "Date": "Fri, 29 May 2020 15:52:07 GMT", + "Etag": "W/\"bab706f1ac796504b56e336533ceee0f\"", + "Content-Type": "application/json; charset=utf-8", + "Transfer-Encoding": "chunked", + "Connection": "keep-alive", + "Cache-Control": "max-age=0, private, must-revalidate", + "Referrer-Policy": "strict-origin-when-cross-origin" + }, + "json_body": { + "app": { + "id": "5ed12fa6f112e2000f9f93f7", + "name": "some-example-app", + "parent_app_name": "", + "git_url": "git@staging.scalingo.com:some-example-app.git", + "url": "https://some-example-app.staging.scalingo.io", + "created_at": "2020-05-29T15:52:07.096Z", + "updated_at": "2020-05-29T15:52:07.096Z", + "status": "new", + "owner": { + "username": "example-username", + "email": "example@null.scalingo.com", + "id": "us-676bb0c1-1ca9-4682-8ee1-257422e9eab5", + "flags": { + "": true, + "admin": true + } + }, + "last_deployed_at": null, + "last_deployed_by": null, + "links": { + "deployments_stream": "wss://deployments-staging.scalingo.com/apps/some-example-app" + }, + "git_source": null, + "flags": { + }, + "limits": { + }, + "last_deployment_id": null, + "force_https": false, + "sticky_session": false, + "router_logs": false, + "stack_id": "st-66a577a9-7c41-4fbc-b8ac-07cebd91339b", + "base_url": "https://some-example-app.staging.scalingo.io", + "new_dashboard_url": null, + "new_region": null + } + } + } +} diff --git a/samples/regional/deployments/for-with-paging.json b/samples/regional/deployments/for-with-pages.json similarity index 97% rename from samples/regional/deployments/for-with-paging.json rename to samples/regional/deployments/for-with-pages.json index c0b073d..9c3fbea 100644 --- a/samples/regional/deployments/for-with-paging.json +++ b/samples/regional/deployments/for-with-pages.json @@ -19,7 +19,7 @@ }, "json_body": { "deployments": [ - + {"id": 1} ], "meta": { "pagination": { @@ -32,4 +32,4 @@ } } } -} \ No newline at end of file +} diff --git a/samples/regional/environment/_meta.json b/samples/regional/environment/_meta.json index 9548484..d412e63 100644 --- a/samples/regional/environment/_meta.json +++ b/samples/regional/environment/_meta.json @@ -12,7 +12,9 @@ } }, "update": { - "valid": "newvalue", + "valid": { + "value": "newvalue" + }, "bulk": [ { "name": "name1", diff --git a/samples/regional/scm_repo_links/_meta.json b/samples/regional/scm_repo_links/_meta.json index bca8c99..86d82fd 100644 --- a/samples/regional/scm_repo_links/_meta.json +++ b/samples/regional/scm_repo_links/_meta.json @@ -17,6 +17,8 @@ } }, "deploy": { - "valid": "master" + "valid": { + "branch": "master" + } } } diff --git a/samples/regional_database/backups/_meta.json b/samples/regional_database/backups/_meta.json index 2baf9c3..bc70f41 100644 --- a/samples/regional_database/backups/_meta.json +++ b/samples/regional_database/backups/_meta.json @@ -1,4 +1,4 @@ { "addon_id": "63bfe3b600deff4f0516cc12", - "backup_id": "5bb95a904ffb096e9a2831b8" + "id": "5bb95a904ffb096e9a2831b8" } diff --git a/spec/scalingo/auth/keys_spec.rb b/spec/scalingo/auth/keys_spec.rb index c6a9c0a..2c9415b 100644 --- a/spec/scalingo/auth/keys_spec.rb +++ b/spec/scalingo/auth/keys_spec.rb @@ -10,14 +10,14 @@ describe_method "create" do context "success" do - let(:arguments) { meta[:create][:valid] } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end context "unprocessable" do - let(:arguments) { meta[:create][:invalid] } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-422" } it_behaves_like "an unprocessable request" @@ -26,14 +26,14 @@ describe_method "show" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { {id: meta[:id]} } let(:stub_pattern) { "show-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { meta[:not_found_id] } + let(:params) { {id: meta[:not_found_id]} } let(:stub_pattern) { "show-404" } it_behaves_like "a not found response" @@ -42,14 +42,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { {id: meta[:id]} } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { meta[:not_found_id] } + let(:params) { {id: meta[:not_found_id]} } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/auth/scm_integrations_spec.rb b/spec/scalingo/auth/scm_integrations_spec.rb index 65c0d38..39a562c 100644 --- a/spec/scalingo/auth/scm_integrations_spec.rb +++ b/spec/scalingo/auth/scm_integrations_spec.rb @@ -10,14 +10,14 @@ describe_method "create" do context "success" do - let(:arguments) { meta[:create][:valid] } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end context "failure" do - let(:arguments) { meta[:create][:invalid] } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-422" } it_behaves_like "an unprocessable request" @@ -26,14 +26,14 @@ describe_method "show" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { {id: meta[:id]} } let(:stub_pattern) { "show-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { meta[:not_found_id] } + let(:params) { {id: meta[:not_found_id]} } let(:stub_pattern) { "show-404" } it_behaves_like "a not found response" @@ -42,14 +42,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { {id: meta[:id]} } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { meta[:not_found_id] } + let(:params) { {id: meta[:not_found_id]} } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/auth/tokens_spec.rb b/spec/scalingo/auth/tokens_spec.rb index de798b3..c8af105 100644 --- a/spec/scalingo/auth/tokens_spec.rb +++ b/spec/scalingo/auth/tokens_spec.rb @@ -5,7 +5,7 @@ subject { auth_guest.tokens } context "with a valid token" do - let(:arguments) { meta[:exchange][:valid] } + let(:basic) { {password: meta[:exchange][:valid]} } let(:stub_pattern) { "exchange-200" } it "is successful" do @@ -15,7 +15,7 @@ end context "with an invalid token" do - let(:arguments) { meta[:exchange][:invalid] } + let(:basic) { {password: meta[:exchange][:invalid]} } let(:stub_pattern) { "exchange-401" } it "is rejected with an valid token" do @@ -33,7 +33,7 @@ describe_method "create" do context "success" do - let(:arguments) { meta[:create][:valid] } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 @@ -42,14 +42,14 @@ describe_method "renew" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { {id: meta[:id]} } let(:stub_pattern) { "renew-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { meta[:not_found_id] } + let(:params) { {id: meta[:not_found_id]} } let(:stub_pattern) { "renew-404" } it_behaves_like "a not found response" @@ -58,14 +58,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { {id: meta[:id]} } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { meta[:not_found_id] } + let(:params) { {id: meta[:not_found_id]} } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/auth/two_factor_auth_spec.rb b/spec/scalingo/auth/two_factor_auth_spec.rb index 08cffee..8e39f94 100644 --- a/spec/scalingo/auth/two_factor_auth_spec.rb +++ b/spec/scalingo/auth/two_factor_auth_spec.rb @@ -9,20 +9,21 @@ describe_method "initiate" do context "success" do - let(:arguments) { Scalingo::Auth::TwoFactorAuth::DEFAULT_PROVIDER } + let(:body) { meta[:initiate][:valid] } let(:stub_pattern) { "initiate-success" } it_behaves_like "a singular object response", 201 end context "wrong provider" do - let(:arguments) { meta[:initiate][:invalid] } + let(:body) { meta[:initiate][:invalid] } let(:stub_pattern) { "initiate-wrong-provider" } it_behaves_like "a client error" end context "already enabled" do + let(:body) { meta[:initiate][:valid] } let(:stub_pattern) { "initiate-already-enabled" } it_behaves_like "a client error" @@ -31,7 +32,7 @@ describe_method "validate" do context "success" do - let(:arguments) { meta[:validate][:valid] } + let(:body) { meta[:validate][:valid] } let(:stub_pattern) { "validate-success" } let(:expected_keys) { %i[codes user] } @@ -39,14 +40,14 @@ end context "wrong provider" do - let(:arguments) { meta[:validate][:invalid] } + let(:body) { meta[:validate][:invalid] } let(:stub_pattern) { "validate-wrong" } it_behaves_like "a client error" end context "already enabled" do - let(:arguments) { meta[:validate][:invalid] } + let(:body) { meta[:validate][:invalid] } let(:stub_pattern) { "validate-not-initiated" } it_behaves_like "a client error" diff --git a/spec/scalingo/auth/user_spec.rb b/spec/scalingo/auth/user_spec.rb index 56cd49d..a7db45e 100644 --- a/spec/scalingo/auth/user_spec.rb +++ b/spec/scalingo/auth/user_spec.rb @@ -9,14 +9,14 @@ describe_method "update" do context "success" do - let(:arguments) { meta[:update][:valid] } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" end context "unprocessable" do - let(:arguments) { meta[:update][:invalid] } + let(:body) { meta[:update][:invalid] } let(:stub_pattern) { "update-422" } it_behaves_like "an unprocessable request" diff --git a/spec/scalingo/billing/profile_spec.rb b/spec/scalingo/billing/profile_spec.rb index 1260ea2..dfff233 100644 --- a/spec/scalingo/billing/profile_spec.rb +++ b/spec/scalingo/billing/profile_spec.rb @@ -17,7 +17,7 @@ describe_method "create" do context "success" do - let(:arguments) { meta[:create][:valid] } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 @@ -30,7 +30,7 @@ end context "unprocessable" do - let(:arguments) { meta[:create][:invalid] } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-422" } it_behaves_like "an unprocessable request" @@ -39,14 +39,16 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:id], meta[:update][:valid]] } + let(:params) { {id: meta[:id]} } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" end context "unprocessable" do - let(:arguments) { [meta[:id], meta[:update][:invalid]] } + let(:params) { {id: meta[:id]} } + let(:body) { meta[:update][:invalid] } let(:stub_pattern) { "update-422" } it_behaves_like "an unprocessable request" diff --git a/spec/scalingo/regional/addons_spec.rb b/spec/scalingo/regional/addons_spec.rb index ac6ed2f..22c9cb0 100644 --- a/spec/scalingo/regional/addons_spec.rb +++ b/spec/scalingo/regional/addons_spec.rb @@ -3,8 +3,7 @@ RSpec.describe Scalingo::Regional::Addons do describe_method "categories" do context "guest" do - subject { guest_endpoint } - + let(:params) { {connected: false} } let(:expected_count) { 2 } let(:stub_pattern) { "categories-guest" } @@ -13,6 +12,7 @@ end context "logged" do + let(:params) { {connected: true} } let(:expected_count) { 2 } let(:stub_pattern) { "categories-logged" } @@ -23,8 +23,7 @@ describe_method "providers" do context "guest" do - subject { guest_endpoint } - + let(:params) { {connected: false} } let(:expected_count) { 9 } let(:stub_pattern) { "providers-guest" } @@ -33,6 +32,7 @@ end context "logged" do + let(:params) { {connected: true} } let(:expected_count) { 11 } let(:stub_pattern) { "providers-logged" } @@ -43,7 +43,8 @@ describe_method "provision" do context "success" do - let(:arguments) { [meta[:app_id], meta[:provision][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:provision][:valid] } let(:stub_pattern) { "provision-201" } let(:expected_keys) { %i[addon message] } @@ -51,7 +52,8 @@ end context "failure" do - let(:arguments) { [meta[:app_id], meta[:provision][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:provision][:invalid] } let(:stub_pattern) { "provision-400" } it_behaves_like "a client error" @@ -60,7 +62,7 @@ describe_method "for" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "for-200" } it_behaves_like "a collection response" @@ -70,14 +72,14 @@ describe_method "find" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "find-404" } it_behaves_like "a not found response" @@ -86,14 +88,14 @@ describe_method "sso" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "sso-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "sso-404" } it_behaves_like "a not found response" @@ -102,14 +104,14 @@ describe_method "token" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "token-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "token-404" } it_behaves_like "a not found response" @@ -118,7 +120,7 @@ describe_method "authenticate!" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "token-200" } it_behaves_like "a singular object response" @@ -129,7 +131,7 @@ end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "token-404" } it_behaves_like "a not found response" @@ -138,7 +140,8 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } let(:expected_keys) { %i[addon message] } @@ -146,7 +149,8 @@ end context "failure" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:invalid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:invalid] } let(:stub_pattern) { "update-404" } it_behaves_like "a not found response" @@ -155,14 +159,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/regional/apps_spec.rb b/spec/scalingo/regional/apps_spec.rb index 5c6bb17..0533e0e 100644 --- a/spec/scalingo/regional/apps_spec.rb +++ b/spec/scalingo/regional/apps_spec.rb @@ -11,14 +11,22 @@ describe_method "create" do context "success" do - let(:arguments) { meta[:create][:valid] } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end + context "dry run" do + let(:params) { {dry_run: true} } + let(:body) { meta[:create][:valid] } + let(:stub_pattern) { "create-201-dry-run" } + + it_behaves_like "a singular object response", 201 + end + context "failure" do - let(:arguments) { meta[:create][:invalid] } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-422" } it_behaves_like "an unprocessable request" @@ -27,14 +35,14 @@ describe_method "find" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { meta.slice(:id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { meta[:not_found_id] } + let(:params) { {id: meta[:not_found_id]} } let(:stub_pattern) { "find-404" } it_behaves_like "a not found response" @@ -43,14 +51,16 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:id], meta[:update][:valid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" end context "invalid stack" do - let(:arguments) { [meta[:id], meta[:update][:invalid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:update][:invalid] } let(:stub_pattern) { "update-stack-404" } it_behaves_like "a not found response" @@ -59,7 +69,7 @@ describe_method "logs_url" do context "success" do - let(:arguments) { meta[:id] } + let(:params) { meta.slice(:id) } let(:stub_pattern) { "logs_url" } let(:expected_keys) { %i[app logs_url] } @@ -69,21 +79,24 @@ describe_method "destroy" do context "success" do - let(:arguments) { [meta[:id], meta[:destroy][:valid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:destroy][:valid] } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { [meta[:not_found_id], meta[:destroy][:valid]] } + let(:params) { {id: meta[:not_found_id]} } + let(:body) { meta[:destroy][:valid] } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" end context "unprocessable" do - let(:arguments) { [meta[:id], meta[:destroy][:invalid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:destroy][:invalid] } let(:stub_pattern) { "destroy-422" } it_behaves_like "an unprocessable request" @@ -92,21 +105,24 @@ describe_method "rename" do context "success" do - let(:arguments) { [meta[:id], meta[:rename][:valid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:rename][:valid] } let(:stub_pattern) { "rename-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:not_found_id], meta[:rename][:valid]] } + let(:params) { {id: meta[:not_found_id]} } + let(:body) { meta[:rename][:valid] } let(:stub_pattern) { "rename-404" } it_behaves_like "a not found response" end context "unprocessable" do - let(:arguments) { [meta[:id], meta[:rename][:invalid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:rename][:invalid] } let(:stub_pattern) { "rename-422" } it_behaves_like "an unprocessable request" @@ -115,21 +131,24 @@ describe_method "transfer" do context "success" do - let(:arguments) { [meta[:id], meta[:transfer][:valid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:transfer][:valid] } let(:stub_pattern) { "transfer-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:not_found_id], meta[:transfer][:valid]] } + let(:params) { {id: meta[:not_found_id]} } + let(:body) { meta[:transfer][:valid] } let(:stub_pattern) { "transfer-404" } it_behaves_like "a not found response" end context "unprocessable" do - let(:arguments) { [meta[:id], meta[:transfer][:invalid]] } + let(:params) { meta.slice(:id) } + let(:body) { meta[:transfer][:invalid] } let(:stub_pattern) { "transfer-422" } it_behaves_like "an unprocessable request" diff --git a/spec/scalingo/regional/autoscalers_spec.rb b/spec/scalingo/regional/autoscalers_spec.rb index 42aeb87..c6b6fa3 100644 --- a/spec/scalingo/regional/autoscalers_spec.rb +++ b/spec/scalingo/regional/autoscalers_spec.rb @@ -3,14 +3,16 @@ RSpec.describe Scalingo::Regional::Autoscalers do describe_method "create" do context "success" do - let(:arguments) { [meta[:app_id], meta[:create][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end context "failure" do - let(:arguments) { [meta[:app_id], meta[:create][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-500" } it_behaves_like "a server error" @@ -19,7 +21,7 @@ describe_method "for" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "for-200" } it_behaves_like "a collection response" @@ -29,14 +31,14 @@ describe_method "find" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "find-404" } it_behaves_like "a not found response" @@ -45,21 +47,24 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" end context "failure" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:invalid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:invalid] } let(:stub_pattern) { "update-500" } it_behaves_like "a server error" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-404" } it_behaves_like "a not found response" @@ -68,14 +73,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/regional/collaborators_spec.rb b/spec/scalingo/regional/collaborators_spec.rb index e2285d3..96b253a 100644 --- a/spec/scalingo/regional/collaborators_spec.rb +++ b/spec/scalingo/regional/collaborators_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Scalingo::Regional::Collaborators do describe_method "for" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "for-200" } it_behaves_like "a collection response" @@ -13,14 +13,16 @@ describe_method "invite" do context "success" do - let(:arguments) { [meta[:app_id], meta[:invite][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:invite][:valid] } let(:stub_pattern) { "invite-201" } it_behaves_like "a singular object response", 201 end context "failure" do - let(:arguments) { [meta[:app_id], meta[:invite][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:invite][:invalid] } let(:stub_pattern) { "invite-422" } it_behaves_like "an unprocessable request" @@ -29,21 +31,21 @@ describe_method "accept" do context "success" do - let(:arguments) { meta[:accept][:valid] } + let(:body) { meta[:accept][:valid] } let(:stub_pattern) { "accept-200" } it_behaves_like "a singular object response" end context "already collaborating" do - let(:arguments) { meta[:accept][:valid] } + let(:body) { meta[:accept][:valid] } let(:stub_pattern) { "accept-400" } it_behaves_like "a client error" end context "not found" do - let(:arguments) { meta[:accept][:invalid] } + let(:body) { meta[:accept][:invalid] } let(:stub_pattern) { "accept-404" } it_behaves_like "a not found response" @@ -52,14 +54,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/regional/containers_spec.rb b/spec/scalingo/regional/containers_spec.rb index 6b2e1bd..f2e92b0 100644 --- a/spec/scalingo/regional/containers_spec.rb +++ b/spec/scalingo/regional/containers_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Scalingo::Regional::Containers do describe_method "sizes" do context "guest" do - subject { guest_endpoint } + let(:params) { {connected: false} } let(:expected_count) { 7 } let(:stub_pattern) { "sizes-guest" } @@ -23,7 +23,7 @@ describe_method "for" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:expected_count) { 2 } let(:expected_keys) { %i[name] } let(:stub_pattern) { "for-200" } @@ -35,14 +35,16 @@ describe_method "restart" do context "success" do - let(:arguments) { [meta[:app_id], meta[:restart][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:restart][:valid] } let(:stub_pattern) { "restart-202" } it_behaves_like "a singular object response", 202 end context "success" do - let(:arguments) { [meta[:app_id], meta[:restart][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:restart][:invalid] } let(:stub_pattern) { "restart-422" } it_behaves_like "an unprocessable request" @@ -51,14 +53,16 @@ describe_method "scale" do context "success" do - let(:arguments) { [meta[:app_id], meta[:scale][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:scale][:valid] } let(:stub_pattern) { "scale-202" } it_behaves_like "a singular object response", 202 end context "success" do - let(:arguments) { [meta[:app_id], meta[:scale][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:scale][:invalid] } let(:stub_pattern) { "scale-422" } it_behaves_like "an unprocessable request" diff --git a/spec/scalingo/regional/deployments_spec.rb b/spec/scalingo/regional/deployments_spec.rb index e687f10..3fbd60a 100644 --- a/spec/scalingo/regional/deployments_spec.rb +++ b/spec/scalingo/regional/deployments_spec.rb @@ -3,24 +3,35 @@ RSpec.describe Scalingo::Regional::Deployments do describe_method "for" do context "success" do - let(:arguments) { [meta[:app_id], {}] } - let(:stub_pattern) { "for-without-pages" } + let(:params) { meta.slice(:app_id) } - it_behaves_like "a collection response" - it_behaves_like "a paginated collection" + context "with pages" do + let(:params) { meta.slice(:app_id).merge(query: {page: 3}) } + let(:stub_pattern) { "for-with-pages" } + + it_behaves_like "a collection response" + it_behaves_like "a paginated collection" + end + + context "without pages" do + let(:stub_pattern) { "for-without-pages" } + + it_behaves_like "a collection response" + it_behaves_like "a paginated collection" + end end end describe_method "find" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end context "failure" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "find-404" } it_behaves_like "a not found response" @@ -29,14 +40,14 @@ describe_method "logs" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "logs-200" } it_behaves_like "a singular object response" end context "failure" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "logs-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/regional/domains_spec.rb b/spec/scalingo/regional/domains_spec.rb index 214d14b..a6f927a 100644 --- a/spec/scalingo/regional/domains_spec.rb +++ b/spec/scalingo/regional/domains_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Scalingo::Regional::Domains do describe_method "for" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "for-200" } it_behaves_like "a collection response" @@ -13,14 +13,14 @@ describe_method "find" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "find-404" } it_behaves_like "a not found response" @@ -29,14 +29,16 @@ describe_method "create" do context "success" do - let(:arguments) { [meta[:app_id], meta[:create][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end context "failure" do - let(:arguments) { [meta[:app_id], meta[:create][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-422" } it_behaves_like "an unprocessable request" @@ -45,21 +47,24 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-404" } it_behaves_like "a not found response" end context "failure" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:invalid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:invalid] } let(:stub_pattern) { "update-422" } it_behaves_like "an unprocessable request" @@ -68,14 +73,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/regional/environment_spec.rb b/spec/scalingo/regional/environment_spec.rb index a4c655d..2d12da8 100644 --- a/spec/scalingo/regional/environment_spec.rb +++ b/spec/scalingo/regional/environment_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Scalingo::Regional::Environment do describe_method "for" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "for-200" } it_behaves_like "a collection response" @@ -13,14 +13,16 @@ describe_method "create" do context "success" do - let(:arguments) { [meta[:app_id], meta[:create][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end context "failure" do - let(:arguments) { [meta[:app_id], meta[:create][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-422" } it_behaves_like "an unprocessable request" @@ -29,14 +31,16 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-404" } it_behaves_like "a not found response" @@ -44,7 +48,8 @@ end describe_method "bulk_update" do - let(:arguments) { [meta[:app_id], meta[:update][:bulk]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:update][:bulk] } let(:expected_count) { 4 } let(:stub_pattern) { "bulk-update-200" } @@ -54,14 +59,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" @@ -69,7 +74,8 @@ end describe_method "bulk_destroy" do - let(:arguments) { [meta[:app_id], meta[:destroy][:bulk]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:destroy][:bulk] } let(:stub_pattern) { "bulk-destroy-204" } it_behaves_like "an empty response" diff --git a/spec/scalingo/regional/events_spec.rb b/spec/scalingo/regional/events_spec.rb index c076a6d..154956e 100644 --- a/spec/scalingo/regional/events_spec.rb +++ b/spec/scalingo/regional/events_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Scalingo::Regional::Events do describe_method "categories" do context "guest" do - subject { guest_endpoint } + let(:params) { {connected: false} } let(:expected_count) { 7 } let(:stub_pattern) { "categories-guest" } @@ -13,6 +13,8 @@ end context "logged" do + let(:params) { {connected: true} } + let(:expected_count) { 7 } let(:stub_pattern) { "categories-logged" } @@ -23,7 +25,7 @@ describe_method "types" do context "guest" do - subject { guest_endpoint } + let(:params) { {connected: false} } let(:expected_count) { 33 } let(:stub_pattern) { "types-guest" } @@ -33,6 +35,7 @@ end context "logged" do + let(:params) { {connected: true} } let(:expected_count) { 33 } let(:stub_pattern) { "types-logged" } @@ -43,7 +46,6 @@ describe_method "all" do context "success" do - let(:arguments) { {} } let(:expected_count) { 30 } let(:stub_pattern) { "all-200" } @@ -54,7 +56,7 @@ describe_method "for" do context "success" do - let(:arguments) { [meta[:app_id], {}] } + let(:params) { meta.slice(:app_id) } let(:expected_count) { 18 } let(:stub_pattern) { "for-200" } diff --git a/spec/scalingo/regional/logs_spec.rb b/spec/scalingo/regional/logs_spec.rb index 51ad0ef..5000613 100644 --- a/spec/scalingo/regional/logs_spec.rb +++ b/spec/scalingo/regional/logs_spec.rb @@ -3,23 +3,24 @@ RSpec.describe Scalingo::Regional::Logs do describe_method "get" do context "guest" do - subject { guest_endpoint } - - let(:arguments) { [meta[:urls][:guest], {}] } + let(:arguments) { meta[:urls][:guest] } + let(:params) { {connected: false} } let(:stub_pattern) { "get-guest-200" } it_behaves_like "a singular object response" end context "logged" do - let(:arguments) { [meta[:urls][:logged], {}] } + let(:arguments) { meta[:urls][:logged] } + let(:params) { {connected: true} } let(:stub_pattern) { "get-logged-200" } it_behaves_like "a singular object response" end context "with limit" do - let(:arguments) { [meta[:urls][:with_limit], meta[:options]] } + let(:arguments) { meta[:urls][:with_limit] } + let(:params) { meta[:options] } let(:stub_pattern) { "get-with-limit-200" } it_behaves_like "a singular object response" @@ -28,7 +29,7 @@ describe_method "archives" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:expected_count) { 0 } let(:stub_pattern) { "archives-200" } diff --git a/spec/scalingo/regional/metrics_spec.rb b/spec/scalingo/regional/metrics_spec.rb index 895164c..793b520 100644 --- a/spec/scalingo/regional/metrics_spec.rb +++ b/spec/scalingo/regional/metrics_spec.rb @@ -3,14 +3,14 @@ RSpec.describe Scalingo::Regional::Metrics do describe_method "types" do context "guest" do - subject { guest_endpoint } - + let(:connected) { false } let(:stub_pattern) { "types-guest" } it_behaves_like "a singular object response" end context "logged" do + let(:connected) { true } let(:stub_pattern) { "types-logged" } it_behaves_like "a singular object response" @@ -21,7 +21,7 @@ let(:expected_keys) { %i[time value] } context "cpu" do - let(:arguments) { [meta[:app_id], meta[:for][:valid_cpu]] } + let(:params) { meta.slice(:app_id).merge(meta[:for][:valid_cpu]) } let(:expected_count) { 181 } let(:stub_pattern) { "for-valid-cpu-200" } @@ -30,14 +30,14 @@ end context "router" do - let(:arguments) { [meta[:app_id], meta[:for][:valid_router]] } + let(:params) { meta.slice(:app_id).merge(meta[:for][:valid_router]) } let(:stub_pattern) { "for-valid-router-404" } it_behaves_like "a not found response" end context "invalid" do - let(:arguments) { [meta[:app_id], meta[:for][:invalid]] } + let(:params) { meta.slice(:app_id).merge(meta[:for][:invalid]) } let(:stub_pattern) { "for-invalid-400" } it_behaves_like "a client error" diff --git a/spec/scalingo/regional/notifiers_spec.rb b/spec/scalingo/regional/notifiers_spec.rb index f9a3353..d928a46 100644 --- a/spec/scalingo/regional/notifiers_spec.rb +++ b/spec/scalingo/regional/notifiers_spec.rb @@ -3,8 +3,7 @@ RSpec.describe Scalingo::Regional::Notifiers do describe_method "platforms" do context "guest" do - subject { guest_endpoint } - + let(:params) { {connected: false} } let(:expected_count) { 4 } let(:stub_pattern) { "platforms-guest" } @@ -13,6 +12,7 @@ end context "logged" do + let(:params) { {connected: true} } let(:expected_count) { 4 } let(:stub_pattern) { "platforms-logged" } @@ -23,7 +23,7 @@ describe_method "for" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "for-200" } it_behaves_like "a collection response" @@ -33,14 +33,14 @@ describe_method "find" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "find-404" } it_behaves_like "a not found response" @@ -49,21 +49,24 @@ describe_method "create" do context "success" do - let(:arguments) { [meta[:app_id], meta[:create][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end context "not found" do - let(:arguments) { [meta[:app_id], meta[:create][:not_found]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:not_found] } let(:stub_pattern) { "create-404" } it_behaves_like "a not found response" end context "failure" do - let(:arguments) { [meta[:app_id], meta[:create][:invalid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:invalid] } let(:stub_pattern) { "create-422" } it_behaves_like "an unprocessable request" @@ -72,14 +75,14 @@ describe_method "test" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "test-200" } it_behaves_like "a singular object response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "test-404" } it_behaves_like "a not found response" @@ -88,7 +91,8 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id, :id) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" @@ -97,14 +101,14 @@ describe_method "destroy" do context "success" do - let(:arguments) { [meta[:app_id], meta[:id]] } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" end context "not found" do - let(:arguments) { [meta[:app_id], meta[:not_found_id]] } + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "destroy-404" } it_behaves_like "a not found response" diff --git a/spec/scalingo/regional/operations_spec.rb b/spec/scalingo/regional/operations_spec.rb index fa912f1..616c668 100644 --- a/spec/scalingo/regional/operations_spec.rb +++ b/spec/scalingo/regional/operations_spec.rb @@ -1,27 +1,35 @@ require "spec_helper" RSpec.describe Scalingo::Regional::Operations do - describe_method "get" do + describe_method "find" do context "success" do - let(:arguments) { "apps/#{meta[:app_id]}/operations/#{meta[:id]}" } + let(:params) { meta.slice(:app_id, :id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end - context "failure" do - let(:arguments) { "apps/#{meta[:app_id]}/operations/#{meta[:not_found_id]}" } + context "not found" do + let(:params) { meta.slice(:app_id).merge(id: meta[:not_found_id]) } let(:stub_pattern) { "find-404" } it_behaves_like "a not found response" end end - describe_method "find" do - it "delegates to get" do - expect(subject).to receive(:get).with("apps/a/operations/b", :headers).once + describe_method "get" do + context "success" do + let(:arguments) { "apps/#{meta[:app_id]}/operations/#{meta[:id]}" } + let(:stub_pattern) { "find-200" } - subject.find(:a, :b, :headers) + it_behaves_like "a singular object response" + end + + context "failure" do + let(:arguments) { "apps/#{meta[:app_id]}/operations/#{meta[:not_found_id]}" } + let(:stub_pattern) { "find-404" } + + it_behaves_like "a not found response" end end end diff --git a/spec/scalingo/regional/scm_repo_links_spec.rb b/spec/scalingo/regional/scm_repo_links_spec.rb index bbb4ece..3cc15c0 100644 --- a/spec/scalingo/regional/scm_repo_links_spec.rb +++ b/spec/scalingo/regional/scm_repo_links_spec.rb @@ -3,7 +3,7 @@ RSpec.describe Scalingo::Regional::ScmRepoLinks do describe_method "show" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "show-200" } it_behaves_like "a singular object response" @@ -12,7 +12,8 @@ describe_method "create" do context "success" do - let(:arguments) { [meta[:app_id], meta[:create][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:create][:valid] } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 @@ -21,7 +22,8 @@ describe_method "update" do context "success" do - let(:arguments) { [meta[:app_id], meta[:update][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:update][:valid] } let(:stub_pattern) { "update-200" } it_behaves_like "a singular object response" @@ -30,7 +32,8 @@ describe_method "deploy" do context "success" do - let(:arguments) { [meta[:app_id], meta[:deploy][:valid]] } + let(:params) { meta.slice(:app_id) } + let(:body) { meta[:deploy][:valid] } let(:stub_pattern) { "manual-deploy-200" } it_behaves_like "a singular object response" @@ -39,7 +42,7 @@ describe_method "destroy" do context "success" do - let(:arguments) { meta[:app_id] } + let(:params) { meta.slice(:app_id) } let(:stub_pattern) { "destroy-204" } it_behaves_like "an empty response" diff --git a/spec/scalingo/regional_database/backups_spec.rb b/spec/scalingo/regional_database/backups_spec.rb index ab88eab..dd48607 100644 --- a/spec/scalingo/regional_database/backups_spec.rb +++ b/spec/scalingo/regional_database/backups_spec.rb @@ -7,14 +7,14 @@ describe_method "create" do context "success" do - let(:arguments) { [meta[:addon_id]] } + let(:params) { meta.slice(:addon_id) } let(:stub_pattern) { "create-201" } it_behaves_like "a singular object response", 201 end context "failure" do - let(:arguments) { [meta[:addon_id]] } + let(:params) { meta.slice(:addon_id) } let(:stub_pattern) { "create-400" } it_behaves_like "a client error" @@ -23,7 +23,7 @@ describe_method "for" do context "success" do - let(:arguments) { [meta[:addon_id]] } + let(:params) { meta.slice(:addon_id) } let(:stub_pattern) { "for-200" } let(:expected_count) { 3 } @@ -32,7 +32,7 @@ end context "failure" do - let(:arguments) { [meta[:addon_id]] } + let(:params) { meta.slice(:addon_id) } let(:stub_pattern) { "for-400" } it_behaves_like "a client error" @@ -41,7 +41,7 @@ describe_method "archive" do context "success" do - let(:arguments) { [meta[:addon_id], meta[:backup_id]] } + let(:params) { meta.slice(:addon_id, :id) } let(:stub_pattern) { "archive-200" } let(:expected_keys) { %i[download_url] } @@ -49,7 +49,7 @@ end context "failure" do - let(:arguments) { [meta[:addon_id], meta[:backup_id]] } + let(:params) { meta.slice(:addon_id, :id) } let(:stub_pattern) { "archive-400" } it_behaves_like "a client error" diff --git a/spec/scalingo/regional_database/databases_spec.rb b/spec/scalingo/regional_database/databases_spec.rb index 18d035a..21a0e34 100644 --- a/spec/scalingo/regional_database/databases_spec.rb +++ b/spec/scalingo/regional_database/databases_spec.rb @@ -7,14 +7,14 @@ describe_method "find" do context "success" do - let(:arguments) { [meta[:id]] } + let(:params) { meta.slice(:id) } let(:stub_pattern) { "find-200" } it_behaves_like "a singular object response" end context "failure" do - let(:arguments) { [meta[:id]] } + let(:params) { meta.slice(:id) } let(:stub_pattern) { "find-400" } it_behaves_like "a client error" @@ -23,14 +23,14 @@ describe_method "upgrade" do context "success" do - let(:arguments) { [meta[:id]] } + let(:params) { meta.slice(:id) } let(:stub_pattern) { "upgrade-202" } it_behaves_like "a singular object response", 202 end context "failure" do - let(:arguments) { [meta[:id]] } + let(:params) { meta.slice(:id) } let(:stub_pattern) { "upgrade-400" } it_behaves_like "a client error" diff --git a/spec/support/scalingo.rb b/spec/support/scalingo.rb index e8aa5dc..54f7d92 100644 --- a/spec/support/scalingo.rb +++ b/spec/support/scalingo.rb @@ -99,16 +99,27 @@ def describe_method(method_name, &block) raise NameError, "No method named `#{method_name}` for class #{described_class}" end + # Helper method to quickly define a context for a method with default let values context(method_name) do let(:method_name) { method_name } + let(:basic) { nil } + let(:params) { {} } + let(:body) { nil } let(:arguments) { nil } let(:response) { + args = [method_name] + + # A few methods use positional arguments if arguments.is_a?(Array) - subject.public_send(*[method_name, *arguments].compact) - else - subject.public_send(*[method_name, arguments].compact) + args += arguments + elsif arguments + args << arguments end + + args.compact! + + subject.public_send(*args, body: body, basic: basic, **params) } instance_exec(&block) diff --git a/spec/support/shared.rb b/spec/support/shared.rb index b652db7..8e37f79 100644 --- a/spec/support/shared.rb +++ b/spec/support/shared.rb @@ -1,6 +1,5 @@ RSpec.shared_examples "a successful response" do |code = 200| let(:expected_code) { code } - let(:custom_headers) { {"X-Custom-Header" => "custom"} } it "is successful" do expect(response).to be_success @@ -10,25 +9,19 @@ # Checking that the method accepts a block and passes the faraday object it "can configure the request via a block" do expect { |block| + args = [method_name] + + # A few methods use positional arguments if arguments.is_a?(Array) - subject.public_send(*[method_name, *arguments].compact, &block) - else - subject.public_send(*[method_name, arguments].compact, &block) + args += arguments + elsif arguments + args << arguments end - }.to yield_with_args(Faraday::Request) - end - # Leverages the block version to check that the headers can also be set with an argument - it "can configure headers via the last argument" do - checker = proc { |conn| - expect(conn.headers["X-Custom-Header"]).to eq "custom" - } + args.compact! - if arguments.is_a?(Array) - subject.public_send(*[method_name, *arguments, custom_headers].compact, &checker) - else - subject.public_send(*[method_name, arguments, custom_headers].compact, &checker) - end + subject.public_send(*args, **params, body: body, &block) + }.to yield_with_args(Faraday::Request, Hash) end end