bigbluebutton-api-ruby 1.2.0 → 1.3.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.
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.rdoc +8 -0
- data/Gemfile.lock +3 -3
- data/README.rdoc +20 -16
- data/Rakefile +5 -4
- data/bigbluebutton-api-ruby.gemspec +1 -1
- data/examples/config_xml.rb +74 -0
- data/examples/create.rb +29 -0
- data/examples/join_example.rb +0 -8
- data/examples/{overall_0.7_example.rb → overall_example.rb} +0 -0
- data/features/config.yml.example +6 -5
- data/features/create_meetings.feature +1 -10
- data/features/end_meetings.feature +3 -21
- data/features/pre_upload_slides.feature +1 -1
- data/features/recordings.feature +1 -1
- data/features/support/features_helpers.rb +1 -1
- data/lib/bigbluebutton_api.rb +342 -176
- data/lib/bigbluebutton_config_layout.rb +56 -0
- data/lib/bigbluebutton_config_xml.rb +122 -0
- data/lib/bigbluebutton_formatter.rb +12 -6
- data/lib/bigbluebutton_hash_to_xml.rb +35 -0
- data/lib/bigbluebutton_modules.rb +1 -2
- data/spec/bigbluebutton_api_0.81_spec.rb +154 -0
- data/spec/bigbluebutton_api_spec.rb +327 -75
- data/spec/bigbluebutton_config_layout_spec.rb +86 -0
- data/spec/bigbluebutton_config_xml_spec.rb +276 -0
- data/spec/bigbluebutton_formatter_spec.rb +28 -6
- data/spec/{hash_to_xml_spec.rb → bigbluebutton_hash_to_xml_spec.rb} +13 -13
- metadata +16 -10
- data/.rvmrc +0 -6
- data/lib/hash_to_xml.rb +0 -33
- data/spec/bigbluebutton_api_0.8_spec.rb +0 -273
@@ -0,0 +1,56 @@
|
|
1
|
+
require "xmlsimple"
|
2
|
+
|
3
|
+
module BigBlueButton
|
4
|
+
|
5
|
+
# A helper class to work with layout definition files.
|
6
|
+
# You set an xml file on it (usually obtained from a property of in the XML obtained from
|
7
|
+
# BigBlueButtonApi#get_default_config_xml), use it to work with the layouts, and then get
|
8
|
+
# the new xml from this class.
|
9
|
+
#
|
10
|
+
# === Usage example:
|
11
|
+
#
|
12
|
+
# xml = api.get_default_config_xml
|
13
|
+
# config_xml = BigBlueButton::BigBlueButtonConfigXml.new(xml)
|
14
|
+
# url = config_xml.get_attribute("LayoutModule", "layoutConfig", true)
|
15
|
+
# # send a request to 'url' to fetch the xml file into 'response'
|
16
|
+
#
|
17
|
+
# layout_config = BigBlueButton::BigBlueButtonConfigLayout.new(response)
|
18
|
+
# layout_config.get_available_layouts
|
19
|
+
#
|
20
|
+
class BigBlueButtonConfigLayout
|
21
|
+
|
22
|
+
attr_accessor :xml
|
23
|
+
|
24
|
+
# xml (string):: The XML that has the definition of all layouts, usually fetched from
|
25
|
+
# the web conference server.
|
26
|
+
def initialize(xml)
|
27
|
+
@xml = nil
|
28
|
+
opts = { 'ForceArray' => false, 'KeepRoot' => true }
|
29
|
+
begin
|
30
|
+
@xml = XmlSimple.xml_in(xml, opts)
|
31
|
+
rescue Exception => e
|
32
|
+
raise BigBlueButton::BigBlueButtonException.new("Error parsing the layouts XML. Error: #{e.message}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns an array with the name of each layout available in the XML.
|
37
|
+
# Will return only unique names, ordered the way they are ordered in the XML.
|
38
|
+
# Returns nil if the XML is not properly formatted and an empty
|
39
|
+
# array if there are no layouts in the file.
|
40
|
+
def get_available_layouts
|
41
|
+
if xml_has_layouts
|
42
|
+
xml["layouts"]["layout"].map{ |l| l["name"] }.uniq
|
43
|
+
else
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def xml_has_layouts
|
51
|
+
@xml and @xml["layouts"] and @xml["layouts"]["layout"]
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require "xmlsimple"
|
2
|
+
|
3
|
+
module BigBlueButton
|
4
|
+
|
5
|
+
# A helper class to work with config.xml files.
|
6
|
+
# You set an xml file on it (usually obtained via BigBlueButtonApi#get_default_config_xml),
|
7
|
+
# use it to modify this xml, and then get the new xml from this class (usually to set in the
|
8
|
+
# server using BigBlueButtonApi#set_config_xml).
|
9
|
+
#
|
10
|
+
# === Usage example:
|
11
|
+
#
|
12
|
+
# xml = api.get_default_config_xml
|
13
|
+
# config_xml = BigBlueButton::BigBlueButtonConfigXml.new(xml)
|
14
|
+
#
|
15
|
+
# # change the xml a bit
|
16
|
+
# config_xml.set_attribute("skinning", "enabled", "false", false)
|
17
|
+
# config_xml.set_attribute("layout", "defaultLayout", "Webinar", false)
|
18
|
+
# config_xml.set_attribute("layout", "showLayoutTools", "false", false)
|
19
|
+
#
|
20
|
+
# # set the new xml in the server
|
21
|
+
# api.set_config_xml("meeting-id", config_xml)
|
22
|
+
#
|
23
|
+
class BigBlueButtonConfigXml
|
24
|
+
|
25
|
+
attr_accessor :xml
|
26
|
+
|
27
|
+
def initialize(xml)
|
28
|
+
@original_xml = nil
|
29
|
+
@xml = nil
|
30
|
+
unless xml.nil?
|
31
|
+
opts = { 'ForceArray' => false, 'KeepRoot' => true }
|
32
|
+
begin
|
33
|
+
@xml = XmlSimple.xml_in(xml, opts)
|
34
|
+
@original_xml = Marshal.load(Marshal.dump(@xml))
|
35
|
+
rescue Exception => e
|
36
|
+
raise BigBlueButton::BigBlueButtonException.new("Error parsing the config XML. Error: #{e.message}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_attribute(finder, attr_name, is_module=true)
|
42
|
+
if is_module
|
43
|
+
tag = find_module(finder)
|
44
|
+
else
|
45
|
+
tag = find_tag(finder)
|
46
|
+
end
|
47
|
+
if tag
|
48
|
+
find_attribute(tag, attr_name)
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_attribute(finder, attr_name, value, is_module=true)
|
55
|
+
if is_module
|
56
|
+
tag = find_module(finder)
|
57
|
+
else
|
58
|
+
tag = find_tag(finder)
|
59
|
+
end
|
60
|
+
if tag
|
61
|
+
attr = find_attribute(tag, attr_name)
|
62
|
+
if attr
|
63
|
+
tag[attr_name] = value
|
64
|
+
else
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
else
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def as_string
|
73
|
+
XmlSimple.xml_out(@xml, { 'RootName' => nil, 'XmlDeclaration' => false, 'NoIndent' => true })
|
74
|
+
end
|
75
|
+
|
76
|
+
def is_modified?
|
77
|
+
@xml and
|
78
|
+
@xml != @original_xml
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
def find_module(module_name)
|
84
|
+
if xml_has_modules
|
85
|
+
modules = @xml["config"]["modules"]["module"]
|
86
|
+
modules = [modules] unless modules.is_a?(Array)
|
87
|
+
modules.each do |mod|
|
88
|
+
if mod["name"] == module_name
|
89
|
+
return mod
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def find_tag(name)
|
97
|
+
if xml_has_config
|
98
|
+
@xml["config"][name]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_attribute(mod, attr_name)
|
103
|
+
if mod and mod[attr_name]
|
104
|
+
return mod[attr_name]
|
105
|
+
else
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def xml_has_modules
|
111
|
+
xml_has_config and
|
112
|
+
@xml["config"]["modules"] and
|
113
|
+
@xml["config"]["modules"]["module"]
|
114
|
+
end
|
115
|
+
|
116
|
+
def xml_has_config
|
117
|
+
@xml and @xml["config"]
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -52,7 +52,7 @@ module BigBlueButton
|
|
52
52
|
if value.downcase == "null"
|
53
53
|
result = nil
|
54
54
|
else
|
55
|
-
# note:
|
55
|
+
# note: just in case the value comes as a string in the format: "Thu Sep 01 17:51:42 UTC 2011"
|
56
56
|
result = DateTime.parse(value)
|
57
57
|
end
|
58
58
|
end
|
@@ -92,11 +92,17 @@ module BigBlueButton
|
|
92
92
|
def self.format_meeting(meeting)
|
93
93
|
f = BigBlueButtonFormatter.new(meeting)
|
94
94
|
f.to_string(:meetingID)
|
95
|
+
f.to_string(:meetingName)
|
95
96
|
f.to_string(:moderatorPW)
|
96
97
|
f.to_string(:attendeePW)
|
97
98
|
f.to_boolean(:hasBeenForciblyEnded)
|
98
99
|
f.to_boolean(:running)
|
99
100
|
f.to_int(:createTime) if meeting.has_key?(:createTime)
|
101
|
+
f.to_string(:dialNumber)
|
102
|
+
f.to_int(:voiceBridge)
|
103
|
+
f.to_int(:participantCount)
|
104
|
+
f.to_int(:listenerCount)
|
105
|
+
f.to_int(:videoCount)
|
100
106
|
meeting
|
101
107
|
end
|
102
108
|
|
@@ -152,18 +158,18 @@ module BigBlueButton
|
|
152
158
|
#
|
153
159
|
# Other examples:
|
154
160
|
#
|
155
|
-
# Hash:
|
161
|
+
# # Hash:
|
156
162
|
# { :name => "Test", :attendees => {} }
|
157
|
-
# Result:
|
163
|
+
# # Result:
|
158
164
|
# { :name => "Test", :attendees => [] }
|
159
165
|
#
|
160
|
-
# Hash:
|
166
|
+
# # Hash:
|
161
167
|
# { :name => "Test", :attendees => { :attendee => { :name => "attendee1" } } }
|
162
|
-
# Result:
|
168
|
+
# # Result:
|
163
169
|
# { :name => "Test", :attendees => [ { :name => "attendee1" } ] }
|
164
170
|
#
|
165
171
|
def flatten_objects(first, second)
|
166
|
-
if @hash[first].empty?
|
172
|
+
if !@hash[first] or @hash[first].empty?
|
167
173
|
collection = []
|
168
174
|
else
|
169
175
|
node = @hash[first][second]
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'xmlsimple'
|
2
|
+
|
3
|
+
module BigBlueButton
|
4
|
+
class BigBlueButtonHash < Hash
|
5
|
+
class << self
|
6
|
+
def from_xml(xml_io)
|
7
|
+
begin
|
8
|
+
# we'll not use 'KeyToSymbol' because it doesn't symbolize the keys for node attributes
|
9
|
+
opts = { 'ForceArray' => false, 'ForceContent' => false } #
|
10
|
+
hash = XmlSimple.xml_in(xml_io, opts)
|
11
|
+
return symbolize_keys(hash)
|
12
|
+
rescue Exception => e
|
13
|
+
raise BigBlueButtonException.new("Impossible to convert XML to hash. Error: #{e.message}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def symbolize_keys(arg)
|
18
|
+
case arg
|
19
|
+
when Array
|
20
|
+
arg.map { |elem| symbolize_keys elem }
|
21
|
+
when Hash
|
22
|
+
Hash[
|
23
|
+
arg.map { |key, value|
|
24
|
+
k = key.is_a?(String) ? key.to_sym : key
|
25
|
+
v = symbolize_keys value
|
26
|
+
[k,v]
|
27
|
+
}]
|
28
|
+
else
|
29
|
+
arg
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -2,8 +2,7 @@ require "base64"
|
|
2
2
|
|
3
3
|
module BigBlueButton
|
4
4
|
|
5
|
-
#
|
6
|
-
# BigBlueButtonApi#create_meeting().
|
5
|
+
# A class to store the modules configuration to be passed in BigBlueButtonApi#create_meeting().
|
7
6
|
#
|
8
7
|
# === Usage example:
|
9
8
|
#
|
@@ -0,0 +1,154 @@
|
|
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.81" }
|
10
|
+
let(:debug) { false }
|
11
|
+
let(:api) { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
|
12
|
+
|
13
|
+
describe "#get_default_config_xml" do
|
14
|
+
let(:response) { "<response><returncode>1</returncode></response>" }
|
15
|
+
let(:response_asObject) { {"response" => {"returncode" => "1" } } }
|
16
|
+
|
17
|
+
context "with response as a string" do
|
18
|
+
context "and without non standard options" do
|
19
|
+
before { api.should_receive(:send_api_request).with(:getDefaultConfigXML, {}, nil, true).and_return(response) }
|
20
|
+
it { api.get_default_config_xml() }
|
21
|
+
it { api.get_default_config_xml().should == response }
|
22
|
+
it { api.get_default_config_xml(false).should_not == response_asObject }
|
23
|
+
end
|
24
|
+
|
25
|
+
context "and with non standard options" do
|
26
|
+
let(:params_in) {
|
27
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
28
|
+
}
|
29
|
+
before { api.should_receive(:send_api_request).with(:getDefaultConfigXML, params_in, nil, true).and_return(response) }
|
30
|
+
it { api.get_default_config_xml(false, params_in) }
|
31
|
+
it { api.get_default_config_xml(false, params_in).should == response }
|
32
|
+
it { api.get_default_config_xml(false, params_in).should_not == response_asObject }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with response as a object" do
|
37
|
+
context "and without non standard options" do
|
38
|
+
before { api.should_receive(:send_api_request).with(:getDefaultConfigXML, {}, nil, true).and_return(response) }
|
39
|
+
it { api.get_default_config_xml(true) }
|
40
|
+
it { api.get_default_config_xml(true).should == response_asObject }
|
41
|
+
it { api.get_default_config_xml(true).should_not == response }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "and with non standard options" do
|
45
|
+
let(:params_in) {
|
46
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
47
|
+
}
|
48
|
+
before { api.should_receive(:send_api_request).with(:getDefaultConfigXML, params_in, nil, true).and_return(response) }
|
49
|
+
it { api.get_default_config_xml(true, params_in) }
|
50
|
+
it { api.get_default_config_xml(true, params_in).should == response_asObject }
|
51
|
+
it { api.get_default_config_xml(true, params_in).should_not == response }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#set_config_xml" do
|
57
|
+
let(:configToken) { "asdfl234kjasdfsadfy" }
|
58
|
+
let(:meeting_id) { "meeting-id" }
|
59
|
+
let(:xml) { "<response><returncode>SUCCESS</returncode><configToken>asdfl234kjasdfsadfy</configToken></response>" }
|
60
|
+
let(:response) {
|
61
|
+
{ :returncode => "SUCCESS", :configToken => configToken }
|
62
|
+
}
|
63
|
+
|
64
|
+
context "without non standard options" do
|
65
|
+
let(:params) {
|
66
|
+
{ :meetingID => meeting_id, :configXML => xml }
|
67
|
+
}
|
68
|
+
|
69
|
+
before { api.should_receive(:send_api_request).with(:setConfigXML, params, xml).and_return(response) }
|
70
|
+
it { api.set_config_xml(meeting_id, xml) }
|
71
|
+
it { api.set_config_xml(meeting_id, xml).should == configToken }
|
72
|
+
end
|
73
|
+
|
74
|
+
context "with non standard options" do
|
75
|
+
let(:params_in) {
|
76
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
77
|
+
}
|
78
|
+
let(:params_out) {
|
79
|
+
{ :meetingID => meeting_id, :configXML => xml, :anything1 => "anything-1", :anything2 => 2 }
|
80
|
+
}
|
81
|
+
|
82
|
+
before { api.should_receive(:send_api_request).with(:setConfigXML, params_out, xml).and_return(response) }
|
83
|
+
it { api.set_config_xml(meeting_id, xml, params_in) }
|
84
|
+
it { api.set_config_xml(meeting_id, xml, params_in).should == configToken }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#get_available_layouts" do
|
89
|
+
let(:config_xml) { # a simplified config.xml file
|
90
|
+
"<config>
|
91
|
+
<modules>
|
92
|
+
<module name=\"LayoutModule\" url=\"http://test-server.org/client/LayoutModule.swf?v=4357\"
|
93
|
+
uri=\"rtmp://test-server.org/bigbluebutton\"
|
94
|
+
layoutConfig=\"http://test-server.org/client/conf/layout.xml\"
|
95
|
+
enableEdit=\"false\"/>
|
96
|
+
</modules>
|
97
|
+
</config>"
|
98
|
+
}
|
99
|
+
let(:layouts_xml) { # a simplified layouts.xml file
|
100
|
+
"<layouts>
|
101
|
+
<layout name=\"Default\" default=\"true\">
|
102
|
+
<window name=\"NotesWindow\" hidden=\"true\" width=\"0.7\" height=\"1\" x=\"0\" y=\"0\" draggable=\"false\" resizable=\"false\"/>
|
103
|
+
</layout>
|
104
|
+
<layout name=\"Video Chat\">
|
105
|
+
<window name=\"NotesWindow\" hidden=\"true\" width=\"0.7\" height=\"1\" x=\"0\" y=\"0\" draggable=\"false\" resizable=\"false\"/>
|
106
|
+
</layout>
|
107
|
+
</layouts>"
|
108
|
+
}
|
109
|
+
|
110
|
+
context "when an XML is passed" do
|
111
|
+
before {
|
112
|
+
response = double("Net::HTTPResponse")
|
113
|
+
response.stub(:body).and_return(layouts_xml)
|
114
|
+
api.should_receive(:send_request)
|
115
|
+
.with("http://test-server.org/client/conf/layout.xml")
|
116
|
+
.and_return(response)
|
117
|
+
}
|
118
|
+
subject { api.get_available_layouts(config_xml) }
|
119
|
+
it { should be_instance_of(Array) }
|
120
|
+
it { subject.count.should be(2) }
|
121
|
+
it { should include("Default") }
|
122
|
+
it { should include("Video Chat") }
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when no XML is passed" do
|
126
|
+
before {
|
127
|
+
api.should_receive(:get_default_config_xml)
|
128
|
+
.and_return(config_xml)
|
129
|
+
response = double("Net::HTTPResponse")
|
130
|
+
response.stub(:body).and_return(layouts_xml)
|
131
|
+
api.should_receive(:send_request)
|
132
|
+
.with("http://test-server.org/client/conf/layout.xml")
|
133
|
+
.and_return(response)
|
134
|
+
}
|
135
|
+
subject { api.get_available_layouts }
|
136
|
+
it { should be_instance_of(Array) }
|
137
|
+
it { subject.count.should be(2) }
|
138
|
+
it { should include("Default") }
|
139
|
+
it { should include("Video Chat") }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "#get_default_layouts" do
|
144
|
+
subject { api.get_default_layouts }
|
145
|
+
it { should be_instance_of(Array) }
|
146
|
+
it { should include("Default") }
|
147
|
+
it { should include("Video Chat") }
|
148
|
+
it { should include("Meeting") }
|
149
|
+
it { should include("Webinar") }
|
150
|
+
it { should include("Lecture assistant") }
|
151
|
+
it { should include("Lecture") }
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
# Note:
|
3
|
+
# Note: Uses version 0.8 by default. For things that only exist in newer versions,
|
4
|
+
# there are separate files with more tests.
|
4
5
|
describe BigBlueButton::BigBlueButtonApi do
|
5
6
|
|
6
7
|
# default variables and API object for all tests
|
7
8
|
let(:url) { "http://server.com" }
|
8
9
|
let(:salt) { "1234567890abcdefghijkl" }
|
9
|
-
let(:version) { "0.
|
10
|
+
let(:version) { "0.8" }
|
10
11
|
let(:debug) { false }
|
11
12
|
let(:api) { BigBlueButton::BigBlueButtonApi.new(url, salt, version, debug) }
|
12
13
|
|
@@ -18,15 +19,15 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
18
19
|
it { subject.version.should == version }
|
19
20
|
it { subject.debug.should == debug }
|
20
21
|
it { subject.timeout.should == 10 }
|
21
|
-
it { subject.supported_versions.should include("0.7") }
|
22
22
|
it { subject.supported_versions.should include("0.8") }
|
23
|
+
it { subject.supported_versions.should include("0.81") }
|
23
24
|
it { subject.request_headers.should == {} }
|
24
25
|
end
|
25
26
|
|
26
27
|
context "when the version is not informed, get it from the BBB server" do
|
27
|
-
before { BigBlueButton::BigBlueButtonApi.any_instance.should_receive(:get_api_version).and_return("0.
|
28
|
+
before { BigBlueButton::BigBlueButtonApi.any_instance.should_receive(:get_api_version).and_return("0.8") }
|
28
29
|
subject { BigBlueButton::BigBlueButtonApi.new(url, salt, nil) }
|
29
|
-
it { subject.version.should == "0.
|
30
|
+
it { subject.version.should == "0.8" }
|
30
31
|
end
|
31
32
|
|
32
33
|
it "when the version is not supported raise an error" do
|
@@ -37,7 +38,7 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
37
38
|
|
38
39
|
context "current supported versions" do
|
39
40
|
subject { BigBlueButton::BigBlueButtonApi.new(url, salt) }
|
40
|
-
it { subject.supported_versions.should == ["0.
|
41
|
+
it { subject.supported_versions.should == ["0.8", "0.81"] }
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -87,16 +88,84 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
87
88
|
api.create_meeting("name", "meeting-id", params)
|
88
89
|
}
|
89
90
|
end
|
91
|
+
|
92
|
+
context "with modules" do
|
93
|
+
let(:req_params) {
|
94
|
+
{ :name => "name", :meetingID => "meeting-id", :moderatorPW => "mp", :attendeePW => "ap" }
|
95
|
+
}
|
96
|
+
let(:req_response) {
|
97
|
+
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE", :createTime => "123123123" }
|
98
|
+
}
|
99
|
+
let(:final_response) {
|
100
|
+
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false, :createTime => 123123123 }
|
101
|
+
}
|
102
|
+
let(:modules) {
|
103
|
+
m = BigBlueButton::BigBlueButtonModules.new
|
104
|
+
m.add_presentation(:url, "http://www.samplepdf.com/sample.pdf")
|
105
|
+
m.add_presentation(:url, "http://www.samplepdf.com/sample2.pdf")
|
106
|
+
m.add_presentation(:base64, "JVBERi0xLjQKJ....[clipped here]....0CiUlRU9GCg==", "first-class.pdf")
|
107
|
+
m
|
108
|
+
}
|
109
|
+
|
110
|
+
before {
|
111
|
+
api.should_receive(:send_api_request).with(:create, req_params, modules.to_xml).
|
112
|
+
and_return(req_response)
|
113
|
+
}
|
114
|
+
subject {
|
115
|
+
options = { :moderatorPW => "mp", :attendeePW => "ap" }
|
116
|
+
api.create_meeting("name", "meeting-id", options, modules)
|
117
|
+
}
|
118
|
+
it { subject.should == final_response }
|
119
|
+
end
|
120
|
+
|
121
|
+
context "without modules" do
|
122
|
+
let(:req_params) {
|
123
|
+
{ :name => "name", :meetingID => "meeting-id", :moderatorPW => "mp", :attendeePW => "ap",
|
124
|
+
:welcome => "Welcome!", :dialNumber => 12345678, :logoutURL => "http://example.com",
|
125
|
+
:maxParticipants => 25, :voiceBridge => 12345, :record => "true", :duration => 20,
|
126
|
+
:meta_1 => "meta1", :meta_2 => "meta2" }
|
127
|
+
}
|
128
|
+
let(:req_response) {
|
129
|
+
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE", :createTime => "123123123" }
|
130
|
+
}
|
131
|
+
let(:final_response) {
|
132
|
+
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false, :createTime => 123123123 }
|
133
|
+
}
|
134
|
+
|
135
|
+
before { api.should_receive(:send_api_request).with(:create, req_params).and_return(req_response) }
|
136
|
+
subject {
|
137
|
+
options = { :moderatorPW => "mp", :attendeePW => "ap", :welcome => "Welcome!", :dialNumber => 12345678,
|
138
|
+
:logoutURL => "http://example.com", :maxParticipants => 25, :voiceBridge => 12345, :record => true,
|
139
|
+
:duration => 20, :meta_1 => "meta1", :meta_2 => "meta2" }
|
140
|
+
api.create_meeting("name", "meeting-id", options)
|
141
|
+
}
|
142
|
+
it { subject.should == final_response }
|
143
|
+
end
|
90
144
|
end
|
91
145
|
|
92
146
|
describe "#end_meeting" do
|
93
147
|
let(:meeting_id) { "meeting-id" }
|
94
148
|
let(:moderator_password) { "password" }
|
95
|
-
let(:params) { { :meetingID => meeting_id, :password => moderator_password } }
|
96
|
-
let(:response) { "anything" }
|
97
149
|
|
98
|
-
|
99
|
-
|
150
|
+
context "standard case" do
|
151
|
+
let(:params) { { :meetingID => meeting_id, :password => moderator_password } }
|
152
|
+
let(:response) { "anything" }
|
153
|
+
|
154
|
+
before { api.should_receive(:send_api_request).with(:end, params).and_return(response) }
|
155
|
+
it { api.end_meeting(meeting_id, moderator_password).should == response }
|
156
|
+
end
|
157
|
+
|
158
|
+
context "accepts non standard options" do
|
159
|
+
let(:params_in) {
|
160
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
161
|
+
}
|
162
|
+
let(:params_out) {
|
163
|
+
{ :meetingID => meeting_id, :password => moderator_password,
|
164
|
+
:anything1 => "anything-1", :anything2 => 2 }
|
165
|
+
}
|
166
|
+
before { api.should_receive(:send_api_request).with(:end, params_out) }
|
167
|
+
it { api.end_meeting(meeting_id, moderator_password, params_in) }
|
168
|
+
end
|
100
169
|
end
|
101
170
|
|
102
171
|
describe "#is_meeting_running?" do
|
@@ -114,18 +183,29 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
114
183
|
before { api.should_receive(:send_api_request).with(:isMeetingRunning, params).and_return(response) }
|
115
184
|
it { api.is_meeting_running?(meeting_id).should == false }
|
116
185
|
end
|
186
|
+
|
187
|
+
context "accepts non standard options" do
|
188
|
+
let(:params_in) {
|
189
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
190
|
+
}
|
191
|
+
let(:params_out) {
|
192
|
+
{ :meetingID => meeting_id, :anything1 => "anything-1", :anything2 => 2 }
|
193
|
+
}
|
194
|
+
before { api.should_receive(:send_api_request).with(:isMeetingRunning, params_out) }
|
195
|
+
it { api.is_meeting_running?(meeting_id, params_in) }
|
196
|
+
end
|
117
197
|
end
|
118
198
|
|
119
199
|
describe "#join_meeting_url" do
|
120
200
|
context "standard case" do
|
121
201
|
let(:params) {
|
122
202
|
{ :meetingID => "meeting-id", :password => "pw", :fullName => "Name",
|
123
|
-
:userID => "id123", :webVoiceConf => 12345678 }
|
203
|
+
:userID => "id123", :webVoiceConf => 12345678, :createTime => 9876543 }
|
124
204
|
}
|
125
205
|
|
126
206
|
before { api.should_receive(:get_url).with(:join, params).and_return("test-url") }
|
127
207
|
it {
|
128
|
-
options = { :userID => "id123", :webVoiceConf => 12345678 }
|
208
|
+
options = { :userID => "id123", :webVoiceConf => 12345678, :createTime => 9876543 }
|
129
209
|
api.join_meeting_url("meeting-id", "Name", "pw", options).should == "test-url"
|
130
210
|
}
|
131
211
|
end
|
@@ -140,82 +220,87 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
140
220
|
end
|
141
221
|
end
|
142
222
|
|
143
|
-
describe "#
|
223
|
+
describe "#get_meeting_info" do
|
224
|
+
let(:meeting_id) { "meeting-id" }
|
225
|
+
let(:password) { "password" }
|
226
|
+
|
144
227
|
context "standard case" do
|
145
|
-
let(:params) {
|
146
|
-
|
147
|
-
|
148
|
-
}
|
228
|
+
let(:params) { { :meetingID => meeting_id, :password => password } }
|
229
|
+
|
230
|
+
let(:attendee1) { { :userID => 123, :fullName => "Dexter Morgan", :role => "MODERATOR" } }
|
231
|
+
let(:attendee2) { { :userID => "id2", :fullName => "Cameron", :role => "VIEWER" } }
|
232
|
+
let(:response) {
|
233
|
+
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE",
|
234
|
+
:running => "TRUE", :startTime => "Thu Sep 01 17:51:42 UTC 2011", :endTime => "null",
|
235
|
+
:returncode => true, :attendees => { :attendee => [ attendee1, attendee2 ] },
|
236
|
+
:messageKey => "mkey", :message => "m", :participantCount => "50", :moderatorCount => "3",
|
237
|
+
:meetingName => "meeting-name", :maxUsers => "100", :voiceBridge => "12341234", :createTime => "123123123",
|
238
|
+
:recording => "false", :meta_1 => "abc", :meta_2 => "2" }
|
239
|
+
} # hash after the send_api_request call, before the formatting
|
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
|
149
251
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
api.join_meeting("meeting-id", "Name", "pw", options).should == "join-return"
|
154
|
-
}
|
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 }
|
155
255
|
end
|
156
256
|
|
157
257
|
context "accepts non standard options" do
|
158
|
-
let(:
|
159
|
-
{ :
|
160
|
-
|
258
|
+
let(:params_in) {
|
259
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
260
|
+
}
|
261
|
+
let(:params_out) {
|
262
|
+
{ :meetingID => meeting_id, :password => password,
|
263
|
+
:anything1 => "anything-1", :anything2 => 2 }
|
161
264
|
}
|
162
|
-
before { api.should_receive(:send_api_request).with(:
|
163
|
-
it { api.
|
265
|
+
before { api.should_receive(:send_api_request).with(:getMeetingInfo, params_out).and_return({}) }
|
266
|
+
it { api.get_meeting_info(meeting_id, password, params_in) }
|
164
267
|
end
|
165
268
|
end
|
166
269
|
|
167
|
-
describe "#get_meeting_info" do
|
168
|
-
let(:meeting_id) { "meeting-id" }
|
169
|
-
let(:password) { "password" }
|
170
|
-
let(:params) { { :meetingID => meeting_id, :password => password } }
|
171
|
-
|
172
|
-
let(:attendee1) { { :userID => 123, :fullName => "Dexter Morgan", :role => "MODERATOR" } }
|
173
|
-
let(:attendee2) { { :userID => "id2", :fullName => "Cameron", :role => "VIEWER" } }
|
174
|
-
let(:response) {
|
175
|
-
{ :meetingID => 123, :moderatorPW => 111, :attendeePW => 222, :hasBeenForciblyEnded => "FALSE",
|
176
|
-
:running => "TRUE", :startTime => "Thu Sep 01 17:51:42 UTC 2011", :endTime => "null",
|
177
|
-
:returncode => true, :attendees => { :attendee => [ attendee1, attendee2 ] },
|
178
|
-
:messageKey => "mkey", :message => "m", :participantCount => "50", :moderatorCount => "3" }
|
179
|
-
} # hash after the send_api_request call, before the formatting
|
180
|
-
|
181
|
-
let(:expected_attendee1) { { :userID => "123", :fullName => "Dexter Morgan", :role => :moderator } }
|
182
|
-
let(:expected_attendee2) { { :userID => "id2", :fullName => "Cameron", :role => :viewer } }
|
183
|
-
let(:final_response) {
|
184
|
-
{ :meetingID => "123", :moderatorPW => "111", :attendeePW => "222", :hasBeenForciblyEnded => false,
|
185
|
-
:running => true, :startTime => DateTime.parse("Thu Sep 01 17:51:42 UTC 2011"), :endTime => nil,
|
186
|
-
:returncode => true, :attendees => [ expected_attendee1, expected_attendee2 ],
|
187
|
-
:messageKey => "mkey", :message => "m", :participantCount => 50, :moderatorCount => 3 }
|
188
|
-
} # expected return hash after all the formatting
|
189
|
-
|
190
|
-
# ps: not mocking the formatter here because it's easier to just check the results (final_response)
|
191
|
-
before { api.should_receive(:send_api_request).with(:getMeetingInfo, params).and_return(response) }
|
192
|
-
it { api.get_meeting_info(meeting_id, password).should == final_response }
|
193
|
-
end
|
194
|
-
|
195
270
|
describe "#get_meetings" do
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
271
|
+
context "standard case" do
|
272
|
+
let(:meeting_hash1) { { :meetingID => "Demo Meeting", :attendeePW => "ap", :moderatorPW => "mp", :hasBeenForciblyEnded => false, :running => true } }
|
273
|
+
let(:meeting_hash2) { { :meetingID => "Ended Meeting", :attendeePW => "pass", :moderatorPW => "pass", :hasBeenForciblyEnded => true, :running => false } }
|
274
|
+
let(:flattened_response) {
|
275
|
+
{ :returncode => true, :meetings => [ meeting_hash1, meeting_hash2 ], :messageKey => "mkey", :message => "m" }
|
276
|
+
} # hash *after* the flatten_objects call
|
201
277
|
|
202
|
-
|
203
|
-
|
278
|
+
before {
|
279
|
+
api.should_receive(:send_api_request).with(:getMeetings, {}).
|
204
280
|
and_return(flattened_response)
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
281
|
+
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
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 }
|
288
|
+
end
|
289
|
+
|
290
|
+
context "accepts non standard options" do
|
291
|
+
let(:params) {
|
292
|
+
{ :anything1 => "anything-1", :anything2 => 2 }
|
293
|
+
}
|
294
|
+
before { api.should_receive(:send_api_request).with(:getMeetings, params).and_return({}) }
|
295
|
+
it { api.get_meetings(params) }
|
296
|
+
end
|
212
297
|
end
|
213
298
|
|
214
299
|
describe "#get_api_version" do
|
215
300
|
context "returns the version returned by the server" do
|
216
|
-
let(:hash) { { :returncode => true, :version => "0.
|
301
|
+
let(:hash) { { :returncode => true, :version => "0.8" } }
|
217
302
|
before { api.should_receive(:send_api_request).with(:index).and_return(hash) }
|
218
|
-
it { api.get_api_version.should == "0.
|
303
|
+
it { api.get_api_version.should == "0.8" }
|
219
304
|
end
|
220
305
|
|
221
306
|
context "returns an empty string when the server responds with an empty hash" do
|
@@ -370,12 +455,12 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
370
455
|
end
|
371
456
|
|
372
457
|
context "checking if it has a :response key" do
|
373
|
-
before {
|
458
|
+
before { BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return({ }) }
|
374
459
|
it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
375
460
|
end
|
376
461
|
|
377
462
|
context "checking if it the :response key has a :returncode key" do
|
378
|
-
before {
|
463
|
+
before { BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return({ :response => { } }) }
|
379
464
|
it { expect { make_request }.to raise_error(BigBlueButton::BigBlueButtonException) }
|
380
465
|
end
|
381
466
|
end
|
@@ -386,7 +471,7 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
386
471
|
before do
|
387
472
|
api.should_receive(:send_request).with(url, data).and_return(response_mock)
|
388
473
|
response_mock.should_receive(:body).twice.and_return("response-body")
|
389
|
-
|
474
|
+
BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return(response)
|
390
475
|
|
391
476
|
# here starts the validation
|
392
477
|
# doesn't test the resulting format, only that the formatter was called
|
@@ -403,7 +488,7 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
403
488
|
before do
|
404
489
|
api.should_receive(:send_request).with(url, data).and_return(response_mock)
|
405
490
|
response_mock.should_receive(:body).twice.and_return("response-body")
|
406
|
-
|
491
|
+
BigBlueButton::BigBlueButtonHash.should_receive(:from_xml).with("response-body").and_return(response)
|
407
492
|
|
408
493
|
formatter_mock = mock(BigBlueButton::BigBlueButtonFormatter)
|
409
494
|
BigBlueButton::BigBlueButtonFormatter.should_receive(:new).with(response).and_return(formatter_mock)
|
@@ -473,7 +558,174 @@ describe BigBlueButton::BigBlueButtonApi do
|
|
473
558
|
api.send(:send_request, url, data).should == "ok"
|
474
559
|
}
|
475
560
|
end
|
561
|
+
end
|
562
|
+
|
563
|
+
describe "#get_recordings" do
|
564
|
+
let(:recording1) { { :recordID => "id1", :meetindID => "meeting-id" } } # simplified "recording" node in the response
|
565
|
+
let(:recording2) { { :recordID => "id2", :meetindID => "meeting-id" } }
|
566
|
+
let(:response) {
|
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
|
578
|
+
|
579
|
+
context "without meeting ID" do
|
580
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, {}).and_return(response) }
|
581
|
+
it { api.get_recordings.should == response }
|
582
|
+
end
|
583
|
+
|
584
|
+
context "with one meeting ID" do
|
585
|
+
context "in an array" do
|
586
|
+
let(:options) { { :meetingID => ["meeting-id"] } }
|
587
|
+
let(:req_params) { { :meetingID => "meeting-id" } }
|
588
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
589
|
+
it { api.get_recordings(options).should == response }
|
590
|
+
end
|
591
|
+
|
592
|
+
context "in a string" do
|
593
|
+
let(:options) { { :meetingID => "meeting-id" } }
|
594
|
+
let(:req_params) { { :meetingID => "meeting-id" } }
|
595
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
596
|
+
it { api.get_recordings(options).should == response }
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
context "with several meeting IDs" do
|
601
|
+
context "in an array" do
|
602
|
+
let(:options) { { :meetingID => ["meeting-id-1", "meeting-id-2"] } }
|
603
|
+
let(:req_params) { { :meetingID => "meeting-id-1,meeting-id-2" } }
|
604
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
605
|
+
it { api.get_recordings(options).should == response }
|
606
|
+
end
|
607
|
+
|
608
|
+
context "in a string" do
|
609
|
+
let(:options) { { :meetingID => "meeting-id-1,meeting-id-2" } }
|
610
|
+
let(:req_params) { { :meetingID => "meeting-id-1,meeting-id-2" } }
|
611
|
+
before { api.should_receive(:send_api_request).with(:getRecordings, req_params).and_return(response) }
|
612
|
+
it { api.get_recordings(options).should == response }
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
context "formats the response" do
|
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
|
628
|
+
|
629
|
+
describe "#publish_recordings" do
|
630
|
+
|
631
|
+
context "publish is converted to string" do
|
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" } }
|
642
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
643
|
+
it { api.publish_recordings(recordIDs, true) }
|
644
|
+
end
|
645
|
+
|
646
|
+
context "in a string" do
|
647
|
+
let(:recordIDs) { "id-1" }
|
648
|
+
let(:req_params) { { :publish => "true", :recordID => "id-1" } }
|
649
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
650
|
+
it { api.publish_recordings(recordIDs, true) }
|
651
|
+
end
|
652
|
+
end
|
476
653
|
|
654
|
+
context "with several recording IDs" do
|
655
|
+
context "in an array" do
|
656
|
+
let(:recordIDs) { ["id-1", "id-2"] }
|
657
|
+
let(:req_params) { { :publish => "true", :recordID => "id-1,id-2" } }
|
658
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
659
|
+
it { api.publish_recordings(recordIDs, true) }
|
660
|
+
end
|
661
|
+
|
662
|
+
context "in a string" do
|
663
|
+
let(:recordIDs) { "id-1,id-2,id-3" }
|
664
|
+
let(:req_params) { { :publish => "true", :recordID => "id-1,id-2,id-3" } }
|
665
|
+
before { api.should_receive(:send_api_request).with(:publishRecordings, req_params) }
|
666
|
+
it { api.publish_recordings(recordIDs, true) }
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
context "accepts non standard options" do
|
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
|
683
|
+
|
684
|
+
describe "#delete_recordings" do
|
685
|
+
|
686
|
+
context "with one recording ID" do
|
687
|
+
context "in an array" do
|
688
|
+
let(:recordIDs) { ["id-1"] }
|
689
|
+
let(:req_params) { { :recordID => "id-1" } }
|
690
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
691
|
+
it { api.delete_recordings(recordIDs) }
|
692
|
+
end
|
693
|
+
|
694
|
+
context "in a string" do
|
695
|
+
let(:recordIDs) { "id-1" }
|
696
|
+
let(:req_params) { { :recordID => "id-1" } }
|
697
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
698
|
+
it { api.delete_recordings(recordIDs) }
|
699
|
+
end
|
700
|
+
end
|
701
|
+
|
702
|
+
context "with several recording IDs" do
|
703
|
+
context "in an array" do
|
704
|
+
let(:recordIDs) { ["id-1", "id-2"] }
|
705
|
+
let(:req_params) { { :recordID => "id-1,id-2" } }
|
706
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
707
|
+
it { api.delete_recordings(recordIDs) }
|
708
|
+
end
|
709
|
+
|
710
|
+
context "in a string" do
|
711
|
+
let(:recordIDs) { "id-1,id-2,id-3" }
|
712
|
+
let(:req_params) { { :recordID => "id-1,id-2,id-3" } }
|
713
|
+
before { api.should_receive(:send_api_request).with(:deleteRecordings, req_params) }
|
714
|
+
it { api.delete_recordings(recordIDs) }
|
715
|
+
end
|
716
|
+
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
|
477
729
|
end
|
478
730
|
|
479
731
|
end
|