bigbluebutton-api-ruby 0.0.10 → 0.0.11

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.
data/.gitignore CHANGED
@@ -1,5 +1,5 @@
1
1
  *.gem
2
2
  pkg
3
- *.*~
3
+ *~
4
4
  test/config.yml
5
5
  doc/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ if [ -e '.rvmrc_custom' ]; then
3
+ source .rvmrc_custom;
4
+ else
5
+ rvm --create use 1.9.2@bigbluebutton-api-ruby;
6
+ fi
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.0.11
2
+
3
+ * The file "bigbluebutton-api" was renamed to "bigbluebutton_api". All "require" calls must be updated.
4
+ * Splitted the library in more files (more modular) and created rspec tests for it.
5
+ * Added a BigBlueButtonApi.timeout attribute to timeout get requests and avoid blocks when the server is down. Defaults to 2 secs.
6
+ * New method last_http_response to access the last HTTP response object.
7
+ * Automatically detects the BBB server version if not informed by the user.
8
+
1
9
  == 0.0.10
2
10
 
3
11
  * Returning hash now will *always* have these 3 values: :returncode (boolean), :messageKey (string) and :message (string).
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'nokogiri', '1.4.1'
4
+
5
+ group :developement do
6
+ gem 'rspec', '~> 2.6'
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ nokogiri (1.4.1)
6
+ rspec (2.6.0)
7
+ rspec-core (~> 2.6.0)
8
+ rspec-expectations (~> 2.6.0)
9
+ rspec-mocks (~> 2.6.0)
10
+ rspec-core (2.6.4)
11
+ rspec-expectations (2.6.0)
12
+ diff-lcs (~> 1.1.2)
13
+ rspec-mocks (2.6.0)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ nokogiri (= 1.4.1)
20
+ rspec (~> 2.6)
@@ -2,7 +2,7 @@ $:.push File.expand_path("../lib", __FILE__)
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'bigbluebutton-api-ruby'
5
- s.version = '0.0.10'
5
+ s.version = '0.0.11'
6
6
  s.extra_rdoc_files = ['README.rdoc', 'LICENSE', 'CHANGELOG.rdoc']
7
7
  s.summary = 'Provides an interface to the BigBlueButton web meeting API (https://github.com/mconf/bigbluebutton-api-ruby)'
8
8
  s.description = s.summary
@@ -5,26 +5,15 @@ require 'digest/sha1'
5
5
  require 'rubygems'
6
6
  require 'nokogiri'
7
7
  require 'hash_to_xml'
8
+ require 'bigbluebutton_exception'
9
+ require 'bigbluebutton_formatter'
8
10
 
9
11
  module BigBlueButton
10
12
 
11
- class BigBlueButtonException < Exception
12
- attr_accessor :key
13
-
14
- def to_s
15
- unless key.blank?
16
- super.to_s + ", messageKey: #{key}"
17
- else
18
- super
19
- end
20
- end
21
-
22
- end
23
-
24
13
  # This class provides access to the BigBlueButton API. BigBlueButton
25
14
  # is an open source project that provides web conferencing for distance
26
15
  # education (http://code.google.com/p/bigbluebutton/wiki/API). This API
27
- # was developed to support the following version of BBB: 0.64, 0.7
16
+ # was developed to support the following version of BBB: 0.7, 0.8 (soon)
28
17
  #
29
18
  # Sample usage of the API is as follows:
30
19
  # 1) Create a meeting with the create_meeting call
@@ -42,8 +31,6 @@ module BigBlueButton
42
31
  # Copyright:: Copyright (c) 2010 Joe Kinsella
43
32
  # License:: Distributes under same terms as Ruby
44
33
  #
45
- # TODO: Automatically detect API version using request to index - added in 0.7
46
- #
47
34
  # Considerations about the returning hash:
48
35
  # * The XML returned by BBB is converted to a Hash. See the desired method's documentation for examples.
49
36
  # * Three values will *always* exist in the hash: :returncode (boolean), :messageKey (string) and :message (string)
@@ -58,54 +45,38 @@ module BigBlueButton
58
45
  #
59
46
  class BigBlueButtonApi
60
47
 
61
- attr_accessor :url, :supported_versions, :salt, :version, :debug
48
+ attr_accessor :url, :supported_versions, :salt, :version, :debug, :timeout
62
49
 
63
50
  # Initializes an instance
64
51
  # url:: URL to a BigBlueButton server (e.g. http://demo.bigbluebutton.org/bigbluebutton/api)
65
52
  # salt:: Secret salt for this server
66
- # version:: API version: 0.64 or 0.7
53
+ # version:: API version: 0.7 (valid for 0.7, 0.71 and 0.71a)
67
54
  def initialize(url, salt, version='0.7', debug=false)
68
- @supported_versions = ['0.7', '0.64']
69
- unless @supported_versions.include?(version)
70
- raise BigBlueButtonException.new("BigBlueButton error: Invalid API version #{version}. Supported versions: #{@supported_versions.join(', ')}")
71
- end
55
+ @supported_versions = ['0.7']
72
56
  @url = url
73
57
  @salt = salt
74
58
  @debug = debug
75
- @version = version
76
- puts "BigBlueButtonAPI: Using version #{@version}" if @debug
77
- end
59
+ @timeout = 2 # 2 seconds timeout for get requests
78
60
 
79
- # DEPRECATED
80
- # Use join_meeting_url
81
- def moderator_url(meeting_id, user_name, password,
82
- user_id = nil, web_voice_conf = nil)
83
- warn "#{caller[0]}: moderator_url is deprecated and will soon be removed, please use join_meeting_url instead."
84
- join_meeting_url(meeting_id, user_name, password, user_id, web_voice_conf)
85
- end
61
+ @version = version || get_api_version
62
+ unless @supported_versions.include?(@version)
63
+ raise BigBlueButtonException.new("BigBlueButton error: Invalid API version #{version}. Supported versions: #{@supported_versions.join(', ')}")
64
+ end
86
65
 
87
- # DEPRECATED
88
- # Use join_meeting_url
89
- def attendee_url(meeting_id, user_name, password,
90
- user_id = nil, web_voice_conf = nil)
91
- warn "#{caller[0]}: attendee_url is deprecated and will soon be removed, please use join_meeting_url instead."
92
- join_meeting_url(meeting_id, user_name, password, user_id, web_voice_conf)
66
+ puts "BigBlueButtonAPI: Using version #{@version}" if @debug
93
67
  end
94
68
 
95
69
  # Returns the url used to join the meeting
96
70
  # meeting_id:: Unique identifier for the meeting
97
71
  # user_name:: Name of the user
98
72
  # password:: Password for this meeting - used to set the user as moderator or attendee
99
- # user_id:: Unique identifier for this user (>= 0.7)
100
- # web_voice_conf:: Custom voice-extension for users using VoIP (>= 0.7)
73
+ # user_id:: Unique identifier for this user
74
+ # web_voice_conf:: Custom voice-extension for users using VoIP
101
75
  def join_meeting_url(meeting_id, user_name, password,
102
76
  user_id = nil, web_voice_conf = nil)
103
77
 
104
- params = { :meetingID => meeting_id, :password => password, :fullName => user_name }
105
- if @version == '0.7'
106
- params[:userID] = user_id
107
- params[:webVoiceConf] = web_voice_conf
108
- end
78
+ params = { :meetingID => meeting_id, :password => password, :fullName => user_name,
79
+ :userID => user_id, :webVoiceConf => web_voice_conf }
109
80
  get_url(:join, params)
110
81
  end
111
82
 
@@ -118,7 +89,7 @@ module BigBlueButton
118
89
  # welcome_message:: Welcome message to display in chat window
119
90
  # dialin_number:: Dial in number for conference using a regular phone
120
91
  # logout_url:: URL to return user to after exiting meeting
121
- # voice_bridge:: Voice conference number (>= 0.7)
92
+ # voice_bridge:: Voice conference number
122
93
  #
123
94
  # === Return examples (for 0.7)
124
95
  #
@@ -139,7 +110,6 @@ module BigBlueButton
139
110
  # :message=>"This conference was already in existence and may currently be in progress."
140
111
  # }
141
112
  #
142
- # TODO check if voice_bridge exists in 0.64
143
113
  def create_meeting(meeting_name, meeting_id, moderator_password = nil, attendee_password = nil,
144
114
  welcome_message = nil, dial_number = nil, logout_url = nil,
145
115
  max_participants = nil, voice_bridge = nil)
@@ -147,15 +117,16 @@ module BigBlueButton
147
117
  params = { :name => meeting_name, :meetingID => meeting_id,
148
118
  :moderatorPW => moderator_password, :attendeePW => attendee_password,
149
119
  :welcome => welcome_message, :dialNumber => dial_number,
150
- :logoutURL => logout_url, :maxParticpants => max_participants }
151
- params[:voiceBridge] = voice_bridge if @version == '0.7'
120
+ :logoutURL => logout_url, :maxParticpants => max_participants,
121
+ :voiceBridge => voice_bridge }
152
122
 
153
123
  response = send_api_request(:create, params)
154
124
 
155
- response[:meetingID] = response[:meetingID].to_s
156
- response[:moderatorPW] = response[:moderatorPW].to_s
157
- response[:attendeePW] = response[:attendeePW].to_s
158
- response[:hasBeenForciblyEnded] = response[:hasBeenForciblyEnded].downcase == "true"
125
+ formatter = BigBlueButtonFormatter.new(response)
126
+ formatter.to_string(:meetingID)
127
+ formatter.to_string(:moderatorPW)
128
+ formatter.to_string(:attendeePW)
129
+ formatter.to_boolean(:hasBeenForciblyEnded)
159
130
 
160
131
  response
161
132
  end
@@ -183,7 +154,7 @@ module BigBlueButton
183
154
  # meeting_id:: Unique identifier for the meeting
184
155
  def is_meeting_running?(meeting_id)
185
156
  hash = send_api_request(:isMeetingRunning, { :meetingID => meeting_id } )
186
- hash[:running].downcase == "true"
157
+ BigBlueButtonFormatter.new(hash).to_boolean(:running)
187
158
  end
188
159
 
189
160
  # Warning: As of this version of the gem, this call does not work
@@ -196,16 +167,11 @@ module BigBlueButton
196
167
  # meeting_id:: Unique identifier for the meeting
197
168
  # user_name:: Name of the user
198
169
  # password:: Moderator or attendee password for this meeting
199
- # user_id:: Unique identifier for this user (>=0.7)
200
- # web_voice_conf:: Custom voice-extension for users using VoIP (>=0.7)
170
+ # user_id:: Unique identifier for this user
171
+ # web_voice_conf:: Custom voice-extension for users using VoIP
201
172
  def join_meeting(meeting_id, user_name, password, user_id = nil, web_voice_conf = nil)
202
- params = { :meetingID => meeting_id, :password => password, :fullName => user_name }
203
- if @version == '0.64'
204
- params[:redirectImmediately] = 0
205
- elsif @version == '0.7'
206
- params[:userID] = user_id
207
- params[:webVoiceConf] = web_voice_conf
208
- end
173
+ params = { :meetingID => meeting_id, :password => password, :fullName => user_name,
174
+ :userID => user_id, :webVoiceConf => web_voice_conf }
209
175
  send_api_request(:join, params)
210
176
  end
211
177
 
@@ -242,30 +208,17 @@ module BigBlueButton
242
208
  def get_meeting_info(meeting_id, password)
243
209
  response = send_api_request(:getMeetingInfo, { :meetingID => meeting_id, :password => password } )
244
210
 
245
- # simplify the hash making a node :attendees with an array with all attendees
246
- if response[:attendees].empty?
247
- attendees = []
248
- else
249
- node = response[:attendees][:attendee]
250
- if node.kind_of?(Array)
251
- attendees = node
252
- else
253
- attendees = []
254
- attendees << node
255
- end
256
- end
257
- response[:attendees] = attendees
258
- response[:attendees].each { |att| att[:role] = att[:role].downcase.to_sym }
259
-
260
- response[:meetingID] = response[:meetingID].to_s
261
- response[:moderatorPW] = response[:moderatorPW].to_s
262
- response[:attendeePW] = response[:attendeePW].to_s
263
- response[:hasBeenForciblyEnded] = response[:hasBeenForciblyEnded].downcase == "true"
264
- response[:running] = response[:running].downcase == "true"
265
- response[:startTime] = response[:startTime].downcase == "null" ?
266
- nil : DateTime.parse(response[:startTime])
267
- response[:endTime] = response[:endTime].downcase == "null" ?
268
- nil : DateTime.parse(response[:endTime])
211
+ formatter = BigBlueButtonFormatter.new(response)
212
+ formatter.flatten_objects(:attendees, :attendee)
213
+ response[:attendees].each { |a| formatter.format_attendee(a) }
214
+
215
+ formatter.to_string(:meetingID)
216
+ formatter.to_string(:moderatorPW)
217
+ formatter.to_string(:attendeePW)
218
+ formatter.to_boolean(:hasBeenForciblyEnded)
219
+ formatter.to_boolean(:running)
220
+ formatter.to_datetime(:startTime)
221
+ formatter.to_datetime(:endTime)
269
222
 
270
223
  response
271
224
  end
@@ -292,52 +245,23 @@ module BigBlueButton
292
245
  def get_meetings
293
246
  response = send_api_request(:getMeetings, { :random => rand(9999999999) } )
294
247
 
295
- # simplify the hash making a node :meetings with an array with all meetings
296
- if response[:meetings].empty?
297
- meetings = []
298
- else
299
- node = response[:meetings][:meeting]
300
- if node.kind_of?(Array)
301
- meetings = node
302
- else
303
- meetings = []
304
- meetings << node
305
- end
306
- end
307
- response[:meetings] = meetings
308
-
309
- response[:meetings].each do |meeting|
310
- meeting[:meetingID] = meeting[:meetingID].to_s
311
- meeting[:moderatorPW] = meeting[:moderatorPW].to_s
312
- meeting[:attendeePW] = meeting[:attendeePW].to_s
313
- meeting[:hasBeenForciblyEnded] = meeting[:hasBeenForciblyEnded].downcase == "true"
314
- meeting[:running] = meeting[:running].downcase == "true"
315
- end
316
-
248
+ formatter = BigBlueButtonFormatter.new(response)
249
+ formatter.flatten_objects(:meetings, :meeting)
250
+ response[:meetings].each { |m| formatter.format_meeting(m) }
317
251
  response
318
252
  end
319
253
 
320
254
  # Returns the API version (as string) of the associated server. This actually returns
321
- # the version requested to the BBB server, and not the version set by the user in
322
- # the initialization.
323
- #
324
- # Works for BBB >= 0.7 only. For earlier versions, returns an empty string.
255
+ # the version returned by the BBB server, and not the version set by the user in
256
+ # the initialization of this object.
325
257
  def get_api_version
326
258
  response = send_api_request(:index)
327
- if response[:returncode]
328
- response[:version].to_s
329
- else
330
- ""
331
- end
259
+ response[:returncode] ? response[:version].to_s : ""
332
260
  end
333
261
 
334
262
  # Make a simple request to the server to test the connection
335
263
  def test_connection
336
- if @version == '0.7'
337
- response = send_api_request(:index)
338
- else
339
- response = get_meetings
340
- end
264
+ response = send_api_request(:index)
341
265
  response[:returncode]
342
266
  end
343
267
 
@@ -350,56 +274,50 @@ module BigBlueButton
350
274
  r
351
275
  end
352
276
 
353
- protected
277
+ def last_http_response
278
+ @http_response
279
+ end
354
280
 
355
- def get_url(method, data)
281
+ def get_url(method, data={})
356
282
  if method == :index
357
283
  return @url
358
284
  end
359
285
 
360
286
  url = "#{@url}/#{method}?"
361
287
 
288
+ # stringify and escape all params
362
289
  data.delete_if { |k, v| v.nil? } unless data.nil?
363
290
  params = ""
364
291
  params = data.map{ |k,v| "#{k}=" + CGI::escape(v.to_s) unless k.nil? || v.nil? }.join("&")
365
292
 
293
+ # checksum calc
366
294
  checksum_param = params + @salt
367
- checksum_param = method.to_s + checksum_param if @version == '0.7'
295
+ checksum_param = method.to_s + checksum_param
368
296
  checksum = Digest::SHA1.hexdigest(checksum_param)
369
297
 
370
- "#{url}#{params}&checksum=#{checksum}"
298
+ # final url
299
+ url += "#{params}&" unless params.empty?
300
+ url += "checksum=#{checksum}"
371
301
  end
372
302
 
373
303
  def send_api_request(method, data = {})
374
304
  url = get_url(method, data)
375
- begin
376
- res = Net::HTTP.get_response(URI.parse(url))
377
- puts "BigBlueButtonAPI: URL request = #{url}" if @debug
378
- puts "BigBlueButtonAPI: URL response = #{res.body}" if @debug
379
- rescue Exception => socketerror
380
- raise BigBlueButtonException.new("Connection error. Your URL is probably incorrect: \"#{@url}\"")
381
- end
382
305
 
383
- if res.body.empty?
384
- raise BigBlueButtonException.new("No response body")
385
- end
306
+ @http_response = send_request(url)
307
+ return { } if @http_response.body.empty?
386
308
 
387
309
  # 'Hashify' the XML
388
- hash = Hash.from_xml res.body
310
+ hash = Hash.from_xml(@http_response.body)
389
311
 
390
312
  # simple validation of the xml body
391
313
  unless hash.has_key?(:response) and hash[:response].has_key?(:returncode)
392
314
  raise BigBlueButtonException.new("Invalid response body. Is the API URL correct? \"#{@url}\", version #{@version}")
393
315
  end
394
316
 
395
- # and remove the "response" node
396
- hash = Hash[hash[:response]].inject({}){|h,(k,v)| h[k] = v; h}
397
-
398
- # Adjust some values. There will always be a returncode, message and messageKey in the hash.
399
- hash[:returncode] = hash[:returncode].downcase == "success" # true instead of "SUCCESS"
400
- hash[:messageKey] = "" if !hash.has_key?(:messageKey) or hash[:messageKey].empty? # "" instead of {}
401
- hash[:message] = "" if !hash.has_key?(:message) or hash[:message].empty? # "" instead of {}
317
+ # default cleanup in the response
318
+ hash = BigBlueButtonFormatter.new(hash).default_formatting
402
319
 
320
+ # all responses should have a returncode
403
321
  unless hash[:returncode]
404
322
  exception = BigBlueButtonException.new(hash[:message])
405
323
  exception.key = hash.has_key?(:messageKey) ? hash[:messageKey] : ""
@@ -409,6 +327,25 @@ module BigBlueButton
409
327
  hash
410
328
  end
411
329
 
330
+ protected
331
+
332
+ def send_request(url)
333
+ begin
334
+ puts "BigBlueButtonAPI: URL request = #{url}" if @debug
335
+ url_parsed = URI.parse(url)
336
+ http = Net::HTTP.new(url_parsed.host, url_parsed.port)
337
+ http.open_timeout = @timeout
338
+ http.read_timeout = @timeout
339
+ response = http.get(url_parsed.request_uri)
340
+ puts "BigBlueButtonAPI: URL response = #{response.body}" if @debug
341
+ rescue TimeoutError => error
342
+ raise BigBlueButtonException.new("Timeout error. Your server is probably down: \"#{@url}\"")
343
+ rescue Exception => error
344
+ raise BigBlueButtonException.new("Connection error. Your URL is probably incorrect: \"#{@url}\"")
345
+ end
346
+ response
347
+ end
348
+
412
349
  end
413
350
  end
414
351
 
@@ -0,0 +1,13 @@
1
+ module BigBlueButton
2
+
3
+ class BigBlueButtonException < Exception
4
+ attr_accessor :key
5
+
6
+ def to_s
7
+ s = super.to_s
8
+ s += ", messageKey: #{key.to_s}" unless key.nil? or key.to_s.empty?
9
+ s
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,76 @@
1
+ module BigBlueButton
2
+
3
+ # Helper class to format the response hash received when the BigBlueButtonApi makes API calls
4
+ class BigBlueButtonFormatter
5
+ attr_accessor :hash
6
+
7
+ def initialize(hash)
8
+ @hash = hash
9
+ end
10
+
11
+ # converts a value in the @hash to boolean
12
+ def to_boolean(key)
13
+ @hash[key] = @hash[key].downcase == "true"
14
+ end
15
+
16
+ # converts a value in the @hash to string
17
+ def to_string(key)
18
+ @hash[key] = @hash[key].to_s
19
+ end
20
+
21
+ # converts a value in the @hash to DateTime
22
+ def to_datetime(key)
23
+ @hash[key] = @hash[key].downcase == "null" ? nil : DateTime.parse(@hash[key])
24
+ end
25
+
26
+ # Default formatting for all responses given by a BBB server
27
+ def default_formatting
28
+
29
+ # remove the "response" node
30
+ response = Hash[@hash[:response]].inject({}){|h,(k,v)| h[k] = v; h}
31
+
32
+ # Adjust some values. There will always be a returncode, a message and a messageKey in the hash.
33
+ response[:returncode] = response[:returncode].downcase == "success" # true instead of "SUCCESS"
34
+ response[:messageKey] = "" if !response.has_key?(:messageKey) or response[:messageKey].empty? # "" instead of {}
35
+ response[:message] = "" if !response.has_key?(:message) or response[:message].empty? # "" instead of {}
36
+
37
+ @hash = response
38
+ end
39
+
40
+ # default formatting for a meeting hash
41
+ def format_meeting(meeting)
42
+ meeting[:meetingID] = meeting[:meetingID].to_s
43
+ meeting[:moderatorPW] = meeting[:moderatorPW].to_s
44
+ meeting[:attendeePW] = meeting[:attendeePW].to_s
45
+ meeting[:hasBeenForciblyEnded] = meeting[:hasBeenForciblyEnded].downcase == "true"
46
+ meeting[:running] = meeting[:running].downcase == "true"
47
+ meeting
48
+ end
49
+
50
+ # default formatting for an attendee hash
51
+ def format_attendee(attendee)
52
+ attendee[:userID] = attendee[:userID].to_s
53
+ attendee[:role] = attendee[:role].downcase.to_sym
54
+ attendee
55
+ end
56
+
57
+ # simplifies the hash making a node e.g. :attendee with an array with all attendees
58
+ # TODO: comments with the expected @hash at this point
59
+ def flatten_objects(first, second)
60
+ if @hash[first].empty?
61
+ collection = []
62
+ else
63
+ node = @hash[first][second]
64
+ if node.kind_of?(Array)
65
+ collection = node
66
+ else
67
+ collection = []
68
+ collection << node
69
+ end
70
+ end
71
+ @hash[first] = collection
72
+ @hash
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,386 @@
1
+ require 'spec_helper'
2
+
3
+ describe BigBlueButton::BigBlueButtonApi do
4
+
5
+ # default variables and API object for all tests
6
+ let(:url) { "http://server.com" }
7
+ let(:salt) { "1234567890abcdefghijkl" }
8
+ let(:version) { "0.7" }
9
+ let(:debug) { false }
10
+ let(:api) { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
11
+
12
+ describe "#initialize" do
13
+ context "standard initialization" do
14
+ subject { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
15
+ it { subject.url.should be(url) }
16
+ it { subject.salt.should be(salt) }
17
+ it { subject.version.should be(version) }
18
+ it { subject.debug.should be(debug) }
19
+ it { subject.timeout.should be(2) }
20
+ it { subject.supported_versions.should include("0.7") }
21
+ end
22
+
23
+ context "when the version is not informed, get it from the BBB server" do
24
+ before { BigBlueButton::BigBlueButtonApi.any_instance.should_receive(:get_api_version).and_return("0.7") }
25
+ subject { BigBlueButton::BigBlueButtonApi.new(url, salt, nil) }
26
+ it { subject.version.should == "0.7" }
27
+ end
28
+
29
+ it "when the version is not supported raise an error" do
30
+ expect {
31
+ BigBlueButton::BigBlueButtonApi.new(url, salt, "0.not-supported", nil)
32
+ }.to raise_error(BigBlueButton::BigBlueButtonException)
33
+ end
34
+
35
+ context "current supported versions" do
36
+ subject { BigBlueButton::BigBlueButtonApi.new(url, salt) }
37
+ it { subject.supported_versions.should == ["0.7"] }
38
+ end
39
+ end
40
+
41
+ describe "#join_meeting_url" do
42
+ let(:meeting_id) { "meeting-id" }
43
+ let(:password) { "password" }
44
+ let(:user_name) { "user-name" }
45
+ let(:user_id) { "user-id" }
46
+ let(:web_voice_conf) { "web-voice-conf" }
47
+ let(:params) {
48
+ { :meetingID => meeting_id, :password => password, :fullName => user_name,
49
+ :userID => user_id, :webVoiceConf => web_voice_conf }
50
+ }
51
+
52
+ before { api.should_receive(:get_url).with(:join, params).and_return("test-url") }
53
+ it { api.join_meeting_url(meeting_id, user_name, password, user_id, web_voice_conf).should == "test-url" }
54
+ end
55
+
56
+ describe "#create_meeting" do
57
+ let(:meeting_name) { "name" }
58
+ let(:meeting_id) { "meeting-id" }
59
+ let(:moderator_password) { "moderator-password" }
60
+ let(:attendee_password) { "attendee-password" }
61
+ let(:welcome_message) { "welcome" }
62
+ let(:dial_number) { "dial-number" }
63
+ let(:logout_url) { "logout-url" }
64
+ let(:max_participants) { "max-participants" }
65
+ let(:voice_bridge) { "voice-bridge" }
66
+ let(:params) {
67
+ { :name => meeting_name, :meetingID => meeting_id,
68
+ :moderatorPW => moderator_password, :attendeePW => attendee_password,
69
+ :welcome => welcome_message, :dialNumber => dial_number,
70
+ :logoutURL => logout_url, :maxParticpants => max_participants,
71
+ :voiceBridge => voice_bridge }
72
+ }
73
+ let(:response) { { :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE" } }
74
+ let(:expected_response) { { :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false } }
75
+
76
+ # ps: not mocking the formatter here because it's easier to just check the results (expected_response)
77
+ before { api.should_receive(:send_api_request).with(:create, params).and_return(response) }
78
+ subject { api.create_meeting(meeting_name, meeting_id, moderator_password,
79
+ attendee_password, welcome_message, dial_number,
80
+ logout_url, max_participants, voice_bridge) }
81
+ it { subject.should == expected_response }
82
+ end
83
+
84
+ describe "#end_meeting" do
85
+ let(:meeting_id) { "meeting-id" }
86
+ let(:moderator_password) { "password" }
87
+ let(:params) { { :meetingID => meeting_id, :password => moderator_password } }
88
+ let(:response) { "anything" }
89
+
90
+ before { api.should_receive(:send_api_request).with(:end, params).and_return(response) }
91
+ it { api.end_meeting(meeting_id, moderator_password).should == response }
92
+ end
93
+
94
+ describe "#is_meeting_running?" do
95
+ let(:meeting_id) { "meeting-id" }
96
+ let(:params) { { :meetingID => meeting_id } }
97
+
98
+ context "when the meeting is running" do
99
+ let(:response) { { :running => "TRUE" } }
100
+ before { api.should_receive(:send_api_request).with(:isMeetingRunning, params).and_return(response) }
101
+ it { api.is_meeting_running?(meeting_id).should == true }
102
+ end
103
+
104
+ context "when the meeting is not running" do
105
+ let(:response) { { :running => "FALSE" } }
106
+ before { api.should_receive(:send_api_request).with(:isMeetingRunning, params).and_return(response) }
107
+ it { api.is_meeting_running?(meeting_id).should == false }
108
+ end
109
+ end
110
+
111
+ describe "#join_meeting" do
112
+ let(:meeting_id) { "meeting-id" }
113
+ let(:password) { "password" }
114
+ let(:user_name) { "user-name" }
115
+ let(:user_id) { "user-id" }
116
+ let(:web_voice_conf) { "web-voice-conf" }
117
+ let(:params) {
118
+ { :meetingID => meeting_id, :password => password, :fullName => user_name,
119
+ :userID => user_id, :webVoiceConf => web_voice_conf }
120
+ }
121
+
122
+ before { api.should_receive(:send_api_request).with(:join, params).and_return("join-return") }
123
+ it { api.join_meeting(meeting_id, user_name, password, user_id, web_voice_conf).should == "join-return" }
124
+ end
125
+
126
+ describe "#get_meeting_info" do
127
+ let(:meeting_id) { "meeting-id" }
128
+ let(:password) { "password" }
129
+ let(:params) { { :meetingID => meeting_id, :password => password } }
130
+
131
+ let(:attendee1) { { :userID => 123, :fullName => "Dexter Morgan", :role => "MODERATOR" } }
132
+ let(:attendee2) { { :userID => "id2", :fullName => "Cameron", :role => "VIEWER" } }
133
+ let(:response) {
134
+ { :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE",
135
+ :running => "TRUE", :startTime => "Thu Sep 01 17:51:42 UTC 2011", :endTime => "null",
136
+ :returncode => true, :attendees => { :attendee => [ attendee1, attendee2 ] }, :messageKey => "mkey", :message => "m" }
137
+ } # hash after the send_api_request call, before the specific formatting
138
+
139
+ let(:expected_attendee1) { { :userID => "123", :fullName => "Dexter Morgan", :role => :moderator } }
140
+ let(:expected_attendee2) { { :userID => "id2", :fullName => "Cameron", :role => :viewer } }
141
+ let(:expected_response) {
142
+ { :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false,
143
+ :running => true, :startTime => DateTime.parse("Thu Sep 01 17:51:42 UTC 2011"), :endTime => nil,
144
+ :returncode => true, :attendees => [ expected_attendee1, expected_attendee2 ], :messageKey => "mkey", :message => "m" }
145
+ } # expected return hash after all the formatting
146
+
147
+ # ps: not mocking the formatter here because it's easier to just check the results (expected_response)
148
+ before { api.should_receive(:send_api_request).with(:getMeetingInfo, params).and_return(response) }
149
+ it { api.get_meeting_info(meeting_id, password).should == expected_response }
150
+ end
151
+
152
+ describe "#get_meetings" do
153
+ let(:meeting_hash1) { { :meetingID => "Demo Meeting", :attendeePW => "ap", :moderatorPW => "mp", :hasBeenForciblyEnded => false, :running => true } }
154
+ let(:meeting_hash2) { { :meetingID => "Ended Meeting", :attendeePW => "pass", :moderatorPW => "pass", :hasBeenForciblyEnded => true, :running => false } }
155
+ let(:flattened_response) {
156
+ { :returncode => true, :meetings => [ meeting_hash1, meeting_hash2 ], :messageKey => "mkey", :message => "m" }
157
+ } # hash *after* the flatten_objects call
158
+
159
+ before {
160
+ # FIXME: how to expect a hash with a random value in the should_receive below?
161
+ api.should_receive(:send_api_request).with(:getMeetings, anything).and_return(flattened_response)
162
+ formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
163
+ formatter_mock.should_receive(:flatten_objects).with(:meetings, :meeting)
164
+ formatter_mock.should_receive(:format_meeting).with(meeting_hash1)
165
+ formatter_mock.should_receive(:format_meeting).with(meeting_hash2)
166
+ BigBlueButton::BigBlueButtonFormatter.should_receive(:new).and_return(formatter_mock)
167
+ }
168
+ it { api.get_meetings }
169
+ end
170
+
171
+ describe "#get_api_version" do
172
+ context "returns the version returned by the server" do
173
+ let(:hash) { { :returncode => true, :version => "0.7" } }
174
+ before { api.should_receive(:send_api_request).with(:index).and_return(hash) }
175
+ it { api.get_api_version.should == "0.7" }
176
+ end
177
+
178
+ context "returns an empty string when the server responds with an empty hash" do
179
+ before { api.should_receive(:send_api_request).with(:index).and_return({}) }
180
+ it { api.get_api_version.should == "" }
181
+ end
182
+ end
183
+
184
+ describe "#test_connection" do
185
+ context "returns the returncode returned by the server" do
186
+ let(:hash) { { :returncode => "any-value" } }
187
+ before { api.should_receive(:send_api_request).with(:index).and_return(hash) }
188
+ it { api.test_connection.should == "any-value" }
189
+ end
190
+ end
191
+
192
+ describe "#==" do
193
+ let(:api2) { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
194
+
195
+ context "compares attributes" do
196
+ it { api.should == api2 }
197
+ end
198
+
199
+ context "differs #debug" do
200
+ before { api2.debug = !api.debug }
201
+ it { api.should_not == api2 }
202
+ end
203
+
204
+ context "differs #salt" do
205
+ before { api2.salt = api.salt + "x" }
206
+ it { api.should_not == api2 }
207
+ end
208
+
209
+ context "differs #version" do
210
+ before { api2.version = api.version + "x" }
211
+ it { api.should_not == api2 }
212
+ end
213
+
214
+ context "differs #supported_versions" do
215
+ before { api2.supported_versions << "x" }
216
+ it { api.should_not == api2 }
217
+ end
218
+ end
219
+
220
+ describe "#last_http_response" do
221
+ # we test this through a #test_connection call
222
+
223
+ let(:request_mock) { mock }
224
+ before {
225
+ api.should_receive(:get_url)
226
+ # this return value will be stored in @http_response
227
+ api.should_receive(:send_request).and_return(request_mock)
228
+ # to return fast from #send_api_request
229
+ request_mock.should_receive(:body).and_return("")
230
+ api.test_connection
231
+ }
232
+ it { api.last_http_response.should == request_mock }
233
+ end
234
+
235
+ describe "#get_url" do
236
+
237
+ context "when method = :index" do
238
+ it { api.get_url(:index).should == api.url }
239
+ end
240
+
241
+ context "when method != :index" do
242
+ context "validates the entire url" do
243
+ context "with params" do
244
+ let(:params) { { :param1 => "value1", :param2 => "value2" } }
245
+ subject { api.get_url(:join, params) }
246
+ it { subject.should match(/#{url}\/join\?param1=value1&param2=value2/) }
247
+ end
248
+
249
+ context "without params" do
250
+ subject { api.get_url(:join) }
251
+ it { subject.should match(/#{url}\/join\?[^&]/) }
252
+ end
253
+ end
254
+
255
+ context "discards params with nil value" do
256
+ let(:params) { { :param1 => "value1", :param2 => nil } }
257
+ subject { api.get_url(:join, params) }
258
+ it { subject.should_not match(/param2=/) }
259
+ end
260
+
261
+ context "escapes all params" do
262
+ let(:params) { { :param1 => "value with spaces", :param2 => "@$" } }
263
+ subject { api.get_url(:join, params) }
264
+ it { subject.should match(/param1=value\+with\+spaces/) }
265
+ it { subject.should match(/param2=%40%24/) }
266
+ end
267
+
268
+ context "includes the checksum" do
269
+ let(:params) { { :param1 => "value1", :param2 => "value2" } }
270
+ let(:checksum) { Digest::SHA1.hexdigest("joinparam1=value1&param2=value2#{salt}") }
271
+ subject { api.get_url(:join, params) }
272
+ it { subject.should match(/checksum=#{checksum}$/) }
273
+ end
274
+ end
275
+ end
276
+
277
+ # FIXME: this complex test means that the method is too complex - try to refactor it
278
+ describe "#send_api_request" do
279
+ let(:method) { :join }
280
+ let(:params) { { :param1 => "value1" } }
281
+ let(:target_url) { "http://test-server:8080?param1=value1&checksum=12345" }
282
+ let(:make_request) { api.send_api_request(method, params) }
283
+ before { api.should_receive(:get_url).with(method, params).and_return(target_url) }
284
+
285
+ def setup_http_mock
286
+ @http_mock = mock(Net::HTTP)
287
+ Net::HTTP.should_receive(:new).with("test-server", 8080).and_return(@http_mock)
288
+ @http_mock.should_receive(:"open_timeout=").with(api.timeout)
289
+ @http_mock.should_receive(:"read_timeout=").with(api.timeout)
290
+ end
291
+
292
+ context "sets up the Net::HTTP object correctly" do
293
+ before do
294
+ setup_http_mock
295
+ response_mock = mock()
296
+ @http_mock.should_receive(:get).and_return(response_mock)
297
+ response_mock.should_receive(:body).and_return("") # so the method exits right after the setup
298
+ end
299
+ it { make_request }
300
+ end
301
+
302
+ context "handles a TimeoutError" do
303
+ before do
304
+ setup_http_mock
305
+ @http_mock.should_receive(:get) { raise TimeoutError }
306
+ end
307
+ it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
308
+ end
309
+
310
+ context "handles general Exceptions" do
311
+ before do
312
+ setup_http_mock
313
+ @http_mock.should_receive(:get) { raise Exception }
314
+ end
315
+ it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
316
+ end
317
+
318
+ context "returns an empty hash if the response body is empty" do
319
+ before do
320
+ setup_http_mock
321
+ response_mock = mock()
322
+ @http_mock.should_receive(:get).and_return(response_mock)
323
+ response_mock.should_receive(:body).and_return("")
324
+ end
325
+ it { make_request.should == { } }
326
+ end
327
+
328
+ context "hashfies and validates the response body" do
329
+ before do
330
+ setup_http_mock
331
+ response_mock = mock()
332
+ @http_mock.should_receive(:get).and_return(response_mock)
333
+ response_mock.should_receive(:body).twice.and_return("response-body")
334
+ end
335
+
336
+ context "checking if it has a :response key" do
337
+ before { Hash.should_receive(:from_xml).with("response-body").and_return({ }) }
338
+ it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
339
+ end
340
+
341
+ context "checking if it the :response key has a :returncode key" do
342
+ before { Hash.should_receive(:from_xml).with("response-body").and_return({ :response => { } }) }
343
+ it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
344
+ end
345
+ end
346
+
347
+ context "formats the response hash" do
348
+ let(:response) { { :response => { :returncode => true } } }
349
+ let(:formatted_response) { { :returncode => true } }
350
+ before do
351
+ setup_http_mock
352
+
353
+ response_mock = mock()
354
+ @http_mock.should_receive(:get).and_return(response_mock)
355
+ response_mock.should_receive(:body).twice.and_return("response-body")
356
+ Hash.should_receive(:from_xml).with("response-body").and_return(response)
357
+
358
+ # here starts the validation
359
+ formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
360
+ BigBlueButton::BigBlueButtonFormatter.should_receive(:new).with(response).and_return(formatter_mock)
361
+ formatter_mock.should_receive(:default_formatting).and_return(formatted_response)
362
+ end
363
+ it { make_request }
364
+ end
365
+
366
+ context "raise an error if the formatted response has no :returncode" do
367
+ let(:response) { { :response => { :returncode => true } } }
368
+ let(:formatted_response) { { } }
369
+ before do
370
+ setup_http_mock
371
+
372
+ response_mock = mock()
373
+ @http_mock.should_receive(:get).and_return(response_mock)
374
+ response_mock.should_receive(:body).twice.and_return("response-body")
375
+ Hash.should_receive(:from_xml).with("response-body").and_return(response)
376
+
377
+ formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
378
+ BigBlueButton::BigBlueButtonFormatter.should_receive(:new).with(response).and_return(formatter_mock)
379
+ formatter_mock.should_receive(:default_formatting).and_return(formatted_response)
380
+ end
381
+ it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
382
+ end
383
+
384
+ end
385
+
386
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe BigBlueButton::BigBlueButtonException do
4
+
5
+ describe "#key" do
6
+ subject { BigBlueButton::BigBlueButtonException.new }
7
+ it { should respond_to(:key) }
8
+ it { should respond_to("key=") }
9
+ end
10
+
11
+ describe "#to_s" do
12
+ context "when key is set" do
13
+ let(:api) { BigBlueButton::BigBlueButtonException.new("super-msg") }
14
+ before { api.key = "key-msg" }
15
+ it { api.to_s.should == "super-msg, messageKey: key-msg" }
16
+ end
17
+
18
+ context "when key is not set" do
19
+ let(:api) { BigBlueButton::BigBlueButtonException.new("super-msg") }
20
+ before { api.key = nil }
21
+ it { api.to_s.should == "super-msg" }
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ describe BigBlueButton::BigBlueButtonFormatter do
4
+
5
+ describe "#hash" do
6
+ subject { BigBlueButton::BigBlueButtonFormatter.new({}) }
7
+ it { subject.should respond_to(:hash) }
8
+ it { subject.should respond_to(:"hash=") }
9
+ end
10
+
11
+ describe "#to_stringtring" do
12
+ let(:hash) { { :param1 => "123", :param2 => 123, :param3 => true } }
13
+ subject { BigBlueButton::BigBlueButtonFormatter.new(hash) }
14
+ it { subject.to_string(:param1).should == "123" }
15
+ it { subject.to_string(:param2).should == "123" }
16
+ it { subject.to_string(:param3).should == "true" }
17
+ end
18
+
19
+ describe "#to_booleanoolean" do
20
+ let(:hash) { { :true1 => "TRUE", :true2 => "true", :false1 => "FALSE", :false2 => "false" } }
21
+ subject { BigBlueButton::BigBlueButtonFormatter.new(hash) }
22
+ it { subject.to_boolean(:true1).should be_true }
23
+ it { subject.to_boolean(:true2).should be_true }
24
+ it { subject.to_boolean(:false1).should be_false }
25
+ it { subject.to_boolean(:false2).should be_false }
26
+ end
27
+
28
+ describe "#to_datetime" do
29
+ let(:hash) { { :param1 => "Thu Sep 01 17:51:42 UTC 2011", :param2 => "Thu Sep 08", :param3 => "NULL" } }
30
+ subject { BigBlueButton::BigBlueButtonFormatter.new(hash) }
31
+ it { subject.to_datetime(:param1).should == DateTime.parse("Thu Sep 01 17:51:42 UTC 2011") }
32
+ it { subject.to_datetime(:param2).should == DateTime.parse("Thu Sep 08") }
33
+ it { subject.to_datetime(:param3).should == nil }
34
+ end
35
+
36
+ describe "#default_formatting" do
37
+ let(:input) { { :response => { :returncode => "SUCCESS", :messageKey => "mkey", :message => "m" } } }
38
+ let(:formatter) { BigBlueButton::BigBlueButtonFormatter.new(input) }
39
+
40
+ context "standard case" do
41
+ let(:expected_output) { { :returncode => true, :messageKey => "mkey", :message => "m" } }
42
+ subject { formatter.default_formatting }
43
+ it { subject.should == expected_output }
44
+ end
45
+
46
+ context "when :returncode should be false" do
47
+ before { input[:response][:returncode] = "ERROR" }
48
+ subject { formatter.default_formatting }
49
+ it { subject[:returncode].should be_false }
50
+ end
51
+
52
+ context "when :messageKey is empty" do
53
+ before { input[:response][:messageKey] = {} }
54
+ subject { formatter.default_formatting }
55
+ it { subject[:messageKey].should == "" }
56
+ end
57
+
58
+ context "when :messageKey is nil" do
59
+ before { input[:response].delete(:messageKey) }
60
+ subject { formatter.default_formatting }
61
+ it { subject[:messageKey].should == "" }
62
+ end
63
+
64
+ context "when :message is empty" do
65
+ before { input[:response][:message] = {} }
66
+ subject { formatter.default_formatting }
67
+ it { subject[:message].should == "" }
68
+ end
69
+
70
+ context "when there's no :message key" do
71
+ before { input[:response].delete(:message) }
72
+ subject { formatter.default_formatting }
73
+ it { subject[:message].should == "" }
74
+ end
75
+ end
76
+
77
+ describe "#format_meeting" do
78
+ let(:formatter) { BigBlueButton::BigBlueButtonFormatter.new({}) }
79
+ let(:hash) {
80
+ { :meetingID => 123, :moderatorPW => 111, :attendeePW => 222,
81
+ :hasBeenForciblyEnded => "FALSE", :running => "TRUE" }
82
+ }
83
+
84
+ subject { formatter.format_meeting(hash) }
85
+ it { subject[:meetingID].should == "123" }
86
+ it { subject[:moderatorPW].should == "111" }
87
+ it { subject[:attendeePW].should == "222" }
88
+ it { subject[:hasBeenForciblyEnded].should == false }
89
+ it { subject[:running].should == true }
90
+ end
91
+
92
+ describe "#format_attendee" do
93
+ let(:formatter) { BigBlueButton::BigBlueButtonFormatter.new({}) }
94
+ let(:hash) { { :userID => 123, :fullName => "Cameron", :role => "VIEWER" } }
95
+
96
+ subject { formatter.format_attendee(hash) }
97
+ it { subject[:userID].should == "123" }
98
+ it { subject[:fullName].should == "Cameron" }
99
+ it { subject[:role].should == :viewer }
100
+ end
101
+
102
+ describe "#flatten_objects" do
103
+ let(:formatter) { BigBlueButton::BigBlueButtonFormatter.new({ }) }
104
+
105
+ context "standard case" do
106
+ context "when the target key is empty" do
107
+ let(:hash) { { :objects => {} } }
108
+ before { formatter.hash = hash }
109
+ subject { formatter.flatten_objects(:objects, :object) }
110
+ it { subject.should == { :objects => [] } }
111
+ end
112
+
113
+ context "when there's only one object in the list" do
114
+ let(:object_hash) { { :id => 1 } }
115
+ let(:hash) { { :objects => { :object => object_hash } } }
116
+ before { formatter.hash = hash }
117
+ subject { formatter.flatten_objects(:objects, :object) }
118
+ it { subject.should == { :objects => [ object_hash ] } }
119
+ end
120
+
121
+ context "when there are several objects in the list" do
122
+ let(:object_hash1) { { :id => 1 } }
123
+ let(:object_hash2) { { :id => 2 } }
124
+ let(:hash) { { :objects => { :object => [ object_hash1, object_hash2 ] } } }
125
+ before { formatter.hash = hash }
126
+ subject { formatter.flatten_objects(:objects, :object) }
127
+ it { subject.should == { :objects => [ object_hash1, object_hash2 ] } }
128
+ end
129
+ end
130
+
131
+ context "using different keys" do
132
+ let(:hash1) { { :any => 1 } }
133
+ let(:hash2) { { :any => 2 } }
134
+ let(:collection_hash) { { :foos => { :bar => [ hash1, hash2 ] } } }
135
+ before { formatter.hash = collection_hash }
136
+ subject { formatter.flatten_objects(:foos, :bar) }
137
+ it { subject.should == { :foos => [ hash1, hash2 ] } }
138
+ end
139
+
140
+ end
141
+
142
+
143
+ end
@@ -0,0 +1,13 @@
1
+ # Load support files
2
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
3
+
4
+ # Load Factories
5
+ #require 'factory_girl'
6
+ #require 'forgery'
7
+ #Dir["#{ File.dirname(__FILE__)}/factories/*.rb"].each { |f| require f }
8
+
9
+ RSpec.configure do |config|
10
+ config.mock_with :rspec
11
+ end
12
+
13
+ require "bigbluebutton_api"
data/test/test.rb CHANGED
@@ -1,10 +1,13 @@
1
+ $:.unshift File.expand_path(File.dirname(__FILE__))
2
+ $:.unshift File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib')
3
+
1
4
  require 'bigbluebutton-api'
2
5
  require 'thread'
3
6
  require 'yaml'
4
7
 
5
8
  def prepare
6
9
 
7
- config_file = 'test/config.yml'
10
+ config_file = File.join(File.dirname(__FILE__), 'config.yml')
8
11
  unless File.exist? config_file
9
12
  puts config_file + " does not exists. Copy the example and configure your server."
10
13
  puts "cp test/config.yml.example test/config.yml"
@@ -135,8 +138,17 @@ def join_test
135
138
 
136
139
  end
137
140
 
141
+ def get_version_test
142
+ @api = BigBlueButton::BigBlueButtonApi.new(@config['bbb_url'], @config['bbb_salt'], nil, true)
143
+
144
+ puts
145
+ puts "---------------------------------------------------"
146
+ puts "The version of your BBB server is: #{@api.version}"
147
+ end
148
+
138
149
  begin
139
150
  prepare
140
151
  general_test
141
152
  #join_test
153
+ #get_version_test
142
154
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bigbluebutton-api-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-04-28 00:00:00.000000000Z
13
+ date: 2011-09-02 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
17
- requirement: &80178430 !ruby/object:Gem::Requirement
17
+ requirement: &20159120 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,7 +22,7 @@ dependencies:
22
22
  version: 1.4.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *80178430
25
+ version_requirements: *20159120
26
26
  description: Provides an interface to the BigBlueButton web meeting API (https://github.com/mconf/bigbluebutton-api-ruby)
27
27
  email:
28
28
  - leonardodaronco@gmail.com
@@ -35,13 +35,23 @@ extra_rdoc_files:
35
35
  - CHANGELOG.rdoc
36
36
  files:
37
37
  - .gitignore
38
+ - .rspec
39
+ - .rvmrc
38
40
  - CHANGELOG.rdoc
41
+ - Gemfile
42
+ - Gemfile.lock
39
43
  - LICENSE
40
44
  - README.rdoc
41
45
  - Rakefile
42
46
  - bigbluebutton-api-ruby.gemspec
43
- - lib/bigbluebutton-api.rb
47
+ - lib/bigbluebutton_api.rb
48
+ - lib/bigbluebutton_exception.rb
49
+ - lib/bigbluebutton_formatter.rb
44
50
  - lib/hash_to_xml.rb
51
+ - spec/bigbluebutton_api_spec.rb
52
+ - spec/bigbluebutton_exception_spec.rb
53
+ - spec/bigbluebutton_formatter_spec.rb
54
+ - spec/spec_helper.rb
45
55
  - test/config.yml.example
46
56
  - test/test.rb
47
57
  homepage: https://github.com/mconf/bigbluebutton-api-ruby/
@@ -64,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
74
  version: '0'
65
75
  requirements: []
66
76
  rubyforge_project:
67
- rubygems_version: 1.7.2
77
+ rubygems_version: 1.8.10
68
78
  signing_key:
69
79
  specification_version: 3
70
80
  summary: Provides an interface to the BigBlueButton web meeting API (https://github.com/mconf/bigbluebutton-api-ruby)