bigbluebutton_rails 1.4.0 → 2.0.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.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +10 -1
  4. data/CHANGELOG.md +259 -0
  5. data/Gemfile +14 -19
  6. data/Gemfile.lock +194 -188
  7. data/README.md +416 -0
  8. data/Rakefile +12 -12
  9. data/TODO.md +13 -0
  10. data/app/controllers/bigbluebutton/playback_types_controller.rb +44 -0
  11. data/app/controllers/bigbluebutton/recordings_controller.rb +17 -10
  12. data/app/controllers/bigbluebutton/rooms_controller.rb +65 -36
  13. data/app/controllers/bigbluebutton/servers_controller.rb +12 -8
  14. data/app/models/bigbluebutton_metadata.rb +1 -1
  15. data/app/models/bigbluebutton_playback_format.rb +22 -1
  16. data/app/models/bigbluebutton_playback_type.rb +29 -0
  17. data/app/models/bigbluebutton_recording.rb +38 -19
  18. data/app/models/bigbluebutton_room.rb +150 -73
  19. data/app/models/bigbluebutton_room_options.rb +10 -7
  20. data/app/models/bigbluebutton_server.rb +69 -13
  21. data/app/models/bigbluebutton_server_config.rb +49 -0
  22. data/app/views/bigbluebutton/recordings/_form.html.erb +4 -0
  23. data/app/views/bigbluebutton/recordings/_recordings.html.erb +10 -3
  24. data/app/views/bigbluebutton/rooms/_form.html.erb +18 -6
  25. data/app/views/bigbluebutton/rooms/_rooms.html.erb +6 -3
  26. data/app/views/bigbluebutton/rooms/invite.html.erb +5 -5
  27. data/app/views/bigbluebutton/rooms/show.html.erb +18 -6
  28. data/app/views/bigbluebutton/servers/_form.html.erb +1 -1
  29. data/app/views/bigbluebutton/servers/show.html.erb +5 -0
  30. data/app/workers/bigbluebutton_finish_meetings.rb +11 -0
  31. data/app/workers/bigbluebutton_update_recordings.rb +11 -0
  32. data/app/workers/bigbluebutton_update_server_configs.rb +18 -0
  33. data/bigbluebutton_rails.gemspec +8 -7
  34. data/config/locales/en.yml +52 -7
  35. data/config/locales/pt-br.yml +162 -0
  36. data/config/resque/resque.rake +27 -0
  37. data/config/resque/workers_schedule.yml +17 -0
  38. data/lib/bigbluebutton_rails.rb +30 -2
  39. data/lib/bigbluebutton_rails/background_tasks.rb +31 -0
  40. data/lib/bigbluebutton_rails/controller_methods.rb +12 -8
  41. data/lib/bigbluebutton_rails/dial_number.rb +48 -0
  42. data/lib/bigbluebutton_rails/rails/routes.rb +9 -2
  43. data/lib/bigbluebutton_rails/utils.rb +9 -2
  44. data/lib/bigbluebutton_rails/version.rb +1 -1
  45. data/lib/generators/bigbluebutton_rails/install_generator.rb +0 -8
  46. data/lib/generators/bigbluebutton_rails/templates/migration.rb +28 -6
  47. data/lib/generators/bigbluebutton_rails/templates/migration_2_0_0.rb +56 -0
  48. data/lib/tasks/bigbluebutton_rails/meetings.rake +1 -13
  49. data/lib/tasks/bigbluebutton_rails/recordings.rake +1 -12
  50. data/lib/tasks/bigbluebutton_rails/server_configs.rake +10 -0
  51. data/spec/bigbluebutton_rails_spec.rb +0 -13
  52. data/spec/controllers/bigbluebutton/playback_types_controller_spec.rb +76 -0
  53. data/spec/controllers/bigbluebutton/recordings_controller_spec.rb +109 -37
  54. data/spec/controllers/bigbluebutton/rooms_controller_exception_handling_spec.rb +1 -0
  55. data/spec/controllers/bigbluebutton/rooms_controller_json_responses_spec.rb +27 -3
  56. data/spec/controllers/bigbluebutton/rooms_controller_spec.rb +338 -77
  57. data/spec/controllers/bigbluebutton/servers_controller_json_responses_spec.rb +8 -0
  58. data/spec/controllers/bigbluebutton/servers_controller_spec.rb +182 -47
  59. data/spec/factories/bigbluebutton_meeting.rb +2 -2
  60. data/spec/factories/bigbluebutton_playback_format.rb +2 -2
  61. data/spec/factories/bigbluebutton_playback_type.rb +7 -0
  62. data/spec/factories/bigbluebutton_recording.rb +8 -0
  63. data/spec/factories/bigbluebutton_room.rb +10 -3
  64. data/spec/factories/bigbluebutton_server.rb +6 -1
  65. data/spec/factories/bigbluebutton_server_config.rb +6 -0
  66. data/spec/generators/install_generator_spec.rb +0 -16
  67. data/spec/lib/bigbluebutton_rails/background_tasks_spec.rb +61 -0
  68. data/spec/lib/bigbluebutton_rails/dial_number_spec.rb +78 -0
  69. data/spec/lib/bigbluebutton_rails/utils_spec.rb +56 -0
  70. data/spec/lib/tasks/meetings_rake_spec.rb +14 -1
  71. data/spec/lib/tasks/recordings_rake_spec.rb +14 -1
  72. data/spec/models/bigbluebutton_meeting_db_spec.rb +3 -3
  73. data/spec/models/bigbluebutton_meeting_spec.rb +4 -4
  74. data/spec/models/bigbluebutton_playback_format_db_spec.rb +0 -1
  75. data/spec/models/bigbluebutton_playback_format_spec.rb +75 -4
  76. data/spec/models/bigbluebutton_playback_type_db_spec.rb +14 -0
  77. data/spec/models/bigbluebutton_playback_type_spec.rb +76 -0
  78. data/spec/models/bigbluebutton_recording_db_spec.rb +3 -1
  79. data/spec/models/bigbluebutton_recording_spec.rb +234 -58
  80. data/spec/models/bigbluebutton_room_db_spec.rb +8 -6
  81. data/spec/models/bigbluebutton_room_options_db_spec.rb +1 -0
  82. data/spec/models/bigbluebutton_room_options_spec.rb +137 -38
  83. data/spec/models/bigbluebutton_room_spec.rb +540 -153
  84. data/spec/models/bigbluebutton_server_config_spec.rb +115 -0
  85. data/spec/models/bigbluebutton_server_spec.rb +180 -23
  86. data/spec/rails_app/app/controllers/my_playback_types_controller.rb +7 -0
  87. data/spec/rails_app/app/views/frontpage/show.html.erb +1 -0
  88. data/spec/rails_app/app/views/my_playback_types/index.html.erb +33 -0
  89. data/spec/rails_app/config/application.rb +0 -3
  90. data/spec/rails_app/config/database.yml.travis +10 -0
  91. data/spec/rails_app/config/environments/development.rb +1 -6
  92. data/spec/rails_app/config/environments/production.rb +2 -0
  93. data/spec/rails_app/config/environments/test.rb +2 -0
  94. data/spec/rails_app/config/routes.rb +5 -2
  95. data/spec/rails_app/db/seeds.rb +1 -1
  96. data/spec/rails_app/features/config.yml.example +3 -4
  97. data/spec/rails_app/features/join_rooms.feature +14 -14
  98. data/spec/rails_app/features/step_definitions/activity_monitor_servers_step.rb +2 -2
  99. data/spec/rails_app/features/step_definitions/create_rooms_steps.rb +4 -4
  100. data/spec/rails_app/features/step_definitions/destroy_rooms_steps.rb +2 -2
  101. data/spec/rails_app/features/step_definitions/join_rooms_steps.rb +10 -10
  102. data/spec/rails_app/features/step_definitions/web_steps.rb +2 -2
  103. data/spec/rails_app/features/support/configurations.rb +1 -1
  104. data/spec/rails_app/features/support/templates.rb +12 -12
  105. data/spec/rails_app/lib/tasks/db/populate.rake +19 -6
  106. data/spec/routing/bigbluebutton/custom_controllers_routing_spec.rb +1 -1
  107. data/spec/routing/bigbluebutton/recordings_only_routing_spec.rb +2 -2
  108. data/spec/routing/bigbluebutton/recordings_routing_spec.rb +2 -2
  109. data/spec/routing/bigbluebutton/rooms_only_routing_spec.rb +1 -1
  110. data/spec/routing/bigbluebutton/rooms_routing_spec.rb +15 -1
  111. data/spec/routing/bigbluebutton/servers_only_routing_spec.rb +1 -1
  112. data/spec/routing/bigbluebutton/servers_routing_spec.rb +1 -1
  113. data/spec/spec_helper.rb +23 -31
  114. data/spec/support/matchers/delegate_matcher.rb +8 -1
  115. data/spec/support/matchers/shoulda/respond_with_json_matcher.rb +2 -2
  116. data/spec/support/mocked_server.rb +2 -0
  117. data/spec/support/shared_contexts/rake.rb +23 -0
  118. data/spec/workers/bigbluebutton_finish_meetings_spec.rb +14 -0
  119. data/spec/workers/bigbluebutton_update_recordings_spec.rb +14 -0
  120. data/spec/workers/bigbluebutton_update_server_configs_spec.rb +47 -0
  121. metadata +70 -59
  122. data/CHANGELOG.rdoc +0 -111
  123. data/README.rdoc +0 -319
  124. data/TODO.rdoc +0 -16
  125. data/config/schedule.rb +0 -7
@@ -9,8 +9,10 @@ describe BigbluebuttonRoom do
9
9
  it { should have_db_column(:owner_type).of_type(:string) }
10
10
  it { should have_db_column(:meetingid).of_type(:string) }
11
11
  it { should have_db_column(:name).of_type(:string) }
12
- it { should have_db_column(:attendee_password).of_type(:string) }
13
- it { should have_db_column(:moderator_password).of_type(:string) }
12
+ it { should have_db_column(:attendee_key).of_type(:string) }
13
+ it { should have_db_column(:moderator_key).of_type(:string) }
14
+ it { should have_db_column(:attendee_api_password).of_type(:string) }
15
+ it { should have_db_column(:moderator_api_password).of_type(:string) }
14
16
  it { should have_db_column(:welcome_msg).of_type(:string) }
15
17
  it { should have_db_column(:dial_number).of_type(:string) }
16
18
  it { should have_db_column(:logout_url).of_type(:string) }
@@ -19,17 +21,17 @@ describe BigbluebuttonRoom do
19
21
  it { should have_db_column(:private).of_type(:boolean) }
20
22
  it { should have_db_column(:external).of_type(:boolean) }
21
23
  it { should have_db_column(:param).of_type(:string) }
22
- it { should have_db_column(:record).of_type(:boolean) }
24
+ it { should have_db_column(:record_meeting).of_type(:boolean) }
23
25
  it { should have_db_column(:duration).of_type(:integer) }
24
26
  it { should have_db_column(:created_at).of_type(:datetime) }
25
27
  it { should have_db_column(:updated_at).of_type(:datetime) }
28
+ it { should have_db_column(:create_time).of_type(:integer) }
26
29
  it { should have_db_index(:server_id) }
27
30
  it { should have_db_index(:meetingid).unique(true) }
28
- it { should have_db_index(:voice_bridge).unique(true) }
29
31
  it "default values" do
30
32
  room = BigbluebuttonRoom.new
31
- room.private.should be_false
32
- room.external.should be_false
33
+ room.private.should be_falsey
34
+ room.external.should be_falsey
33
35
  room.meetingid.should_not be_nil
34
36
  end
35
37
  end
@@ -11,6 +11,7 @@ describe BigbluebuttonRoomOptions do
11
11
  it { should have_db_column(:presenter_share_only).of_type(:boolean)}
12
12
  it { should have_db_column(:auto_start_video).of_type(:boolean) }
13
13
  it { should have_db_column(:auto_start_audio).of_type(:boolean) }
14
+ it { should have_db_column(:background).of_type(:string) }
14
15
  end
15
16
 
16
17
  end
@@ -15,13 +15,6 @@ describe BigbluebuttonRoomOptions do
15
15
  .room.should be_a_kind_of(BigbluebuttonRoom) }
16
16
  it { should validate_presence_of(:room_id) }
17
17
 
18
- describe "#get_available_layouts" do
19
- it "returns the layouts available" do
20
- expected = ["Default", "Video Chat", "Meeting", "Webinar", "Lecture assistant", "Lecture"]
21
- room_options.get_available_layouts.should eql(expected)
22
- end
23
- end
24
-
25
18
  describe "#set_on_config_xml" do
26
19
  let(:config_xml) { '<config></config>' }
27
20
 
@@ -31,7 +24,8 @@ describe BigbluebuttonRoomOptions do
31
24
  room_options.update_attributes(:default_layout => "AnyLayout",
32
25
  :presenter_share_only => true,
33
26
  :auto_start_video => false,
34
- :auto_start_audio => false)
27
+ :auto_start_audio => false,
28
+ :background => "http://mconf.org/anything")
35
29
  BigBlueButton::BigBlueButtonConfigXml.any_instance
36
30
  .should_receive(:set_attribute)
37
31
  .with('layout', 'defaultLayout', "AnyLayout", false)
@@ -47,6 +41,9 @@ describe BigbluebuttonRoomOptions do
47
41
  BigBlueButton::BigBlueButtonConfigXml.any_instance
48
42
  .should_receive(:set_attribute)
49
43
  .with('PhoneModule', 'autoJoin', false, true)
44
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
45
+ .should_receive(:set_attribute)
46
+ .with('branding', 'background', "http://mconf.org/anything", false)
50
47
  BigBlueButton::BigBlueButtonConfigXml.any_instance
51
48
  .should_receive(:is_modified?).and_return(true)
52
49
  BigBlueButton::BigBlueButtonConfigXml.any_instance
@@ -58,33 +55,26 @@ describe BigbluebuttonRoomOptions do
58
55
 
59
56
  context "if the xml did not change" do
60
57
  before {
61
- room_options.update_attributes(:default_layout => "AnyLayout",
62
- :presenter_share_only => false,
63
- :auto_start_video => false,
64
- :auto_start_audio => false)
65
- BigBlueButton::BigBlueButtonConfigXml.any_instance
66
- .should_receive(:set_attribute)
67
- .with('layout', 'defaultLayout', "AnyLayout", false)
68
- BigBlueButton::BigBlueButtonConfigXml.any_instance
69
- .should_receive(:set_attribute)
70
- .with('VideoconfModule', 'presenterShareOnly', false, true)
71
- BigBlueButton::BigBlueButtonConfigXml.any_instance
72
- .should_receive(:set_attribute)
73
- .with('PhoneModule', 'presenterShareOnly', false, true)
74
- BigBlueButton::BigBlueButtonConfigXml.any_instance
75
- .should_receive(:set_attribute)
76
- .with('VideoconfModule', 'autoStart', false, true)
77
- BigBlueButton::BigBlueButtonConfigXml.any_instance
78
- .should_receive(:set_attribute)
79
- .with('PhoneModule', 'autoJoin', false, true)
80
- BigBlueButton::BigBlueButtonConfigXml.any_instance
58
+ BigBlueButton::BigBlueButtonConfigXml.stub(:set_attribute)
59
+
60
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
81
61
  .should_receive(:is_modified?).and_return(false)
82
62
  }
83
63
  subject { room_options.set_on_config_xml(config_xml) }
84
- it("returns false") { should be_false }
64
+ it("returns false") { should be(false) }
85
65
  end
86
66
 
87
67
  context "if #default_layout is" do
68
+ context "a valid string" do
69
+ before {
70
+ room_options.update_attributes(:default_layout => "my layout")
71
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
72
+ .should_receive(:set_attribute)
73
+ .with('layout', 'defaultLayout', "my layout", anything)
74
+ }
75
+ it("sets the property in the xml") { room_options.set_on_config_xml(config_xml) }
76
+ end
77
+
88
78
  context "nil" do
89
79
  before {
90
80
  room_options.update_attributes(:default_layout => nil)
@@ -119,6 +109,32 @@ describe BigbluebuttonRoomOptions do
119
109
  }
120
110
  it("doesn't set the property in the xml") { room_options.set_on_config_xml(config_xml) }
121
111
  end
112
+
113
+ context "true" do
114
+ before {
115
+ room_options.update_attributes(:presenter_share_only => true)
116
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
117
+ .should_receive(:set_attribute)
118
+ .with('VideoconfModule', 'presenterShareOnly', true, anything)
119
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
120
+ .should_receive(:set_attribute)
121
+ .with('PhoneModule', 'presenterShareOnly', true, anything)
122
+ }
123
+ it("sets the property in the xml") { room_options.set_on_config_xml(config_xml) }
124
+ end
125
+
126
+ context "false" do
127
+ before {
128
+ room_options.update_attributes(:presenter_share_only => false)
129
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
130
+ .should_receive(:set_attribute)
131
+ .with('VideoconfModule', 'presenterShareOnly', false, anything)
132
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
133
+ .should_receive(:set_attribute)
134
+ .with('PhoneModule', 'presenterShareOnly', false, anything)
135
+ }
136
+ it("sets the property in the xml") { room_options.set_on_config_xml(config_xml) }
137
+ end
122
138
  end
123
139
 
124
140
  context "if #auto_start_video is" do
@@ -131,6 +147,26 @@ describe BigbluebuttonRoomOptions do
131
147
  }
132
148
  it("doesn't set the property in the xml") { room_options.set_on_config_xml(config_xml) }
133
149
  end
150
+
151
+ context "true" do
152
+ before {
153
+ room_options.update_attributes(:auto_start_video => true)
154
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
155
+ .should_receive(:set_attribute)
156
+ .with('VideoconfModule', 'autoStart', true, anything)
157
+ }
158
+ it("sets the property in the xml") { room_options.set_on_config_xml(config_xml) }
159
+ end
160
+
161
+ context "false" do
162
+ before {
163
+ room_options.update_attributes(:auto_start_video => false)
164
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
165
+ .should_receive(:set_attribute)
166
+ .with('VideoconfModule', 'autoStart', false, anything)
167
+ }
168
+ it("sets the property in the xml") { room_options.set_on_config_xml(config_xml) }
169
+ end
134
170
  end
135
171
 
136
172
  context "if #auto_start_audio is" do
@@ -143,63 +179,126 @@ describe BigbluebuttonRoomOptions do
143
179
  }
144
180
  it("doesn't set the property in the xml") {room_options.set_on_config_xml(config_xml) }
145
181
  end
182
+
183
+ context "true" do
184
+ before {
185
+ room_options.update_attributes(:auto_start_audio => true)
186
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
187
+ .should_receive(:set_attribute)
188
+ .with('PhoneModule', 'autoJoin', true, anything)
189
+ }
190
+ it("sets the property in the xml") {room_options.set_on_config_xml(config_xml) }
191
+ end
192
+
193
+ context "false" do
194
+ before {
195
+ room_options.update_attributes(:auto_start_audio => false)
196
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
197
+ .should_receive(:set_attribute)
198
+ .with('PhoneModule', 'autoJoin', false, anything)
199
+ }
200
+ it("sets the property in the xml") {room_options.set_on_config_xml(config_xml) }
201
+ end
146
202
  end
147
203
 
204
+ context "if #background is" do
205
+ context "a valid string" do
206
+ before {
207
+ room_options.update_attributes(:background => "my background")
208
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
209
+ .should_receive(:set_attribute)
210
+ .with('branding', 'background', 'my background', anything)
211
+ }
212
+ it("sets the property in the xml") { room_options.set_on_config_xml(config_xml) }
213
+ end
214
+
215
+ context "nil" do
216
+ before {
217
+ room_options.update_attributes(:background => nil)
218
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
219
+ .should_not_receive(:set_attribute)
220
+ .with('branding', 'background', anything, anything)
221
+ }
222
+ it("doesn't set the property in the xml") {room_options.set_on_config_xml(config_xml) }
223
+ end
224
+
225
+ context "empty string" do
226
+ before {
227
+ room_options.update_attributes(:background => "")
228
+ BigBlueButton::BigBlueButtonConfigXml.any_instance
229
+ .should_not_receive(:set_attribute)
230
+ .with('branding', 'background', anything, anything)
231
+ }
232
+ it("doesn't set the property in the xml") { room_options.set_on_config_xml(config_xml) }
233
+ end
234
+ end
148
235
  end
149
236
 
150
237
  describe "#is_modified?" do
151
238
  context "if default_layout is set" do
152
239
  before { room_options.update_attributes(:default_layout => 'Any') }
153
240
  subject { room_options.is_modified? }
154
- it("returns true") { should be_true }
241
+ it { should be(true) }
155
242
  end
156
243
 
157
244
  context "if default_layout is not set" do
158
245
  before { room_options.update_attributes(:default_layout => nil) }
159
246
  subject { room_options.is_modified? }
160
- it("returns false") { should be_false }
247
+ it { should be(false) }
161
248
  end
162
249
 
163
250
  context "if default_layout is empty" do
164
251
  before { room_options.update_attributes(:default_layout => "") }
165
252
  subject { room_options.is_modified? }
166
- it("returns true") { should be_true }
253
+ it { should be(false) }
167
254
  end
168
255
 
169
256
  context "if presenter_share_only is set" do
170
257
  before { room_options.update_attributes(:presenter_share_only => true) }
171
258
  subject { room_options.is_modified? }
172
- it("returns true") { should be_true}
259
+ it { should be(true) }
173
260
  end
174
261
 
175
262
  context "if presenter_share_only is not set" do
176
263
  before { room_options.update_attributes(:presenter_share_only => nil) }
177
264
  subject { room_options.is_modified? }
178
- it("returns false") { should be_false }
265
+ it { should be(false) }
179
266
  end
180
267
 
181
268
  context "if auto_start_video is set" do
182
269
  before { room_options.update_attributes(:auto_start_video => true) }
183
270
  subject { room_options.is_modified? }
184
- it("returns true") { should be_true}
271
+ it { should be(true) }
185
272
  end
186
273
 
187
274
  context "if auto_start_video is not set" do
188
275
  before { room_options.update_attributes(:auto_start_video => nil) }
189
276
  subject { room_options.is_modified? }
190
- it("returns false" ) { should be_false }
277
+ it { should be(false) }
191
278
  end
192
279
 
193
280
  context "if auto_start_audio is set" do
194
281
  before { room_options.update_attributes(:auto_start_audio => true) }
195
282
  subject { room_options.is_modified? }
196
- it("returns true") { should be_true}
283
+ it { should be(true) }
197
284
  end
198
285
 
199
286
  context "if auto_start_audio is not set" do
200
287
  before { room_options.update_attributes(:auto_start_audio => nil) }
201
288
  subject { room_options.is_modified? }
202
- it("returns false" ) { should be_false }
289
+ it { should be(false) }
290
+ end
291
+
292
+ context "if background is set" do
293
+ before { room_options.update_attributes(:background => true) }
294
+ subject { room_options.is_modified? }
295
+ it { should be(true) }
296
+ end
297
+
298
+ context "if background is not set" do
299
+ before { room_options.update_attributes(:background => nil) }
300
+ subject { room_options.is_modified? }
301
+ it { should be(false) }
203
302
  end
204
303
  end
205
304
 
@@ -33,17 +33,14 @@ describe BigbluebuttonRoom do
33
33
  it { should delegate(:auto_start_audio).to(:room_options) }
34
34
  it { should delegate(:"auto_start_audio=").to(:room_options) }
35
35
 
36
- it { should delegate(:get_available_layouts).to(:room_options) }
36
+ it { should delegate(:background).to(:room_options) }
37
+ it { should delegate(:"background=").to(:room_options) }
37
38
 
38
39
  it { should validate_presence_of(:meetingid) }
39
40
  it { should validate_uniqueness_of(:meetingid) }
40
41
  it { should ensure_length_of(:meetingid).is_at_least(1).is_at_most(100) }
41
42
 
42
- it { should validate_presence_of(:voice_bridge) }
43
- it { should validate_uniqueness_of(:voice_bridge) }
44
-
45
43
  it { should validate_presence_of(:name) }
46
- it { should validate_uniqueness_of(:name) }
47
44
  it { should ensure_length_of(:name).is_at_least(1).is_at_most(150) }
48
45
 
49
46
  it { should validate_presence_of(:param) }
@@ -52,7 +49,7 @@ describe BigbluebuttonRoom do
52
49
 
53
50
  it { should be_boolean(:private) }
54
51
 
55
- it { should be_boolean(:record) }
52
+ it { should be_boolean(:record_meeting) }
56
53
 
57
54
  it { should validate_presence_of(:duration) }
58
55
  it { should validate_numericality_of(:duration).only_integer }
@@ -60,9 +57,9 @@ describe BigbluebuttonRoom do
60
57
  it { should allow_value(0).for(:duration) }
61
58
  it { should allow_value(1).for(:duration) }
62
59
 
63
- it { should ensure_length_of(:attendee_password).is_at_most(16) }
60
+ it { should ensure_length_of(:attendee_key).is_at_most(16) }
64
61
 
65
- it { should ensure_length_of(:moderator_password).is_at_most(16) }
62
+ it { should ensure_length_of(:moderator_key).is_at_most(16) }
66
63
 
67
64
  it { should ensure_length_of(:welcome_msg).is_at_most(250) }
68
65
 
@@ -71,7 +68,7 @@ describe BigbluebuttonRoom do
71
68
  # attr_accessors
72
69
  [:running, :participant_count, :moderator_count, :attendees,
73
70
  :has_been_forcibly_ended, :start_time, :end_time, :external,
74
- :server, :request_headers, :record, :duration].each do |attr|
71
+ :server, :request_headers, :record_meeting, :duration].each do |attr|
75
72
  it { should respond_to(attr) }
76
73
  it { should respond_to("#{attr}=") }
77
74
  end
@@ -87,13 +84,13 @@ describe BigbluebuttonRoom do
87
84
  it { should respond_to(:is_running?) }
88
85
 
89
86
  describe "#user_role" do
90
- let(:room) { FactoryGirl.build(:bigbluebutton_room, :moderator_password => "mod", :attendee_password => "att") }
87
+ let(:room) { FactoryGirl.build(:bigbluebutton_room, :moderator_key => "mod", :attendee_key => "att") }
91
88
  it { should respond_to(:user_role) }
92
- it { room.user_role({ :password => room.moderator_password }).should == :moderator }
93
- it { room.user_role({ :password => room.attendee_password }).should == :attendee }
94
- it { room.user_role({ :password => "wrong" }).should == nil }
95
- it { room.user_role({ :password => nil }).should == nil }
96
- it { room.user_role({ :not_password => "any" }).should == nil }
89
+ it { room.user_role({ :key => room.moderator_key }).should == :moderator }
90
+ it { room.user_role({ :key => room.attendee_key }).should == :attendee }
91
+ it { room.user_role({ :key => "wrong" }).should == nil }
92
+ it { room.user_role({ :key => nil }).should == nil }
93
+ it { room.user_role({ :not_key => "any" }).should == nil }
97
94
  it { room.user_role({ }).should == nil }
98
95
  it { room.user_role(nil).should == nil }
99
96
  end
@@ -119,18 +116,18 @@ describe BigbluebuttonRoom do
119
116
  let(:room) { BigbluebuttonRoom.last }
120
117
  let(:room2) { BigbluebuttonRoom.last }
121
118
  it { should respond_to(:attr_equal?) }
122
- it { room.attr_equal?(room2).should be_true }
119
+ it { room.attr_equal?(room2).should be_truthy }
123
120
  it "differentiates instance variables" do
124
121
  room2.running = !room.running
125
- room.attr_equal?(room2).should be_false
122
+ room.attr_equal?(room2).should be(false)
126
123
  end
127
124
  it "differentiates attributes" do
128
125
  room2.private = !room.private
129
- room.attr_equal?(room2).should be_false
126
+ room.attr_equal?(room2).should be(false)
130
127
  end
131
128
  it "differentiates objects" do
132
129
  room2 = room.dup
133
- room.attr_equal?(room2).should be_false
130
+ room.attr_equal?(room2).should be(false)
134
131
  end
135
132
  end
136
133
 
@@ -140,8 +137,8 @@ describe BigbluebuttonRoom do
140
137
  it "fetched attributes before they are fetched" do
141
138
  room.participant_count.should be(0)
142
139
  room.moderator_count.should be(0)
143
- room.running.should be_false
144
- room.has_been_forcibly_ended.should be_false
140
+ room.running.should be(false)
141
+ room.has_been_forcibly_ended.should be(false)
145
142
  room.start_time.should be_nil
146
143
  room.end_time.should be_nil
147
144
  room.attendees.should eql([])
@@ -155,25 +152,7 @@ describe BigbluebuttonRoom do
155
152
  b.meetingid.should == "user defined"
156
153
  }
157
154
  end
158
-
159
- context "voice_bridge" do
160
- it {
161
- b = BigbluebuttonRoom.new(:voice_bridge => "user defined")
162
- b.voice_bridge.should == "user defined"
163
- }
164
- context "with a random value" do
165
- it { room.voice_bridge.should_not be_nil }
166
- it { room.voice_bridge.should =~ /7[0-9]{4}/ }
167
- it "tries to randomize 10 times if voice_bridge already exists" do
168
- room = FactoryGirl.create(:bigbluebutton_room, :voice_bridge => "70000")
169
- BigbluebuttonRoom.stub(:find_by_voice_bridge).and_return(room)
170
- SecureRandom.should_receive(:random_number).exactly(10).and_return(0000)
171
- room2 = BigbluebuttonRoom.new # triggers the random_number calls
172
- room2.voice_bridge.should == "70000"
173
- end
174
- end
175
- end
176
- end
155
+ end
177
156
 
178
157
  describe "#room_options" do
179
158
  it "is created when the room is created" do
@@ -192,12 +171,12 @@ describe BigbluebuttonRoom do
192
171
  }
193
172
  it { @room.room_options.should_not be_nil }
194
173
  it("is not promptly saved") {
195
- @room.room_options.new_record?.should be_true
174
+ @room.room_options.new_record?.should be(true)
196
175
  }
197
176
  it("is saved when the room is saved") {
198
177
  @room.save!
199
178
  @room.reload
200
- @room.room_options.new_record?.should be_false
179
+ @room.room_options.new_record?.should be(false)
201
180
  }
202
181
  end
203
182
  end
@@ -226,7 +205,7 @@ describe BigbluebuttonRoom do
226
205
 
227
206
  context "sets param as the downcased parameterized name if param is" do
228
207
  after :each do
229
- @room.save.should be_true
208
+ @room.save.should be_truthy
230
209
  @room.param.should == @room.name.downcase.parameterize
231
210
  end
232
211
  it "nil" do
@@ -240,18 +219,18 @@ describe BigbluebuttonRoom do
240
219
  end
241
220
 
242
221
  context "when room set to private" do
243
- context "sets passwords that are not yet defined" do
244
- let(:room) { FactoryGirl.create(:bigbluebutton_room, :private => false, :moderator_password => nil, :attendee_password => nil) }
222
+ context "sets keys that are not yet defined" do
223
+ let(:room) { FactoryGirl.create(:bigbluebutton_room, :private => false, :moderator_key => nil, :attendee_key => nil) }
245
224
  before(:each) { room.update_attributes(:private => true) }
246
- it { room.moderator_password.should_not be_nil }
247
- it { room.attendee_password.should_not be_nil }
225
+ it { room.moderator_key.should_not be_nil }
226
+ it { room.attendee_key.should_not be_nil }
248
227
  end
249
228
 
250
- context "only sets the passwords if the room was public before" do
251
- let(:room) { FactoryGirl.create(:bigbluebutton_room, :private => true, :moderator_password => "123", :attendee_password => "321") }
229
+ context "only sets the keys if the room was public before" do
230
+ let(:room) { FactoryGirl.create(:bigbluebutton_room, :private => true, :moderator_key => "123", :attendee_key => "321") }
252
231
  before(:each) { room.update_attributes(:private => true) }
253
- it { room.moderator_password.should == "123" }
254
- it { room.attendee_password.should == "321" }
232
+ it { room.moderator_key.should == "123" }
233
+ it { room.attendee_key.should == "321" }
255
234
  end
256
235
  end
257
236
 
@@ -270,9 +249,9 @@ describe BigbluebuttonRoom do
270
249
  room.server = mocked_server
271
250
  }
272
251
  before(:each) { @response = room.fetch_is_running? }
273
- it { room.running.should be_false }
274
- it { room.is_running?.should be_false }
275
- it { @response.should be_false }
252
+ it { room.running.should be(false) }
253
+ it { room.is_running?.should be(false) }
254
+ it { @response.should be(false) }
276
255
  end
277
256
 
278
257
  context "fetches 'running' when running" do
@@ -282,9 +261,9 @@ describe BigbluebuttonRoom do
282
261
  room.server = mocked_server
283
262
  }
284
263
  before(:each) { @response = room.fetch_is_running? }
285
- it { room.running.should be_true }
286
- it { room.is_running?.should be_true }
287
- it { @response.should be_true }
264
+ it { room.running.should be_truthy }
265
+ it { room.is_running?.should be_truthy }
266
+ it { @response.should be_truthy }
288
267
  end
289
268
 
290
269
  end
@@ -326,7 +305,7 @@ describe BigbluebuttonRoom do
326
305
  context "fetches meeting info when the meeting is not running" do
327
306
  before {
328
307
  mocked_api.should_receive(:get_meeting_info).
329
- with(room.meetingid, room.moderator_password).and_return(hash_info)
308
+ with(room.meetingid, room.moderator_api_password).and_return(hash_info)
330
309
  room.should_receive(:require_server)
331
310
  room.server = mocked_server
332
311
  }
@@ -343,7 +322,7 @@ describe BigbluebuttonRoom do
343
322
  context "fetches meeting info when the meeting is running" do
344
323
  before {
345
324
  mocked_api.should_receive(:get_meeting_info).
346
- with(room.meetingid, room.moderator_password).and_return(hash_info2)
325
+ with(room.meetingid, room.moderator_api_password).and_return(hash_info2)
347
326
  room.should_receive(:require_server)
348
327
  room.server = mocked_server
349
328
  }
@@ -366,7 +345,7 @@ describe BigbluebuttonRoom do
366
345
  context "calls #update_current_meeting after the information is fetched" do
367
346
  before {
368
347
  mocked_api.should_receive(:get_meeting_info).
369
- with(room.meetingid, room.moderator_password).and_return(hash_info2)
348
+ with(room.meetingid, room.moderator_api_password).and_return(hash_info2)
370
349
  room.should_receive(:require_server)
371
350
  room.server = mocked_server
372
351
 
@@ -382,7 +361,7 @@ describe BigbluebuttonRoom do
382
361
 
383
362
  context "calls end_meeting" do
384
363
  before {
385
- mocked_api.should_receive(:end_meeting).with(room.meetingid, room.moderator_password)
364
+ mocked_api.should_receive(:end_meeting).with(room.meetingid, room.moderator_api_password)
386
365
  room.should_receive(:require_server)
387
366
  room.server = mocked_server
388
367
  }
@@ -404,15 +383,19 @@ describe BigbluebuttonRoom do
404
383
  end
405
384
 
406
385
  describe "#send_create" do
407
- let(:attendee_password) { Forgery(:basic).password }
408
- let(:moderator_password) { Forgery(:basic).password }
386
+ let(:time) { 1409531761442 }
387
+ let(:new_moderator_api_password) { Forgery(:basic).password }
388
+ let(:new_attendee_api_password) { Forgery(:basic).password }
389
+ let(:voice_bridge) { SecureRandom.random_number(99999) }
409
390
  let(:hash_create) {
410
391
  {
411
392
  :returncode => "SUCCESS", :meetingID => "test_id",
412
- :attendeePW => attendee_password, :moderatorPW => moderator_password,
393
+ :attendeePW => new_attendee_api_password, :moderatorPW => new_moderator_api_password,
394
+ :voiceBridge => voice_bridge, :createTime => time,
413
395
  :hasBeenForciblyEnded => "false", :messageKey => {}, :message => {}
414
396
  }
415
397
  }
398
+ let(:expected_params) { get_create_params(room) }
416
399
  before {
417
400
  room.update_attributes(:welcome_msg => "Anything")
418
401
  FactoryGirl.create(:bigbluebutton_room_metadata, :owner => room)
@@ -441,80 +424,223 @@ describe BigbluebuttonRoom do
441
424
  end
442
425
  end
443
426
 
427
+ context "sets the room's create_time" do
428
+ before do
429
+ mocked_api.should_receive(:create_meeting)
430
+ .with(room.name, room.meetingid, get_create_params(room))
431
+ .and_return(hash_create)
432
+ room.stub(:select_server).and_return(mocked_server)
433
+ room.server = mocked_server
434
+ room.send_create
435
+ end
436
+
437
+ it { expect(room.create_time).to eq(time) }
438
+ end
439
+
444
440
  context "sends create_meeting" do
445
441
 
446
442
  context "for a stored room" do
447
443
  before do
448
444
  mocked_api.should_receive(:create_meeting)
449
- .with(room.name, room.meetingid, get_create_params(room))
445
+ .with(room.name, room.meetingid, expected_params)
450
446
  .and_return(hash_create)
451
447
  room.stub(:select_server).and_return(mocked_server)
448
+
452
449
  room.server = mocked_server
453
450
  room.send_create
454
451
  end
455
- it { room.attendee_password.should be(attendee_password) }
456
- it { room.moderator_password.should be(moderator_password) }
457
- it { room.changed?.should be_false }
452
+ it { room.attendee_api_password.should be(new_attendee_api_password) }
453
+ it { room.moderator_api_password.should be(new_moderator_api_password) }
454
+ it { room.voice_bridge.should be(voice_bridge) }
455
+ it { room.changed?.should be(false) }
458
456
  end
459
457
 
460
458
  context "for a new record" do
461
459
  let(:new_room) { FactoryGirl.build(:bigbluebutton_room) }
462
460
  before do
461
+ params = get_create_params(new_room)
463
462
  mocked_api.should_receive(:create_meeting)
464
- .with(new_room.name, new_room.meetingid, get_create_params(new_room))
463
+ .with(new_room.name, new_room.meetingid, params)
465
464
  .and_return(hash_create)
466
465
  new_room.stub(:select_server).and_return(mocked_server)
467
466
  new_room.server = mocked_server
468
467
  new_room.send_create
469
468
  end
470
- it { new_room.attendee_password.should be(attendee_password) }
471
- it { new_room.moderator_password.should be(moderator_password) }
472
- it("and do not save the record") { new_room.new_record?.should be_true }
469
+ it { new_room.attendee_api_password.should be(new_attendee_api_password) }
470
+ it { new_room.moderator_api_password.should be(new_moderator_api_password) }
471
+ it { new_room.voice_bridge.should be(voice_bridge) }
472
+ it("and do not save the record") { new_room.new_record?.should be_truthy }
473
473
  end
474
474
 
475
475
  context "passing the user" do
476
476
  let(:user) { FactoryGirl.build(:user) }
477
477
  before do
478
+ params = get_create_params(room, user)
478
479
  mocked_api.should_receive(:create_meeting)
479
- .with(room.name, room.meetingid, get_create_params(room, user))
480
+ .with(room.name, room.meetingid, params)
480
481
  .and_return(hash_create)
481
482
  room.stub(:select_server).and_return(mocked_server)
482
483
  room.server = mocked_server
483
484
  room.send_create(user)
484
485
  end
485
- it { room.attendee_password.should be(attendee_password) }
486
- it { room.moderator_password.should be(moderator_password) }
487
- it { room.changed?.should be_false }
486
+ it { room.attendee_api_password.should be(new_attendee_api_password) }
487
+ it { room.moderator_api_password.should be(new_moderator_api_password) }
488
+ it { room.changed?.should be(false) }
488
489
  end
489
490
 
490
491
  context "passing additional options" do
491
492
  let(:user) { FactoryGirl.build(:user) }
492
- let(:user_opts) { { :record => false, :other => true } }
493
+ let(:user_opts) { { :record_meeting => false, :other => true } }
493
494
  before do
495
+ params = get_create_params(room, user).merge(user_opts)
494
496
  mocked_api.should_receive(:create_meeting)
495
- .with(room.name, room.meetingid, get_create_params(room, user).merge(user_opts))
497
+ .with(room.name, room.meetingid, params)
496
498
  .and_return(hash_create)
497
499
  room.stub(:select_server).and_return(mocked_server)
498
500
  room.server = mocked_server
499
501
  room.send_create(user, user_opts)
500
502
  end
501
- it { room.attendee_password.should be(attendee_password) }
502
- it { room.moderator_password.should be(moderator_password) }
503
- it { room.changed?.should be_false }
503
+ it { room.attendee_api_password.should be(new_attendee_api_password) }
504
+ it { room.moderator_api_password.should be(new_moderator_api_password) }
505
+ it { room.changed?.should be(false) }
506
+ end
507
+
508
+ context "when the call to create doesn't return a voice bridge" do
509
+ before do
510
+ room.update_attributes(:voice_bridge => nil)
511
+ hash_create.delete(:voiceBridge)
512
+
513
+ mocked_api.should_receive(:create_meeting)
514
+ .with(room.name, room.meetingid, get_create_params(room))
515
+ .and_return(hash_create)
516
+ room.stub(:select_server).and_return(mocked_server)
517
+ room.server = mocked_server
518
+ room.send_create
519
+ end
520
+ it { room.voice_bridge.should be_nil }
521
+ it { room.changed?.should be(false) }
522
+ end
523
+
524
+ context "when it's set to use local voice bridges" do
525
+ before {
526
+ @use_local_voice_bridges = BigbluebuttonRails.use_local_voice_bridges
527
+ BigbluebuttonRails.use_local_voice_bridges = true
528
+ }
529
+ after {
530
+ BigbluebuttonRails.use_local_voice_bridges = @use_local_voice_bridges
531
+ }
532
+
533
+ context "sets the voice bridge in the params if there's a voice bridge" do
534
+ let(:voice_bridge) { SecureRandom.random_number(99999) }
535
+ before do
536
+ room.update_attributes(:voice_bridge => voice_bridge)
537
+ create_params = get_create_params(room)
538
+ create_params.merge!({ :voiceBridge => voice_bridge })
539
+
540
+ mocked_api.should_receive(:create_meeting)
541
+ .with(room.name, room.meetingid, create_params)
542
+ .and_return(hash_create)
543
+ room.stub(:select_server).and_return(mocked_server)
544
+ room.server = mocked_server
545
+ room.send_create
546
+ end
547
+ it { room.changed?.should be(false) }
548
+ end
549
+
550
+ context "doesn't set the voice bridge if it's blank" do
551
+ let(:voice_bridge) { SecureRandom.random_number(99999) }
552
+ before do
553
+ room.update_attributes(:voice_bridge => "")
554
+
555
+ mocked_api.should_receive(:create_meeting)
556
+ .with(room.name, room.meetingid, get_create_params(room))
557
+ .and_return(hash_create)
558
+ room.stub(:select_server).and_return(mocked_server)
559
+ room.server = mocked_server
560
+ room.send_create
561
+ end
562
+ it { room.changed?.should be(false) }
563
+ end
504
564
  end
505
565
  end
506
566
 
507
- context "generates a meetingid if nil" do
567
+ context "generating a meeting id" do
508
568
  let(:new_id) { "new id" }
509
- before {
510
- room.meetingid = nil
569
+
570
+ ['', nil].each do |value|
571
+ it "generates a new one if it's empty or nil" do
572
+ room.meetingid = value
573
+ room.stub(:select_server).and_return(mocked_server)
574
+ room.server = mocked_server
575
+ room.should_receive(:unique_meetingid).and_return(new_id)
576
+ mocked_api.should_receive(:create_meeting)
577
+ .with(room.name, new_id, anything)
578
+ room.send_create
579
+ end
580
+ end
581
+
582
+ it "doesn't generate a new meetingid if already set" do
583
+ old_id = "old id"
584
+ room.meetingid = old_id
511
585
  room.stub(:select_server).and_return(mocked_server)
512
586
  room.server = mocked_server
513
- }
514
- it "before calling create" do
515
- room.should_receive(:unique_meetingid).and_return(new_id)
587
+ room.should_not_receive(:unique_meetingid)
588
+ mocked_api.should_receive(:create_meeting)
589
+ .with(room.name, old_id, anything)
590
+ room.send_create
591
+ end
592
+ end
593
+
594
+ context "generating a moderator password" do
595
+ let(:new_pass) { "new pass" }
596
+
597
+ ['', nil].each do |value|
598
+ it "generates a new one if it's empty or nil" do
599
+ room.moderator_api_password = value
600
+ room.stub(:select_server).and_return(mocked_server)
601
+ room.server = mocked_server
602
+ room.should_receive(:internal_password).and_return(new_pass)
603
+ mocked_api.should_receive(:create_meeting)
604
+ .with(room.name, anything, hash_including(moderatorPW: new_pass))
605
+ room.send_create
606
+ end
607
+ end
608
+
609
+ it "doesn't generate a new moderator password if already set" do
610
+ old_pass = "old pass"
611
+ room.moderator_api_password = old_pass
612
+ room.stub(:select_server).and_return(mocked_server)
613
+ room.server = mocked_server
614
+ room.should_not_receive(:internal_password)
615
+ mocked_api.should_receive(:create_meeting)
616
+ .with(room.name, anything, hash_including(moderatorPW: old_pass))
617
+ room.send_create
618
+ end
619
+ end
620
+
621
+ context "generating a attendee password" do
622
+ let(:new_pass) { "new pass" }
623
+
624
+ ['', nil].each do |value|
625
+ it "generates a new one if it's empty or nil" do
626
+ room.attendee_api_password = value
627
+ room.stub(:select_server).and_return(mocked_server)
628
+ room.server = mocked_server
629
+ room.should_receive(:internal_password).and_return(new_pass)
630
+ mocked_api.should_receive(:create_meeting)
631
+ .with(room.name, anything, hash_including(attendeePW: new_pass))
632
+ room.send_create
633
+ end
634
+ end
635
+
636
+ it "doesn't generate a new attendee password if already set" do
637
+ old_pass = "old pass"
638
+ room.attendee_api_password = old_pass
639
+ room.stub(:select_server).and_return(mocked_server)
640
+ room.server = mocked_server
641
+ room.should_not_receive(:internal_password)
516
642
  mocked_api.should_receive(:create_meeting)
517
- .with(room.name, new_id, get_create_params(room))
643
+ .with(room.name, anything, hash_including(attendeePW: old_pass))
518
644
  room.send_create
519
645
  end
520
646
  end
@@ -533,29 +659,27 @@ describe BigbluebuttonRoom do
533
659
 
534
660
  context "selects and requires a server" do
535
661
  let(:another_server) { FactoryGirl.create(:bigbluebutton_server) }
536
-
662
+ let(:room2) { FactoryGirl.create(:bigbluebutton_room, :server => nil) }
537
663
  context "and saves the result" do
538
664
  before do
539
- room.should_receive(:select_server).and_return(another_server)
540
- room.should_receive(:require_server)
541
- room.should_receive(:internal_create_meeting)
542
- room.server = mocked_server
543
- room.send_create
665
+ room2.should_receive(:internal_create_meeting)
666
+ room2.send_create
544
667
  end
545
- it { BigbluebuttonRoom.find(room.id).server_id.should == another_server.id }
668
+ # send_create will call require_server, so a server will be assigned
669
+ # to this room
670
+ it { BigbluebuttonRoom.find(room2.id).server_id.should_not be_nil }
546
671
  end
547
672
 
548
673
  context "and does not save when is a new record" do
549
674
  let(:new_room) { FactoryGirl.build(:bigbluebutton_room) }
550
675
  before do
551
- new_room.should_receive(:select_server).and_return(another_server)
552
676
  new_room.should_receive(:require_server)
553
677
  new_room.should_receive(:internal_create_meeting).and_return(nil)
554
678
  new_room.should_not_receive(:save)
555
679
  new_room.server = mocked_server
556
680
  new_room.send_create
557
681
  end
558
- it { new_room.new_record?.should be_true }
682
+ it { new_room.new_record?.should be_truthy }
559
683
  end
560
684
  end
561
685
 
@@ -583,7 +707,7 @@ describe BigbluebuttonRoom do
583
707
  before {
584
708
  room.should_receive(:require_server)
585
709
  mocked_api.should_receive(:join_meeting_url)
586
- .with(room.meetingid, username, room.moderator_password, join_options)
710
+ .with(room.meetingid, username, room.moderator_api_password, join_options)
587
711
  .and_return(expected)
588
712
  room.server = mocked_server
589
713
  }
@@ -596,7 +720,7 @@ describe BigbluebuttonRoom do
596
720
  before {
597
721
  room.should_receive(:require_server)
598
722
  mocked_api.should_receive(:join_meeting_url)
599
- .with(room.meetingid, username, room.attendee_password, join_options)
723
+ .with(room.meetingid, username, room.attendee_api_password, join_options)
600
724
  .and_return(expected)
601
725
  room.server = mocked_server
602
726
  }
@@ -605,16 +729,44 @@ describe BigbluebuttonRoom do
605
729
  end
606
730
 
607
731
  context "without a role" do
608
- let(:expected) { 'expected-url' }
609
- before {
610
- room.should_receive(:require_server)
611
- mocked_api.should_receive(:join_meeting_url)
612
- .with(room.meetingid, username, 'pass', join_options)
613
- .and_return(expected)
614
- room.server = mocked_server
615
- }
616
- subject { room.join_url(username, nil, 'pass', join_options) }
617
- it("returns the correct url") { subject.should eq(expected) }
732
+ context "passing the moderator key" do
733
+ let(:expected) { 'expected-url' }
734
+ before {
735
+ room.should_receive(:require_server)
736
+ mocked_api.should_receive(:join_meeting_url)
737
+ .with(room.meetingid, username, room.moderator_api_password, join_options)
738
+ .and_return(expected)
739
+ room.server = mocked_server
740
+ }
741
+ subject { room.join_url(username, nil, room.moderator_key, join_options) }
742
+ it("returns the correct url") { subject.should eq(expected) }
743
+ end
744
+
745
+ context "passing the attendee key" do
746
+ let(:expected) { 'expected-url' }
747
+ before {
748
+ room.should_receive(:require_server)
749
+ mocked_api.should_receive(:join_meeting_url)
750
+ .with(room.meetingid, username, room.attendee_api_password, join_options)
751
+ .and_return(expected)
752
+ room.server = mocked_server
753
+ }
754
+ subject { room.join_url(username, nil, room.attendee_key, join_options) }
755
+ it("returns the correct url") { subject.should eq(expected) }
756
+ end
757
+
758
+ context "passing an unmatching key" do
759
+ let(:expected) { 'expected-url' }
760
+ before {
761
+ room.should_receive(:require_server)
762
+ mocked_api.should_receive(:join_meeting_url)
763
+ .with(room.meetingid, username, nil, join_options)
764
+ .and_return(expected)
765
+ room.server = mocked_server
766
+ }
767
+ subject { room.join_url(username, nil, "wrong key", join_options) }
768
+ it("returns the correct url") { subject.should eq(expected) }
769
+ end
618
770
  end
619
771
 
620
772
  context "strips the url before returning it" do
@@ -632,8 +784,8 @@ describe BigbluebuttonRoom do
632
784
  describe "#fetch_new_token" do
633
785
  let(:config_xml) {
634
786
  '<config>
635
- <localeversion suppressWarning="false">0.8</localeversion>
636
- <version>0.8</version>
787
+ <localeversion suppressWarning="false">0.9.0</localeversion>
788
+ <version>264</version>
637
789
  <layout showLogButton="false" showVideoLayout="false" showResetLayout="false" defaultLayout="Webinar" showToolbar="true" showFooter="true" showMeetingName="true" showHelpButton="true" showLogoutWindow="true" showLayoutTools="true" showNetworkMonitor="true" confirmLogout="true"/>
638
790
  <modules>
639
791
  <module name="LayoutModule" url="http://server.test/client/LayoutModule.swf?v=15" uri="rtmp://server.test/bigbluebutton" layoutConfig="http://server.test/client/conf/layout.xml" enableEdit="true"/>
@@ -655,6 +807,7 @@ describe BigbluebuttonRoom do
655
807
  mocked_api.should_receive(:set_config_xml)
656
808
  .with(room.meetingid, 'fake-config-xml')
657
809
  .and_return('fake-token')
810
+ mocked_server.should_receive(:update_config).with('fake-config-xml')
658
811
  }
659
812
  it("returns the token generated") { room.fetch_new_token.should eql('fake-token') }
660
813
  end
@@ -682,17 +835,118 @@ describe BigbluebuttonRoom do
682
835
 
683
836
  end
684
837
 
685
- context "validates passwords" do
838
+ context "#available_layouts" do
839
+ context "delegates to server" do
840
+ let(:room) { FactoryGirl.build(:bigbluebutton_room) }
841
+ let(:layouts) { [ 'layout-1', 'another layout' ] }
842
+ before {
843
+ room.server.should_receive(:available_layouts)
844
+ .and_return(layouts)
845
+ }
846
+ it { room.available_layouts.should eql(layouts) }
847
+ end
848
+
849
+ context "returns and empty array if the server is nil" do
850
+ let(:room) { FactoryGirl.build(:bigbluebutton_room, server: nil) }
851
+ it { room.available_layouts.should eql([]) }
852
+ end
853
+ end
854
+
855
+ context "#available_layouts_names" do
856
+ context "delegates to server" do
857
+ let(:room) { FactoryGirl.build(:bigbluebutton_room) }
858
+ let(:layouts) { [ 'layout-1', 'another layout' ] }
859
+ before {
860
+ room.server.should_receive(:available_layouts_names)
861
+ .and_return(layouts)
862
+ }
863
+ it { room.available_layouts_names.should eql(layouts) }
864
+ end
865
+
866
+ context "returns and empty array if the server is nil" do
867
+ let(:room) { FactoryGirl.build(:bigbluebutton_room, server: nil) }
868
+ it { room.available_layouts_names.should eql([]) }
869
+ end
870
+ end
871
+
872
+ context "#available_layouts_for_select" do
873
+ context "delegates to server" do
874
+ let(:room) { FactoryGirl.build(:bigbluebutton_room) }
875
+ let(:layouts) { [ 'layout-1', 'another layout' ] }
876
+ before {
877
+ room.server.should_receive(:available_layouts_for_select)
878
+ .and_return(layouts)
879
+ }
880
+ it { room.available_layouts_for_select.should eql(layouts) }
881
+ end
882
+
883
+ context "returns and empty array if the server is nil" do
884
+ let(:room) { FactoryGirl.build(:bigbluebutton_room, server: nil) }
885
+ it { room.available_layouts_for_select.should eql([]) }
886
+ end
887
+ end
888
+
889
+ context "#generate_dial_number!" do
890
+ let(:room) { FactoryGirl.create(:bigbluebutton_room) }
891
+
892
+ context "generates the dial number and saves in the room" do
893
+ before {
894
+ BigbluebuttonRails::DialNumber.stub(:randomize).and_return("(99) 1234-5678")
895
+ }
896
+ it { room.generate_dial_number!.should be(true) }
897
+ it {
898
+ room.generate_dial_number!
899
+ room.reload.dial_number.should eql("(99) 1234-5678")
900
+ }
901
+ end
902
+
903
+ context "uses the pattern informed" do
904
+ before {
905
+ BigbluebuttonRails::DialNumber.should_receive(:randomize).with("(99) 12xx-xxxx")
906
+ }
907
+ it { room.generate_dial_number!("(99) 12xx-xxxx").should be(true) }
908
+ end
909
+
910
+ # tries several times
911
+
912
+ context "tries to generate a unique number multiple times" do
913
+ let!(:another_room) { FactoryGirl.create(:bigbluebutton_room, dial_number: "(99) 1234-5678") }
914
+ before {
915
+ expect(BigbluebuttonRails::DialNumber).to receive(:randomize).exactly(19).times.and_return("(99) 1234-5678")
916
+ expect(BigbluebuttonRails::DialNumber).to receive(:randomize).and_return("(99) 1234-5679") # unique
917
+ }
918
+ it { room.generate_dial_number!.should be(true) }
919
+ it {
920
+ room.generate_dial_number!
921
+ room.reload.dial_number.should eql("(99) 1234-5679")
922
+ }
923
+ end
924
+
925
+ context "returns nil if can't generate a unique number" do
926
+ before { @previous_dn = room.dial_number }
927
+ let!(:another_room) { FactoryGirl.create(:bigbluebutton_room, dial_number: "(99) 1234-5678") }
928
+ before {
929
+ expect(BigbluebuttonRails::DialNumber).to receive(:randomize).exactly(20).times.and_return("(99) 1234-5678")
930
+ }
931
+ it { room.generate_dial_number!.should be_nil }
932
+ it {
933
+ room.generate_dial_number!
934
+ room.reload.dial_number.should eql(@previous_dn)
935
+ }
936
+ end
937
+ end
938
+
939
+ context "validates keys" do
686
940
  context "for private rooms" do
687
941
  let(:room) { FactoryGirl.create(:bigbluebutton_room, :private => true) }
688
- it { room.should_not allow_value('').for(:moderator_password) }
689
- it { room.should_not allow_value('').for(:attendee_password) }
942
+ it { room.should_not allow_value('').for(:moderator_key) }
943
+ it { room.should_not allow_value('').for(:attendee_key) }
690
944
  end
691
945
 
692
946
  context "for public rooms" do
693
947
  let(:room) { FactoryGirl.create(:bigbluebutton_room, :private => false) }
694
- it { room.should allow_value('').for(:moderator_password) }
695
- it { room.should allow_value('').for(:attendee_password) }
948
+ it { room.should allow_value('').for(:moderator_key) }
949
+ it { room.should allow_value('').for(:attendee_key) }
696
950
  end
697
951
  end
698
952
 
@@ -740,16 +994,17 @@ describe BigbluebuttonRoom do
740
994
  room.should_receive(:is_running?).and_return(true)
741
995
  }
742
996
  subject { room.create_meeting(user) }
743
- it { should be_false }
997
+ it { should be(false) }
744
998
  end
745
999
 
746
1000
  context "when the conference is not running" do
747
1001
  before {
748
1002
  room.should_receive(:is_running?).and_return(false)
749
1003
  room.should_receive(:send_create).with(user, {})
1004
+ room.should_receive(:send_end)
750
1005
  }
751
1006
  subject { room.create_meeting(user) }
752
- it { should be_true }
1007
+ it { should be(true) }
753
1008
  end
754
1009
 
755
1010
  context "when the parameter 'request' is informed" do
@@ -760,23 +1015,24 @@ describe BigbluebuttonRoom do
760
1015
  room.should_receive(:add_domain_to_logout_url).with("HTTP://", "test.com:80")
761
1016
  room.should_receive(:is_running?).and_return(false)
762
1017
  room.should_receive(:send_create)
1018
+ room.should_receive(:send_end)
763
1019
  }
764
1020
  subject { room.create_meeting(user, request) }
765
- it { should be_true }
1021
+ it { should be(true) }
766
1022
  end
767
1023
 
768
- # context "when the parameter 'request' is informed" do
769
- # let(:request) { double(ActionDispatch::Request) }
770
- # before {
771
- # request.stub(:protocol).and_return("HTTP://")
772
- # request.stub(:host_with_port).and_return("test.com:80")
773
- # room.should_receive(:add_domain_to_logout_url).with("HTTP://", "test.com:80")
774
- # room.should_receive(:is_running?).and_return(false)
775
- # room.should_receive(:send_create)
776
- # }
777
- # subject { room.create_meeting(user.name, user.id, request) }
778
- # it { should be_true }
779
- # end
1024
+ context "ignores exceptions raised by send_end (for when there's no meeting created)" do
1025
+ before {
1026
+ room.should_receive(:is_running?).and_return(false)
1027
+ room.should_receive(:send_create).with(user, {})
1028
+ room.should_receive(:send_end) { raise BigBlueButton::BigBlueButtonException.new('test') }
1029
+ }
1030
+ it {
1031
+ expect {
1032
+ room.create_meeting(user)
1033
+ }.not_to raise_error
1034
+ }
1035
+ end
780
1036
  end
781
1037
 
782
1038
  describe "#full_logout_url" do
@@ -787,30 +1043,77 @@ describe BigbluebuttonRoom do
787
1043
 
788
1044
  describe "#require_server" do
789
1045
  let(:room) { FactoryGirl.create(:bigbluebutton_room) }
790
- it { should respond_to(:require_server) }
1046
+ it { room.respond_to?(:require_server, true).should be(true) }
791
1047
 
792
- context "throws exception when the room has no server associated" do
793
- before { room.server = nil }
794
- it {
795
- expect {
796
- room.send(:require_server)
797
- }.to raise_error(BigbluebuttonRails::ServerRequired)
1048
+ context "if the room has no server associated" do
1049
+ let(:server) { FactoryGirl.create(:bigbluebutton_server) }
1050
+ before {
1051
+ room.server = nil
798
1052
  }
1053
+
1054
+ context "assigns server to room if there is one" do
1055
+ before {
1056
+ room.send(:require_server)
1057
+ }
1058
+ it { room.reload.server.should_not be_nil }
1059
+ end
1060
+
1061
+ context "raises exception if there are no servers to assign" do
1062
+ before {
1063
+ room.should_receive(:select_server).and_return(nil)
1064
+ }
1065
+ it {
1066
+ expect {
1067
+ room.send(:require_server)
1068
+ }.to raise_error(BigbluebuttonRails::ServerRequired)
1069
+ }
1070
+ end
1071
+
1072
+ context "doesn't save the room if no server is selected" do
1073
+ before {
1074
+ @updated_at = room.updated_at
1075
+ room.should_receive(:select_server).and_return(nil)
1076
+ expect {
1077
+ room.send(:require_server)
1078
+ }.to raise_error(BigbluebuttonRails::ServerRequired)
1079
+ }
1080
+ it { room.updated_at.should eql(@updated_at) }
1081
+ end
1082
+
1083
+ context "doesn't save the room if it's a new record" do
1084
+ let(:room) { FactoryGirl.build(:bigbluebutton_room) }
1085
+ before {
1086
+ room.should_receive(:select_server).and_return(server)
1087
+ room.send(:require_server)
1088
+ }
1089
+ it { room.new_record?.should be(true) }
1090
+ it { room.server.should eql(server) }
1091
+ end
1092
+
1093
+ context "passes the api_method parameter to #select_server" do
1094
+ let(:method) { :my_api_method }
1095
+ before {
1096
+ room.should_receive(:select_server).with(method).and_return(server)
1097
+ }
1098
+ it { room.send(:require_server, method) }
1099
+ end
799
1100
  end
800
1101
 
801
1102
  context "does nothing if the room has a server associated" do
802
- before { room.server = FactoryGirl.create(:bigbluebutton_server) }
803
- it {
1103
+ let(:server) { FactoryGirl.create(:bigbluebutton_server) }
1104
+ before {
1105
+ room.server = server
804
1106
  expect {
805
1107
  room.send(:require_server)
806
- }.not_to raise_error()
1108
+ }.not_to raise_error
807
1109
  }
1110
+ it { room.server.should eql(server) }
808
1111
  end
809
1112
  end
810
1113
 
811
1114
  describe "#select_server" do
812
1115
  let(:room) { FactoryGirl.create(:bigbluebutton_room, :server => nil) }
813
- it { should respond_to(:select_server) }
1116
+ it { room.respond_to?(:select_server, true).should be(true) }
814
1117
 
815
1118
  context "selects the server with less rooms" do
816
1119
  before {
@@ -824,7 +1127,15 @@ describe BigbluebuttonRoom do
824
1127
  end
825
1128
 
826
1129
  context "returns nil of there are no servers" do
827
- before(:each) { BigbluebuttonServer.destroy_all }
1130
+ before { BigbluebuttonServer.destroy_all }
1131
+ it { room.send(:select_server).should == nil }
1132
+ end
1133
+
1134
+ context "returns nil if the room already has a server" do
1135
+ before {
1136
+ 2.times{ FactoryGirl.create(:bigbluebutton_server) }
1137
+ room.update_attributes(server: FactoryGirl.create(:bigbluebutton_server))
1138
+ }
828
1139
  it { room.send(:select_server).should == nil }
829
1140
  end
830
1141
  end
@@ -881,7 +1192,7 @@ describe BigbluebuttonRoom do
881
1192
  before {
882
1193
  room.start_time = Time.now.utc
883
1194
  room.running = !room.running # to change its default value
884
- room.record = !room.record # to change its default value
1195
+ room.record_meeting = !room.record_meeting # to change its default value
885
1196
  }
886
1197
 
887
1198
  context "if there's no meeting associated yet creates one" do
@@ -897,7 +1208,7 @@ describe BigbluebuttonRoom do
897
1208
  it("sets room") { subject.room.should eq(room) }
898
1209
  it("sets meetingid") { subject.meetingid.should eq(room.meetingid) }
899
1210
  it("sets name") { subject.name.should eq(room.name) }
900
- it("sets record") { subject.record.should eq(room.record) }
1211
+ it("sets recorded") { subject.recorded.should eq(room.record_meeting) }
901
1212
  it("sets running") { subject.running.should eq(room.running) }
902
1213
  it("sets start_time") { subject.start_time.utc.to_i.should eq(room.start_time.utc.to_i) }
903
1214
  it("doesn't set creator_id") { subject.creator_id.should be_nil }
@@ -943,7 +1254,7 @@ describe BigbluebuttonRoom do
943
1254
  it("sets room") { subject.room.should eq(room) }
944
1255
  it("sets meetingid") { subject.meetingid.should eq(room.meetingid) }
945
1256
  it("sets name") { subject.name.should eq(room.name) }
946
- it("sets record") { subject.record.should eq(room.record) }
1257
+ it("sets recorded") { subject.recorded.should eq(room.record_meeting) }
947
1258
  it("sets running") { subject.running.should eq(room.running) }
948
1259
  it("sets start_time") { subject.start_time.utc.to_i.should eq(room.start_time.utc.to_i) }
949
1260
  it("doesn't set creator_id") { subject.creator_id.should be_nil }
@@ -968,7 +1279,27 @@ describe BigbluebuttonRoom do
968
1279
  end
969
1280
 
970
1281
  describe "#finish_meetings" do
971
- it "finishes all meetings related to this room that are still running"
1282
+ let!(:room) { FactoryGirl.create(:bigbluebutton_room) }
1283
+
1284
+ context "finishes all meetings related to this room that are still running" do
1285
+ let!(:meeting1) { FactoryGirl.create(:bigbluebutton_meeting, room: room, running: true) }
1286
+ let!(:meeting2) { FactoryGirl.create(:bigbluebutton_meeting, room: room, running: true) }
1287
+ before(:each) { room.finish_meetings }
1288
+ it { meeting1.reload.running.should be(false) }
1289
+ it { meeting2.reload.running.should be(false) }
1290
+ end
1291
+
1292
+ context "works if the room has no meetings" do
1293
+ it { room.finish_meetings }
1294
+ end
1295
+
1296
+ context "works if the room has no meetings running" do
1297
+ let!(:meeting1) { FactoryGirl.create(:bigbluebutton_meeting, room: room, running: false) }
1298
+ let!(:meeting2) { FactoryGirl.create(:bigbluebutton_meeting, room: room, running: false) }
1299
+ it { room.finish_meetings }
1300
+ it { meeting1.reload.running.should be(false) }
1301
+ it { meeting2.reload.running.should be(false) }
1302
+ end
972
1303
  end
973
1304
 
974
1305
  describe "#internal_create_meeting" do
@@ -979,6 +1310,61 @@ describe BigbluebuttonRoom do
979
1310
  it "calls api.create_meeting"
980
1311
  it "accepts additional user options to override the options in the database"
981
1312
 
1313
+ context "adds the invitation URL, if any" do
1314
+ before { mock_server_and_api }
1315
+ let(:room) { FactoryGirl.create(:bigbluebutton_room) }
1316
+
1317
+ before {
1318
+ mocked_api.stub(:"request_headers=")
1319
+ room.server = mocked_server
1320
+ }
1321
+
1322
+ it { room.should_not respond_to(:invitation_url) }
1323
+
1324
+ context "doesn't add the invitation URL by default" do
1325
+ before {
1326
+ mocked_api.should_receive(:create_meeting) do |name, meetingid, opts|
1327
+ opts.should_not have_key('meta_invitation-url')
1328
+ opts.should_not have_key(:'meta_invitation-url')
1329
+ end
1330
+ }
1331
+ it { room.send(:internal_create_meeting) }
1332
+ end
1333
+
1334
+ context "doesn't add the invitation URL if BigbluebuttonRoom#invitation_url returns nil" do
1335
+ before {
1336
+ BigbluebuttonRoom.class_eval do
1337
+ def invitation_url
1338
+ nil
1339
+ end
1340
+ end
1341
+
1342
+ room.should respond_to(:invitation_url)
1343
+ mocked_api.should_receive(:create_meeting) do |name, meetingid, opts|
1344
+ opts.should_not have_key('meta_invitation-url')
1345
+ opts.should_not have_key(:'meta_invitation-url')
1346
+ end
1347
+ }
1348
+ it { room.send(:internal_create_meeting) }
1349
+ end
1350
+
1351
+ context "adds the value returned by BigbluebuttonRoom#invitation_url" do
1352
+ before {
1353
+ BigbluebuttonRoom.class_eval do
1354
+ def invitation_url
1355
+ 'http://my-invitation.url'
1356
+ end
1357
+ end
1358
+
1359
+ room.should respond_to(:invitation_url)
1360
+ mocked_api.should_receive(:create_meeting) do |name, meetingid, opts|
1361
+ opts.should include('meta_invitation-url' => 'http://my-invitation.url')
1362
+ end
1363
+ }
1364
+ it { room.send(:internal_create_meeting) }
1365
+ end
1366
+ end
1367
+
982
1368
  context "schedules a BigbluebuttonMeetingUpdater" do
983
1369
  before { mock_server_and_api }
984
1370
  let(:room) { FactoryGirl.create(:bigbluebutton_room) }
@@ -999,20 +1385,21 @@ describe BigbluebuttonRoom do
999
1385
  it("the job should have the correct parameters") { subject['args'].should eq([room.id]) }
1000
1386
  end
1001
1387
  end
1002
-
1003
1388
  end
1004
1389
 
1005
1390
  def get_create_params(room, user=nil)
1006
1391
  params = {
1007
- :moderatorPW => room.moderator_password,
1008
- :attendeePW => room.attendee_password,
1392
+ :record => room.record_meeting,
1393
+ :duration => room.duration,
1394
+ :moderatorPW => room.moderator_api_password,
1395
+ :attendeePW => room.attendee_api_password,
1009
1396
  :welcome => room.welcome_msg,
1010
1397
  :dialNumber => room.dial_number,
1011
1398
  :logoutURL => room.logout_url,
1012
1399
  :maxParticipants => room.max_participants,
1013
- :voiceBridge => room.voice_bridge,
1014
- :record => room.record,
1015
- :duration => room.duration
1400
+ :moderatorOnlyMessage => room.moderator_only_message,
1401
+ :autoStartRecording => room.auto_start_recording,
1402
+ :allowStartStopRecording => room.allow_start_stop_recording
1016
1403
  }
1017
1404
  room.metadata.each { |meta| params["meta_#{meta.name}"] = meta.content }
1018
1405
  unless user.nil?