Closed mrjoshua22 closed 2 years ago
Если @current_user == nil, то нужно возвращать status :unauthorized. Добавлю следующим коммитом.
Добавлена обработка ActiveRecord::RecordNotFound и JWT::DecodeError
@mrjoshua22 указал замечания
Вот хороший способ избавиться от JSON.parse(response.body) https://stackoverflow.com/questions/5159882/how-to-check-for-a-json-response-using-rspec
module ApiHelpers
def json_body
JSON.parse(response.body)
end
end
RSpec.configure do |config|
config.include ApiHelpers, type: :request
end
@mrjoshua22 все выгрлядит правильно, но можно еще немного улучшить код
def token_authenticate_user
# В будущем будут другие статусы ответа
if authorization_header.blank?
render status: :unauthorized, json: { error: t("api.errors.unauthorized") } and return
end
if authenticate_scheme_bearer?
render status: :unauthorized, json: { error: t("Wrong scheme, you have to use a Bearer") } and return
end
if token.nil? || token.empty?
render status: :unauthorized, json: { error: t("Token is nil or empty") } and return
end
if token_expired?
render status: :unauthorized, json: { error: t("Token is expired") } and return
end
begin
set_user
rescue ActiveRecord::RecordNotFound
render status: :unauthorized, json: { error: t("api.errors.not_found") }
rescue JWT::DecodeError
render status: :unauthorized, json: { error: t("unexpected error") }
end
end
private
# приватные методы не тестируются
def authorization_header
request.headers["Authorization"]
end
def token
authorization_header.split.last
end
def authenticate_scheme_bearer?
authenticate_scheme != "Bearer"
end
def authenticate_scheme
authorization_header.split.first
end
def decoded
JwtService.decode(token)
end
def set_user
@current_user ||= User.find(decoded[:id])
end
# эту проверку забыл указать в задаче
def token_expired?
DateTime.now.to_i > decoded[:exp]
end
Вопросы по замечаниям:
@mrjoshua22 1) Можно использовать blank? 2) authenticate_scheme_wrong - мне тут не нравиться wrong малоинформативно, давай просто сделаем
unless authenticate_scheme_bearer?
render status: :unauthorized, json: { error: t("Wrong scheme, you have to use a Bearer") } and return
end
def authenticate_scheme_bearer?
authenticate_scheme == "Bearer"
end
3) Нет четких критерии, нужно попробовать написать в обоих стилях и посмотреть что лучше читается
По последним замечаниям:
Добавлен метод token_authenticate_user, тесты к нему и гем 'rails-controller-testing'. Метод тестируется через создание анонимного контроллера и использовании в нем метода через before_action. Для проверки значения возвращаемой инстанс переменной @current_user добавлен гем 'rails-controller-testing'. Тесты написаны для запроса с корректным токеном, токена с некорректным payload и запроса без токена вообще.