discourse_api 0.39.0 → 0.41.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +54 -0
  3. data/.gitignore +0 -2
  4. data/.rubocop.yml +2 -6
  5. data/CHANGELOG.md +30 -6
  6. data/README.md +13 -1
  7. data/discourse_api.gemspec +4 -6
  8. data/lib/discourse_api/api/api_key.rb +0 -8
  9. data/lib/discourse_api/api/categories.rb +9 -2
  10. data/lib/discourse_api/api/groups.rb +2 -0
  11. data/lib/discourse_api/api/sso.rb +1 -15
  12. data/lib/discourse_api/client.rb +16 -4
  13. data/lib/discourse_api/single_sign_on.rb +32 -3
  14. data/lib/discourse_api/version.rb +1 -1
  15. data/spec/discourse_api/api/api_key_spec.rb +2 -28
  16. data/spec/discourse_api/api/backups_spec.rb +2 -1
  17. data/spec/discourse_api/api/badges_spec.rb +2 -1
  18. data/spec/discourse_api/api/categories_spec.rb +9 -8
  19. data/spec/discourse_api/api/email_spec.rb +2 -1
  20. data/spec/discourse_api/api/groups_spec.rb +7 -6
  21. data/spec/discourse_api/api/notifications_spec.rb +1 -0
  22. data/spec/discourse_api/api/params_spec.rb +8 -7
  23. data/spec/discourse_api/api/polls_spec.rb +7 -6
  24. data/spec/discourse_api/api/posts_spec.rb +1 -0
  25. data/spec/discourse_api/api/private_messages_spec.rb +1 -0
  26. data/spec/discourse_api/api/search_spec.rb +4 -3
  27. data/spec/discourse_api/api/site_settings_spec.rb +2 -1
  28. data/spec/discourse_api/api/sso_spec.rb +46 -3
  29. data/spec/discourse_api/api/topics_spec.rb +1 -0
  30. data/spec/discourse_api/api/uploads_spec.rb +1 -0
  31. data/spec/discourse_api/api/user_actions_spec.rb +1 -0
  32. data/spec/discourse_api/api/users_spec.rb +4 -3
  33. data/spec/discourse_api/client_spec.rb +11 -10
  34. data/spec/spec_helper.rb +2 -1
  35. metadata +15 -45
  36. data/.travis.yml +0 -11
  37. data/spec/fixtures/generate_api_key.json +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 949fba1e4447d9615d8d3457b79328a866cfe61f325c3cd4f6a2cf3083ad9322
4
- data.tar.gz: 2cc4f93ec719eb99e0bbd02caeecc02c3ed36bcd33b4b6435b9cb56835e622ae
3
+ metadata.gz: e8e19227c879502b171c001c16ecef5ba35e1aa97db19430c30bf35cc7fe6bf0
4
+ data.tar.gz: 94571b5d801c0c89e18768bee1182f5d37114bb2e3b06e6665ace17e9acb001e
5
5
  SHA512:
6
- metadata.gz: 781247a4d7644d9f58609f221da038f8f59e58114ba2450c63c1ef8e7adfda029c775e8b58b0237220c76d3db1d95232249a6d04ff9138da2aa759eaa6938fa2
7
- data.tar.gz: 995b7de67aef36acab3ef778201032aa9c2e9c9762a02d80e6cfeeacccd8dac64c433fc5cda75bfca6fbbcade605ea3917fd6c92283253c7a79618b24d2b644d
6
+ metadata.gz: 32a0f6371f096dff33f1a71ab200d36824ca4a22f49500f7e06c5f245b53073215f3ae11b2410d11ca0a0a94c8d23546bb66faf48727c0bc241c689fd41795a6
7
+ data.tar.gz: 857e1f6535a4d1a49369101e351950f4c393b5f502f2dd7499874347b326b7731a761a97a6f0301b2b97cb64017bc5908bd7505642cb1c6e3524597299ab43fa
@@ -0,0 +1,54 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - master
8
+ tags:
9
+ - v*
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+
15
+ strategy:
16
+ matrix:
17
+ ruby:
18
+ - 2.5
19
+ - 2.6
20
+ - 2.7
21
+
22
+ steps:
23
+ - uses: actions/checkout@v1
24
+
25
+ - name: Setup ruby
26
+ uses: actions/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby }}
29
+ architecture: 'x64'
30
+
31
+ - name: Setup bundler
32
+ run: gem install bundler
33
+
34
+ - name: Setup gems
35
+ run: bundle install
36
+
37
+ - name: Rubocop
38
+ run: bundle exec rubocop
39
+
40
+ - name: RSpec
41
+ run: bundle exec rspec
42
+
43
+ publish:
44
+ if: contains(github.ref, 'refs/tags/v')
45
+ needs: build
46
+ runs-on: ubuntu-latest
47
+
48
+ steps:
49
+ - uses: actions/checkout@v2
50
+
51
+ - name: Release Gem
52
+ uses: CvX/publish-rubygems-action@master
53
+ env:
54
+ RUBYGEMS_API_KEY: ${{secrets.RUBYGEMS_API_KEY}}
data/.gitignore CHANGED
@@ -20,5 +20,3 @@ bin/
20
20
  .ruby-version
21
21
  .env
22
22
  /config.yml
23
-
24
- .rubocop-https---raw-githubusercontent-com-discourse-discourse-master--rubocop-yml
@@ -1,6 +1,2 @@
1
- inherit_from: https://raw.githubusercontent.com/discourse/discourse/master/.rubocop.yml
2
- AllCops:
3
- TargetRubyVersion: 2.4
4
- DisabledByDefault: true
5
- Exclude:
6
- - 'spec/**/**/*.rb'
1
+ inherit_gem:
2
+ rubocop-discourse: default.yml
@@ -2,6 +2,35 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [0.41.0] - 2020-06-17
6
+ ### Added
7
+ - Add basic auth support
8
+
9
+ ### Fixed
10
+ - Fix SSO custom field prefixes
11
+
12
+ ### Removed
13
+ - Obsolete api key endpoints
14
+
15
+ ## [0.40.0] - 2020-05-07
16
+ ### Fixed
17
+ - Add missing attributes to `sync_sso`
18
+
19
+ ### Added
20
+ - Add delete category method
21
+
22
+ ## [0.39.3] - 2020-04-30
23
+ ### Fixed
24
+ - Add `reviewable_by_group_name` to categories
25
+
26
+ ## [0.39.2] - 2020-04-30
27
+ ### Fixed
28
+ - Add `members_visibility_level` to group
29
+
30
+ ## [0.39.1] - 2020-03-27
31
+ ### Fixed
32
+ - Ensure released gem version matches this commit
33
+
5
34
  ## [0.39.0] - 2020-03-27
6
35
  ### Added
7
36
  - Get latest posts across topics via posts.json
@@ -205,7 +234,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
205
234
  ## [0.8.1] - 2016-03-03
206
235
  ### Fixed
207
236
  - enable use of discourse_api to make unauthenticated requests to discourse
208
- endpoints like /categories and /topics
237
+ endpoints like /categories and /topics
209
238
 
210
239
  ## [0.8.0] - 2016-02-28
211
240
  ### Added
@@ -262,8 +291,3 @@ This project adheres to [Semantic Versioning](http://semver.org/).
262
291
  ## [0.1.2] - 2014-05-11
263
292
 
264
293
  - Release
265
-
266
-
267
-
268
-
269
-
data/README.md CHANGED
@@ -52,7 +52,10 @@ client.sync_sso( #=> Synchronizes the SSO record
52
52
  name: "Test Name",
53
53
  username: "test_name",
54
54
  email: "name@example.com",
55
- external_id: "2"
55
+ external_id: "2",
56
+ custom_fields: {
57
+ field_1: 'potato'
58
+ }
56
59
  )
57
60
 
58
61
  # Private messages
@@ -80,6 +83,15 @@ end
80
83
 
81
84
  Check out [lib/discourse_api/error.rb](lib/discourse_api/error.rb) and [lib/discourse_api/client.rb](lib/discourse_api/client.rb)'s `handle_error` method for the types of errors raised by the API.
82
85
 
86
+ If your forum has a basic HTTP authentication enabled, set user and password:
87
+
88
+ ```ruby
89
+ client.basic_auth = {
90
+ user: "test",
91
+ password: "secret"
92
+ }
93
+ ```
94
+
83
95
  ## Contributing
84
96
 
85
97
  1. Fork it
@@ -18,21 +18,19 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'faraday', '~> 0.9'
22
- spec.add_dependency 'faraday_middleware', '~> 0.10'
21
+ spec.add_dependency 'faraday', '~> 1.0'
22
+ spec.add_dependency 'faraday_middleware', '~> 1.0'
23
23
  spec.add_dependency 'rack', '>= 1.6'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 2.0'
26
26
  spec.add_development_dependency 'guard', '~> 2.14'
27
27
  spec.add_development_dependency 'guard-rspec', '~> 4.7'
28
- spec.add_development_dependency 'rake', '~> 11.1'
28
+ spec.add_development_dependency 'rake', '>= 12.3.3'
29
29
  spec.add_development_dependency 'rb-inotify', '~> 0.9'
30
30
  spec.add_development_dependency 'rspec', '~> 3.4'
31
- spec.add_development_dependency 'rubocop', '~> 0.69'
32
31
  spec.add_development_dependency 'simplecov', '~> 0.11'
33
32
  spec.add_development_dependency 'webmock', '~> 2.0'
34
- spec.add_development_dependency 'rubocop-discourse', '~> 1.0'
35
- spec.add_development_dependency 'rubocop-rspec', '~> 1.0'
33
+ spec.add_development_dependency 'rubocop-discourse'
36
34
 
37
35
  spec.required_ruby_version = '>= 2.2.3'
38
36
  end
@@ -7,14 +7,6 @@ module DiscourseApi
7
7
  response.body
8
8
  end
9
9
 
10
- def generate_user_api_key(user_id)
11
- response = post("/admin/users/#{user_id}/generate_api_key.json")
12
- end
13
-
14
- def revoke_user_api_key(user_id)
15
- response = delete("/admin/users/#{user_id}/revoke_api_key.json")
16
- end
17
-
18
10
  def generate_master_key
19
11
  response = post("/admin/api/key")
20
12
  end
@@ -9,7 +9,8 @@ module DiscourseApi
9
9
  args = API.params(args)
10
10
  .required(:name, :color, :text_color)
11
11
  .optional(:slug, :permissions, :auto_close_hours, :auto_close_based_on_last_post, :position, :email_in,
12
- :email_in_allow_strangers, :logo_url, :background_url, :allow_badges, :topic_template, :custom_fields, :description)
12
+ :email_in_allow_strangers, :logo_url, :background_url, :allow_badges, :topic_template, :custom_fields, :description,
13
+ :reviewable_by_group_name, :show_subcategory_list, :subcategory_list_style)
13
14
  .default(parent_category_id: nil)
14
15
  response = post("/categories", args)
15
16
  response['category']
@@ -20,12 +21,18 @@ module DiscourseApi
20
21
  args = API.params(args)
21
22
  .required(:id, :name, :color, :text_color)
22
23
  .optional(:slug, :permissions, :auto_close_hours, :auto_close_based_on_last_post, :position, :email_in,
23
- :email_in_allow_strangers, :logo_url, :background_url, :allow_badges, :topic_template, :custom_fields, :description)
24
+ :email_in_allow_strangers, :logo_url, :background_url, :allow_badges, :topic_template, :custom_fields, :description,
25
+ :reviewable_by_group_name, :show_subcategory_list, :subcategory_list_style)
24
26
  .default(parent_category_id: nil)
25
27
  response = put("/categories/#{category_id}", args)
26
28
  response['body']['category'] if response['body']
27
29
  end
28
30
 
31
+ def delete_category(id)
32
+ response = delete("/categories/#{id}")
33
+ response[:body]['success']
34
+ end
35
+
29
36
  def categories(params = {})
30
37
  response = get('/categories.json', params)
31
38
  response[:body]['category_list']['categories']
@@ -18,6 +18,7 @@ module DiscourseApi
18
18
  :flair_bg_color,
19
19
  :flair_color,
20
20
  :bio_raw,
21
+ :members_visibility_level,
21
22
  :public_admission,
22
23
  :public_exit,
23
24
  :allow_membership_requests,
@@ -46,6 +47,7 @@ module DiscourseApi
46
47
  :flair_bg_color,
47
48
  :flair_color,
48
49
  :bio_raw,
50
+ :members_visibility_level,
49
51
  :public_admission,
50
52
  :public_exit,
51
53
  :allow_membership_requests,
@@ -3,21 +3,7 @@ module DiscourseApi
3
3
  module API
4
4
  module SSO
5
5
  def sync_sso(params = {})
6
- sso = DiscourseApi::SingleSignOn.new
7
- sso.sso_secret = params[:sso_secret]
8
- sso.name = params[:name]
9
- sso.username = params[:username]
10
- sso.email = params[:email]
11
- sso.external_id = params[:external_id]
12
- sso.suppress_welcome_message = params[:suppress_welcome_message] === true
13
- sso.avatar_url = params[:avatar_url]
14
- sso.title = params[:title]
15
- sso.avatar_force_update = params[:avatar_force_update] === true
16
- sso.add_groups = params[:add_groups]
17
- sso.remove_groups = params[:remove_groups]
18
- params.keys.select { |key| key.to_s.start_with?("custom") }.each do |custom_key|
19
- sso.custom_fields[custom_key] = params[custom_key]
20
- end
6
+ sso = DiscourseApi::SingleSignOn.parse_hash(params)
21
7
 
22
8
  post("/admin/users/sync_sso", sso.payload)
23
9
  end
@@ -28,6 +28,7 @@ require 'discourse_api/api/site_settings'
28
28
  module DiscourseApi
29
29
  class Client
30
30
  attr_accessor :api_key
31
+ attr_accessor :basic_auth
31
32
  attr_reader :host, :api_username
32
33
 
33
34
  include DiscourseApi::API::Categories
@@ -112,19 +113,30 @@ module DiscourseApi
112
113
 
113
114
  def connection
114
115
  @connection ||= Faraday.new connection_options do |conn|
115
- # Follow redirects
116
- conn.use FaradayMiddleware::FollowRedirects, limit: 5
117
116
  # Allow uploading of files
118
117
  conn.request :multipart
118
+
119
119
  # Convert request params to "www-form-encoded"
120
120
  conn.request :url_encoded
121
+
122
+ # Allow to interact with forums behind basic HTTP authentication
123
+ if basic_auth
124
+ conn.request :basic_auth, basic_auth[:user], basic_auth[:password]
125
+ end
126
+
127
+ # Follow redirects
128
+ conn.response :follow_redirects, limit: 5
129
+
121
130
  # Parse responses as JSON
122
- conn.use FaradayMiddleware::ParseJson, content_type: 'application/json'
131
+ conn.response :json, content_type: 'application/json'
132
+
123
133
  # For HTTP debugging, uncomment
124
134
  # conn.response :logger
135
+
125
136
  # Use Faraday's default HTTP adapter
126
137
  conn.adapter Faraday.default_adapter
127
- #pass api_key and api_username on every request
138
+
139
+ # Pass api_key and api_username on every request
128
140
  unless api_username.nil?
129
141
  conn.headers['Api-Key'] = api_key
130
142
  conn.headers['Api-Username'] = api_username
@@ -5,7 +5,7 @@ require 'openssl'
5
5
 
6
6
  module DiscourseApi
7
7
  class SingleSignOn
8
- ACCESSORS = [:nonce, :name, :username, :email, :avatar_url, :avatar_force_update, :require_activation,
8
+ ACCESSORS = [:nonce, :name, :username, :email, :avatar_url, :profile_background_url, :card_background_url, :avatar_force_update, :require_activation,
9
9
  :bio, :external_id, :return_sso_url, :admin, :moderator, :suppress_welcome_message, :title,
10
10
  :add_groups, :remove_groups, :groups, :locale, :locale_force_update]
11
11
  FIXNUMS = []
@@ -15,6 +15,7 @@ module DiscourseApi
15
15
  #NONCE_EXPIRY_TIME = 10.minutes # minutes is a rails method and is causing an error. Is this needed in the api?
16
16
 
17
17
  attr_accessor(*ACCESSORS)
18
+ attr_accessor :custom_fields
18
19
  attr_writer :sso_secret, :sso_url
19
20
 
20
21
  def self.sso_secret
@@ -25,6 +26,36 @@ module DiscourseApi
25
26
  raise RuntimeError, "sso_url not implemented on class, be sure to set it on instance"
26
27
  end
27
28
 
29
+ def self.parse_hash(payload)
30
+ payload
31
+ sso = new
32
+
33
+ sso.sso_secret = payload.delete(:sso_secret)
34
+ sso.sso_url = payload.delete(:sso_url)
35
+
36
+ ACCESSORS.each do |k|
37
+ val = payload[k]
38
+
39
+ val = val.to_i if FIXNUMS.include? k
40
+ if BOOLS.include? k
41
+ val = ["true", "false"].include?(val) ? val == "true" : nil
42
+ end
43
+ val = Array(val) if ARRAYS.include?(k) && !val.nil?
44
+ sso.send("#{k}=", val)
45
+ end
46
+ # Set custom_fields
47
+ sso.custom_fields = payload[:custom_fields]
48
+ # Add custom_fields (old format)
49
+ payload.each do |k, v|
50
+ if field = k[/^custom\.(.+)$/, 1]
51
+ # Maintain adding of .custom bug
52
+ sso.custom_fields["custom.#{field}"] = v
53
+ end
54
+ end
55
+
56
+ sso
57
+ end
58
+
28
59
  def self.parse(payload, sso_secret = nil)
29
60
  sso = new
30
61
  sso.sso_secret = sso_secret if sso_secret
@@ -107,7 +138,5 @@ module DiscourseApi
107
138
 
108
139
  Rack::Utils.build_query(payload)
109
140
  end
110
-
111
141
  end
112
-
113
142
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module DiscourseApi
3
- VERSION = "0.39.0"
3
+ VERSION = "0.41.0"
4
4
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::ApiKey do
@@ -30,33 +31,6 @@ describe DiscourseApi::API::ApiKey do
30
31
  end
31
32
  end
32
33
 
33
- describe "#generate_user_api_key" do
34
- before do
35
- url = "#{host}/admin/users/2/generate_api_key.json"
36
- stub_post(url).to_return(body: fixture("generate_api_key.json"),
37
- headers: { content_type: "application/json" })
38
- end
39
-
40
- it "returns the generated api key" do
41
- api_key = subject.generate_user_api_key(2)
42
- expect(api_key).to be_a Hash
43
- expect(api_key['api_key']).to have_key('key')
44
- end
45
- end
46
-
47
- describe "#revoke_user_api_key" do
48
- before do
49
- url = "#{host}/admin/users/2/revoke_api_key.json"
50
- stub_delete(url).to_return(body: "",
51
- headers: { content_type: "application/json" })
52
- end
53
-
54
- it "returns 200" do
55
- response = subject.revoke_user_api_key(2)
56
- expect(response['status']).to eq(200)
57
- end
58
- end
59
-
60
34
  describe "#generate_master_key" do
61
35
  before do
62
36
  url = "#{host}/admin/api/key"
@@ -95,7 +69,7 @@ describe DiscourseApi::API::ApiKey do
95
69
  before do
96
70
  url = "#{host}/admin/api/key"
97
71
  stub_put(url).to_return(body: fixture("regenerate_api_key.json"),
98
- headers: { content_type: "application/json" })
72
+ headers: { content_type: "application/json" })
99
73
  end
100
74
 
101
75
  it "requests the correct resource" do
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Backups do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#backups" do
7
8
  before do
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Badges do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#badges" do
7
8
  before do
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Categories do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#categories" do
7
8
  before do
@@ -42,8 +43,8 @@ describe DiscourseApi::API::Categories do
42
43
  describe '#category_top_topics' do
43
44
  before do
44
45
  stub_get("#{host}/c/category-slug/l/top.json")
45
- .to_return(
46
- body: fixture("category_topics.json"),
46
+ .to_return(
47
+ body: fixture("category_topics.json"),
47
48
  headers: { content_type: "application/json" }
48
49
  )
49
50
  end
@@ -57,8 +58,8 @@ describe DiscourseApi::API::Categories do
57
58
  describe '#category_new_topics' do
58
59
  before do
59
60
  stub_get("#{host}/c/category-slug/l/new.json")
60
- .to_return(
61
- body: fixture("category_topics.json"),
61
+ .to_return(
62
+ body: fixture("category_topics.json"),
62
63
  headers: { content_type: "application/json" }
63
64
  )
64
65
  end
@@ -74,14 +75,14 @@ describe DiscourseApi::API::Categories do
74
75
  stub_post("#{host}/categories")
75
76
  subject.create_category(name: "test_category", color: "283890", text_color: "FFFFFF",
76
77
  description: "This is a description",
77
- permissions: {"group_1" => 1, "admins" => 1})
78
+ permissions: { "group_1" => 1, "admins" => 1 })
78
79
  end
79
-
80
+
80
81
  it "makes a create category request" do
81
82
  expect(a_post("#{host}/categories").with(body:
82
83
  "color=283890&description=This+is+a+description&name=test_category&parent_category_id&permissions%5Badmins%5D=1&permissions%5Bgroup_1%5D=1&text_color=FFFFFF")
83
84
  ).to have_been_made
84
85
  end
85
- end
86
+ end
86
87
 
87
88
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Email do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#email_settings" do
7
8
  before do
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Groups do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#groups" do
7
8
  before do
@@ -51,28 +52,28 @@ describe DiscourseApi::API::Groups do
51
52
  it "adds a single member by username" do
52
53
  subject.group_add(123, username: "sam")
53
54
  expect(a_request(:put, "#{host}/admin/groups/123/members.json").
54
- with(body: {usernames: "sam"})
55
+ with(body: { usernames: "sam" })
55
56
  ).to have_been_made
56
57
  end
57
58
 
58
59
  it "adds an array of members by username" do
59
60
  subject.group_add(123, usernames: ["sam", "jeff"])
60
61
  expect(a_request(:put, "#{host}/admin/groups/123/members.json").
61
- with(body: {usernames: "sam,jeff"})
62
+ with(body: { usernames: "sam,jeff" })
62
63
  ).to have_been_made
63
64
  end
64
65
 
65
66
  it "adds a single member by user_id" do
66
67
  subject.group_add(123, user_id: 456)
67
68
  expect(a_request(:put, "#{host}/admin/groups/123/members.json").
68
- with(body: {user_ids: "456"})
69
+ with(body: { user_ids: "456" })
69
70
  ).to have_been_made
70
71
  end
71
72
 
72
73
  it "adds an array of members by user_id" do
73
74
  subject.group_add(123, user_id: [123, 456])
74
75
  expect(a_request(:put, "#{host}/admin/groups/123/members.json").
75
- with(body: {user_ids: "123,456"})
76
+ with(body: { user_ids: "123,456" })
76
77
  ).to have_been_made
77
78
  end
78
79
  end
@@ -122,7 +123,7 @@ describe DiscourseApi::API::Groups do
122
123
  it "updates user's notification level for group" do
123
124
  subject.group_set_user_notification_level("mygroup", 77, 3)
124
125
  expect(a_post("#{host}/groups/mygroup/notifications?user_id=77&notification_level=3"))
125
- .to have_been_made
126
+ .to have_been_made
126
127
  end
127
128
  end
128
129
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Notifications do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Params do
@@ -6,31 +7,31 @@ describe DiscourseApi::API::Params do
6
7
  end
7
8
 
8
9
  it "should raise on missing required params" do
9
- expect { params_for({o1: "test"}).to_h }.to raise_error(ArgumentError)
10
+ expect { params_for({ o1: "test" }).to_h }.to raise_error(ArgumentError)
10
11
  end
11
12
 
12
13
  it "should not raise when a required param is false" do
13
- expect { params_for({r1: false}).to_h }.not_to raise_error
14
+ expect { params_for({ r1: false }).to_h }.not_to raise_error
14
15
  end
15
16
 
16
17
  it "should not include optional params when not provided" do
17
- expect(params_for({r1: "test"}).to_h).not_to include(:o1)
18
+ expect(params_for({ r1: "test" }).to_h).not_to include(:o1)
18
19
  end
19
20
 
20
21
  it "should include optional params if provided but blank" do
21
- expect(params_for({r1: "test", o2: nil}).to_h).to include(:o2)
22
+ expect(params_for({ r1: "test", o2: nil }).to_h).to include(:o2)
22
23
  end
23
24
 
24
25
  it "should include default params when defined but not provided" do
25
- expect(params_for({r1: "test"}).to_h).to include(d1: "default")
26
+ expect(params_for({ r1: "test" }).to_h).to include(d1: "default")
26
27
  end
27
28
 
28
29
  it "should include default params when defined and provided" do
29
- expect(params_for({r1: "test", d1: "override"}).to_h).to include(d1: "override")
30
+ expect(params_for({ r1: "test", d1: "override" }).to_h).to include(d1: "override")
30
31
  end
31
32
 
32
33
  it "should include optional and default params when defined and provided" do
33
- expect(params_for({r1: "test", o1: "optional", d1: "override"}).to_h).to include(o1: "optional", d1: "override")
34
+ expect(params_for({ r1: "test", o1: "optional", d1: "override" }).to_h).to include(o1: "optional", d1: "override")
34
35
  end
35
36
 
36
37
  end
@@ -1,14 +1,15 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Polls do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#poll vote" do
7
8
  before do
8
9
  path = "#{host}/polls/vote"
9
10
  stub_put(path)
10
- .to_return(body: fixture("polls_vote.json"), headers: { content_type: "application/json" })
11
-
11
+ .to_return(body: fixture("polls_vote.json"), headers: { content_type: "application/json" })
12
+
12
13
  end
13
14
 
14
15
  it "requests the correct resource" do
@@ -29,7 +30,7 @@ describe DiscourseApi::API::Polls do
29
30
  before do
30
31
  path = "#{host}/polls/toggle_status"
31
32
  stub_put(path)
32
- .to_return(body: fixture("polls_toggle_status.json"), headers: { content_type: "application/json" })
33
+ .to_return(body: fixture("polls_toggle_status.json"), headers: { content_type: "application/json" })
33
34
 
34
35
  end
35
36
 
@@ -49,7 +50,7 @@ describe DiscourseApi::API::Polls do
49
50
  describe "#poll voters" do
50
51
  before do
51
52
  stub_get("#{host}/polls/voters.json?post_id=5&poll_name=poll")
52
- .to_return(body: fixture("polls_voters.json"), headers: { content_type: "application/json" })
53
+ .to_return(body: fixture("polls_voters.json"), headers: { content_type: "application/json" })
53
54
  end
54
55
 
55
56
  it "requests the correct resource" do
@@ -64,7 +65,7 @@ describe DiscourseApi::API::Polls do
64
65
  expect(voters['voters']['e539a9df8700d0d05c69356a07b768cf']).to be_an Array
65
66
  expect(voters['voters']['e539a9df8700d0d05c69356a07b768cf'][0]['id']).to eq(356)
66
67
  end
67
- end
68
+ end
68
69
 
69
70
  end
70
71
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Posts do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::PrivateMessages do
@@ -1,16 +1,17 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Search do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#search" do
7
8
  before do
8
- 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/query").with(query: { term: "test" }).to_return(body: fixture("search.json"), headers: { content_type: "application/json" })
9
10
  end
10
11
 
11
12
  it "requests the correct resource" do
12
13
  subject.search("test")
13
- expect(a_get("#{host}/search/query").with(query: { term: "test"} )).to have_been_made
14
+ expect(a_get("#{host}/search/query").with(query: { term: "test" })).to have_been_made
14
15
  end
15
16
 
16
17
  it "returns the requested search" do
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::SiteSettings do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
5
6
 
6
7
  describe "#site_setting_update" do
7
8
  before do
@@ -1,15 +1,58 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::SSO do
4
- subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user" )}
5
+ subject { DiscourseApi::Client.new("#{host}", "test_d7fd0429940", "test_user") }
6
+
7
+ let(:params) do
8
+ {
9
+ sso_secret: 'abc',
10
+ sso_url: 'www.google.com',
11
+ name: 'Some User',
12
+ username: 'some_user',
13
+ email: 'some@email.com',
14
+ external_id: 'abc',
15
+ suppress_welcome_message: false,
16
+ avatar_url: 'https://www.website.com',
17
+ title: 'ruby',
18
+ avatar_force_update: false,
19
+ add_groups: ['a', 'b'],
20
+ remove_groups: ['c', 'd'],
21
+ # old format (which results in custom.custom.field_1 in unsigned_payload)
22
+ 'custom.field_1' => 'tomato',
23
+ # new format
24
+ custom_fields: {
25
+ field_2: 'potato'
26
+ }
27
+ }
28
+ end
29
+ let(:expected_unsigned_payload) do
30
+ 'name=Some+User&username=some_user&email=some%40email.com&'\
31
+ 'avatar_url=https%3A%2F%2Fwww.website.com&external_id=abc&title=ruby'\
32
+ '&add_groups=a&add_groups=b&remove_groups=c&remove_groups=d&custom.field_2=potato&'\
33
+ 'custom.custom.field_1=tomato'
34
+ end
35
+ let(:sso_double) { DiscourseApi::SingleSignOn.parse_hash(params) }
5
36
 
6
37
  describe "#sync_sso" do
7
38
  before do
8
- stub_post(/.*sync_sso.*/).to_return(body: fixture("user.json"), headers: { content_type: "application/json" })
39
+ stub_post(/.*sync_sso.*/).to_return(
40
+ body: fixture("user.json"),
41
+ headers: { content_type: "application/json" }
42
+ )
43
+ end
44
+
45
+ it 'assigns params to sso instance' do
46
+ allow(DiscourseApi::SingleSignOn).to(receive(:parse_hash).with(params).and_return(sso_double))
47
+
48
+ subject.sync_sso(params)
49
+
50
+ expect(sso_double.custom_fields).to eql({ 'custom.field_1' => 'tomato', :field_2 => 'potato' })
51
+ expect(sso_double.unsigned_payload).to eql(expected_unsigned_payload)
9
52
  end
10
53
 
11
54
  it "requests the correct resource" do
12
- subject.sync_sso({sso_secret: "test_d7fd0429940", "custom.riffle_url" => "test"})
55
+ subject.sync_sso({ sso_secret: "test_d7fd0429940", "custom.riffle_url" => "test" })
13
56
  expect(a_post(/.*sync_sso.*/)).to have_been_made
14
57
  end
15
58
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Topics do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Uploads do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::UserActions do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::API::Users do
@@ -113,12 +114,12 @@ describe DiscourseApi::API::Users do
113
114
  end
114
115
 
115
116
  it "makes the post request" do
116
- subject.create_user :name => "Test User", :email => "test2@example.com", :password => "P@ssword", :username => "test2"
117
+ subject.create_user name: "Test User", email: "test2@example.com", password: "P@ssword", username: "test2"
117
118
  expect(a_post("#{host}/users")).to have_been_made
118
119
  end
119
120
 
120
121
  it "returns success" do
121
- response = subject.create_user :name => "Test User", :email => "test2@example.com", :password => "P@ssword", :username => "test2"
122
+ response = subject.create_user name: "Test User", email: "test2@example.com", password: "P@ssword", username: "test2"
122
123
  expect(response).to be_a Hash
123
124
  expect(response['success']).to be_truthy
124
125
  end
@@ -163,7 +164,7 @@ describe DiscourseApi::API::Users do
163
164
  end
164
165
 
165
166
  it "Raises API Error" do
166
- expect{subject.log_out(90)}.to raise_error DiscourseApi::NotFoundError
167
+ expect { subject.log_out(90) }.to raise_error DiscourseApi::NotFoundError
167
168
  end
168
169
  end
169
170
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe DiscourseApi::Client do
@@ -90,26 +91,26 @@ describe DiscourseApi::Client do
90
91
 
91
92
  describe "#post" do
92
93
  before do
93
- stub_post("#{host}/test/post").with(body: { created: "object"})
94
+ stub_post("#{host}/test/post").with(body: { created: "object" })
94
95
  subject.api_key = 'test_d7fd0429940'
95
96
  subject.api_username = 'test_user'
96
97
  end
97
98
 
98
99
  it "allows custom post requests" do
99
100
  subject.post("/test/post", { created: "object" })
100
- expect(a_post("#{host}/test/post").with(body: { created: "object"})).to have_been_made
101
+ expect(a_post("#{host}/test/post").with(body: { created: "object" })).to have_been_made
101
102
  end
102
103
 
103
104
  context 'when using a host with a subdirectory' do
104
105
  subject { DiscourseApi::Client.new("#{host}/forum") }
105
106
 
106
107
  before do
107
- stub_post("#{host}/forum/test/post").with(body: { created: "object"})
108
+ stub_post("#{host}/forum/test/post").with(body: { created: "object" })
108
109
  end
109
110
 
110
111
  it "allows custom post requests" do
111
112
  subject.post("/test/post", { created: "object" })
112
- expect(a_post("#{host}/forum/test/post").with(body: { created: "object"})).to have_been_made
113
+ expect(a_post("#{host}/forum/test/post").with(body: { created: "object" })).to have_been_made
113
114
  end
114
115
  end
115
116
  end
@@ -144,18 +145,18 @@ describe DiscourseApi::Client do
144
145
  it "catches 500 errors" do
145
146
  connection = instance_double(Faraday::Connection)
146
147
  allow(connection).to receive(:get).and_return(OpenStruct.new(env: { body: 'error page html' }, status: 500))
147
- allow(subject).to receive(:connection).and_return(connection)
148
- expect{subject.send(:request, :get, "/test")}.to raise_error DiscourseApi::Error
148
+ allow(Faraday).to receive(:new).and_return(connection)
149
+ expect { subject.send(:request, :get, "/test") }.to raise_error DiscourseApi::Error
149
150
  end
150
151
 
151
152
  it "catches Faraday errors" do
152
- allow(subject).to receive(:connection).and_raise(Faraday::ClientError.new("BOOM!"))
153
- expect{subject.send(:request, :get, "/test")}.to raise_error DiscourseApi::Error
153
+ allow(Faraday).to receive(:new).and_raise(Faraday::ClientError.new("BOOM!"))
154
+ expect { subject.send(:request, :get, "/test") }.to raise_error DiscourseApi::Error
154
155
  end
155
156
 
156
157
  it "catches JSON::ParserError errors" do
157
- allow(subject).to receive(:connection).and_raise(JSON::ParserError.new("unexpected token"))
158
- expect{subject.send(:request, :get, "/test")}.to raise_error DiscourseApi::Error
158
+ allow(Faraday).to receive(:new).and_raise(JSON::ParserError.new("unexpected token"))
159
+ expect { subject.send(:request, :get, "/test") }.to raise_error DiscourseApi::Error
159
160
  end
160
161
  end
161
162
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'simplecov'
2
3
 
3
4
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
@@ -18,7 +19,7 @@ RSpec.configure do |config|
18
19
  end
19
20
  end
20
21
 
21
- WebMock.disable_net_connect!(:allow_localhost => true)
22
+ WebMock.disable_net_connect!(allow_localhost: true)
22
23
 
23
24
  def host
24
25
  'http://localhost:3000'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: discourse_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.0
4
+ version: 0.41.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2020-03-27 00:00:00.000000000 Z
14
+ date: 2020-06-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: faraday
@@ -19,28 +19,28 @@ dependencies:
19
19
  requirements:
20
20
  - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: '0.9'
22
+ version: '1.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '0.9'
29
+ version: '1.0'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: faraday_middleware
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - "~>"
35
35
  - !ruby/object:Gem::Version
36
- version: '0.10'
36
+ version: '1.0'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: '0.10'
43
+ version: '1.0'
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: rack
46
46
  requirement: !ruby/object:Gem::Requirement
@@ -101,16 +101,16 @@ dependencies:
101
101
  name: rake
102
102
  requirement: !ruby/object:Gem::Requirement
103
103
  requirements:
104
- - - "~>"
104
+ - - ">="
105
105
  - !ruby/object:Gem::Version
106
- version: '11.1'
106
+ version: 12.3.3
107
107
  type: :development
108
108
  prerelease: false
109
109
  version_requirements: !ruby/object:Gem::Requirement
110
110
  requirements:
111
- - - "~>"
111
+ - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: '11.1'
113
+ version: 12.3.3
114
114
  - !ruby/object:Gem::Dependency
115
115
  name: rb-inotify
116
116
  requirement: !ruby/object:Gem::Requirement
@@ -139,20 +139,6 @@ dependencies:
139
139
  - - "~>"
140
140
  - !ruby/object:Gem::Version
141
141
  version: '3.4'
142
- - !ruby/object:Gem::Dependency
143
- name: rubocop
144
- requirement: !ruby/object:Gem::Requirement
145
- requirements:
146
- - - "~>"
147
- - !ruby/object:Gem::Version
148
- version: '0.69'
149
- type: :development
150
- prerelease: false
151
- version_requirements: !ruby/object:Gem::Requirement
152
- requirements:
153
- - - "~>"
154
- - !ruby/object:Gem::Version
155
- version: '0.69'
156
142
  - !ruby/object:Gem::Dependency
157
143
  name: simplecov
158
144
  requirement: !ruby/object:Gem::Requirement
@@ -185,30 +171,16 @@ dependencies:
185
171
  name: rubocop-discourse
186
172
  requirement: !ruby/object:Gem::Requirement
187
173
  requirements:
188
- - - "~>"
189
- - !ruby/object:Gem::Version
190
- version: '1.0'
191
- type: :development
192
- prerelease: false
193
- version_requirements: !ruby/object:Gem::Requirement
194
- requirements:
195
- - - "~>"
196
- - !ruby/object:Gem::Version
197
- version: '1.0'
198
- - !ruby/object:Gem::Dependency
199
- name: rubocop-rspec
200
- requirement: !ruby/object:Gem::Requirement
201
- requirements:
202
- - - "~>"
174
+ - - ">="
203
175
  - !ruby/object:Gem::Version
204
- version: '1.0'
176
+ version: '0'
205
177
  type: :development
206
178
  prerelease: false
207
179
  version_requirements: !ruby/object:Gem::Requirement
208
180
  requirements:
209
- - - "~>"
181
+ - - ">="
210
182
  - !ruby/object:Gem::Version
211
- version: '1.0'
183
+ version: '0'
212
184
  description: Discourse API
213
185
  email:
214
186
  - sam.saffron@gmail.com
@@ -219,9 +191,9 @@ executables: []
219
191
  extensions: []
220
192
  extra_rdoc_files: []
221
193
  files:
194
+ - ".github/workflows/ci.yml"
222
195
  - ".gitignore"
223
196
  - ".rubocop.yml"
224
- - ".travis.yml"
225
197
  - CHANGELOG.md
226
198
  - Gemfile
227
199
  - Guardfile
@@ -307,7 +279,6 @@ files:
307
279
  - spec/fixtures/category_topics.json
308
280
  - spec/fixtures/email_list_all.json
309
281
  - spec/fixtures/email_settings.json
310
- - spec/fixtures/generate_api_key.json
311
282
  - spec/fixtures/generate_master_key.json
312
283
  - spec/fixtures/group.json
313
284
  - spec/fixtures/groups.json
@@ -401,7 +372,6 @@ test_files:
401
372
  - spec/fixtures/category_topics.json
402
373
  - spec/fixtures/email_list_all.json
403
374
  - spec/fixtures/email_settings.json
404
- - spec/fixtures/generate_api_key.json
405
375
  - spec/fixtures/generate_master_key.json
406
376
  - spec/fixtures/group.json
407
377
  - spec/fixtures/groups.json
@@ -1,11 +0,0 @@
1
- language: 'ruby'
2
-
3
- before_install:
4
- - 'gem update --system'
5
- - 'gem install bundler'
6
-
7
- rvm:
8
- - '2.5.5'
9
- - '2.6.2'
10
-
11
- script: 'bundle exec rake'
@@ -1,12 +0,0 @@
1
- {
2
- "api_key": {
3
- "id": 5,
4
- "key": "e722e04df8cf6d097d565ca04eea1ff8e9e8f09beb405bae6f0c79852916f334",
5
- "user": {
6
- "id": 2,
7
- "username": "robin",
8
- "uploaded_avatar_id": 3,
9
- "avatar_template": "/user_avatar/localhost/robin/{size}/3.png"
10
- }
11
- }
12
- }