Skip to content
Snippets Groups Projects
Unverified Commit 941c22df authored by Ahmad Farhat's avatar Ahmad Farhat Committed by GitHub
Browse files

Added a new optional (default enabled) room config (#4629)

* Added a new optional (default enabled) room config

* Replace default with default_enabled

* rspec

* missed a few:
parent daf9ace5
No related branches found
No related tags found
No related merge requests found
Showing
with 132 additions and 56 deletions
......@@ -270,8 +270,9 @@
},
"room_configuration": {
"room_configuration": "Room Configuration",
"optional": "Optional",
"enabled": "Enabled",
"default": "Optional (default: enabled)",
"optional": "Optional (default: disabled)",
"enabled": "Force Enabled",
"disabled": "Disabled",
"configurations": {
"allow_room_to_be_recorded": "Allow Room to be recorded",
......
......@@ -236,11 +236,8 @@ input.search-bar {
// Custom Select component.
.select{
.dropdown-item.active, .dropdown-item:active {
background-color: var(--brand-color) !important;
}
.dropdown-item.active:hover {
color: $black !important;
background-color: var(--brand-color-light) !important;
color: var(--brand-color) !important;
}
}
......@@ -381,6 +378,29 @@ input.search-bar {
}
}
.setting-select {
button {
background: white !important;
color: black !important;
border-color: gainsboro !important;
min-width: 260px;
text-align: left;
&:hover, &:focus, &:active {
background: white !important;
color: black !important;
border-color: gainsboro !important;
}
&:focus {
box-shadow: 0 0 0 0.25rem var(--brand-color-light) !important;
}
}
.dropdown-menu {
min-width: 260px;
}
}
input[type='text']:focus {
border-color: whitesmoke !important;
box-shadow: 0 0 0 2px var(--brand-color-light) !important;
......
......@@ -48,7 +48,7 @@ module Api
def create_meeting_options(provider:)
RoomsConfiguration.create! [
{ meeting_option: MeetingOption.find_by(name: 'record'), value: 'optional', provider: },
{ meeting_option: MeetingOption.find_by(name: 'record'), value: 'default_enabled', provider: },
{ meeting_option: MeetingOption.find_by(name: 'muteOnStart'), value: 'optional', provider: },
{ meeting_option: MeetingOption.find_by(name: 'guestPolicy'), value: 'optional', provider: },
{ meeting_option: MeetingOption.find_by(name: 'glAnyoneCanStart'), value: 'optional', provider: },
......
......@@ -19,7 +19,7 @@ module Api
end
# PATCH /api/v1/room_settings/:friendly_id
# Updates a room's settings if the room config is set to optional
# Updates a room's settings if the room config is set to optional or default
def update
name = room_setting_params[:settingName]
value = room_setting_params[:settingValue].to_s
......@@ -31,7 +31,10 @@ module Api
is_access_code = %w[glViewerAccessCode glModeratorAccessCode].include? name
return render_error status: :forbidden unless config_value == 'optional' || (config_value == 'true' && is_access_code && value != 'false')
# Only allow the settings to update if the room config is default or optional / if it is an access_code regeneration
unless %w[optional default_enabled].include?(config_value) || (config_value == 'true' && is_access_code && value != 'false')
return render_error status: :forbidden
end
value = infer_access_code(value:) if is_access_code # Handling access code update.
......
......@@ -88,7 +88,7 @@ export default function EditRoleForm({ role }) {
defaultValue={rolePermissions?.ManageUsers === 'true'}
updateMutation={updateRolePermission}
/>
{(roomConfigs?.data?.record === 'optional') && (
{['optional', 'default_enabled'].includes(roomConfigs?.data?.record) && (
<RolePermissionRow
permissionName="CanRecord"
description="Allow users with this role to record their meetings"
......
......@@ -17,15 +17,18 @@ export default function RoomConfigRow({
title={title}
description={subtitle}
>
<Dropdown.Item value="true" onClick={() => useUpdateRoom.mutate({ value: 'true' })}>
{t('admin.room_configuration.enabled')}
</Dropdown.Item>
<Dropdown.Item value="default" onClick={() => useUpdateRoom.mutate({ value: 'default_enabled' })}>
{t('admin.room_configuration.default')}
</Dropdown.Item>
<Dropdown.Item value="optional" onClick={() => useUpdateRoom.mutate({ value: 'optional' })}>
{t('admin.room_configuration.optional')}
</Dropdown.Item>
<Dropdown.Item value="false" onClick={() => useUpdateRoom.mutate({ value: 'false' })}>
{t('admin.room_configuration.disabled')}
</Dropdown.Item>
<Dropdown.Item value="true" onClick={() => useUpdateRoom.mutate({ value: 'true' })}>
{t('admin.room_configuration.enabled')}
</Dropdown.Item>
</SettingSelect>
);
}
......
......@@ -23,7 +23,7 @@ export default function AccessCodeRow({
return null;
}
const deleteButton = config === 'optional' ? (
const deleteButton = ['optional', 'default_enabled'].includes(config) ? (
<Button
variant="icon"
onClick={handleDeleteCode}
......
......@@ -19,7 +19,7 @@ export default function RoomSettings() {
const currentUser = useAuth();
const { friendlyId } = useParams();
const roomSetting = useRoomSettings(friendlyId);
const roomsConfigs = useRoomConfigs();
const { data: roomConfigs } = useRoomConfigs();
const updateMutationWrapper = () => useUpdateRoomSetting(friendlyId);
const deleteMutationWrapper = (args) => useDeleteRoom({ friendlyId, ...args });
......@@ -35,14 +35,14 @@ export default function RoomSettings() {
settingName="glViewerAccessCode"
updateMutation={updateMutationWrapper}
code={roomSetting?.data?.glViewerAccessCode}
config={roomsConfigs?.data?.glViewerAccessCode}
config={roomConfigs?.glViewerAccessCode}
description={t('room.settings.generate_viewers_access_code')}
/>
<AccessCodeRow
settingName="glModeratorAccessCode"
updateMutation={updateMutationWrapper}
code={roomSetting?.data?.glModeratorAccessCode}
config={roomsConfigs?.data?.glModeratorAccessCode}
config={roomConfigs?.glModeratorAccessCode}
description={t('room.settings.generate_mods_access_code')}
/>
</Col>
......@@ -53,7 +53,7 @@ export default function RoomSettings() {
settingName="record"
updateMutation={updateMutationWrapper}
value={roomSetting?.data?.record}
config={roomsConfigs?.data?.record}
config={roomConfigs?.record}
description={t('room.settings.allow_room_to_be_recorded')}
/>
)}
......@@ -61,35 +61,35 @@ export default function RoomSettings() {
settingName="glRequireAuthentication"
updateMutation={updateMutationWrapper}
value={roomSetting?.data?.glRequireAuthentication}
config={roomsConfigs?.data?.glRequireAuthentication}
config={roomConfigs?.glRequireAuthentication}
description={t('room.settings.require_signed_in')}
/>
<RoomSettingsRow
settingName="guestPolicy"
updateMutation={updateMutationWrapper}
value={roomSetting?.data?.guestPolicy}
config={roomsConfigs?.data?.guestPolicy}
config={roomConfigs?.guestPolicy}
description={t('room.settings.require_mod_approval')}
/>
<RoomSettingsRow
settingName="glAnyoneCanStart"
updateMutation={updateMutationWrapper}
value={roomSetting?.data?.glAnyoneCanStart}
config={roomsConfigs?.data?.glAnyoneCanStart}
config={roomConfigs?.glAnyoneCanStart}
description={t('room.settings.allow_any_user_to_start')}
/>
<RoomSettingsRow
settingName="glAnyoneJoinAsModerator"
updateMutation={updateMutationWrapper}
value={roomSetting?.data?.glAnyoneJoinAsModerator}
config={roomsConfigs?.data?.glAnyoneJoinAsModerator}
config={roomConfigs?.glAnyoneJoinAsModerator}
description={t('room.settings.all_users_join_as_mods')}
/>
<RoomSettingsRow
settingName="muteOnStart"
updateMutation={updateMutationWrapper}
value={roomSetting?.data?.muteOnStart}
config={roomsConfigs?.data?.muteOnStart}
config={roomConfigs?.muteOnStart}
description={t('room.settings.mute_users_on_join')}
/>
<div className="float-end mt-3">
......
......@@ -24,4 +24,14 @@ class MeetingOption < ApplicationRecord
.pluck(:name, :value)
.to_h
end
def true_value
if name.ends_with? 'AccessCode'
SecureRandom.alphanumeric(6).downcase
elsif name == 'guestPolicy'
'ASK_MODERATOR'
else
'true'
end
end
end
......@@ -47,11 +47,14 @@ class Room < ApplicationRecord
# Autocreate all meeting options using the default values
def create_meeting_options
configs = MeetingOption.get_config_value(name: %w[glViewerAccessCode glModeratorAccessCode], provider: user.provider)
configs = configs.select { |_k, v| v == 'true' }
configs = RoomsConfiguration.joins(:meeting_option).where(provider: user.provider).pluck(:name, :value).to_h
MeetingOption.all.find_each do |option|
value = configs.key?(option.name) ? SecureRandom.alphanumeric(6).downcase : option.default_value
value = if %w[true default_enabled].include? configs[option.name]
option.true_value
else
option.default_value
end
RoomMeetingOption.create(room: self, meeting_option: option, value:)
end
end
......
......@@ -3,8 +3,8 @@
class RoomsConfiguration < ApplicationRecord
belongs_to :meeting_option
validates :provider, presence: true
# 'option': Optional config, 'true': Force enabled, 'false': Disabled.
validates :value, inclusion: { in: %w[optional true false] }
# 'option': 'default_enabled': Optional but defaulted to true, 'optional' Optional but defaulted to false, 'true': Force enabled, 'false': Disabled.
validates :value, inclusion: { in: %w[default_enabled optional true false] }
validates :meeting_option_id, uniqueness: { scope: :provider }
delegate :name, to: :meeting_option
......
......@@ -18,7 +18,7 @@ class RoomSettingsGetter
# Fetching only rooms configs that are not optional to overwrite the settings values.
@rooms_configs = MeetingOption.joins(:rooms_configurations)
.where(rooms_configurations: { provider: })
.where.not(rooms_configurations: { value: 'optional' })
.where.not(rooms_configurations: { value: %w[optional default_enabled] })
.pluck(:name, :value)
.to_h
end
......
# frozen_string_literal: true
class UpdateRecordRoomsConfigurationDefault < ActiveRecord::Migration[7.0]
def up
RoomsConfiguration.find_by(meeting_option: MeetingOption.find_by(name: 'record'), provider: 'greenlight').update(value: 'default_enabled')
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
DataMigrate::Data.define(version: 20221116010619)
DataMigrate::Data.define(version: 20230123174546)
......@@ -57,6 +57,18 @@ RSpec.describe Api::V1::RoomSettingsController, type: :controller do
expect(room.room_meeting_options.take.value).to eq('notOptionalAnymore')
end
it 'uses MeetingOption::get_config_value and updates the setting if its config is "default_enabled"' do
expect(MeetingOption).to receive(:get_config_value).with(name: 'setting', provider: 'greenlight').and_call_original
meeting_option = create(:meeting_option, name: 'setting')
create(:rooms_configuration, meeting_option:, value: 'default_enabled')
create(:room_meeting_option, room:, meeting_option:)
put :update, params: { room_setting: { settingName: 'setting', settingValue: 'notOptionalAnymore' }, friendly_id: room.friendly_id }
expect(response).to have_http_status(:ok)
expect(room.room_meeting_options.take.value).to eq('notOptionalAnymore')
end
context 'Access codes' do
it 'uses MeetingOption::get_config_value and generates a code if it\'s not disabled and the value is "true"' do
random_access_code_name = %w[glViewerAccessCode glModeratorAccessCode].sample
......
......@@ -4,6 +4,6 @@ FactoryBot.define do
factory :rooms_configuration do
meeting_option
provider { 'greenlight' }
value { %w[true false optional].sample }
value { %w[true false optional default_enabled].sample }
end
end
......@@ -74,13 +74,10 @@ RSpec.describe Room, type: :model do
describe 'create_meeting_options' do
let!(:viewer_access_code) { create(:meeting_option, name: 'glViewerAccessCode', default_value: '') }
let!(:moderator_access_code) { create(:meeting_option, name: 'glModeratorAccessCode', default_value: '') }
before do
create_list(:meeting_option, 3)
end
let!(:meeting_options) { create_list(:meeting_option, 4) }
it 'creates a RoomMeetingOption for each MeetingOption' do
expect { create(:room) }.to change(RoomMeetingOption, :count).from(0).to(5)
expect { create(:room) }.to change(RoomMeetingOption, :count).from(0).to(6)
end
it 'does not generate an access code if the room config is not enabled' do
......@@ -88,6 +85,21 @@ RSpec.describe Room, type: :model do
expect(RoomMeetingOption.find_by(meeting_option: viewer_access_code).value).to eql('')
end
context 'room configs' do
it 'sets the meeting option settings correctly based on the room configs' do
create(:rooms_configuration, meeting_option: meeting_options[0], value: 'true')
create(:rooms_configuration, meeting_option: meeting_options[1], value: 'false')
create(:rooms_configuration, meeting_option: meeting_options[2], value: 'optional')
create(:rooms_configuration, meeting_option: meeting_options[3], value: 'default_enabled')
create(:room)
expect(RoomMeetingOption.find_by(meeting_option: meeting_options[0]).value).to eq('true')
expect(RoomMeetingOption.find_by(meeting_option: meeting_options[1]).value).to eq(meeting_options[1].default_value)
expect(RoomMeetingOption.find_by(meeting_option: meeting_options[2]).value).to eq(meeting_options[2].default_value)
expect(RoomMeetingOption.find_by(meeting_option: meeting_options[3]).value).to eq('true')
end
context 'when access code room config is enabled' do
before do
create(:rooms_configuration, provider: 'greenlight', value: 'true', meeting_option: viewer_access_code)
......@@ -118,6 +130,7 @@ RSpec.describe Room, type: :model do
end
end
end
end
context 'instance methods' do
describe '#get_setting' do
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment