Update `Ajax::RelationshipController` to use usernames; Test Use Case
This commit is contained in:
parent
4a1ed5394a
commit
d609435f7c
|
@ -8,8 +8,10 @@ class Ajax::RelationshipController < AjaxController
|
|||
before_action :authenticate_user!
|
||||
|
||||
def create
|
||||
params.require :target_user
|
||||
|
||||
UseCase::Relationship::Create.call(
|
||||
current_user_id: current_user.id,
|
||||
current_user: current_user.screen_name,
|
||||
target_user: params[:target_user],
|
||||
type: params[:type]
|
||||
)
|
||||
|
@ -23,7 +25,7 @@ class Ajax::RelationshipController < AjaxController
|
|||
|
||||
def destroy
|
||||
UseCase::Relationship::Destroy.call(
|
||||
current_user_id: current_user.id,
|
||||
current_user: current_user.screen_name,
|
||||
target_user: params[:target_user],
|
||||
type: params[:type]
|
||||
)
|
||||
|
|
|
@ -18,6 +18,30 @@ class AjaxController < ApplicationController
|
|||
return_response
|
||||
end
|
||||
|
||||
rescue_from(KeyError) do |e|
|
||||
Sentry.capture_exception(e)
|
||||
|
||||
@response = {
|
||||
success: false,
|
||||
message: "Missing parameter: #{e.key}",
|
||||
status: :err
|
||||
}
|
||||
|
||||
return_response
|
||||
end
|
||||
|
||||
rescue_from(Dry::Types::CoercionError, Dry::Types::ConstraintError) do |e|
|
||||
Sentry.capture_exception(e)
|
||||
|
||||
@response = {
|
||||
success: false,
|
||||
message: "Invalid parameter",
|
||||
status: :err
|
||||
}
|
||||
|
||||
return_response
|
||||
end
|
||||
|
||||
rescue_from(ActiveRecord::RecordNotFound) do |e|
|
||||
Sentry.capture_exception(e)
|
||||
|
||||
|
|
|
@ -19,9 +19,6 @@ module Errors
|
|||
end
|
||||
end
|
||||
|
||||
class ParamIsMissing < BadRequest
|
||||
end
|
||||
|
||||
class InvalidBanDuration < BadRequest
|
||||
end
|
||||
|
||||
|
|
|
@ -4,4 +4,6 @@ require 'dry-types'
|
|||
|
||||
module Types
|
||||
include Dry.Types()
|
||||
|
||||
RelationshipTypes = Types::String.enum('follow')
|
||||
end
|
||||
|
|
|
@ -15,13 +15,5 @@ module UseCase
|
|||
def call
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def not_blank!(*args)
|
||||
args.each do |arg|
|
||||
raise Errors::ParamIsMissing if instance_variable_get("@#{arg}").blank?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,15 +6,11 @@ require "errors"
|
|||
module UseCase
|
||||
module Relationship
|
||||
class Create < UseCase::Base
|
||||
option :current_user_id, type: Types::Coercible::Integer
|
||||
option :current_user, type: Types::Coercible::String
|
||||
option :target_user, type: Types::Coercible::String
|
||||
option :type, type: Types::Coercible::String
|
||||
option :type, type: Types::RelationshipTypes
|
||||
|
||||
def call
|
||||
not_blank! :current_user_id, :target_user, :type
|
||||
|
||||
type = @type.downcase
|
||||
ensure_type(type)
|
||||
source_user = find_source_user
|
||||
target_user = find_target_user
|
||||
|
||||
|
@ -31,19 +27,14 @@ module UseCase
|
|||
|
||||
private
|
||||
|
||||
def ensure_type(type)
|
||||
raise Errors::BadRequest unless type == 'follow'
|
||||
end
|
||||
|
||||
def find_source_user
|
||||
user_id = @current_user_id
|
||||
::User.find(user_id)
|
||||
return current_user if current_user.is_a?(::User)
|
||||
::User.find_by!(screen_name: current_user)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
raise Errors::UserNotFound
|
||||
end
|
||||
|
||||
def find_target_user
|
||||
target_user = @target_user
|
||||
return target_user if target_user.is_a?(::User)
|
||||
::User.find_by!(screen_name: target_user)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
|
|
|
@ -6,15 +6,11 @@ require "errors"
|
|||
module UseCase
|
||||
module Relationship
|
||||
class Destroy < UseCase::Base
|
||||
option :current_user_id, type: Types::Coercible::Integer
|
||||
option :target_user, type: Types::Coercible::String
|
||||
option :type, type: Types::Coercible::String
|
||||
option :current_user, type: Types::Coercible::String | Types.Instance(User)
|
||||
option :target_user, type: Types::Coercible::String | Types.Instance(User)
|
||||
option :type, type: Types::RelationshipTypes
|
||||
|
||||
def call
|
||||
not_blank! :current_user_id, :target_user, :type
|
||||
|
||||
type = @type.downcase
|
||||
ensure_type(type)
|
||||
source_user = find_source_user
|
||||
target_user = find_target_user
|
||||
|
||||
|
@ -31,20 +27,13 @@ module UseCase
|
|||
|
||||
private
|
||||
|
||||
def ensure_type(type)
|
||||
raise Errors::BadRequest unless type == 'follow'
|
||||
end
|
||||
|
||||
def find_source_user
|
||||
user_id = @current_user_id
|
||||
::User.find(user_id)
|
||||
::User.find_by!(screen_name: current_user)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
raise Errors::UserNotFound
|
||||
end
|
||||
|
||||
def find_target_user
|
||||
target_user = @target_user
|
||||
return target_user if target_user.is_a?(::User)
|
||||
::User.find_by!(screen_name: target_user)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
raise Errors::UserNotFound
|
||||
|
|
|
@ -5,9 +5,9 @@ require "rails_helper"
|
|||
|
||||
describe Ajax::RelationshipController, type: :controller do
|
||||
shared_examples_for "params is empty" do
|
||||
let(:params) { { type: type } } # type is still required as it's part of the route
|
||||
let(:params) { }
|
||||
|
||||
include_examples "ajax does not succeed", "param is missing"
|
||||
include_examples "ajax does not succeed", "is required"
|
||||
end
|
||||
|
||||
let!(:user) { FactoryBot.create(:user) }
|
||||
|
@ -60,7 +60,7 @@ describe Ajax::RelationshipController, type: :controller do
|
|||
let(:type) { "dick" }
|
||||
|
||||
it_behaves_like "params is empty"
|
||||
include_examples "ajax does not succeed", "Bad Request"
|
||||
include_examples "ajax does not succeed", "Invalid parameter"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -85,8 +85,6 @@ describe Ajax::RelationshipController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
it_behaves_like "params is empty"
|
||||
|
||||
context "target_user does not exist" do
|
||||
let(:target_user) { "peter-witzig" }
|
||||
|
||||
|
@ -114,8 +112,7 @@ describe Ajax::RelationshipController, type: :controller do
|
|||
context "type = 'dick'" do
|
||||
let(:type) { "dick" }
|
||||
|
||||
it_behaves_like "params is empty"
|
||||
include_examples "ajax does not succeed", "Bad Request"
|
||||
include_examples "ajax does not succeed", "Invalid parameter"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
require "use_case/relationship/create"
|
||||
require "errors"
|
||||
|
||||
describe UseCase::Relationship::Create do
|
||||
shared_examples_for "valid relationship type" do
|
||||
context "current_user does not exist" do
|
||||
let(:current_user) { "Schweinsbraten" }
|
||||
|
||||
include_examples "raises an error", Errors::UserNotFound
|
||||
end
|
||||
|
||||
context "target_user does not exist" do
|
||||
let(:target_user) { "peterwitzig" }
|
||||
|
||||
include_examples "raises an error", Errors::UserNotFound
|
||||
end
|
||||
|
||||
context "target_user is current_user" do
|
||||
let(:target_user) { user1.screen_name }
|
||||
|
||||
include_examples "raises an error", Errors::SelfAction
|
||||
end
|
||||
|
||||
context "target_user is different from current_user" do
|
||||
its([:status]) { is_expected.to eq(201) }
|
||||
its([:extra]) { is_expected.to eq(target_user: user2) }
|
||||
|
||||
it "creates a relationship" do
|
||||
expect { subject }.to change { Relationship.count }.by(1)
|
||||
last_relationship = Relationship.last
|
||||
expect(last_relationship.source_id).to eq(user1.id)
|
||||
expect(last_relationship.target_id).to eq(user2.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:base_params) do
|
||||
{
|
||||
current_user: current_user,
|
||||
target_user: target_user,
|
||||
type: type
|
||||
}
|
||||
end
|
||||
let(:params) { base_params }
|
||||
let(:current_user) { user1.screen_name }
|
||||
let(:target_user) { user2.screen_name }
|
||||
let(:type) { nil }
|
||||
|
||||
# test data:
|
||||
let!(:user1) { FactoryBot.create(:user, screen_name: "timallen") }
|
||||
let!(:user2) { FactoryBot.create(:user, screen_name: "joehilyar") }
|
||||
|
||||
subject { described_class.call(params) }
|
||||
|
||||
context "type = 'follow'" do
|
||||
let(:type) { "follow" }
|
||||
|
||||
include_examples "valid relationship type"
|
||||
end
|
||||
|
||||
context "type = 'dick'" do
|
||||
let(:type) { "dick" }
|
||||
|
||||
include_examples "raises an error", Dry::Types::ConstraintError
|
||||
end
|
||||
end
|
|
@ -0,0 +1,73 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
require "use_case/relationship/destroy"
|
||||
require "errors"
|
||||
|
||||
describe UseCase::Relationship::Destroy do
|
||||
shared_examples_for "valid relationship type" do
|
||||
its([:status]) { is_expected.to eq(204) }
|
||||
its([:extra]) { is_expected.to eq(target_user: user2) }
|
||||
|
||||
context "relationship exists" do
|
||||
before do
|
||||
user1.public_send(type, user2)
|
||||
end
|
||||
|
||||
it "destroys a relationship" do
|
||||
expect { subject }.to change { Relationship.count }.by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
context "relationship does not exist" do
|
||||
it "does not change anything at all" do
|
||||
expect { subject }.to change { Relationship.count }.by(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "current_user does not exist" do
|
||||
let(:current_user) { "Schweinsbraten" }
|
||||
let(:target_user) { user2.screen_name }
|
||||
|
||||
include_examples "raises an error", Errors::UserNotFound
|
||||
end
|
||||
|
||||
context "target_user does not exist" do
|
||||
let(:current_user) { user1.screen_name }
|
||||
let(:target_user) { "peterwitzig" }
|
||||
|
||||
include_examples "raises an error", Errors::UserNotFound
|
||||
end
|
||||
end
|
||||
|
||||
let(:base_params) do
|
||||
{
|
||||
current_user: current_user,
|
||||
target_user: target_user,
|
||||
type: type
|
||||
}
|
||||
end
|
||||
let(:params) { base_params }
|
||||
let(:current_user) { user1.screen_name }
|
||||
let(:target_user) { user2.screen_name }
|
||||
let(:type) { nil }
|
||||
|
||||
# test data:
|
||||
let!(:user1) { FactoryBot.create(:user, screen_name: "timallen") }
|
||||
let!(:user2) { FactoryBot.create(:user, screen_name: "joehilyar") }
|
||||
|
||||
subject { described_class.call(params) }
|
||||
|
||||
context "type = 'follow'" do
|
||||
let(:type) { "follow" }
|
||||
|
||||
include_examples "valid relationship type"
|
||||
end
|
||||
|
||||
context "type = 'dick'" do
|
||||
let(:type) { "dick" }
|
||||
|
||||
include_examples "raises an error", Dry::Types::ConstraintError
|
||||
end
|
||||
end
|
|
@ -1,5 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.shared_examples_for "raises an error" do |error_klass|
|
||||
it "raises an error" do
|
||||
expect { subject }.to raise_error(kind_of(error_klass))
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_examples_for "ajax does not succeed" do |part_of_error_message|
|
||||
it "ajax does not succeed" do
|
||||
subject
|
||||
|
|
Loading…
Reference in New Issue