diff --git a/app/views/shared/_header.html.erb b/app/views/shared/_header.html.erb
index 5fc1ed08..33961a66 100755
--- a/app/views/shared/_header.html.erb
+++ b/app/views/shared/_header.html.erb
@@ -31,7 +31,9 @@
<% end %>
- <% if current_user.role.get_permission("can_create_rooms") && !current_user.has_role?(:super_admin) %>
+ <% recording = room_configuration("Room Configuration Recording") %>
+ <% if current_user.role.get_permission("can_create_rooms") && !current_user.has_role?(:super_admin) &&
+ recording != "disabled" %>
<% all_rec_page = params[:controller] == "users" && params[:action] == "recordings" ? "active" : "" %>
<%= link_to get_user_recordings_path(current_user), class: "px-3 mx-1 mt-1 header-nav #{all_rec_page}" do %>
diff --git a/app/views/shared/components/_public_recording_row.html.erb b/app/views/shared/components/_public_recording_row.html.erb
index 9848cc0d..c450eb1f 100644
--- a/app/views/shared/components/_public_recording_row.html.erb
+++ b/app/views/shared/components/_public_recording_row.html.erb
@@ -16,13 +16,14 @@
-
- <% if recording[:metadata][:name] %>
+ <% if recording[:metadata][:name] %>
+
<%= recording[:metadata][:name] %>
- <% else %>
+ <% else %>
+
<%= recording[:name] %>
- <% end %>
-
+ <% end %>
+
<%= t("recording.recorded_on", date: recording_date(recording[:startTime])) %>
diff --git a/app/views/shared/components/_recording_row.html.erb b/app/views/shared/components/_recording_row.html.erb
index 17d1dd5f..695e46b1 100644
--- a/app/views/shared/components/_recording_row.html.erb
+++ b/app/views/shared/components/_recording_row.html.erb
@@ -16,13 +16,14 @@
-
- <% if recording[:metadata][:name] %>
+ <% if recording[:metadata][:name] %>
+
<%= recording[:metadata][:name] %>
- <% else %>
+ <% else %>
+
<%= recording[:name] %>
- <% end %>
-
+ <% end %>
+
diff --git a/app/views/shared/components/_subtitle.html.erb b/app/views/shared/components/_subtitle.html.erb
index 01699cc3..43acd90a 100644
--- a/app/views/shared/components/_subtitle.html.erb
+++ b/app/views/shared/components/_subtitle.html.erb
@@ -16,18 +16,10 @@
<% if search %>
- <%= subtitle %>
+ <%= title(subtitle) %>
- <% if admin_invite_registration %>
-
- <%= link_to "#inviteModal", :class => "btn btn-primary", "data-toggle": "modal" do %>
- <%= t("administrator.users.invite") %>
- <% end %>
-
- <% end %>
-
..." value="<%= @search %>">
@@ -46,7 +38,7 @@
<% else %>
- <%= subtitle %>
+ <%= title(subtitle) %>
<% end %>
diff --git a/app/views/shared/modals/_create_room_modal.html.erb b/app/views/shared/modals/_create_room_modal.html.erb
index 2534d5b8..255ff574 100644
--- a/app/views/shared/modals/_create_room_modal.html.erb
+++ b/app/views/shared/modals/_create_room_modal.html.erb
@@ -69,7 +69,6 @@
<% end %>
-
<% moderator = room_configuration("Room Configuration All Join Moderator") %>
<% if moderator != "disabled" %>
<% end %>
-
+ <% recording = room_configuration("Room Configuration Recording") %>
+ <% if recording_consent_required? && recording != "disabled" %>
+
+ <% end %>
<%= button_to "/", method: :delete, id: "remove-shared-confirm", class: "btn btn-danger my-1 btn-del-room" do %>
- <%= hidden_field_tag :user_id, current_user.id %>
<%= t("modal.remove_shared.delete") %>
<% end %>
diff --git a/config/application.rb b/config/application.rb
index c8ab2e0d..8fe4db4d 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -52,7 +52,7 @@ module Greenlight
# Use standalone BigBlueButton server.
config.bigbluebutton_endpoint = if ENV["BIGBLUEBUTTON_ENDPOINT"].present?
- ENV["BIGBLUEBUTTON_ENDPOINT"]
+ ENV["BIGBLUEBUTTON_ENDPOINT"]
else
config.bigbluebutton_endpoint_default
end
@@ -128,6 +128,9 @@ module Greenlight
config.report_issue_url = ENV["REPORT_ISSUE_URL"]
config.help_url = ENV["HELP_URL"].nil? ? "https://docs.bigbluebutton.org/greenlight/gl-overview.html" : ENV["HELP_URL"]
+ # File types allowed in preupload presentation
+ config.allowed_file_types = ".doc,.docx,.pptx,.pdf"
+
# DEFAULTS
# Default branding image if the user does not specify one
@@ -157,6 +160,12 @@ module Greenlight
# Allow users to share rooms by default
config.shared_access_default = "true"
+ # Don't require recording consent by default
+ config.require_consent_default = "false"
+
+ # Don't allow users to preupload presentations by default
+ config.preupload_presentation_default = "false"
+
# Default admin password
config.admin_password_default = ENV['ADMIN_PASSWORD'] || 'administrator'
end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 771a6c69..99771b60 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -61,7 +61,13 @@ Rails.application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Store uploaded files on the local file system (see config/storage.yml for options)
- config.active_storage.service = :local
+ config.active_storage.service = if ENV["AWS_ACCESS_KEY_ID"].present?
+ :amazon
+ elsif ENV["GCS_PRIVATE_KEY_ID"].present?
+ :google
+ else
+ :local
+ end
# Mount Action Cable outside main process or domain
# config.action_cable.mount_path = nil
diff --git a/config/locales/en.yml b/config/locales/en.yml
index a7531e33..daf29b19 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -36,7 +36,7 @@ en:
enabled: Enabled
info: Only allow authenticated users to join a room
title: Require Authentication for Rooms
- user-info: You must sign in to Greenlight to join this room
+ user-info: You must sign in above to join this room.
branding:
change: Change Image
info: Change the branding image that appears in the top left corner
@@ -45,9 +45,9 @@ en:
invalid: Invalid URL
legal:
change: Change URL
- info: Change the Legal Link that appears in the bottom of the page
- placeholder: Legal URL...
- title: Legal
+ info: Change the Terms Link that appears in the bottom of the page
+ placeholder: Terms URL...
+ title: Terms
invalid: Invalid URL
privpolicy:
change: Change URL
@@ -82,6 +82,18 @@ en:
info: Set the default recording visbility for new recordings
title: Recording Default Visibility
warning: This setting will only be applied to rooms that aren't running
+ require_consent:
+ info: This setting enables a room setting that allows room owners to specify which rooms can be recorded. Users joining a recorded room must consent before joining.
+ title: Require Room Owner and Joiner Consent to Recording
+ maintenance_banner:
+ info: Displays a Banner to inform the user of a scheduled maintenance
+ title: Maintenance Banner
+ display: Set
+ clear: Clear
+ time: "Example: Update scheduled on December 13 @ 23:00 ET. Users may experience problems signing in."
+ preupload:
+ info: Users can preupload a presentation to be used as the default presentation for that specific room
+ title: Allow Users to Preupload Presentations
registration:
info: Change the way that users register to the website
title: Registration Method
@@ -96,6 +108,10 @@ en:
info: Setting to disabled will remove the button from the Room options dropdown, preventing users from sharing rooms
title: Allow Users to Share Rooms
subtitle: Customize Greenlight
+ tabs:
+ appearance: Appearance
+ administration: Administration
+ settings: Settings
title: Site Settings
flash:
approved: User has been successfully approved.
@@ -106,7 +122,7 @@ en:
demoted: User has been successfully demoted
invite: Invite successfully sent to %{email}
invite_email_verification: Emails must be enabled in order to use this method. Please contact your system administrator.
- merge_fail: There was an issue merging the user accounts. Please check the users selected and try again
+ merge_fail: There was an issue merging the user accounts. Please check the users selected and try again
merge_success: User accounts merged successfully
perm_deleted: User has been permanently deleted
promoted: User has been successfully promoted
@@ -136,7 +152,7 @@ en:
edit_site_settings: Allow users with this role to edit site settings
edit_roles: Allow users with this role to edit other roles
manage_users: Allow users with this role to manage users
- invalid_assignment: There was a problem assigning the roles to the user. Please check the values and try again
+ invalid_assignment: There was a problem assigning the roles to the user. Please check the values and try again
colour:
title: Role Colour
info: Set the colour that will be associated with the role
@@ -150,6 +166,8 @@ en:
info: Allows any user to start the meeting at any time. By default, only the room owner can start the meeting.
all_moderator:
info: Gives all users moderator privileges in BigBlueButton when they join the meeting.
+ recordings:
+ info: Allows room owners to specify whether they want the option to record a room or not. If enabled, the moderator must still click the "Record" button once the meeting has started.
options:
disabled: Disabled
enabled: Always Enabled
@@ -261,7 +279,7 @@ en:
designs: Custom Designs
authentication: User Authentication
footer:
- legal: Legal
+ legal: Terms
privpolicy: Privacy Policy
powered_by: Powered by %{href}.
forgot_password:
@@ -393,6 +411,14 @@ en:
or: or
with: Sign in with %{provider}
forgot_password: Forgot Password?
+ preupload:
+ change: Replace Presentation
+ choose: Choose a file (%{type})
+ current: "Current Presentation:"
+ footer: Depending on the size of the presentation, it may require additional time to upload before it can be used.
+ invalid: Invalid size/file type. Please see the restrictions below.
+ title: Add Presentation
+ use: Use Presentation
rename_recording:
remove_shared:
title: Are you sure you want to remove this room from your room list?
@@ -407,6 +433,7 @@ en:
require_approval: Require moderator approval before joining
start: Allow any user to start this meeting
footer_text: Adjustment to your room can be done at anytime.
+ recording: Allow room to be recorded
rename_room:
name_placeholder: Enter a new room name...
share_access:
@@ -474,7 +501,7 @@ en:
fail: Your account has not been approved yet. If multiples days have passed since you signed up, please contact your administrator.
signup: Your account was successfully created. It has been sent to an administrator for approval.
banned:
- fail: You do not have access to this application. If you believe this is a mistake, please contact your administrator.
+ fail: You do not have access to this application. If you believe this is a mistake, please contact your administrator.
deprecated:
new_signin: Select a new login method for you account. All your rooms from your old account will be migrated to the new account
twitter_signin: Signing in via Twitter has been deprecated and will be removed in the next release. Click here to move your account to a new authentication method
@@ -501,6 +528,7 @@ en:
user: User
room:
access_code_required: Please enter a valid access code to join the room
+ add_presentation: Add Presentation
create_room: Create a Room
create_room_error: There was an error creating the room
create_room_success: Room created successfully
@@ -510,7 +538,9 @@ en:
fail: Failed to delete room (%{error})
enter_the_access_code: Enter the room's access code
invalid_provider: You have entered an invalid url. Please check the url and try again.
+ invitation_description: You have been invited to join %{name} using BigBlueButton. To join, click the link above and enter your name.
invited: You have been invited to join
+ recording_present: The session is going to be recorded. This may include voice and video from your side.
invite_participants: Invite Participants
join: Join
last_session: Last session on %{session}
@@ -527,6 +557,10 @@ en:
recent_rooms: Go To a Recently Joined Room
title: Join a Room
no_sessions: This room has no sessions, yet!
+ preupload_success: Successfully added presentation
+ preupload_error: There was an error updating the room presentation
+ preupload_remove_success: Successfully removed presentation
+ preupload_remove_error: There was an error removing the room presentation
recordings: Room Recordings
room_limit: You have reached the maximum number of rooms allowed
room_limit_exceeded: You have exceeded the number of rooms allowed. Please delete %{difference} room(s) to access this room.
diff --git a/config/routes.rb b/config/routes.rb
index 5290b9f6..8082da57 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -122,6 +122,9 @@ Rails.application.routes.draw do
patch '/', to: 'rooms#update', as: :update_room
get '/room_settings', to: 'rooms#room_settings'
post '/update_settings', to: 'rooms#update_settings'
+ get '/current_presentation', to: 'rooms#current_presentation'
+ post '/preupload_presentation', to: 'rooms#preupload_presentation'
+ post '/remove_presentation', to: 'rooms#remove_presentation'
post '/update_shared_access', to: 'rooms#shared_access', as: :room_shared_access
delete '/remove_shared_access', to: 'rooms#remove_shared_access', as: :room_remove_shared_access
get '/shared_users', to: 'rooms#shared_users', as: :room_shared_users
diff --git a/config/storage.yml b/config/storage.yml
index d32f76e8..1c872b81 100644
--- a/config/storage.yml
+++ b/config/storage.yml
@@ -7,19 +7,29 @@ local:
root: <%= Rails.root.join("storage") %>
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
-# amazon:
-# service: S3
-# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
-# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
-# region: us-east-1
-# bucket: your_own_bucket
+amazon:
+ service: S3
+ access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
+ secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
+ region: <%= ENV['AWS_REGION'] %>
+ bucket: <%= ENV['AWS_BUCKET'] %>
# Remember not to checkin your GCS keyfile to a repository
-# google:
-# service: GCS
-# project: your_project
-# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
-# bucket: your_own_bucket
+google:
+ service: GCS
+ project: "<%= ENV['GCS_PROJECT'] %>"
+ bucket: "<%= ENV['GCS_BUCKET'] %>"
+ credentials:
+ type: 'service_account'
+ project_id: "<%= ENV['GCS_PROJECT_ID'] %>"
+ private_key_id: "<%= ENV['GCS_PRIVATE_KEY_ID'] %>"
+ private_key: "<%= ENV['GCS_PRIVATE_KEY']&.lines&.join("\\n") %>"
+ client_email: "<%= ENV['GCS_CLIENT_EMAIL'] %>"
+ client_id: "<%= ENV['GCS_CLIENT_ID'] %>"
+ auth_uri: 'https://accounts.google.com/o/oauth2/auth'
+ token_uri: 'https://accounts.google.com/o/oauth2/token'
+ auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs'
+ client_x509_cert_url: "<%= ENV['GCS_CLIENT_CERT'] %>"
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
# microsoft:
diff --git a/db/migrate/20200615190507_create_active_storage_tables.active_storage.rb b/db/migrate/20200615190507_create_active_storage_tables.active_storage.rb
new file mode 100644
index 00000000..8a54e20f
--- /dev/null
+++ b/db/migrate/20200615190507_create_active_storage_tables.active_storage.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+# This migration comes from active_storage (originally 20170806125915)
+class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
+ def change
+ create_table :active_storage_blobs do |t|
+ t.string :key, null: false
+ t.string :filename, null: false
+ t.string :content_type
+ t.text :metadata
+ t.bigint :byte_size, null: false
+ t.string :checksum, null: false
+ t.datetime :created_at, null: false
+
+ t.index [:key], unique: true
+ end
+
+ create_table :active_storage_attachments do |t|
+ t.string :name, null: false
+ t.references :record, null: false, polymorphic: true, index: false
+ t.references :blob, null: false
+
+ t.datetime :created_at, null: false
+
+ t.index [:record_type, :record_id, :name, :blob_id], name: "index_active_storage_attachments_uniqueness", unique: true
+ t.foreign_key :active_storage_blobs, column: :blob_id
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 89cc2aae..13d6c35d 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,28 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2020_04_13_150518) do
+ActiveRecord::Schema.define(version: 2020_06_15_190507) do
+
+ create_table "active_storage_attachments", force: :cascade do |t|
+ t.string "name", null: false
+ t.string "record_type", null: false
+ t.integer "record_id", null: false
+ t.integer "blob_id", null: false
+ t.datetime "created_at", null: false
+ t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
+ t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
+ end
+
+ create_table "active_storage_blobs", force: :cascade do |t|
+ t.string "key", null: false
+ t.string "filename", null: false
+ t.string "content_type"
+ t.text "metadata"
+ t.bigint "byte_size", null: false
+ t.string "checksum", null: false
+ t.datetime "created_at", null: false
+ t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
+ end
create_table "features", force: :cascade do |t|
t.integer "setting_id"
diff --git a/docker-compose.yml b/docker-compose.yml
index 63d97a0b..d334c9ee 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,6 +17,7 @@ services:
# tag: $LOG_TAG
volumes:
- ./log:/usr/src/app/log
+ - ./storage:/usr/src/app/storage
# When using sqlite3 as the database
# - ./db/production:/usr/src/app/db/production
# When using postgresql as the database
diff --git a/greenlight.nginx b/greenlight.nginx
index b3d5f904..fb0b90f0 100644
--- a/greenlight.nginx
+++ b/greenlight.nginx
@@ -24,3 +24,10 @@ location /b/cable {
client_body_timeout 6h;
send_timeout 6h;
}
+
+# Only needed if using presentations and deployed at a relative root (ex "/b")
+# If deploying at "/", delete the section below
+
+location /rails/active_storage {
+ return 301 /b$request_uri;
+}
\ No newline at end of file
diff --git a/lib/assets/_primary_themes.scss b/lib/assets/_primary_themes.scss
index e493602b..76e7fe9f 100644
--- a/lib/assets/_primary_themes.scss
+++ b/lib/assets/_primary_themes.scss
@@ -80,6 +80,20 @@ a {
}
}
+.nav-tabs .nav-link{
+ &.active {
+ border-color: $primary-color !important;
+ }
+
+ &:not(.active){
+ color: #9aa0ac !important;
+ &:hover:not(.disabled) {
+ border-color: $primary-color;
+ color: $primary-color !important;
+ }
+ }
+}
+
.dropdown-item {
color: #6e7687 !important;
&:hover {
diff --git a/lib/tasks/room.rake b/lib/tasks/room.rake
index 72c2007a..7deec6a9 100644
--- a/lib/tasks/room.rake
+++ b/lib/tasks/room.rake
@@ -33,4 +33,18 @@ namespace :room do
end
end
end
+
+ task four: :environment do
+ Room.all.each do |room|
+ next if room.uid.split("-").length > 3
+
+ begin
+ new_uid = room.uid + "-" + SecureRandom.alphanumeric(3).downcase
+ puts "Updating #{room.uid} to #{new_uid}"
+ room.update_attributes(uid: new_uid)
+ rescue => e
+ puts "Failed to update #{room.uid} to #{new_uid} - #{e}"
+ end
+ end
+ end
end
diff --git a/lib/tasks/user.rake b/lib/tasks/user.rake
index 57abe064..21b8ecea 100644
--- a/lib/tasks/user.rake
+++ b/lib/tasks/user.rake
@@ -47,7 +47,7 @@ namespace :user do
user.set_role(u[:role])
- puts "Account succesfully created."
+ puts "Account successfully created."
puts "Email: #{u[:email]}"
puts "Password: #{u[:password]}"
puts "Role: #{u[:role]}"
diff --git a/sample.env b/sample.env
index 6b3d67a8..0a0c50e5 100644
--- a/sample.env
+++ b/sample.env
@@ -156,7 +156,8 @@ RELATIVE_URL_ROOT=/b
# require-moderator-approval: Require moderators to approve new users before they can join the room
# anyone-can-start: Allows anyone with the join url to start the room in BigBlueButton
# all-join-moderator: All users join as moderators in BigBlueButton
-ROOM_FEATURES=mute-on-join,require-moderator-approval,anyone-can-start,all-join-moderator
+# recording: Sessions are recorded
+ROOM_FEATURES=mute-on-join,require-moderator-approval,anyone-can-start,all-join-moderator,recording
# Specify the maximum number of records to be sent to the BigBlueButton API in one call
# Default is set to 25 records
@@ -258,3 +259,24 @@ DB_PASSWORD=password
# invite - For invite only registration
# approval - For approve/decline registration
DEFAULT_REGISTRATION=open
+
+# Preupload Presentation Storage
+#
+# By default, if Preupload Presentation is enabled for rooms, presentations are uploaded locally to ~/greenlight/storage
+# If you prefer to use AWS S3 or GCS Storage, you can set the variables below
+#
+# For AWS S3:
+# AWS_ACCESS_KEY_ID=
+# AWS_SECRET_ACCESS_KEY=
+# AWS_REGION=
+# AWS_BUCKET=
+#
+# For GCS Storage:
+# GCS_PROJECT_ID=
+# GCS_PRIVATE_KEY_ID=
+# GCS_PRIVATE_KEY=
+# GCS_CLIENT_EMAIL=
+# GCS_CLIENT_ID=
+# GCS_CLIENT_CERT=
+# GCS_PROJECT=
+# GCS_BUCKET=
\ No newline at end of file
diff --git a/scripts/image_build.sh b/scripts/image_build.sh
index 4794c2d2..47566a43 100755
--- a/scripts/image_build.sh
+++ b/scripts/image_build.sh
@@ -50,7 +50,7 @@ if [ -z $CD_REF_NAME ]; then
export CD_REF_NAME=$(git branch | grep \* | cut -d ' ' -f2)
fi
-if [ "$CD_REF_NAME" != "master" ] && [[ "$CD_REF_NAME" != *"release"* ]] && ( [ -z "$CD_BUILD_ALL" ] || [ "$CD_BUILD_ALL" != "true" ] ); then
+if [ "$CD_REF_NAME" != "master" ] && [[ "$CD_REF_NAME" != *"release"* ]] && [[ "$CD_REF_NAME" != *"alpha"* ]] && ( [ -z "$CD_BUILD_ALL" ] || [ "$CD_BUILD_ALL" != "true" ] ); then
echo "#### Docker image for $CD_REF_SLUG:$CD_REF_NAME won't be built"
exit 0
fi
diff --git a/spec/controllers/admins_controller_spec.rb b/spec/controllers/admins_controller_spec.rb
index bace5761..a172ea89 100644
--- a/spec/controllers/admins_controller_spec.rb
+++ b/spec/controllers/admins_controller_spec.rb
@@ -290,12 +290,12 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id
fake_image_url = "example.com"
- post :update_settings, params: { setting: "Branding Image", value: fake_image_url }
+ post :update_settings, params: { setting: "Branding Image", value: fake_image_url, tab: "appearance" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
expect(feature[:value]).to eq(fake_image_url)
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "appearance"))
end
end
@@ -307,12 +307,12 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id
fake_url = "example.com"
- post :update_settings, params: { setting: "Legal URL", value: fake_url }
+ post :update_settings, params: { setting: "Legal URL", value: fake_url, tab: "administration" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Legal URL")
expect(feature[:value]).to eq(fake_url)
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "administration"))
end
end
@@ -324,12 +324,12 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id
fake_url = "example.com"
- post :update_settings, params: { setting: "Privacy Policy URL", value: fake_url }
+ post :update_settings, params: { setting: "Privacy Policy URL", value: fake_url, tab: "administration" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Privacy Policy URL")
expect(feature[:value]).to eq(fake_url)
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "administration"))
end
end
@@ -346,7 +346,7 @@ describe AdminsController, type: :controller do
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
expect(feature[:value]).to eq(primary_color)
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "appearance"))
end
it "changes the primary-lighten on the page" do
@@ -356,12 +356,12 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color
- post :update_settings, params: { setting: "Primary Color Lighten", value: primary_color }
+ post :update_settings, params: { setting: "Primary Color Lighten", value: primary_color, tab: "appearance" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
expect(feature[:value]).to eq(primary_color)
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "appearance"))
end
it "changes the primary-darken on the page" do
@@ -371,12 +371,12 @@ describe AdminsController, type: :controller do
@request.session[:user_id] = @admin.id
primary_color = Faker::Color.hex_color
- post :update_settings, params: { setting: "Primary Color Darken", value: primary_color }
+ post :update_settings, params: { setting: "Primary Color Darken", value: primary_color, tab: "appearance" }
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
expect(feature[:value]).to eq(primary_color)
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "appearance"))
end
end
end
@@ -396,7 +396,7 @@ describe AdminsController, type: :controller do
expect(feature[:value]).to eq(Rails.configuration.registration_methods[:invite])
expect(flash[:success]).to be_present
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "settings"))
end
it "does not allow the user to change to invite if emails are off" do
@@ -409,7 +409,7 @@ describe AdminsController, type: :controller do
post :registration_method, params: { value: "invite" }
expect(flash[:alert]).to be_present
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "settings"))
end
end
@@ -425,7 +425,7 @@ describe AdminsController, type: :controller do
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
expect(feature[:value]).to eq("true")
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "settings"))
end
end
@@ -441,7 +441,7 @@ describe AdminsController, type: :controller do
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
expect(feature[:value]).to eq("5")
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "settings"))
end
end
@@ -457,7 +457,25 @@ describe AdminsController, type: :controller do
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Default Recording Visibility")
expect(feature[:value]).to eq("public")
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "settings"))
+ end
+ end
+
+ context "POST #maintenance_banner" do
+ it "displays a banner with the maintenance string" do
+ allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
+ allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
+
+ @request.session[:user_id] = @admin.id
+ fake_banner_string = "Maintenance work at 2 pm"
+
+ post :update_settings, params: { setting: "Maintenance Banner", value: fake_banner_string, tab: "administration" }
+
+ feature = Setting.find_by(provider: "provider1").features.find_by(name: "Maintenance Banner")
+
+ expect(flash[:success]).to be_present
+ expect(feature[:value]).to eq(fake_banner_string)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "administration"))
end
end
@@ -473,7 +491,7 @@ describe AdminsController, type: :controller do
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Shared Access")
expect(feature[:value]).to eq("false")
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "settings"))
end
end
@@ -537,7 +555,7 @@ describe AdminsController, type: :controller do
feature = Setting.find_by(provider: "provider1").features.find_by(name: "Shared Access")
expect(feature[:value]).to eq("false")
- expect(response).to redirect_to(admin_site_settings_path)
+ expect(response).to redirect_to(admin_site_settings_path(tab: "settings"))
end
it "doesn't allow a user with the incorrect permission to edit site settings" do
diff --git a/spec/controllers/rooms_controller_spec.rb b/spec/controllers/rooms_controller_spec.rb
index 38134af5..59b661ee 100644
--- a/spec/controllers/rooms_controller_spec.rb
+++ b/spec/controllers/rooms_controller_spec.rb
@@ -185,7 +185,7 @@ describe RoomsController, type: :controller do
room_params = { name: name, "mute_on_join": "1",
"require_moderator_approval": "1", "anyone_can_start": "1", "all_join_moderator": "1" }
json_room_settings = "{\"muteOnStart\":true,\"requireModeratorApproval\":true," \
- "\"anyoneCanStart\":true,\"joinModerator\":true}"
+ "\"anyoneCanStart\":true,\"joinModerator\":true,\"recording\":false}"
post :create, params: { room: room_params }
@@ -202,8 +202,10 @@ describe RoomsController, type: :controller do
@owner.main_room.update_attribute(:room_settings, { "muteOnStart": true, "requireModeratorApproval": true,
"anyoneCanStart": true, "joinModerator": true }.to_json)
- json_room_settings = "{\"muteOnStart\":true,\"requireModeratorApproval\":true," \
- "\"anyoneCanStart\":true,\"joinModerator\":true}"
+ json_room_settings = { "anyoneCanStart" => true,
+ "joinModerator" => true,
+ "muteOnStart" => true,
+ "requireModeratorApproval" => true }
get :room_settings, params: { room_uid: @owner.main_room }, format: :json
@@ -571,7 +573,7 @@ describe RoomsController, type: :controller do
it "properly updates room name through the room settings modal and redirects to current page" do
@request.session[:user_id] = @user.id
- name = Faker::Games::Pokemon.name
+ name = Faker::Name.first_name
room_params = { room_uid: @secondary_room.uid, room: { "name": name } }
@@ -583,9 +585,9 @@ describe RoomsController, type: :controller do
it "properly updates room settings through the room settings modal and redirects to current page" do
@request.session[:user_id] = @user.id
- room_params = { "mute_on_join": "1", "name": @secondary_room.name }
+ room_params = { "mute_on_join": "1", "name": @secondary_room.name, "recording": "1" }
formatted_room_params = "{\"muteOnStart\":true,\"requireModeratorApproval\":false," \
- "\"anyoneCanStart\":false,\"joinModerator\":false}" # JSON string format
+ "\"anyoneCanStart\":false,\"joinModerator\":false,\"recording\":true}" # JSON string format
expect { post :update_settings, params: { room_uid: @secondary_room.uid, room: room_params } }
.to change { @secondary_room.reload.room_settings }
@@ -608,7 +610,7 @@ describe RoomsController, type: :controller do
room_params = { "mute_on_join": "1", "name": @secondary_room.name }
formatted_room_params = "{\"muteOnStart\":true,\"requireModeratorApproval\":false," \
- "\"anyoneCanStart\":false,\"joinModerator\":false}" # JSON string format
+ "\"anyoneCanStart\":false,\"joinModerator\":false,\"recording\":false}" # JSON string format
expect { post :update_settings, params: { room_uid: @secondary_room.uid, room: room_params } }
.to change { @secondary_room.reload.room_settings }
@@ -814,4 +816,107 @@ describe RoomsController, type: :controller do
expect(response).to redirect_to root_path
end
end
+
+ describe "POST #preupload_presentation" do
+ before do
+ @user = create(:user)
+ @file = fixture_file_upload('files/sample.pdf', 'application/pdf')
+ @invalid_file = fixture_file_upload('files/invalid.jpg', 'image/jpg')
+ allow(Rails.configuration).to receive(:preupload_presentation_default).and_return("true")
+ end
+
+ it "adds a presentation to the room" do
+ @request.session[:user_id] = @user.id
+
+ post :preupload_presentation, params: { room_uid: @user.main_room, room: { presentation: @file } }
+
+ expect(@user.main_room.presentation.attached?).to be true
+ expect(flash[:success]).to be_present
+ expect(response).to redirect_to @user.main_room
+ end
+
+ it "rejects file types that are not allowed" do
+ @request.session[:user_id] = @user.id
+
+ post :preupload_presentation, params: { room_uid: @user.main_room, room: { presentation: @invalid_file } }
+
+ expect(@user.main_room.presentation.attached?).to be false
+ expect(flash[:alert]).to be_present
+ expect(response).to redirect_to @user.main_room
+ end
+
+ it "allows admins to add a presentation to the room" do
+ allow_any_instance_of(User).to receive(:admin_of?).and_return(true)
+ @admin = create(:user)
+ @admin.set_role :admin
+ @request.session[:user_id] = @admin.id
+
+ post :preupload_presentation, params: { room_uid: @user.main_room, room: { presentation: @file } }
+
+ expect(@user.main_room.presentation.attached?).to be true
+ expect(flash[:success]).to be_present
+ expect(response).to redirect_to @user.main_room
+ end
+
+ it "redirects to root path if not admin of current user" do
+ allow_any_instance_of(User).to receive(:admin_of?).and_return(false)
+ @admin = create(:user)
+ @admin.set_role :admin
+ @request.session[:user_id] = @admin.id
+
+ post :preupload_presentation, params: { room_uid: @user.main_room, room: { presentation: @file } }
+
+ expect(response).to redirect_to(root_path)
+ end
+ end
+
+ describe "POST #remove_presentation" do
+ before do
+ @user = create(:user)
+ @user.main_room.presentation.attach(fixture_file_upload('files/sample.pdf', 'application/pdf'))
+ allow(Rails.configuration).to receive(:shared_access_default).and_return("true")
+ end
+
+ it "removes a presentation from a room" do
+ @request.session[:user_id] = @user.id
+
+ expect(@user.main_room.presentation.attached?).to be true
+
+ post :remove_presentation, params: { room_uid: @user.main_room }
+
+ @user.main_room.reload
+
+ expect(@user.main_room.presentation.attached?).to be false
+ expect(flash[:success]).to be_present
+ expect(response).to redirect_to @user.main_room
+ end
+
+ it "allows admins to remove a presentation from a room" do
+ allow_any_instance_of(User).to receive(:admin_of?).and_return(true)
+ @admin = create(:user)
+ @admin.set_role :admin
+ @request.session[:user_id] = @admin.id
+
+ expect(@user.main_room.presentation.attached?).to be true
+
+ post :remove_presentation, params: { room_uid: @user.main_room }
+
+ @user.main_room.reload
+
+ expect(@user.main_room.presentation.attached?).to be false
+ expect(flash[:success]).to be_present
+ expect(response).to redirect_to @user.main_room
+ end
+
+ it "redirects to root path if not admin of current user" do
+ allow_any_instance_of(User).to receive(:admin_of?).and_return(false)
+ @admin = create(:user)
+ @admin.set_role :admin
+ @request.session[:user_id] = @admin.id
+
+ post :preupload_presentation, params: { room_uid: @user.main_room, room: { presentation: @file } }
+
+ expect(response).to redirect_to(root_path)
+ end
+ end
end
diff --git a/spec/fixtures/files/invalid.jpg b/spec/fixtures/files/invalid.jpg
new file mode 100644
index 00000000..1db39e04
Binary files /dev/null and b/spec/fixtures/files/invalid.jpg differ
diff --git a/spec/fixtures/files/sample.pdf b/spec/fixtures/files/sample.pdf
new file mode 100644
index 00000000..dbf091df
--- /dev/null
+++ b/spec/fixtures/files/sample.pdf
@@ -0,0 +1,198 @@
+%PDF-1.3
+%âãÏÓ
+
+1 0 obj
+<<
+/Type /Catalog
+/Outlines 2 0 R
+/Pages 3 0 R
+>>
+endobj
+
+2 0 obj
+<<
+/Type /Outlines
+/Count 0
+>>
+endobj
+
+3 0 obj
+<<
+/Type /Pages
+/Count 2
+/Kids [ 4 0 R 6 0 R ]
+>>
+endobj
+
+4 0 obj
+<<
+/Type /Page
+/Parent 3 0 R
+/Resources <<
+/Font <<
+/F1 9 0 R
+>>
+/ProcSet 8 0 R
+>>
+/MediaBox [0 0 612.0000 792.0000]
+/Contents 5 0 R
+>>
+endobj
+
+5 0 obj
+<< /Length 1074 >>
+stream
+2 J
+BT
+0 0 0 rg
+/F1 0027 Tf
+57.3750 722.2800 Td
+( A Simple PDF File ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 688.6080 Td
+( This is a small demonstration .pdf file - ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 664.7040 Td
+( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 652.7520 Td
+( text. And more text. And more text. And more text. ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 628.8480 Td
+( And more text. And more text. And more text. And more text. And more ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 616.8960 Td
+( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 604.9440 Td
+( more text. And more text. And more text. And more text. And more text. ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 592.9920 Td
+( And more text. And more text. ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 569.0880 Td
+( And more text. And more text. And more text. And more text. And more ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 557.1360 Td
+( text. And more text. And more text. Even more. Continued on page 2 ...) Tj
+ET
+endstream
+endobj
+
+6 0 obj
+<<
+/Type /Page
+/Parent 3 0 R
+/Resources <<
+/Font <<
+/F1 9 0 R
+>>
+/ProcSet 8 0 R
+>>
+/MediaBox [0 0 612.0000 792.0000]
+/Contents 7 0 R
+>>
+endobj
+
+7 0 obj
+<< /Length 676 >>
+stream
+2 J
+BT
+0 0 0 rg
+/F1 0027 Tf
+57.3750 722.2800 Td
+( Simple PDF File 2 ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 688.6080 Td
+( ...continued from page 1. Yet more text. And more text. And more text. ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 676.6560 Td
+( And more text. And more text. And more text. And more text. And more ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 664.7040 Td
+( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 652.7520 Td
+( paint dry. And more text. And more text. And more text. And more text. ) Tj
+ET
+BT
+/F1 0010 Tf
+69.2500 640.8000 Td
+( Boring. More, a little more text. The end, and just as well. ) Tj
+ET
+endstream
+endobj
+
+8 0 obj
+[/PDF /Text]
+endobj
+
+9 0 obj
+<<
+/Type /Font
+/Subtype /Type1
+/Name /F1
+/BaseFont /Helvetica
+/Encoding /WinAnsiEncoding
+>>
+endobj
+
+10 0 obj
+<<
+/Creator (Rave \(http://www.nevrona.com/rave\))
+/Producer (Nevrona Designs)
+/CreationDate (D:20060301072826)
+>>
+endobj
+
+xref
+0 11
+0000000000 65535 f
+0000000019 00000 n
+0000000093 00000 n
+0000000147 00000 n
+0000000222 00000 n
+0000000390 00000 n
+0000001522 00000 n
+0000001690 00000 n
+0000002423 00000 n
+0000002456 00000 n
+0000002574 00000 n
+
+trailer
+<<
+/Size 11
+/Root 1 0 R
+/Info 10 0 R
+>>
+
+startxref
+2714
+%%EOF
| |