diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index a4542c19..e4754e1e 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -300,7 +300,7 @@ Lint/UnusedBlockArgument:
# Offense count: 136
Metrics/AbcSize:
- Max: 86
+ Max: 98
# Offense count: 258
# Configuration parameters: CountComments, ExcludedMethods.
@@ -320,7 +320,7 @@ Metrics/LineLength:
# Offense count: 133
# Configuration parameters: CountComments.
Metrics/MethodLength:
- Max: 56
+ Max: 63
# Offense count: 4
# Configuration parameters: CountComments.
diff --git a/Gemfile b/Gemfile
index e624a1f7..9be883a3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -209,6 +209,9 @@ gem 'sprockets-rails'
# for multiple speakers select on proposal/event forms
gem 'selectize-rails'
+# For collecting performance data
+gem 'skylight'
+
# Nokogiri < 1.8.1 is subject to:
# CVE-2017-0663, CVE-2017-7375, CVE-2017-7376, CVE-2017-9047, CVE-2017-9048,
# CVE-2017-9049, CVE-2017-9050
diff --git a/Gemfile.lock b/Gemfile.lock
index 0f64b0e8..9e07eb20 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -297,7 +297,7 @@ GEM
nenv (0.3.0)
netrc (0.11.0)
nio4r (2.1.0)
- nokogiri (1.8.1)
+ nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
notiffany (0.1.1)
nenv (~> 0.1)
@@ -505,6 +505,8 @@ GEM
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
sixarm_ruby_unaccent (1.1.1)
+ skylight (1.5.1)
+ activesupport (>= 3.0.0)
slop (3.6.0)
sort_alphabetical (1.0.2)
unicode_utils (>= 1.2.2)
@@ -668,6 +670,7 @@ DEPENDENCIES
sass-rails (>= 4.0.2)
selectize-rails
shoulda-matchers
+ skylight
spring-commands-rspec
sprockets-rails
sqlite3
diff --git a/INSTALL.md b/INSTALL.md
index ea47fd93..f07b198f 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -78,35 +78,6 @@ You should not directly expose the web server port unless you have a good reason
## Configure
There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file.
-| Variable | Content | Purpose |
-|---------- |--------- |--------- |
-| OSEM_NAME | openSUSE Events | The name of your page |
-| OSEM_HOSTNAME | events.opensuse.org | The host this OSEM instance runs on |
-| OSEM_EMAIL_ADDRESS | events@opensuse.org | The address OSEM uses for sending mails |
-| OSEM_ICHAIN_ENABLED | true/false | Enable the usage of [devise_ichain_authenticatable](https://github.com/openSUSE/devise_ichain_authenticatable) |
-| OSEM_TRANSIFEX_APIKEY | *string* | Use this api key for [transifex](https://www.transifex.com/). See TRANSLATION.md for details. |
-| OSEM_ERRBIT_HOST | errbit.opensuse.org | The [errbit](https://github.com/errbit/errbit) host to post exceptions to |
-| OSEM_ERRBIT_APIKEY | *string* | The api key for the errbit host |
-| OSEM_FACTORY_LINT | *boolean* (true/false) | Setting this to false will disable linting of factories before running spec
-| OSEM_GOOGLE_KEY | *string* | OMNIAUTH Developer Key for GOOGLE
-| OSEM_GOOGLE_SECRET | *string* | OMNIAUTH Developer Secret for GOOGLE
-| OSEM_FACEBOOK_KEY | *string* | OMNIAUTH Developer Key for Facebook
-| OSEM_FACEBOOK_SECRET | *string* | OMNIAUTH Developer Secret for Facebook
-| OSEM_GITHUB_KEY | *string* | OMNIAUTH Developer Key for GitHub
-| OSEM_GITHUB_SECRET | *string* | OMNIAUTH Developer Secret for GitHub
-| OSEM_SUSE_KEY | *string* | OMNIAUTH Developer Key for openSUSE
-| OSEM_SUSE_SECRET | *string* | OMNIAUTH Developer Secret for openSUSE
-| OSEM_SMTP_ADDRESS | smtp.opensuse.org | The smtp server to use
-| OSEM_SMTP_PORT | *int* | The port on the smtp server
-| OSEM_SMTP_USERNAME | *string* | The user for the smtp server
-| OSEM_SMTP_PASSWORD | *string* | The password for the smtp server
-| OSEM_SMTP_AUTHENTICATION | plain, login or cram_md5 | The auth method for the smtp server
-| OSEM_SMTP_DOMAIN | opensuse.org | The HELO domain for the smtp server
-| CLOUDINARY_URL | *string* | Configure your cloudinary.com cloud name and api key/secret
-| STRIPE_PUBLISHABLE_KEY | *string* | Publishable Key for Stripe Gateway
-| STRIPE_SECRET_KEY | *string* | Secret Key for Stripe Gateway
-| OSEM_REDIS_URL | *string* | Redis server URL e.g. redis://localhost:6379/1
-
### Online Ticket Payments
We use [Stripe](https://stripe.com) for accepting your ticket payments securely over the web.
Our application uses iFrame for accepting your user's payment details without storing them, making the application PCI SAQ-A Compliant.
@@ -121,8 +92,10 @@ If you would like to resize exisiting logos in your OSEM installation you can do
```shell
$ bundle exec rake logo:reprocess
```
+### Ruby
+OSEM is using Ruby version 2.4
-### openID
+## openID
In order to use [openID](http://openid.net/) logins for your OSEM installation you need to register your application with the providers ([Google](https://code.google.com/apis/console#:access), [GitHub](https://github.com/settings/applications/new) or [Facebook](https://developers.facebook.com/)) and enter their API keys in the environment variables found in your *.env* file(s).
## Recurring Jobs
@@ -130,3 +103,8 @@ Open a separate terminal and go into the directory where the rails app is presen
```
bundle exec rake jobs:work
```
+
+## Performance
+If you are experiencing performance issues (or just curious), you may be able to [apply a free Skylight account](https://www.skylight.io/oss).
+Once you have your account setup, simply set `SKYLIGHT_AUTHENTICATION` and `SKYLIGHT_PUBLIC_DASHBOARD_URL` in your `.env` file.
+If you are reporting a performance issue or submiting a performance patch, it would be helpful (but not required) to link to the relevant Skylight data.
diff --git a/app/assets/stylesheets/osem.scss b/app/assets/stylesheets/osem.scss
index bbcabc44..7d0d0519 100644
--- a/app/assets/stylesheets/osem.scss
+++ b/app/assets/stylesheets/osem.scss
@@ -115,3 +115,9 @@ p.comment-body {
float: right;
}
}
+
+/* omniauth btn grp */
+#openid-btn-grp{
+ display: flex;
+ justify-content: center;
+}
\ No newline at end of file
diff --git a/app/controllers/admin/commercials_controller.rb b/app/controllers/admin/commercials_controller.rb
index 3c694246..1bc587ce 100644
--- a/app/controllers/admin/commercials_controller.rb
+++ b/app/controllers/admin/commercials_controller.rb
@@ -57,7 +57,9 @@ module Admin
def mass_upload
errors = Commercial.read_file(params[:file]) if params[:file]
- if errors.all? { |_k, v| v.blank? }
+ if !params[:file]
+ flash[:error] = 'Empty file detected while adding commercials to Event'
+ elsif errors.all? { |_k, v| v.blank? }
flash[:notice] = 'Successfully added commercials.'
else
errors_text = ''
diff --git a/app/controllers/admin/conferences_controller.rb b/app/controllers/admin/conferences_controller.rb
index 921a23d1..6342f09f 100644
--- a/app/controllers/admin/conferences_controller.rb
+++ b/app/controllers/admin/conferences_controller.rb
@@ -20,6 +20,10 @@ module Admin
@total_submissions = Event.count
@new_submissions = Event.where('created_at > ?', current_user.last_sign_in_at).count
+ @total_withdrawn = Event.where(state: :withdrawn).count
+ @new_withdrawn = Event
+ .where('state = ? and created_at > ?', 'withdrawn', current_user.last_sign_in_at).count
+
@active_conferences = Conference.get_active_conferences_for_dashboard # pending or the last two
@deactive_conferences = Conference
.get_conferences_without_active_for_dashboard(@active_conferences) # conferences without active
@@ -116,13 +120,19 @@ module Admin
@total_reg = @conference.registrations.count
@new_reg = @conference.registrations.where('created_at > ?', current_user.last_sign_in_at).count
- @total_submissions = @program.events.count
- @new_submissions = @program.events
+ @all_events = @program.events
+
+ @total_submissions = @all_events.count
+ @new_submissions = @all_events
.where('created_at > ?', current_user.last_sign_in_at).count
@program_length = @conference.current_program_hours
@new_program_length = @conference.new_program_hours(current_user.last_sign_in_at)
+ @total_withdrawn = @all_events.where(state: :withdrawn).count
+ @new_withdrawn = @all_events
+ .where('state = "withdrawn" and created_at > ?', current_user.last_sign_in_at).count
+
# Step by step list
@conference_progress = @conference.get_status
@@ -162,13 +172,17 @@ module Admin
# Doughnut charts
@event_type_distribution = @conference.event_type_distribution
@event_type_distribution_confirmed = @conference.event_type_distribution(:confirmed)
+ @event_type_distribution_withdrawn = @conference.event_type_distribution(:withdrawn)
@difficulty_levels_distribution = @conference.difficulty_levels_distribution
@difficulty_levels_distribution_confirmed = @conference
.difficulty_levels_distribution(:confirmed)
+ @difficulty_levels_distribution_withdrawn = @conference
+ .difficulty_levels_distribution(:withdrawn)
@tracks_distribution = @conference.tracks_distribution
@tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed)
+ @tracks_distribution_withdrawn = @conference.tracks_distribution(:withdrawn)
# Recent actions information
@recent_events = @conference.program.events.limit(5).order(created_at: :desc)
diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb
index 5e907cea..1c9b37b3 100644
--- a/app/controllers/conferences_controller.rb
+++ b/app/controllers/conferences_controller.rb
@@ -55,6 +55,7 @@ class ConferencesController < ApplicationController
@sponsorship_levels = @conference.sponsorship_levels.eager_load(
:sponsors
).order('sponsorship_levels.position ASC', 'sponsors.name')
+ @sponsors = @conference.sponsors
end
end
diff --git a/app/controllers/physical_tickets_controller.rb b/app/controllers/physical_tickets_controller.rb
index 2f6f18ec..c3cc40cb 100644
--- a/app/controllers/physical_tickets_controller.rb
+++ b/app/controllers/physical_tickets_controller.rb
@@ -10,7 +10,7 @@ class PhysicalTicketsController < ApplicationController
end
def show
- @file_name = "ticket_for_#{@conference.short_title}"
+ @file_name = "ticket_for_#{@conference.short_title}.pdf"
@user = @physical_ticket.user
@ticket_layout = @conference.ticket_layout.to_sym
@qrcode_image = RQRCode::QRCode.new(@physical_ticket.token).as_png(size: 180, border_modules: 0)
diff --git a/app/models/ability.rb b/app/models/ability.rb
index b833b6f4..d6b3ef21 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -66,7 +66,13 @@ class Ability
can [:new, :create], Registration do |registration|
conference = registration.conference
- conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user)
+ if conference.user_registered? user
+ false
+ elsif conference.program.speakers.confirmed.include?(user) && conference.registration_period
+ true
+ else
+ conference.registration_open? && !conference.registration_limit_exceeded?
+ end
end
can :index, Organization
diff --git a/app/models/conference.rb b/app/models/conference.rb
index 03402652..81e9ec32 100644
--- a/app/models/conference.rb
+++ b/app/models/conference.rb
@@ -1029,7 +1029,7 @@ class Conference < ApplicationRecord
# * +hash+ -> object_type => {color, value}
def calculate_event_distribution(group_by_id, association_symbol, state = nil)
grouped = if state
- program.events.select(group_by_id).where('state = ?', 'confirmed').group(group_by_id)
+ program.events.select(group_by_id).where('state = ?', state).group(group_by_id)
else
program.events.select(group_by_id).group(group_by_id)
end
diff --git a/app/models/organization.rb b/app/models/organization.rb
index 21d0989b..1e3974de 100644
--- a/app/models/organization.rb
+++ b/app/models/organization.rb
@@ -7,7 +7,11 @@ class Organization < ApplicationRecord
after_create :create_roles
- validates :name, presence: true
+ validates :name,
+ uniqueness: {
+ case_sensitive: false
+ },
+ presence: true
mount_uploader :picture, PictureUploader, mount_on: :picture
diff --git a/app/models/registration.rb b/app/models/registration.rb
index 1198324e..45d2d55b 100644
--- a/app/models/registration.rb
+++ b/app/models/registration.rb
@@ -1,4 +1,5 @@
class Registration < ApplicationRecord
+ require 'csv'
belongs_to :user
belongs_to :conference
diff --git a/app/views/admin/conferences/index.html.haml b/app/views/admin/conferences/index.html.haml
index 02208aeb..2fde1575 100644
--- a/app/views/admin/conferences/index.html.haml
+++ b/app/views/admin/conferences/index.html.haml
@@ -1,5 +1,5 @@
.row
- .col-sm-4.col-xs-4
+ .col-sm-3.col-xs-3
.dashbox.text-center
%span.fa.fa-user.fa-lg
%span.fa.fa-lg
@@ -11,7 +11,7 @@
%span.label.label-success{ title: "+ #{@new_user} since you last logged in!" }
+
= @new_user
- .col-sm-4.col-xs-4
+ .col-sm-3.col-xs-3
.dashbox.text-center
%span.fa.fa-check-square.fa-lg
%span.fa.fa-lg
@@ -23,7 +23,7 @@
%span.label.label-success{ title: "+#{@new_reg} since you last logged in!" }
+
= @new_reg
- .col-sm-4.col-xs-4
+ .col-sm-3.col-xs-3
.dashbox.text-center
%span.fa.fa-file-text.fa-lg
%span.fa.fa-lg
@@ -35,6 +35,18 @@
%span.label.label-success{ title: "+#{@new_submissions} since you last logged in!" }
+
= @new_submissions
+ .col-sm-3.col-xs-3
+ .dashbox.text-center
+ %span.fa.fa-archive.fa-lg
+ %span.fa.fa-lg
+ = @total_withdrawn
+ %p
+ %small
+ #{'Withdrawn'.pluralize(@total_withdrawn)}
+ - if @new_withdrawn
+ %span.label.label-success{ title: "+#{@new_withdrawn} since you last logged in!" }
+ +
+ = @new_withdrawn
.row#registrations
.col-md-8
diff --git a/app/views/admin/conferences/show.html.haml b/app/views/admin/conferences/show.html.haml
index cddae4c2..ca59d8d9 100644
--- a/app/views/admin/conferences/show.html.haml
+++ b/app/views/admin/conferences/show.html.haml
@@ -3,7 +3,7 @@
Dashboard for #{@conference.title}
%hr
.row
- .col-sm-4.col-xs-4
+ .col-sm-3.col-xs-3
.dashbox.text-center
%span.fa.fa-user.fa-lg
%span.fa.fa-lg
@@ -16,7 +16,7 @@
+
= @new_reg
- .col-sm-4.col-xs-4
+ .col-sm-3.col-xs-3
.dashbox.text-center
%span.fa.fa-check-square.fa-lg
%span.fa.fa-lg
@@ -29,7 +29,7 @@
+
= @new_submissions
- .col-sm-4.col-xs-4
+ .col-sm-3.col-xs-3
.dashbox.text-center
%span.fa.fa-file-text.fa-lg
%span.fa.fa-lg
@@ -42,6 +42,19 @@
+
= @new_program_length
+ .col-sm-3.col-xs-3
+ .dashbox.text-center
+ %span.fa.fa-archive.fa-lg
+ %span.fa.fa-lg
+ = @total_withdrawn
+ %p
+ %small
+ #{'Withdrawn'.pluralize(@total_withdrawn)}
+ - if @new_withdrawn
+ %span.label.label-success{ title: "+#{@new_withdrawn} since you last logged in!" }
+ +
+ = @new_withdrawn
+
.row
.col-md-12
.row
@@ -91,6 +104,10 @@
%a{ href: '#distribution_confirmed', 'data-toggle' => 'tab' }
%span.fa.fa-comment
Confirmed
+ %li
+ %a{ href: '#distribution_withdrawn', 'data-toggle' => 'tab' }
+ %span.fa.fa-archive
+ Withdrawn
.tab-content
.tab-pane.active#distribution_all
.row
@@ -108,6 +125,14 @@
= render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_confirmed}
.col-md-4
= render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_confirmed}
+ .tab-pane#distribution_withdrawn
+ .row
+ .col-md-4
+ = render partial: 'doughnut_chart', locals: {title: 'Event types', data: @event_type_distribution_withdrawn}
+ .col-md-4
+ = render partial: 'doughnut_chart', locals: {title: 'Difficulty levels', data: @difficulty_levels_distribution_withdrawn}
+ .col-md-4
+ = render partial: 'doughnut_chart', locals: {title: 'Tracks', data: @tracks_distribution_withdrawn}
.row
.col-md-8
diff --git a/app/views/conferences/_social_media.haml b/app/views/conferences/_social_media.haml
index 32cf1b16..28a87dbc 100644
--- a/app/views/conferences/_social_media.haml
+++ b/app/views/conferences/_social_media.haml
@@ -15,6 +15,9 @@
- unless contact.googleplus.blank?
= link_to "#{ contact.googleplus }" do
%i.fa.fa-google-plus-square.fa-4x
+ - unless contact.mastodon.blank?
+ = link_to "#{ contact.mastodon }" do
+ %i.fa.icon-mastodon.fa-4x
- unless contact.email.blank?
= mail_to "#{ contact.email }" do
%i.fa.fa-envelope-o.fa-4x
diff --git a/app/views/conferences/_social_media.html.haml b/app/views/conferences/_social_media.html.haml
deleted file mode 100644
index 49216b6c..00000000
--- a/app/views/conferences/_social_media.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-.container
- .row
- .col-md-12.text-center
- - unless @conference.contact.facebook.blank?
- = link_to "#{ @conference.contact.facebook }" do
- %i.fa.fa-facebook-square.fa-4x
- - unless @conference.contact.twitter.blank?
- = link_to "#{ @conference.contact.twitter }" do
- %i.fa.fa-twitter.fa-4x
- - unless @conference.contact.instagram.blank?
- = link_to "#{ @conference.contact.instagram }" do
- %i.fa.fa-instagram.fa-4x
- - unless @conference.contact.googleplus.blank?
- = link_to "#{ @conference.contact.googleplus }" do
- %i.fa.fa-google-plus-square.fa-4x
- - unless @conference.contact.mastodon.blank?
- = link_to "#{ @conference.contact.mastodon }" do
- %i.fa.icon-mastodon.fa-4x
- - unless @conference.contact.email.blank?
- = mail_to "#{ @conference.contact.email }" do
- %i.fa.fa-envelope-o.fa-4x
diff --git a/app/views/conferences/_sponsors.haml b/app/views/conferences/_sponsors.haml
index 8f4d55c6..5d7bbaa9 100644
--- a/app/views/conferences/_sponsors.haml
+++ b/app/views/conferences/_sponsors.haml
@@ -2,7 +2,7 @@
%li
%a.smoothscroll{ href: '#sponsors' } Sponsors
-- cache [conference, sponsorship_levels, '#splash#sponsors'] do
+- cache [conference, sponsors, sponsorship_levels, '#splash#sponsors'] do
%section#sponsors
.container
- sponsorship_levels.each do |sponsorship_level|
@@ -31,6 +31,6 @@
= link_to(sponsorship_mailto(conference)) do
Contact us!
-- sponsorship_levels.collect(&:sponsors).flatten.each do |sponsor|
+- sponsors.each do |sponsor|
- content_for :modals do
= render 'modal_description', object: sponsor
diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml
index ea99b419..246ccc35 100644
--- a/app/views/conferences/show.html.haml
+++ b/app/views/conferences/show.html.haml
@@ -43,7 +43,8 @@
-# sponsorship
- if @conference.splashpage.include_sponsors
= render 'sponsors', conference: @conference,
- sponsorship_levels: @sponsorship_levels
+ sponsorship_levels: @sponsorship_levels,
+ sponsors: @sponsors
-# footer
- if @conference.splashpage.include_social_media
diff --git a/app/views/devise/shared/_openid_links.html.haml b/app/views/devise/shared/_openid_links.html.haml
index 8bcc96da..09c7a7ea 100644
--- a/app/views/devise/shared/_openid_links.html.haml
+++ b/app/views/devise/shared/_openid_links.html.haml
@@ -1,5 +1,5 @@
.text-center
- .btn-group.btn-group-lg
+ .btn-group.btn-group-lg#openid-btn-grp
- omniauth_configured.each do |provider|
= link_to "user_#{provider}_omniauth_authorize".to_sym, class: "btn btn-success btn-lg",
id: "omniauth-#{provider}",
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index aa155bcb..128f491a 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -37,11 +37,14 @@
%p.muted.text-center
%small
This tool is
- =link_to "free software,", "http://www.gnu.org/philosophy/free-sw.html"
+ #{link_to "free software", "http://www.gnu.org/philosophy/free-sw.html"},
released under the
- =link_to "MIT license.", "http://opensource.org/licenses/MIT"
+ #{link_to "MIT license", "http://opensource.org/licenses/MIT"}.
You can run, copy, distribute, study, change and improve it.
The source code and the developers are on
- =link_to "github.", "https://github.com/openSUSE/osem"
+ #{link_to "GitHub", "https://github.com/openSUSE/osem"}.
+ - if ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"].present?
+ Performance data is available on
+ #{link_to "Skylight", ENV["SKYLIGHT_PUBLIC_DASHBOARD_URL"]}.
= yield :script_body
= piwik_tracking_tag
diff --git a/dotenv.example b/dotenv.example
index e0e3f519..6d8dd025 100644
--- a/dotenv.example
+++ b/dotenv.example
@@ -46,6 +46,10 @@ OSEM_SUSE_SECRET=''
STRIPE_PUBLISHABLE_KEY=''
STRIPE_SECRET_KEY=''
+# (OPTIONAL) Skylight keys. See https://www.skylight.io/oss.
+# SKYLIGHT_AUTHENTICATION=''
+# SKYLIGHT_PUBLIC_DASHBOARD_URL='https://oss.skylight.io/app/applications/xxxxxxxxxxxx'
+
# Disable linting of factories in the test suite.
# Speeds up turn around times of tests
OSEM_FACTORY_LINT="false"
diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb
index ff9d676b..984ef137 100644
--- a/spec/controllers/admin/conferences_controller_spec.rb
+++ b/spec/controllers/admin/conferences_controller_spec.rb
@@ -95,6 +95,75 @@ describe Admin::ConferencesController do
get :show, id: conference.short_title
expect(response).to render_template :show
end
+
+ it 'assigns conference withdrawn events distribution to event_type_distribution_withdrawn' do
+ conference
+ create(:event, program: conference.program)
+ workshop = create(:event_type, title: 'Workshop', color: '#000000', program: conference.program)
+ lecture = create(:event_type, title: 'Lecture', color: '#ffffff', program: conference.program)
+ get :show, id: conference.short_title
+ expect(assigns(:event_type_distribution_withdrawn)).to be_empty
+ create(:event, program: conference.program, state: 'withdrawn', event_type: lecture)
+ create(:event, program: conference.program, state: 'withdrawn', event_type: workshop)
+ get :show, id: conference.short_title
+ expect(assigns(:event_type_distribution_withdrawn)).not_to be_empty
+ result = {}
+ result['Workshop'] = {
+ 'value' => 1,
+ 'color' => '#000000'
+ }
+ result['Lecture'] = {
+ 'value' => 1,
+ 'color' => '#FFFFFF'
+ }
+ expect(assigns(:event_type_distribution_withdrawn)).to eq(result)
+ end
+
+ it 'assigns conference withdrawn difficulty level distribution to difficulty_levels_distribution_withdrawn' do
+ conference
+ create(:event, program: conference.program)
+ get :show, id: conference.short_title
+ expect(assigns(:difficulty_levels_distribution_withdrawn)).to be_empty
+ easy = create(:difficulty_level, title: 'Easy', color: '#000000')
+ hard = create(:difficulty_level, title: 'Hard', color: '#ffffff')
+ create(:event, program: conference.program, state: 'withdrawn', difficulty_level: easy)
+ create(:event, program: conference.program, state: 'withdrawn', difficulty_level: hard)
+ get :show, id: conference.short_title
+ expect(assigns(:difficulty_levels_distribution_withdrawn)).not_to be_empty
+ result = {}
+ result['Easy'] = {
+ 'value' => 1,
+ 'color' => '#000000'
+ }
+ result['Hard'] = {
+ 'value' => 1,
+ 'color' => '#FFFFFF'
+ }
+ expect(assigns(:difficulty_levels_distribution_withdrawn)).to eq(result)
+ end
+
+ it 'assigns conference withdrawn track distribution to tracks_distribution_withdrawn' do
+ conference
+ create(:event, program: conference.program)
+ get :show, id: conference.short_title
+ expect(assigns(:tracks_distribution_withdrawn)).to be_empty
+ track_one = create(:track, name: 'Track One', color: '#000000', program: conference.program)
+ track_two = create(:track, name: 'Track Two', color: '#FFFFFF', program: conference.program)
+ create(:event, program: conference.program, state: 'withdrawn', track: track_one)
+ create(:event, program: conference.program, state: 'withdrawn', track: track_two)
+ get :show, id: conference.short_title
+ expect(assigns(:tracks_distribution_withdrawn)).not_to be_empty
+ result = {}
+ result['Track One'] = {
+ 'value' => 1,
+ 'color' => '#000000'
+ }
+ result['Track Two'] = {
+ 'value' => 1,
+ 'color' => '#FFFFFF'
+ }
+ expect(assigns(:tracks_distribution_withdrawn)).to eq(result)
+ end
end
describe 'GET #index' do
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 214e522a..4d1c2eab 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -30,7 +30,45 @@ describe ApplicationController, type: :controller do
expect(controller.after_sign_in_path_for(user)).to eq conferences_path
end
end
-
+ end
+
+ end
+
+end
+
+describe ApplicationController, type: :request do
+ let(:conference) { create(:conference) }
+
+ describe 'Skylight link' do
+
+ around do |example|
+ original_value = ENV['SKYLIGHT_PUBLIC_DASHBOARD_URL']
+ example.run
+ ENV['SKYLIGHT_PUBLIC_DASHBOARD_URL'] = original_value
+ end
+
+ context 'when SKYLIGHT_PUBLIC_DASHBOARD_URL is set' do
+ before do
+ ENV['SKYLIGHT_PUBLIC_DASHBOARD_URL'] = 'https://oss.skylight.io/app/applications/my-osem'
+ end
+
+ it 'should include a link to view performance data' do
+ get '/'
+ expect(response.body).to match(/Performance data/i)
+ expect(response.body).to include('https://oss.skylight.io/app/applications/my-osem')
+ end
+ end
+
+ context 'when SKYLIGHT_PUBLIC_DASHBOARD_URL is not set' do
+ before do
+ ENV['SKYLIGHT_PUBLIC_DASHBOARD_URL'] = nil
+ end
+
+ it 'should not include a link to view performance data' do
+ get '/'
+ expect(response.body).to_not match(/performance data/i)
+ expect(response.body).to_not match(/skylight/i)
+ end
end
end
diff --git a/spec/factories/organizations.rb b/spec/factories/organizations.rb
index 0ee76554..f6331873 100644
--- a/spec/factories/organizations.rb
+++ b/spec/factories/organizations.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :organization do
- name { Faker::Company.name }
+ sequence(:name) { |n| "#{Faker::Company.name} #{n}" }
description { Faker::Lorem.paragraph }
# after(:create) do |organization|
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index 7936ddbb..26522913 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -89,11 +89,131 @@ describe 'User' do
let(:other_self_organized_track) { create(:track, :self_organized) }
it{ should be_able_to(:manage, user) }
-
it{ should be_able_to(:manage, registration_public) }
it{ should be_able_to(:manage, registration_not_public) }
- it{ should_not be_able_to(:new, Registration.new(conference_id: conference_with_closed_registration.id))}
- it{ should_not be_able_to(:create, Registration.new(conference_id: conference_with_closed_registration.id))}
+
+ # Test for user can register or not
+ context 'when user is not a speaker with event confirmed' do
+ let(:conference) { create(:conference) }
+
+ context 'when the registration is closed' do
+ before :each do
+ create(:registration_period, conference: conference, start_date: Date.current - 6.days, end_date: Date.current - 6.days)
+ end
+
+ it{ should_not be_able_to(:new, Registration.new(conference: conference)) }
+ it{ should_not be_able_to(:create, Registration.new(conference: conference)) }
+ end
+
+ context 'when the registration period is not set' do
+ it{ should_not be_able_to(:new, Registration.new(conference: conference)) }
+ it{ should_not be_able_to(:create, Registration.new(conference: conference)) }
+ end
+
+ context 'when user has already registered' do
+ before :each do
+ create(:registration, conference: conference, user: user)
+ end
+
+ it{ should_not be_able_to(:new, Registration.new(conference: conference)) }
+ it{ should_not be_able_to(:create, Registration.new(conference: conference)) }
+ end
+
+ context 'when registrations are open' do
+ before :each do
+ create(:registration_period, conference: conference)
+ end
+
+ it{ should be_able_to(:new, Registration.new(conference: conference)) }
+ it{ should be_able_to(:create, Registration.new(conference: conference)) }
+
+ context 'when user has not registered with no registration_limit_exceeded' do
+ before :each do
+ conference.registration_limit = 1
+ end
+
+ it{ should be_able_to(:new, Registration.new(conference: conference)) }
+ it{ should be_able_to(:create, Registration.new(conference: conference)) }
+ end
+
+ context 'when user has not registered with registration_limit_exceeded' do
+ before :each do
+ conference.registration_limit = 1
+ create(:registration, conference: conference, user: user2)
+ end
+
+ it{ should_not be_able_to(:new, Registration.new(conference: conference)) }
+ it{ should_not be_able_to(:create, Registration.new(conference: conference)) }
+ end
+ end
+ end
+
+ context 'when user is a speaker with event confirmed' do
+ let(:conference_with_speaker_confirmed) { create(:conference) }
+ let(:event_with_speaker_confirmed) { create(:event, state: 'confirmed', program: conference_with_speaker_confirmed.program) }
+
+ before :each do
+ event_with_speaker_confirmed.speakers << user
+ end
+
+ context 'when registration period is not set' do
+ it{ should_not be_able_to(:new, Registration.new(conference: conference_with_speaker_confirmed)) }
+ it{ should_not be_able_to(:create, Registration.new(conference: conference_with_speaker_confirmed)) }
+ end
+
+ context 'when speaker has already registered' do
+ before :each do
+ create(:registration, conference: conference_with_speaker_confirmed, user: user)
+ end
+
+ it{ should_not be_able_to(:new, Registration.new(conference: conference_with_speaker_confirmed)) }
+ it{ should_not be_able_to(:create, Registration.new(conference: conference_with_speaker_confirmed)) }
+ end
+
+ context 'when registration period is set' do
+ before :each do
+ create(:registration_period, conference: conference_with_speaker_confirmed)
+ end
+
+ context 'when registrations are open' do
+ context 'when speaker has not registered' do
+ it{ should be_able_to(:new, Registration.new(conference: conference_with_speaker_confirmed)) }
+ it{ should be_able_to(:create, Registration.new(conference: conference_with_speaker_confirmed)) }
+ end
+
+ context 'when registration_limit_exceeded' do
+ before :each do
+ conference_with_speaker_confirmed.registration_limit = 1
+ create(:registration, conference: conference_with_speaker_confirmed, user: user2)
+ end
+
+ it{ should be_able_to(:new, Registration.new(conference: conference_with_speaker_confirmed)) }
+ it{ should be_able_to(:create, Registration.new(conference: conference_with_speaker_confirmed)) }
+ end
+ end
+
+ context 'when registrations are closed' do
+ before :each do
+ create(:registration_period, conference: conference_with_speaker_confirmed, start_date: Date.current - 6.days, end_date: Date.current - 6.days)
+ end
+
+ context 'when speaker has not registered' do
+ it{ should be_able_to(:new, Registration.new(conference: conference_with_speaker_confirmed)) }
+ it{ should be_able_to(:create, Registration.new(conference: conference_with_speaker_confirmed)) }
+ end
+
+ context 'with registration_limit_exceeded' do
+ before :each do
+ conference_with_speaker_confirmed.registration_limit = 1
+ create(:registration, conference: conference_with_speaker_confirmed, user: user2)
+ end
+
+ it{ should be_able_to(:new, Registration.new(conference: conference_with_speaker_confirmed)) }
+ it{ should be_able_to(:create, Registration.new(conference: conference_with_speaker_confirmed)) }
+ end
+ end
+ end
+ end
it{ should be_able_to(:index, Ticket) }
it{ should be_able_to(:manage, TicketPurchase.new(user_id: user.id)) }
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 704b8e08..60e07602 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -63,7 +63,12 @@ RSpec.configure do |config|
Capybara.javascript_driver = :poltergeist
Capybara.register_driver :poltergeist do |app|
- Capybara::Poltergeist::Driver.new(app, phantomjs: Phantomjs.path, js_errors: false, window_size: [1920, 1080])
+ Capybara::Poltergeist::Driver.new(
+ app,
+ phantomjs: Phantomjs.path,
+ js_errors: false,
+ window_size: [1920, 1080]
+ )
end
# Includes helpers and connect them to specific types of tests
diff --git a/spec/support/external_request.rb b/spec/support/external_request.rb
index d09ebc0a..ed7da3d3 100644
--- a/spec/support/external_request.rb
+++ b/spec/support/external_request.rb
@@ -11,9 +11,9 @@ end
def mock_commercial_request
response = {
author_name: 'Confreaks',
- html: '',
+ html: '',
thumbnail_width: 480,
- thumbnail_url: 'https://i.ytimg.com/vi/BTTygyxuGj8/hqdefault.jpg',
+ thumbnail_url: '/images/rails.png',
provider_name: 'YouTube',
width: 459,
type: 'video',