Skip to content

Commit

Permalink
Adding json responses in rooms_controller. Refs issue 143.
Browse files Browse the repository at this point in the history
  • Loading branch information
daronco committed Jun 6, 2011
1 parent 8d64e8a commit cfd5bb4
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 9 deletions.
50 changes: 42 additions & 8 deletions app/controllers/bigbluebutton/rooms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Bigbluebutton::RoomsController < ApplicationController

before_filter :find_server
respond_to :html, :except => :running
respond_to :json, :only => :running
respond_to :json, :only => [:running, :show, :new, :index, :create, :update, :end, :destroy]

def index
# TODO restrict to rooms belonging to the selected server
Expand Down Expand Up @@ -35,11 +35,12 @@ def create

respond_with @room do |format|
if @room.save
message = t('bigbluebutton_rails.rooms.notice.create.success')
format.html {
message = t('bigbluebutton_rails.rooms.notice.create.success')
params[:redir_url] ||= bigbluebutton_server_room_path(@server, @room)
redirect_to params[:redir_url], :notice => message
}
format.json { render :json => @room, :status => :created }
else
format.html {
unless params[:redir_url].blank?
Expand All @@ -49,6 +50,7 @@ def create
render :action => "new"
end
}
format.json { render :json => @room.errors, :status => :unprocessable_entity }
end
end
end
Expand All @@ -68,6 +70,7 @@ def update
params[:redir_url] ||= bigbluebutton_server_room_path(@server, @room)
redirect_to params[:redir_url], :notice => message
}
format.json { head :ok }
else
format.html {
unless params[:redir_url].blank?
Expand All @@ -77,6 +80,7 @@ def update
render :action => "edit"
end
}
format.json { render :json => @room.errors, :status => :unprocessable_entity }
end
end
end
Expand All @@ -86,17 +90,30 @@ def destroy

# TODO Destroy the room record even if end_meeting failed?

error = false
begin
@room.fetch_is_running?
@room.send_end if @room.is_running?
rescue BigBlueButton::BigBlueButtonException => e
flash[:error] = e.to_s
error = true
message = e.to_s
# TODO Better error message: "Room destroyed in DB, but not in BBB..."
end

@room.destroy
params[:redir_url] ||= bigbluebutton_server_rooms_url
redirect_to params[:redir_url]

respond_with do |format|
format.html {
flash[:error] = message if error
params[:redir_url] ||= bigbluebutton_server_rooms_url
redirect_to params[:redir_url]
}
if error
format.json { render :json => message, :status => :error }
else
format.json { head :ok }
end
end
end

# Used to join public rooms with a logged user.
Expand Down Expand Up @@ -161,19 +178,36 @@ def running
def end
@room = BigbluebuttonRoom.find(params[:id])

error = false
begin
@room.fetch_is_running?
if @room.is_running?
@room.send_end
message = t('bigbluebutton_rails.rooms.notice.end.success')
else
error = true
message = t('bigbluebutton_rails.rooms.notice.end.not_running')
end
rescue BigBlueButton::BigBlueButtonException => e
flash[:error] = e.to_s
redirect_to request.referer
error = true
message = e.to_s
end

if error
respond_with do |format|
format.html {
flash[:error] = message
redirect_to request.referer
}
format.json { render :json => message, :status => :error }
end
else
redirect_to(bigbluebutton_server_room_path(@server, @room), :notice => message)
respond_with do |format|
format.html {
redirect_to(bigbluebutton_server_room_path(@server, @room), :notice => message)
}
format.json { head :ok }
end
end

end
Expand Down
152 changes: 151 additions & 1 deletion spec/controllers/bigbluebutton/rooms_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def build_running_json(value, error=nil)

describe "#update" do
let(:new_room) { Factory.build(:bigbluebutton_room) }
before { @room = room }
before { @room = room } # need this to trigger let(:room) and actually create the room

context "on success" do
before :each do
Expand Down Expand Up @@ -381,6 +381,7 @@ def build_running_json(value, error=nil)
context "room is not running" do
before { mocked_api.should_receive(:is_meeting_running?).and_return(false) }
before(:each) { get :end, :server_id => mocked_server.to_param, :id => room.to_param }
it { should respond_with(:redirect) }
it { should set_the_flash.to(I18n.t('bigbluebutton_rails.rooms.notice.end.not_running')) }
end
end
Expand Down Expand Up @@ -567,6 +568,7 @@ def build_running_json(value, error=nil)
it { should assign_to(:server).with(server) }
end

# make sure that the exceptions thrown by bigbluebutton-api-ruby are treated by the controller
context "exception handling" do
let(:bbb_error_msg) { "err msg" }
let(:bbb_error) { BigBlueButton::BigBlueButtonException.new(bbb_error_msg) }
Expand Down Expand Up @@ -673,5 +675,153 @@ def build_running_json(value, error=nil)

end # exception handling

# verify all JSON responses
context "json responses for " do
describe "#show" do
before(:each) { get :show, :server_id => server.to_param, :id => room.to_param, :format => 'json' }
it { should respond_with(:success) }
it { should respond_with_content_type(:json) }
it { response.body.should == room.to_json }
end

describe "#new" do
before(:each) { get :new, :server_id => server.to_param, :format => 'json' }
it { should respond_with(:success) }
it { should respond_with_content_type(:json) }
it {
# we ignore all values bc a BigbluebuttonRoom is generated with some
# random values (meetingid, voice_bridge)
should respond_with_json(BigbluebuttonRoom.new.to_json).ignoring_values
}
end

describe "#index" do
before do
@room1 = Factory.create(:bigbluebutton_room, :server => server)
@room2 = Factory.create(:bigbluebutton_room, :server => server)
end
before(:each) { get :index, :server_id => server.to_param, :format => 'json' }
it { should respond_with(:success) }
it { should respond_with_content_type(:json) }
it { should respond_with_json([@room1, @room2].to_json) }
end

describe "#create" do
let(:new_room) { Factory.build(:bigbluebutton_room, :server => server) }

context "on success" do
before(:each) {
post :create, :server_id => server.to_param, :bigbluebutton_room => new_room.attributes, :format => 'json'
}
it { should respond_with(:created) }
it { should respond_with_content_type(:json) }
it { should respond_with_json(new_room.to_json).ignoring_attributes }
end

context "on failure" do
before(:each) {
new_room.name = nil # invalid
post :create, :server_id => server.to_param, :bigbluebutton_room => new_room.attributes, :format => 'json'
}
it { should respond_with(:unprocessable_entity) }
it { should respond_with_content_type(:json) }
it {
new_room.save # should fail
should respond_with_json(new_room.errors.to_json)
}
end
end

describe "#update" do
let(:new_room) { Factory.build(:bigbluebutton_room) }
before { @room = room }

context "on success" do
before(:each) {
put :update, :server_id => server.to_param, :id => @room.to_param, :bigbluebutton_room => new_room.attributes, :format => 'json'
}
it { should respond_with(:success) }
it { should respond_with_content_type(:json) }
end

context "on failure" do
before(:each) {
new_room.name = nil # invalid
put :update, :server_id => server.to_param, :id => @room.to_param, :bigbluebutton_room => new_room.attributes, :format => 'json'
}
it { should respond_with(:unprocessable_entity) }
it { should respond_with_content_type(:json) }
it {
new_room.save # should fail
should respond_with_json(new_room.errors.to_json)
}
end
end

describe "#end" do
before { mock_server_and_api }

context "room is running" do
before {
mocked_api.should_receive(:is_meeting_running?).and_return(true)
mocked_api.should_receive(:end_meeting).with(room.meetingid, room.moderator_password)
}
before(:each) { get :end, :server_id => mocked_server.to_param, :id => room.to_param, :format => 'json' }
it { should respond_with(:success) }
it { should respond_with_content_type(:json) }
end

context "room is not running" do
before { mocked_api.should_receive(:is_meeting_running?).and_return(false) }
before(:each) { get :end, :server_id => mocked_server.to_param, :id => room.to_param, :format => 'json' }
it { should respond_with(:error) }
it { should respond_with_content_type(:json) }
it { should respond_with_json(I18n.t('bigbluebutton_rails.rooms.notice.end.not_running')) }
end

context "throwing an exception" do
let(:msg) { "any error message" }
before {
mocked_api.should_receive(:is_meeting_running?).and_return{ raise BigBlueButton::BigBlueButtonException.new(msg) }
}
before(:each) { get :end, :server_id => mocked_server.to_param, :id => room.to_param, :format => 'json' }
it { should respond_with(:error) }
it { should respond_with_content_type(:json) }
it { should respond_with_json(msg) }
end

end

describe "#destroy" do
before { mock_server_and_api }

context "on success" do
before {
mocked_api.should_receive(:is_meeting_running?).and_return(true)
mocked_api.should_receive(:end_meeting)
}
before(:each) {
delete :destroy, :server_id => mocked_server.to_param, :id => room.to_param, :format => 'json'
}
it { should respond_with(:success) }
it { should respond_with_content_type(:json) }
end

context "throwing error" do
let(:msg) { "any error message" }
before {
mocked_api.should_receive(:is_meeting_running?).and_return{ raise BigBlueButton::BigBlueButtonException.new(msg) }
}
before(:each) {
delete :destroy, :server_id => mocked_server.to_param, :id => room.to_param, :format => 'json'
}
it { should respond_with(:error) }
it { should respond_with_content_type(:json) }
it { should respond_with_json(msg) }
end
end

end # json responses

end

67 changes: 67 additions & 0 deletions spec/support/matchers/shoulda/respond_with_json_matcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
module Shoulda # :nodoc:
module Matchers
module ActionController # :nodoc:

# Ensures a controller responded with the expected json.
def respond_with_json(status)
RespondWithJsonMatcher.new(status)
end

class RespondWithJsonMatcher # :nodoc:

def initialize(expected_json)
@no_values = false
@ignored = []
@expected = expected_json
end

def ignoring_attributes(ignored = ['id', 'updated_at', 'created_at'])
@ignored = ignored
self
end

def ignoring_values()
@no_values = true
self
end

def matches?(controller)
@actual = controller.response.body

# remove the selected attributes
@ignored.each do |attr|
@actual.gsub!(/.#{attr}.:[^{,]*[,]+/, "")
@expected.gsub!(/.#{attr}.:[^{,]*[,]+/, "")
end
# remove the values of all attributes
if @no_values
@actual.gsub!(/:[^{,]*/, "")
@expected.gsub!(/:[^{,]*/, "")
end

@actual == @expected
end

def failure_message
s = "Expected the following json strings to be equal: \n"
s += "Expected: " + @expected.inspect + "\n"
s += " Got: " + @actual.inspect
s
end

def negative_failure_message
s = "Expected the following json strings to be different: \n"
s += "Expected: " + @expected.inspect + "\n"
s += " Got: " + @actual.inspect
s
end

def description
"respond with a defined json string"
end

end

end
end
end

0 comments on commit cfd5bb4

Please sign in to comment.