discourse_api 0.43.0 → 0.46.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,7 @@ module DiscourseApi
3
3
  module API
4
4
  module Tags
5
5
  def show_tag(tag)
6
- response = get("/tags/#{tag}")
6
+ response = get("/tag/#{tag}")
7
7
  response[:body]
8
8
  end
9
9
  end
@@ -29,6 +29,11 @@ module DiscourseApi
29
29
  response[:body]['topic_list']['topics']
30
30
  end
31
31
 
32
+ def top_topics(params = {})
33
+ response = get("/top.json", params)
34
+ response[:body]['topic_list']['topics']
35
+ end
36
+
32
37
  def new_topics(params = {})
33
38
  response = get("/new.json", params)
34
39
  response[:body]['topic_list']['topics']
@@ -69,15 +74,45 @@ module DiscourseApi
69
74
  delete("/t/#{id}.json")
70
75
  end
71
76
 
72
- def topic_posts(topic_id, post_ids = [])
77
+ def topic_posts(topic_id, post_ids = [], params = {})
78
+ params = API.params(params)
79
+ .optional(:asc,
80
+ :filter,
81
+ :include_raw,
82
+ :include_suggested,
83
+ :post_number,
84
+ :username_filters,
85
+ )
86
+
73
87
  url = ["/t/#{topic_id}/posts.json"]
74
88
  if post_ids.count > 0
75
89
  url.push('?')
76
90
  url.push(post_ids.map { |id| "post_ids[]=#{id}" }.join('&'))
77
91
  end
78
- response = get(url.join)
92
+ response = get(url.join, params)
79
93
  response[:body]
80
94
  end
95
+
96
+ def change_owner(topic_id, params = {})
97
+ params = API.params(params)
98
+ .required(:username, :post_ids)
99
+
100
+ post("/t/#{topic_id}/change-owner.json", params)
101
+ end
102
+
103
+ def topic_set_user_notification_level(topic_id, params)
104
+ params = API.params(params)
105
+ .required(:notification_level)
106
+ post("/t/#{topic_id}/notifications", params)
107
+ end
108
+
109
+ def bookmark_topic(topic_id)
110
+ put("/t/#{topic_id}/bookmark.json")
111
+ end
112
+
113
+ def remove_topic_bookmark(topic_id)
114
+ put("/t/#{topic_id}/remove_bookmarks.json")
115
+ end
81
116
  end
82
117
  end
83
118
  end
@@ -52,7 +52,7 @@ module DiscourseApi
52
52
  def create_user(args)
53
53
  args = API.params(args)
54
54
  .required(:name, :email, :password, :username)
55
- .optional(:active, :staged, :user_fields)
55
+ .optional(:active, :approved, :staged, :user_fields)
56
56
  .to_h
57
57
  post("/users", args)
58
58
  end
@@ -29,7 +29,9 @@ module DiscourseApi
29
29
  class Client
30
30
  attr_accessor :api_key
31
31
  attr_accessor :basic_auth
32
- attr_reader :host, :api_username
32
+ attr_reader :host, :api_username, :timeout
33
+
34
+ DEFAULT_TIMEOUT = 30
33
35
 
34
36
  include DiscourseApi::API::Categories
35
37
  include DiscourseApi::API::Search
@@ -60,6 +62,11 @@ module DiscourseApi
60
62
  @use_relative = check_subdirectory(host)
61
63
  end
62
64
 
65
+ def timeout=(timeout)
66
+ @timeout = timeout
67
+ @connection.options.timeout = timeout if @connection
68
+ end
69
+
63
70
  def api_username=(api_username)
64
71
  @api_username = api_username
65
72
  @connection.headers['Api-Username'] = api_username unless @connection.nil?
@@ -68,6 +75,9 @@ module DiscourseApi
68
75
  def connection_options
69
76
  @connection_options ||= {
70
77
  url: @host,
78
+ request: {
79
+ timeout: @timeout || DEFAULT_TIMEOUT
80
+ },
71
81
  headers: {
72
82
  accept: 'application/json',
73
83
  user_agent: user_agent,
@@ -158,6 +168,8 @@ module DiscourseApi
158
168
  response.env
159
169
  rescue Faraday::ClientError, JSON::ParserError
160
170
  raise DiscourseApi::Error
171
+ rescue Faraday::ConnectionFailed
172
+ raise DiscourseApi::Timeout
161
173
  end
162
174
 
163
175
  def handle_error(response)
@@ -33,4 +33,7 @@ module DiscourseApi
33
33
 
34
34
  class TooManyRequests < DiscourseError
35
35
  end
36
+
37
+ class Timeout < DiscourseError
38
+ end
36
39
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module DiscourseApi
3
- VERSION = "0.43.0"
3
+ VERSION = "0.46.0"
4
4
  end
@@ -10,77 +10,101 @@ describe DiscourseApi::API::ApiKey do
10
10
  )
11
11
  }
12
12
 
13
- describe "#api" do
13
+ describe "#list_api_keys" do
14
14
  before do
15
- url = "#{host}/admin/api.json"
16
- stub_get(url).to_return(body: fixture("api.json"),
15
+ url = "#{host}/admin/api/keys"
16
+ stub_get(url).to_return(body: fixture("list_api_keys.json"),
17
17
  headers: { content_type: "application/json" })
18
18
  end
19
19
 
20
20
  it "requests the correct resource" do
21
- subject.api
22
- url = "#{host}/admin/api.json"
21
+ subject.list_api_keys
22
+ url = "#{host}/admin/api/keys"
23
23
  expect(a_get(url)).to have_been_made
24
24
  end
25
25
 
26
26
  it "returns the requested api keys" do
27
- api = subject.api
28
- expect(api).to be_an Array
29
- expect(api.first).to be_a Hash
30
- expect(api.first).to have_key('key')
27
+ keys = subject.list_api_keys
28
+ expect(keys["keys"]).to be_an Array
29
+ expect(keys["keys"].first).to be_a Hash
30
+ expect(keys["keys"].first).to have_key('key')
31
31
  end
32
32
  end
33
33
 
34
- describe "#generate_master_key" do
34
+ describe "#create_api_key" do
35
35
  before do
36
- url = "#{host}/admin/api/key"
37
- stub_post(url).to_return(body: fixture("generate_master_key.json"),
36
+ url = "#{host}/admin/api/keys"
37
+ stub_post(url).to_return(body: fixture("api_key.json"),
38
38
  headers: { content_type: "application/json" })
39
39
  end
40
40
 
41
- it "returns the generated master key" do
42
- master_key = subject.generate_master_key
43
- expect(master_key).to be_a Hash
44
- expect(master_key['api_key']).to have_key('key')
45
- expect(master_key['api_key']['user']).to eq(nil)
41
+ it "requests the correct resource" do
42
+ subject.create_api_key(key: { username: 'robin' })
43
+ url = "#{host}/admin/api/keys"
44
+ expect(a_post(url)).to have_been_made
45
+ end
46
+
47
+ it "returns the generated api key" do
48
+ api_key = subject.create_api_key(key: { username: 'robin' })
49
+ expect(api_key).to be_a Hash
50
+ expect(api_key['key']).to have_key('key')
46
51
  end
47
52
  end
48
53
 
49
54
  describe "#revoke_api_key" do
50
55
  before do
51
- url = "#{host}/admin/api/key?id=10"
52
- stub_delete(url).to_return(body: "",
53
- headers: { content_type: "application/json" })
56
+ url = "#{host}/admin/api/keys/10/revoke"
57
+ stub_post(url).to_return(body: fixture("api_key.json"),
58
+ headers: { content_type: "application/json" })
54
59
  end
55
60
 
56
61
  it "requests the correct resource" do
57
62
  subject.revoke_api_key(10)
58
- url = "#{host}/admin/api/key?id=10"
59
- expect(a_delete(url)).to have_been_made
63
+ url = "#{host}/admin/api/keys/10/revoke"
64
+ expect(a_post(url)).to have_been_made
60
65
  end
61
66
 
62
- it "returns 200" do
63
- response = subject.revoke_api_key(10)
64
- expect(response['status']).to eq(200)
67
+ it "returns the api key" do
68
+ api_key = subject.revoke_api_key(10)
69
+ expect(api_key['key']).to have_key('key')
65
70
  end
66
71
  end
67
72
 
68
- describe "#regenerate_api_key" do
73
+ describe "#undo_revoke_api_key" do
69
74
  before do
70
- url = "#{host}/admin/api/key"
71
- stub_put(url).to_return(body: fixture("regenerate_api_key.json"),
72
- headers: { content_type: "application/json" })
75
+ url = "#{host}/admin/api/keys/10/undo-revoke"
76
+ stub_post(url).to_return(body: fixture("api_key.json"),
77
+ headers: { content_type: "application/json" })
73
78
  end
74
79
 
75
80
  it "requests the correct resource" do
76
- subject.regenerate_api_key(10)
77
- url = "#{host}/admin/api/key"
78
- expect(a_put(url)).to have_been_made
81
+ subject.undo_revoke_api_key(10)
82
+ url = "#{host}/admin/api/keys/10/undo-revoke"
83
+ expect(a_post(url)).to have_been_made
79
84
  end
80
85
 
81
- it "returns the regenerated api key" do
82
- key = subject.regenerate_api_key(10)
83
- expect(key['api_key']).to have_key('key')
86
+ it "returns the api key" do
87
+ api_key = subject.undo_revoke_api_key(10)
88
+ expect(api_key['key']).to have_key('key')
89
+ end
90
+ end
91
+
92
+ describe "#delete_api_key" do
93
+ before do
94
+ url = "#{host}/admin/api/keys/10"
95
+ stub_delete(url).to_return(body: '{"success": "OK"}',
96
+ headers: { content_type: "application/json" })
97
+ end
98
+
99
+ it "requests the correct resource" do
100
+ subject.delete_api_key(10)
101
+ url = "#{host}/admin/api/keys/10"
102
+ expect(a_delete(url)).to have_been_made
103
+ end
104
+
105
+ it "returns 200" do
106
+ response = subject.delete_api_key(10)
107
+ expect(response['status']).to eq(200)
84
108
  end
85
109
  end
86
110
  end
@@ -28,6 +28,25 @@ describe DiscourseApi::API::Categories do
28
28
  end
29
29
  end
30
30
 
31
+ describe "#categories_full" do
32
+ before do
33
+ stub_get("#{host}/categories.json")
34
+ .to_return(body: fixture("categories.json"), headers: { content_type: "application/json" })
35
+ end
36
+
37
+ it "requests the correct resource" do
38
+ subject.categories
39
+ expect(a_get("#{host}/categories.json")).to have_been_made
40
+ end
41
+
42
+ it "returns the entire categories response" do
43
+ categories = subject.categories_full
44
+ expect(categories).to be_a Hash
45
+ expect(categories).to have_key 'category_list'
46
+ expect(categories).to have_key 'featured_users'
47
+ end
48
+ end
49
+
31
50
  describe '#category_latest_topics' do
32
51
  before do
33
52
  stub_get("#{host}/c/category-slug/l/latest.json")
@@ -40,6 +59,20 @@ describe DiscourseApi::API::Categories do
40
59
  end
41
60
  end
42
61
 
62
+ describe '#category_latest_topics_full' do
63
+ before do
64
+ stub_get("#{host}/c/category-slug/l/latest.json")
65
+ .to_return(body: fixture("category_latest_topics.json"), headers: { content_type: "application/json" })
66
+ end
67
+
68
+ it "returns the entire latest topics in a category response" do
69
+ latest_topics = subject.category_latest_topics_full(category_slug: 'category-slug')
70
+ expect(latest_topics).to be_a Hash
71
+ expect(latest_topics).to have_key 'topic_list'
72
+ expect(latest_topics).to have_key 'users'
73
+ end
74
+ end
75
+
43
76
  describe '#category_top_topics' do
44
77
  before do
45
78
  stub_get("#{host}/c/category-slug/l/top.json")
@@ -55,6 +88,23 @@ describe DiscourseApi::API::Categories do
55
88
  end
56
89
  end
57
90
 
91
+ describe '#category_top_topics_full' do
92
+ before do
93
+ stub_get("#{host}/c/category-slug/l/top.json")
94
+ .to_return(
95
+ body: fixture("category_topics.json"),
96
+ headers: { content_type: "application/json" }
97
+ )
98
+ end
99
+
100
+ it "returns the entire top topics in a category response" do
101
+ topics = subject.category_top_topics_full('category-slug')
102
+ expect(topics).to be_a Hash
103
+ expect(topics).to have_key 'topic_list'
104
+ expect(topics).to have_key 'users'
105
+ end
106
+ end
107
+
58
108
  describe '#category_new_topics' do
59
109
  before do
60
110
  stub_get("#{host}/c/category-slug/l/new.json")
@@ -70,6 +120,23 @@ describe DiscourseApi::API::Categories do
70
120
  end
71
121
  end
72
122
 
123
+ describe '#category_new_topics_full' do
124
+ before do
125
+ stub_get("#{host}/c/category-slug/l/new.json")
126
+ .to_return(
127
+ body: fixture("category_topics.json"),
128
+ headers: { content_type: "application/json" }
129
+ )
130
+ end
131
+
132
+ it "returns the new topics in a category" do
133
+ topics = subject.category_new_topics_full('category-slug')
134
+ expect(topics).to be_a Hash
135
+ expect(topics).to have_key 'topic_list'
136
+ expect(topics).to have_key 'users'
137
+ end
138
+ end
139
+
73
140
  describe '#category_new_category' do
74
141
  before do
75
142
  stub_post("#{host}/categories")
@@ -85,4 +152,27 @@ describe DiscourseApi::API::Categories do
85
152
  end
86
153
  end
87
154
 
155
+ describe "#category_set_user_notification" do
156
+ before do
157
+ stub_post("#{host}/category/1/notifications").to_return(body: fixture("notification_success.json"), headers: { content_type: "application/json" })
158
+ end
159
+
160
+ it "makes the post request" do
161
+ response = subject.category_set_user_notification(id: 1, notification_level: 3)
162
+ expect(a_post("#{host}/category/1/notifications")).to have_been_made
163
+ expect(response['success']).to eq('OK')
164
+ end
165
+ end
166
+
167
+ describe "#category_set_user_notification_level" do
168
+ before do
169
+ stub_post("#{host}/category/1/notifications").to_return(body: fixture("notification_success.json"), headers: { content_type: "application/json" })
170
+ end
171
+
172
+ it "makes the post request" do
173
+ response = subject.category_set_user_notification_level(1, notification_level: 3)
174
+ expect(a_post("#{host}/category/1/notifications").with(body: "notification_level=3")).to have_been_made
175
+ expect(response['success']).to eq('OK')
176
+ end
177
+ end
88
178
  end
@@ -6,12 +6,12 @@ describe DiscourseApi::API::Search do
6
6
 
7
7
  describe "#search" do
8
8
  before do
9
- stub_get("#{host}/search/query").with(query: { term: "test" }).to_return(body: fixture("search.json"), headers: { content_type: "application/json" })
9
+ stub_get("#{host}/search").with(query: { q: "test" }).to_return(body: fixture("search.json"), headers: { content_type: "application/json" })
10
10
  end
11
11
 
12
12
  it "requests the correct resource" do
13
13
  subject.search("test")
14
- expect(a_get("#{host}/search/query").with(query: { term: "test" })).to have_been_made
14
+ expect(a_get("#{host}/search").with(query: { q: "test" })).to have_been_made
15
15
  end
16
16
 
17
17
  it "returns the requested search" do
@@ -55,6 +55,29 @@ describe DiscourseApi::API::Topics do
55
55
  end
56
56
  end
57
57
 
58
+ describe "#top_topics" do
59
+ before do
60
+ stub_get("#{host}/top.json").to_return(body: fixture("top.json"), headers: { content_type: "application/json" })
61
+ end
62
+
63
+ it "requests the correct resource" do
64
+ subject.top_topics
65
+ expect(a_get("#{host}/top.json")).to have_been_made
66
+ end
67
+
68
+ it "returns the requested topics" do
69
+ topics = subject.top_topics
70
+ expect(topics).to be_an Array
71
+ expect(topics.first).to be_a Hash
72
+ end
73
+
74
+ it "can take a hash param" do
75
+ topics = subject.top_topics({})
76
+ expect(topics).to be_an Array
77
+ expect(topics.first).to be_a Hash
78
+ end
79
+ end
80
+
58
81
  describe "#new_topics" do
59
82
  before do
60
83
  stub_get("#{host}/new.json").to_return(body: fixture("new.json"), headers: { content_type: "application/json" })
@@ -147,6 +170,14 @@ describe DiscourseApi::API::Topics do
147
170
  expect(body['post_stream']['posts']).to be_an Array
148
171
  expect(body['post_stream']['posts'].first).to be_a Hash
149
172
  end
173
+
174
+ it "can retrieve a topic posts' raw attribute" do
175
+ body = subject.topic_posts(57, [123], { include_raw: true })
176
+ expect(body).to be_a Hash
177
+ expect(body['post_stream']['posts']).to be_an Array
178
+ expect(body['post_stream']['posts'].first).to be_a Hash
179
+ expect(body['post_stream']['posts'].first['raw']).to be_an Array
180
+ end
150
181
  end
151
182
 
152
183
  describe "#create_topic_with_tags" do
@@ -166,4 +197,39 @@ describe DiscourseApi::API::Topics do
166
197
  end
167
198
  end
168
199
 
200
+ describe "#topic_set_user_notification_level" do
201
+ before do
202
+ stub_post("#{host}/t/1/notifications").to_return(body: fixture("notification_success.json"), headers: { content_type: "application/json" })
203
+ end
204
+
205
+ it "makes the post request" do
206
+ response = subject.topic_set_user_notification_level(1, notification_level: 3)
207
+ expect(a_post("#{host}/t/1/notifications").with(body: "notification_level=3")).to have_been_made
208
+ expect(response['success']).to eq('OK')
209
+ end
210
+ end
211
+
212
+ describe "#bookmark_topic" do
213
+ before do
214
+ stub_put("#{host}/t/1/bookmark.json").to_return(body: "", headers: { content_type: "application/json" })
215
+ end
216
+
217
+ it "makes the put request" do
218
+ response = subject.bookmark_topic(1)
219
+ expect(a_put("#{host}/t/1/bookmark.json")).to have_been_made
220
+ expect(response.body).to eq(nil)
221
+ end
222
+ end
223
+
224
+ describe "#remove_topic_bookmark" do
225
+ before do
226
+ stub_put("#{host}/t/1/remove_bookmarks.json").to_return(body: "", headers: { content_type: "application/json" })
227
+ end
228
+
229
+ it "makes the put request" do
230
+ response = subject.remove_topic_bookmark(1)
231
+ expect(a_put("#{host}/t/1/remove_bookmarks.json")).to have_been_made
232
+ expect(response.body).to eq(nil)
233
+ end
234
+ end
169
235
  end