Merge branch 'master' into new
This commit is contained in:
commit
764c03e692
49 changed files with 392 additions and 97 deletions
|
|
@ -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.
|
||||
|
|
|
|||
3
Gemfile
3
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
38
INSTALL.md
38
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.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
@import "breakpoints.css.scss";
|
||||
@import "breakpoints.scss";
|
||||
|
||||
.dashbox span.fa {
|
||||
line-height: 1.1em;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
@import "breakpoints.css.scss";
|
||||
@import "breakpoints.scss";
|
||||
.nav-osem {
|
||||
border: none;
|
||||
@include breakpoint(xs) {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
@import "breakpoints.css.scss";
|
||||
@import "breakpoints.scss";
|
||||
|
||||
#splash {
|
||||
// Counter the general padding for #content
|
||||
|
|
@ -115,3 +115,9 @@ p.comment-body {
|
|||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
/* omniauth btn grp */
|
||||
#openid-btn-grp{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
@ -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 = ''
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ class ConferencesController < ApplicationController
|
|||
authorize! :show, @conference # TODO: reduce the 10 queries performed here
|
||||
|
||||
splashpage = @conference.splashpage
|
||||
|
||||
unless splashpage.present?
|
||||
redirect_to admin_conference_splashpage_path(@conference.short_title) && return
|
||||
end
|
||||
|
||||
if splashpage.include_cfp
|
||||
cfps = @conference.program.cfps
|
||||
@call_for_events = cfps.find { |call| call.cfp_type == 'events' }
|
||||
|
|
@ -50,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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -595,11 +595,11 @@ class Conference < ApplicationRecord
|
|||
# * +ActiveRecord+
|
||||
def self.get_active_conferences_for_dashboard
|
||||
result = Conference.where('start_date > ?', Time.now)
|
||||
.select('id, short_title, color, start_date')
|
||||
.select('id, short_title, color, start_date, organization_id')
|
||||
|
||||
if result.empty?
|
||||
result = Conference
|
||||
.select('id, short_title, color, start_date').limit(2)
|
||||
.select('id, short_title, color, start_date, organization_id').limit(2)
|
||||
.order(start_date: :desc)
|
||||
end
|
||||
result
|
||||
|
|
@ -611,7 +611,7 @@ class Conference < ApplicationRecord
|
|||
# ====Returns
|
||||
# * +ActiveRecord+
|
||||
def self.get_conferences_without_active_for_dashboard(active_conferences)
|
||||
result = Conference.select('id, short_title, color, start_date').order(start_date: :desc)
|
||||
result = Conference.select('id, short_title, color, start_date, organization_id').order(start_date: :desc)
|
||||
result - active_conferences
|
||||
end
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
class Registration < ApplicationRecord
|
||||
require 'csv'
|
||||
belongs_to :user
|
||||
belongs_to :conference
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,11 @@ class Ticket < ApplicationRecord
|
|||
|
||||
def tickets_turnover_total(id)
|
||||
tickets = TicketPurchase.where(ticket_id: id).paid
|
||||
tickets.inject(0){ |sum, ticket| sum + (ticket.amount_paid * ticket.quantity) }
|
||||
if tickets.blank?
|
||||
Money.new(0, Ticket.find(id).price_currency)
|
||||
else
|
||||
tickets.inject(Money.new(0, tickets.first.price_currency)){ |sum, ticket| sum + (ticket.amount_paid * ticket.quantity) }
|
||||
end
|
||||
end
|
||||
|
||||
def tickets_sold
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@
|
|||
.col-md-12
|
||||
.page-header
|
||||
%h1 Organizations
|
||||
.btn-group.pull-right
|
||||
= link_to 'Create Organization', new_admin_organization_path, class: 'btn btn-success pull-right'
|
||||
- if can? :manage, :all
|
||||
.btn-group.pull-right
|
||||
= link_to 'Create Organization', new_admin_organization_path, class: 'btn btn-success pull-right'
|
||||
%p.text-muted
|
||||
Manage organizations in OSEM
|
||||
.row
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
.row
|
||||
.col-md-6
|
||||
- if @conference.venue.location?
|
||||
= render '/conferences/venue_map'
|
||||
= render '/conferences/venue_map', venue: @conference.venue
|
||||
-else
|
||||
- if @venue.commercial.nil?
|
||||
.row
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
= image_tag(@booth.picture.thumb.url, size: '20%', alt: '')
|
||||
= @booth.title
|
||||
.btn-group.pull-right
|
||||
= link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, @booth), class: 'btn btn-mini btn-primary'
|
||||
= link_to 'Edit', edit_conference_booth_path(@conference.short_title, @booth), class: 'btn btn-mini btn-primary'
|
||||
|
||||
.row
|
||||
.col-md-12
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@
|
|||
left!
|
||||
%p.cta-button
|
||||
= link_to "Submit your proposal now",
|
||||
conference_program_proposals_path(conference_id),
|
||||
new_conference_program_proposal_path(conference_id),
|
||||
class: 'btn btn-success btn-lg text-center'
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@
|
|||
left!
|
||||
%p.cta-button
|
||||
= link_to("Submit your request for track",
|
||||
conference_program_tracks_path(conference_id),
|
||||
new_conference_program_track_path(conference_id),
|
||||
class: 'btn btn-success btn-lg text-center')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# This file is used by Rack-based servers to start the application.
|
||||
|
||||
require ::File.expand_path('../config/environment', __FILE__)
|
||||
use Rack::Deflater
|
||||
run Osem::Application
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ module Osem
|
|||
# Version of your assets, change this if you want to expire all your assets
|
||||
config.assets.version = '1.0'
|
||||
|
||||
# Set cache headers
|
||||
config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=31536000' }
|
||||
|
||||
config.active_job.queue_adapter = :delayed_job
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ Osem::Application.configure do
|
|||
# Generate digests for assets URLs
|
||||
config.assets.digest = true
|
||||
|
||||
config.assets.css_compressor = :sass
|
||||
config.assets.js_compressor = :uglifier
|
||||
config.assets.gzip = true
|
||||
|
||||
# Defaults to nil and saved in location specified by config.assets.prefix
|
||||
# config.assets.manifest = YOUR_PATH
|
||||
|
||||
|
|
|
|||
|
|
@ -496,7 +496,7 @@ ActiveRecord::Schema.define(version: 20171201163628) do
|
|||
t.integer "user_id"
|
||||
t.integer "payment_id"
|
||||
t.integer "week"
|
||||
t.float "amount_paid"
|
||||
t.float "amount_paid", default: 0.0
|
||||
end
|
||||
|
||||
create_table "ticket_scannings", force: :cascade do |t|
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ SECRET_KEY_BASE=changemechangemechangeme"
|
|||
OSEM_EMAIL_ADDRESS="osem@mailhog"
|
||||
OSEM_SMTP_AUTHENTICATION="login"
|
||||
OSEM_SMTP_ADDRESS="mailhog"
|
||||
OSEM_SMTP_PORT="1025"
|
||||
OSEM_SMTP_PORT=1025
|
||||
OSEM_SMTP_USERNAME="mailhog"
|
||||
OSEM_SMTP_PASSWORD="mailhog"
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
|
|||
|
|
@ -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)) }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ end
|
|||
def mock_commercial_request
|
||||
response = {
|
||||
author_name: 'Confreaks',
|
||||
html: '<iframe width=\'560\' height=\'315\' src=\'https://www.youtube.com/embed/BTTygyxuGj8?feature=oembed\' frameborder=\'0\' allowfullscreen></iframe>',
|
||||
html: '<iframe width="560" height="315" frameborder="0" allowfullscreen></iframe>',
|
||||
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',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue