discourse_api 0.39.0 → 0.41.0

Sign up to get free protection for your applications and to get access to all the features.
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
- }