DEV: api documentation updates (#9612)

* DEV: api documentation updates

- Created a script to convert json responses to rswag
- Documented several api endpoints
- Switched rswag to use header based auth

* Update script, fix some schema missmatches
This commit is contained in:
Blake Erickson 2020-05-11 13:06:49 -06:00 committed by GitHub
parent af6e61defd
commit ab919332dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1072 additions and 7 deletions

101
script/json_to_rswag.rb Normal file
View File

@ -0,0 +1,101 @@
# frozen_string_literal: true
require 'json'
# This script is used for development to help document rswag api responses. It
# takes a json response string as an input and converts it to ruby in the format
# that rswag wants so that you can copy+paste it into the appropriate spec rather
# than typing it by hand.
#
# example:
#
# ruby script/json_to_rswag.rb '{"success":true,"active":true,"message":"Your account is activated and ready to use.","user_id":18}'
#
# will output:
#
# schema type: :object, properties: {
# success: { type: :boolean },
# active: { type: :boolean },
# message: { type: :string },
# user_id: { type: :integer },
# }
class JsonToRswag
def initialize
@output = Array.new
@output.push("schema type: :object, properties: {")
end
def get_type(k, v)
type = ""
type = "integer" if v.is_a? Integer
type = "number" if v.is_a? Float
type = "object" if v.is_a? Hash
type = "array" if v.is_a? Array
type = "boolean" if v == true || v == false
type = "null" if v == nil
type = "string" if v.is_a? String
if type == ""
puts "Cannot determine type for:"
puts v
exit 1
end
type
end
def run(h, indent)
h.each do |k, v|
type = get_type(k, v)
if type == "object"
@output << "#{' ' * indent}#{k}: {"
@output << "#{' ' * (indent + 2)}type: :object,"
@output << "#{' ' * (indent + 2)}properties: {"
run(v, indent + 4)
@output << "#{' ' * indent}},"
end
if type == "array"
@output << "#{' ' * indent}#{k}: {"
@output << "#{' ' * (indent + 2)}type: :array,"
@output << "#{' ' * (indent + 2)}items: {"
a = v.first
if a.is_a? Hash
@output << "#{' ' * (indent + 4)}type: :object,"
@output << "#{' ' * (indent + 4)}properties: {"
run(a , indent + 6)
@output << "#{' ' * (indent + 2)}},"
else
@output << "#{' ' * (indent + 2)}},"
end
@output << "#{' ' * indent}},"
end
if type == "null"
@output << "#{' ' * indent}#{k}: { type: :string, nullable: true },"
elsif type != "object" && type != "array"
@output << "#{' ' * indent}#{k}: { type: :#{type} },"
end
end
@output << "#{' ' * (indent - 2)}}"
end
def print
puts @output
end
end
input = ARGV[0]
if input == nil || input == ""
puts "Please pass in a json string."
exit 1
end
json = JSON.parse(input)
json_to_rswag = JsonToRswag.new
json_to_rswag.run(json, 2)
json_to_rswag.print

View File

@ -4,6 +4,7 @@ require 'swagger_helper'
describe 'categories' do
let(:admin) { Fabricate(:admin) }
let!(:category) { Fabricate(:category, user: admin) }
before do
Jobs.run_immediately!
@ -13,11 +14,7 @@ describe 'categories' do
path '/categories.json' do
post 'Creates a category' do
before do
Jobs.run_immediately!
sign_in(admin)
end
tags 'Category'
tags 'Categories'
consumes 'application/json'
parameter name: :category, in: :body, schema: {
type: :object,
@ -38,6 +35,46 @@ describe 'categories' do
id: { type: :integer },
name: { type: :string },
color: { type: :string },
text_color: { type: :string },
slug: { type: :string },
topic_count: { type: :integer },
post_count: { type: :integer },
position: { type: :integer },
description: { type: :string, nullable: true },
description_text: { type: :string, nullable: true },
topic_url: { type: :string },
read_restricted: { type: :boolean },
permission: { type: :integer, nullable: true },
notification_level: { type: :integer, nullable: true },
can_edit: { type: :boolean },
topic_template: { type: :string, nullable: true },
has_children: { type: :boolean, nullable: true },
sort_order: { type: :string, nullable: true },
show_subcategory_list: { type: :boolean },
num_featured_topics: { type: :integer },
default_view: { type: :string, nullable: true },
subcategory_list_style: { type: :string },
default_topic_period: { type: :string },
minimum_required_tags: { type: :integer },
navigate_to_first_post_after_read: { type: :boolean },
custom_fields: { type: :object },
min_tags_from_required_group: { type: :integer },
required_tag_group_name: { type: :string, nullable: true },
available_groups: { type: :array },
auto_close_hours: { type: :integer, nullable: true },
auto_close_based_on_last_post: { type: :boolean },
group_permissions: { type: :array },
email_in: { type: :boolean, nullable: true },
email_in_allow_strangers: { type: :boolean },
mailinglist_mirror: { type: :boolean },
all_topics_wiki: { type: :boolean },
can_delete: { type: :boolean },
cannot_delete_reason: { type: :string, nullable: true },
allow_badges: { type: :boolean },
topic_featured_link_allowed: { type: :boolean },
search_priority: { type: :integer },
uploaded_logo: { type: :string, nullable: true },
uploaded_background: { type: :string, nullable: true },
},
required: ["id"]
}
@ -49,7 +86,7 @@ describe 'categories' do
end
get 'Retreives a list of categories' do
tags 'Category'
tags 'Categories'
produces 'application/json'
response '200', 'categories response' do
@ -62,7 +99,46 @@ describe 'categories' do
draft: { type: :string, nullable: true },
draft_key: { type: :string },
draft_sequence: { type: :integer },
categories: { type: :array },
categories: {
type: :array,
items: {
type: :object,
properties: {
id: { type: :integer },
name: { type: :string },
color: { type: :string },
text_color: { type: :string },
slug: { type: :string },
topic_count: { type: :integer },
post_count: { type: :integer },
position: { type: :integer },
description: { type: :string, nullable: true },
description_text: { type: :string, nullable: true },
topic_url: { type: :string, nullable: true },
read_restricted: { type: :boolean },
permission: { type: :integer, nullable: true },
notification_level: { type: :integer, nullable: true },
can_edit: { type: :boolean },
topic_template: { type: :string, nullable: true },
has_children: { type: :boolean, nullable: true },
sort_order: { type: :string, nullable: true },
show_subcategory_list: { type: :boolean },
num_featured_topics: { type: :integer },
default_view: { type: :string, nullable: true },
subcategory_list_style: { type: :string },
default_topic_period: { type: :string },
minimum_required_tags: { type: :integer },
navigate_to_first_post_after_read: { type: :boolean },
topics_day: { type: :integer },
topics_week: { type: :integer },
topics_month: { type: :integer },
topics_year: { type: :integer },
topics_all_time: { type: :integer },
uploaded_logo: { type: :string, nullable: true },
uploaded_background: { type: :string, nullable: true },
}
}
},
}, required: ["categories"]
}
}, required: ["category_list"]
@ -70,4 +146,274 @@ describe 'categories' do
end
end
end
path '/categories/{category_id}.json' do
put 'Updates a category' do
tags 'Categories'
consumes 'application/json'
parameter name: :category_id, in: :path, schema: { type: :string }
parameter name: :category, in: :body, schema: {
type: :object,
properties: {
name: { type: :string },
color: { type: :string },
text_color: { type: :string },
},
required: [ 'name', 'color', 'text_color' ]
}
produces 'application/json'
response '200', 'category created' do
schema type: :object, properties: {
success: { type: :string },
category: {
type: :object,
properties: {
id: { type: :integer },
name: { type: :string },
color: { type: :string },
text_color: { type: :string },
slug: { type: :string },
topic_count: { type: :integer },
post_count: { type: :integer },
position: { type: :integer },
description: { type: :string, nullable: true },
description_text: { type: :string, nullable: true },
description_excerpt: { type: :string, nullable: true },
topic_url: { type: :string, nullable: true },
read_restricted: { type: :boolean },
permission: { type: :string, nullable: true },
notification_level: { type: :integer, nullable: true },
can_edit: { type: :boolean },
topic_template: { type: :string, nullable: true },
has_children: { type: :string, nullable: true },
sort_order: { type: :string, nullable: true },
sort_ascending: { type: :string, nullable: true },
show_subcategory_list: { type: :boolean },
num_featured_topics: { type: :integer },
default_view: { type: :string, nullable: true },
subcategory_list_style: { type: :string },
default_top_period: { type: :string },
minimum_required_tags: { type: :integer },
navigate_to_first_post_after_read: { type: :boolean },
custom_fields: {
type: :object,
properties: {
}
},
min_tags_from_required_group: { type: :integer },
required_tag_group_name: { type: :string, nullable: true },
available_groups: {
type: :array,
items: {
},
},
auto_close_hours: { type: :string, nullable: true },
auto_close_based_on_last_post: { type: :boolean },
group_permissions: {
type: :array,
items: {
type: :object,
properties: {
permission_type: { type: :integer },
group_name: { type: :string },
}
},
},
email_in: { type: :string, nullable: true },
email_in_allow_strangers: { type: :boolean },
mailinglist_mirror: { type: :boolean },
all_topics_wiki: { type: :boolean },
can_delete: { type: :boolean },
cannot_delete_reason: { type: :string, nullable: true },
allow_badges: { type: :boolean },
topic_featured_link_allowed: { type: :boolean },
search_priority: { type: :integer },
uploaded_logo: { type: :string, nullable: true },
uploaded_background: { type: :string, nullable: true },
}
},
}
let(:category_id) { category.id }
run_test!
end
end
end
path '/c/{category_id}.json' do
get 'List topics' do
tags 'Categories'
produces 'application/json'
parameter name: :category_id, in: :path, schema: { type: :string }
response '200', 'response' do
schema type: :object, properties: {
users: {
type: :array,
items: {
type: :object,
properties: {
id: { type: :integer },
username: { type: :string },
name: { type: :string, nullable: true },
avatar_template: { type: :string },
}
}
},
primary_groups: {
type: :array
},
topic_list: {
type: :object,
properties: {
can_create_topic: { type: :boolean },
draft: { type: :string, nullable: true },
draft_key: { type: :string },
draft_sequence: { type: :integer },
per_page: { type: :integer },
topics: {
type: :array,
items: {
type: :object,
properties: {
id: { type: :integer },
title: { type: :string },
fancy_title: { type: :string },
slug: { type: :string },
posts_count: { type: :integer },
reply_count: { type: :integer },
highest_post_number: { type: :integer },
image_url: { type: :string, nullable: true },
created_at: { type: :string },
last_posted_at: { type: :string },
bumped: { type: :boolean },
bumped_at: { type: :string },
archetype: { type: :string },
unseen: { type: :boolean },
pinned: { type: :boolean },
unpinned: { type: :boolean, nullable: true },
excerpt: { type: :string },
visible: { type: :boolean },
closed: { type: :boolean },
archived: { type: :boolean },
bookmarked: { type: :boolean, nullable: true },
liked: { type: :boolean, nullable: true },
views: { type: :integer },
like_count: { type: :integer },
has_summary: { type: :boolean },
last_poster_username: { type: :string },
category_id: { type: :integer },
op_like_count: { type: :integer },
pinned_globally: { type: :boolean },
featured_link: { type: :string, nullable: true },
posters: {
type: :array,
items: {
type: :object,
properties: {
extras: { type: :string },
description: { type: :string },
user_id: { type: :integer },
primary_group_id: { type: :integer, nullable: true },
}
}
}
}
}
}
}
}
}
let(:category_id) { category.id }
run_test!
end
end
end
path '/c/{category_id}/show.json' do
get 'Show category' do
tags 'Categories'
produces 'application/json'
parameter name: :category_id, in: :path, schema: { type: :string }
response '200', 'response' do
schema type: :object, properties: {
category: {
type: :object,
properties: {
id: { type: :integer },
name: { type: :string },
color: { type: :string },
text_color: { type: :string },
slug: { type: :string },
topic_count: { type: :integer },
post_count: { type: :integer },
position: { type: :integer },
description: { type: :string, nullable: true },
description_text: { type: :string, nullable: true },
description_excerpt: { type: :string, nullable: true },
topic_url: { type: :string, nullable: true },
read_restricted: { type: :boolean },
permission: { type: :integer },
notification_level: { type: :integer, nullable: true },
can_edit: { type: :boolean },
topic_template: { type: :string, nullable: true },
has_children: { type: :string, nullable: true },
sort_order: { type: :string, nullable: true },
sort_ascending: { type: :string, nullable: true },
show_subcategory_list: { type: :boolean },
num_featured_topics: { type: :integer },
default_view: { type: :string, nullable: true },
subcategory_list_style: { type: :string },
default_top_period: { type: :string },
minimum_required_tags: { type: :integer },
navigate_to_first_post_after_read: { type: :boolean },
custom_fields: {
type: :object,
properties: {
}
},
min_tags_from_required_group: { type: :integer },
required_tag_group_name: { type: :string, nullable: true },
available_groups: {
type: :array,
items: {
},
},
auto_close_hours: { type: :string, nullable: true },
auto_close_based_on_last_post: { type: :boolean },
group_permissions: {
type: :array,
items: {
type: :object,
properties: {
permission_type: { type: :integer },
group_name: { type: :string },
}
},
},
email_in: { type: :string, nullable: true },
email_in_allow_strangers: { type: :boolean },
mailinglist_mirror: { type: :boolean },
all_topics_wiki: { type: :boolean },
can_delete: { type: :boolean },
cannot_delete_reason: { type: :string, nullable: true },
allow_badges: { type: :boolean },
topic_featured_link_allowed: { type: :boolean },
search_priority: { type: :integer },
uploaded_logo: { type: :string, nullable: true },
uploaded_background: { type: :string, nullable: true },
}
},
}
let(:category_id) { category.id }
run_test!
end
end
end
end

View File

@ -0,0 +1,79 @@
# frozen_string_literal: true
require 'swagger_helper'
describe 'groups' do
let(:admin) { Fabricate(:admin) }
before do
Jobs.run_immediately!
sign_in(admin)
end
path '/admin/groups.json' do
post 'Creates a group' do
tags 'Group'
consumes 'application/json'
parameter name: :group, in: :body, schema: {
type: :object,
properties: {
group: {
type: :object,
properties: {
name: { type: :string },
}, required: [ 'name' ]
}
},
}
produces 'application/json'
response '200', 'group created' do
schema type: :object, properties: {
basic_group: {
type: :object,
properties: {
id: { type: :integer },
automatic: { type: :boolean },
name: { type: :string },
user_count: { type: :integer },
mentionable_level: { type: :integer },
messageable_level: { type: :integer },
visibility_level: { type: :integer },
automatic_membership_email_domains: { type: :string, nullable: true },
automatic_membership_retroactive: { type: :boolean },
primary_group: { type: :boolean },
title: { type: :string, nullable: true },
grant_trust_level: { type: :string, nullable: true },
incoming_email: { type: :string, nullable: true },
has_messages: { type: :boolean },
flair_url: { type: :string, nullable: true },
flair_bg_color: { type: :string, nullable: true },
flair_color: { type: :string, nullable: true },
bio_raw: { type: :string, nullable: true },
bio_cooked: { type: :string, nullable: true },
bio_excerpt: { type: :string, nullable: true },
public_admission: { type: :boolean },
public_exit: { type: :boolean },
allow_membership_requests: { type: :boolean },
full_name: { type: :string, nullable: true },
default_notification_level: { type: :integer },
membership_request_template: { type: :string, nullable: true },
membership_visibility_level: { type: :integer },
can_see_members: { type: :boolean },
publish_read_state: { type: :boolean },
},
required: ["id"]
}
}, required: ["basic_group"]
let(:group) { { name: 'awesome' } }
run_test! do |response|
data = JSON.parse(response.body)
expect(data['basic_group']['name']).to eq("awesome")
end
end
end
end
end

View File

@ -0,0 +1,484 @@
# frozen_string_literal: true
require 'swagger_helper'
describe 'posts' do
let(:'Api-Key') { Fabricate(:api_key).key }
let(:'Api-Username') { 'system' }
path '/posts.json' do
get 'List latest posts across topics' do
tags 'Posts'
parameter name: 'Api-Key', in: :header, type: :string, required: true
parameter name: 'Api-Username', in: :header, type: :string, required: true
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: :string, nullable: true },
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: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
can_recover: { type: :boolean },
can_wiki: { type: :boolean },
user_title: { type: :string, nullable: true },
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: :string, nullable: true },
user_deleted: { type: :boolean },
edit_reason: { type: :string, nullable: true },
can_view_edit_history: { type: :boolean },
wiki: { type: :boolean },
reviewable_id: { type: :string, nullable: true },
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'
consumes 'application/json'
parameter name: 'Api-Key', in: :header, type: :string, required: true
parameter name: 'Api-Username', in: :header, type: :string, required: true
# Can't be named :post!
parameter name: :post_body, in: :body, schema: {
type: :object,
properties: {
title: {
type: :string,
description: 'Required if creating a new topic or new private message.'
},
topic_id: {
type: :integer,
description: 'Required if creating a new post.'
},
raw: { type: :string },
category: {
type: :integer,
description: 'Optional if creating a new topic, and ignored if creating a new post.'
},
target_usernames: {
type: :string,
description: 'Required for private message, comma separated.',
example: 'blake,sam'
},
archetype: { type: :string },
created_at: { type: :string },
},
required: [ 'raw' ]
}
produces 'application/json'
response '200', 'post created' do
schema type: :object, properties: {
id: { type: :integer },
name: { type: :string, nullable: true },
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: :string, nullable: true },
quote_count: { type: :integer },
incoming_link_count: { type: :integer },
reads: { type: :integer },
readers_count: { type: :integer },
score: { type: :integer },
yours: { type: :boolean },
topic_id: { type: :integer },
topic_slug: { type: :string },
display_username: { type: :string, nullable: true },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
can_recover: { type: :boolean },
can_wiki: { type: :boolean },
user_title: { type: :string, nullable: true },
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 },
draft_sequence: { type: :integer },
hidden: { type: :boolean },
trust_level: { type: :integer },
deleted_at: { type: :string, nullable: true },
user_deleted: { type: :boolean },
edit_reason: { type: :string, nullable: true },
can_view_edit_history: { type: :boolean },
wiki: { type: :boolean },
reviewable_id: { type: :string, nullable: true },
reviewable_score_count: { type: :integer },
reviewable_score_pending_count: { type: :integer },
}
let(:post_body) { Fabricate(:post) }
run_test!
end
end
end
path '/posts/{id}.json' do
get 'Retreive a single post' do
tags 'Posts'
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 }
produces 'application/json'
response '200', 'latest posts' do
schema type: :object, properties: {
id: { type: :integer },
name: { type: :string, nullable: true },
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: :string, nullable: true },
quote_count: { type: :integer },
incoming_link_count: { type: :integer },
reads: { type: :integer },
readers_count: { type: :integer },
score: { type: :integer },
yours: { type: :boolean },
topic_id: { type: :integer },
topic_slug: { type: :string },
display_username: { type: :string, nullable: true },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
can_recover: { type: :boolean },
can_wiki: { type: :boolean },
user_title: { type: :string, nullable: true },
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: :string, nullable: true },
user_deleted: { type: :boolean },
edit_reason: { type: :string, nullable: true },
can_view_edit_history: { type: :boolean },
wiki: { type: :boolean },
reviewable_id: { type: :string, nullable: true },
reviewable_score_count: { type: :integer },
reviewable_score_pending_count: { type: :integer },
}
let(:id) { Fabricate(:post).id }
run_test!
end
end
put 'Update a single post' do
tags 'Posts'
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: {
post: {
type: :object,
properties: {
raw: { type: :string },
edit_reason: { type: :string },
}, required: [ 'raw' ]
}
}
}
produces 'application/json'
response '200', 'post updated' do
schema type: :object, properties: {
post: {
type: :object,
properties: {
id: { type: :integer },
name: { type: :string, nullable: true },
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: :string, nullable: true },
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, nullable: true },
primary_group_name: { type: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
can_recover: { type: :boolean },
can_wiki: { type: :boolean },
user_title: { type: :string, nullable: true },
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 },
draft_sequence: { type: :integer },
hidden: { type: :boolean },
trust_level: { type: :integer },
deleted_at: { type: :string, nullable: true },
user_deleted: { type: :boolean },
edit_reason: { type: :string, nullable: true },
can_view_edit_history: { type: :boolean },
wiki: { type: :boolean },
reviewable_id: { type: :string, nullable: true },
reviewable_score_count: { type: :integer },
reviewable_score_pending_count: { type: :integer },
}
},
}
let(:post_body) { { 'post': { 'raw': 'Updated content!', 'edit_reason': 'fixed typo' } } }
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
end
end
end
path '/posts/{id}/locked.json' do
put 'Lock a post from being edited' do
tags 'Posts'
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: :boolean }
}, 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'
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: [ '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: :string, nullable: true },
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: :string, nullable: true },
primary_group_flair_url: { type: :string, nullable: true },
primary_group_flair_bg_color: { type: :string, nullable: true },
primary_group_flair_color: { type: :string, nullable: true },
version: { type: :integer },
can_edit: { type: :boolean },
can_delete: { type: :boolean },
can_recover: { type: :boolean },
can_wiki: { type: :boolean },
user_title: { type: :string, nullable: true },
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: :string, nullable: true },
user_deleted: { type: :boolean },
edit_reason: { type: :string, nullable: true },
can_view_edit_history: { type: :boolean },
wiki: { type: :boolean },
notice_type: { type: :string },
reviewable_id: { type: :string, nullable: true },
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

View File

@ -0,0 +1,55 @@
# frozen_string_literal: true
require 'swagger_helper'
describe 'users' do
let(:'Api-Key') { Fabricate(:api_key).key }
let(:'Api-Username') { 'system' }
path '/users.json' do
post 'Creates a user' do
tags 'Users'
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: :user_body, in: :body, schema: {
type: :object,
properties: {
"name": { type: :string },
"email": { type: :string },
"password": { type: :string },
"username": { type: :string },
"active": { type: :boolean },
"approved": { type: :boolean },
"user_fields[1]": { type: :string },
},
required: ['name', 'email', 'password', 'username']
}
produces 'application/json'
response '200', 'user created' do
schema type: :object, properties: {
success: { type: :boolean },
active: { type: :boolean },
message: { type: :string },
user_id: { type: :integer },
}
let(:user_body) { {
name: 'user',
username: 'user1',
email: 'user1@example.com',
password: '13498428e9597cab689b468ebc0a5d33',
active: true
} }
run_test! do |response|
data = JSON.parse(response.body)
expect(data['success']).to eq(true)
expect(data['active']).to eq(true)
end
end
end
end
end