Merge branch 'master' into feature/bootstrap
This commit is contained in:
commit
53979580d8
|
@ -67,3 +67,7 @@ jobs:
|
|||
env:
|
||||
POSTGRES_PORT: ${{ job.services.postgres.ports[5432] }}
|
||||
REDIS_URL: "redis://localhost:${{ job.services.redis.ports[6379] }}"
|
||||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
file: ./coverage/coverage.xml
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -90,14 +90,14 @@ group :development, :test do
|
|||
gem 'puma'
|
||||
gem 'rspec-rails', '~> 3.9'
|
||||
gem 'rspec-its', '~> 1.3'
|
||||
gem "rspec-sidekiq", "~> 3.0"
|
||||
gem "rspec-sidekiq", "~> 3.0", require: false
|
||||
gem 'factory_bot_rails', require: false
|
||||
gem 'faker'
|
||||
gem 'capybara'
|
||||
gem 'poltergeist'
|
||||
gem 'simplecov', require: false
|
||||
gem 'simplecov-json', require: false
|
||||
gem 'simplecov-rcov', require: false
|
||||
gem 'simplecov-cobertura', require: false
|
||||
gem 'database_cleaner'
|
||||
gem 'better_errors'
|
||||
gem 'letter_opener' # Use this just in local test environments
|
||||
|
|
|
@ -444,12 +444,12 @@ GEM
|
|||
simplecov (0.18.5)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov-cobertura (1.3.1)
|
||||
simplecov (~> 0.8)
|
||||
simplecov-html (0.12.2)
|
||||
simplecov-json (0.2.1)
|
||||
json
|
||||
simplecov
|
||||
simplecov-rcov (0.2.3)
|
||||
simplecov (>= 0.4.1)
|
||||
spring (2.1.0)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
|
@ -572,8 +572,8 @@ DEPENDENCIES
|
|||
sass-rails (~> 5.0)
|
||||
sidekiq (< 6)
|
||||
simplecov
|
||||
simplecov-cobertura
|
||||
simplecov-json
|
||||
simplecov-rcov
|
||||
spring (~> 2.0)
|
||||
sweetalert-rails
|
||||
timecop
|
||||
|
|
|
@ -19,7 +19,7 @@ class Ajax::GroupController < AjaxController
|
|||
params.require :user
|
||||
|
||||
begin
|
||||
target_user = User.find_by_screen_name(params[:user])
|
||||
target_user = User.find_by_screen_name!(params[:user])
|
||||
group = Group.create! user: current_user, display_name: params[:name]
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
NewRelic::Agent.notice_error(e)
|
||||
|
@ -85,7 +85,7 @@ class Ajax::GroupController < AjaxController
|
|||
add = params[:add] == 'true'
|
||||
|
||||
begin
|
||||
group = current_user.groups.find_by_name(params[:group])
|
||||
group = current_user.groups.find_by_name!(params[:group])
|
||||
rescue ActiveRecord::RecordNotFound => e
|
||||
NewRelic::Agent.notice_error(e)
|
||||
@response[:status] = :notfound
|
||||
|
@ -93,7 +93,7 @@ class Ajax::GroupController < AjaxController
|
|||
return
|
||||
end
|
||||
|
||||
target_user = User.find_by_screen_name(params[:user])
|
||||
target_user = User.find_by_screen_name!(params[:user])
|
||||
|
||||
if add
|
||||
group.add_member target_user if group.members.find_by_user_id(target_user.id).nil?
|
||||
|
|
|
@ -46,6 +46,8 @@ class Ajax::InboxController < AjaxController
|
|||
end
|
||||
|
||||
def remove_all
|
||||
raise unless user_signed_in?
|
||||
|
||||
begin
|
||||
Inbox.where(user: current_user).each { |i| i.remove }
|
||||
rescue => e
|
||||
|
|
|
@ -111,7 +111,7 @@ class Ajax::ModerationController < AjaxController
|
|||
params.require :permaban
|
||||
|
||||
reason = params[:reason]
|
||||
target = User.find_by_screen_name(params[:user])
|
||||
target = User.find_by_screen_name!(params[:user])
|
||||
unban = params[:ban] == "0"
|
||||
perma = params[:permaban] == "1"
|
||||
|
||||
|
@ -149,7 +149,7 @@ class Ajax::ModerationController < AjaxController
|
|||
|
||||
status = params[:status] == 'true'
|
||||
|
||||
target_user = User.find_by_screen_name(params[:user])
|
||||
target_user = User.find_by_screen_name!(params[:user])
|
||||
|
||||
@response[:message] = I18n.t('messages.moderation.privilege.nope')
|
||||
return unless %w(moderator admin).include? params[:type].downcase
|
||||
|
|
|
@ -27,9 +27,11 @@ class Ajax::QuestionController < AjaxController
|
|||
params.require :anonymousQuestion
|
||||
params.require :rcpt
|
||||
|
||||
is_never_anonymous = user_signed_in? && (params[:rcpt].start_with?('grp:') || params[:rcpt] == 'followers')
|
||||
|
||||
begin
|
||||
question = Question.create!(content: params[:question],
|
||||
author_is_anonymous: params[:anonymousQuestion],
|
||||
author_is_anonymous: is_never_anonymous ? false : params[:anonymousQuestion],
|
||||
user: current_user)
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
NewRelic::Agent.notice_error(e)
|
||||
|
@ -38,6 +40,11 @@ class Ajax::QuestionController < AjaxController
|
|||
return
|
||||
end
|
||||
|
||||
if !user_signed_in? && !question.author_is_anonymous
|
||||
question.delete
|
||||
return
|
||||
end
|
||||
|
||||
unless current_user.nil?
|
||||
current_user.increment! :asked_count unless params[:anonymousQuestion] == 'true'
|
||||
end
|
||||
|
@ -53,19 +60,27 @@ class Ajax::QuestionController < AjaxController
|
|||
QuestionWorker.perform_async params[:rcpt], current_user.id, question.id
|
||||
rescue ActiveRecord::RecordNotFound => e
|
||||
NewRelic::Agent.notice_error(e)
|
||||
question.delete
|
||||
@response[:status] = :not_found
|
||||
@response[:message] = I18n.t('messages.question.create.not_found')
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
if User.find(params[:rcpt]).nil?
|
||||
u = User.find_by_id(params[:rcpt])
|
||||
if u.nil?
|
||||
@response[:status] = :not_found
|
||||
@response[:message] = I18n.t('messages.question.create.not_found')
|
||||
question.delete
|
||||
return
|
||||
end
|
||||
|
||||
Inbox.create!(user_id: params[:rcpt], question_id: question.id, new: true)
|
||||
if !u.privacy_allow_anonymous_questions && question.author_is_anonymous
|
||||
question.delete
|
||||
return
|
||||
end
|
||||
|
||||
Inbox.create!(user_id: u.id, question_id: question.id, new: true)
|
||||
end
|
||||
|
||||
@response[:status] = :okay
|
||||
|
|
|
@ -19,7 +19,7 @@ class Ajax::ReportController < AjaxController
|
|||
|
||||
object = case obj
|
||||
when 'User'
|
||||
User.find_by_screen_name params[:id]
|
||||
User.find_by_screen_name! params[:id]
|
||||
when 'Question'
|
||||
Question.find params[:id]
|
||||
when 'Answer'
|
||||
|
|
|
@ -6,6 +6,18 @@ class AjaxController < ApplicationController
|
|||
|
||||
respond_to :json
|
||||
|
||||
rescue_from(StandardError) do |e|
|
||||
NewRelic::Agent.notice_error(e)
|
||||
|
||||
@response = {
|
||||
success: false,
|
||||
message: "Something went wrong",
|
||||
status: :err
|
||||
}
|
||||
|
||||
return_response
|
||||
end
|
||||
|
||||
rescue_from(ActiveRecord::RecordNotFound) do |e|
|
||||
NewRelic::Agent.notice_error(e)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Question < ApplicationRecord
|
||||
include Question::AnswerMethods
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :user, optional: true
|
||||
has_many :answers, dependent: :destroy
|
||||
has_many :inboxes, dependent: :destroy
|
||||
|
||||
|
|
|
@ -3,14 +3,7 @@
|
|||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::AnswerController, type: :controller do
|
||||
shared_examples "returns the expected response" do
|
||||
it "returns the expected response" do
|
||||
expect(JSON.parse(subject.body)).to match(expected_response)
|
||||
end
|
||||
end
|
||||
|
||||
let(:user) { FactoryBot.create(:user) }
|
||||
describe Ajax::AnswerController, :ajax_controller, type: :controller do
|
||||
let(:question) { FactoryBot.create(:question, user: FactoryBot.build(:user, privacy_allow_stranger_answers: asker_allows_strangers)) }
|
||||
let(:asker_allows_strangers) { true }
|
||||
|
||||
|
@ -186,7 +179,7 @@ describe Ajax::AnswerController, type: :controller do
|
|||
|
||||
describe "#destroy" do
|
||||
let(:answer_user) { user }
|
||||
let(:question) { FactoryBot.create(:question, user: FactoryBot.create(:user)) }
|
||||
let(:question) { FactoryBot.create(:question) }
|
||||
let(:answer) { FactoryBot.create(:answer, user: answer_user, question: question) }
|
||||
let(:answer_id) { answer.id }
|
||||
|
||||
|
|
|
@ -0,0 +1,226 @@
|
|||
# coding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::CommentController, :ajax_controller, type: :controller do
|
||||
let(:answer) { FactoryBot.create(:answer, user: FactoryBot.create(:user)) }
|
||||
|
||||
describe "#create" do
|
||||
let(:params) do
|
||||
{
|
||||
answer: answer_id,
|
||||
comment: comment
|
||||
}.compact
|
||||
end
|
||||
|
||||
subject { post(:create, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
shared_examples "creates the comment" do
|
||||
it "creates a comment to the answer" do
|
||||
expect { subject }.to(change { Comment.count }.by(1))
|
||||
expect(answer.reload.comments.ids).to include(Comment.last.id)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
shared_examples "does not create the comment" do
|
||||
it "does not create a comment" do
|
||||
expect { subject }.not_to(change { Comment.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when all parameters are given" do
|
||||
let(:comment) { "// Here be dragons." }
|
||||
|
||||
context "when answer exists" do
|
||||
let(:answer_id) { answer.id }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"render" => anything,
|
||||
"count" => 1
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "creates the comment"
|
||||
|
||||
context "when comment is too long" do
|
||||
let(:comment) { "E" * 621 }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "rec_inv",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "does not create the comment"
|
||||
end
|
||||
end
|
||||
|
||||
context "when answer does not exist" do
|
||||
let(:answer_id) { "nein!" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => anything,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "does not create the comment"
|
||||
end
|
||||
end
|
||||
|
||||
context "when some parameters are missing" do
|
||||
let(:answer_id) { nil }
|
||||
let(:comment) { "" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "parameter_error",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:answer_id) { answer.id }
|
||||
let(:comment) { "HACKED" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
let(:answer_user) { FactoryBot.create(:user) }
|
||||
let(:answer) { FactoryBot.create(:answer, user: answer_user) }
|
||||
let(:comment_user) { user }
|
||||
let(:comment) { FactoryBot.create(:comment, user: comment_user, answer: answer) }
|
||||
let(:comment_id) { comment.id }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
comment: comment_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { delete(:destroy, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
shared_examples "deletes the comment" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"count" => 0
|
||||
}
|
||||
end
|
||||
|
||||
it "deletes the comment" do
|
||||
comment # ensure we already have it in the db
|
||||
expect { subject }.to(change { Comment.count }.by(-1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
shared_examples "does not delete the comment" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "nopriv",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not delete the comment" do
|
||||
comment # ensure we already have it in the db
|
||||
expect { subject }.not_to(change { Comment.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when the comment exists and was made by the current user" do
|
||||
include_examples "deletes the comment"
|
||||
end
|
||||
|
||||
context "when the comment exists and was not made by the current user" do
|
||||
let(:comment_user) { FactoryBot.create(:user) }
|
||||
|
||||
include_examples "does not delete the comment"
|
||||
|
||||
context "when the current user created the answer" do
|
||||
let(:answer_user) { user }
|
||||
|
||||
include_examples "deletes the comment"
|
||||
end
|
||||
|
||||
%i[moderator administrator].each do |privileged_role|
|
||||
context "when the current user is a #{privileged_role}" do
|
||||
around do |example|
|
||||
user.add_role privileged_role
|
||||
example.run
|
||||
user.remove_role privileged_role
|
||||
end
|
||||
|
||||
include_examples "deletes the comment"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the comment does not exist" do
|
||||
let(:comment_id) { "sonic_the_hedgehog" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => anything,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "nopriv",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,159 @@
|
|||
# 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.friends.ids).not_to include(target_user.id)
|
||||
expect { subject }.to(change { user.friends.count }.by(1))
|
||||
expect(user.friends.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.friends.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.friends.ids).to include(target_user.id)
|
||||
expect { subject }.to(change { user.friends.count }.by(-1))
|
||||
expect(user.friends.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.friends.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.friends.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,341 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::GroupController, :ajax_controller, type: :controller do
|
||||
let(:target_user) { FactoryBot.create(:user) }
|
||||
|
||||
describe "#create" do
|
||||
let(:name) { "I signori della gallassia" }
|
||||
let(:target_user_param) { target_user.screen_name }
|
||||
let(:params) do
|
||||
{
|
||||
"name" => name,
|
||||
"user" => target_user_param
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:create, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"render" => anything
|
||||
}
|
||||
end
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
it "creates the group" do
|
||||
expect { subject }.to(change { user.groups.count }.by(1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when name param is missing" do
|
||||
let(:name) { "" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "toolong",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create the group" do
|
||||
expect { subject }.not_to(change { user.groups.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when target user does not exist" do
|
||||
let(:target_user_param) { "giuseppe-drogo" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "notfound",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create the group" do
|
||||
expect { subject }.not_to(change { user.groups.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when group name is invalid for reasons" do
|
||||
let(:name) { "\u{1f43e}" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "toolong",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create the group" do
|
||||
expect { subject }.not_to(change { user.groups.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when group already exists" do
|
||||
before(:each) { post(:create, params: params) }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "exists",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create the group" do
|
||||
expect { subject }.not_to(change { user.groups.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when someone else created a group with the same name" do
|
||||
before(:each) do
|
||||
FactoryBot.create(:group, user: target_user, display_name: name)
|
||||
end
|
||||
|
||||
it "creates the group" do
|
||||
expect { subject }.to(change { user.groups.count }.by(1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "noauth",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
let(:name) { "I signori della gallassia" }
|
||||
let(:group) { FactoryBot.create(:group, user: user, display_name: name) }
|
||||
let(:group_param) { group.name }
|
||||
let(:params) do
|
||||
{
|
||||
"group" => group_param
|
||||
}
|
||||
end
|
||||
|
||||
subject { delete(:destroy, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
it "deletes the group" do
|
||||
group
|
||||
expect { subject }.to(change { user.groups.count }.by(-1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when group param is missing" do
|
||||
let(:group_param) { "" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "parameter_error",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not delete the group" do
|
||||
expect { subject }.not_to(change { user.groups.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when group does not exist" do
|
||||
let(:group_param) { "the-foobars-and-the-dingdongs" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not delete the group" do
|
||||
expect { subject }.not_to(change { user.groups.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when someone else created a group with the same name" do
|
||||
before(:each) do
|
||||
group
|
||||
FactoryBot.create(:group, user: target_user, display_name: name)
|
||||
end
|
||||
|
||||
it "deletes the group" do
|
||||
expect { subject }.to(change { user.groups.count }.by(-1))
|
||||
end
|
||||
|
||||
it "does not delete the other users' group" do
|
||||
expect { subject }.not_to(change { target_user.groups.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "noauth",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#membership" do
|
||||
let(:name) { "The Agency" }
|
||||
let(:members) { [] }
|
||||
let(:group) { FactoryBot.create(:group, user: user, display_name: name, members: members) }
|
||||
let(:group_param) { group.name }
|
||||
let(:target_user_param) { target_user.screen_name }
|
||||
let(:params) do
|
||||
{
|
||||
"group" => group_param,
|
||||
"user" => target_user_param,
|
||||
"add" => add_param
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:membership, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"checked" => expected_checked
|
||||
}
|
||||
end
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when add is false" do
|
||||
let(:add_param) { "false" }
|
||||
let(:expected_checked) { false }
|
||||
|
||||
it "does not do anything" do
|
||||
expect { subject }.not_to(change { group.members })
|
||||
expect(group.members.map { |gm| gm.user.id }.sort ).to eq([])
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when the user was already added to the group" do
|
||||
let(:members) { [target_user] }
|
||||
|
||||
it "removes the user from the group" do
|
||||
expect { subject }.to(change { group.reload.members.map { |gm| gm.user.id }.sort }.from([target_user.id]).to([]))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when add is true" do
|
||||
let(:add_param) { "true" }
|
||||
let(:expected_checked) { true }
|
||||
|
||||
it "adds the user to the group" do
|
||||
expect { subject }.to(change { group.reload.members.map { |gm| gm.user.id }.sort }.from([]).to([target_user.id]))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when the user was already added to the group" do
|
||||
let(:members) { [target_user] }
|
||||
|
||||
it "does not add the user to the group again" do
|
||||
expect { subject }.not_to(change { group.members })
|
||||
expect(group.members.map { |gm| gm.user.id }.sort ).to eq([target_user.id])
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when group does not exist" do
|
||||
let(:group_param) { "the-good-agency" }
|
||||
let(:add_param) { "add" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "notfound",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when target user does not exist" do
|
||||
let(:target_user_param) { "erwin-proell" }
|
||||
let(:add_param) { "add" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:add_param) { "whatever" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "noauth",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,244 @@
|
|||
# coding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::InboxController, :ajax_controller, type: :controller do
|
||||
describe "#create" do
|
||||
subject { post(:create) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"render" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "creates a generated question to the user's inbox" do
|
||||
allow(QuestionGenerator).to receive(:generate).and_return("Is Mayonnaise an instrument?")
|
||||
expect { subject }.to(change { user.inboxes.count }.by(1))
|
||||
expect(user.inboxes.last.question.author_is_anonymous).to eq(true)
|
||||
expect(user.inboxes.last.question.author_name).to eq("justask")
|
||||
expect(user.inboxes.last.question.user).to eq(user)
|
||||
expect(user.inboxes.last.question.content).to eq("Is Mayonnaise an instrument?")
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "noauth",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#remove" do
|
||||
let(:params) do
|
||||
{
|
||||
id: inbox_entry_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { delete(:remove, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when inbox entry exists" do
|
||||
let(:inbox_entry) { FactoryBot.create(:inbox, user: inbox_user) }
|
||||
let(:inbox_entry_id) { inbox_entry.id }
|
||||
|
||||
# ensure the inbox entry exists
|
||||
before(:each) { inbox_entry }
|
||||
|
||||
context "when inbox entry belongs to the current user" do
|
||||
let(:inbox_user) { user }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "removes the inbox entry" do
|
||||
expect { subject }.to(change { user.inboxes.count }.by(-1))
|
||||
expect { Inbox.find(inbox_entry.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when inbox entry does not belong to the current user" do
|
||||
let(:inbox_user) { FactoryBot.create(:user) }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not remove the inbox entry" do
|
||||
expect { subject }.not_to(change { Inbox.count })
|
||||
expect { Inbox.find(inbox_entry.id) }.not_to raise_error
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when inbox entry does not exist" do
|
||||
let(:inbox_entry_id) { "Nein!" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:inbox_entry_id) { "HACKED" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#remove_all" do
|
||||
subject { delete(:remove_all) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when user has some inbox entries" do
|
||||
let(:some_other_user) { FactoryBot.create(:user) }
|
||||
before do
|
||||
10.times { FactoryBot.create(:inbox, user: user) }
|
||||
10.times { FactoryBot.create(:inbox, user: some_other_user) }
|
||||
end
|
||||
|
||||
it "deletes all the entries from the user's inbox" do
|
||||
expect { subject }.to(change { [Inbox.count, user.inboxes.count] }.from([20, 10]).to([10, 0]))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#remove_all_author" do
|
||||
let(:params) do
|
||||
{
|
||||
author: author
|
||||
}
|
||||
end
|
||||
|
||||
subject { delete(:remove_all_author, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
let(:author) { user.screen_name }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when user has some inbox entries" do
|
||||
let(:some_other_user) { FactoryBot.create(:user) }
|
||||
let(:author) { some_other_user.screen_name }
|
||||
before do
|
||||
normal_question = FactoryBot.create(:question, user: some_other_user, author_is_anonymous: false)
|
||||
anon_question = FactoryBot.create(:question, user: some_other_user, author_is_anonymous: true)
|
||||
|
||||
10.times { FactoryBot.create(:inbox, user: user) }
|
||||
3.times { FactoryBot.create(:inbox, user: user, question: normal_question) }
|
||||
2.times { FactoryBot.create(:inbox, user: user, question: anon_question) }
|
||||
end
|
||||
|
||||
it "deletes all the entries asked by some other user which are not anonymous from the user's inbox" do
|
||||
expect { subject }.to(change { user.inboxes.count }.from(15).to(12))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when author is unknown" do
|
||||
let(:author) { "schmarrn" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:author) { "hackerman1337" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,650 @@
|
|||
# coding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::ModerationController, :ajax_controller, type: :controller do
|
||||
shared_examples "fails when report does not exist" do
|
||||
let(:report_id) { "Burgenland" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
let(:target_user) { FactoryBot.create(:user) }
|
||||
let(:report) do
|
||||
Reports::User.create!(
|
||||
user: user,
|
||||
target_id: target_user.id
|
||||
)
|
||||
end
|
||||
let(:user_role) { :moderator }
|
||||
|
||||
before do
|
||||
user.add_role user_role if user_role
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
describe "#vote" do
|
||||
let(:params) do
|
||||
{
|
||||
id: report_id,
|
||||
upvote: upvote
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:vote, params: params) }
|
||||
|
||||
context "when report exists" do
|
||||
let(:report_id) { report.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"count" => expected_count
|
||||
}
|
||||
end
|
||||
|
||||
context "when upvote is true" do
|
||||
let(:upvote) { "true" }
|
||||
let(:expected_count) { 1 }
|
||||
|
||||
it "creates a moderation vote" do
|
||||
expect { subject }.to(change { ModerationVote.count }.by(1))
|
||||
expect(report.moderation_votes.last.user).to eq(user)
|
||||
expect(report.moderation_votes.last.upvote).to eq(true)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when moderation vote already exists" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
before { post(:vote, params: params) }
|
||||
|
||||
it "does not create a new moderation vote" do
|
||||
expect { subject }.to_not(change { ModerationVote.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when upvote is false" do
|
||||
let(:upvote) { "false" }
|
||||
let(:expected_count) { 0 }
|
||||
|
||||
it "creates a moderation vote" do
|
||||
expect { subject }.to(change { ModerationVote.count }.by(1))
|
||||
expect(report.moderation_votes.last.user).to eq(user)
|
||||
expect(report.moderation_votes.last.upvote).to eq(false)
|
||||
end
|
||||
|
||||
context "when moderation vote already exists" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
before { post(:vote, params: params) }
|
||||
|
||||
it "does not create a new moderation vote" do
|
||||
expect { subject }.to_not(change { ModerationVote.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "fails when report does not exist" do
|
||||
let(:upvote) { "true" }
|
||||
|
||||
it "does not create a moderation vote" do
|
||||
expect { subject }.to_not(change { ModerationVote.count })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy_vote" do
|
||||
let(:params) do
|
||||
{
|
||||
id: report_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:destroy_vote, params: params) }
|
||||
|
||||
context "when report exists" do
|
||||
let(:report_id) { report.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"count" => expected_count
|
||||
}
|
||||
end
|
||||
|
||||
context "when the user already voted" do
|
||||
let(:expected_count) { 0 }
|
||||
|
||||
before { post(:vote, params: params.merge("upvote" => true)) }
|
||||
|
||||
it "removes a moderation vote" do
|
||||
expect { subject }.to(change { ModerationVote.count }.by(-1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when the user has not voted yet" do
|
||||
let(:expected_count) { 0 }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a new moderation vote" do
|
||||
expect { subject }.to_not(change { ModerationVote.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "fails when report does not exist" do
|
||||
it "does not create a moderation vote" do
|
||||
expect { subject }.to_not(change { ModerationVote.count })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy_report" do
|
||||
let(:params) do
|
||||
{
|
||||
id: report_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:destroy_report, params: params) }
|
||||
|
||||
context "when report exists" do
|
||||
let(:report_id) { report.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
before { report }
|
||||
|
||||
it "does not actually destroy the report" do
|
||||
expect { subject }.to_not(change { Report.count })
|
||||
end
|
||||
|
||||
it "only marks the report as deleted" do
|
||||
expect { subject }.to(change { report.reload.deleted }.from(false).to(true))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
it_behaves_like "fails when report does not exist"
|
||||
end
|
||||
|
||||
describe "#create_comment" do
|
||||
let(:params) do
|
||||
{
|
||||
id: report_id,
|
||||
comment: comment
|
||||
}
|
||||
end
|
||||
let(:comment) { "ZEFIX NUAMOI!" }
|
||||
|
||||
subject { post(:create_comment, params: params) }
|
||||
|
||||
context "when report exists" do
|
||||
let(:report_id) { report.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"render" => anything,
|
||||
"count" => 1
|
||||
}
|
||||
end
|
||||
|
||||
it "creates a moderation comment" do
|
||||
expect { subject }.to(change { ModerationComment.count }.by(1))
|
||||
expect(report.moderation_comments.last.user).to eq(user)
|
||||
expect(report.moderation_comments.last.content).to eq(comment)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when comment is blank" do
|
||||
let(:comment) { "" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "parameter_error",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a moderation comment" do
|
||||
expect { subject }.to_not(change { ModerationComment.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when comment is the letter E 621 times" do
|
||||
let(:comment) { "E" * 621 }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "rec_inv",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a moderation comment" do
|
||||
expect { subject }.to_not(change { ModerationComment.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "fails when report does not exist" do
|
||||
it "does not create a moderation comment" do
|
||||
expect { subject }.to_not(change { ModerationComment.count })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy_comment" do
|
||||
let(:comment) { ModerationComment.create!(user: comment_user, report: report, content: "sigh") }
|
||||
let(:params) do
|
||||
{
|
||||
comment: comment_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:destroy_comment, params: params) }
|
||||
|
||||
context "when comment exists" do
|
||||
let(:comment_id) { comment.id }
|
||||
|
||||
before { comment }
|
||||
|
||||
context "when comment was made by the current user" do
|
||||
let(:comment_user) { user }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "destroys the comment" do
|
||||
expect { subject }.to(change { ModerationComment.count }.by(-1))
|
||||
expect { comment.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when comment was made by someone else" do
|
||||
let(:comment_user) { FactoryBot.create(:user) }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "nopriv",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not destroy the comment" do
|
||||
expect { subject }.not_to(change { ModerationComment.count })
|
||||
expect { comment.reload }.not_to raise_error
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
context "when current user is an administrator" do
|
||||
let(:user_role) { :administrator }
|
||||
|
||||
it "does not destroy the comment" do
|
||||
expect { subject }.not_to(change { ModerationComment.count })
|
||||
expect { comment.reload }.not_to raise_error
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when comment does not exist" do
|
||||
let(:comment_id) { "Rügenwalder" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not destroy any comment" do
|
||||
expect { subject }.not_to(change { ModerationComment.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#ban" do
|
||||
let(:params) do
|
||||
{
|
||||
user: user_param,
|
||||
ban: ban,
|
||||
permaban: permaban,
|
||||
reason: "just a prank, bro",
|
||||
until: wrongly_formatted_date_ugh
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:ban, params: params) }
|
||||
|
||||
context "when user exists" do
|
||||
shared_examples "does not ban administrators" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "nopriv",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
before { target_user.add_role :administrator }
|
||||
|
||||
it "does not ban the target user" do
|
||||
subject
|
||||
expect(target_user).not_to be_banned
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
let(:user_param) { target_user.screen_name }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
before { target_user }
|
||||
|
||||
context "when ban = 0" do
|
||||
let(:ban) { "0" }
|
||||
let(:wrongly_formatted_date_ugh) { nil }
|
||||
|
||||
"01".each_char do |pb|
|
||||
context "when permaban = #{pb}" do
|
||||
let(:permaban) { pb }
|
||||
|
||||
context "when user is already banned" do
|
||||
before { target_user.ban }
|
||||
|
||||
it "unbans the user" do
|
||||
expect { subject }.to(change { target_user.reload.banned? }.from(true).to(false))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when user is not yet banned" do
|
||||
it "does not change the status of the ban" do
|
||||
expect { subject }.not_to(change { target_user.reload.banned? })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when ban = 1" do
|
||||
let(:ban) { "1" }
|
||||
let(:wrongly_formatted_date_ugh) { "4/20/2420 12:00 AM" }
|
||||
|
||||
context "when permaban = 0" do
|
||||
let(:permaban) { "0" }
|
||||
|
||||
it "bans the user until 2420-04-20" do
|
||||
expect { subject }.to(change { target_user.reload.banned? }.from(false).to(true))
|
||||
expect(target_user).not_to be_permanently_banned
|
||||
expect(target_user.ban_reason).to eq("just a prank, bro")
|
||||
expect(target_user.banned_until).to eq(DateTime.strptime(wrongly_formatted_date_ugh, "%m/%d/%Y %I:%M %p"))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
it_behaves_like "does not ban administrators"
|
||||
end
|
||||
|
||||
context "when permaban = 1" do
|
||||
let(:permaban) { "1" }
|
||||
|
||||
it "bans the user for all eternity" do
|
||||
expect { subject }.to(change { target_user.reload.banned? }.from(false).to(true))
|
||||
expect(target_user).to be_permanently_banned
|
||||
expect(target_user.ban_reason).to eq("just a prank, bro")
|
||||
expect(target_user.banned_until).to be_nil
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
|
||||
it_behaves_like "does not ban administrators"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when user does not exist" do
|
||||
let(:user_param) { "fritz-fantom" }
|
||||
let(:ban) { "1" }
|
||||
let(:permaban) { "1" }
|
||||
let(:wrongly_formatted_date_ugh) { "4/20/2420 12:00 AM" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#privilege" do
|
||||
valid_role_pairs = {
|
||||
moderator: :moderator,
|
||||
admin: :administrator
|
||||
}.freeze
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
user: user_param,
|
||||
type: type,
|
||||
status: status
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:privilege, params: params) }
|
||||
|
||||
context "when user exists" do
|
||||
let(:user_param) { target_user.screen_name }
|
||||
before { target_user }
|
||||
|
||||
{
|
||||
nil => "has no extra roles",
|
||||
:moderator => "is a moderator"
|
||||
}.each do |u_role, context_desc|
|
||||
context "when the current user #{context_desc}" do
|
||||
let(:user_role) { u_role }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "nopriv",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
valid_role_pairs.each do |type, role_name|
|
||||
context "when type is #{type}" do
|
||||
let(:type) { type }
|
||||
|
||||
context "when status is true" do
|
||||
let(:status) { "true" }
|
||||
|
||||
it "does not modify the roles on the target user" do
|
||||
expect { subject }.not_to(change { target_user.reload.roles.to_a })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when status is false" do
|
||||
let(:status) { "true" }
|
||||
|
||||
before { target_user.add_role role_name }
|
||||
|
||||
it "does not modify the roles on the target user" do
|
||||
expect { subject }.not_to(change { target_user.reload.roles.to_a })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the current user is an administrator" do
|
||||
let(:user_role) { :administrator }
|
||||
|
||||
valid_role_pairs.each do |type, role_name|
|
||||
context "when type is #{type}" do
|
||||
let(:type) { type }
|
||||
|
||||
context "when status is true" do
|
||||
let(:status) { "true" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"checked" => true
|
||||
}
|
||||
end
|
||||
|
||||
it "adds the #{role_name} role to the target user" do
|
||||
expect { subject }.to(change { target_user.roles.reload.to_a })
|
||||
expect(target_user).to have_role(role_name)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when status is false" do
|
||||
let(:status) { "false" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
"checked" => false
|
||||
}
|
||||
end
|
||||
|
||||
before { target_user.add_role role_name }
|
||||
|
||||
it "removes the #{role_name} role from the target user" do
|
||||
expect { subject }.to(change { target_user.reload.roles.to_a })
|
||||
expect(target_user).not_to have_role(role_name)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when type is some bogus value" do
|
||||
let(:type) { "some bogus value" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
%w[true false].each do |s|
|
||||
context "when status is #{s}" do
|
||||
let(:status) { s }
|
||||
|
||||
it "does not modify the roles on the target user" do
|
||||
expect { subject }.not_to(change { target_user.reload.roles.to_a })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when user does not exist" do
|
||||
let(:user_param) { "fritz-fantom" }
|
||||
let(:type) { "admin" }
|
||||
let(:status) { "true" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,399 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::QuestionController, :ajax_controller, type: :controller do
|
||||
describe "#create" do
|
||||
shared_examples "creates the question" do |check_for_inbox = true|
|
||||
it "creates the question" do
|
||||
expect { subject }.to(change { Question.count }.by(1))
|
||||
expect(Question.last.content).to eq(question_content)
|
||||
expect(Question.last.author_is_anonymous).to be(expected_question_anonymous)
|
||||
expect(Question.last.user).to eq(expected_question_user)
|
||||
end
|
||||
|
||||
if check_for_inbox
|
||||
it "adds the question to the target users' inbox" do
|
||||
expect { subject }.to(change { target_user.inboxes.count }.by(1))
|
||||
expect(target_user.inboxes.last.question.content).to eq(question_content)
|
||||
end
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
shared_examples "does not create the question" do |check_for_inbox = true|
|
||||
it "does not create the question" do
|
||||
expect { subject }.not_to(change { Question.count })
|
||||
end
|
||||
|
||||
if check_for_inbox
|
||||
it "does not add the question to the target users' inbox" do
|
||||
expect { subject }.not_to(change { target_user.inboxes.count })
|
||||
end
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
shared_examples "enqueues a QuestionWorker job" do |expected_rcpt|
|
||||
it "enqueues a QuestionWorker job" do
|
||||
allow(QuestionWorker).to receive(:perform_async)
|
||||
subject
|
||||
expect(QuestionWorker).to have_received(:perform_async).with(expected_rcpt, user.id, Question.last.id)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
shared_examples "does not enqueue a QuestionWorker job" do
|
||||
it "does not enqueue a QuestionWorker job" do
|
||||
allow(QuestionWorker).to receive(:perform_async)
|
||||
subject
|
||||
expect(QuestionWorker).not_to have_received(:perform_async)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
let(:target_user) { FactoryBot.create(:user, privacy_allow_anonymous_questions: user_allows_anonymous_questions) }
|
||||
let(:params) do
|
||||
{
|
||||
question: question_content,
|
||||
anonymousQuestion: anonymous_question,
|
||||
rcpt: rcpt
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:create, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
let(:question_content) { "Was letzte Preis?" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
let(:expected_question_user) { user }
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when rcpt is a valid user" do
|
||||
let(:rcpt) { target_user.id }
|
||||
|
||||
context "when user allows anonymous questions" do
|
||||
let(:user_allows_anonymous_questions) { true }
|
||||
|
||||
context "when anonymousQuestion is true" do
|
||||
let(:anonymous_question) { "true" }
|
||||
let(:expected_question_anonymous) { true }
|
||||
|
||||
include_examples "creates the question"
|
||||
end
|
||||
|
||||
context "when anonymousQuestion is false" do
|
||||
let(:anonymous_question) { "false" }
|
||||
let(:expected_question_anonymous) { false }
|
||||
|
||||
include_examples "creates the question"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user does not allow anonymous questions" do
|
||||
let(:user_allows_anonymous_questions) { false }
|
||||
|
||||
context "when anonymousQuestion is true" do
|
||||
let(:anonymous_question) { "true" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "unknown",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "does not create the question"
|
||||
end
|
||||
|
||||
context "when anonymousQuestion is false" do
|
||||
let(:anonymous_question) { "false" }
|
||||
let(:expected_question_anonymous) { false }
|
||||
|
||||
include_examples "creates the question"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when rcpt is followers" do
|
||||
let(:rcpt) { "followers" }
|
||||
|
||||
context "when anonymousQuestion is true" do
|
||||
let(:anonymous_question) { "true" }
|
||||
let(:expected_question_anonymous) { false }
|
||||
|
||||
include_examples "creates the question", false
|
||||
include_examples "enqueues a QuestionWorker job", "followers"
|
||||
end
|
||||
|
||||
context "when anonymousQuestion is false" do
|
||||
let(:anonymous_question) { "false" }
|
||||
let(:expected_question_anonymous) { false }
|
||||
|
||||
include_examples "creates the question", false
|
||||
include_examples "enqueues a QuestionWorker job", "followers"
|
||||
end
|
||||
end
|
||||
|
||||
context "when rcpt is a group" do
|
||||
let(:rcpt) { "grp:foobar" }
|
||||
|
||||
context "when group exists" do
|
||||
let(:group) { FactoryBot.create(:group, display_name: "FooBar", user: user) }
|
||||
before { group }
|
||||
|
||||
context "when anonymousQuestion is true" do
|
||||
let(:anonymous_question) { "true" }
|
||||
let(:expected_question_anonymous) { false }
|
||||
|
||||
include_examples "creates the question", false
|
||||
include_examples "enqueues a QuestionWorker job", "grp:foobar"
|
||||
end
|
||||
|
||||
context "when anonymousQuestion is false" do
|
||||
let(:anonymous_question) { "false" }
|
||||
let(:expected_question_anonymous) { false }
|
||||
|
||||
include_examples "creates the question", false
|
||||
include_examples "enqueues a QuestionWorker job", "grp:foobar"
|
||||
end
|
||||
end
|
||||
|
||||
context "when group does not exist" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
context "when anonymousQuestion is true" do
|
||||
let(:anonymous_question) { "true" }
|
||||
|
||||
include_examples "does not create the question", false
|
||||
include_examples "does not enqueue a QuestionWorker job"
|
||||
end
|
||||
|
||||
context "when anonymousQuestion is false" do
|
||||
let(:anonymous_question) { "false" }
|
||||
|
||||
include_examples "does not create the question", false
|
||||
include_examples "does not enqueue a QuestionWorker job"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when rcpt is a non-existent user" do
|
||||
let(:rcpt) { "tripmeister_eder" }
|
||||
let(:anonymous_question) { "false" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "does not create the question", false
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:target_user) { FactoryBot.create(:user, privacy_allow_anonymous_questions: user_allows_anonymous_questions) }
|
||||
let(:question_content) { "Was letzte Preis?" }
|
||||
let(:anonymous_question) { "true" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
let(:expected_question_anonymous) { true }
|
||||
let(:expected_question_user) { nil }
|
||||
|
||||
context "when rcpt is a valid user" do
|
||||
let(:rcpt) { target_user.id }
|
||||
|
||||
context "when user allows anonymous questions" do
|
||||
let(:user_allows_anonymous_questions) { true }
|
||||
|
||||
include_examples "creates the question"
|
||||
|
||||
context "when anonymousQuestion is false" do
|
||||
let(:anonymous_question) { "false" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "unknown",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "does not create the question"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user does not allow anonymous questions" do
|
||||
let(:user_allows_anonymous_questions) { false }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "unknown",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "does not create the question"
|
||||
|
||||
context "when anonymousQuestion is false" do
|
||||
let(:anonymous_question) { "false" }
|
||||
|
||||
include_examples "does not create the question"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when rcpt is followers" do
|
||||
let(:rcpt) { "followers" }
|
||||
|
||||
include_examples "does not enqueue a QuestionWorker job"
|
||||
end
|
||||
|
||||
context "when rcpt is a group" do
|
||||
let(:rcpt) { "grp:foobar" }
|
||||
|
||||
include_examples "does not enqueue a QuestionWorker job"
|
||||
end
|
||||
|
||||
context "when rcpt is a non-existent user" do
|
||||
let(:rcpt) { "tripmeister_eder" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "does not create the question", false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
shared_examples "does not delete the question" do |expected_status|
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => expected_status,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not delete the question" do
|
||||
question # ensure we already have it in the db
|
||||
expect { subject }.not_to(change { Question.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
let(:question_user) { user }
|
||||
let(:question) { FactoryBot.create(:question, user: question_user) }
|
||||
let(:question_id) { question.id }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
question: question_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { delete(:destroy, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
shared_examples "deletes the question" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "deletes the question" do
|
||||
question # ensure we already have it in the db
|
||||
expect { subject }.to(change { Question.count }.by(-1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when the question exists and was made by the current user" do
|
||||
include_examples "deletes the question"
|
||||
end
|
||||
|
||||
context "when the question exists and was not made by the current user" do
|
||||
let(:question_user) { FactoryBot.create(:user) }
|
||||
|
||||
include_examples "does not delete the question", "not_authorized"
|
||||
|
||||
%i[moderator administrator].each do |privileged_role|
|
||||
context "when the current user is a #{privileged_role}" do
|
||||
around do |example|
|
||||
user.add_role privileged_role
|
||||
example.run
|
||||
user.remove_role privileged_role
|
||||
end
|
||||
|
||||
include_examples "deletes the question"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the question exists and was not made by any registered user" do
|
||||
let(:question_user) { nil }
|
||||
|
||||
include_examples "does not delete the question", "not_authorized"
|
||||
|
||||
%i[moderator administrator].each do |privileged_role|
|
||||
context "when the current user is a #{privileged_role}" do
|
||||
around do |example|
|
||||
user.add_role privileged_role
|
||||
example.run
|
||||
user.remove_role privileged_role
|
||||
end
|
||||
|
||||
include_examples "deletes the question"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when the question does not exist" do
|
||||
let(:question_id) { "sonic_the_hedgehog" }
|
||||
|
||||
include_examples "does not delete the question", "not_found"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
include_examples "does not delete the question", "err"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,151 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::ReportController, :ajax_controller, type: :controller do
|
||||
describe "#create" do
|
||||
let(:params) do
|
||||
{
|
||||
id: id,
|
||||
type: type,
|
||||
reason: reason
|
||||
}
|
||||
end
|
||||
subject { post(:create, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
shared_examples "reporting an item" do |type|
|
||||
let(:type) { type }
|
||||
let(:id) { object.id }
|
||||
|
||||
context "when #{type} exists" do
|
||||
before { object }
|
||||
|
||||
context "when reason is empty" do
|
||||
let(:reason) { "" }
|
||||
|
||||
it "creates a report of type Reports::#{type.capitalize}" do
|
||||
report_klass = "Reports::#{type.capitalize}".constantize
|
||||
expect { subject }.to(change { report_klass.count }.by(1))
|
||||
expect(report_klass.last.target).to eq(object)
|
||||
expect(report_klass.last.reason).to be_blank
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when reason is not empty" do
|
||||
let(:reason) { "I don't like this" }
|
||||
|
||||
it "creates a report of type Reports::#{type.capitalize}" do
|
||||
report_klass = "Reports::#{type.capitalize}".constantize
|
||||
expect { subject }.to(change { report_klass.count }.by(1))
|
||||
expect(report_klass.last.target).to eq(object)
|
||||
expect(report_klass.last.reason).to eq(reason)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when #{type} does not exist" do
|
||||
let(:id) { "nonexistent" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything,
|
||||
}
|
||||
end
|
||||
|
||||
context "when reason is empty" do
|
||||
let(:reason) { "" }
|
||||
|
||||
it "does not create a report" do
|
||||
expect { subject }.not_to(change { Report.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when reason is not empty" do
|
||||
let(:reason) { "I don't like this" }
|
||||
|
||||
it "does not create a report" do
|
||||
expect { subject }.not_to(change { Report.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:target_user) { FactoryBot.create(:user) }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything,
|
||||
}
|
||||
end
|
||||
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
it_behaves_like "reporting an item", "user" do
|
||||
let(:object) { target_user }
|
||||
let(:id) { object.screen_name }
|
||||
end
|
||||
|
||||
it_behaves_like "reporting an item", "question" do
|
||||
let(:object) { FactoryBot.create(:question, user: target_user) }
|
||||
end
|
||||
|
||||
it_behaves_like "reporting an item", "answer" do
|
||||
let(:object) { FactoryBot.create(:answer, user: target_user) }
|
||||
end
|
||||
|
||||
it_behaves_like "reporting an item", "comment" do
|
||||
let(:answer) { FactoryBot.create(:answer, user: target_user) }
|
||||
let(:object) { FactoryBot.create(:comment, user: target_user, answer: answer) }
|
||||
end
|
||||
|
||||
context "when type is anything else" do
|
||||
let(:id) { "whatever" }
|
||||
let(:type) { "whatever" }
|
||||
let(:reason) { "whatever" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything,
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a report" do
|
||||
expect { subject }.not_to(change { Report.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:id) { "peter_zwegat" }
|
||||
let(:type) { "user" }
|
||||
let(:reason) { "I'm broke now thanks to this bloke" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "err",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a report" do
|
||||
expect { subject }.not_to(change { Report.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,292 @@
|
|||
# coding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::SmileController, :ajax_controller, type: :controller do
|
||||
describe "#create" do
|
||||
let(:params) do
|
||||
{
|
||||
id: answer_id
|
||||
}.compact
|
||||
end
|
||||
let(:answer) { FactoryBot.create(:answer, user: user) }
|
||||
|
||||
subject { post(:create, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when answer exists" do
|
||||
let(:answer_id) { answer.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "creates a smile to the answer" do
|
||||
expect { subject }.to(change { Smile.count }.by(1))
|
||||
expect(answer.reload.smiles.ids).to include(Smile.last.id)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when answer does not exist" do
|
||||
let(:answer_id) { "nein!" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => anything,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a smile" do
|
||||
expect { subject }.not_to(change { Smile.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when some parameters are missing" do
|
||||
let(:answer_id) { nil }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "parameter_error",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:answer_id) { answer.id }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
let(:answer) { FactoryBot.create(:answer, user: user) }
|
||||
let(:smile) { FactoryBot.create(:smile, user: user, answer: answer) }
|
||||
let(:answer_id) { answer.id }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
id: answer_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { delete(:destroy, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when the smile exists" do
|
||||
# ensure we already have it in the db
|
||||
before(:each) { smile }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "deletes the smile" do
|
||||
expect { subject }.to(change { Smile.count }.by(-1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when the smile does not exist" do
|
||||
let(:answer_id) { "sonic_the_hedgehog" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => anything,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create_comment" do
|
||||
let(:params) do
|
||||
{
|
||||
id: comment_id
|
||||
}.compact
|
||||
end
|
||||
let(:answer) { FactoryBot.create(:answer, user: user) }
|
||||
let(:comment) { FactoryBot.create(:comment, user: user, answer: answer) }
|
||||
|
||||
subject { post(:create_comment, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when comment exists" do
|
||||
let(:comment_id) { comment.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "creates a smile to the comment" do
|
||||
expect { subject }.to(change { CommentSmile.count }.by(1))
|
||||
expect(comment.reload.smiles.ids).to include(CommentSmile.last.id)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when comment does not exist" do
|
||||
let(:comment_id) { "nein!" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => anything,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a smile" do
|
||||
expect { subject }.not_to(change { CommentSmile.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when some parameters are missing" do
|
||||
let(:comment_id) { nil }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "parameter_error",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:comment_id) { comment.id }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy_comment" do
|
||||
let(:answer) { FactoryBot.create(:answer, user: user) }
|
||||
let(:comment) { FactoryBot.create(:comment, user: user, answer: answer) }
|
||||
let(:comment_smile) { FactoryBot.create(:comment_smile, user: user, comment: comment) }
|
||||
let(:comment_id) { comment.id }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
id: comment_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { delete(:destroy_comment, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when the smile exists" do
|
||||
# ensure we already have it in the db
|
||||
before(:each) { comment_smile }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => "okay",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "deletes the smile" do
|
||||
expect { subject }.to(change { CommentSmile.count }.by(-1))
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when the smile does not exist" do
|
||||
let(:answer_id) { "sonic_the_hedgehog" }
|
||||
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => anything,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "fail",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,160 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe Ajax::SubscriptionController, :ajax_controller, type: :controller do
|
||||
# need to use a different user here, as after a create the user owning the
|
||||
# answer is automatically subscribed to it
|
||||
let(:answer_user) { FactoryBot.create(:user) }
|
||||
let(:answer) { FactoryBot.create(:answer, user: answer_user) }
|
||||
|
||||
describe "#subscribe" do
|
||||
let(:params) do
|
||||
{
|
||||
answer: answer_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:subscribe, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when answer exists" do
|
||||
let(:answer_id) { answer.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => 418,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
context "when subscription does not exist" do
|
||||
it "creates a subscription on the answer" do
|
||||
expect { subject }.to(change { answer.subscriptions.count }.by(1))
|
||||
expect(answer.subscriptions.where(is_active: true).map { |s| s.user.id }.sort).to eq([answer_user.id, user.id].sort)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when subscription already exists" do
|
||||
before(:each) { Subscription.subscribe(user, answer) }
|
||||
|
||||
it "does not modify the answer's subscriptions" do
|
||||
expect { subject }.to(change { answer.subscriptions.count }.by(0))
|
||||
expect(answer.subscriptions.where(is_active: true).map { |s| s.user.id }.sort).to eq([answer_user.id, user.id].sort)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when answer does not exist" do
|
||||
let(:answer_id) { "Bielefeld" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a new subscription" do
|
||||
expect { subject }.not_to(change { Subscription.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:answer_id) { answer.id }
|
||||
|
||||
it "redirects to somewhere else, apparently" do
|
||||
subject
|
||||
expect(response).to be_a_redirect
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#unsubscribe" do
|
||||
let(:params) do
|
||||
{
|
||||
answer: answer_id
|
||||
}
|
||||
end
|
||||
|
||||
subject { post(:unsubscribe, params: params) }
|
||||
|
||||
context "when user is signed in" do
|
||||
before(:each) { sign_in(user) }
|
||||
|
||||
context "when answer exists" do
|
||||
let(:answer_id) { answer.id }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => true,
|
||||
"status" => 418,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
context "when subscription exists" do
|
||||
before(:each) { Subscription.subscribe(user, answer) }
|
||||
|
||||
it "removes an active subscription from the answer" do
|
||||
expect { subject }.to(change { answer.subscriptions.where(is_active: true).count }.by(-1))
|
||||
expect(answer.subscriptions.where(is_active: true).map { |s| s.user.id }.sort).to eq([answer_user.id].sort)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
|
||||
context "when subscription does not exist" do
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => 418,
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not modify the answer's subscriptions" do
|
||||
expect { subject }.to(change { answer.subscriptions.count }.by(0))
|
||||
expect(answer.subscriptions.where(is_active: true).map { |s| s.user.id }.sort).to eq([answer_user.id].sort)
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when answer does not exist" do
|
||||
let(:answer_id) { "Bielefeld" }
|
||||
let(:expected_response) do
|
||||
{
|
||||
"success" => false,
|
||||
"status" => "not_found",
|
||||
"message" => anything
|
||||
}
|
||||
end
|
||||
|
||||
it "does not create a new subscription" do
|
||||
expect { subject }.not_to(change { Subscription.count })
|
||||
end
|
||||
|
||||
include_examples "returns the expected response"
|
||||
end
|
||||
end
|
||||
|
||||
context "when user is not signed in" do
|
||||
let(:answer_id) { answer.id }
|
||||
|
||||
it "redirects to somewhere else, apparently" do
|
||||
subject
|
||||
expect(response).to be_a_redirect
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :comment do
|
||||
transient do
|
||||
answer_content { Faker::Lorem.sentence }
|
||||
end
|
||||
|
||||
content { Faker::Lorem.sentence }
|
||||
answer { FactoryBot.build(:answer, content: answer_content) }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :comment_smile do
|
||||
user { FactoryBot.build(:user) }
|
||||
comment { FactoryBot.build(:comment) }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :group do
|
||||
sequence(:display_name) { |i| "#{Faker::Internet.username(specifier: 0..12, separators: %w[_])}#{i}" }
|
||||
user { FactoryBot.build(:user) }
|
||||
|
||||
transient do
|
||||
members { [] }
|
||||
end
|
||||
|
||||
after(:create) do |group, evaluator|
|
||||
evaluator.members.each do |member|
|
||||
GroupMember.create(group_id: group.id, user_id: member.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :smile do
|
||||
user { FactoryBot.build(:user) }
|
||||
answer { FactoryBot.build(:answer) }
|
||||
end
|
||||
end
|
|
@ -12,6 +12,7 @@ require "rspec/its"
|
|||
require "devise"
|
||||
require "capybara/rails"
|
||||
require "capybara/rspec"
|
||||
require "rspec-sidekiq"
|
||||
|
||||
# Requires supporting ruby files with custom matchers and macros, etc, in
|
||||
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.shared_context "AjaxController context" do
|
||||
let(:user) { FactoryBot.create(:user) }
|
||||
|
||||
shared_examples "returns the expected response" do
|
||||
it "returns the expected response" do
|
||||
expect(JSON.parse(subject.body)).to match(expected_response)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.include_context "AjaxController context", ajax_controller: true
|
||||
end
|
|
@ -1,6 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "simplecov"
|
||||
# require "simplecov-rcov"
|
||||
# SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
||||
SimpleCov.start "rails"
|
||||
|
||||
if ENV.key?("GITHUB_ACTIONS")
|
||||
require "simplecov-cobertura"
|
||||
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue