bigbluebutton-api-ruby 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.ruby-version +1 -1
- data/.travis.yml +5 -3
- data/CHANGELOG.rdoc +7 -0
- data/Gemfile.lock +5 -3
- data/LICENSE +1 -1
- data/README.rdoc +5 -2
- data/Rakefile +4 -1
- data/bigbluebutton-api-ruby.gemspec +11 -10
- data/examples/join_example.rb +0 -1
- data/features/config.yml.example +2 -4
- data/lib/bigbluebutton_api.rb +2 -2
- data/spec/bigbluebutton_api_0.9_spec.rb +33 -0
- data/spec/bigbluebutton_api_spec.rb +606 -600
- metadata +16 -24
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e8411f3d08298b647a2fa645f80aa7aa5c06ae60
|
4
|
+
data.tar.gz: 52acdabcf29a08606ff12125d7069210d05eaa72
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3f47f27947d7ae7e248bae4d5046bfcb6f1fb6e61302c595422574ca7f2b7a31fefc7950aaee8c3e5ff580172fb7dc8c7309a3c0c14e893b91d0ff429278a21
|
7
|
+
data.tar.gz: 2069dc248ece7867760884d34e2d703258c91897527a9f317edb0c0b57adf1a9b201bde4a186302c1ad42453011a1aba27b28e3298ac45c906de04655886f6ef
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.2.0
|
data/.travis.yml
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 1.4.0
|
2
|
+
|
3
|
+
* Updated default ruby version to 2.2.0.
|
4
|
+
* Add support for BigBlueButton 0.9 (includes all 0.9.x). Consists only in accepting the version
|
5
|
+
"0.9", since this new API version doesn't break compatibility with the previous version and
|
6
|
+
also doesn't add new API calls.
|
7
|
+
|
1
8
|
=== 1.3.0
|
2
9
|
|
3
10
|
* Drop support to BigBlueButton 0.7 and add BigBlueButton to 0.81. Includes support to the new API calls <tt>getDefaultConfigXML</tt> and <tt>setConfigXML</tt>.
|
data/Gemfile.lock
CHANGED
@@ -7,7 +7,7 @@ GIT
|
|
7
7
|
PATH
|
8
8
|
remote: .
|
9
9
|
specs:
|
10
|
-
bigbluebutton-api-ruby (1.
|
10
|
+
bigbluebutton-api-ruby (1.4.0)
|
11
11
|
xml-simple (>= 1.1.1)
|
12
12
|
|
13
13
|
GEM
|
@@ -39,12 +39,14 @@ GEM
|
|
39
39
|
forgery (0.5.0)
|
40
40
|
gherkin (2.9.3)
|
41
41
|
json (>= 1.4.6)
|
42
|
-
json (1.
|
42
|
+
json (1.8.3)
|
43
43
|
libwebsocket (0.1.3)
|
44
44
|
addressable
|
45
45
|
mime-types (1.18)
|
46
|
+
mini_portile (0.6.2)
|
46
47
|
multi_json (1.3.4)
|
47
|
-
nokogiri (1.
|
48
|
+
nokogiri (1.6.6.2)
|
49
|
+
mini_portile (~> 0.6.0)
|
48
50
|
rack (1.4.1)
|
49
51
|
rack-test (0.6.1)
|
50
52
|
rack (>= 1.0)
|
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -22,8 +22,9 @@ A few features it has:
|
|
22
22
|
|
23
23
|
The current version of this gem supports <em>all</em> the following versions of BigBlueButton:
|
24
24
|
|
25
|
-
* 0.
|
25
|
+
* 0.9 (includes all 0.9.x)
|
26
26
|
* 0.81
|
27
|
+
* 0.8
|
27
28
|
|
28
29
|
Older versions:
|
29
30
|
|
@@ -34,8 +35,10 @@ Older versions:
|
|
34
35
|
|
35
36
|
Tested in rubies:
|
36
37
|
|
38
|
+
* ruby-2.2.0 *recommended*
|
39
|
+
* ruby-2.1.2
|
37
40
|
* ruby-2.0.0 (p353)
|
38
|
-
* ruby-1.9.3 (p484)
|
41
|
+
* ruby-1.9.3 (p484)
|
39
42
|
* ruby-1.9.2 (p290)
|
40
43
|
|
41
44
|
Use these versions to be sure it will work. Other patches of these rubies (e.g. ruby 1.9.3-p194) should work as well.
|
data/Rakefile
CHANGED
@@ -11,13 +11,16 @@ RSpec::Core::RakeTask.new(:spec)
|
|
11
11
|
|
12
12
|
Cucumber::Rake::Task.new do |t|
|
13
13
|
|
14
|
+
# Disable all features that need the bot. It isn't working since BigBlueButton 0.81.
|
15
|
+
prepend = "--tags ~@need-bot"
|
16
|
+
|
14
17
|
# in jruby the class BigBlueButtonBot doesn't work (it uses fork)
|
15
18
|
if defined?(RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
|
16
19
|
puts "Jruby detected, ignoring features with @need-bot"
|
17
20
|
prepend = "--tags ~@need-bot"
|
18
21
|
end
|
19
22
|
|
20
|
-
# defaults to
|
23
|
+
# defaults to the latest version, that runs all tests
|
21
24
|
# if set to 0.8 only, won't run tests for newer versions
|
22
25
|
if ENV["V"] == "0.8" or ENV["VERSION"] == "0.8"
|
23
26
|
t.cucumber_opts = "--format pretty --tags ~@wip --tags @version-all #{prepend}"
|
@@ -1,17 +1,18 @@
|
|
1
1
|
$:.push File.expand_path("../lib", __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name
|
5
|
-
s.version
|
4
|
+
s.name = 'bigbluebutton-api-ruby'
|
5
|
+
s.version = '1.4.0'
|
6
|
+
s.licenses = ['MIT']
|
6
7
|
s.extra_rdoc_files = ['README.rdoc', 'LICENSE', 'LICENSE_003', 'CHANGELOG.rdoc']
|
7
|
-
s.summary
|
8
|
-
s.description
|
9
|
-
s.authors
|
10
|
-
s.email
|
11
|
-
s.homepage
|
12
|
-
s.bindir
|
13
|
-
s.files
|
14
|
-
s.require_paths
|
8
|
+
s.summary = 'Provides an interface to the BigBlueButton web meeting API (https://github.com/mconf/bigbluebutton-api-ruby)'
|
9
|
+
s.description = s.summary
|
10
|
+
s.authors = ['Leonardo Crauss Daronco', 'Joe Kinsella']
|
11
|
+
s.email = ['leonardodaronco@gmail.com', 'joe.kinsella@gmail.com']
|
12
|
+
s.homepage = "https://github.com/mconf/bigbluebutton-api-ruby/"
|
13
|
+
s.bindir = "bin"
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.require_paths = ["lib"]
|
15
16
|
|
16
17
|
s.add_runtime_dependency('xml-simple', '>= 1.1.1')
|
17
18
|
end
|
data/examples/join_example.rb
CHANGED
@@ -10,7 +10,6 @@ begin
|
|
10
10
|
meeting_name = "Test Meeting"
|
11
11
|
meeting_id = "test-meeting"
|
12
12
|
moderator_name = "House"
|
13
|
-
attendee_name = "Cameron"
|
14
13
|
unless @api.is_meeting_running?(meeting_id)
|
15
14
|
puts "---------------------------------------------------"
|
16
15
|
options = { :moderatorPW => "54321",
|
data/features/config.yml.example
CHANGED
@@ -10,13 +10,11 @@ timeout_ending: 30
|
|
10
10
|
timeout_bot_start: 60
|
11
11
|
|
12
12
|
servers:
|
13
|
-
test-install-
|
13
|
+
test-install-091:
|
14
14
|
salt: '8cd8ef52e8e101574e400365b55e11a6'
|
15
15
|
url: 'http://test-install.blindsidenetworks.com/bigbluebutton/api'
|
16
|
-
version: '0.
|
17
|
-
mobile_salt: '03b07' # needed for >= 0.8
|
16
|
+
version: '0.9'
|
18
17
|
bbb-08:
|
19
18
|
salt: 'lka98f52e8akdlsoie400365b55e98s7'
|
20
19
|
url: 'http://yourserver.com/bigbluebutton/api'
|
21
20
|
version: '0.8'
|
22
|
-
mobile_salt: '03b07' # needed for >= 0.8
|
data/lib/bigbluebutton_api.rb
CHANGED
@@ -67,8 +67,8 @@ module BigBlueButton
|
|
67
67
|
# url:: URL to a BigBlueButton server (e.g. http://demo.bigbluebutton.org/bigbluebutton/api)
|
68
68
|
# salt:: Secret salt for this server
|
69
69
|
# version:: API version e.g. 0.81
|
70
|
-
def initialize(url, salt, version='0.
|
71
|
-
@supported_versions = ['0.8', '0.81']
|
70
|
+
def initialize(url, salt, version='0.9', debug=false)
|
71
|
+
@supported_versions = ['0.8', '0.81', '0.9']
|
72
72
|
@url = url
|
73
73
|
@salt = salt
|
74
74
|
@debug = debug
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Tests for BBB API version 0.81
|
4
|
+
describe BigBlueButton::BigBlueButtonApi do
|
5
|
+
|
6
|
+
# default variables and API object for all tests
|
7
|
+
let(:url) { "http://server.com" }
|
8
|
+
let(:salt) { "1234567890abcdefghijkl" }
|
9
|
+
let(:version) { "0.9" }
|
10
|
+
let(:debug) { false }
|
11
|
+
let(:api) { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
|
12
|
+
|
13
|
+
describe "#create_meeting" do
|
14
|
+
context "accepts the new parameters" do
|
15
|
+
let(:req_params) {
|
16
|
+
{ :name => "name", :meetingID => "meeting-id",
|
17
|
+
:moderatorOnlyMessage => "my-msg", :autoStartRecording => "false",
|
18
|
+
:allowStartStopRecording => "true"
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
before { api.should_receive(:send_api_request).with(:create, req_params) }
|
23
|
+
it {
|
24
|
+
options = {
|
25
|
+
:moderatorOnlyMessage => "my-msg",
|
26
|
+
:autoStartRecording => "false",
|
27
|
+
:allowStartStopRecording => "true"
|
28
|
+
}
|
29
|
+
api.create_meeting("name", "meeting-id", options)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -4,728 +4,734 @@ require 'spec_helper'
|
|
4
4
|
# there are separate files with more tests.
|
5
5
|
describe BigBlueButton::BigBlueButtonApi do
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
7
|
+
shared_examples_for "BigBlueButtonApi" do |version|
|
8
|
+
|
9
|
+
# default variables and API object for all tests
|
10
|
+
let(:url) { "http://server.com" }
|
11
|
+
let(:salt) { "1234567890abcdefghijkl" }
|
12
|
+
let(:debug) { false }
|
13
|
+
let(:api) { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
|
14
|
+
|
15
|
+
describe "#initialize" do
|
16
|
+
context "standard initialization" do
|
17
|
+
subject { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
|
18
|
+
it { subject.url.should == url }
|
19
|
+
it { subject.salt.should == salt }
|
20
|
+
it { subject.version.should == version }
|
21
|
+
it { subject.debug.should == debug }
|
22
|
+
it { subject.timeout.should == 10 }
|
23
|
+
it { subject.supported_versions.should include("0.8") }
|
24
|
+
it { subject.supported_versions.should include("0.81") }
|
25
|
+
it { subject.supported_versions.should include("0.9") }
|
26
|
+
it { subject.request_headers.should == {} }
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
context "when the version is not informed, get it from the BBB server" do
|
30
|
+
before { BigBlueButton::BigBlueButtonApi.any_instance.should_receive(:get_api_version).and_return("0.8") }
|
31
|
+
subject { BigBlueButton::BigBlueButtonApi.new(url, salt, nil) }
|
32
|
+
it { subject.version.should == "0.8" }
|
33
|
+
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
it "when the version is not supported raise an error" do
|
36
|
+
expect {
|
37
|
+
BigBlueButton::BigBlueButtonApi.new(url, salt, "0.not-supported", nil)
|
38
|
+
}.to raise_error(BigBlueButton::BigBlueButtonException)
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
context "current supported versions" do
|
42
|
+
subject { BigBlueButton::BigBlueButtonApi.new(url, salt) }
|
43
|
+
it { subject.supported_versions.should == ["0.8", "0.81", "0.9"] }
|
44
|
+
end
|
42
45
|
end
|
43
|
-
end
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
47
|
+
describe "#create_meeting" do
|
48
|
+
context "standard case" do
|
49
|
+
let(:req_params) {
|
50
|
+
{ :name => "name", :meetingID => "meeting-id", :moderatorPW => "mp", :attendeePW => "ap",
|
51
|
+
:welcome => "Welcome!", :dialNumber => 12345678, :logoutURL => "http://example.com",
|
52
|
+
:maxParticipants => 25, :voiceBridge => 12345, :webVoice => "12345abc", :record => "true" }
|
53
|
+
}
|
54
|
+
let(:req_response) {
|
55
|
+
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE" }
|
56
|
+
}
|
57
|
+
let(:final_response) {
|
58
|
+
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false }
|
59
|
+
}
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
61
|
+
# ps: not mocking the formatter here because it's easier to just check the results (final_response)
|
62
|
+
before { api.should_receive(:send_api_request).with(:create, req_params).and_return(req_response) }
|
63
|
+
subject {
|
64
|
+
options = { :moderatorPW => "mp", :attendeePW => "ap", :welcome => "Welcome!",
|
65
|
+
:dialNumber => 12345678, :logoutURL => "http://example.com", :maxParticipants => 25,
|
66
|
+
:voiceBridge => 12345, :webVoice => "12345abc", :record => "true" }
|
67
|
+
api.create_meeting("name", "meeting-id", options)
|
68
|
+
}
|
69
|
+
it { subject.should == final_response }
|
70
|
+
end
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
72
|
+
context "accepts non standard options" do
|
73
|
+
let(:params) {
|
74
|
+
{ :name => "name", :meetingID => "meeting-id",
|
75
|
+
:moderatorPW => "mp", :attendeePW => "ap", :nonStandard => 1 }
|
76
|
+
}
|
77
|
+
before { api.should_receive(:send_api_request).with(:create, params) }
|
78
|
+
it { api.create_meeting("name", "meeting-id", params) }
|
79
|
+
end
|
78
80
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
81
|
+
context "accepts :record as boolean" do
|
82
|
+
let(:req_params) {
|
83
|
+
{ :name => "name", :meetingID => "meeting-id",
|
84
|
+
:moderatorPW => "mp", :attendeePW => "ap", :record => "true" }
|
85
|
+
}
|
86
|
+
before { api.should_receive(:send_api_request).with(:create, req_params) }
|
87
|
+
it {
|
88
|
+
params = { :name => "name", :meetingID => "meeting-id",
|
89
|
+
:moderatorPW => "mp", :attendeePW => "ap", :record => true }
|
90
|
+
api.create_meeting("name", "meeting-id", params)
|
91
|
+
}
|
92
|
+
end
|
91
93
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
94
|
+
context "with modules" do
|
95
|
+
let(:req_params) {
|
96
|
+
{ :name => "name", :meetingID => "meeting-id", :moderatorPW => "mp", :attendeePW => "ap" }
|
97
|
+
}
|
98
|
+
let(:req_response) {
|
99
|
+
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE", :createTime => "123123123" }
|
100
|
+
}
|
101
|
+
let(:final_response) {
|
102
|
+
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false, :createTime => 123123123 }
|
103
|
+
}
|
104
|
+
let(:modules) {
|
105
|
+
m = BigBlueButton::BigBlueButtonModules.new
|
106
|
+
m.add_presentation(:url, "http://www.samplepdf.com/sample.pdf")
|
107
|
+
m.add_presentation(:url, "http://www.samplepdf.com/sample2.pdf")
|
108
|
+
m.add_presentation(:base64, "JVBERi0xLjQKJ....[clipped here]....0CiUlRU9GCg==", "first-class.pdf")
|
109
|
+
m
|
110
|
+
}
|
109
111
|
|
110
|
-
|
111
|
-
|
112
|
+
before {
|
113
|
+
api.should_receive(:send_api_request).with(:create, req_params, modules.to_xml).
|
112
114
|
and_return(req_response)
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
115
|
+
}
|
116
|
+
subject {
|
117
|
+
options = { :moderatorPW => "mp", :attendeePW => "ap" }
|
118
|
+
api.create_meeting("name", "meeting-id", options, modules)
|
119
|
+
}
|
120
|
+
it { subject.should == final_response }
|
121
|
+
end
|
120
122
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
123
|
+
context "without modules" do
|
124
|
+
let(:req_params) {
|
125
|
+
{ :name => "name", :meetingID => "meeting-id", :moderatorPW => "mp", :attendeePW => "ap",
|
126
|
+
:welcome => "Welcome!", :dialNumber => 12345678, :logoutURL => "http://example.com",
|
127
|
+
:maxParticipants => 25, :voiceBridge => 12345, :record => "true", :duration => 20,
|
128
|
+
:meta_1 => "meta1", :meta_2 => "meta2" }
|
129
|
+
}
|
130
|
+
let(:req_response) {
|
131
|
+
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE", :createTime => "123123123" }
|
132
|
+
}
|
133
|
+
let(:final_response) {
|
134
|
+
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false, :createTime => 123123123 }
|
135
|
+
}
|
134
136
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
137
|
+
before { api.should_receive(:send_api_request).with(:create, req_params).and_return(req_response) }
|
138
|
+
subject {
|
139
|
+
options = { :moderatorPW => "mp", :attendeePW => "ap", :welcome => "Welcome!", :dialNumber => 12345678,
|
140
|
+
:logoutURL => "http://example.com", :maxParticipants => 25, :voiceBridge => 12345, :record => true,
|
141
|
+
:duration => 20, :meta_1 => "meta1", :meta_2 => "meta2" }
|
142
|
+
api.create_meeting("name", "meeting-id", options)
|
143
|
+
}
|
144
|
+
it { subject.should == final_response }
|
145
|
+
end
|
143
146
|
end
|
144
|
-
end
|
145
147
|
|
146
|
-
|
147
|
-
|
148
|
-
|
148
|
+
describe "#end_meeting" do
|
149
|
+
let(:meeting_id) { "meeting-id" }
|
150
|
+
let(:moderator_password) { "password" }
|
149
151
|
|
150
|
-
|
151
|
-
|
152
|
-
|
152
|
+
context "standard case" do
|
153
|
+
let(:params) { { :meetingID => meeting_id, :password => moderator_password } }
|
154
|
+
let(:response) { "anything" }
|
153
155
|
|
154
|
-
|
155
|
-
|
156
|
-
|
156
|
+
before { api.should_receive(:send_api_request).with(:end, params).and_return(response) }
|
157
|
+
it { api.end_meeting(meeting_id, moderator_password).should == response }
|
158
|
+
end
|
157
159
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
160
|
+
context "accepts non standard options" do
|
161
|
+
let(:params_in) {
|
162
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
163
|
+
}
|
164
|
+
let(:params_out) {
|
165
|
+
{ :meetingID => meeting_id, :password => moderator_password,
|
166
|
+
:anything1 => "anything-1", :anything2 => 2 }
|
167
|
+
}
|
168
|
+
before { api.should_receive(:send_api_request).with(:end, params_out) }
|
169
|
+
it { api.end_meeting(meeting_id, moderator_password, params_in) }
|
170
|
+
end
|
168
171
|
end
|
169
|
-
end
|
170
172
|
|
171
|
-
|
172
|
-
|
173
|
-
|
173
|
+
describe "#is_meeting_running?" do
|
174
|
+
let(:meeting_id) { "meeting-id" }
|
175
|
+
let(:params) { { :meetingID => meeting_id } }
|
174
176
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
177
|
+
context "when the meeting is running" do
|
178
|
+
let(:response) { { :running => "TRUE" } }
|
179
|
+
before { api.should_receive(:send_api_request).with(:isMeetingRunning, params).and_return(response) }
|
180
|
+
it { api.is_meeting_running?(meeting_id).should == true }
|
181
|
+
end
|
180
182
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
183
|
+
context "when the meeting is not running" do
|
184
|
+
let(:response) { { :running => "FALSE" } }
|
185
|
+
before { api.should_receive(:send_api_request).with(:isMeetingRunning, params).and_return(response) }
|
186
|
+
it { api.is_meeting_running?(meeting_id).should == false }
|
187
|
+
end
|
186
188
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
189
|
+
context "accepts non standard options" do
|
190
|
+
let(:params_in) {
|
191
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
192
|
+
}
|
193
|
+
let(:params_out) {
|
194
|
+
{ :meetingID => meeting_id, :anything1 => "anything-1", :anything2 => 2 }
|
195
|
+
}
|
196
|
+
before { api.should_receive(:send_api_request).with(:isMeetingRunning, params_out) }
|
197
|
+
it { api.is_meeting_running?(meeting_id, params_in) }
|
198
|
+
end
|
196
199
|
end
|
197
|
-
end
|
198
200
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
201
|
+
describe "#join_meeting_url" do
|
202
|
+
context "standard case" do
|
203
|
+
let(:params) {
|
204
|
+
{ :meetingID => "meeting-id", :password => "pw", :fullName => "Name",
|
205
|
+
:userID => "id123", :webVoiceConf => 12345678, :createTime => 9876543 }
|
206
|
+
}
|
205
207
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
208
|
+
before { api.should_receive(:get_url).with(:join, params).and_return("test-url") }
|
209
|
+
it {
|
210
|
+
options = { :userID => "id123", :webVoiceConf => 12345678, :createTime => 9876543 }
|
211
|
+
api.join_meeting_url("meeting-id", "Name", "pw", options).should == "test-url"
|
212
|
+
}
|
213
|
+
end
|
212
214
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
215
|
+
context "accepts non standard options" do
|
216
|
+
let(:params) {
|
217
|
+
{ :meetingID => "meeting-id", :password => "pw",
|
218
|
+
:fullName => "Name", :userID => "id123", :nonStandard => 1 }
|
219
|
+
}
|
220
|
+
before { api.should_receive(:get_url).with(:join, params) }
|
221
|
+
it { api.join_meeting_url("meeting-id", "Name", "pw", params) }
|
222
|
+
end
|
220
223
|
end
|
221
|
-
end
|
222
|
-
|
223
|
-
describe "#get_meeting_info" do
|
224
|
-
let(:meeting_id) { "meeting-id" }
|
225
|
-
let(:password) { "password" }
|
226
224
|
|
227
|
-
|
228
|
-
let(:
|
225
|
+
describe "#get_meeting_info" do
|
226
|
+
let(:meeting_id) { "meeting-id" }
|
227
|
+
let(:password) { "password" }
|
228
|
+
|
229
|
+
context "standard case" do
|
230
|
+
let(:params) { { :meetingID => meeting_id, :password => password } }
|
231
|
+
|
232
|
+
let(:attendee1) { { :userID => 123, :fullName => "Dexter Morgan", :role => "MODERATOR" } }
|
233
|
+
let(:attendee2) { { :userID => "id2", :fullName => "Cameron", :role => "VIEWER" } }
|
234
|
+
let(:response) {
|
235
|
+
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE",
|
236
|
+
:running => "TRUE", :startTime => "Thu Sep 01 17:51:42 UTC 2011", :endTime => "null",
|
237
|
+
:returncode => true, :attendees => { :attendee => [ attendee1, attendee2 ] },
|
238
|
+
:messageKey => "mkey", :message => "m", :participantCount => "50", :moderatorCount => "3",
|
239
|
+
:meetingName => "meeting-name", :maxUsers => "100", :voiceBridge => "12341234", :createTime => "123123123",
|
240
|
+
:recording => "false", :meta_1 => "abc", :meta_2 => "2" }
|
241
|
+
} # hash after the send_api_request call, before the formatting
|
242
|
+
|
243
|
+
let(:expected_attendee1) { { :userID => "123", :fullName => "Dexter Morgan", :role => :moderator } }
|
244
|
+
let(:expected_attendee2) { { :userID => "id2", :fullName => "Cameron", :role => :viewer } }
|
245
|
+
let(:final_response) {
|
246
|
+
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false,
|
247
|
+
:running => true, :startTime => DateTime.parse("Thu Sep 01 17:51:42 UTC 2011"), :endTime => nil,
|
248
|
+
:returncode => true, :attendees => [ expected_attendee1, expected_attendee2 ],
|
249
|
+
:messageKey => "mkey", :message => "m", :participantCount => 50, :moderatorCount => 3,
|
250
|
+
:meetingName => "meeting-name", :maxUsers => 100, :voiceBridge => 12341234, :createTime => 123123123,
|
251
|
+
:recording => false, :meta_1 => "abc", :meta_2 => "2" }
|
252
|
+
} # expected return hash after all the formatting
|
253
|
+
|
254
|
+
# ps: not mocking the formatter here because it's easier to just check the results (final_response)
|
255
|
+
before { api.should_receive(:send_api_request).with(:getMeetingInfo, params).and_return(response) }
|
256
|
+
it { api.get_meeting_info(meeting_id, password).should == final_response }
|
257
|
+
end
|
229
258
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
:
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
let(:expected_attendee1) { { :userID => "123", :fullName => "Dexter Morgan", :role => :moderator } }
|
242
|
-
let(:expected_attendee2) { { :userID => "id2", :fullName => "Cameron", :role => :viewer } }
|
243
|
-
let(:final_response) {
|
244
|
-
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false,
|
245
|
-
:running => true, :startTime => DateTime.parse("Thu Sep 01 17:51:42 UTC 2011"), :endTime => nil,
|
246
|
-
:returncode => true, :attendees => [ expected_attendee1, expected_attendee2 ],
|
247
|
-
:messageKey => "mkey", :message => "m", :participantCount => 50, :moderatorCount => 3,
|
248
|
-
:meetingName => "meeting-name", :maxUsers => 100, :voiceBridge => 12341234, :createTime => 123123123,
|
249
|
-
:recording => false, :meta_1 => "abc", :meta_2 => "2" }
|
250
|
-
} # expected return hash after all the formatting
|
251
|
-
|
252
|
-
# ps: not mocking the formatter here because it's easier to just check the results (final_response)
|
253
|
-
before { api.should_receive(:send_api_request).with(:getMeetingInfo, params).and_return(response) }
|
254
|
-
it { api.get_meeting_info(meeting_id, password).should == final_response }
|
259
|
+
context "accepts non standard options" do
|
260
|
+
let(:params_in) {
|
261
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
262
|
+
}
|
263
|
+
let(:params_out) {
|
264
|
+
{ :meetingID => meeting_id, :password => password,
|
265
|
+
:anything1 => "anything-1", :anything2 => 2 }
|
266
|
+
}
|
267
|
+
before { api.should_receive(:send_api_request).with(:getMeetingInfo, params_out).and_return({}) }
|
268
|
+
it { api.get_meeting_info(meeting_id, password, params_in) }
|
269
|
+
end
|
255
270
|
end
|
256
271
|
|
257
|
-
|
258
|
-
|
259
|
-
{ :
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
272
|
+
describe "#get_meetings" do
|
273
|
+
context "standard case" do
|
274
|
+
let(:meeting_hash1) { { :meetingID => "Demo Meeting", :attendeePW => "ap", :moderatorPW => "mp", :hasBeenForciblyEnded => false, :running => true } }
|
275
|
+
let(:meeting_hash2) { { :meetingID => "Ended Meeting", :attendeePW => "pass", :moderatorPW => "pass", :hasBeenForciblyEnded => true, :running => false } }
|
276
|
+
let(:flattened_response) {
|
277
|
+
{ :returncode => true, :meetings => [ meeting_hash1, meeting_hash2 ], :messageKey => "mkey", :message => "m" }
|
278
|
+
} # hash *after* the flatten_objects call
|
279
|
+
|
280
|
+
before {
|
281
|
+
api.should_receive(:send_api_request).with(:getMeetings, {}).
|
282
|
+
and_return(flattened_response)
|
283
|
+
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
284
|
+
formatter_mock.should_receive(:flatten_objects).with(:meetings, :meeting)
|
285
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).and_return(formatter_mock)
|
286
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_meeting).with(meeting_hash1)
|
287
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_meeting).with(meeting_hash2)
|
288
|
+
}
|
289
|
+
it { api.get_meetings }
|
290
|
+
end
|
291
|
+
|
292
|
+
context "accepts non standard options" do
|
293
|
+
let(:params) {
|
294
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
295
|
+
}
|
296
|
+
before { api.should_receive(:send_api_request).with(:getMeetings, params).and_return({}) }
|
297
|
+
it { api.get_meetings(params) }
|
298
|
+
end
|
267
299
|
end
|
268
|
-
end
|
269
300
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
} # hash *after* the flatten_objects call
|
301
|
+
describe "#get_api_version" do
|
302
|
+
context "returns the version returned by the server" do
|
303
|
+
let(:hash) { { :returncode => true, :version => "0.8" } }
|
304
|
+
before { api.should_receive(:send_api_request).with(:index).and_return(hash) }
|
305
|
+
it { api.get_api_version.should == "0.8" }
|
306
|
+
end
|
277
307
|
|
278
|
-
|
279
|
-
api.should_receive(:send_api_request).with(:
|
280
|
-
|
281
|
-
|
282
|
-
formatter_mock.should_receive(:flatten_objects).with(:meetings, :meeting)
|
283
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).and_return(formatter_mock)
|
284
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_meeting).with(meeting_hash1)
|
285
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_meeting).with(meeting_hash2)
|
286
|
-
}
|
287
|
-
it { api.get_meetings }
|
308
|
+
context "returns an empty string when the server responds with an empty hash" do
|
309
|
+
before { api.should_receive(:send_api_request).with(:index).and_return({}) }
|
310
|
+
it { api.get_api_version.should == "" }
|
311
|
+
end
|
288
312
|
end
|
289
313
|
|
290
|
-
|
291
|
-
|
292
|
-
{ :
|
293
|
-
|
294
|
-
|
295
|
-
|
314
|
+
describe "#test_connection" do
|
315
|
+
context "returns the returncode returned by the server" do
|
316
|
+
let(:hash) { { :returncode => "any-value" } }
|
317
|
+
before { api.should_receive(:send_api_request).with(:index).and_return(hash) }
|
318
|
+
it { api.test_connection.should == "any-value" }
|
319
|
+
end
|
296
320
|
end
|
297
|
-
end
|
298
321
|
|
299
|
-
|
300
|
-
|
301
|
-
let(:hash) { { :returncode => true, :version => "0.8" } }
|
302
|
-
before { api.should_receive(:send_api_request).with(:index).and_return(hash) }
|
303
|
-
it { api.get_api_version.should == "0.8" }
|
304
|
-
end
|
322
|
+
describe "#==" do
|
323
|
+
let(:api2) { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
|
305
324
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
end
|
310
|
-
end
|
325
|
+
context "compares attributes" do
|
326
|
+
it { api.should == api2 }
|
327
|
+
end
|
311
328
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
it { api.test_connection.should == "any-value" }
|
317
|
-
end
|
318
|
-
end
|
329
|
+
context "differs #debug" do
|
330
|
+
before { api2.debug = !api.debug }
|
331
|
+
it { api.should_not == api2 }
|
332
|
+
end
|
319
333
|
|
320
|
-
|
321
|
-
|
334
|
+
context "differs #salt" do
|
335
|
+
before { api2.salt = api.salt + "x" }
|
336
|
+
it { api.should_not == api2 }
|
337
|
+
end
|
322
338
|
|
323
|
-
|
324
|
-
|
325
|
-
|
339
|
+
context "differs #version" do
|
340
|
+
before { api2.version = api.version + "x" }
|
341
|
+
it { api.should_not == api2 }
|
342
|
+
end
|
326
343
|
|
327
|
-
|
328
|
-
|
329
|
-
|
344
|
+
context "differs #supported_versions" do
|
345
|
+
before { api2.supported_versions << "x" }
|
346
|
+
it { api.should_not == api2 }
|
347
|
+
end
|
330
348
|
end
|
331
349
|
|
332
|
-
|
333
|
-
|
334
|
-
it { api.should_not == api2 }
|
335
|
-
end
|
350
|
+
describe "#last_http_response" do
|
351
|
+
# we test this through a #test_connection call
|
336
352
|
|
337
|
-
|
338
|
-
before {
|
339
|
-
|
353
|
+
let(:request_mock) { mock }
|
354
|
+
before {
|
355
|
+
api.should_receive(:get_url)
|
356
|
+
# this return value will be stored in @http_response
|
357
|
+
api.should_receive(:send_request).and_return(request_mock)
|
358
|
+
# to return fast from #send_api_request
|
359
|
+
request_mock.should_receive(:body).and_return("")
|
360
|
+
api.test_connection
|
361
|
+
}
|
362
|
+
it { api.last_http_response.should == request_mock }
|
340
363
|
end
|
341
364
|
|
342
|
-
|
343
|
-
|
344
|
-
|
365
|
+
describe "#last_xml_response" do
|
366
|
+
# we test this through a #test_connection call
|
367
|
+
|
368
|
+
let(:request_mock) { mock }
|
369
|
+
let(:expected_xml) { "<response><returncode>SUCCESS</returncode></response>" }
|
370
|
+
before {
|
371
|
+
api.should_receive(:get_url)
|
372
|
+
api.should_receive(:send_request).and_return(request_mock)
|
373
|
+
request_mock.should_receive(:body).at_least(1).and_return(expected_xml)
|
374
|
+
api.test_connection
|
375
|
+
}
|
376
|
+
it { api.last_xml_response.should == expected_xml }
|
345
377
|
end
|
346
|
-
end
|
347
378
|
|
348
|
-
|
349
|
-
# we test this through a #test_connection call
|
350
|
-
|
351
|
-
let(:request_mock) { mock }
|
352
|
-
before {
|
353
|
-
api.should_receive(:get_url)
|
354
|
-
# this return value will be stored in @http_response
|
355
|
-
api.should_receive(:send_request).and_return(request_mock)
|
356
|
-
# to return fast from #send_api_request
|
357
|
-
request_mock.should_receive(:body).and_return("")
|
358
|
-
api.test_connection
|
359
|
-
}
|
360
|
-
it { api.last_http_response.should == request_mock }
|
361
|
-
end
|
379
|
+
describe "#get_url" do
|
362
380
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
let(:request_mock) { mock }
|
367
|
-
let(:expected_xml) { "<response><returncode>SUCCESS</returncode></response>" }
|
368
|
-
before {
|
369
|
-
api.should_receive(:get_url)
|
370
|
-
api.should_receive(:send_request).and_return(request_mock)
|
371
|
-
request_mock.should_receive(:body).at_least(1).and_return(expected_xml)
|
372
|
-
api.test_connection
|
373
|
-
}
|
374
|
-
it { api.last_xml_response.should == expected_xml }
|
375
|
-
end
|
381
|
+
context "when method = :index" do
|
382
|
+
it { api.get_url(:index).should == api.url }
|
383
|
+
end
|
376
384
|
|
377
|
-
|
385
|
+
context "when method != :index" do
|
386
|
+
context "validates the entire url" do
|
387
|
+
context "with params" do
|
388
|
+
let(:params) { { :param1 => "value1", :param2 => "value2" } }
|
389
|
+
subject { api.get_url(:join, params) }
|
390
|
+
it {
|
391
|
+
# the hash can be sorted differently depending on the ruby version
|
392
|
+
if params.map{ |k,v| "#{k}" }.join =~ /^param1/
|
393
|
+
subject.should match(/#{url}\/join\?param1=value1¶m2=value2/)
|
394
|
+
else
|
395
|
+
subject.should match(/#{url}\/join\?param2=value2¶m1=value1/)
|
396
|
+
end
|
397
|
+
}
|
398
|
+
end
|
378
399
|
|
379
|
-
|
380
|
-
|
381
|
-
|
400
|
+
context "without params" do
|
401
|
+
subject { api.get_url(:join) }
|
402
|
+
it { subject.should match(/#{url}\/join\?[^&]/) }
|
403
|
+
end
|
404
|
+
end
|
382
405
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
406
|
+
context "discards params with nil value" do
|
407
|
+
let(:params) { { :param1 => "value1", :param2 => nil } }
|
408
|
+
subject { api.get_url(:join, params) }
|
409
|
+
it { subject.should_not match(/param2=/) }
|
410
|
+
end
|
411
|
+
|
412
|
+
context "escapes all params" do
|
413
|
+
let(:params) { { :param1 => "value with spaces", :param2 => "@$" } }
|
387
414
|
subject { api.get_url(:join, params) }
|
388
|
-
it {
|
415
|
+
it { subject.should match(/param1=value\+with\+spaces/) }
|
416
|
+
it { subject.should match(/param2=%40%24/) }
|
417
|
+
end
|
418
|
+
|
419
|
+
context "includes the checksum" do
|
420
|
+
let(:params) { { :param1 => "value1", :param2 => "value2" } }
|
421
|
+
let(:checksum) {
|
389
422
|
# the hash can be sorted differently depending on the ruby version
|
390
423
|
if params.map{ |k,v| "#{k}" }.join =~ /^param1/
|
391
|
-
|
424
|
+
"67882ae54f49600f56f358c10d24697ef7d8c6b2"
|
392
425
|
else
|
393
|
-
|
426
|
+
"85a54e28e4ec18bfdcb214a73f74d35b09a84176"
|
394
427
|
end
|
395
428
|
}
|
396
|
-
|
397
|
-
|
398
|
-
context "without params" do
|
399
|
-
subject { api.get_url(:join) }
|
400
|
-
it { subject.should match(/#{url}\/join\?[^&]/) }
|
429
|
+
subject { api.get_url(:join, params) }
|
430
|
+
it { subject.should match(/checksum=#{checksum}$/) }
|
401
431
|
end
|
402
432
|
end
|
433
|
+
end
|
403
434
|
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
435
|
+
describe "#send_api_request" do
|
436
|
+
let(:method) { :join }
|
437
|
+
let(:params) { { :param1 => "value1" } }
|
438
|
+
let(:data) { "any data" }
|
439
|
+
let(:url) { "http://test-server:8080?param1=value1&checksum=12345" }
|
440
|
+
let(:make_request) { api.send_api_request(method, params, data) }
|
441
|
+
let(:response_mock) { mock() } # mock of what send_request() would return
|
409
442
|
|
410
|
-
|
411
|
-
let(:params) { { :param1 => "value with spaces", :param2 => "@$" } }
|
412
|
-
subject { api.get_url(:join, params) }
|
413
|
-
it { subject.should match(/param1=value\+with\+spaces/) }
|
414
|
-
it { subject.should match(/param2=%40%24/) }
|
415
|
-
end
|
443
|
+
before { api.should_receive(:get_url).with(method, params).and_return(url) }
|
416
444
|
|
417
|
-
context "
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
else
|
424
|
-
"85a54e28e4ec18bfdcb214a73f74d35b09a84176"
|
425
|
-
end
|
426
|
-
}
|
427
|
-
subject { api.get_url(:join, params) }
|
428
|
-
it { subject.should match(/checksum=#{checksum}$/) }
|
445
|
+
context "returns an empty hash if the response body is empty" do
|
446
|
+
before do
|
447
|
+
api.should_receive(:send_request).with(url, data).and_return(response_mock)
|
448
|
+
response_mock.should_receive(:body).and_return("")
|
449
|
+
end
|
450
|
+
it { make_request.should == { } }
|
429
451
|
end
|
430
|
-
end
|
431
|
-
end
|
432
|
-
|
433
|
-
describe "#send_api_request" do
|
434
|
-
let(:method) { :join }
|
435
|
-
let(:params) { { :param1 => "value1" } }
|
436
|
-
let(:data) { "any data" }
|
437
|
-
let(:url) { "http://test-server:8080?param1=value1&checksum=12345" }
|
438
|
-
let(:make_request) { api.send_api_request(method, params, data) }
|
439
|
-
let(:response_mock) { mock() } # mock of what send_request() would return
|
440
452
|
|
441
|
-
|
453
|
+
context "hashfies and validates the response body" do
|
454
|
+
before do
|
455
|
+
api.should_receive(:send_request).with(url, data).and_return(response_mock)
|
456
|
+
response_mock.should_receive(:body).twice.and_return("response-body")
|
457
|
+
end
|
442
458
|
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
end
|
448
|
-
it { make_request.should == { } }
|
449
|
-
end
|
459
|
+
context "checking if it has a :response key" do
|
460
|
+
before { BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return({ }) }
|
461
|
+
it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
462
|
+
end
|
450
463
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
464
|
+
context "checking if it the :response key has a :returncode key" do
|
465
|
+
before { BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return({ :response => { } }) }
|
466
|
+
it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
467
|
+
end
|
455
468
|
end
|
456
469
|
|
457
|
-
context "
|
458
|
-
|
459
|
-
|
470
|
+
context "formats the response hash" do
|
471
|
+
let(:response) { { :returncode => "SUCCESS" } }
|
472
|
+
let(:formatted_response) { { :returncode => true, :messageKey => "", :message => "" } }
|
473
|
+
before do
|
474
|
+
api.should_receive(:send_request).with(url, data).and_return(response_mock)
|
475
|
+
response_mock.should_receive(:body).twice.and_return("response-body")
|
476
|
+
BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return(response)
|
477
|
+
|
478
|
+
# here starts the validation
|
479
|
+
# doesn't test the resulting format, only that the formatter was called
|
480
|
+
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
481
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).with(response).and_return(formatter_mock)
|
482
|
+
formatter_mock.should_receive(:default_formatting).and_return(formatted_response)
|
483
|
+
end
|
484
|
+
it { make_request }
|
460
485
|
end
|
461
486
|
|
462
|
-
context "
|
463
|
-
|
487
|
+
context "raise an error if the formatted response has no :returncode" do
|
488
|
+
let(:response) { { :returncode => true } }
|
489
|
+
let(:formatted_response) { { } }
|
490
|
+
before do
|
491
|
+
api.should_receive(:send_request).with(url, data).and_return(response_mock)
|
492
|
+
response_mock.should_receive(:body).twice.and_return("response-body")
|
493
|
+
BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return(response)
|
494
|
+
|
495
|
+
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
496
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).with(response).and_return(formatter_mock)
|
497
|
+
formatter_mock.should_receive(:default_formatting).and_return(formatted_response)
|
498
|
+
end
|
464
499
|
it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
465
500
|
end
|
466
501
|
end
|
467
502
|
|
468
|
-
|
469
|
-
let(:
|
470
|
-
let(:
|
471
|
-
before do
|
472
|
-
api.should_receive(:send_request).with(url, data).and_return(response_mock)
|
473
|
-
response_mock.should_receive(:body).twice.and_return("response-body")
|
474
|
-
BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return(response)
|
503
|
+
describe "#send_request" do
|
504
|
+
let(:url) { "http://test-server:8080/res?param1=value1&checksum=12345" }
|
505
|
+
let(:url_parsed) { URI.parse(url) }
|
475
506
|
|
476
|
-
# here starts the validation
|
477
|
-
# doesn't test the resulting format, only that the formatter was called
|
478
|
-
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
479
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).with(response).and_return(formatter_mock)
|
480
|
-
formatter_mock.should_receive(:default_formatting).and_return(formatted_response)
|
481
|
-
end
|
482
|
-
it { make_request }
|
483
|
-
end
|
484
|
-
|
485
|
-
context "raise an error if the formatted response has no :returncode" do
|
486
|
-
let(:response) { { :returncode => true } }
|
487
|
-
let(:formatted_response) { { } }
|
488
507
|
before do
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
494
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).with(response).and_return(formatter_mock)
|
495
|
-
formatter_mock.should_receive(:default_formatting).and_return(formatted_response)
|
508
|
+
@http_mock = mock(Net::HTTP)
|
509
|
+
@http_mock.should_receive(:"open_timeout=").with(api.timeout)
|
510
|
+
@http_mock.should_receive(:"read_timeout=").with(api.timeout)
|
511
|
+
Net::HTTP.should_receive(:new).with("test-server", 8080).and_return(@http_mock)
|
496
512
|
end
|
497
|
-
it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
498
|
-
end
|
499
|
-
end
|
500
513
|
|
501
|
-
|
502
|
-
|
503
|
-
|
514
|
+
context "standard case" do
|
515
|
+
before { @http_mock.should_receive(:get).with("/res?param1=value1&checksum=12345", {}).and_return("ok") }
|
516
|
+
it { api.send(:send_request, url).should == "ok" }
|
517
|
+
end
|
504
518
|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
Net::HTTP.should_receive(:new).with("test-server", 8080).and_return(@http_mock)
|
510
|
-
end
|
519
|
+
context "handles a TimeoutError" do
|
520
|
+
before { @http_mock.should_receive(:get) { raise TimeoutError } }
|
521
|
+
it { expect { api.send(:send_request, url) }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
522
|
+
end
|
511
523
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
524
|
+
context "handles general Exceptions" do
|
525
|
+
before { @http_mock.should_receive(:get) { raise Exception } }
|
526
|
+
it { expect { api.send(:send_request, url) }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
527
|
+
end
|
516
528
|
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
529
|
+
context "post with data" do
|
530
|
+
let(:data) { "any data" }
|
531
|
+
before {
|
532
|
+
path = "/res?param1=value1&checksum=12345"
|
533
|
+
opts = { 'Content-Type' => 'text/xml' }
|
534
|
+
@http_mock.should_receive(:post).with(path, data, opts).and_return("ok")
|
535
|
+
}
|
536
|
+
it {
|
537
|
+
api.send(:send_request, url, data).should == "ok"
|
538
|
+
}
|
539
|
+
end
|
521
540
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
541
|
+
context "get with headers" do
|
542
|
+
let(:headers_hash) { { :anything => "anything" } }
|
543
|
+
before { @http_mock.should_receive(:get).with("/res?param1=value1&checksum=12345", headers_hash).and_return("ok") }
|
544
|
+
it {
|
545
|
+
api.request_headers = headers_hash
|
546
|
+
api.send(:send_request, url).should == "ok"
|
547
|
+
}
|
548
|
+
end
|
526
549
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
550
|
+
context "get with headers" do
|
551
|
+
let(:headers_hash) { { :anything => "anything" } }
|
552
|
+
let(:data) { "any data" }
|
553
|
+
before {
|
554
|
+
path = "/res?param1=value1&checksum=12345"
|
555
|
+
opts = { 'Content-Type' => 'text/xml', :anything => "anything" }
|
556
|
+
@http_mock.should_receive(:post).with(path, data, opts).and_return("ok")
|
557
|
+
}
|
558
|
+
it {
|
559
|
+
api.request_headers = headers_hash
|
560
|
+
api.send(:send_request, url, data).should == "ok"
|
561
|
+
}
|
562
|
+
end
|
537
563
|
end
|
538
564
|
|
539
|
-
|
540
|
-
let(:
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
api.send(:send_request, url).should == "ok"
|
565
|
+
describe "#get_recordings" do
|
566
|
+
let(:recording1) { { :recordID => "id1", :meetindID => "meeting-id" } } # simplified "recording" node in the response
|
567
|
+
let(:recording2) { { :recordID => "id2", :meetindID => "meeting-id" } }
|
568
|
+
let(:response) {
|
569
|
+
{ :returncode => true, :recordings => { :recording => [ recording1, recording2 ] }, :messageKey => "mkey", :message => "m" }
|
545
570
|
}
|
546
|
-
|
571
|
+
let(:flattened_response) {
|
572
|
+
{ :returncode => true, :recordings => [ recording1, recording2 ], :messageKey => "mkey", :message => "m" }
|
573
|
+
} # hash *after* the flatten_objects call
|
547
574
|
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
opts = { 'Content-Type' => 'text/xml', :anything => "anything" }
|
554
|
-
@http_mock.should_receive(:post).with(path, data, opts).and_return("ok")
|
555
|
-
}
|
556
|
-
it {
|
557
|
-
api.request_headers = headers_hash
|
558
|
-
api.send(:send_request, url, data).should == "ok"
|
559
|
-
}
|
560
|
-
end
|
561
|
-
end
|
575
|
+
context "accepts non standard options" do
|
576
|
+
let(:params) { { :meetingID => "meeting-id", :nonStandard => 1 } }
|
577
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, params).and_return(response) }
|
578
|
+
it { api.get_recordings(params) }
|
579
|
+
end
|
562
580
|
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
{ :returncode => true, :recordings => { :recording => [ recording1, recording2 ] }, :messageKey => "mkey", :message => "m" }
|
568
|
-
}
|
569
|
-
let(:flattened_response) {
|
570
|
-
{ :returncode => true, :recordings => [ recording1, recording2 ], :messageKey => "mkey", :message => "m" }
|
571
|
-
} # hash *after* the flatten_objects call
|
572
|
-
|
573
|
-
context "accepts non standard options" do
|
574
|
-
let(:params) { { :meetingID => "meeting-id", :nonStandard => 1 } }
|
575
|
-
before { api.should_receive(:send_api_request).with(:getRecordings, params).and_return(response) }
|
576
|
-
it { api.get_recordings(params) }
|
577
|
-
end
|
581
|
+
context "without meeting ID" do
|
582
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, {}).and_return(response) }
|
583
|
+
it { api.get_recordings.should == response }
|
584
|
+
end
|
578
585
|
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
586
|
+
context "with one meeting ID" do
|
587
|
+
context "in an array" do
|
588
|
+
let(:options) { { :meetingID => ["meeting-id"] } }
|
589
|
+
let(:req_params) { { :meetingID => "meeting-id" } }
|
590
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
591
|
+
it { api.get_recordings(options).should == response }
|
592
|
+
end
|
583
593
|
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
594
|
+
context "in a string" do
|
595
|
+
let(:options) { { :meetingID => "meeting-id" } }
|
596
|
+
let(:req_params) { { :meetingID => "meeting-id" } }
|
597
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
598
|
+
it { api.get_recordings(options).should == response }
|
599
|
+
end
|
590
600
|
end
|
591
601
|
|
592
|
-
context "
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
602
|
+
context "with several meeting IDs" do
|
603
|
+
context "in an array" do
|
604
|
+
let(:options) { { :meetingID => ["meeting-id-1", "meeting-id-2"] } }
|
605
|
+
let(:req_params) { { :meetingID => "meeting-id-1,meeting-id-2" } }
|
606
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
607
|
+
it { api.get_recordings(options).should == response }
|
608
|
+
end
|
599
609
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
610
|
+
context "in a string" do
|
611
|
+
let(:options) { { :meetingID => "meeting-id-1,meeting-id-2" } }
|
612
|
+
let(:req_params) { { :meetingID => "meeting-id-1,meeting-id-2" } }
|
613
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
614
|
+
it { api.get_recordings(options).should == response }
|
615
|
+
end
|
606
616
|
end
|
607
617
|
|
608
|
-
context "
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
618
|
+
context "formats the response" do
|
619
|
+
before {
|
620
|
+
api.should_receive(:send_api_request).with(:getRecordings, anything).and_return(flattened_response)
|
621
|
+
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
622
|
+
formatter_mock.should_receive(:flatten_objects).with(:recordings, :recording)
|
623
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_recording).with(recording1)
|
624
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_recording).with(recording2)
|
625
|
+
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).and_return(formatter_mock)
|
626
|
+
}
|
627
|
+
it { api.get_recordings }
|
613
628
|
end
|
614
629
|
end
|
615
630
|
|
616
|
-
|
617
|
-
before {
|
618
|
-
api.should_receive(:send_api_request).with(:getRecordings, anything).and_return(flattened_response)
|
619
|
-
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
620
|
-
formatter_mock.should_receive(:flatten_objects).with(:recordings, :recording)
|
621
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_recording).with(recording1)
|
622
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:format_recording).with(recording2)
|
623
|
-
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).and_return(formatter_mock)
|
624
|
-
}
|
625
|
-
it { api.get_recordings }
|
626
|
-
end
|
627
|
-
end
|
631
|
+
describe "#publish_recordings" do
|
628
632
|
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
let(:recordIDs) { "any" }
|
633
|
-
let(:req_params) { { :publish => "false", :recordID => "any" } }
|
634
|
-
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
635
|
-
it { api.publish_recordings(recordIDs, false) }
|
636
|
-
end
|
637
|
-
|
638
|
-
context "with one recording ID" do
|
639
|
-
context "in an array" do
|
640
|
-
let(:recordIDs) { ["id-1"] }
|
641
|
-
let(:req_params) { { :publish => "true", :recordID => "id-1" } }
|
633
|
+
context "publish is converted to string" do
|
634
|
+
let(:recordIDs) { "any" }
|
635
|
+
let(:req_params) { { :publish => "false", :recordID => "any" } }
|
642
636
|
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
643
|
-
it { api.publish_recordings(recordIDs,
|
637
|
+
it { api.publish_recordings(recordIDs, false) }
|
644
638
|
end
|
645
639
|
|
646
|
-
context "
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
640
|
+
context "with one recording ID" do
|
641
|
+
context "in an array" do
|
642
|
+
let(:recordIDs) { ["id-1"] }
|
643
|
+
let(:req_params) { { :publish => "true", :recordID => "id-1" } }
|
644
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
645
|
+
it { api.publish_recordings(recordIDs, true) }
|
646
|
+
end
|
647
|
+
|
648
|
+
context "in a string" do
|
649
|
+
let(:recordIDs) { "id-1" }
|
650
|
+
let(:req_params) { { :publish => "true", :recordID => "id-1" } }
|
651
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
652
|
+
it { api.publish_recordings(recordIDs, true) }
|
653
|
+
end
|
651
654
|
end
|
652
|
-
end
|
653
655
|
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
656
|
+
context "with several recording IDs" do
|
657
|
+
context "in an array" do
|
658
|
+
let(:recordIDs) { ["id-1", "id-2"] }
|
659
|
+
let(:req_params) { { :publish => "true", :recordID => "id-1,id-2" } }
|
660
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
661
|
+
it { api.publish_recordings(recordIDs, true) }
|
662
|
+
end
|
663
|
+
|
664
|
+
context "in a string" do
|
665
|
+
let(:recordIDs) { "id-1,id-2,id-3" }
|
666
|
+
let(:req_params) { { :publish => "true", :recordID => "id-1,id-2,id-3" } }
|
667
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
668
|
+
it { api.publish_recordings(recordIDs, true) }
|
669
|
+
end
|
660
670
|
end
|
661
671
|
|
662
|
-
context "
|
663
|
-
let(:recordIDs) { "id-1
|
664
|
-
let(:
|
665
|
-
|
666
|
-
|
672
|
+
context "accepts non standard options" do
|
673
|
+
let(:recordIDs) { ["id-1"] }
|
674
|
+
let(:params_in) {
|
675
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
676
|
+
}
|
677
|
+
let(:params_out) {
|
678
|
+
{ :publish => "true", :recordID => "id-1",
|
679
|
+
:anything1 => "anything-1", :anything2 => 2 }
|
680
|
+
}
|
681
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, params_out) }
|
682
|
+
it { api.publish_recordings(recordIDs, true, params_in) }
|
667
683
|
end
|
668
684
|
end
|
669
685
|
|
670
|
-
|
671
|
-
let(:recordIDs) { ["id-1"] }
|
672
|
-
let(:params_in) {
|
673
|
-
{ :anything1 => "anything-1", :anything2 => 2 }
|
674
|
-
}
|
675
|
-
let(:params_out) {
|
676
|
-
{ :publish => "true", :recordID => "id-1",
|
677
|
-
:anything1 => "anything-1", :anything2 => 2 }
|
678
|
-
}
|
679
|
-
before { api.should_receive(:send_api_request).with(:publishRecordings, params_out) }
|
680
|
-
it { api.publish_recordings(recordIDs, true, params_in) }
|
681
|
-
end
|
682
|
-
end
|
686
|
+
describe "#delete_recordings" do
|
683
687
|
|
684
|
-
|
688
|
+
context "with one recording ID" do
|
689
|
+
context "in an array" do
|
690
|
+
let(:recordIDs) { ["id-1"] }
|
691
|
+
let(:req_params) { { :recordID => "id-1" } }
|
692
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
693
|
+
it { api.delete_recordings(recordIDs) }
|
694
|
+
end
|
685
695
|
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
696
|
+
context "in a string" do
|
697
|
+
let(:recordIDs) { "id-1" }
|
698
|
+
let(:req_params) { { :recordID => "id-1" } }
|
699
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
700
|
+
it { api.delete_recordings(recordIDs) }
|
701
|
+
end
|
692
702
|
end
|
693
703
|
|
694
|
-
context "
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
704
|
+
context "with several recording IDs" do
|
705
|
+
context "in an array" do
|
706
|
+
let(:recordIDs) { ["id-1", "id-2"] }
|
707
|
+
let(:req_params) { { :recordID => "id-1,id-2" } }
|
708
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
709
|
+
it { api.delete_recordings(recordIDs) }
|
710
|
+
end
|
701
711
|
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
712
|
+
context "in a string" do
|
713
|
+
let(:recordIDs) { "id-1,id-2,id-3" }
|
714
|
+
let(:req_params) { { :recordID => "id-1,id-2,id-3" } }
|
715
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
716
|
+
it { api.delete_recordings(recordIDs) }
|
717
|
+
end
|
708
718
|
end
|
709
719
|
|
710
|
-
context "
|
711
|
-
let(:recordIDs) { "id-1
|
712
|
-
let(:
|
713
|
-
|
714
|
-
|
720
|
+
context "accepts non standard options" do
|
721
|
+
let(:recordIDs) { ["id-1"] }
|
722
|
+
let(:params_in) {
|
723
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
724
|
+
}
|
725
|
+
let(:params_out) {
|
726
|
+
{ :recordID => "id-1", :anything1 => "anything-1", :anything2 => 2 }
|
727
|
+
}
|
728
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, params_out) }
|
729
|
+
it { api.delete_recordings(recordIDs, params_in) }
|
715
730
|
end
|
716
731
|
end
|
717
|
-
|
718
|
-
context "accepts non standard options" do
|
719
|
-
let(:recordIDs) { ["id-1"] }
|
720
|
-
let(:params_in) {
|
721
|
-
{ :anything1 => "anything-1", :anything2 => 2 }
|
722
|
-
}
|
723
|
-
let(:params_out) {
|
724
|
-
{ :recordID => "id-1", :anything1 => "anything-1", :anything2 => 2 }
|
725
|
-
}
|
726
|
-
before { api.should_receive(:send_api_request).with(:deleteRecordings, params_out) }
|
727
|
-
it { api.delete_recordings(recordIDs, params_in) }
|
728
|
-
end
|
729
732
|
end
|
730
733
|
|
734
|
+
it_should_behave_like "BigBlueButtonApi", "0.8"
|
735
|
+
it_should_behave_like "BigBlueButtonApi", "0.81"
|
736
|
+
it_should_behave_like "BigBlueButtonApi", "0.9"
|
731
737
|
end
|