zoom_rb 1.1.0 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1daca097d96a5590a12307f6fb353a613e8c74ae5c0a0ab93fde738fcd3518b
4
- data.tar.gz: 33bbfbb55bb2343c296cddfd92906b799fd57ded467f7755e836971b58f675ad
3
+ metadata.gz: 891b312a2bfaf07b88b453c90875e5611d81c75ddf62fe0874712d624f5defdb
4
+ data.tar.gz: 90ea1015c081c3607f44c7693bd31f9e64ee118b09bf0b7099e46ef89564c177
5
5
  SHA512:
6
- metadata.gz: 3c02b9b0964774320e19da1a8269e864c012b86ea32e4383d1e69618dc6d6a2e927fb263782009c199a57003c3b11b6c928b3d5945a955df8aaf4050fabd0721
7
- data.tar.gz: a5b0c0c8ae5d8c59e30967a4b48e1372dccd0642dd90a5bc8551b917b0a91f8a912dfe2a4c056caae6659ac477812cfd79b745659ac361b63649edbc2a163c86
6
+ metadata.gz: cbeb2d5bdcf4b16bc581679f12044301f1cc18e533bcf97a97b6d63002123e71f798098f582305f7a5948862f896e7e4fa8bfe9fac7270e540567912a2c48426
7
+ data.tar.gz: 2d853dab47d2ee2df3b0f431db12ec88f1e4b7f8c1656f2ccf811adedf08a98dde36c7b52a6e7b892262549844e44cedf9511c733aaaba5fb081fa578650062b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ # 1.1.2
2
+
3
+ ### New Features
4
+
5
+ * Add ServerToServer OAuth client [#423](https://github.com/hintmedia/zoom_rb/pull/423)
6
+
7
+ ### Fixes
8
+
9
+ * Webinar Settings API permits `language_interpretation` key/values [#424](https://github.com/hintmedia/zoom_rb/pull/424)
10
+ * Check if response is a `Hash` [#421](https://github.com/hintmedia/zoom_rb/pull/421)
11
+
12
+
13
+ # 1.1.1
14
+
15
+ ### Fixes
16
+ * Use correct "question_and_answer" API spec
17
+ * Raise a `Zoom::Error` exception when HTTP status is at or above 400
18
+ * Avoid SimpleCov error by making the gemspec permissive to newer versions
19
+
1
20
  # 1.1.0
2
21
 
3
22
  ### New features
data/Gemfile.lock CHANGED
@@ -1,20 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zoom_rb (1.1.0)
5
- httparty (~> 0.13)
4
+ zoom_rb (1.1.3)
5
+ httparty (>= 0.13)
6
6
  json (>= 1.8)
7
7
  jwt
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (6.1.4)
12
+ activesupport (7.0.2.2)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 1.6, < 2)
15
15
  minitest (>= 5.1)
16
16
  tzinfo (~> 2.0)
17
- zeitwerk (~> 2.3)
18
17
  addressable (2.8.0)
19
18
  public_suffix (>= 2.0.2, < 5.0)
20
19
  ast (2.4.2)
@@ -23,7 +22,7 @@ GEM
23
22
  concurrent-ruby (1.1.9)
24
23
  crack (0.4.5)
25
24
  rexml
26
- diff-lcs (1.4.4)
25
+ diff-lcs (1.5.0)
27
26
  docile (1.4.0)
28
27
  hashdiff (1.0.1)
29
28
  hint-rubocop_style (0.3.6)
@@ -34,18 +33,18 @@ GEM
34
33
  httparty (0.20.0)
35
34
  mime-types (~> 3.0)
36
35
  multi_xml (>= 0.5.2)
37
- i18n (1.8.10)
36
+ i18n (1.10.0)
38
37
  concurrent-ruby (~> 1.0)
39
- json (2.5.1)
38
+ json (2.6.1)
40
39
  jwt (2.3.0)
41
40
  method_source (1.0.0)
42
41
  mime-types (3.4.1)
43
42
  mime-types-data (~> 3.2015)
44
43
  mime-types-data (3.2022.0105)
45
- minitest (5.14.4)
44
+ minitest (5.15.0)
46
45
  multi_xml (0.6.0)
47
- parallel (1.20.1)
48
- parser (3.0.2.0)
46
+ parallel (1.21.0)
47
+ parser (3.1.1.0)
49
48
  ast (~> 2.4.1)
50
49
  pry (0.13.1)
51
50
  coderay (~> 1.1)
@@ -55,71 +54,70 @@ GEM
55
54
  pry (~> 0.13.0)
56
55
  public_suffix (4.0.6)
57
56
  rack (2.2.3)
58
- rainbow (3.0.0)
59
- regexp_parser (2.1.1)
57
+ rainbow (3.1.1)
58
+ regexp_parser (2.2.1)
60
59
  rexml (3.2.5)
61
- rspec (3.10.0)
62
- rspec-core (~> 3.10.0)
63
- rspec-expectations (~> 3.10.0)
64
- rspec-mocks (~> 3.10.0)
65
- rspec-core (3.10.1)
66
- rspec-support (~> 3.10.0)
67
- rspec-expectations (3.10.1)
60
+ rspec (3.11.0)
61
+ rspec-core (~> 3.11.0)
62
+ rspec-expectations (~> 3.11.0)
63
+ rspec-mocks (~> 3.11.0)
64
+ rspec-core (3.11.0)
65
+ rspec-support (~> 3.11.0)
66
+ rspec-expectations (3.11.0)
68
67
  diff-lcs (>= 1.2.0, < 2.0)
69
- rspec-support (~> 3.10.0)
70
- rspec-mocks (3.10.2)
68
+ rspec-support (~> 3.11.0)
69
+ rspec-mocks (3.11.0)
71
70
  diff-lcs (>= 1.2.0, < 2.0)
72
- rspec-support (~> 3.10.0)
73
- rspec-support (3.10.2)
74
- rspec_junit_formatter (0.4.1)
71
+ rspec-support (~> 3.11.0)
72
+ rspec-support (3.11.0)
73
+ rspec_junit_formatter (0.5.1)
75
74
  rspec-core (>= 2, < 4, != 2.12.0)
76
- rubocop (1.18.3)
75
+ rubocop (1.25.1)
77
76
  parallel (~> 1.10)
78
- parser (>= 3.0.0.0)
77
+ parser (>= 3.1.0.0)
79
78
  rainbow (>= 2.2.2, < 4.0)
80
79
  regexp_parser (>= 1.8, < 3.0)
81
80
  rexml
82
- rubocop-ast (>= 1.7.0, < 2.0)
81
+ rubocop-ast (>= 1.15.1, < 2.0)
83
82
  ruby-progressbar (~> 1.7)
84
83
  unicode-display_width (>= 1.4.0, < 3.0)
85
- rubocop-ast (1.8.0)
86
- parser (>= 3.0.1.1)
87
- rubocop-performance (1.11.4)
84
+ rubocop-ast (1.16.0)
85
+ parser (>= 3.1.1.0)
86
+ rubocop-performance (1.13.2)
88
87
  rubocop (>= 1.7.0, < 2.0)
89
88
  rubocop-ast (>= 0.4.0)
90
- rubocop-rails (2.11.3)
89
+ rubocop-rails (2.13.2)
91
90
  activesupport (>= 4.2.0)
92
91
  rack (>= 1.1)
93
92
  rubocop (>= 1.7.0, < 2.0)
94
- rubocop-rspec (2.4.0)
95
- rubocop (~> 1.0)
96
- rubocop-ast (>= 1.1.0)
93
+ rubocop-rspec (2.8.0)
94
+ rubocop (~> 1.19)
97
95
  ruby-progressbar (1.11.0)
98
- simplecov (0.16.1)
96
+ simplecov (0.21.2)
99
97
  docile (~> 1.1)
100
- json (>= 1.8, < 3)
101
- simplecov-html (~> 0.10.0)
102
- simplecov-html (0.10.2)
98
+ simplecov-html (~> 0.11)
99
+ simplecov_json_formatter (~> 0.1)
100
+ simplecov-html (0.12.3)
101
+ simplecov_json_formatter (0.1.4)
103
102
  tzinfo (2.0.4)
104
103
  concurrent-ruby (~> 1.0)
105
- unicode-display_width (2.0.0)
106
- webmock (3.13.0)
107
- addressable (>= 2.3.6)
104
+ unicode-display_width (2.1.0)
105
+ webmock (3.14.0)
106
+ addressable (>= 2.8.0)
108
107
  crack (>= 0.3.2)
109
108
  hashdiff (>= 0.4.0, < 2.0.0)
110
- zeitwerk (2.4.2)
111
109
 
112
110
  PLATFORMS
113
111
  ruby
114
112
 
115
113
  DEPENDENCIES
116
- hint-rubocop_style (~> 0)
114
+ hint-rubocop_style
117
115
  pry-byebug
118
- rspec (~> 3.8)
119
- rspec_junit_formatter (~> 0.4.1)
120
- simplecov (~> 0.16.1)
121
- webmock (~> 3.4)
116
+ rspec (>= 3.8)
117
+ rspec_junit_formatter (>= 0.4.1)
118
+ simplecov (>= 0.16.1)
119
+ webmock (>= 3.4)
122
120
  zoom_rb!
123
121
 
124
122
  BUNDLED WITH
125
- 2.2.32
123
+ 2.3.8
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -12,6 +12,11 @@ module Zoom
12
12
  permit: :code_verifier,
13
13
  args_to_params: { auth_code: :code }
14
14
 
15
+ post 'access_tokens_account_credentials',
16
+ '/oauth/token?grant_type=account_credentials',
17
+ oauth: true,
18
+ require: :account_id
19
+
15
20
  post 'refresh_tokens',
16
21
  '/oauth/token',
17
22
  oauth: true,
@@ -6,16 +6,30 @@ module Zoom
6
6
  extend Zoom::Actions
7
7
 
8
8
  RECURRENCE_KEYS = %i[type repeat_interval weekly_days monthly_day monthly_week
9
- monthly_week_day end_times end_date_time].freeze
10
- SETTINGS_KEYS = %i[host_video panelists_video practice_session hd_video approval_type
11
- registration_type audio auto_recording enforce_login
12
- enforce_login_domains alternative_hosts close_registration
13
- show_share_button allow_multiple_devices on_demand
14
- request_permission_to_unmute_participants global_dial_in_countries
15
- contact_name contact_email registrants_restrict_number
16
- post_webinar_survey survey_url registrants_email_notification
17
- meeting_authentication authentication_option
18
- authentication_domains registrants_confirmation_email question_answer].freeze
9
+ monthly_week_day end_times end_date_time].freeze
10
+ SETTINGS_KEYS = [
11
+ %i[
12
+ host_video panelists_video practice_session hd_video approval_type
13
+ registration_type audio auto_recording enforce_login
14
+ enforce_login_domains alternative_hosts close_registration
15
+ show_share_button allow_multiple_devices on_demand
16
+ request_permission_to_unmute_participants global_dial_in_countries
17
+ contact_name contact_email registrants_restrict_number
18
+ post_webinar_survey survey_url registrants_email_notification
19
+ meeting_authentication authentication_option
20
+ authentication_domains registrants_confirmation_email
21
+ ],
22
+ {
23
+ language_interpretation: [
24
+ :enable,
25
+ interpreters: %i[email languages]
26
+ ],
27
+ question_and_answer: %i[
28
+ allow_anonymous_questions answer_questions attendees_can_comment
29
+ attendees_can_upvote enable
30
+ ]
31
+ }
32
+ ].freeze
19
33
 
20
34
  get 'webinar_list', '/users/:host_id/webinars',
21
35
  permit: %i[page_size page_number]
@@ -63,6 +77,9 @@ module Zoom
63
77
  get 'webinar_poll_get', '/webinars/:webinar_id/polls/:poll_id'
64
78
 
65
79
  get 'webinar_panelist_list', '/webinars/:webinar_id/panelists'
80
+
81
+ get 'past_webinars_absentees', '/past_webinars/:webinar_uuid/absentees',
82
+ permit: %i[occurrence_id page_size next_page_token]
66
83
  end
67
84
  end
68
85
  end
data/lib/zoom/actions.rb CHANGED
@@ -30,7 +30,7 @@ module Zoom
30
30
  client, method, parsed_path, params, request_options, oauth =
31
31
  args.values_at :client, :method, :parsed_path, :params, :request_options, :oauth
32
32
  case method
33
- when :get
33
+ when :get, :delete
34
34
  request_options[:query] = params
35
35
  when :post, :put, :patch
36
36
  request_options[:body] =
data/lib/zoom/client.rb CHANGED
@@ -59,3 +59,4 @@ end
59
59
 
60
60
  require 'zoom/clients/jwt'
61
61
  require 'zoom/clients/oauth'
62
+ require 'zoom/clients/server_to_server_oauth'
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Zoom
4
+ class Client
5
+ class ServerToServerOAuth < Zoom::Client
6
+ attr_reader :access_token, :expires_in, :expires_at
7
+
8
+ def initialize(config)
9
+ Zoom::Params.new(config).permit(%i[access_token account_id client_id client_secret timeout])
10
+ Zoom::Params.new(config).require_one_of(%i[access_token account_id])
11
+
12
+ config.each { |k, v| instance_variable_set("@#{k}", v) }
13
+ self.class.default_timeout(@timeout || 20)
14
+ end
15
+
16
+ def auth
17
+ response = access_tokens_account_credentials(account_id: @account_id)
18
+ set_tokens(response)
19
+ response
20
+ end
21
+
22
+ def auth_token
23
+ return Base64.urlsafe_encode64("#{@client_id}:#{@client_secret}") if @client_id && @client_secret
24
+
25
+ Base64.urlsafe_encode64("#{Zoom.configuration.api_key}:#{Zoom.configuration.api_secret}")
26
+ end
27
+
28
+ private
29
+
30
+ def set_tokens(response)
31
+ if response.is_a?(Hash) && !response.key?(:error)
32
+ @access_token = response["access_token"]
33
+ @expires_in = response["expires_in"]
34
+ @expires_at = @expires_in ? (Time.now + @expires_in).to_i : nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
data/lib/zoom/error.rb CHANGED
@@ -15,4 +15,11 @@ module Zoom
15
15
  class ParameterNotPermitted < StandardError; end
16
16
  class ParameterValueNotPermitted < StandardError; end
17
17
  class AuthenticationError < StandardError; end
18
+ class BadRequest < StandardError; end
19
+ class Unauthorized < StandardError; end
20
+ class Forbidden < StandardError; end
21
+ class NotFound < StandardError; end
22
+ class Conflict < StandardError; end
23
+ class TooManyRequests < StandardError; end
24
+ class InternalServerError < StandardError; end
18
25
  end
data/lib/zoom/params.rb CHANGED
@@ -32,7 +32,7 @@ module Zoom
32
32
  array << hash_filter(filter)
33
33
  end
34
34
  end
35
- non_permitted_params = @parameters.keys - permitted_keys.flatten
35
+ non_permitted_params = parameters_keys - permitted_keys.flatten
36
36
  raise Zoom::ParameterNotPermitted, non_permitted_params.to_s unless non_permitted_params.empty?
37
37
  end
38
38
 
@@ -106,5 +106,13 @@ module Zoom
106
106
  raise Zoom::ParameterValueNotPermitted, "#{key}: #{value}"
107
107
  end
108
108
  end
109
+
110
+ def parameters_keys
111
+ if @parameters.kind_of?(Array)
112
+ @parameters.map(&:keys).flatten.uniq
113
+ else
114
+ @parameters.keys
115
+ end
116
+ end
109
117
  end
110
118
  end
data/lib/zoom/utils.rb CHANGED
@@ -11,14 +11,21 @@ module Zoom
11
11
  name ? ArgumentError.new("Unrecognized parameter #{name}") : ArgumentError.new
12
12
  end
13
13
 
14
- def raise_if_error!(response)
15
- return response unless response&.key?('code')
14
+ def raise_if_error!(response, http_code=200)
15
+ return response unless response.is_a?(Hash) && response.key?('code')
16
16
 
17
17
  code = response['code']
18
-
19
- raise AuthenticationError, build_error(response) if code == 124
20
18
  error_hash = build_error(response)
21
- raise Error.new(error_hash, error_hash) if code >= 300
19
+
20
+ raise AuthenticationError, error_hash if code == 124
21
+ raise BadRequest, error_hash if code == 400
22
+ raise Unauthorized, error_hash if code == 401
23
+ raise Forbidden, error_hash if code == 403
24
+ raise NotFound, error_hash if code == 404
25
+ raise Conflict, error_hash if code == 409
26
+ raise TooManyRequests, error_hash if code == 429
27
+ raise InternalServerError, error_hash if code == 500
28
+ raise Error.new(error_hash, error_hash)
22
29
  end
23
30
 
24
31
  def build_error(response)
@@ -28,7 +35,7 @@ module Zoom
28
35
  end
29
36
 
30
37
  def parse_response(http_response)
31
- raise_if_error!(http_response.parsed_response) || http_response.code
38
+ raise_if_error!(http_response.parsed_response, http_response.code) || http_response.code
32
39
  end
33
40
 
34
41
  def extract_options!(array)
data/lib/zoom/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zoom
4
- VERSION = '1.1.0'
4
+ VERSION = '1.1.3'
5
5
  end
@@ -24,6 +24,12 @@
24
24
  "allow_multiple_devices": true,
25
25
  "practice_session": false,
26
26
  "hd_video": false,
27
- "question_answer": true
27
+ "question_and_answer": {
28
+ "allow_anonymous_questions": true,
29
+ "answer_questions": "all",
30
+ "attendees_can_comment": true,
31
+ "attendees_can_upvote": true,
32
+ "enable": true
33
+ }
28
34
  }
29
35
  }
@@ -0,0 +1,37 @@
1
+ {
2
+ "next_page_token": "w7587w4eiyfsudgf",
3
+ "page_count": 1,
4
+ "page_number": 1,
5
+ "page_size": 30,
6
+ "total_records": 20,
7
+ "registrants": [
8
+ {
9
+ "id": "9tboDiHUQAeOnbmudzWa5g",
10
+ "address": "1800 Amphibious Blvd.",
11
+ "city": "Mountain View",
12
+ "comments": "Looking forward to the discussion.",
13
+ "country": "US",
14
+ "custom_questions": [
15
+ {
16
+ "title": "What do you hope to learn from this?",
17
+ "value": "Look forward to learning how you come up with new recipes and what other services you offer."
18
+ }
19
+ ],
20
+ "email": "jchill@example.com",
21
+ "first_name": "Jill",
22
+ "industry": "Food",
23
+ "job_title": "Chef",
24
+ "last_name": "Chill",
25
+ "no_of_employees": "1-20",
26
+ "org": "Cooking Org",
27
+ "phone": "5550100",
28
+ "purchasing_time_frame": "1-3 months",
29
+ "role_in_purchase_process": "Influencer",
30
+ "state": "CA",
31
+ "status": "approved",
32
+ "zip": "94045",
33
+ "create_time": "2022-03-22T05:59:09Z",
34
+ "join_url": "https://example.com/j/11111"
35
+ }
36
+ ]
37
+ }
@@ -44,7 +44,7 @@ describe Zoom::Actions::Groups do
44
44
  end
45
45
 
46
46
  it 'raises an error' do
47
- expect { response }.to raise_error(Zoom::Error)
47
+ expect { response }.to raise_error(Zoom::Conflict)
48
48
  end
49
49
  end
50
50
 
@@ -59,7 +59,7 @@ describe Zoom::Actions::Groups do
59
59
  end
60
60
 
61
61
  it 'raises an error' do
62
- expect { response }.to raise_error(Zoom::Error)
62
+ expect { response }.to raise_error(Zoom::TooManyRequests)
63
63
  end
64
64
  end
65
65
 
@@ -32,12 +32,12 @@ describe Zoom::Actions::Groups do
32
32
  :patch,
33
33
  zoom_url("/groups/#{args[:group_id]}")
34
34
  ).to_return(status: 404,
35
- body: json_response('error', 'group_not_exist'),
35
+ body: '{ "code": 404, "message": "Group name Zoom Group Name is already in use." }',
36
36
  headers: { 'Content-Type' => 'application/json' })
37
37
  end
38
38
 
39
- it 'raises an error' do
40
- expect { zc.group_update(args) }.to raise_error(Zoom::Error)
39
+ it 'raises Zoom::NotFound' do
40
+ expect { zc.group_update(args) }.to raise_error(Zoom::NotFound)
41
41
  end
42
42
  end
43
43
 
@@ -51,8 +51,8 @@ describe Zoom::Actions::Groups do
51
51
  headers: { 'Content-Type' => 'application/json' })
52
52
  end
53
53
 
54
- it 'raises an error' do
55
- expect { zc.group_update(args) }.to raise_error(Zoom::Error)
54
+ it 'raises Zoom::Conflict' do
55
+ expect { zc.group_update(args) }.to raise_error(Zoom::Conflict)
56
56
  end
57
57
  end
58
58
  end
@@ -38,7 +38,7 @@ describe Zoom::Actions::IM::Chat do
38
38
  end
39
39
 
40
40
  it 'raises Zoom::Error exception' do
41
- expect { zc.get_chat_channels(args) }.to raise_error(Zoom::Error, {
41
+ expect { zc.get_chat_channels(args) }.to raise_error(Zoom::BadRequest, {
42
42
  base: "Unauthorized request. You do not have permission to access this user’s channel information."
43
43
  }.to_s)
44
44
  end
@@ -37,7 +37,7 @@ describe Zoom::Actions::User do
37
37
  end
38
38
 
39
39
  it 'raises an error' do
40
- expect { zc.user_email_update(args) }.to raise_error(Zoom::Error)
40
+ expect { zc.user_email_update(args) }.to raise_error(Zoom::BadRequest)
41
41
  end
42
42
  end
43
43
 
@@ -37,7 +37,7 @@ describe Zoom::Actions::User do
37
37
  end
38
38
 
39
39
  it 'raises an error' do
40
- expect { zc.user_status_update(args) }.to raise_error(Zoom::Error)
40
+ expect { zc.user_status_update(args) }.to raise_error(Zoom::BadRequest)
41
41
  end
42
42
  end
43
43
 
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Zoom::Actions::Webinar do
4
+ let(:zc) { zoom_client }
5
+ let(:args) { { webinar_uuid: '123456789' } }
6
+
7
+ describe '#past_webinars_absentees' do
8
+ context 'with a valid response' do
9
+ before :each do
10
+ stub_request(
11
+ :get,
12
+ zoom_url("/past_webinars/#{args[:webinar_uuid]}/absentees")
13
+ ).to_return(status: 200,
14
+ body: json_response('webinar', 'past_webinars_absentees'),
15
+ headers: { 'Content-Type' => 'application/json' })
16
+ end
17
+
18
+ it "requires a 'uuid' argument" do
19
+ expect { zc.past_webinars_absentees(filter_key(args, :webinar_uuid)) }.to raise_error(Zoom::ParameterMissing, [:webinar_uuid].to_s)
20
+ end
21
+
22
+ it 'returns a webinar instance with registrants as an array' do
23
+ expect(zc.past_webinars_absentees(args)['registrants']).to be_kind_of(Array)
24
+ end
25
+ end
26
+
27
+ context 'with a 4xx response' do
28
+ before :each do
29
+ stub_request(
30
+ :get,
31
+ zoom_url("/past_webinars/#{args[:webinar_uuid]}/absentees")
32
+ ).to_return(status: 404,
33
+ body: json_response('error', 'validation'),
34
+ headers: { 'Content-Type' => 'application/json' })
35
+ end
36
+
37
+ it 'raises Zoom::Error exception' do
38
+ expect { zc.past_webinars_absentees(args) }.to raise_error(Zoom::Error)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -83,6 +83,7 @@ describe Zoom::Actions do
83
83
  let(:method) { :delete }
84
84
 
85
85
  it 'calls delete method on client with delete request_options' do
86
+ request_options[:query] = params
86
87
  expect(client.class).to receive(method).with(parsed_path, **request_options)
87
88
  subject
88
89
  end
@@ -120,4 +120,69 @@ describe Zoom::Client do
120
120
  end
121
121
  end
122
122
  end
123
+
124
+ describe 'ServerToServerOAuth client' do
125
+ let(:access_token) {'xxx'}
126
+ let(:client) do
127
+ Zoom::Client::ServerToServerOAuth.new(access_token: access_token, timeout: 30)
128
+ end
129
+
130
+ it 'raises an error if there is no arguments' do
131
+ expect { Zoom::Client::ServerToServerOAuth.new(timeout: 30) }.to raise_error(Zoom::ParameterMissing)
132
+ end
133
+
134
+ it 'requires at least an access token' do
135
+ expect { Zoom::Client::ServerToServerOAuth.new(access_token: access_token) }.not_to raise_error
136
+ end
137
+
138
+ it 'requires at least an account_id' do
139
+ expect { Zoom::Client::ServerToServerOAuth.new(access_token: access_token) }.not_to raise_error
140
+ end
141
+
142
+ it 'creates instance of Zoom::Client if api_key and api_secret is provided' do
143
+ expect(client).to be_kind_of(Zoom::Client)
144
+ end
145
+
146
+ it 'has the bearer token in the auth header' do
147
+ expect(client.request_headers['Authorization']).to eq("Bearer #{access_token}")
148
+ end
149
+
150
+ describe 'set_tokens' do
151
+ let(:client) { Zoom::Client::ServerToServerOAuth.new(account_id: 'xxx') }
152
+
153
+ before :each do
154
+ Zoom.configure do |config|
155
+ config.timeout = 20
156
+ end
157
+
158
+ stub_request(
159
+ :post,
160
+ zoom_auth_url('oauth/token')
161
+ ).to_return(body: json_response('token', 'access_token'),
162
+ headers: { 'Content-Type' => 'application/json' })
163
+ end
164
+
165
+ it 'sets the access_token, expires_in and expires_at' do
166
+ expected_values = JSON.parse(json_response('token', 'access_token'))
167
+ client.auth
168
+ expect(client.access_token).to eq(expected_values['access_token'])
169
+ expect(client.expires_in).to eq(expected_values['expires_in'])
170
+ expect(client.expires_at).to eq((Time.now + expected_values['expires_in']).to_i)
171
+ end
172
+
173
+ context 'when client_id and client_secret is not provided' do
174
+ it 'has the basic auth authorization header based on api_key and api_secret' do
175
+ expect(client.oauth_request_headers['Authorization']).to eq("Basic eHh4Onh4eA==")
176
+ end
177
+ end
178
+
179
+ context 'when client_id and client_secret are provided' do
180
+ let(:client) { Zoom::Client::ServerToServerOAuth.new(account_id: 'xxx', client_id: 'yyy', client_secret: 'yyy') }
181
+
182
+ it 'has the basic auth authorization header based on client_id and client_secret' do
183
+ expect(client.oauth_request_headers['Authorization']).to eq("Basic eXl5Onl5eQ==")
184
+ end
185
+ end
186
+ end
187
+ end
123
188
  end
@@ -98,4 +98,22 @@ RSpec.describe Zoom::Params do
98
98
  expect { params.permit_value(:baz, values) }.to raise_error(Zoom::ParameterValueNotPermitted, "#{:baz.to_s}: #{:bang.to_s}")
99
99
  end
100
100
  end
101
+
102
+ describe '#parameters_keys' do
103
+ context 'when param is array ' do
104
+ let(:params) { Zoom::Params.new([{foo: :bar, baz: :bang}, {foo: :bar1, baz: :bang1}]) }
105
+
106
+ it 'get each object keys and return unique of them' do
107
+ expect(params.parameters_keys).to eq([:foo, :baz])
108
+ end
109
+ end
110
+
111
+ context 'when param is Hash ' do
112
+ let(:params) { Zoom::Params.new({foo: :bar, baz: :bang}) }
113
+
114
+ it 'return hash keys' do
115
+ expect(params.parameters_keys).to eq([:foo, :baz])
116
+ end
117
+ end
118
+ end
101
119
  end
@@ -16,19 +16,59 @@ describe Zoom::Utils do
16
16
 
17
17
  describe '#raise_if_error!' do
18
18
  it 'raises Zoom::AuthenticationError if error is present and code = 124' do
19
- response = { 'code' => 124, 'message' => 'Invalid access token.' }
19
+ response = { 'code' => 124, 'message' => 'Authentication error.' }
20
20
  expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::AuthenticationError)
21
21
  end
22
22
 
23
- it 'raises Zoom::Error if error is present and code >= 300' do
24
- response = { 'code' => 400, 'message' => 'lol error' }
25
- expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::Error)
23
+ it 'raises Zoom::BadRequest if error is present and code = 400' do
24
+ response = { 'code' => 400, 'message' => 'Bas request.' }
25
+ expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::BadRequest)
26
+ end
27
+
28
+ it 'raises Zoom::Unauthorized if error is present and code = 401' do
29
+ response = { 'code' => 401, 'message' => 'Unauthorized.' }
30
+ expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::Unauthorized)
31
+ end
32
+
33
+ it 'raises Zoom::Forbidden if error is present and code = 403' do
34
+ response = { 'code' => 403, 'message' => 'Forbidden.' }
35
+ expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::Forbidden)
36
+ end
37
+
38
+ it 'raises Zoom::NotFound if error is present and code = 404' do
39
+ response = { 'code' => 404, 'message' => 'NotFound.' }
40
+ expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::NotFound)
41
+ end
42
+
43
+ it 'raises Zoom::Conflict if error is present and code = 409' do
44
+ response = { 'code' => 409, 'message' => 'Conflict.' }
45
+ expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::Conflict)
46
+ end
47
+
48
+ it 'raises Zoom::TooManyRequests if error is present and code = 429' do
49
+ response = { 'code' => 429, 'message' => 'Too many requests.' }
50
+ expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::TooManyRequests)
51
+ end
52
+
53
+ it 'raises Zoom::InternalServerError if error is present and code = 500' do
54
+ response = { 'code' => 500, 'message' => 'Internal server error.' }
55
+ expect { Utils.raise_if_error!(response) }.to raise_error(Zoom::InternalServerError)
26
56
  end
27
57
 
28
58
  it 'does not raise Zoom::Error if error is not present' do
29
59
  response = {}
30
60
  expect { Utils.raise_if_error!(response) }.to_not raise_error
31
61
  end
62
+
63
+ it 'does not raise Zoom::Error if response is not a Hash' do
64
+ response = 'xxx'
65
+ expect { Utils.raise_if_error!(response) }.to_not raise_error
66
+ end
67
+
68
+ it 'raises Zoom::Error if http code is not in [124, 400, 401, 403, 404, 429, 500]' do
69
+ response = { 'code' => 180, 'message' => 'lol error' }
70
+ expect { Utils.raise_if_error!(response, 400) }.to raise_error(Zoom::Error)
71
+ end
32
72
  end
33
73
 
34
74
  describe '#extract_options!' do
data/spec/spec_helper.rb CHANGED
@@ -45,6 +45,10 @@ def oauth_client
45
45
  Zoom::Client::OAuth.new(auth_token: 'xxx', auth_code: 'xxx', redirect_uri: 'xxx', timeout: 15)
46
46
  end
47
47
 
48
+ def server_to_server_oauth_client
49
+ Zoom::Client::ServerToServerOAuth.new(account_id: 'xxx')
50
+ end
51
+
48
52
  def zoom_client
49
53
  jwt_client
50
54
  end
data/zoom_rb.gemspec CHANGED
@@ -6,16 +6,16 @@ require 'zoom/version'
6
6
 
7
7
  Gem::Specification.new do |gem|
8
8
 
9
- gem.add_dependency 'httparty', '~> 0.13'
9
+ gem.add_dependency 'httparty', '>= 0.13'
10
10
  gem.add_dependency 'json', '>= 1.8'
11
11
  gem.add_dependency 'jwt'
12
12
 
13
13
  gem.add_development_dependency 'pry-byebug'
14
- gem.add_development_dependency 'hint-rubocop_style', '~> 0'
15
- gem.add_development_dependency 'rspec', '~> 3.8'
16
- gem.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
17
- gem.add_development_dependency 'simplecov', '~> 0.16.1'
18
- gem.add_development_dependency 'webmock', '~> 3.4'
14
+ gem.add_development_dependency 'hint-rubocop_style'
15
+ gem.add_development_dependency 'rspec', '>= 3.8'
16
+ gem.add_development_dependency 'rspec_junit_formatter', '>= 0.4.1'
17
+ gem.add_development_dependency 'simplecov', '>= 0.16.1'
18
+ gem.add_development_dependency 'webmock', '>= 3.4'
19
19
 
20
20
  gem.authors = ['Kyle Boe']
21
21
  gem.email = ['kyle@boe.codes']
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zoom_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Boe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-11 00:00:00.000000000 Z
11
+ date: 2022-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.13'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.13'
27
27
  - !ruby/object:Gem::Dependency
@@ -70,70 +70,70 @@ dependencies:
70
70
  name: hint-rubocop_style
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '3.8'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.8'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec_junit_formatter
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: 0.4.1
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.4.1
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: simplecov
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: 0.16.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.16.1
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: webmock
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
131
  version: '3.4'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '3.4'
139
139
  description: A Ruby API wrapper for zoom.us API
@@ -151,6 +151,7 @@ files:
151
151
  - LICENSE
152
152
  - Makefile
153
153
  - README.md
154
+ - Rakefile
154
155
  - lib/zoom/actions.rb
155
156
  - lib/zoom/actions/account.rb
156
157
  - lib/zoom/actions/billing.rb
@@ -171,6 +172,7 @@ files:
171
172
  - lib/zoom/client.rb
172
173
  - lib/zoom/clients/jwt.rb
173
174
  - lib/zoom/clients/oauth.rb
175
+ - lib/zoom/clients/server_to_server_oauth.rb
174
176
  - lib/zoom/constants/account/options/pay_modes.rb
175
177
  - lib/zoom/constants/account/settings/permitted_settings.rb
176
178
  - lib/zoom/constants/constants.rb
@@ -296,6 +298,7 @@ files:
296
298
  - spec/fixtures/webinar/list.json
297
299
  - spec/fixtures/webinar/panelist_list.json
298
300
  - spec/fixtures/webinar/past_webinar_list.json
301
+ - spec/fixtures/webinar/past_webinars_absentees.json
299
302
  - spec/fixtures/webinar/poll_get.json
300
303
  - spec/fixtures/webinar/polls_list.json
301
304
  - spec/fixtures/webinar/registrant/add.json
@@ -432,6 +435,7 @@ files:
432
435
  - spec/lib/zoom/actions/webinar/list_registration_spec.rb
433
436
  - spec/lib/zoom/actions/webinar/list_spec.rb
434
437
  - spec/lib/zoom/actions/webinar/panelist_list_spec.rb
438
+ - spec/lib/zoom/actions/webinar/past_webinar_absentees_spec.rb
435
439
  - spec/lib/zoom/actions/webinar/past_webinar_list_spec.rb
436
440
  - spec/lib/zoom/actions/webinar/poll_get_spec.rb
437
441
  - spec/lib/zoom/actions/webinar/polls_list_spec.rb
@@ -470,7 +474,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
470
474
  - !ruby/object:Gem::Version
471
475
  version: '0'
472
476
  requirements: []
473
- rubygems_version: 3.2.32
477
+ rubygems_version: 3.3.7
474
478
  signing_key:
475
479
  specification_version: 4
476
480
  summary: zoom.us API wrapper
@@ -576,6 +580,7 @@ test_files:
576
580
  - spec/fixtures/webinar/list.json
577
581
  - spec/fixtures/webinar/panelist_list.json
578
582
  - spec/fixtures/webinar/past_webinar_list.json
583
+ - spec/fixtures/webinar/past_webinars_absentees.json
579
584
  - spec/fixtures/webinar/poll_get.json
580
585
  - spec/fixtures/webinar/polls_list.json
581
586
  - spec/fixtures/webinar/registrant/add.json
@@ -712,6 +717,7 @@ test_files:
712
717
  - spec/lib/zoom/actions/webinar/list_registration_spec.rb
713
718
  - spec/lib/zoom/actions/webinar/list_spec.rb
714
719
  - spec/lib/zoom/actions/webinar/panelist_list_spec.rb
720
+ - spec/lib/zoom/actions/webinar/past_webinar_absentees_spec.rb
715
721
  - spec/lib/zoom/actions/webinar/past_webinar_list_spec.rb
716
722
  - spec/lib/zoom/actions/webinar/poll_get_spec.rb
717
723
  - spec/lib/zoom/actions/webinar/polls_list_spec.rb