621 lines
20 KiB
Ruby
621 lines
20 KiB
Ruby
# frozen_string_literal: true
|
|
require "swagger_helper"
|
|
|
|
RSpec.describe "posts" do
|
|
let(:"Api-Key") { Fabricate(:api_key).key }
|
|
let(:"Api-Username") { "system" }
|
|
let(:admin) { Fabricate(:admin) }
|
|
|
|
before do
|
|
Jobs.run_immediately!
|
|
sign_in(admin)
|
|
end
|
|
|
|
path "/posts.json" do
|
|
get "List latest posts across topics" do
|
|
tags "Posts"
|
|
operationId "listPosts"
|
|
parameter name: "Api-Key", in: :header, type: :string, required: true
|
|
parameter name: "Api-Username", in: :header, type: :string, required: true
|
|
parameter name: "before",
|
|
in: :query,
|
|
type: :string,
|
|
description: "Load posts with an id lower than this value. Useful for pagination.",
|
|
required: false
|
|
produces "application/json"
|
|
|
|
response "200", "latest posts" do
|
|
schema type: :object,
|
|
properties: {
|
|
latest_posts: {
|
|
type: :array,
|
|
items: {
|
|
type: :object,
|
|
properties: {
|
|
id: {
|
|
type: :integer,
|
|
},
|
|
name: {
|
|
type: :string,
|
|
},
|
|
username: {
|
|
type: :string,
|
|
},
|
|
avatar_template: {
|
|
type: :string,
|
|
},
|
|
created_at: {
|
|
type: :string,
|
|
},
|
|
cooked: {
|
|
type: :string,
|
|
},
|
|
post_number: {
|
|
type: :integer,
|
|
},
|
|
post_type: {
|
|
type: :integer,
|
|
},
|
|
updated_at: {
|
|
type: :string,
|
|
},
|
|
reply_count: {
|
|
type: :integer,
|
|
},
|
|
reply_to_post_number: {
|
|
type: %i[string null],
|
|
},
|
|
quote_count: {
|
|
type: :integer,
|
|
},
|
|
incoming_link_count: {
|
|
type: :integer,
|
|
},
|
|
reads: {
|
|
type: :integer,
|
|
},
|
|
readers_count: {
|
|
type: :integer,
|
|
},
|
|
score: {
|
|
type: :number,
|
|
},
|
|
yours: {
|
|
type: :boolean,
|
|
},
|
|
topic_id: {
|
|
type: :integer,
|
|
},
|
|
topic_slug: {
|
|
type: :string,
|
|
},
|
|
topic_title: {
|
|
type: :string,
|
|
},
|
|
topic_html_title: {
|
|
type: :string,
|
|
},
|
|
category_id: {
|
|
type: :integer,
|
|
},
|
|
display_username: {
|
|
type: :string,
|
|
},
|
|
primary_group_name: {
|
|
type: %i[string null],
|
|
},
|
|
flair_name: {
|
|
type: %i[string null],
|
|
},
|
|
flair_url: {
|
|
type: %i[string null],
|
|
},
|
|
flair_bg_color: {
|
|
type: %i[string null],
|
|
},
|
|
flair_color: {
|
|
type: %i[string null],
|
|
},
|
|
flair_group_id: {
|
|
type: %i[integer null],
|
|
},
|
|
version: {
|
|
type: :integer,
|
|
},
|
|
can_edit: {
|
|
type: :boolean,
|
|
},
|
|
can_delete: {
|
|
type: :boolean,
|
|
},
|
|
can_recover: {
|
|
type: :boolean,
|
|
},
|
|
can_see_hidden_post: {
|
|
type: :boolean,
|
|
},
|
|
can_wiki: {
|
|
type: :boolean,
|
|
},
|
|
user_title: {
|
|
type: %i[string null],
|
|
},
|
|
raw: {
|
|
type: :string,
|
|
},
|
|
actions_summary: {
|
|
type: :array,
|
|
items: {
|
|
type: :object,
|
|
properties: {
|
|
id: {
|
|
type: :integer,
|
|
},
|
|
can_act: {
|
|
type: :boolean,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
moderator: {
|
|
type: :boolean,
|
|
},
|
|
admin: {
|
|
type: :boolean,
|
|
},
|
|
staff: {
|
|
type: :boolean,
|
|
},
|
|
user_id: {
|
|
type: :integer,
|
|
},
|
|
hidden: {
|
|
type: :boolean,
|
|
},
|
|
trust_level: {
|
|
type: :integer,
|
|
},
|
|
deleted_at: {
|
|
type: %i[string null],
|
|
},
|
|
user_deleted: {
|
|
type: :boolean,
|
|
},
|
|
edit_reason: {
|
|
type: %i[string null],
|
|
},
|
|
can_view_edit_history: {
|
|
type: :boolean,
|
|
},
|
|
wiki: {
|
|
type: :boolean,
|
|
},
|
|
reviewable_id: {
|
|
type: %i[integer null],
|
|
},
|
|
reviewable_score_count: {
|
|
type: :integer,
|
|
},
|
|
reviewable_score_pending_count: {
|
|
type: :integer,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
let!(:post) { Fabricate(:post) }
|
|
run_test!
|
|
end
|
|
end
|
|
|
|
post "Creates a new topic, a new post, or a private message" do
|
|
tags "Posts", "Topics", "Private Messages"
|
|
operationId "createTopicPostPM"
|
|
consumes "application/json"
|
|
expected_request_schema = load_spec_schema("topic_create_request")
|
|
parameter name: :params, in: :body, schema: expected_request_schema
|
|
|
|
produces "application/json"
|
|
response "200", "post created" do
|
|
expected_response_schema = load_spec_schema("topic_create_response")
|
|
schema expected_response_schema
|
|
|
|
let(:params) do
|
|
post = Fabricate(:post)
|
|
post.serializable_hash(only: %i[topic_id raw created_at]).as_json
|
|
end
|
|
|
|
it_behaves_like "a JSON endpoint", 200 do
|
|
let(:expected_response_schema) { expected_response_schema }
|
|
let(:expected_request_schema) { expected_request_schema }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
path "/posts/{id}.json" do
|
|
get "Retrieve a single post" do
|
|
tags "Posts"
|
|
operationId "getPost"
|
|
consumes "application/json"
|
|
description <<~TEXT
|
|
This endpoint can be used to get the number of likes on a post using the
|
|
`actions_summary` property in the response. `actions_summary` responses
|
|
with the id of `2` signify a `like`. If there are no `actions_summary`
|
|
items with the id of `2`, that means there are 0 likes. Other ids likely
|
|
refer to various different flag types.
|
|
TEXT
|
|
|
|
expected_request_schema = nil
|
|
parameter name: :id, in: :path, schema: { type: :string }
|
|
|
|
produces "application/json"
|
|
|
|
response "200", "single post" do
|
|
expected_response_schema = load_spec_schema("post_show_response")
|
|
schema expected_response_schema
|
|
|
|
let(:id) { Fabricate(:post).id }
|
|
run_test!
|
|
|
|
it_behaves_like "a JSON endpoint", 200 do
|
|
let(:expected_response_schema) { expected_response_schema }
|
|
let(:expected_request_schema) { expected_request_schema }
|
|
end
|
|
end
|
|
|
|
response "200", "single reviewable post" do
|
|
expected_response_schema = load_spec_schema("post_show_response")
|
|
schema expected_response_schema
|
|
|
|
let(:id) do
|
|
topic = Fabricate(:topic)
|
|
post = Fabricate(:post, topic: topic)
|
|
Fabricate(:reviewable_flagged_post, topic: topic, target: post)
|
|
|
|
post.id
|
|
end
|
|
|
|
let(:moderator) { Fabricate(:moderator) }
|
|
before { sign_in(moderator) }
|
|
|
|
run_test!
|
|
|
|
it_behaves_like "a JSON endpoint", 200 do
|
|
let(:expected_response_schema) { expected_response_schema }
|
|
let(:expected_request_schema) { expected_request_schema }
|
|
end
|
|
end
|
|
end
|
|
|
|
put "Update a single post" do
|
|
tags "Posts"
|
|
operationId "updatePost"
|
|
consumes "application/json"
|
|
expected_request_schema = load_spec_schema("post_update_request")
|
|
parameter name: :id, in: :path, schema: { type: :string }
|
|
parameter name: :params, in: :body, schema: expected_request_schema
|
|
|
|
produces "application/json"
|
|
response "200", "post updated" do
|
|
expected_response_schema = load_spec_schema("post_update_response")
|
|
schema expected_response_schema
|
|
|
|
let(:params) do
|
|
{ "post" => { "raw" => "Updated content!", "edit_reason" => "fixed typo" } }
|
|
end
|
|
let(:id) { Fabricate(:post).id }
|
|
|
|
run_test! do |response|
|
|
data = JSON.parse(response.body)
|
|
expect(data["post"]["cooked"]).to eq("<p>Updated content!</p>")
|
|
expect(data["post"]["edit_reason"]).to eq("fixed typo")
|
|
end
|
|
|
|
it_behaves_like "a JSON endpoint", 200 do
|
|
let(:expected_response_schema) { expected_response_schema }
|
|
let(:expected_request_schema) { expected_request_schema }
|
|
end
|
|
end
|
|
end
|
|
|
|
delete "delete a single post" do
|
|
tags "Posts"
|
|
operationId "deletePost"
|
|
consumes "application/json"
|
|
expected_request_schema = load_spec_schema("post_delete_request")
|
|
parameter name: :id, in: :path, schema: { type: :integer }
|
|
parameter name: :params, in: :body, schema: expected_request_schema
|
|
|
|
produces "application/json"
|
|
response "200", "success response" do
|
|
expected_response_schema = nil
|
|
schema expected_response_schema
|
|
|
|
let(:topic) { Fabricate(:topic) }
|
|
let(:post) { Fabricate(:post, topic_id: topic.id, post_number: 3) }
|
|
let(:id) { post.id }
|
|
let(:params) { { "force_destroy" => false } }
|
|
|
|
it_behaves_like "a JSON endpoint", 200 do
|
|
let(:expected_response_schema) { expected_response_schema }
|
|
let(:expected_request_schema) { expected_request_schema }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
path "/posts/{id}/replies.json" do
|
|
get "List replies to a post" do
|
|
tags "Posts"
|
|
operationId "postReplies"
|
|
consumes "application/json"
|
|
expected_request_schema = nil
|
|
parameter name: :id, in: :path, schema: { type: :string }
|
|
|
|
produces "application/json"
|
|
response "200", "post replies" do
|
|
expected_response_schema = load_spec_schema("post_replies_response")
|
|
schema expected_response_schema
|
|
|
|
fab!(:user)
|
|
fab!(:topic)
|
|
fab!(:post) { Fabricate(:post, topic: topic, user: user) }
|
|
let!(:reply) do
|
|
PostCreator.new(
|
|
user,
|
|
raw: "this is some text for my post",
|
|
topic_id: topic.id,
|
|
reply_to_post_number: post.post_number,
|
|
).create
|
|
end
|
|
let!(:id) { post.id }
|
|
|
|
it_behaves_like "a JSON endpoint", 200 do
|
|
let(:expected_response_schema) { expected_response_schema }
|
|
let(:expected_request_schema) { expected_request_schema }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
path "/posts/{id}/locked.json" do
|
|
put "Lock a post from being edited" do
|
|
tags "Posts"
|
|
operationId "lockPost"
|
|
consumes "application/json"
|
|
parameter name: "Api-Key", in: :header, type: :string, required: true
|
|
parameter name: "Api-Username", in: :header, type: :string, required: true
|
|
parameter name: :id, in: :path, schema: { type: :string }
|
|
|
|
parameter name: :post_body,
|
|
in: :body,
|
|
schema: {
|
|
type: :object,
|
|
properties: {
|
|
locked: {
|
|
type: :string,
|
|
},
|
|
},
|
|
required: ["locked"],
|
|
}
|
|
|
|
produces "application/json"
|
|
response "200", "post updated" do
|
|
schema type: :object, properties: { locked: { type: :boolean } }
|
|
|
|
let(:post_body) { { locked: "true" } }
|
|
let(:id) { Fabricate(:post).id }
|
|
|
|
run_test! do |response|
|
|
data = JSON.parse(response.body)
|
|
expect(data["locked"]).to eq(true)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
path "/post_actions.json" do
|
|
post "Like a post and other actions" do
|
|
tags "Posts"
|
|
operationId "performPostAction"
|
|
consumes "application/json"
|
|
parameter name: "Api-Key", in: :header, type: :string, required: true
|
|
parameter name: "Api-Username", in: :header, type: :string, required: true
|
|
|
|
parameter name: :post_body,
|
|
in: :body,
|
|
schema: {
|
|
type: :object,
|
|
properties: {
|
|
id: {
|
|
type: :integer,
|
|
},
|
|
post_action_type_id: {
|
|
type: :integer,
|
|
},
|
|
flag_topic: {
|
|
type: :boolean,
|
|
},
|
|
},
|
|
required: %w[id post_action_type_id],
|
|
}
|
|
|
|
produces "application/json"
|
|
response "200", "post updated" do
|
|
schema type: :object,
|
|
properties: {
|
|
id: {
|
|
type: :integer,
|
|
},
|
|
name: {
|
|
type: :string,
|
|
},
|
|
username: {
|
|
type: :string,
|
|
},
|
|
avatar_template: {
|
|
type: :string,
|
|
},
|
|
created_at: {
|
|
type: :string,
|
|
},
|
|
cooked: {
|
|
type: :string,
|
|
},
|
|
post_number: {
|
|
type: :integer,
|
|
},
|
|
post_type: {
|
|
type: :integer,
|
|
},
|
|
updated_at: {
|
|
type: :string,
|
|
},
|
|
reply_count: {
|
|
type: :integer,
|
|
},
|
|
reply_to_post_number: {
|
|
type: %i[string null],
|
|
},
|
|
quote_count: {
|
|
type: :integer,
|
|
},
|
|
incoming_link_count: {
|
|
type: :integer,
|
|
},
|
|
reads: {
|
|
type: :integer,
|
|
},
|
|
readers_count: {
|
|
type: :integer,
|
|
},
|
|
score: {
|
|
type: :number,
|
|
},
|
|
yours: {
|
|
type: :boolean,
|
|
},
|
|
topic_id: {
|
|
type: :integer,
|
|
},
|
|
topic_slug: {
|
|
type: :string,
|
|
},
|
|
display_username: {
|
|
type: :string,
|
|
},
|
|
primary_group_name: {
|
|
type: %i[string null],
|
|
},
|
|
flair_name: {
|
|
type: %i[string null],
|
|
},
|
|
flair_url: {
|
|
type: %i[string null],
|
|
},
|
|
flair_bg_color: {
|
|
type: %i[string null],
|
|
},
|
|
flair_color: {
|
|
type: %i[string null],
|
|
},
|
|
version: {
|
|
type: :integer,
|
|
},
|
|
can_edit: {
|
|
type: :boolean,
|
|
},
|
|
can_delete: {
|
|
type: :boolean,
|
|
},
|
|
can_recover: {
|
|
type: :boolean,
|
|
},
|
|
can_wiki: {
|
|
type: :boolean,
|
|
},
|
|
user_title: {
|
|
type: %i[string null],
|
|
},
|
|
actions_summary: {
|
|
type: :array,
|
|
items: {
|
|
type: :object,
|
|
properties: {
|
|
id: {
|
|
type: :integer,
|
|
},
|
|
count: {
|
|
type: :integer,
|
|
},
|
|
acted: {
|
|
type: :boolean,
|
|
},
|
|
can_undo: {
|
|
type: :boolean,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
moderator: {
|
|
type: :boolean,
|
|
},
|
|
admin: {
|
|
type: :boolean,
|
|
},
|
|
staff: {
|
|
type: :boolean,
|
|
},
|
|
user_id: {
|
|
type: :integer,
|
|
},
|
|
hidden: {
|
|
type: :boolean,
|
|
},
|
|
trust_level: {
|
|
type: :integer,
|
|
},
|
|
deleted_at: {
|
|
type: %i[string null],
|
|
},
|
|
user_deleted: {
|
|
type: :boolean,
|
|
},
|
|
edit_reason: {
|
|
type: %i[string null],
|
|
},
|
|
can_view_edit_history: {
|
|
type: :boolean,
|
|
},
|
|
wiki: {
|
|
type: :boolean,
|
|
},
|
|
notice: {
|
|
type: :object,
|
|
},
|
|
reviewable_id: {
|
|
type: %i[integer null],
|
|
},
|
|
reviewable_score_count: {
|
|
type: :integer,
|
|
},
|
|
reviewable_score_pending_count: {
|
|
type: :integer,
|
|
},
|
|
}
|
|
|
|
let(:id) { Fabricate(:post).id }
|
|
let(:post_body) { { id: id, post_action_type_id: 2 } }
|
|
|
|
run_test! do |response|
|
|
data = JSON.parse(response.body)
|
|
expect(data["actions_summary"][0]["id"]).to eq(2)
|
|
expect(data["actions_summary"][0]["count"]).to eq(1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|