add helpers concept. authorize helpers.
This commit is contained in:
parent
0881970064
commit
21c3057b35
|
@ -6,6 +6,20 @@ module BtcPay
|
|||
class ApiKeys < Base
|
||||
PATH = '/api-keys'
|
||||
|
||||
# @see https://docs.btcpayserver.org/API/Greenfield/v1/#tag/Authorization/paths/~1api-keys~1authorize/get
|
||||
def authorize(permissions: [], application_name:, strict: true, selective_stores: false, **opts)
|
||||
opts.merge!(
|
||||
{
|
||||
permissions: Array(permissions),
|
||||
applicationName: application_name,
|
||||
strict: strict,
|
||||
selectiveStores: selective_stores
|
||||
}
|
||||
)
|
||||
|
||||
client.get('/api-keys/authorize', options: opts, include_api_path: false)
|
||||
end
|
||||
|
||||
# @see https://docs.btcpayserver.org/API/Greenfield/v1/#tag/API-Keys/paths/~1api~1v1~1api-keys~1current/get
|
||||
def current(**opts)
|
||||
client.get(path('current'), options: opts)
|
||||
|
|
|
@ -1,32 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../service'
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
module Api
|
||||
class Base
|
||||
def initialize(client:)
|
||||
@client = client
|
||||
@logger = @client.logger
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def base_path
|
||||
raise NotImplementedError.new
|
||||
end
|
||||
|
||||
def path(*args)
|
||||
request_path = args.prepend(base_path.presence).compact.join('/')
|
||||
request_path[0].eql?('/') ? request_path : '/' + request_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :client, :logger
|
||||
class Base < Client::Service
|
||||
require_relative './api_keys'
|
||||
require_relative './users'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require_relative './api_keys'
|
||||
require_relative './users'
|
||||
|
|
|
@ -6,6 +6,7 @@ require 'rest_client'
|
|||
|
||||
require_relative './result'
|
||||
require_relative './api/base'
|
||||
require_relative './helpers/base'
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
|
@ -36,8 +37,8 @@ module BtcPay
|
|||
# @param options [Hash]
|
||||
# @param headers [Hash]
|
||||
# @return [Result]
|
||||
def get(uri, options: {}, headers: {})
|
||||
request(uri, method: :get, options: options, headers: headers)
|
||||
def get(uri, options: {}, headers: {}, **kwargs)
|
||||
request(uri, method: :get, options: options, headers: headers, **kwargs)
|
||||
end
|
||||
|
||||
# POST request
|
||||
|
@ -66,6 +67,10 @@ module BtcPay
|
|||
@api_keys ||= Api::ApiKeys.new(client: self)
|
||||
end
|
||||
|
||||
def api_keys_helper
|
||||
@api_keys_helper ||= Helpers::ApiKeys.new(client: self)
|
||||
end
|
||||
|
||||
def users
|
||||
@users ||= Api::Users.new(client: self)
|
||||
end
|
||||
|
@ -86,26 +91,12 @@ module BtcPay
|
|||
end
|
||||
|
||||
# @yield [Result]
|
||||
def request(uri, method:, payload: nil, options: {}, headers: {})
|
||||
options ||= {}
|
||||
headers ||= {}
|
||||
|
||||
url = URI(config.base_url)
|
||||
url.path = API_PATH + uri
|
||||
url.query = CGI.unescape(options.to_query).presence
|
||||
|
||||
params = {
|
||||
method: method,
|
||||
url: url.to_s,
|
||||
payload: payload.presence,
|
||||
headers: default_headers.merge(headers),
|
||||
open_timeout: open_timeout,
|
||||
timeout: timeout
|
||||
}.compact
|
||||
def request(uri, **kwargs)
|
||||
params = request_builder(uri, **kwargs)
|
||||
return params if kwargs[:skip_request]
|
||||
|
||||
response = RestClient::Request.execute(params)
|
||||
|
||||
logger.debug(message: 'GET Request', url: url, options: options, status: response.code)
|
||||
logger.debug(message: 'GET Request', url: params[:url], options: kwargs[:options], status: response.code)
|
||||
result = success?(response.code) ? Result.success(response) : Result.failed(response)
|
||||
|
||||
logger.warn(error: 'Request Error', code: result.code, body: result.raw) if result.failure?
|
||||
|
@ -118,6 +109,28 @@ module BtcPay
|
|||
handle_error(e)
|
||||
end
|
||||
|
||||
# @param uri
|
||||
# @option
|
||||
def request_builder(uri, **kwargs)
|
||||
options = kwargs[:options] ||= {}
|
||||
headers = kwargs[:headers] ||= {}
|
||||
|
||||
url = URI(config.base_url)
|
||||
url.path = kwargs[:skip_api_path] ? uri : API_PATH + uri
|
||||
url.query = CGI.unescape(options.to_query).presence
|
||||
|
||||
return url.to_s if kwargs[:skip_request]
|
||||
|
||||
{
|
||||
method: kwargs[:method],
|
||||
url: url.to_s,
|
||||
payload: kwargs[:payload].presence,
|
||||
headers: default_headers.merge(headers),
|
||||
open_timeout: open_timeout,
|
||||
timeout: timeout
|
||||
}.compact
|
||||
end
|
||||
|
||||
# Handle errors
|
||||
# @param error [Error]
|
||||
# @return [Result]
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
module Helpers
|
||||
class ApiKeys < Helpers::Base
|
||||
def authorize
|
||||
Authorize.new(client: client)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def base_path
|
||||
nil
|
||||
end
|
||||
|
||||
class Authorize
|
||||
PATH = '/api-keys/authorize'
|
||||
|
||||
def initialize(client:)
|
||||
@client = client
|
||||
@logger = @client.logger
|
||||
end
|
||||
|
||||
def html(**opts)
|
||||
get(**opts)
|
||||
end
|
||||
|
||||
def link(**opts)
|
||||
get(skip_request: true, **opts)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :client, :logger
|
||||
|
||||
def get(permissions: [], application_name:, strict: true, selective_stores: false, **opts)
|
||||
opts.merge!(
|
||||
{
|
||||
permissions: Array(permissions),
|
||||
applicationName: application_name,
|
||||
strict: strict,
|
||||
selectiveStores: selective_stores
|
||||
}
|
||||
)
|
||||
|
||||
skip_request = opts.delete(:skip_request)
|
||||
client.get(PATH, options: opts, skip_api_path: true, skip_request: skip_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../service'
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
module Helpers
|
||||
class Base < Client::Service
|
||||
require_relative './api_keys'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -64,22 +64,22 @@ module BtcPay
|
|||
return if response.blank?
|
||||
|
||||
body = MultiJson.load(response)
|
||||
return body.with_indifferent_access if body.respond_to?(:with_indifferent_access)
|
||||
raise NotImplemented.new('Unknown response type') unless body.is_a?(Array)
|
||||
|
||||
case body
|
||||
when Array
|
||||
key = success? ? :data : :errors
|
||||
{
|
||||
key => body.map(&:with_indifferent_access)
|
||||
}
|
||||
else
|
||||
body.with_indifferent_access
|
||||
end
|
||||
key = success? ? :data : :errors
|
||||
{
|
||||
key => body.map(&:with_indifferent_access)
|
||||
}
|
||||
rescue MultiJson::ParseError
|
||||
response
|
||||
rescue StandardError => e
|
||||
raise ResponseBodyParseError.new(error: 'JSON parse error', message: e.message, body: body)
|
||||
raise ResponseBodyParseError.new(error: 'JSON parse error', message: e.message, body: response)
|
||||
end
|
||||
|
||||
def rubify_body
|
||||
return if raw.blank?
|
||||
return unless raw.respond_to?(:deep_transform_keys)
|
||||
|
||||
raw.deep_transform_keys { |key| key.to_s.underscore }.with_indifferent_access
|
||||
end
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BtcPay
|
||||
module Client
|
||||
class Service
|
||||
def initialize(client:)
|
||||
@client = client
|
||||
@logger = @client.logger
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def base_path
|
||||
raise NotImplementedError.new
|
||||
end
|
||||
|
||||
def path(*args)
|
||||
request_path = args.prepend(base_path.presence).compact.join('/')
|
||||
request_path[0].eql?('/') ? request_path : '/' + request_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :client, :logger
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,209 @@
|
|||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: http://localhost:49392/api-keys/authorize?applicationName=foobar&permissions%5B%5D=unrestricted&selectiveStores=false&strict=true
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
Accept:
|
||||
- application/json
|
||||
User-Agent:
|
||||
- btcpay_ruby/0.1.0
|
||||
Content-Type:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- deflate, gzip
|
||||
Authorization:
|
||||
- token 9133b8ef3ae9a4b7f2d9a6efef1d5cf738067c68
|
||||
Host:
|
||||
- localhost:49392
|
||||
response:
|
||||
status:
|
||||
code: 302
|
||||
message: Found
|
||||
headers:
|
||||
Date:
|
||||
- Fri, 31 Jul 2020 01:33:20 GMT
|
||||
Server:
|
||||
- Kestrel
|
||||
Content-Length:
|
||||
- '0'
|
||||
Location:
|
||||
- http://localhost:49392/Account/Login?ReturnUrl=%2Fapi-keys%2Fauthorize%3FapplicationName%3Dfoobar%26permissions%5B%5D%3Dunrestricted%26selectiveStores%3Dfalse%26strict%3Dtrue
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: ''
|
||||
recorded_at: Fri, 31 Jul 2020 01:33:21 GMT
|
||||
- request:
|
||||
method: get
|
||||
uri: http://localhost:49392/Account/Login?ReturnUrl=/api-keys/authorize?applicationName=foobar%26permissions%5B%5D=unrestricted%26selectiveStores=false%26strict=true
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
Accept:
|
||||
- application/json
|
||||
User-Agent:
|
||||
- btcpay_ruby/0.1.0
|
||||
Content-Type:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- deflate, gzip
|
||||
Authorization:
|
||||
- token 9133b8ef3ae9a4b7f2d9a6efef1d5cf738067c68
|
||||
Host:
|
||||
- localhost:49392
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Date:
|
||||
- Fri, 31 Jul 2020 01:33:20 GMT
|
||||
Content-Type:
|
||||
- text/html; charset=utf-8
|
||||
Server:
|
||||
- Kestrel
|
||||
Cache-Control:
|
||||
- no-cache, no-store
|
||||
Pragma:
|
||||
- no-cache
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Expires:
|
||||
- Thu, 01 Jan 1970 00:00:00 GMT
|
||||
Set-Cookie:
|
||||
- ".AspNetCore.Antiforgery.Mk-_zf2J-V0=CfDJ8FnOlqdJk7hFrjBUfYfP5HlB-FeX7VFnMWWqaILnxw9EDiOr4BQizk1Dazj8E32rpIGmnRHyKWvXRHXZJyLtQwVVenV3V87sjdSEKffI4Kii7lRLYDczr4dmKkEYb8xdAqbMLv9ThC7kSSCLQmr-9FM;
|
||||
path=/; samesite=strict; httponly"
|
||||
- ".AspNetCore.Mvc.CookieTempDataProvider=; expires=Thu, 01 Jan 1970 00:00:00
|
||||
GMT; path=/; samesite=lax; httponly"
|
||||
- Identity.External=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax;
|
||||
httponly
|
||||
X-Frame-Options:
|
||||
- DENY
|
||||
Referrer-Policy:
|
||||
- same-origin
|
||||
X-Xss-Protection:
|
||||
- 1; mode=block
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n \n<meta charset=\"utf-8\"
|
||||
/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"
|
||||
/>\n<meta name=\"description\" content=\"\">\n<meta name=\"author\" content=\"\">\n<title>Log
|
||||
in</title>\n<link href=\"/main/bootstrap/bootstrap.css?v=Dkg9ITOesbl8jUO7t3zHEIvMa_mVhQjpYWTQBtdDeh4\"
|
||||
rel=\"stylesheet\" />\n<link href=\"/main/bootstrap4-creativestart/creative.css?v=MOEzzK9YyA1W2wHpe5IeH6T859WAm0ufZjZNBT2FQF4\"
|
||||
rel=\"stylesheet\" />\n<link href=\"/main/themes/default-dark.css?v=Jfqq3eXcV7ehSKHXMVV4JGcokr8F74GkdHowK55hAsw\"
|
||||
rel=\"stylesheet\" />\n<link href=\"/bundles/main-bundle.min.css?v=ubBeJLlvfQ8Rw17qs0tDKGcAaLAX4bQiGooEo7gA5Hw\"
|
||||
rel=\"stylesheet\" />\n\n<script src=\"/bundles/main-bundle.min.js?v=KbmYpknPoAEBawvH0HP710wPkyHmzKZirYvs4QmW9s0\"
|
||||
type=\"text/javascript\"></script>\n\n\n\n <link href=\"/main/fonts/Montserrat.css?v=EP3QtcFCZ4q4VE8vS4u8iT6ZDkPePw98EjfTxAUzSY4\"
|
||||
rel=\"stylesheet\">\n <style>\n .content-wrapper {\n padding:
|
||||
70px 0;\n }\n\n @media screen and (min-width: 768px) {\n .content-wrapper
|
||||
{\n padding: 100px 0;\n }\n }\n\n .col-head
|
||||
{\n display: flex;\n align-items: center;\n flex-direction:
|
||||
column;\n justify-content: center;\n text-align: center;\n
|
||||
\ }\n\n @media screen and (min-width: 768px) {\n .col-head
|
||||
{\n text-align: left;\n flex-direction: row;\n
|
||||
\ justify-content: start;\n }\n }\n\n .head-logo
|
||||
{\n height: 70px;\n margin-bottom: 1rem;\n }\n\n
|
||||
\ @media screen and (min-width: 768px) {\n .head-logo {\n
|
||||
\ height: 100px;\n margin-bottom: 0;\n margin-right:
|
||||
50px;\n }\n }\n\n .lead-title {\n font-family:
|
||||
Montserrat;\n font-style: normal;\n font-weight: bold;\n
|
||||
\ font-size: 24px;\n line-height: 1.2;\n /*
|
||||
or 150% */\n letter-spacing: 0.1em;\n }\n\n @media
|
||||
screen and (min-width: 768px) {\n .lead-title {\n font-size:
|
||||
40px;\n }\n }\n\n .lead-login {\n font-family:
|
||||
Montserrat;\n font-style: normal;\n font-weight: normal;\n
|
||||
\ font-size: 18px;\n line-height: 33px;\n /*
|
||||
or 183% */\n letter-spacing: 0.1em;\n }\n\n .lead-h
|
||||
{\n font-family: Montserrat;\n font-style: normal;\n
|
||||
\ margin-bottom: 30px;\n font-weight: 600;\n font-size:
|
||||
14px;\n line-height: 18px;\n /* identical to box height,
|
||||
or 129% */\n letter-spacing: 0.1em;\n text-transform:
|
||||
uppercase;\n }\n </style>\n</head>\n<body>\n <section class=\"content-wrapper\">\n
|
||||
\ <!-- Dummy navbar-brand, hackish way to keep test AssertNoError passing
|
||||
-->\n <div class=\"navbar-brand\" style=\"display:none;\"></div>\n
|
||||
\ <div class=\"container\">\n <div class=\"row\">\n <div
|
||||
class=\"col-12 col-head\">\n <a href=\"/\"><img src=\"/img/btcpay-logo.svg?v=Fhv_MV_FZUb6EtYg7v7TsDa6MKTPBQwrsuNeg8jZduQ\"
|
||||
alt=\"BTCPay Server\" class=\"head-logo\" /></a>\n <h1
|
||||
class=\"lead-title text-uppercase\">Welcome to your BTCPay Server</h1>\n </div>\n
|
||||
\ </div>\n <div class=\"row\">\n <div
|
||||
class=\"col-md-7 order-md-1 order-2\">\n <hr class=\"primary
|
||||
ml-0\" style=\"margin:30px auto;\">\n <p class=\"lead-login\"
|
||||
style=\"margin-bottom:69px;\">BTCPay Server is a self-hosted, open-source
|
||||
cryptocurrency payment processor. It is secure, private, censorship-resistant
|
||||
and free.</p>\n <h3 class=\"lead-h text-center\">\n BTCPayServer
|
||||
Supporters\n <a href=\"https://foundation.btcpayserver.org/\" target=\"_blank\">\n
|
||||
\ <span class=\"fa fa-question-circle-o\" title=\"More information...\"></span>\n
|
||||
\ </a>\n</h3>\n<div class=\"row justify-content-center\">\n<div class=\"figure
|
||||
p-3\">\n <a href=\"https://kraken.com\" target=\"_blank\">\n <img
|
||||
src=\"/img/kraken.svg?v=-1HiBbDEkG_-e5cWYuyt7qz0IlEP6-6LhCdKms9cBUA\" alt=\"Sponsor
|
||||
Kraken\" height=\"75\" />\n </a>\n <div class=\"figure-caption
|
||||
text-center\">\n <a href=\"https://kraken.com\" class=\"text-muted
|
||||
small\" target=\"_blank\">Kraken</a>\n </div>\n </div>\n <div
|
||||
class=\"figure p-3\">\n <a href=\"https://twitter.com/sqcrypto\" target=\"_blank\">\n
|
||||
\ <img src=\"/img/squarecrypto.svg?v=l9UXRUhbHPS84ZGuoYCLF1-_HtuCzO9ImDRRQtYNgCA\"
|
||||
alt=\"Sponsor Square Crypto\" height=\"75\" />\n </a>\n <div
|
||||
class=\"figure-caption text-center\">\n <a href=\"https://twitter.com/sqcrypto\"
|
||||
class=\"text-muted small\" target=\"_blank\">Square Crypto</a>\n </div>\n
|
||||
\ </div>\n <div class=\"figure p-3\">\n <a href=\"https://www.btse.com\"
|
||||
target=\"_blank\">\n <img src=\"/img/btse.svg?v=z0-5Kw9SwxgkJoNUdkz8Lqr5JMu823vJT6f9n1FIkQ0\"
|
||||
alt=\"Sponsor BTSE\" height=\"75\" />\n </a>\n <div class=\"figure-caption
|
||||
text-center\">\n <a href=\"https://www.btse.com/\" class=\"text-muted
|
||||
small\" target=\"_blank\">BTSE</a>\n </div>\n </div>\n <div class=\"figure
|
||||
p-3\">\n <a href=\"https://www.dglab.com/en/\" target=\"_blank\">\n
|
||||
\ <img src=\"/img/dglab.svg?v=nOfIrlS6w7sXe-itwveN5zwcG_mvBL6Y5Itt3PVmZMw\"
|
||||
alt=\"Sponsor DG lab\" height=\"75\" />\n </a>\n <div class=\"figure-caption
|
||||
text-center\">\n <a href=\"https://www.dglab.com/en/\" class=\"text-muted
|
||||
small\" target=\"_blank\">DG Lab</a>\n </div>\n </div>\n <div
|
||||
class=\"figure p-3\">\n <a href=\"https://www.okcoin.com/\" target=\"_blank\">\n
|
||||
\ <img src=\"/img/okcoin.svg?v=1UIKVP3kI8eGaCV2tsyqcECxws3cgSwn7WyY133PEUE\"
|
||||
alt=\"Sponsor OKCoin\" height=\"75\" />\n </a>\n <div class=\"figure-caption
|
||||
text-center\">\n <a href=\"https://www.okcoin.com/\" class=\"text-muted
|
||||
small\" target=\"_blank\">OKCoin</a>\n </div>\n </div>\n <div
|
||||
class=\"figure p-3\">\n <a href=\"https://acinq.co/\" target=\"_blank\">\n
|
||||
\ <img src=\"/img/acinq-logo.svg?v=YQOiNW_A5zTBMgtNYkh7KX0Gb07pqlzImUtBIysMDg8\"
|
||||
alt=\"Sponsor ACINQ\" height=\"75\" />\n </a>\n <div class=\"figure-caption
|
||||
text-center\">\n <a href=\"https://acinq.co/\" class=\"text-muted
|
||||
small\" target=\"_blank\">ACINQ</a>\n </div>\n </div>\n</div>\n<div
|
||||
class=\"row justify-content-center\">\n <a href=\"https://foundation.btcpayserver.org\"
|
||||
target=\"_blank\" class=\"btn btn-link text-center col-12\">View all supporters</a>\n</div>\n\n
|
||||
\ </div>\n <div class=\"col-md-5 order-md-2 order-1\">\n
|
||||
\ <div class=\"modal-dialog modal-login\">\n <div class=\"modal-content\">\n
|
||||
\ <div class=\"modal-header\">\n <h4 class=\"modal-title\">Sign
|
||||
In</h4>\n </div>\n <div class=\"modal-body\">\n <form
|
||||
method=\"post\" action=\"/Account/Login?returnurl=%2Fapi-keys%2Fauthorize%3FapplicationName%3Dfoobar%26permissions%5B%5D%3Dunrestricted%26selectiveStores%3Dfalse%26strict%3Dtrue\">\n
|
||||
\ <fieldset >\n \n <div
|
||||
class=\"form-group\">\n <div class=\"input-group\">\n
|
||||
\ <div class=\"input-group-prepend\">\n <label
|
||||
for=\"Email\" class=\"input-group-text\"><span class=\"input-group-addon fa
|
||||
fa-user\"></span></label>\n </div>\n\n <input
|
||||
class=\"form-control\" placeholder=\"Email\" required=\"required\" type=\"email\"
|
||||
data-val=\"true\" data-val-email=\"The Email field is not a valid e-mail address.\"
|
||||
data-val-required=\"The Email field is required.\" id=\"Email\" name=\"Email\"
|
||||
value=\"\" />\n </div>\n <span
|
||||
class=\"text-danger field-validation-valid\" data-valmsg-for=\"Email\" data-valmsg-replace=\"true\"></span>\n
|
||||
\ </div>\n <div class=\"form-group\">\n
|
||||
\ <div class=\"input-group\">\n <div
|
||||
class=\"input-group-prepend\">\n <label for=\"Password\"
|
||||
class=\"input-group-text\"><span class=\"input-group-addon fa fa-lock\"></span></label>\n
|
||||
\ </div>\n <input class=\"form-control\"
|
||||
placeholder=\"Password\" required=\"required\" type=\"password\" data-val=\"true\"
|
||||
data-val-required=\"The Password field is required.\" id=\"Password\" name=\"Password\"
|
||||
/>\n </div>\n <span class=\"text-danger
|
||||
field-validation-valid\" data-valmsg-for=\"Password\" data-valmsg-replace=\"true\"></span>\n
|
||||
\ </div>\n <div class=\"form-group\">\n
|
||||
\ <button type=\"submit\" class=\"btn btn-primary btn-block
|
||||
btn-lg\" id=\"LoginButton\">Sign in</button>\n </div>\n
|
||||
\ <p class=\"hint-text\"><a href=\"/Account/ForgotPassword\">Forgot
|
||||
your password?</a></p>\n </fieldset>\n <input name=\"__RequestVerificationToken\"
|
||||
type=\"hidden\" value=\"CfDJ8FnOlqdJk7hFrjBUfYfP5HmE6-HnJIDh88GI1_VgU9WzEm4bWVKPZeYSCp7zyuSHjJ3iopE2_7dFUkbhJgPujr64iT086AcJPdxv0ImuP9n_NHw7REOUvjzlZTYpLXmJ3UexbsKRaGld6dH_3z_iNpQ\"
|
||||
/></form>\n </div>\n </div>\n</div>\n\n\n </div>\n
|
||||
\ </div>\n </div>\n </section>\n \n<script src=\"/bundles/jqueryvalidate-bundle.min.js?v=kQkuPdzJND7ExPNd8ORxjsLGbF4lBMzWvF1V2zsv3gE\"
|
||||
type=\"text/javascript\"></script>\n\n\n</body>\n</html>\n"
|
||||
recorded_at: Fri, 31 Jul 2020 01:33:21 GMT
|
||||
recorded_with: VCR 6.0.0
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe BtcPay::Client::Helpers::ApiKeys do
|
||||
let(:client) { build(:client) }
|
||||
let(:base_subject) { described_class.new(client: client) }
|
||||
|
||||
let(:options) { { permissions: %w[unrestricted], application_name: 'foobar' } }
|
||||
|
||||
context '#authorize' do
|
||||
subject { base_subject.authorize }
|
||||
|
||||
describe 'GET #html', :vcr do
|
||||
let(:response) { subject.html(**options) }
|
||||
|
||||
it do
|
||||
expect(subject).to be_a(BtcPay::Client::Helpers::ApiKeys::Authorize)
|
||||
expect(response).to be_success
|
||||
end
|
||||
end
|
||||
|
||||
describe '#link', :vcr do
|
||||
let(:response) { subject.link(**options) }
|
||||
|
||||
it do
|
||||
expect(subject).to be_a(BtcPay::Client::Helpers::ApiKeys::Authorize)
|
||||
expect(response).to eq('http://localhost:49392/api-keys/authorize?applicationName=foobar&permissions[]=unrestricted&selectiveStores=false&strict=true')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue