bigbluebutton_rails 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.0.4
2
+
3
+ * A random voice_bridge with 5 digits (recommended) is set when a room is created.
4
+ * Routes generators now allow specifying custom controllers instead of the defaults Bigbluebutton::ServersController and Bigbluebutton::RoomsController.
5
+ * Some bug fixes (including fixes for ruby 1.8).
6
+
1
7
  == 0.0.3
2
8
 
3
9
  * Rooms can be public or private
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bigbluebutton_rails (0.0.3)
4
+ bigbluebutton_rails (0.0.4)
5
5
  bigbluebutton-api-ruby (~> 0.0.10)
6
6
  rails (~> 3.0.3)
7
7
 
data/README.rdoc CHANGED
@@ -7,18 +7,22 @@ Features:
7
7
  * Full API access using bigbluebutton-api-ruby (https://github.com/mconf/bigbluebutton-api-ruby)
8
8
  * Easy way to join conferences: simply create a room and call the "join" action
9
9
  * Easy integration with authentication and authorization mechanisms, such as Devise and CanCan
10
+ * Possibility to create private rooms, that require a password to join
11
+ * Deals with visitors (users that are not logged), allowing (or forbidding) them to join rooms
12
+ * Random meeting IDs to avoid problems with end_meeting, timeouts and reuse of URLs
10
13
 
11
- Future:
12
- * Private room and invitations to allow visitants to join conferences (using a password or not).
14
+ Planned features:
13
15
  * Friendly URLs (e.g. http://somewhere.com/my-server/my-room)
14
- * Random meeting IDs to avoid problems with end_meeting and timeouts
16
+ * Limit the number of users per room and rooms per server
15
17
  * Server administration (modify config.xml, use bbb-conf, etc.)
18
+ * Load balancing
19
+ * Dealing with rooms that exist in the BigBlueButton server but not in the DB
16
20
 
17
21
  For more future features and issues check {our google code page}[http://code.google.com/p/mconf/issues/list?can=2&q=label%3AComponent%20label%3ABigBlueButtonRails].
18
22
 
19
23
  == Installation
20
24
 
21
- You can install the latest version of bigbluebutton_rails using RubyGems:
25
+ You can install the latest version of BigbluebuttonRails using RubyGems:
22
26
 
23
27
  gem install bigbluebutton_rails
24
28
 
@@ -31,24 +35,13 @@ After installing, you need to run the generator:
31
35
  rails generate bigbluebutton_rails:install
32
36
 
33
37
  This generator will create a migration file and a locale file in your application directories.
34
- Take a look at the migration to see how the models used by bigbluebutton_rails look like.
38
+ Take a look at the migration to see how the models used by BigbluebuttonRails look like.
35
39
 
36
- All models, controllers and views used are embedded in the gem, but you can replace or extend them if you need to.
37
- There is one generator to help you with that:
38
-
39
- rails generate bigbluebutton_rails:views
40
-
41
- It copies all bigbluebutton_rails views into your application, so you can customize them as you wish.
42
-
43
- There is yet another generator that copies the public files (javascripts, images and stylesheets) used by bigbluebutton_rails:
44
-
45
- rails generate bigbluebutton_rails:public
46
-
47
- For more information see the section Dependencies below.
40
+ To now more about the generators see {How to: Generators}[https://github.com/mconf/bigbluebutton_rails/wiki/How-to:-Generators]
48
41
 
49
42
  === Routes
50
43
 
51
- The routes to bigbluebutton_rails can be generated with the helper <tt>bigbluebutton_routes</tt>. See the example below:
44
+ The routes to BigbluebuttonRails can be generated with the helper <tt>bigbluebutton_routes</tt>. See the example below:
52
45
 
53
46
  bigbluebutton_routes :default
54
47
 
@@ -63,42 +56,49 @@ The first line generates the default routes. You need to call it at least once t
63
56
 
64
57
  bigbluebutton_routes :default
65
58
 
66
- To have your rooms beloging to a model other than servers, use the room_matchers:
59
+ It generates routes scoped with 'bigbluebutton'. These routes look like:
60
+
61
+ /bigbluebutton/servers
62
+ /bigbluebutton/servers/1/rooms/2
63
+ /bigbluebutton/servers/2/rooms/3/join
64
+
65
+ You can customize the scope name and also make the routes point to custom controllers.
66
+
67
+ bigbluebutton_routes :default, :scope => 'webconference', :controllers => { :servers => 'custom_servers', :rooms => 'custom_rooms' }
68
+ bigbluebutton_routes :default, :scope => '' # to remove the scope
69
+
70
+ If you customize the controllers as in the first line in the example above, be warned that every route generated after this will
71
+ be using these controllers!
72
+
73
+ You may also want shorter routes to access conference rooms. For that, use the option <tt>room_matchers</tt>:
67
74
 
68
75
  bigbluebutton_routes :room_matchers
69
76
 
70
- It creates routes to the actions "show", "running", "end", and "join".
77
+ It creates routes to the actions used to access the conference room: "show", "join", "auth", "running", "end", and "invite".
71
78
  So you can allow access to webconference rooms using URLs such as:
72
79
 
73
80
  http://myserver.com/user-10/room-5/join
74
81
  http://myserver.com/zaphod/public-room/join
75
82
 
76
- Obs: bigbluebutton_rails does not allows the room access using IDs such as "room-5" or "public-room" yet, but soon you it will.
83
+ Obs: BigbluebuttonRails does not allows the room access using IDs such as "room-5" or "public-room" yet, but soon you it will.
77
84
 
78
85
  === User authorization, permissions and assumptions
79
86
 
80
- There are some basic assumptions made by bigbluebutton_rails:
87
+ There are some basic assumptions made by BigbluebuttonRails:
81
88
 
82
89
  * You have a method called <tt>current_user</tt> that returns the current user;
83
90
  * The <tt>current_user</tt> has an attribute or method called "name" that returns his/her fullname.
84
91
 
85
92
  If you don't, you can change this behaviour easily, keep reading.
86
93
 
87
- bigbluebutton_rails uses the methods <tt>bigbluebutton_user</tt> and <tt>bigbluebutton_role(room)</tt> to get the current user and to get the permission that the current
88
- user has in the <tt>room</tt>, respectively. These methods are defined in <tt>lib/bigbluebutton_rails/controller_methods.rb</tt> and you can reimplement them in your
89
- application controller to change their behaviour.
90
-
91
- Although this is the general rule, the permission checking is different for public or private rooms. Check the <tt>How it Works</tt>
92
- section below for more details.
93
-
94
-
95
- ==== Integration with Devise
96
-
97
- To be written...
94
+ BigbluebuttonRails uses the methods <tt>bigbluebutton_user</tt> and <tt>bigbluebutton_role(room)</tt> to get the current user and to get the permission that the current
95
+ user has in the <tt>room</tt>, respectively. These methods are defined in {lib/bigbluebutton_rails/controller_methods.rb}[https://github.com/mconf/bigbluebutton_rails/blob/master/lib/bigbluebutton_rails/controller_methods.rb]
96
+ and you can reimplement them in your application controller to change their behaviour.
98
97
 
99
- ==== Integration with CanCan
98
+ ==== See also
100
99
 
101
- To be written...
100
+ * {How to: Integrate with Devise}[https://github.com/mconf/bigbluebutton_rails/wiki/How-to:-Integrate-with-Devise]
101
+ * {How to: Integrate with CanCan}[https://github.com/mconf/bigbluebutton_rails/wiki/How-to:-Integrate-with-CanCan]
102
102
 
103
103
  === Dependencies
104
104
 
@@ -119,7 +119,7 @@ JQuery is used in the views <tt>join_wait</tt> and <tt>invite</tt> and can be co
119
119
 
120
120
  === Overview
121
121
 
122
- bigbluebutton_rails has two entities: servers and rooms. Servers can have multiple rooms, that belong to a server and can also belong to any other model.
122
+ BigbluebuttonRails has two entities: servers and rooms. Servers can have multiple rooms, that belong to a server and can also belong to any other model.
123
123
  You can make a room belong to a user, for example.
124
124
 
125
125
  Every server has an associated API object (using the gem bigbluebutton-api-ruby) used to access the BigBlueButton server.
@@ -130,7 +130,7 @@ These extra actions will be explained bellow.
130
130
 
131
131
  A room model has methods to fetch and send information to the BBB server. They are simple API calls, but the "fetch" methods check the response and store
132
132
  data from it, while the "send" methods just make the API call. You can, for example, use <tt>fetch_meeting_info</tt> to get information about the meeting
133
- (will trigger the API call <tt>getMeetingInfo</tt>). The data parsed from the response wil be stored in the model and can be accessed using it's attributes.
133
+ (will trigger the API call <tt>getMeetingInfo</tt>). The data parsed from the response wil be stored in the model and can be accessed using it's attributes.
134
134
 
135
135
  All methods in the models that trigger any API call are documented with "Triggers API call" and the API functions that are called. Be aware that they
136
136
  can throw a BigBlueButtonException.
@@ -148,9 +148,11 @@ the user. Basic differences:
148
148
 
149
149
  * <tt>invite</tt> renders a view to ask for a user name and a password. It is used to enable <b>anonymous users</b> to join a room or
150
150
  to define the user role using the <b>room password</b> instead of the <tt>bigbluebutton_role</tt> method.
151
- * It first checks <tt>bigbluebutton_role</tt> to see if the current user already has a role in the target room. In case it has, redirects to <tt>join</tt>.
152
- * If there is a user logged, uses <tt>bigbluebutton_user().name</tt> as the user name. Otherwise, ask the user to type a name.
153
- * <tt>join</tt> requires a <b>logged user</b> and uses <tt>bigbluebutton_role</tt> to get the role of this user.
151
+ * It first checks <tt>bigbluebutton_role</tt> to see if the current user already has a role in the target room.
152
+ * In case it has (see {controller_methods.rb}[https://github.com/mconf/bigbluebutton_rails/blob/master/lib/bigbluebutton_rails/controller_methods.rb] for more info), redirects to <tt>join</tt>.
153
+ * Otherwise:
154
+ * If there is a user logged, uses <tt>bigbluebutton_user().name</tt> as the user name. Otherwise, ask the user to type a name.
155
+ * <tt>join</tt> requires a <b>logged user</b> and uses <tt>bigbluebutton_role</tt> to get the role for this user
154
156
  * It redirects the user straight to the meeting if the join is successful.
155
157
  * In case there's no role associated with the current user, falls back to <tt>invite</tt> to ask for a password.
156
158
 
@@ -159,11 +161,11 @@ Internally, they use the same algorithm:
159
161
  * If the user is a moderator:
160
162
  * If the room is not created yet, creates it.
161
163
  * Redirects the user to the meeting as a moderator.
162
- * If the user is a normal attendee:
164
+ * If the user is not a moderator (a normal attendee):
163
165
  * If the meeting is running, redirects the user to the meeting as an attendee.
164
166
  * Otherwise:
165
- * <tt>join</tt> redirects to <tt>join_wait</tt>, to wait for a moderator before joining the conference.
166
- * <tt>invite</tt> renders the invite view again and shows a warning that the metting is not running.
167
+ * <tt>join</tt> redirects to <tt>join_wait</tt>, to wait for a moderator before joining the conference. The page will continuously pool the server to check if the meeting is running. When it starts, it redirects the user to the conference.
168
+ * <tt>invite</tt> renders the invite view again and shows a warning informing that the meeting is not running. The user must re-submit the form to try again.
167
169
 
168
170
  == Development
169
171
 
@@ -26,7 +26,7 @@ class Bigbluebutton::RoomsController < ApplicationController
26
26
  def create
27
27
  @room = BigbluebuttonRoom.new(params[:bigbluebutton_room])
28
28
  @room.server = @server
29
-
29
+
30
30
  # TODO Generate a random meetingid everytime a room is created
31
31
  if !params[:bigbluebutton_room].has_key?(:meetingid) or
32
32
  params[:bigbluebutton_room][:meetingid].blank?
@@ -152,9 +152,9 @@ class Bigbluebutton::RoomsController < ApplicationController
152
152
  @room.fetch_is_running?
153
153
  rescue BigBlueButton::BigBlueButtonException => e
154
154
  flash[:error] = e.to_s
155
- render :json => { running: "false", error: "#{e.to_s}" }
155
+ render :json => { :running => "false", :error => "#{e.to_s}" }
156
156
  else
157
- render :json => { running: "#{@room.is_running?}" }
157
+ render :json => { :running => "#{@room.is_running?}" }
158
158
  end
159
159
 
160
160
  end
@@ -12,6 +12,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
12
12
  validates :welcome_msg, :length => { :maximum => 250 }
13
13
  validates :private, :inclusion => { :in => [true, false] }
14
14
  validates :randomize_meetingid, :inclusion => { :in => [true, false] }
15
+ validates :voice_bridge, :presence => true, :uniqueness => true
15
16
 
16
17
  # Passwords are 16 character strings
17
18
  # See http://groups.google.com/group/bigbluebutton-dev/browse_thread/thread/9be5aae1648bcab?pli=1
@@ -62,7 +63,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
62
63
  response[:attendees].each do |att|
63
64
  attendee = BigbluebuttonAttendee.new
64
65
  attendee.from_hash(att)
65
- @attendees << attendee
66
+ @attendees << attendee
66
67
  end
67
68
 
68
69
  response
@@ -158,6 +159,7 @@ class BigbluebuttonRoom < ActiveRecord::Base
158
159
 
159
160
  def init
160
161
  self[:meetingid] ||= random_meetingid
162
+ self[:voice_bridge] ||= random_voice_bridge
161
163
 
162
164
  # fetched attributes
163
165
  @participant_count = 0
@@ -179,6 +181,16 @@ class BigbluebuttonRoom < ActiveRecord::Base
179
181
  end
180
182
  end
181
183
 
184
+ def random_voice_bridge
185
+ value = (70000 + ActiveSupport::SecureRandom.random_number(9999)).to_s
186
+ count = 0
187
+ while not BigbluebuttonRoom.find_by_voice_bridge(value).nil? and count < 10
188
+ count += 1
189
+ value = (70000 + ActiveSupport::SecureRandom.random_number(9999)).to_s
190
+ end
191
+ value
192
+ end
193
+
182
194
  def do_create_meeting
183
195
  self.server.api.create_meeting(self.name, self.meetingid, self.moderator_password,
184
196
  self.attendee_password, self.welcome_msg, self.dial_number,
@@ -14,6 +14,11 @@ class BigbluebuttonServer < ActiveRecord::Base
14
14
 
15
15
  validates :version, :presence => true, :inclusion => { :in => ['0.64', '0.7'] }
16
16
 
17
+ # Array of <tt>BigbluebuttonMeeting</tt>
18
+ attr_reader :meetings
19
+
20
+ after_initialize :init
21
+
17
22
  # Returns the API object (<tt>BigBlueButton::BigBlueButtonAPI</tt> defined in
18
23
  # <tt>bigbluebutton-api-ruby</tt>) associated with this server.
19
24
  def api
@@ -24,9 +29,6 @@ class BigbluebuttonServer < ActiveRecord::Base
24
29
  @api
25
30
  end
26
31
 
27
- # Array of <tt>BigbluebuttonMeeting</tt>
28
- attr_reader :meetings
29
-
30
32
  # Fetches the meetings currently created in the server (running or not).
31
33
  #
32
34
  # Using the response, updates <tt>meetings</tt> with a list of <tt>BigbluebuttonMeeting</tt>
@@ -41,9 +43,8 @@ class BigbluebuttonServer < ActiveRecord::Base
41
43
  response[:meetings].each do |attr|
42
44
  room = BigbluebuttonRoom.find_by_server_id_and_meetingid(self.id, attr[:meetingID])
43
45
  if room.nil?
44
- room = BigbluebuttonRoom.new(:server => self, :meetingid => attr[:meetingID],
45
- :attendee_password => attr[:attendeePW],
46
- :moderator_password => attr[:moderatorPW])
46
+ room = BigbluebuttonRoom.new(:server => self, :meetingid => attr[:meetingID], :name => attr[:meetingID],
47
+ :attendee_password => attr[:attendeePW], :moderator_password => attr[:moderatorPW])
47
48
  room.running = attr[:running]
48
49
  else
49
50
  room.update_attributes(:attendee_password => attr[:attendeePW],
@@ -55,4 +56,11 @@ class BigbluebuttonServer < ActiveRecord::Base
55
56
  end
56
57
  end
57
58
 
59
+ protected
60
+
61
+ def init
62
+ # fetched attributes
63
+ @meetings = []
64
+ end
65
+
58
66
  end
@@ -4,11 +4,11 @@ require "bigbluebutton_rails/version"
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "bigbluebutton_rails"
6
6
  s.version = BigbluebuttonRails::VERSION.dup
7
- s.platform = Gem::Platform::RUBY
7
+ s.platform = Gem::Platform::RUBY
8
8
  s.summary = "BigBlueButton integration for Ruby on Rails"
9
9
  s.email = "mconf@googlegroups.com"
10
10
  s.homepage = "http://github.com/mconf/bigbluebutton_rails"
11
- s.description = "BigBlueButton integration for Ruby on Rails"
11
+ s.description = "It allows you to interact with a BigBlueButton server from your Ruby on Rails web application"
12
12
  s.authors = ['Leonardo Crauss Daronco']
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
@@ -28,21 +28,14 @@ module ActionDispatch::Routing
28
28
  # running_bigbluebutton_server_room GET /bigbluebutton/servers/:server_id/rooms/:id/running(.:format)
29
29
  # { :action=>"running", :controller=>"bigbluebutton/rooms" }
30
30
  #
31
- # The controllers used will always be bigbluebutton/servers and bigbluebutton/rooms,
32
- # but you can change the url using the scope option:
31
+ # The routes point by default to the controllers Bigbluebutton::ServersController and Bigbluebutton::RoomsController
32
+ # and the the routes are scoped (namespaced) with 'bigbluebutton'. You can change the namespace with:
33
33
  #
34
34
  # bigbluebutton_routes :default, :scope => "webconference"
35
35
  #
36
- # This will generate routes such as:
36
+ # You can also change the controllers with:
37
37
  #
38
- # webconference_server GET /webconference/servers/:id(.:format)
39
- # { :action=>"show", :controller=>"bigbluebutton/servers" }
40
- # POST /webconference/servers/:id(.:format)
41
- # { :action=>"update", :controller=>"bigbluebutton/servers" }
42
- # join_webconference_server_room GET /webconference/servers/:server_id/rooms/:id/join(.:format)
43
- # { :action=>"join", :controller=>"bigbluebutton/rooms" }
44
- # running_webconference_server_room GET /webconference/servers/:server_id/rooms/:id/running(.:format)
45
- # { :action=>"running", :controller=>"bigbluebutton/rooms" }
38
+ # bigbluebutton_routes :default, :controllers { :servers => "custom_servers", :rooms => "custom_rooms" }
46
39
  #
47
40
  # ==== Room matchers
48
41
  #
@@ -81,11 +74,12 @@ module ActionDispatch::Routing
81
74
 
82
75
  def bigbluebutton_routes_default(*params) #:nodoc:
83
76
  options = params.extract_options!
84
- options_scope = options.has_key?(:scope) ? options[:scope] : 'bigbluebutton'
77
+ options_scope = options.has_key?(:scope) ? options[:scope] : BigbluebuttonRails.routing_scope
78
+ BigbluebuttonRails.set_controllers(options[:controllers])
85
79
 
86
80
  scope options_scope, :as => options_scope do
87
- resources :servers, :controller => 'bigbluebutton/servers' do
88
- resources :rooms, :controller => 'bigbluebutton/rooms' do
81
+ resources :servers, :controller => BigbluebuttonRails.controllers[:servers] do
82
+ resources :rooms, :controller => BigbluebuttonRails.controllers[:rooms] do
89
83
  get :join, :on => :member
90
84
  get :running, :on => :member
91
85
  get :end, :on => :member
@@ -98,12 +92,12 @@ module ActionDispatch::Routing
98
92
 
99
93
  def bigbluebutton_routes_room_matchers(*params) #:nodoc:
100
94
  # TODO This is generating helpers like "user_running_room" instead of "running_user_room"
101
- get 'room/:id' => 'bigbluebutton/rooms#show', :as => 'room'
102
- get 'room/:id/join' => 'bigbluebutton/rooms#join', :as => 'join_room'
103
- post 'room/:id/join' => 'bigbluebutton/rooms#auth', :as => 'join_room'
104
- get 'room/:id/running' => 'bigbluebutton/rooms#running', :as => 'running_room'
105
- get 'room/:id/end' => 'bigbluebutton/rooms#end', :as => 'end_room'
106
- get 'room/:id/invite' => 'bigbluebutton/rooms#invite', :as => 'invite_room'
95
+ get 'room/:id' => "#{BigbluebuttonRails.controllers[:rooms]}#show", :as => 'room'
96
+ get 'room/:id/join' => "#{BigbluebuttonRails.controllers[:rooms]}#join", :as => 'join_room'
97
+ post 'room/:id/join' => "#{BigbluebuttonRails.controllers[:rooms]}#auth", :as => 'join_room'
98
+ get 'room/:id/running' => "#{BigbluebuttonRails.controllers[:rooms]}#running", :as => 'running_room'
99
+ get 'room/:id/end' => "#{BigbluebuttonRails.controllers[:rooms]}#end", :as => 'end_room'
100
+ get 'room/:id/invite' => "#{BigbluebuttonRails.controllers[:rooms]}#invite", :as => 'invite_room'
107
101
  end
108
102
 
109
103
  end
@@ -1,3 +1,3 @@
1
1
  module BigbluebuttonRails
2
- VERSION = "0.0.3".freeze
2
+ VERSION = "0.0.4".freeze
3
3
  end
@@ -6,4 +6,17 @@ module BigbluebuttonRails
6
6
  require 'bigbluebutton_rails/rails'
7
7
  require 'bigbluebutton_rails/controller_methods'
8
8
  require 'bigbluebutton_rails/rails/routes'
9
+
10
+ # Default controllers to generate the routes
11
+ mattr_accessor :controllers
12
+ @@controllers = { :servers => 'bigbluebutton/servers', :rooms => 'bigbluebutton/rooms' }
13
+
14
+ # Default scope for routes
15
+ mattr_accessor :routing_scope
16
+ @@routing_scope = 'bigbluebutton'
17
+
18
+ def self.set_controllers(options)
19
+ @@controllers.merge!(options).slice!(:servers, :rooms) unless options.nil?
20
+ end
21
+
9
22
  end
@@ -7,7 +7,7 @@ class BigbluebuttonAttendee
7
7
  def from_hash(hash)
8
8
  self.user_id = hash[:userID].to_s
9
9
  self.full_name = hash[:fullName].to_s
10
- self.role = hash[:role].downcase == "moderator" ? :moderator : :attendee
10
+ self.role = hash[:role].to_s.downcase == "moderator" ? :moderator : :attendee
11
11
  end
12
12
 
13
13
  def ==(other)
@@ -27,6 +27,7 @@ class CreateBigbluebuttonRails < ActiveRecord::Migration
27
27
  end
28
28
  add_index :bigbluebutton_rooms, :server_id
29
29
  add_index :bigbluebutton_rooms, :meetingid, :unique => true
30
+ add_index :bigbluebutton_rooms, :voice_bridge, :unique => true
30
31
  end
31
32
 
32
33
  def self.down
@@ -23,11 +23,12 @@ describe BigbluebuttonRoom do
23
23
  it { should have_db_column(:randomize_meetingid).of_type(:boolean) }
24
24
  it { should have_db_index(:server_id) }
25
25
  it { should have_db_index(:meetingid).unique(true) }
26
- it {
26
+ it { should have_db_index(:voice_bridge).unique(true) }
27
+ it {
27
28
  room = BigbluebuttonRoom.new
28
29
  room.private.should be_false
29
30
  }
30
- it {
31
+ it {
31
32
  room = BigbluebuttonRoom.new
32
33
  room.randomize_meetingid.should be_true
33
34
  }
@@ -44,6 +45,7 @@ describe BigbluebuttonRoom do
44
45
 
45
46
  it { should validate_presence_of(:server_id) }
46
47
  it { should validate_presence_of(:meetingid) }
48
+ it { should validate_presence_of(:voice_bridge) }
47
49
  it { should validate_presence_of(:name) }
48
50
 
49
51
  it { should be_boolean(:private) }
@@ -59,6 +61,7 @@ describe BigbluebuttonRoom do
59
61
 
60
62
  it { should validate_uniqueness_of(:meetingid) }
61
63
  it { should validate_uniqueness_of(:name) }
64
+ it { should validate_uniqueness_of(:voice_bridge) }
62
65
 
63
66
  it {
64
67
  room = Factory.create(:bigbluebutton_room)
@@ -103,11 +106,83 @@ describe BigbluebuttonRoom do
103
106
  room.attendees.should == []
104
107
  end
105
108
 
106
- it "meetingid if it's nil" do
107
- room.meetingid.should_not be_nil
109
+ context "meetingid" do
110
+ it { room.meetingid.should_not be_nil }
111
+ it {
112
+ b = BigbluebuttonRoom.new(:meetingid => "user defined")
113
+ b.meetingid.should == "user defined"
114
+ }
115
+ end
116
+
117
+ context "voice_bridge" do
118
+ it { room.voice_bridge.should_not be_nil }
119
+ it { room.voice_bridge.length.should == 5 }
120
+ it { room.voice_bridge[0].should == '7' }
121
+ it {
122
+ b = BigbluebuttonRoom.new(:voice_bridge => "user defined")
123
+ b.voice_bridge.should == "user defined"
124
+ }
108
125
  end
109
126
  end
110
127
 
128
+
129
+
130
+ =begin
131
+ context "randomizes meetingid" do
132
+ let(:fail_hash) { { :returncode => true, :meetingID => "new id",
133
+ :messageKey => "duplicateWarning" } }
134
+ let(:success_hash) { { :returncode => true, :meetingID => "new id",
135
+ :messageKey => "" } }
136
+ let(:new_id) { "new id" }
137
+ before {
138
+ room.randomize_meetingid = true
139
+ room.server = mocked_server
140
+ }
141
+
142
+ it "before calling create" do
143
+ room.should_receive(:random_meetingid).and_return(new_id)
144
+ mocked_api.should_receive(:create_meeting).
145
+ with(room.name, new_id, room.moderator_password,
146
+ room.attendee_password, room.welcome_msg, room.dial_number,
147
+ room.logout_url, room.max_participants, room.voice_bridge)
148
+ room.send_create
149
+ end
150
+
151
+ it "and tries again on error" do
152
+ # fails twice and them succeds
153
+ room.should_receive(:random_meetingid).exactly(3).times.and_return(new_id)
154
+ mocked_api.should_receive(:create_meeting).
155
+ with(room.name, new_id, room.moderator_password,
156
+ room.attendee_password, room.welcome_msg, room.dial_number,
157
+ room.logout_url, room.max_participants, room.voice_bridge).
158
+ twice.
159
+ and_return(fail_hash)
160
+ mocked_api.should_receive(:create_meeting).
161
+ with(room.name, new_id, room.moderator_password,
162
+ room.attendee_password, room.welcome_msg, room.dial_number,
163
+ room.logout_url, room.max_participants, room.voice_bridge).
164
+ once.
165
+ and_return(success_hash)
166
+ room.send_create
167
+ end
168
+
169
+ it "and limits to 10 tries" do
170
+ room.should_receive(:random_meetingid).exactly(11).times.and_return(new_id)
171
+ mocked_api.should_receive(:create_meeting).
172
+ with(room.name, new_id, room.moderator_password,
173
+ room.attendee_password, room.welcome_msg, room.dial_number,
174
+ room.logout_url, room.max_participants, room.voice_bridge).
175
+ exactly(10).times.
176
+ and_return(fail_hash)
177
+ room.send_create
178
+ end
179
+ end
180
+
181
+ end
182
+ =end
183
+
184
+
185
+
111
186
  context "using the api" do
112
187
  before { mock_server_and_api }
113
188
  let(:room) { Factory.create(:bigbluebutton_room) }
@@ -137,13 +212,13 @@ describe BigbluebuttonRoom do
137
212
  describe "#fetch_meeting_info" do
138
213
 
139
214
  # these hashes should be exactly as returned by bigbluebutton-api-ruby to be sure we are testing it right
140
- let(:hash_info) {
215
+ let(:hash_info) {
141
216
  { :returncode=>true, :meetingID=>"test_id", :attendeePW=>"1234", :moderatorPW=>"4321",
142
217
  :running=>false, :hasBeenForciblyEnded=>false, :startTime=>nil, :endTime=>nil,
143
218
  :participantCount=>0, :moderatorCount=>0, :attendees=>[], :messageKey=>"", :message=>""
144
219
  }
145
220
  }
146
- let(:users) {
221
+ let(:users) {
147
222
  [
148
223
  {:userID=>"ndw1fnaev0rj", :fullName=>"House M.D.", :role=>:moderator},
149
224
  {:userID=>"gn9e22b7ynna", :fullName=>"Dexter Morgan", :role=>:moderator},
@@ -151,7 +226,7 @@ describe BigbluebuttonRoom do
151
226
  {:userID=>"rbepbovolsxt", :fullName=>"Trinity", :role=>:viewer}
152
227
  ]
153
228
  }
154
- let(:hash_info2) {
229
+ let(:hash_info2) {
155
230
  { :returncode=>true, :meetingID=>"test_id", :attendeePW=>"1234", :moderatorPW=>"4321",
156
231
  :running=>true, :hasBeenForciblyEnded=>false, :startTime=>DateTime.parse("Wed Apr 06 17:09:57 UTC 2011"),
157
232
  :endTime=>nil, :participantCount=>4, :moderatorCount=>2,
@@ -214,7 +289,7 @@ describe BigbluebuttonRoom do
214
289
  let(:attendee_password) { Forgery(:basic).password }
215
290
  let(:moderator_password) { Forgery(:basic).password }
216
291
  let(:hash_create) {
217
- {
292
+ {
218
293
  :returncode => "SUCCESS", :meetingID => "test_id",
219
294
  :attendeePW => attendee_password, :moderatorPW => moderator_password,
220
295
  :hasBeenForciblyEnded => "false", :messageKey => {}, :message => {}
@@ -44,8 +44,8 @@ describe BigbluebuttonServer do
44
44
  server = Factory.create(:bigbluebutton_server)
45
45
  Factory.create(:bigbluebutton_room, :server => server)
46
46
  Factory.create(:bigbluebutton_room, :server => server)
47
- expect {
48
- expect {
47
+ expect {
48
+ expect {
49
49
  server.destroy
50
50
  }.to change{ BigbluebuttonServer.count }.by(-1)
51
51
  }.to change{ BigbluebuttonRoom.count }.by(-2)
@@ -90,6 +90,14 @@ describe BigbluebuttonServer do
90
90
  end
91
91
  end
92
92
 
93
+ context "initializes" do
94
+ let(:server) { BigbluebuttonServer.new }
95
+
96
+ it "fetched attributes before they are fetched" do
97
+ server.meetings.should == []
98
+ end
99
+ end
100
+
93
101
  context "fetching info from bbb" do
94
102
  let(:server) { Factory.create(:bigbluebutton_server) }
95
103
  let(:room1) { Factory.create(:bigbluebutton_room, :server => server, :meetingid => "room1") }
@@ -107,7 +115,7 @@ describe BigbluebuttonServer do
107
115
  { :meetingID => "im not in the db", :attendeePW=>"pass", :moderatorPW=>"pass", :hasBeenForciblyEnded => true, :running => true}
108
116
  ]
109
117
  }
110
- let(:hash) {
118
+ let(:hash) {
111
119
  { :returncode => true,
112
120
  :meetings => meetings
113
121
  }
@@ -0,0 +1,8 @@
1
+ class CustomRoomsController < ApplicationController
2
+ def index
3
+ end
4
+
5
+ def show
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class CustomServersController < ApplicationController
2
+ def index
3
+ end
4
+
5
+ def show
6
+ end
7
+
8
+ end
@@ -11,4 +11,7 @@ RailsApp::Application.routes.draw do
11
11
  end
12
12
  end
13
13
 
14
+ # note: controllers modified here will be used in the routes added after this (if any)
15
+ bigbluebutton_routes :default, :scope => "custom", :controllers => { :servers => 'custom_servers', :rooms => 'custom_rooms' }
16
+
14
17
  end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActionController do
4
+ include Shoulda::Matchers::ActionController
5
+
6
+ describe "routing" do
7
+
8
+ # custom controllers - servers
9
+ it {
10
+ {:get => "/custom/servers"}.
11
+ should route_to(:controller => "custom_servers", :action => "index")
12
+ }
13
+ it {
14
+ {:post => "/custom/servers"}.
15
+ should route_to(:controller => "custom_servers", :action => "create")
16
+ }
17
+ it {
18
+ {:get => "/custom/servers/new"}.
19
+ should route_to(:controller => "custom_servers", :action => "new")
20
+ }
21
+ it {
22
+ {:get => "/custom/servers/1/edit"}.
23
+ should route_to(:controller => "custom_servers", :action => "edit", :id => "1")
24
+ }
25
+ it {
26
+ {:get => "/custom/servers/1"}.
27
+ should route_to(:controller => "custom_servers", :action => "show", :id => "1")
28
+ }
29
+ it {
30
+ {:put => "/custom/servers/1"}.
31
+ should route_to(:controller => "custom_servers", :action => "update", :id => "1")
32
+ }
33
+ it {
34
+ {:delete => "/custom/servers/1"}.
35
+ should route_to(:controller => "custom_servers", :action => "destroy", :id => "1")
36
+ }
37
+
38
+ # custom controllers - rooms
39
+ it {
40
+ {:get => "/custom/servers/1/rooms"}.
41
+ should route_to(:controller => "custom_rooms", :action => "index", :server_id => "1")
42
+ }
43
+ it {
44
+ {:get => "/custom/servers/1/rooms/new"}.
45
+ should route_to(:controller => "custom_rooms", :action => "new", :server_id => "1")
46
+ }
47
+ it {
48
+ {:get => "/custom/servers/1/rooms/1/edit"}.
49
+ should route_to(:controller => "custom_rooms", :action => "edit", :server_id => "1", :id => "1")
50
+ }
51
+ it {
52
+ {:get => "/custom/servers/1/rooms/1"}.
53
+ should route_to(:controller => "custom_rooms", :action => "show", :server_id => "1", :id => "1")
54
+ }
55
+ it {
56
+ {:put => "/custom/servers/1/rooms/1"}.
57
+ should route_to(:controller => "custom_rooms", :action => "update", :server_id => "1", :id => "1")
58
+ }
59
+ it {
60
+ {:delete => "/custom/servers/1/rooms/1"}.
61
+ should route_to(:controller => "custom_rooms", :action => "destroy", :server_id => "1", :id => "1")
62
+ }
63
+ it {
64
+ {:get => "/custom/servers/1/rooms/1/join"}.
65
+ should route_to(:controller => "custom_rooms", :action => "join", :server_id => "1", :id => "1")
66
+ }
67
+ it {
68
+ {:get => "/custom/servers/1/rooms/1/running"}.
69
+ should route_to(:controller => "custom_rooms", :action => "running", :server_id => "1", :id => "1")
70
+ }
71
+ it {
72
+ {:get => "/custom/servers/1/rooms/1/end"}.
73
+ should route_to(:controller => "custom_rooms", :action => "end", :server_id => "1", :id => "1")
74
+ }
75
+ it {
76
+ {:get => "/custom/servers/1/rooms/1/invite"}.
77
+ should route_to(:controller => "custom_rooms", :action => "invite", :server_id => "1", :id => "1")
78
+ }
79
+ it {
80
+ {:post => "/custom/servers/1/rooms/1/join"}.
81
+ should route_to(:controller => "custom_rooms", :action => "auth", :server_id => "1", :id => "1")
82
+ }
83
+
84
+ end
85
+
86
+ end
87
+
@@ -4,34 +4,39 @@ describe Bigbluebutton::ServersController do
4
4
  include Shoulda::Matchers::ActionController
5
5
 
6
6
  describe "routing" do
7
- it {
8
- should route(:get, "/bigbluebutton/servers").
9
- to(:action => :index)
10
- }
11
- it {
12
- should route(:post, "/bigbluebutton/servers").
13
- to(:action => :create)
14
- }
15
- it {
16
- should route(:get, "/bigbluebutton/servers/new").
17
- to(:action => :new)
18
- }
19
- it {
20
- should route(:get, "/bigbluebutton/servers/1/edit").
21
- to(:action => :edit, :id => 1)
22
- }
23
- it {
24
- should route(:get, "/bigbluebutton/servers/1").
25
- to(:action => :show, :id => 1)
26
- }
27
- it {
28
- should route(:put, "/bigbluebutton/servers/1").
29
- to(:action => :update, :id => 1)
30
- }
31
- it {
32
- should route(:delete, "/bigbluebutton/servers/1").
33
- to(:action => :destroy, :id => 1)
34
- }
7
+
8
+ # normal and scoped routes
9
+ ['bigbluebutton', 'webconference'].each do |prefix|
10
+ it {
11
+ {:get => "/#{prefix}/servers"}.
12
+ should route_to(:controller => "bigbluebutton/servers", :action => "index")
13
+ }
14
+ it {
15
+ {:post => "/#{prefix}/servers"}.
16
+ should route_to(:controller => "bigbluebutton/servers", :action => "create")
17
+ }
18
+ it {
19
+ {:get => "/#{prefix}/servers/new"}.
20
+ should route_to(:controller => "bigbluebutton/servers", :action => "new")
21
+ }
22
+ it {
23
+ {:get => "/#{prefix}/servers/1/edit"}.
24
+ should route_to(:controller => "bigbluebutton/servers", :action => "edit", :id => "1")
25
+ }
26
+ it {
27
+ {:get => "/#{prefix}/servers/1"}.
28
+ should route_to(:controller => "bigbluebutton/servers", :action => "show", :id => "1")
29
+ }
30
+ it {
31
+ {:put => "/#{prefix}/servers/1"}.
32
+ should route_to(:controller => "bigbluebutton/servers", :action => "update", :id => "1")
33
+ }
34
+ it {
35
+ {:delete => "/#{prefix}/servers/1"}.
36
+ should route_to(:controller => "bigbluebutton/servers", :action => "destroy", :id => "1")
37
+ }
38
+ end
39
+
35
40
  end
36
41
 
37
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bigbluebutton_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-04-28 00:00:00.000000000Z
12
+ date: 2011-05-16 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &73818420 !ruby/object:Gem::Requirement
16
+ requirement: &87438090 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.0.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *73818420
24
+ version_requirements: *87438090
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bigbluebutton-api-ruby
27
- requirement: &73814520 !ruby/object:Gem::Requirement
27
+ requirement: &87437620 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.0.10
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *73814520
35
+ version_requirements: *87437620
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec-rails
38
- requirement: &73814050 !ruby/object:Gem::Requirement
38
+ requirement: &87437220 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.5.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *73814050
46
+ version_requirements: *87437220
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: factory_girl
49
- requirement: &73813560 !ruby/object:Gem::Requirement
49
+ requirement: &87436820 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.3.2
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *73813560
57
+ version_requirements: *87436820
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sqlite3-ruby
60
- requirement: &73813050 !ruby/object:Gem::Requirement
60
+ requirement: &87436290 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.3.3
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *73813050
68
+ version_requirements: *87436290
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: generator_spec
71
- requirement: &73812640 !ruby/object:Gem::Requirement
71
+ requirement: &87435880 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.8.2
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *73812640
79
+ version_requirements: *87435880
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: shoulda-matchers
82
- requirement: &73812110 !ruby/object:Gem::Requirement
82
+ requirement: &87435530 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 1.0.0.beta
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *73812110
90
+ version_requirements: *87435530
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: forgery
93
- requirement: &73811720 !ruby/object:Gem::Requirement
93
+ requirement: &87435160 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,8 +98,9 @@ dependencies:
98
98
  version: 0.3.7
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *73811720
102
- description: BigBlueButton integration for Ruby on Rails
101
+ version_requirements: *87435160
102
+ description: It allows you to interact with a BigBlueButton server from your Ruby
103
+ on Rails web application
103
104
  email: mconf@googlegroups.com
104
105
  executables: []
105
106
  extensions: []
@@ -157,6 +158,8 @@ files:
157
158
  - spec/rails_app/.gitignore
158
159
  - spec/rails_app/Rakefile
159
160
  - spec/rails_app/app/controllers/application_controller.rb
161
+ - spec/rails_app/app/controllers/custom_rooms_controller.rb
162
+ - spec/rails_app/app/controllers/custom_servers_controller.rb
160
163
  - spec/rails_app/app/controllers/space_controller.rb
161
164
  - spec/rails_app/app/controllers/user_controller.rb
162
165
  - spec/rails_app/app/helpers/application_helper.rb
@@ -199,6 +202,7 @@ files:
199
202
  - spec/rails_app/public/stylesheets/scaffold.css
200
203
  - spec/rails_app/script/rails
201
204
  - spec/rails_app/vendor/plugins/.gitkeep
205
+ - spec/routing/bigbluebutton/custom_controllers_routing_spec.rb
202
206
  - spec/routing/bigbluebutton/rooms_routing_spec.rb
203
207
  - spec/routing/bigbluebutton/servers_routing_spec.rb
204
208
  - spec/spec_helper.rb
@@ -219,7 +223,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
219
223
  version: '0'
220
224
  segments:
221
225
  - 0
222
- hash: 1022773263
226
+ hash: 986260833
223
227
  required_rubygems_version: !ruby/object:Gem::Requirement
224
228
  none: false
225
229
  requirements:
@@ -228,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
232
  version: '0'
229
233
  segments:
230
234
  - 0
231
- hash: 1022773263
235
+ hash: 986260833
232
236
  requirements: []
233
237
  rubyforge_project:
234
238
  rubygems_version: 1.7.2