From 151193bb118d8c90b8c1be4fa1495fd7c8dd0ca4 Mon Sep 17 00:00:00 2001 From: Blake Erickson Date: Wed, 3 Feb 2021 17:12:35 -0700 Subject: [PATCH] document api endpoints (#11958) * DEV: Documented several group endpoints * documented some more endpoints * document more api endpoints * Document backup endpoints * remove puts --- spec/requests/api/backups_spec.rb | 122 +++++++ spec/requests/api/groups_spec.rb | 138 +++++++- .../schemas/json/backups_create_request.json | 11 + .../schemas/json/backups_list_response.json | 24 ++ .../json/group_add_members_request.json | 10 + .../json/group_add_members_response.json | 25 ++ .../schemas/json/group_members_response.json | 140 ++++++++ .../json/group_remove_members_request.json | 10 + .../json/group_remove_members_response.json | 25 ++ .../api/schemas/json/group_response.json | 331 ++++++++++++++++++ .../schemas/json/groups_list_response.json | 200 +++++++++++ .../api/schemas/json/search_request.json | 11 + .../api/schemas/json/search_response.json | 115 ++++++ .../json/user_password_change_request.json | 15 + .../json/user_password_reset_request.json | 11 + .../json/user_password_reset_response.json | 15 + spec/requests/api/search_spec.rb | 34 ++ spec/requests/api/users_spec.rb | 50 +++ 18 files changed, 1286 insertions(+), 1 deletion(-) create mode 100644 spec/requests/api/backups_spec.rb create mode 100644 spec/requests/api/schemas/json/backups_create_request.json create mode 100644 spec/requests/api/schemas/json/backups_list_response.json create mode 100644 spec/requests/api/schemas/json/group_add_members_request.json create mode 100644 spec/requests/api/schemas/json/group_add_members_response.json create mode 100644 spec/requests/api/schemas/json/group_members_response.json create mode 100644 spec/requests/api/schemas/json/group_remove_members_request.json create mode 100644 spec/requests/api/schemas/json/group_remove_members_response.json create mode 100644 spec/requests/api/schemas/json/group_response.json create mode 100644 spec/requests/api/schemas/json/groups_list_response.json create mode 100644 spec/requests/api/schemas/json/search_request.json create mode 100644 spec/requests/api/schemas/json/search_response.json create mode 100644 spec/requests/api/schemas/json/user_password_change_request.json create mode 100644 spec/requests/api/schemas/json/user_password_reset_request.json create mode 100644 spec/requests/api/schemas/json/user_password_reset_response.json create mode 100644 spec/requests/api/search_spec.rb diff --git a/spec/requests/api/backups_spec.rb b/spec/requests/api/backups_spec.rb new file mode 100644 index 00000000000..c4423696a0a --- /dev/null +++ b/spec/requests/api/backups_spec.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true +require 'swagger_helper' + +describe 'backups' do + + let(:admin) { Fabricate(:admin) } + let(:backup_filename) { "2014-02-10-065935.tar.gz" } + let(:backup_filename2) { "2014-02-11-065935.tar.gz" } + + def create_backup_files(*filenames) + @paths = filenames.map do |filename| + path = backup_path(filename) + File.open(path, "w") { |f| f.write("test backup") } + path + end + end + + def backup_path(filename) + File.join(BackupRestore::LocalBackupStore.base_directory, filename) + end + + before do + Jobs.run_immediately! + sign_in(admin) + SiteSetting.backup_location = BackupLocationSiteSetting::LOCAL + create_backup_files(backup_filename) + end + + after do + Discourse.redis.flushdb + + @paths&.each { |path| File.delete(path) if File.exists?(path) } + @paths = nil + end + + path '/admin/backups.json' do + get 'List backups' do + tags 'Backups' + consumes 'application/json' + expected_request_schema = nil + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('backups_list_response') + schema expected_response_schema + + 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 + + post 'Create backup' do + tags 'Backups' + consumes 'application/json' + expected_request_schema = load_spec_schema('backups_create_request') + parameter name: :params, in: :body, schema: expected_request_schema + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('success_ok_response') + schema expected_response_schema + + #BackupRestore.expects(:backup!).with(admin.id, publish_to_message_bus: true, with_uploads: false, client_id: "foo") + let(:params) { { 'with_uploads' => false } } + + #it_behaves_like "a JSON endpoint", 200 do + # let(:expected_response_schema) { expected_response_schema } + # let(:expected_request_schema) { expected_request_schema } + #end + + # Skipping this test for now because mocking of BackupRestore isn't working for some reason. + # Without mocking it spawns a background process which we don't want to happen in our tests. + # This still allows the API docs to be generated for this endpoint. + xit + end + end + end + + path '/admin/backups/{filename}' do + put 'Send download backup email' do + tags 'Backups' + consumes 'application/json' + expected_request_schema = nil + parameter name: :filename, in: :path, type: :string, required: true + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = nil + + let(:filename) { backup_filename } + + 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 + + get 'Download backup' do + tags 'Backups' + consumes 'application/json' + expected_request_schema = nil + parameter name: :filename, in: :path, type: :string, required: true + parameter name: :token, in: :query, type: :string, required: true + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = nil + + let(:filename) { backup_filename } + let(:token) { EmailBackupToken.set(admin.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 +end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index b5c28bfd7ed..e959eae88a0 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -75,11 +75,32 @@ describe 'groups' do end end + path '/admin/groups/{id}.json' do + delete 'Delete a group' do + tags 'Groups' + consumes 'application/json' + parameter name: :id, in: :path, type: :integer + expected_request_schema = nil + + produces 'application/json' + response '200', 'response' do + expected_response_schema = load_spec_schema('success_ok_response') + schema expected_response_schema + + let(:id) { Fabricate(:group).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 '/groups/{id}.json' do put 'Update a group' do tags 'Groups' consumes 'application/json' - parameter name: :id, in: :path, schema: { type: :string } + parameter name: :id, in: :path, type: :integer parameter name: :group, in: :body, schema: { type: :object, properties: { @@ -106,4 +127,119 @@ describe 'groups' do end end + path '/groups/{name}.json' do + get 'Get a group' do + tags 'Groups' + consumes 'application/json' + parameter name: :name, in: :path, type: :string + expected_request_schema = nil + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('group_response') + schema expected_response_schema + + let(:name) { Fabricate(:group).name } + + 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 '/groups/{name}/members.json' do + get 'List group members' do + tags 'Groups' + consumes 'application/json' + parameter name: :name, in: :path, type: :string + expected_request_schema = nil + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('group_members_response') + schema expected_response_schema + + let(:name) { Fabricate(:group).name } + + 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 '/groups/{id}/members.json' do + put 'Add group members' do + tags 'Groups' + consumes 'application/json' + parameter name: :id, in: :path, type: :integer + expected_request_schema = load_spec_schema('group_add_members_request') + parameter name: :params, in: :body, schema: expected_request_schema + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('group_add_members_response') + schema expected_response_schema + + let(:id) { Fabricate(:group).id } + let(:user) { Fabricate(:user) } + let(:user2) { Fabricate(:user) } + let(:usernames) { "#{user.username},#{user2.username}" } + let(:params) { { 'usernames' => usernames } } + + 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 'Remove group members' do + tags 'Groups' + consumes 'application/json' + parameter name: :id, in: :path, type: :integer + expected_request_schema = load_spec_schema('group_remove_members_request') + parameter name: :params, in: :body, schema: expected_request_schema + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('group_remove_members_response') + schema expected_response_schema + + let(:id) { Fabricate(:group).id } + let(:user) { Fabricate(:user) } + let(:user2) { Fabricate(:user) } + let(:usernames) { "#{user.username},#{user2.username}" } + let(:params) { { 'usernames' => usernames } } + + 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 '/groups.json' do + get 'List groups' do + tags 'Groups' + consumes 'application/json' + expected_request_schema = nil + + produces 'application/json' + response '200', 'response' do + expected_response_schema = load_spec_schema('groups_list_response') + schema expected_response_schema + + 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 + end diff --git a/spec/requests/api/schemas/json/backups_create_request.json b/spec/requests/api/schemas/json/backups_create_request.json new file mode 100644 index 00000000000..a207b8fb81f --- /dev/null +++ b/spec/requests/api/schemas/json/backups_create_request.json @@ -0,0 +1,11 @@ +{ + "additionalProperties": false, + "properties": { + "with_uploads": { + "type": "boolean" + } + }, + "required": [ + "with_uploads" + ] +} diff --git a/spec/requests/api/schemas/json/backups_list_response.json b/spec/requests/api/schemas/json/backups_list_response.json new file mode 100644 index 00000000000..5c24391e04c --- /dev/null +++ b/spec/requests/api/schemas/json/backups_list_response.json @@ -0,0 +1,24 @@ +{ + "type": "array", + "minItems": 1, + "uniqItems": true, + "items": { + "type": "object", + "properties": { + "filename": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "last_modified": { + "type": "string" + } + }, + "required": [ + "filename", + "size", + "last_modified" + ] + } +} diff --git a/spec/requests/api/schemas/json/group_add_members_request.json b/spec/requests/api/schemas/json/group_add_members_request.json new file mode 100644 index 00000000000..1ac6f3cefbf --- /dev/null +++ b/spec/requests/api/schemas/json/group_add_members_request.json @@ -0,0 +1,10 @@ +{ + "additionalProperties": false, + "properties": { + "usernames": { + "type": "string", + "description": "comma separated list", + "example": "username1,username2" + } + } +} diff --git a/spec/requests/api/schemas/json/group_add_members_response.json b/spec/requests/api/schemas/json/group_add_members_response.json new file mode 100644 index 00000000000..40b05621aaf --- /dev/null +++ b/spec/requests/api/schemas/json/group_add_members_response.json @@ -0,0 +1,25 @@ +{ + "additionalProperties": false, + "properties": { + "success": { + "type": "string" + }, + "usernames": { + "type": "array", + "items": [ + + ] + }, + "emails": { + "type": "array", + "items": [ + + ] + } + }, + "required": [ + "success", + "usernames", + "emails" + ] +} diff --git a/spec/requests/api/schemas/json/group_members_response.json b/spec/requests/api/schemas/json/group_members_response.json new file mode 100644 index 00000000000..f19aa511339 --- /dev/null +++ b/spec/requests/api/schemas/json/group_members_response.json @@ -0,0 +1,140 @@ +{ + "additionalProperties": false, + "properties": { + "members": { + "type": "array", + "items": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer" + }, + "username": { + "type": "string" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "avatar_template": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "last_posted_at": { + "type": "string" + }, + "last_seen_at": { + "type": "string" + }, + "added_at": { + "type": "string" + }, + "timezone": { + "type": "string" + } + }, + "required": [ + "id", + "username", + "name", + "avatar_template", + "title", + "last_posted_at", + "last_seen_at", + "added_at", + "timezone" + ] + } + ] + }, + "owners": { + "type": "array", + "items": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer" + }, + "username": { + "type": "string" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "avatar_template": { + "type": "string" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "last_posted_at": { + "type": "string" + }, + "last_seen_at": { + "type": "string" + }, + "added_at": { + "type": "string" + }, + "timezone": { + "type": "string" + } + }, + "required": [ + "id", + "username", + "name", + "avatar_template", + "title", + "last_posted_at", + "last_seen_at", + "added_at", + "timezone" + ] + } + ] + }, + "meta": { + "type": "object", + "additionalProperties": false, + "properties": { + "total": { + "type": "integer" + }, + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + } + }, + "required": [ + "total", + "limit", + "offset" + ] + } + }, + "required": [ + "members", + "owners", + "meta" + ] +} diff --git a/spec/requests/api/schemas/json/group_remove_members_request.json b/spec/requests/api/schemas/json/group_remove_members_request.json new file mode 100644 index 00000000000..1ac6f3cefbf --- /dev/null +++ b/spec/requests/api/schemas/json/group_remove_members_request.json @@ -0,0 +1,10 @@ +{ + "additionalProperties": false, + "properties": { + "usernames": { + "type": "string", + "description": "comma separated list", + "example": "username1,username2" + } + } +} diff --git a/spec/requests/api/schemas/json/group_remove_members_response.json b/spec/requests/api/schemas/json/group_remove_members_response.json new file mode 100644 index 00000000000..a54f042b488 --- /dev/null +++ b/spec/requests/api/schemas/json/group_remove_members_response.json @@ -0,0 +1,25 @@ +{ + "additionalProperties": false, + "properties": { + "success": { + "type": "string" + }, + "usernames": { + "type": "array", + "items": [ + + ] + }, + "skipped_usernames": { + "type": "array", + "items": [ + + ] + } + }, + "required": [ + "success", + "usernames", + "skipped_usernames" + ] +} diff --git a/spec/requests/api/schemas/json/group_response.json b/spec/requests/api/schemas/json/group_response.json new file mode 100644 index 00000000000..b4bf0f15cc9 --- /dev/null +++ b/spec/requests/api/schemas/json/group_response.json @@ -0,0 +1,331 @@ +{ + "additionalProperties": false, + "properties": { + "group": { + "type": "object", + "additionalProperties": false, + "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" + }, + "primary_group": { + "type": "boolean" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "grant_trust_level": { + "type": [ + "string", + "null" + ] + }, + "incoming_email": { + "type": [ + "string", + "null" + ] + }, + "has_messages": { + "type": "boolean" + }, + "flair_url": { + "type": [ + "string", + "null" + ] + }, + "flair_bg_color": { + "type": [ + "string", + "null" + ] + }, + "flair_color": { + "type": [ + "string", + "null" + ] + }, + "bio_raw": { + "type": [ + "string", + "null" + ] + }, + "bio_cooked": { + "type": [ + "string", + "null" + ] + }, + "bio_excerpt": { + "type": [ + "string", + "null" + ] + }, + "public_admission": { + "type": "boolean" + }, + "public_exit": { + "type": "boolean" + }, + "allow_membership_requests": { + "type": "boolean" + }, + "full_name": { + "type": [ + "string", + "null" + ] + }, + "default_notification_level": { + "type": "integer" + }, + "membership_request_template": { + "type": [ + "string", + "null" + ] + }, + "is_group_user": { + "type": "boolean" + }, + "members_visibility_level": { + "type": "integer" + }, + "can_see_members": { + "type": "boolean" + }, + "can_admin_group": { + "type": "boolean" + }, + "publish_read_state": { + "type": "boolean" + }, + "is_group_owner_display": { + "type": "boolean" + }, + "mentionable": { + "type": "boolean" + }, + "messageable": { + "type": "boolean" + }, + "automatic_membership_email_domains": { + "type": [ + "string", + "null" + ] + }, + "smtp_server": { + "type": [ + "string", + "null" + ] + }, + "smtp_port": { + "type": [ + "string", + "null" + ] + }, + "smtp_ssl": { + "type": [ + "string", + "null" + ] + }, + "imap_server": { + "type": [ + "string", + "null" + ] + }, + "imap_port": { + "type": [ + "string", + "null" + ] + }, + "imap_ssl": { + "type": [ + "string", + "null" + ] + }, + "imap_mailbox_name": { + "type": "string" + }, + "imap_mailboxes": { + "type": "array", + "items": [ + + ] + }, + "email_username": { + "type": [ + "string", + "null" + ] + }, + "email_password": { + "type": [ + "string", + "null" + ] + }, + "imap_last_error": { + "type": [ + "string", + "null" + ] + }, + "imap_old_emails": { + "type": [ + "string", + "null" + ] + }, + "imap_new_emails": { + "type": [ + "string", + "null" + ] + }, + "message_count": { + "type": "integer" + }, + "allow_unknown_sender_topic_replies": { + "type": "boolean" + }, + "watching_category_ids": { + "type": "array", + "items": [ + + ] + }, + "tracking_category_ids": { + "type": "array", + "items": [ + + ] + }, + "watching_first_post_category_ids": { + "type": "array", + "items": [ + + ] + }, + "regular_category_ids": { + "type": "array", + "items": [ + + ] + }, + "muted_category_ids": { + "type": "array", + "items": [ + + ] + } + }, + "required": [ + "id", + "automatic", + "name", + "user_count", + "mentionable_level", + "messageable_level", + "visibility_level", + "primary_group", + "title", + "grant_trust_level", + "incoming_email", + "has_messages", + "flair_url", + "flair_bg_color", + "flair_color", + "bio_raw", + "bio_cooked", + "bio_excerpt", + "public_admission", + "public_exit", + "allow_membership_requests", + "full_name", + "default_notification_level", + "membership_request_template", + "is_group_user", + "members_visibility_level", + "can_see_members", + "can_admin_group", + "publish_read_state", + "is_group_owner_display", + "mentionable", + "messageable", + "automatic_membership_email_domains", + "smtp_server", + "smtp_port", + "smtp_ssl", + "imap_server", + "imap_port", + "imap_ssl", + "imap_mailbox_name", + "imap_mailboxes", + "email_username", + "email_password", + "imap_last_error", + "imap_old_emails", + "imap_new_emails", + "message_count", + "allow_unknown_sender_topic_replies", + "watching_category_ids", + "tracking_category_ids", + "watching_first_post_category_ids", + "regular_category_ids", + "muted_category_ids" + ] + }, + "extras": { + "type": "object", + "additionalProperties": false, + "properties": { + "visible_group_names": { + "type": "array", + "items": [ + + ] + } + }, + "required": [ + "visible_group_names" + ] + } + }, + "required": [ + "group", + "extras" + ] +} diff --git a/spec/requests/api/schemas/json/groups_list_response.json b/spec/requests/api/schemas/json/groups_list_response.json new file mode 100644 index 00000000000..2123948cfb8 --- /dev/null +++ b/spec/requests/api/schemas/json/groups_list_response.json @@ -0,0 +1,200 @@ +{ + "additionalProperties": false, + "properties": { + "groups": { + "type": "array", + "items": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "id": { + "type": "integer" + }, + "automatic": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "user_count": { + "type": "integer" + }, + "mentionable_level": { + "type": "integer" + }, + "messageable_level": { + "type": "integer" + }, + "visibility_level": { + "type": "integer" + }, + "primary_group": { + "type": "boolean" + }, + "title": { + "type": [ + "string", + "null" + ] + }, + "grant_trust_level": { + "type": [ + "string", + "null" + ] + }, + "incoming_email": { + "type": [ + "string", + "null" + ] + }, + "has_messages": { + "type": "boolean" + }, + "flair_url": { + "type": [ + "string", + "null" + ] + }, + "flair_bg_color": { + "type": [ + "string", + "null" + ] + }, + "flair_color": { + "type": [ + "string", + "null" + ] + }, + "bio_raw": { + "type": [ + "string", + "null" + ] + }, + "bio_cooked": { + "type": [ + "string", + "null" + ] + }, + "bio_excerpt": { + "type": [ + "string", + "null" + ] + }, + "public_admission": { + "type": "boolean" + }, + "public_exit": { + "type": "boolean" + }, + "allow_membership_requests": { + "type": "boolean" + }, + "full_name": { + "type": [ + "string", + "null" + ] + }, + "default_notification_level": { + "type": "integer" + }, + "membership_request_template": { + "type": [ + "string", + "null" + ] + }, + "is_group_user": { + "type": "boolean" + }, + "is_group_owner": { + "type": "boolean" + }, + "members_visibility_level": { + "type": "integer" + }, + "can_see_members": { + "type": "boolean" + }, + "can_admin_group": { + "type": "boolean" + }, + "publish_read_state": { + "type": "boolean" + } + }, + "required": [ + "id", + "automatic", + "name", + "display_name", + "user_count", + "mentionable_level", + "messageable_level", + "visibility_level", + "primary_group", + "title", + "grant_trust_level", + "incoming_email", + "has_messages", + "flair_url", + "flair_bg_color", + "flair_color", + "bio_raw", + "bio_cooked", + "bio_excerpt", + "public_admission", + "public_exit", + "allow_membership_requests", + "full_name", + "default_notification_level", + "membership_request_template", + "members_visibility_level", + "can_see_members", + "can_admin_group", + "publish_read_state" + ] + } + ] + }, + "extras": { + "type": "object", + "additionalProperties": false, + "properties": { + "type_filters": { + "type": "array", + "items": [ + + ] + } + }, + "required": [ + "type_filters" + ] + }, + "total_rows_groups": { + "type": "integer" + }, + "load_more_groups": { + "type": "string" + } + }, + "required": [ + "groups", + "extras", + "total_rows_groups", + "load_more_groups" + ] +} diff --git a/spec/requests/api/schemas/json/search_request.json b/spec/requests/api/schemas/json/search_request.json new file mode 100644 index 00000000000..0344b0f9299 --- /dev/null +++ b/spec/requests/api/schemas/json/search_request.json @@ -0,0 +1,11 @@ +{ + "additionalProperties": false, + "properties": { + "q": { + "type": "string" + } + }, + "required": [ + "q" + ] +} diff --git a/spec/requests/api/schemas/json/search_response.json b/spec/requests/api/schemas/json/search_response.json new file mode 100644 index 00000000000..999fecbc6d0 --- /dev/null +++ b/spec/requests/api/schemas/json/search_response.json @@ -0,0 +1,115 @@ +{ + "additionalProperties": false, + "properties": { + "posts": { + "type": "array", + "items": [ + + ] + }, + "users": { + "type": "array", + "items": [ + + ] + }, + "categories": { + "type": "array", + "items": [ + + ] + }, + "groups": { + "type": "array", + "items": [ + + ] + }, + "grouped_search_result": { + "type": ["object", "null"], + "additionalProperties": false, + "properties": { + "more_posts": { + "type": [ + "string", + "null" + ] + }, + "more_users": { + "type": [ + "string", + "null" + ] + }, + "more_categories": { + "type": [ + "string", + "null" + ] + }, + "term": { + "type": "string" + }, + "search_log_id": { + "type": "integer" + }, + "more_full_page_results": { + "type": [ + "string", + "null" + ] + }, + "can_create_topic": { + "type": "boolean" + }, + "error": { + "type": [ + "string", + "null" + ] + }, + "post_ids": { + "type": "array", + "items": [ + + ] + }, + "user_ids": { + "type": "array", + "items": [ + + ] + }, + "category_ids": { + "type": "array", + "items": [ + + ] + }, + "group_ids": { + "type": "array", + "items": [ + + ] + } + }, + "required": [ + "more_posts", + "more_users", + "more_categories", + "term", + "search_log_id", + "more_full_page_results", + "can_create_topic", + "error", + "post_ids", + "user_ids", + "category_ids", + "group_ids" + ] + } + }, + "required": [ + "grouped_search_result" + ] +} diff --git a/spec/requests/api/schemas/json/user_password_change_request.json b/spec/requests/api/schemas/json/user_password_change_request.json new file mode 100644 index 00000000000..de84d710343 --- /dev/null +++ b/spec/requests/api/schemas/json/user_password_change_request.json @@ -0,0 +1,15 @@ +{ + "additionalProperties": false, + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + } + }, + "required": [ + "username", + "password" + ] +} diff --git a/spec/requests/api/schemas/json/user_password_reset_request.json b/spec/requests/api/schemas/json/user_password_reset_request.json new file mode 100644 index 00000000000..2ddb7d6d98b --- /dev/null +++ b/spec/requests/api/schemas/json/user_password_reset_request.json @@ -0,0 +1,11 @@ +{ + "additionalProperties": false, + "properties": { + "login": { + "type": "string" + } + }, + "required": [ + "login" + ] +} diff --git a/spec/requests/api/schemas/json/user_password_reset_response.json b/spec/requests/api/schemas/json/user_password_reset_response.json new file mode 100644 index 00000000000..a0157c34d74 --- /dev/null +++ b/spec/requests/api/schemas/json/user_password_reset_response.json @@ -0,0 +1,15 @@ +{ + "additionalProperties": false, + "properties": { + "success": { + "type": "string" + }, + "user_found": { + "type": "boolean" + } + }, + "required": [ + "success", + "user_found" + ] +} diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb new file mode 100644 index 00000000000..4fe9beaa53b --- /dev/null +++ b/spec/requests/api/search_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true +require 'swagger_helper' + +describe 'groups' do + + let(:admin) { Fabricate(:admin) } + + before do + Jobs.run_immediately! + sign_in(admin) + end + + path '/search.json' do + get 'Search for a term' do + tags 'Search' + consumes 'application/json' + expected_request_schema = load_spec_schema('search_request') + parameter name: :params, in: :body, schema: expected_request_schema + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('search_response') + schema expected_response_schema + + let(:params) { { 'q' => 'awesome post' } } + + 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 +end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 23179e4f195..365b4d5e03e 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -460,4 +460,54 @@ describe 'users' do end end + path '/session/forgot_password.json' do + post 'Send password reset email' do + tags 'Users' + consumes 'application/json' + expected_request_schema = load_spec_schema('user_password_reset_request') + parameter name: :params, in: :body, schema: expected_request_schema + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = load_spec_schema('user_password_reset_response') + schema expected_response_schema + + let(:user) { Fabricate(:user) } + let(:params) { { 'login' => user.username } } + + 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 '/users/password-reset/{token}.json' do + put 'Change password' do + tags 'Users' + consumes 'application/json' + expected_request_schema = load_spec_schema('user_password_change_request') + parameter name: :token, in: :path, type: :string, required: true + parameter name: :params, in: :body, schema: expected_request_schema + + produces 'application/json' + response '200', 'success response' do + expected_response_schema = nil + + let(:user) { Fabricate(:user) } + let(:token) { user.email_tokens.create(email: user.email).token } + let(:params) { { + 'username' => user.username, + 'password' => 'NH8QYbxYS5Zv5qEFzA4jULvM' + } } + + 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 + end