Skip to content
Snippets Groups Projects
Commit af7ab5a9 authored by Khemissi Amir's avatar Khemissi Amir Committed by GitHub
Browse files

Backend: Added the room session start feature. (#3355)

parent fc9eb430
No related branches found
No related tags found
No related merge requests found
......@@ -35,9 +35,12 @@ RSpec/FilePath:
RSpec/MessageSpies:
Enabled: false
# Enable having lines with up to 130 charachters in length.
RSpec/MultipleMemoizedHelpers:
Enabled: false
# Enable having lines with up to 150 charachters in length.
Layout/LineLength:
Max: 130
Max: 150
# Avoid methods longer than 10 lines of code.
Metrics/MethodLength:
......
......@@ -4,7 +4,7 @@ module Api
module V1
class RoomsController < ApplicationController
skip_before_action :verify_authenticity_token # TODO: amir - Revisit this.
before_action :find_room, only: :show
before_action :find_room, only: %i[show start]
# GET /api/v1/rooms.json
# Returns: { data: Array[serializable objects(rooms)] , errors: Array[String] }
......@@ -20,6 +20,30 @@ module Api
render_json data: @room, status: :ok
end
# POST /api/v1/rooms/:friendly_id/start.json
# Returns: { data: Array[serializable objects] , errors: Array[String] }
# Does: Starts the Room meeting and joins in the meeting starter.
def start
# TODO: amir - Check the legitimately of the action.
bbb_api = BigBlueButtonApi.new
meeting_starter = current_user ? "user(id):#{current_user.id}" : 'unauthenticated user'
options = { logoutURL: request.headers['Referer'] || root_url }
retries = 0
begin
logger.info "Starting meeting for room(friendly_id):#{@room.friendly_id} by #{meeting_starter}."
join_url = bbb_api.start_meeting room: @room, meeting_starter: current_user, options: options
logger.info "meeting successfully started for room(friendly_id):#{@room.friendly_id} by #{meeting_starter}."
render_json data: { join_url: }, status: :created
rescue BigBlueButton::BigBlueButtonException => e
retries += 1
logger.info "Retrying meeting start for room(friendly_id):#{@room.friendly_id} because of error(key): #{e.key} #{retries} times..."
retry unless retries >= 3
raise e
end
end
private
def find_room
......
......@@ -12,6 +12,19 @@ class BigBlueButtonApi
@bbb_server ||= BigBlueButton::BigBlueButtonApi.new(bbb_endpoint, bbb_secret, '1.8')
end
# Start a meeting for a specific room and returns the join URL.
def start_meeting(room:, meeting_starter:, options: {})
# TODO: amir - Revisit this.
create_options = default_create_opts.merge(options)
join_options = { join_via_html5: true } # TODO: amir - Revisit this (createTime,...).
user_name = meeting_starter&.name || 'Someone'
password = (meeting_starter && create_options[:moderatorPW]) || create_options[:attendeePW]
bbb_server.create_meeting room.name, room.friendly_id, create_options
bbb_server.join_meeting_url room.friendly_id, user_name, password, join_options
end
private
def bbb_endpoint
......@@ -21,4 +34,20 @@ class BigBlueButtonApi
def bbb_secret
ENV.fetch 'BIGBLUEBUTTON_SECRET', '8cd8ef52e8e101574e400365b55e11a6'
end
def default_create_opts
{
# TODO: amir - revisit this.
record: true,
logoutURL: 'http://localhost',
moderatorPW: 'mp',
attendeePW: 'ap',
moderatorOnlyMessage: 'Welcome Moderator',
muteOnStart: false,
guestPolicy: 'ALWAYS_ACCEPT',
'meta_gl-v3-listed': 'public',
'meta_bbb-origin-version': 3,
'meta_bbb-origin': 'Greenlight'
}
end
end
......@@ -12,7 +12,9 @@ Rails.application.routes.draw do
end
end
resources :users, only: [:create]
resources :rooms, only: %i[show index], param: :friendly_id
resources :rooms, only: %i[show index], param: :friendly_id do
post '/start', to: 'rooms#start', as: :start_meeting, on: :member
end
end
end
match '*path', to: 'components#index', via: :all # Enable CSR for full fledged http requests.
......
......@@ -42,4 +42,26 @@ RSpec.describe Api::V1::RoomsController, type: :controller do
expect(JSON.parse(response.body)['data']).to be_empty
end
end
describe '#start_meeting' do
let(:join_url) { 'https://test.com/bigbluebutton/api?join' }
let(:bbb_service) { instance_double(BigBlueButtonApi) }
before do
allow(BigBlueButtonApi).to receive(:new).and_return(bbb_service)
allow(bbb_service).to receive(:start_meeting).and_return(join_url)
end
it 'returns the join_url for existent room' do
room = create(:room, user:)
post :start, params: { friendly_id: room.friendly_id }
expect(response).to have_http_status(:created)
expect(JSON.parse(response.body)['data']['join_url']).to eq(join_url)
end
it 'returns not_found if the room doesn\'t exist' do
post :start, params: { friendly_id: 'invalid_friendly_id' }
expect(response).to have_http_status(:not_found)
end
end
end
......@@ -5,6 +5,18 @@ require 'bigbluebutton_api'
describe BigBlueButtonApi, type: :service do
let(:bbb_service) { described_class.new }
let(:default_create_opts) do
{
moderatorPW: 'mp',
attendeePW: 'ap'
}
end
let(:default_join_opts) do
{
join_via_html5: true
}
end
before do
ENV['BIGBLUEBUTTON_ENDPOINT'] = 'http://test.com/bigbluebutton/api'
......@@ -26,4 +38,35 @@ describe BigBlueButtonApi, type: :service do
expect(bbb_api).to eq(bbb_api2).and eq(bbb_api3)
end
end
describe 'Room meeting creation' do
let(:bbb_server) { instance_double(BigBlueButton::BigBlueButtonApi) }
let(:room) { create(:room) }
let(:meeting_starter) { room.user }
before do
allow(bbb_service).to receive(:default_create_opts).and_return(default_create_opts)
allow(BigBlueButton::BigBlueButtonApi).to receive(:new).and_return(bbb_server)
allow(bbb_server).to receive(:create_meeting).and_return(true)
allow(bbb_server).to receive(:join_meeting_url).and_return(true)
end
it 'calls bbb_api#create_meeting' do
expect(bbb_server).to receive(:create_meeting).with(room.name, room.friendly_id, default_create_opts)
bbb_service.start_meeting room:, meeting_starter: nil, options: {}
end
describe 'calls bbb_api#join_meeting_url' do
it 'With Moderator password and the meeting starter name for authenticated requests' do
expect(bbb_server).to receive(:join_meeting_url).with(room.friendly_id, meeting_starter.name, default_create_opts[:moderatorPW],
default_join_opts)
bbb_service.start_meeting room:, meeting_starter:, options: {}
end
it 'With attendee password and user name as "Someone" for unauthenticated requests' do
expect(bbb_server).to receive(:join_meeting_url).with(room.friendly_id, 'Someone', default_create_opts[:attendeePW], default_join_opts)
bbb_service.start_meeting room:, meeting_starter: nil, options: {}
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment