Implement relationship logic as use case
This commit is contained in:
parent
d20e07ee19
commit
3962671135
|
@ -1,39 +0,0 @@
|
||||||
class Ajax::FriendController < AjaxController
|
|
||||||
def create
|
|
||||||
params.require :screen_name
|
|
||||||
|
|
||||||
target_user = User.find_by_screen_name(params[:screen_name])
|
|
||||||
|
|
||||||
begin
|
|
||||||
current_user.follow target_user
|
|
||||||
rescue => e
|
|
||||||
Sentry.capture_exception(e)
|
|
||||||
@response[:status] = :fail
|
|
||||||
@response[:message] = I18n.t('messages.friend.create.fail')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
@response[:status] = :okay
|
|
||||||
@response[:message] = I18n.t('messages.friend.create.okay')
|
|
||||||
@response[:success] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
params.require :screen_name
|
|
||||||
|
|
||||||
target_user = User.find_by_screen_name(params[:screen_name])
|
|
||||||
|
|
||||||
begin
|
|
||||||
current_user.unfollow target_user
|
|
||||||
rescue => e
|
|
||||||
Sentry.capture_exception(e)
|
|
||||||
@response[:status] = :fail
|
|
||||||
@response[:message] = I18n.t('messages.friend.destroy.fail')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
@response[:status] = :okay
|
|
||||||
@response[:message] = I18n.t('messages.friend.destroy.okay')
|
|
||||||
@response[:success] = true
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "use_case/relationship/create"
|
||||||
|
require "use_case/relationship/destroy"
|
||||||
|
require "errors"
|
||||||
|
|
||||||
|
class Ajax::RelationshipController < AjaxController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
|
||||||
|
def create
|
||||||
|
UseCase::Relationship::Create.call(
|
||||||
|
current_user_id: current_user.id,
|
||||||
|
target_user: params[:target_user],
|
||||||
|
type: params[:type]
|
||||||
|
)
|
||||||
|
@response[:success] = true
|
||||||
|
@response[:message] = t(".success")
|
||||||
|
rescue Errors::Base => e
|
||||||
|
@response[:message] = t(e.locale_tag)
|
||||||
|
ensure
|
||||||
|
return_response
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
UseCase::Relationship::Destroy.call(
|
||||||
|
current_user_id: current_user.id,
|
||||||
|
target_user: params[:target_user],
|
||||||
|
type: params[:type]
|
||||||
|
)
|
||||||
|
@response[:success] = true
|
||||||
|
@response[:message] = t(".success")
|
||||||
|
rescue Errors::Base => e
|
||||||
|
@response[:message] = t(e.locale_tag)
|
||||||
|
ensure
|
||||||
|
return_response
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,14 +7,15 @@ export function userActionHandler(event: Event): void {
|
||||||
const target = button.dataset.target;
|
const target = button.dataset.target;
|
||||||
const action = button.dataset.action;
|
const action = button.dataset.action;
|
||||||
|
|
||||||
const targetURL = action === 'follow' ? '/ajax/create_friend' : '/ajax/destroy_friend';
|
const targetURL = action === 'follow' ? '/ajax/create_relationship' : '/ajax/destroy_relationship';
|
||||||
let success = false;
|
let success = false;
|
||||||
|
|
||||||
Rails.ajax({
|
Rails.ajax({
|
||||||
url: targetURL,
|
url: targetURL,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: new URLSearchParams({
|
data: new URLSearchParams({
|
||||||
screen_name: target
|
screen_name: target,
|
||||||
|
type: "follow"
|
||||||
}).toString(),
|
}).toString(),
|
||||||
success: (data) => {
|
success: (data) => {
|
||||||
success = data.success;
|
success = data.success;
|
||||||
|
|
|
@ -95,16 +95,6 @@ class User < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# follows an user.
|
|
||||||
def follow(target_user)
|
|
||||||
active_relationships.create(target: target_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
# unfollows an user
|
|
||||||
def unfollow(target_user)
|
|
||||||
active_relationships.find_by(target: target_user).destroy
|
|
||||||
end
|
|
||||||
|
|
||||||
# @param list [List]
|
# @param list [List]
|
||||||
# @return [Boolean] true if +self+ is a member of +list+
|
# @return [Boolean] true if +self+ is a member of +list+
|
||||||
def member_of?(list)
|
def member_of?(list)
|
||||||
|
|
|
@ -20,9 +20,7 @@ class User
|
||||||
|
|
||||||
# Follow an user
|
# Follow an user
|
||||||
def follow(target_user)
|
def follow(target_user)
|
||||||
raise Justask::Errors::FollowingOtherBlockedSelf if target_user.blocking?(self)
|
raise Errors::FollowingSelf if target_user == self
|
||||||
raise Justask::Errors::FollowingSelfBlockedOther if blocking?(target_user)
|
|
||||||
raise Justask::Errors::FollowingSelf if target_user == self
|
|
||||||
create_relationship(active_follow_relationships, target_user)
|
create_relationship(active_follow_relationships, target_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -457,3 +457,24 @@ en:
|
||||||
invalid_code: "The code you entered was invalid."
|
invalid_code: "The code you entered was invalid."
|
||||||
setup:
|
setup:
|
||||||
success: "Two factor authentication has been enabled for your account."
|
success: "Two factor authentication has been enabled for your account."
|
||||||
|
errors:
|
||||||
|
base: "An error occurred"
|
||||||
|
|
||||||
|
bad_request: "Bad Request"
|
||||||
|
param_is_missing: "param is missing"
|
||||||
|
|
||||||
|
forbidden: "This is illegal, you know"
|
||||||
|
blocked: "You have been blocked from performing this request"
|
||||||
|
other_blocked_self: "You have been blocked by this user"
|
||||||
|
asking_other_blocked_self: "You have been blocked from asking this user questions"
|
||||||
|
following_other_blocked_self: "You have been blocked from following this user"
|
||||||
|
self_blocked_other: "You cannot do this while blocking this user"
|
||||||
|
asking_self_blocked_other: "You cannot ask an user who you are currently blocking"
|
||||||
|
following_self_blocked_other: "You cannot follow an user who you are currently blocking"
|
||||||
|
self_action: "You cannot do this to yourself"
|
||||||
|
following_self: "You cannot follow yourself"
|
||||||
|
|
||||||
|
not_found: "That does not exist"
|
||||||
|
user_not_found: "User not found"
|
||||||
|
|
||||||
|
conflict: "This already exists"
|
||||||
|
|
|
@ -102,8 +102,8 @@ Rails.application.routes.draw do
|
||||||
match '/delete_all_inbox/:author', to: 'inbox#remove_all_author', via: :post, as: :delete_all_author
|
match '/delete_all_inbox/:author', to: 'inbox#remove_all_author', via: :post, as: :delete_all_author
|
||||||
match '/answer', to: 'answer#create', via: :post, as: :answer
|
match '/answer', to: 'answer#create', via: :post, as: :answer
|
||||||
match '/destroy_answer', to: 'answer#destroy', via: :post, as: :destroy_answer
|
match '/destroy_answer', to: 'answer#destroy', via: :post, as: :destroy_answer
|
||||||
match '/create_friend', to: 'friend#create', via: :post, as: :create_friend
|
match '/create_relationship', to: 'relationship#create', via: :post, as: :create_relationship
|
||||||
match '/destroy_friend', to: 'friend#destroy', via: :post, as: :destroy_friend
|
match '/destroy_relationship', to: 'relationship#destroy', via: :post, as: :destroy_relationship
|
||||||
match '/create_smile', to: 'smile#create', via: :post, as: :create_smile
|
match '/create_smile', to: 'smile#create', via: :post, as: :create_smile
|
||||||
match '/destroy_smile', to: 'smile#destroy', via: :post, as: :destroy_smile
|
match '/destroy_smile', to: 'smile#destroy', via: :post, as: :destroy_smile
|
||||||
match '/create_comment_smile', to: 'smile#create_comment', via: :post, as: :create_comment_smile
|
match '/create_comment_smile', to: 'smile#create_comment', via: :post, as: :create_comment_smile
|
||||||
|
|
|
@ -122,7 +122,6 @@ ActiveRecord::Schema.define(version: 2022_01_05_171216) do
|
||||||
t.boolean "new"
|
t.boolean "new"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.string "state"
|
|
||||||
t.index ["new"], name: "index_notifications_on_new"
|
t.index ["new"], name: "index_notifications_on_new"
|
||||||
t.index ["recipient_id"], name: "index_notifications_on_recipient_id"
|
t.index ["recipient_id"], name: "index_notifications_on_recipient_id"
|
||||||
end
|
end
|
||||||
|
@ -278,12 +277,7 @@ ActiveRecord::Schema.define(version: 2022_01_05_171216) do
|
||||||
t.integer "asked_count", default: 0, null: false
|
t.integer "asked_count", default: 0, null: false
|
||||||
t.integer "answered_count", default: 0, null: false
|
t.integer "answered_count", default: 0, null: false
|
||||||
t.integer "commented_count", default: 0, null: false
|
t.integer "commented_count", default: 0, null: false
|
||||||
t.string "display_name"
|
|
||||||
t.integer "smiled_count", default: 0, null: false
|
t.integer "smiled_count", default: 0, null: false
|
||||||
t.string "motivation_header", default: "", null: false
|
|
||||||
t.string "website", default: "", null: false
|
|
||||||
t.string "location", default: "", null: false
|
|
||||||
t.text "bio", default: "", null: false
|
|
||||||
t.string "profile_picture_file_name"
|
t.string "profile_picture_file_name"
|
||||||
t.boolean "profile_picture_processing"
|
t.boolean "profile_picture_processing"
|
||||||
t.integer "profile_picture_x"
|
t.integer "profile_picture_x"
|
||||||
|
@ -329,6 +323,5 @@ ActiveRecord::Schema.define(version: 2022_01_05_171216) do
|
||||||
t.index ["user_id"], name: "index_users_roles_on_user_id"
|
t.index ["user_id"], name: "index_users_roles_on_user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_foreign_key "mute_rules", "users"
|
|
||||||
add_foreign_key "profiles", "users"
|
add_foreign_key "profiles", "users"
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,10 @@ module Errors
|
||||||
def code
|
def code
|
||||||
@code ||= self.class.name.sub('Errors::', '').underscore
|
@code ||= self.class.name.sub('Errors::', '').underscore
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def locale_tag
|
||||||
|
@locale_tag ||= "errors.#{code}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class BadRequest < Base
|
class BadRequest < Base
|
||||||
|
@ -15,6 +19,9 @@ module Errors
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ParamIsMissing < BadRequest
|
||||||
|
end
|
||||||
|
|
||||||
class InvalidBanDuration < BadRequest
|
class InvalidBanDuration < BadRequest
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -23,4 +30,19 @@ module Errors
|
||||||
403
|
403
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class SelfAction < Forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
class FollowingSelf < SelfAction
|
||||||
|
end
|
||||||
|
|
||||||
|
class NotFound < Base
|
||||||
|
def status
|
||||||
|
404
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class UserNotFound < NotFound
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,5 +15,13 @@ module UseCase
|
||||||
def call
|
def call
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def not_blank!(*args)
|
||||||
|
args.each do |arg|
|
||||||
|
raise Errors::ParamIsMissing if instance_variable_get("@#{arg}").blank?
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -0,0 +1,54 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "use_case/base"
|
||||||
|
require "errors"
|
||||||
|
|
||||||
|
module UseCase
|
||||||
|
module Relationship
|
||||||
|
class Create < UseCase::Base
|
||||||
|
option :current_user_id, type: Types::Coercible::Integer
|
||||||
|
option :target_user, type: Types::Coercible::String
|
||||||
|
option :type, type: Types::Coercible::String
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
source_user.public_send(type, target_user)
|
||||||
|
|
||||||
|
{
|
||||||
|
status: 201,
|
||||||
|
resource: true,
|
||||||
|
extra: {
|
||||||
|
target_user: target_user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,54 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "use_case/base"
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
source_user.public_send("un#{type}", target_user)
|
||||||
|
|
||||||
|
{
|
||||||
|
status: 204,
|
||||||
|
resource: nil,
|
||||||
|
extra: {
|
||||||
|
target_user: target_user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
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)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,159 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "rails_helper"
|
|
||||||
|
|
||||||
describe Ajax::FriendController, :ajax_controller, type: :controller do
|
|
||||||
describe "#create" do
|
|
||||||
let(:params) do
|
|
||||||
{
|
|
||||||
screen_name: screen_name
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { post(:create, params: params) }
|
|
||||||
|
|
||||||
context "when user is signed in" do
|
|
||||||
before(:each) { sign_in(user) }
|
|
||||||
|
|
||||||
context "when target user exists" do
|
|
||||||
let(:target_user) { FactoryBot.create(:user) }
|
|
||||||
let(:screen_name) { target_user.screen_name }
|
|
||||||
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => true,
|
|
||||||
"status" => "okay",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates a follow relationship" do
|
|
||||||
expect(user.followings.ids).not_to include(target_user.id)
|
|
||||||
expect { subject }.to(change { user.followings.count }.by(1))
|
|
||||||
expect(user.followings.ids).to include(target_user.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when target user does not exist" do
|
|
||||||
let(:screen_name) { "tripmeister_eder" }
|
|
||||||
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => true,
|
|
||||||
"status" => "okay",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not create a follow relationship" do
|
|
||||||
expect { subject }.not_to(change { user.followings.count })
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when user is not signed in" do
|
|
||||||
let(:screen_name) { "tutenchamun" }
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => false,
|
|
||||||
"status" => "fail",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#destroy" do
|
|
||||||
let(:params) do
|
|
||||||
{
|
|
||||||
screen_name: screen_name
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { delete(:destroy, params: params) }
|
|
||||||
|
|
||||||
context "when user is signed in" do
|
|
||||||
before(:each) { sign_in(user) }
|
|
||||||
|
|
||||||
context "when target user exists" do
|
|
||||||
let(:target_user) { FactoryBot.create(:user) }
|
|
||||||
let(:screen_name) { target_user.screen_name }
|
|
||||||
|
|
||||||
before(:each) { target_user }
|
|
||||||
|
|
||||||
context "when user follows target" do
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => true,
|
|
||||||
"status" => "okay",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
before(:each) { user.follow target_user }
|
|
||||||
|
|
||||||
it "destroys a follow relationship" do
|
|
||||||
expect(user.followings.ids).to include(target_user.id)
|
|
||||||
expect { subject }.to(change { user.followings.count }.by(-1))
|
|
||||||
expect(user.followings.ids).not_to include(target_user.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when user does not already follow target" do
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => false,
|
|
||||||
"status" => "fail",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not destroy a follow relationship" do
|
|
||||||
expect { subject }.not_to(change { user.followings.count })
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when target user does not exist" do
|
|
||||||
let(:screen_name) { "tripmeister_eder" }
|
|
||||||
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => false,
|
|
||||||
"status" => "fail",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not destroy a follow relationship" do
|
|
||||||
expect { subject }.not_to(change { user.followings.count })
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when user is not signed in" do
|
|
||||||
let(:screen_name) { "tutenchamun" }
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => false,
|
|
||||||
"status" => "fail",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
# coding: utf-8
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
include_examples "ajax does not succeed", "param is missing"
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:user) { FactoryBot.create(:user) }
|
||||||
|
let!(:user2) { FactoryBot.create(:user) }
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
shared_examples_for "valid relationship type" do
|
||||||
|
it_behaves_like "params is empty"
|
||||||
|
|
||||||
|
context "target_user does not exist" do
|
||||||
|
let(:target_user) { "peter-witzig" }
|
||||||
|
|
||||||
|
include_examples "ajax does not succeed", "not found"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "target_user is current user" do
|
||||||
|
let(:target_user) { user.screen_name }
|
||||||
|
|
||||||
|
include_examples "ajax does not succeed", "yourself"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "target_user is different from current_user" do
|
||||||
|
let(:target_user) { user2.screen_name }
|
||||||
|
|
||||||
|
it "creates the relationship" do
|
||||||
|
expect { subject }.to change { Relationship.count }.by(1)
|
||||||
|
expect(Relationship.last.target.screen_name).to eq(target_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:type) { "Sauerkraut" }
|
||||||
|
let(:target_user) { user2.screen_name }
|
||||||
|
let(:params) { { type: type, target_user: target_user } }
|
||||||
|
|
||||||
|
subject { post(:create, params: params) }
|
||||||
|
|
||||||
|
it_behaves_like "requires login"
|
||||||
|
|
||||||
|
context "user signed in" do
|
||||||
|
before(:each) { sign_in(user) }
|
||||||
|
|
||||||
|
context "type = 'follow'" do
|
||||||
|
let(:type) { "follow" }
|
||||||
|
|
||||||
|
include_examples "valid relationship type"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "type = 'dick'" do
|
||||||
|
let(:type) { "dick" }
|
||||||
|
|
||||||
|
it_behaves_like "params is empty"
|
||||||
|
include_examples "ajax does not succeed", "Bad Request"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#destroy" do
|
||||||
|
shared_examples_for "valid relationship type" do
|
||||||
|
let(:target_user) { user2.screen_name }
|
||||||
|
|
||||||
|
context "relationship exists" do
|
||||||
|
before do
|
||||||
|
user.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
|
||||||
|
|
||||||
|
it_behaves_like "params is empty"
|
||||||
|
|
||||||
|
context "target_user does not exist" do
|
||||||
|
let(:target_user) { "peter-witzig" }
|
||||||
|
|
||||||
|
include_examples "ajax does not succeed", "not found"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:type) { "Sauerkraut" }
|
||||||
|
let(:target_user) { user2.screen_name }
|
||||||
|
let(:params) { { type: type, target_user: target_user } }
|
||||||
|
|
||||||
|
subject { delete(:destroy, params: params) }
|
||||||
|
|
||||||
|
it_behaves_like "requires login"
|
||||||
|
|
||||||
|
context "user signed in" do
|
||||||
|
before(:each) { sign_in(user) }
|
||||||
|
|
||||||
|
context "type = 'follow'" do
|
||||||
|
let(:type) { "follow" }
|
||||||
|
|
||||||
|
include_examples "valid relationship type"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "type = 'dick'" do
|
||||||
|
let(:type) { "dick" }
|
||||||
|
|
||||||
|
it_behaves_like "params is empty"
|
||||||
|
include_examples "ajax does not succeed", "Bad Request"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
RSpec.shared_examples_for "ajax does not succeed" do |part_of_error_message|
|
||||||
|
it "ajax does not succeed" do
|
||||||
|
subject
|
||||||
|
expect(assigns(:response)[:success]).to be false
|
||||||
|
expect(assigns(:response)[:message]).to include(part_of_error_message)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
RSpec.shared_examples_for "requires login" do
|
||||||
|
it "redirects to the login page for guests" do
|
||||||
|
subject
|
||||||
|
expect(response).to redirect_to(new_user_session_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not redirect to the login page for users" do
|
||||||
|
sign_in user
|
||||||
|
subject
|
||||||
|
expect(response).to_not redirect_to(new_user_session_path)
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue