450 lines
13 KiB
Ruby
450 lines
13 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "spec_helper"
|
|
|
|
describe Api::V1::CommentsController do
|
|
let(:auth) {
|
|
FactoryGirl.create(
|
|
:auth_with_default_scopes,
|
|
scopes: %w[openid public:read public:modify private:read interactions]
|
|
)
|
|
}
|
|
|
|
let(:auth_public_only) {
|
|
FactoryGirl.create(
|
|
:auth_with_default_scopes,
|
|
scopes: %w[openid public:read public:modify interactions]
|
|
)
|
|
}
|
|
|
|
let(:auth_minimum_scopes) {
|
|
FactoryGirl.create(:auth_with_default_scopes)
|
|
}
|
|
|
|
let!(:access_token) { auth.create_access_token.to_s }
|
|
let!(:access_token_public_only) { auth_public_only.create_access_token.to_s }
|
|
let!(:access_token_minimum_scopes) { auth_minimum_scopes.create_access_token.to_s }
|
|
let(:invalid_token) { SecureRandom.hex(9) }
|
|
|
|
before do
|
|
@status = alice.post(
|
|
"Post",
|
|
status_message: {text: "This is a status message"},
|
|
public: true,
|
|
to: "all",
|
|
type: "Post"
|
|
)
|
|
|
|
@eves_post = eve.post(
|
|
"Post",
|
|
status_message: {text: "This is a status message"},
|
|
public: true,
|
|
to: "all",
|
|
type: "Post"
|
|
)
|
|
|
|
@comment_on_eves_post = comment_service.create(@eves_post.guid, "Comment on eve's post")
|
|
|
|
aspect = auth_public_only.user.aspects.create(name: "first aspect")
|
|
@private_post = auth_public_only.user.post(
|
|
"Post",
|
|
status_message: {text: "This is a private status message"},
|
|
public: false,
|
|
to: [aspect.id],
|
|
type: "Post"
|
|
)
|
|
@comment_on_private_post = comment_service(auth_public_only.user).create(@private_post.guid, "Private comment")
|
|
end
|
|
|
|
describe "#create" do
|
|
context "valid post ID" do
|
|
it "succeeds in adding a comment" do
|
|
comment_text = "This is a comment"
|
|
post(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {body: comment_text, access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(201)
|
|
comment = response_body(response)
|
|
confirm_comment_format(comment, auth.user, comment_text)
|
|
end
|
|
end
|
|
|
|
context "wrong post id" do
|
|
it "fails at adding a comment" do
|
|
post(
|
|
api_v1_post_comments_path(post_id: "999_999_999"),
|
|
params: {body: "text", access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
end
|
|
|
|
context "lack of permissions" do
|
|
it "fails at adding a comment" do
|
|
alice.blocks.create(person: auth.user.person)
|
|
post(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {body: "That shouldn't be there because I am ignored by this user", access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(422)
|
|
end
|
|
end
|
|
|
|
context "with improper credentials" do
|
|
it "fails on private post without private:read" do
|
|
post(
|
|
api_v1_post_comments_path(post_id: @private_post.guid),
|
|
params: {body: "comment text", access_token: access_token_public_only}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
|
|
it "fails without interactions scope" do
|
|
post(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {body: "comment text", access_token: access_token_minimum_scopes}
|
|
)
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "fails without valid token" do
|
|
post(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {body: "comment text", access_token: invalid_token}
|
|
)
|
|
expect(response.status).to eq(401)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#read" do
|
|
before do
|
|
@comment_text1 = "This is a comment"
|
|
@comment_text2 = "This is a comment 2"
|
|
comment_service.create(@status.guid, @comment_text1)
|
|
comment_service.create(@status.guid, @comment_text2)
|
|
end
|
|
|
|
context "valid post ID" do
|
|
it "retrieves related comments" do
|
|
get(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {access_token: access_token_minimum_scopes}
|
|
)
|
|
expect(response.status).to eq(200)
|
|
comments = response_body_data(response)
|
|
expect(comments.length).to eq(2)
|
|
confirm_comment_format(comments[0], auth.user, @comment_text1)
|
|
confirm_comment_format(comments[1], auth.user, @comment_text2)
|
|
end
|
|
end
|
|
|
|
context "wrong post id" do
|
|
it "fails at retrieving comments" do
|
|
get(
|
|
api_v1_post_comments_path(post_id: "999_999_999"),
|
|
params: {access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
end
|
|
|
|
context "improper credentials" do
|
|
it "fails on private post without private:read" do
|
|
get(
|
|
api_v1_post_comments_path(post_id: @private_post.guid),
|
|
params: {access_token: access_token_public_only}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
|
|
it "fails without valid token" do
|
|
get(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {access_token: invalid_token}
|
|
)
|
|
expect(response.status).to eq(401)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#delete" do
|
|
before do
|
|
comment = comment_service.create(@status.guid, "This is a comment")
|
|
@comment_guid = comment.guid
|
|
end
|
|
|
|
context "valid comment ID" do
|
|
it "succeeds in deleting comment" do
|
|
delete(
|
|
api_v1_post_comment_path(
|
|
post_id: @status.guid,
|
|
id: @comment_guid
|
|
),
|
|
params: {access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(204)
|
|
expect { comment_service.find!(@comment_guid) }.to(
|
|
raise_error(ActiveRecord::RecordNotFound)
|
|
)
|
|
end
|
|
end
|
|
|
|
context "invalid Post ID" do
|
|
it "fails at deleting comment" do
|
|
delete(
|
|
api_v1_post_comment_path(
|
|
post_id: "999_999_999",
|
|
id: @comment_guid
|
|
),
|
|
params: {access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
end
|
|
|
|
context "invalid comment ID" do
|
|
it "fails at deleting comment" do
|
|
delete(
|
|
api_v1_post_comment_path(
|
|
post_id: @status.guid,
|
|
id: "1_234_567"
|
|
),
|
|
params: {access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
end
|
|
end
|
|
|
|
context "mismatched post-to-comment ID" do
|
|
it "fails at deleting comment" do
|
|
delete(
|
|
api_v1_post_comment_path(
|
|
post_id: @status.guid,
|
|
id: @comment_on_eves_post.guid
|
|
),
|
|
params: {access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.comments.not_found"))
|
|
end
|
|
end
|
|
|
|
context "insufficient permissions" do
|
|
it "fails at deleting other user's comment on other user's post" do
|
|
alices_comment = comment_service(alice).create(@status.guid, "Alice's comment")
|
|
delete(
|
|
api_v1_post_comment_path(
|
|
post_id: @status.guid,
|
|
id: alices_comment.guid
|
|
),
|
|
params: {access_token: access_token}
|
|
)
|
|
expect(response.status).to eq(403)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.comments.no_delete"))
|
|
end
|
|
end
|
|
|
|
context "improper credentials" do
|
|
it "fails at deleting your comment on post without private:read token" do
|
|
delete(
|
|
api_v1_post_comment_path(
|
|
post_id: @private_post.guid,
|
|
id: @comment_on_private_post.guid
|
|
),
|
|
params: {access_token: access_token_public_only}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
end
|
|
|
|
it "fails without valid token" do
|
|
get(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {access_token: invalid_token}
|
|
)
|
|
expect(response.status).to eq(401)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#report" do
|
|
before do
|
|
comment = comment_service.create(@status.guid, "This is a comment")
|
|
@comment_guid = comment.guid
|
|
end
|
|
|
|
context "valid comment ID" do
|
|
it "succeeds in reporting comment" do
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: @status.guid,
|
|
comment_id: @comment_guid
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token
|
|
}
|
|
)
|
|
expect(response.status).to eq(204)
|
|
report = Report.first
|
|
expect(report.item_type).to eq("Comment")
|
|
expect(report.text).to eq("bad comment")
|
|
end
|
|
end
|
|
|
|
context "invalid comment ID" do
|
|
it "fails at reporting comment" do
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: @status.guid,
|
|
comment_id: "1_234_567"
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token
|
|
}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.comments.not_found"))
|
|
end
|
|
end
|
|
|
|
context "invalid Post ID" do
|
|
it "fails at reporting comment" do
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: "999_999_999",
|
|
comment_id: @comment_guid
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token
|
|
}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
end
|
|
|
|
context "invalid Post ID" do
|
|
it "fails at reporting comment" do
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: "999_999_999",
|
|
comment_id: @comment_guid
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token
|
|
}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
end
|
|
|
|
context "mismatched post-to-comment ID" do
|
|
it "fails at reporting comment" do
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: @status.guid,
|
|
comment_id: @comment_on_eves_post.guid
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token
|
|
}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.comments.not_found"))
|
|
end
|
|
end
|
|
|
|
context "already reported" do
|
|
it "fails at reporting comment" do
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: @status.guid,
|
|
comment_id: @comment_guid
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token
|
|
}
|
|
)
|
|
expect(response.status).to eq(204)
|
|
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: @status.guid,
|
|
comment_id: @comment_guid
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token
|
|
}
|
|
)
|
|
expect(response.status).to eq(409)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.comments.duplicate_report"))
|
|
end
|
|
end
|
|
|
|
context "improper credentials" do
|
|
it "fails on private post without private:read" do
|
|
post(
|
|
api_v1_post_comment_report_path(
|
|
post_id: @private_post.guid,
|
|
comment_id: @comment_on_private_post.guid
|
|
),
|
|
params: {
|
|
reason: "bad comment",
|
|
access_token: access_token_public_only
|
|
}
|
|
)
|
|
expect(response.status).to eq(404)
|
|
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
|
end
|
|
|
|
it "fails without valid token" do
|
|
get(
|
|
api_v1_post_comments_path(post_id: @status.guid),
|
|
params: {access_token: invalid_token}
|
|
)
|
|
expect(response.status).to eq(401)
|
|
end
|
|
end
|
|
end
|
|
|
|
def comment_service(user=auth.user)
|
|
CommentService.new(user)
|
|
end
|
|
|
|
def response_body(response)
|
|
JSON.parse(response.body)
|
|
end
|
|
|
|
def response_body_data(response)
|
|
JSON.parse(response.body)["data"]
|
|
end
|
|
|
|
private
|
|
|
|
# rubocop:disable Metrics/AbcSize
|
|
def confirm_comment_format(comment, user, comment_text)
|
|
expect(comment.has_key?("guid")).to be_truthy
|
|
expect(comment.has_key?("created_at")).to be_truthy
|
|
expect(comment["body"]).to eq(comment_text)
|
|
author = comment["author"]
|
|
expect(author["guid"]).to eq(user.guid)
|
|
expect(author["diaspora_id"]).to eq(user.diaspora_handle)
|
|
expect(author["name"]).to eq(user.name)
|
|
expect(author["avatar"]).to eq(user.profile.image_url)
|
|
end
|
|
# rubocop:enable Metrics/AbcSize
|
|
end
|