discourse_api 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +23 -10
- data/.rubocop.yml +1 -1
- data/.streerc +2 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/README.md +0 -4
- data/discourse_api.gemspec +7 -4
- data/examples/backups.rb +5 -5
- data/examples/badges.rb +5 -5
- data/examples/bookmark_topic.rb +5 -5
- data/examples/category.rb +10 -6
- data/examples/change_topic_status.rb +12 -11
- data/examples/create_private_message.rb +6 -6
- data/examples/create_topic.rb +9 -9
- data/examples/create_update_category.rb +13 -16
- data/examples/create_user.rb +12 -11
- data/examples/dashboard.rb +5 -5
- data/examples/disposable_invite_tokens.rb +9 -10
- data/examples/example.rb +5 -5
- data/examples/group_set_user_notification_level.rb +18 -19
- data/examples/groups.rb +7 -7
- data/examples/invite_users.rb +5 -5
- data/examples/manage_api_keys.rb +6 -11
- data/examples/notifications.rb +6 -6
- data/examples/polls.rb +12 -12
- data/examples/post_action.rb +5 -5
- data/examples/search.rb +5 -5
- data/examples/sent_private_messages.rb +6 -6
- data/examples/sso.rb +6 -6
- data/examples/topic_lists.rb +5 -5
- data/examples/update_user.rb +15 -7
- data/examples/upload_file.rb +7 -7
- data/lib/discourse_api/api/api_key.rb +1 -3
- data/lib/discourse_api/api/backups.rb +1 -1
- data/lib/discourse_api/api/badges.rb +21 -6
- data/lib/discourse_api/api/categories.rb +69 -37
- data/lib/discourse_api/api/dashboard.rb +2 -6
- data/lib/discourse_api/api/groups.rb +68 -73
- data/lib/discourse_api/api/invite.rb +30 -30
- data/lib/discourse_api/api/notifications.rb +2 -3
- data/lib/discourse_api/api/params.rb +4 -14
- data/lib/discourse_api/api/polls.rb +9 -12
- data/lib/discourse_api/api/posts.rb +5 -8
- data/lib/discourse_api/api/private_messages.rb +9 -8
- data/lib/discourse_api/api/search.rb +2 -2
- data/lib/discourse_api/api/topics.rb +20 -22
- data/lib/discourse_api/api/uploads.rb +7 -5
- data/lib/discourse_api/api/user_actions.rb +2 -2
- data/lib/discourse_api/api/users.rb +31 -19
- data/lib/discourse_api/client.rb +58 -56
- data/lib/discourse_api/example_helper.rb +2 -4
- data/lib/discourse_api/single_sign_on.rb +56 -57
- data/lib/discourse_api/version.rb +1 -1
- data/spec/discourse_api/api/api_key_spec.rb +39 -25
- data/spec/discourse_api/api/backups_spec.rb +8 -3
- data/spec/discourse_api/api/badges_spec.rb +17 -7
- data/spec/discourse_api/api/categories_spec.rb +95 -53
- data/spec/discourse_api/api/email_spec.rb +17 -7
- data/spec/discourse_api/api/groups_spec.rb +71 -52
- data/spec/discourse_api/api/invite_spec.rb +41 -21
- data/spec/discourse_api/api/notifications_spec.rb +8 -4
- data/spec/discourse_api/api/params_spec.rb +5 -3
- data/spec/discourse_api/api/polls_spec.rb +53 -44
- data/spec/discourse_api/api/posts_spec.rb +33 -16
- data/spec/discourse_api/api/private_messages_spec.rb +25 -12
- data/spec/discourse_api/api/search_spec.rb +8 -3
- data/spec/discourse_api/api/site_settings_spec.rb +2 -3
- data/spec/discourse_api/api/sso_spec.rb +29 -25
- data/spec/discourse_api/api/topics_spec.rb +100 -31
- data/spec/discourse_api/api/uploads_spec.rb +16 -7
- data/spec/discourse_api/api/user_actions_spec.rb +13 -3
- data/spec/discourse_api/api/users_spec.rb +137 -55
- data/spec/discourse_api/client_spec.rb +32 -32
- data/spec/discourse_api/single_sign_on_spec.rb +43 -0
- data/spec/fixtures/categories.json +1 -1
- data/spec/spec_helper.rb +10 -15
- metadata +57 -12
@@ -8,21 +8,19 @@ module DiscourseApi
|
|
8
8
|
|
9
9
|
def user(username, params = {})
|
10
10
|
response = get("/users/#{username}.json", params)
|
11
|
-
response[:body][
|
11
|
+
response[:body]["user"]
|
12
12
|
end
|
13
13
|
|
14
14
|
def user_sso(user_id)
|
15
15
|
response = get("/admin/users/#{user_id}.json")
|
16
|
-
response[:body][
|
16
|
+
response[:body]["single_sign_on_record"]
|
17
17
|
end
|
18
18
|
|
19
19
|
def update_avatar(username, args)
|
20
|
-
args =
|
21
|
-
.optional(:file, :url)
|
22
|
-
.default(type: 'avatar', synchronous: true)
|
23
|
-
.to_h
|
20
|
+
args =
|
21
|
+
API.params(args).optional(:file, :url).default(type: "avatar", synchronous: true).to_h
|
24
22
|
upload_response = post("/uploads", args)
|
25
|
-
put("/u/#{username}/preferences/avatar/pick", upload_id: upload_response[
|
23
|
+
put("/u/#{username}/preferences/avatar/pick", upload_id: upload_response["id"])
|
26
24
|
end
|
27
25
|
|
28
26
|
def update_email(username, email)
|
@@ -30,10 +28,24 @@ module DiscourseApi
|
|
30
28
|
end
|
31
29
|
|
32
30
|
def update_user(username, args)
|
33
|
-
args =
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
args =
|
32
|
+
API
|
33
|
+
.params(args)
|
34
|
+
.optional(
|
35
|
+
:name,
|
36
|
+
:title,
|
37
|
+
:bio_raw,
|
38
|
+
:location,
|
39
|
+
:website,
|
40
|
+
:profile_background,
|
41
|
+
:card_background,
|
42
|
+
:email_messages_level,
|
43
|
+
:mailing_list_mode,
|
44
|
+
:homepage_id,
|
45
|
+
:theme_ids,
|
46
|
+
:user_fields,
|
47
|
+
)
|
48
|
+
.to_h
|
37
49
|
put("/u/#{username}", args)
|
38
50
|
end
|
39
51
|
|
@@ -42,18 +54,18 @@ module DiscourseApi
|
|
42
54
|
end
|
43
55
|
|
44
56
|
def update_trust_level(user_id, args)
|
45
|
-
args = API.params(args)
|
46
|
-
.required(:level)
|
47
|
-
.to_h
|
57
|
+
args = API.params(args).required(:level).to_h
|
48
58
|
response = put("/admin/users/#{user_id}/trust_level", args)
|
49
59
|
response[:body]
|
50
60
|
end
|
51
61
|
|
52
62
|
def create_user(args)
|
53
|
-
args =
|
54
|
-
|
55
|
-
|
56
|
-
|
63
|
+
args =
|
64
|
+
API
|
65
|
+
.params(args)
|
66
|
+
.required(:name, :email, :password, :username)
|
67
|
+
.optional(:active, :approved, :staged, :user_fields)
|
68
|
+
.to_h
|
57
69
|
post("/users", args)
|
58
70
|
end
|
59
71
|
|
@@ -91,7 +103,7 @@ module DiscourseApi
|
|
91
103
|
|
92
104
|
def by_external_id(external_id)
|
93
105
|
response = get("/users/by-external/#{external_id}")
|
94
|
-
response[:body][
|
106
|
+
response[:body]["user"]
|
95
107
|
end
|
96
108
|
|
97
109
|
def suspend(user_id, suspend_until, reason)
|
data/lib/discourse_api/client.rb
CHANGED
@@ -1,29 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
2
|
+
require "faraday"
|
3
|
+
require "faraday/follow_redirects"
|
4
|
+
require "faraday/multipart"
|
5
|
+
require "json"
|
6
|
+
require "uri"
|
7
|
+
require "discourse_api/version"
|
8
|
+
require "discourse_api/api/categories"
|
9
|
+
require "discourse_api/api/search"
|
10
|
+
require "discourse_api/api/sso"
|
11
|
+
require "discourse_api/api/tags"
|
12
|
+
require "discourse_api/api/topics"
|
13
|
+
require "discourse_api/api/polls"
|
14
|
+
require "discourse_api/api/posts"
|
15
|
+
require "discourse_api/api/users"
|
16
|
+
require "discourse_api/api/groups"
|
17
|
+
require "discourse_api/api/invite"
|
18
|
+
require "discourse_api/api/private_messages"
|
19
|
+
require "discourse_api/api/notifications"
|
20
|
+
require "discourse_api/api/badges"
|
21
|
+
require "discourse_api/api/email"
|
22
|
+
require "discourse_api/api/api_key"
|
23
|
+
require "discourse_api/api/backups"
|
24
|
+
require "discourse_api/api/dashboard"
|
25
|
+
require "discourse_api/api/uploads"
|
26
|
+
require "discourse_api/api/user_actions"
|
27
|
+
require "discourse_api/api/site_settings"
|
27
28
|
|
28
29
|
module DiscourseApi
|
29
30
|
class Client
|
@@ -55,9 +56,9 @@ module DiscourseApi
|
|
55
56
|
include DiscourseApi::API::SiteSettings
|
56
57
|
|
57
58
|
def initialize(host, api_key = nil, api_username = nil)
|
58
|
-
raise ArgumentError,
|
59
|
-
@host
|
60
|
-
@api_key
|
59
|
+
raise ArgumentError, "host needs to be defined" if host.nil? || host.empty?
|
60
|
+
@host = host
|
61
|
+
@api_key = api_key
|
61
62
|
@api_username = api_username
|
62
63
|
@use_relative = check_subdirectory(host)
|
63
64
|
end
|
@@ -69,19 +70,19 @@ module DiscourseApi
|
|
69
70
|
|
70
71
|
def api_username=(api_username)
|
71
72
|
@api_username = api_username
|
72
|
-
@connection.headers[
|
73
|
+
@connection.headers["Api-Username"] = api_username unless @connection.nil?
|
73
74
|
end
|
74
75
|
|
75
76
|
def connection_options
|
76
77
|
@connection_options ||= {
|
77
78
|
url: @host,
|
78
79
|
request: {
|
79
|
-
timeout: @timeout || DEFAULT_TIMEOUT
|
80
|
+
timeout: @timeout || DEFAULT_TIMEOUT,
|
80
81
|
},
|
81
82
|
headers: {
|
82
|
-
accept:
|
83
|
+
accept: "application/json",
|
83
84
|
user_agent: user_agent,
|
84
|
-
}
|
85
|
+
},
|
85
86
|
}
|
86
87
|
end
|
87
88
|
|
@@ -126,43 +127,44 @@ module DiscourseApi
|
|
126
127
|
private
|
127
128
|
|
128
129
|
def connection
|
129
|
-
@connection ||=
|
130
|
-
|
131
|
-
|
130
|
+
@connection ||=
|
131
|
+
Faraday.new connection_options do |conn|
|
132
|
+
# Allow uploading of files
|
133
|
+
conn.request :multipart
|
132
134
|
|
133
|
-
|
134
|
-
|
135
|
+
# Convert request params to "www-form-encoded"
|
136
|
+
conn.request :url_encoded
|
135
137
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
138
|
+
# Allow to interact with forums behind basic HTTP authentication
|
139
|
+
if basic_auth
|
140
|
+
conn.request :authorization, :basic, basic_auth[:user], basic_auth[:password]
|
141
|
+
end
|
140
142
|
|
141
|
-
|
142
|
-
|
143
|
+
# Follow redirects
|
144
|
+
conn.response :follow_redirects, limit: 5
|
143
145
|
|
144
|
-
|
145
|
-
|
146
|
+
# Parse responses as JSON
|
147
|
+
conn.response :json, content_type: "application/json"
|
146
148
|
|
147
|
-
|
148
|
-
|
149
|
+
# For HTTP debugging, uncomment
|
150
|
+
# conn.response :logger
|
149
151
|
|
150
|
-
|
151
|
-
|
152
|
+
# Use Faraday's default HTTP adapter
|
153
|
+
conn.adapter Faraday.default_adapter
|
152
154
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
155
|
+
# Pass api_key and api_username on every request
|
156
|
+
unless api_username.nil?
|
157
|
+
conn.headers["Api-Key"] = api_key
|
158
|
+
conn.headers["Api-Username"] = api_username
|
159
|
+
end
|
157
160
|
end
|
158
|
-
end
|
159
161
|
end
|
160
162
|
|
161
163
|
def request(method, path, params = {})
|
162
164
|
unless Hash === params
|
163
165
|
params = params.to_h if params.respond_to? :to_h
|
164
166
|
end
|
165
|
-
path = @use_relative ? path.sub(
|
167
|
+
path = @use_relative ? path.sub(%r{^/}, "") : path
|
166
168
|
response = connection.send(method.to_sym, path, params)
|
167
169
|
handle_error(response)
|
168
170
|
response.env
|
@@ -188,7 +190,7 @@ module DiscourseApi
|
|
188
190
|
end
|
189
191
|
|
190
192
|
def check_subdirectory(host)
|
191
|
-
URI(host).request_uri !=
|
193
|
+
URI(host).request_uri != "/"
|
192
194
|
end
|
193
195
|
end
|
194
196
|
end
|
@@ -1,11 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require
|
2
|
+
require "yaml"
|
3
3
|
|
4
4
|
module DiscourseApi
|
5
5
|
class ExampleHelper
|
6
|
-
|
7
6
|
def self.load_yml
|
8
|
-
config_yml = File.expand_path(
|
7
|
+
config_yml = File.expand_path("../../../config.yml", __FILE__)
|
9
8
|
puts config_yml
|
10
9
|
begin
|
11
10
|
config = YAML.load_file config_yml
|
@@ -14,6 +13,5 @@ module DiscourseApi
|
|
14
13
|
end
|
15
14
|
config
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
@@ -1,49 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
2
|
+
require "base64"
|
3
|
+
require "rack"
|
4
|
+
require "openssl"
|
5
5
|
|
6
6
|
module DiscourseApi
|
7
7
|
class SingleSignOn
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
8
|
+
class ParseError < RuntimeError
|
9
|
+
end
|
10
|
+
class MissingConfigError < RuntimeError
|
11
|
+
end
|
12
|
+
|
13
|
+
ACCESSORS = %i[
|
14
|
+
add_groups
|
15
|
+
admin
|
16
|
+
avatar_force_update
|
17
|
+
avatar_url
|
18
|
+
bio
|
19
|
+
card_background_url
|
20
|
+
confirmed_2fa
|
21
|
+
email
|
22
|
+
external_id
|
23
|
+
groups
|
24
|
+
locale
|
25
|
+
locale_force_update
|
26
|
+
moderator
|
27
|
+
name
|
28
|
+
no_2fa_methods
|
29
|
+
nonce
|
30
|
+
profile_background_url
|
31
|
+
remove_groups
|
32
|
+
require_2fa
|
33
|
+
require_activation
|
34
|
+
return_sso_url
|
35
|
+
suppress_welcome_message
|
36
|
+
title
|
37
|
+
username
|
33
38
|
]
|
34
39
|
|
35
40
|
FIXNUMS = []
|
36
41
|
|
37
|
-
BOOLS = [
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
BOOLS = %i[
|
43
|
+
admin
|
44
|
+
avatar_force_update
|
45
|
+
confirmed_2fa
|
46
|
+
locale_force_update
|
47
|
+
moderator
|
48
|
+
no_2fa_methods
|
49
|
+
require_2fa
|
50
|
+
require_activation
|
51
|
+
suppress_welcome_message
|
47
52
|
]
|
48
53
|
ARRAYS = [:groups]
|
49
54
|
#NONCE_EXPIRY_TIME = 10.minutes # minutes is a rails method and is causing an error. Is this needed in the api?
|
@@ -52,11 +57,11 @@ module DiscourseApi
|
|
52
57
|
attr_writer :custom_fields, :sso_secret, :sso_url
|
53
58
|
|
54
59
|
def self.sso_secret
|
55
|
-
raise
|
60
|
+
raise MissingConfigError, "sso_secret not implemented on class, be sure to set it on instance"
|
56
61
|
end
|
57
62
|
|
58
63
|
def self.sso_url
|
59
|
-
raise
|
64
|
+
raise MissingConfigError, "sso_url not implemented on class, be sure to set it on instance"
|
60
65
|
end
|
61
66
|
|
62
67
|
def self.parse_hash(payload)
|
@@ -69,9 +74,7 @@ module DiscourseApi
|
|
69
74
|
val = payload[k]
|
70
75
|
|
71
76
|
val = val.to_i if FIXNUMS.include? k
|
72
|
-
if BOOLS.include? k
|
73
|
-
val = ["true", "false"].include?(val) ? val == "true" : nil
|
74
|
-
end
|
77
|
+
val = %w[true false].include?(val) ? val == "true" : nil if BOOLS.include? k
|
75
78
|
val = val.split(",") if ARRAYS.include?(k) && !val.nil?
|
76
79
|
sso.send("#{k}=", val)
|
77
80
|
end
|
@@ -96,11 +99,13 @@ module DiscourseApi
|
|
96
99
|
|
97
100
|
parsed = Rack::Utils.parse_query(payload)
|
98
101
|
if sso.sign(parsed["sso"]) != parsed["sig"]
|
99
|
-
diags =
|
100
|
-
|
101
|
-
|
102
|
+
diags =
|
103
|
+
"\n\nsso: #{parsed["sso"]}\n\nsig: #{parsed["sig"]}\n\nexpected sig: #{sso.sign(parsed["sso"])}"
|
104
|
+
if parsed["sso"] =~ %r{[^a-zA-Z0-9=\r\n/+]}m
|
105
|
+
raise ParseError,
|
106
|
+
"The SSO field should be Base64 encoded, using only A-Z, a-z, 0-9, +, /, and = characters. Your input contains characters we don't understand as Base64, see http://en.wikipedia.org/wiki/Base64 #{diags}"
|
102
107
|
else
|
103
|
-
raise
|
108
|
+
raise ParseError, "Bad signature for payload #{diags}"
|
104
109
|
end
|
105
110
|
end
|
106
111
|
|
@@ -110,9 +115,7 @@ module DiscourseApi
|
|
110
115
|
ACCESSORS.each do |k|
|
111
116
|
val = decoded_hash[k.to_s]
|
112
117
|
val = val.to_i if FIXNUMS.include? k
|
113
|
-
if BOOLS.include? k
|
114
|
-
val = ["true", "false"].include?(val) ? val == "true" : nil
|
115
|
-
end
|
118
|
+
val = %w[true false].include?(val) ? val == "true" : nil if BOOLS.include? k
|
116
119
|
val = val.split(",") if ARRAYS.include?(k) && !val.nil?
|
117
120
|
sso.send("#{k}=", val)
|
118
121
|
end
|
@@ -148,12 +151,12 @@ module DiscourseApi
|
|
148
151
|
|
149
152
|
def to_url(base_url = nil)
|
150
153
|
base = "#{base_url || sso_url}"
|
151
|
-
"#{base}#{base.include?(
|
154
|
+
"#{base}#{base.include?("?") ? "&" : "?"}#{payload}"
|
152
155
|
end
|
153
156
|
|
154
157
|
def payload
|
155
158
|
payload = Base64.strict_encode64(unsigned_payload)
|
156
|
-
"sso=#{CGI
|
159
|
+
"sso=#{CGI.escape(payload)}&sig=#{sign(payload)}"
|
157
160
|
end
|
158
161
|
|
159
162
|
def unsigned_payload
|
@@ -164,11 +167,7 @@ module DiscourseApi
|
|
164
167
|
payload[k] = val
|
165
168
|
end
|
166
169
|
|
167
|
-
if @custom_fields
|
168
|
-
@custom_fields.each do |k, v|
|
169
|
-
payload["custom.#{k}"] = v.to_s
|
170
|
-
end
|
171
|
-
end
|
170
|
+
@custom_fields.each { |k, v| payload["custom.#{k}"] = v.to_s } if @custom_fields
|
172
171
|
|
173
172
|
Rack::Utils.build_query(payload)
|
174
173
|
end
|
@@ -1,20 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require
|
2
|
+
require "spec_helper"
|
3
3
|
|
4
4
|
describe DiscourseApi::API::ApiKey do
|
5
|
-
subject {
|
6
|
-
DiscourseApi::Client.new(
|
7
|
-
"#{host}",
|
8
|
-
"test_d7fd0429940",
|
9
|
-
"test_user"
|
10
|
-
)
|
11
|
-
}
|
5
|
+
subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
|
12
6
|
|
13
7
|
describe "#list_api_keys" do
|
14
8
|
before do
|
15
9
|
url = "#{host}/admin/api/keys"
|
16
|
-
stub_get(url).to_return(
|
17
|
-
|
10
|
+
stub_get(url).to_return(
|
11
|
+
body: fixture("list_api_keys.json"),
|
12
|
+
headers: {
|
13
|
+
content_type: "application/json",
|
14
|
+
},
|
15
|
+
)
|
18
16
|
end
|
19
17
|
|
20
18
|
it "requests the correct resource" do
|
@@ -27,35 +25,43 @@ describe DiscourseApi::API::ApiKey do
|
|
27
25
|
keys = subject.list_api_keys
|
28
26
|
expect(keys["keys"]).to be_an Array
|
29
27
|
expect(keys["keys"].first).to be_a Hash
|
30
|
-
expect(keys["keys"].first).to have_key(
|
28
|
+
expect(keys["keys"].first).to have_key("key")
|
31
29
|
end
|
32
30
|
end
|
33
31
|
|
34
32
|
describe "#create_api_key" do
|
35
33
|
before do
|
36
34
|
url = "#{host}/admin/api/keys"
|
37
|
-
stub_post(url).to_return(
|
38
|
-
|
35
|
+
stub_post(url).to_return(
|
36
|
+
body: fixture("api_key.json"),
|
37
|
+
headers: {
|
38
|
+
content_type: "application/json",
|
39
|
+
},
|
40
|
+
)
|
39
41
|
end
|
40
42
|
|
41
43
|
it "requests the correct resource" do
|
42
|
-
subject.create_api_key(key: { username:
|
44
|
+
subject.create_api_key(key: { username: "robin" })
|
43
45
|
url = "#{host}/admin/api/keys"
|
44
46
|
expect(a_post(url)).to have_been_made
|
45
47
|
end
|
46
48
|
|
47
49
|
it "returns the generated api key" do
|
48
|
-
api_key = subject.create_api_key(key: { username:
|
50
|
+
api_key = subject.create_api_key(key: { username: "robin" })
|
49
51
|
expect(api_key).to be_a Hash
|
50
|
-
expect(api_key[
|
52
|
+
expect(api_key["key"]).to have_key("key")
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
54
56
|
describe "#revoke_api_key" do
|
55
57
|
before do
|
56
58
|
url = "#{host}/admin/api/keys/10/revoke"
|
57
|
-
stub_post(url).to_return(
|
58
|
-
|
59
|
+
stub_post(url).to_return(
|
60
|
+
body: fixture("api_key.json"),
|
61
|
+
headers: {
|
62
|
+
content_type: "application/json",
|
63
|
+
},
|
64
|
+
)
|
59
65
|
end
|
60
66
|
|
61
67
|
it "requests the correct resource" do
|
@@ -66,15 +72,19 @@ describe DiscourseApi::API::ApiKey do
|
|
66
72
|
|
67
73
|
it "returns the api key" do
|
68
74
|
api_key = subject.revoke_api_key(10)
|
69
|
-
expect(api_key[
|
75
|
+
expect(api_key["key"]).to have_key("key")
|
70
76
|
end
|
71
77
|
end
|
72
78
|
|
73
79
|
describe "#undo_revoke_api_key" do
|
74
80
|
before do
|
75
81
|
url = "#{host}/admin/api/keys/10/undo-revoke"
|
76
|
-
stub_post(url).to_return(
|
77
|
-
|
82
|
+
stub_post(url).to_return(
|
83
|
+
body: fixture("api_key.json"),
|
84
|
+
headers: {
|
85
|
+
content_type: "application/json",
|
86
|
+
},
|
87
|
+
)
|
78
88
|
end
|
79
89
|
|
80
90
|
it "requests the correct resource" do
|
@@ -85,15 +95,19 @@ describe DiscourseApi::API::ApiKey do
|
|
85
95
|
|
86
96
|
it "returns the api key" do
|
87
97
|
api_key = subject.undo_revoke_api_key(10)
|
88
|
-
expect(api_key[
|
98
|
+
expect(api_key["key"]).to have_key("key")
|
89
99
|
end
|
90
100
|
end
|
91
101
|
|
92
102
|
describe "#delete_api_key" do
|
93
103
|
before do
|
94
104
|
url = "#{host}/admin/api/keys/10"
|
95
|
-
stub_delete(url).to_return(
|
96
|
-
|
105
|
+
stub_delete(url).to_return(
|
106
|
+
body: '{"success": "OK"}',
|
107
|
+
headers: {
|
108
|
+
content_type: "application/json",
|
109
|
+
},
|
110
|
+
)
|
97
111
|
end
|
98
112
|
|
99
113
|
it "requests the correct resource" do
|
@@ -104,7 +118,7 @@ describe DiscourseApi::API::ApiKey do
|
|
104
118
|
|
105
119
|
it "returns 200" do
|
106
120
|
response = subject.delete_api_key(10)
|
107
|
-
expect(response[
|
121
|
+
expect(response["status"]).to eq(200)
|
108
122
|
end
|
109
123
|
end
|
110
124
|
end
|
@@ -1,12 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require
|
2
|
+
require "spec_helper"
|
3
3
|
|
4
4
|
describe DiscourseApi::API::Backups do
|
5
5
|
subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
|
6
6
|
|
7
7
|
describe "#backups" do
|
8
8
|
before do
|
9
|
-
stub_get("#{host}/admin/backups.json").to_return(
|
9
|
+
stub_get("#{host}/admin/backups.json").to_return(
|
10
|
+
body: fixture("backups.json"),
|
11
|
+
headers: {
|
12
|
+
content_type: "application/json",
|
13
|
+
},
|
14
|
+
)
|
10
15
|
end
|
11
16
|
|
12
17
|
it "requests the correct resource" do
|
@@ -18,7 +23,7 @@ describe DiscourseApi::API::Backups do
|
|
18
23
|
backups = subject.backups
|
19
24
|
expect(backups).to be_an Array
|
20
25
|
expect(backups.first).to be_a Hash
|
21
|
-
expect(backups.first).to have_key(
|
26
|
+
expect(backups.first).to have_key("filename")
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|