Merge branch 'master' into openid

This commit is contained in:
Stella Rouzi 2017-12-15 22:37:50 +02:00 • committed by GitHub
commit a822858761
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 231 additions and 59 deletions

View file

@ -82,7 +82,7 @@ You can read through current enabled rules in `.rubocop.yml` file. Explanations
Additionally you can read through the [ruby style-guide](https://github.com/bbatsov/ruby-style-guide) to better understand core principles.
### Test Suite
We are using [rspec](http://rspec.info/)+[capybara](http://jnicklas.github.io/capybara/)+[factory girl](https://github.com/thoughtbot/factory_girl) as a test suite. You can run it locally
We are using [rspec](http://rspec.info/)+[capybara](http://teamcapybara.github.io/capybara/)+[factory girl](https://github.com/thoughtbot/factory_girl) as a test suite. You can run it locally
```shell
vagrant exec bundle exec rspec

View file

@ -98,6 +98,9 @@ $(function () {
$("#registration-period-start-datepicker").on("dp.change",function (e) {
$('#registration-period-end-datepicker').data("DateTimePicker").setMinDate(e.date);
if (!$('#registration-period-end-datepicker').val()) {
$('#registration-period-end-datepicker').data("DateTimePicker").setDate(e.date);
}
});
$("#registration-period-end-datepicker").on("dp.change",function (e) {
$('#registration-period-start-datepicker').data("DateTimePicker").setMaxDate(e.date);

View file

@ -49,6 +49,26 @@ module Admin
end
end
##
# Received a file from user
# Reads file and creates commercial for event
# File content example:
# EventID:MyURL
def mass_upload
errors = Commercial.read_file(params[:file]) if params[:file]
if errors.all? { |_k, v| v.blank? }
flash[:notice] = 'Successfully added commercials.'
else
errors_text = ''
errors_text << 'Unable to find event with ID: ' + errors[:no_event].join(', ') + '. ' if errors[:no_event].any?
errors_text << 'There were some errors: ' + errors[:validation_errors].join('. ') if errors[:validation_errors].any?
flash[:error] = errors_text
end
redirect_to :back
end
private
def commercial_params

View file

@ -124,6 +124,15 @@ module Admin
def cancel
update_state(:cancel, 'Event canceled!')
selected_schedule = @event.program.selected_schedule
event_schedule = EventSchedule.unscoped.where(event: @event).find_by(schedule: selected_schedule) if selected_schedule
Rails.logger.debug "schedule: #{selected_schedule.inspect} and event_schedule #{event_schedule.inspect}"
if selected_schedule && event_schedule
event_schedule.enabled = false
event_schedule.save
else
@event.event_schedules.destroy_all
end
end
def reject

View file

@ -91,6 +91,15 @@ class ProposalsController < ApplicationController
begin
@event.withdraw
selected_schedule = @event.program.selected_schedule
event_schedule = @event.event_schedules.find_by(schedule: selected_schedule) if selected_schedule
Rails.logger.debug "schedule: #{selected_schedule.inspect} and event_schedule #{event_schedule.inspect}"
if selected_schedule && event_schedule
event_schedule.enabled = false
event_schedule.save
else
@event.event_schedules.destroy_all
end
rescue Transitions::InvalidTransition
redirect_to :back, error: "Event can't be withdrawn"
return

View file

@ -5,7 +5,7 @@ class Commercial < ApplicationRecord
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
validates :url, presence: true
validates :url, presence: true, uniqueness: { scope: :commercialable }
validates :url, format: URI::regexp(%w(http https))
validate :valid_url
@ -20,6 +20,29 @@ class Commercial < ApplicationRecord
end
end
def self.read_file(file)
errors = {}
errors[:no_event] = []
errors[:validation_errors] = []
file.read.each_line do |line|
# Get the event id (text before :)
id = line.match(/:/).pre_match.to_i
# Get the commercial url (text after :)
url = line.match(/:/).post_match
event = Event.find_by(id: id)
# Go to next event, if the event is not found
errors[:no_event] << id && next unless event
commercial = event.commercials.new(url: url)
unless commercial.save
errors[:validation_errors] << "Could not create commercial for event with ID #{event.id} (" + commercial.errors.full_messages.to_sentence + ')'
end
end
errors
end
private
def valid_url

View file

@ -197,6 +197,14 @@ class Event < ApplicationRecord
send(transition)
end
save
# If the event was previously scheduled, and then withdrawn or cancelled
# its event_schedule will have enabled set to false
# If the event is now confirmed again, we want it to be available for scheduling
Rails.logger.debug "transition is #{transition}"
if transition == :confirm
Rails.logger.debug "schedules #{EventSchedule.unscoped.where(event: self, enabled: false)}"
EventSchedule.unscoped.where(event: self, enabled: false).destroy_all
end
rescue Transitions::InvalidTransition => e
alert = "Update state failed. #{e.message}"
end

View file

@ -1,4 +1,5 @@
class EventSchedule < ApplicationRecord
default_scope { where(enabled: true) }
belongs_to :schedule
belongs_to :event
belongs_to :room
@ -33,7 +34,7 @@ class EventSchedule < ApplicationRecord
# Returns event schedules that are scheduled in the same room and start_time as event
#
def intersecting_event_schedules
room.event_schedules.where(start_time: start_time, schedule: schedule).where.not(id: id)
EventSchedule.unscoped.where(room: room, start_time: start_time, schedule: schedule).where.not(id: id)
end
def replacement?

View file

@ -216,7 +216,7 @@ class User < ApplicationRecord
end
def proposals(conference)
events.where('program_id = ? AND event_users.event_role=?', conference.program.id, 'submitter')
events.where('program_id = ? AND (event_users.event_role=? OR event_users.event_role=?)', conference.program.id, 'submitter', 'speaker')
end
def proposal_count(conference)

View file

@ -1,3 +1,5 @@
require 'open-uri'
class TicketPdf < Prawn::Document
def initialize(conference, user, physical_ticket, ticket_layout, file_name)
super(page_layout: ticket_layout, page_size: 'A4', filename: file_name)
@ -43,11 +45,17 @@ class TicketPdf < Prawn::Document
def draw_second_square
move_up 150
if @conference.picture?
if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height]
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], width: 120
else
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], height: 70
conference_image = case @conference.picture.ticket.url[0, 4]
when 'http', 'ftp:' # CDNs
open(@conference.picture.ticket.url)
when '/sys' # local storage
open([
Rails.root,
'/public',
@conference.picture.ticket.url
].join)
end
image conference_image, at: [@mid_horizontal + 30, cursor]
else
image "#{Rails.root}/public/img/osem-logo.png", at: [@mid_horizontal + 30, cursor], height: 70
end

View file

@ -52,10 +52,6 @@ class PictureUploader < CarrierWave::Uploader::Base
"system/#{object_class_name}/#{mounted_as}/#{model.id}"
end
def image
@image ||= MiniMagick::Image.open(file.file)
end
# Create different versions of your uploaded files:
version :large do
process resize_to_fit: [300, 300]
@ -80,6 +76,11 @@ class PictureUploader < CarrierWave::Uploader::Base
process resize_and_pad: [320, 120, 'white']
end
version :ticket, if: :conference?
version :ticket do
process resize_and_pad: [120, 70]
end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_white_list
@ -95,4 +96,8 @@ class PictureUploader < CarrierWave::Uploader::Base
def sponsor?(_picture)
object_class_name == 'sponsors'
end
def conference?(_picture)
object_class_name == 'conferences'
end
end

View file

@ -4,11 +4,15 @@
%h1
Events
= "(#{@events.length})" if @events.any?
.pull-right
.btn-group.pull-right
%button.btn.btn-primary{ 'data-toggle' => 'modal', 'data-target' => '#mass-commercials-modal', title: 'Mass import of commercials for events' }
Add Commercials
- if can? :create, Event
=link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), class: 'button btn btn-default btn-info'
= link_to 'Add Event', new_admin_conference_program_event_path(@conference.short_title), class: 'button btn btn-default btn-info'
- if can? :read, Event
.btn-group
.btn-group
%button.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown', type: 'button', class: 'btn btn-success' }
Export PDF
@ -33,8 +37,27 @@
%li= link_to 'All', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'all')
%li= link_to 'Confirmed', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'confirmed')
%li= link_to 'All with Comments', admin_conference_program_events_path(@conference.short_title, format: :xlsx, event_export_option: 'all_with_comments')
%p.text-muted
All the submissions of your speakers
.modal#mass-commercials-modal
.modal-dialog
.modal-content
.modal-header
%h1 Add commercials to events
.text-muted
Upload your file with data in the following format:
%b Event_ID:Commercial_Link
, eg.
%br
%b 11:https://youtube.com/myvideo
.modal-body
= semantic_form_for '', url: mass_upload_commercials_admin_conference_program_path(@conference.short_title), method: :post do |f|
= f.input 'file', as: :file
.modal-footer
= f.submit 'Add', class: 'btn btn-primary'
.row
.col-md-4
= render partial: 'admin/conferences/doughnut_chart', locals: { title: 'Events state', data: @event_distribution }

View file

@ -9,8 +9,8 @@
.row
.col-md-8
= semantic_form_for(@ticket, url: (@ticket.new_record? ? admin_conference_tickets_path : admin_conference_ticket_path(@conference.short_title, @ticket))) do |f|
= f.input :title
= f.input :description, input_html: { rows: 5, data: { provide: "markdown-editable" } }
= f.input :title, input_html: { autofocus: true }
= f.input :description, input_html: { rows: 5, data: { provide: 'markdown-editable' } }
= f.input :price
= f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY', 'CHF'], include_blank: false
= f.input :registration_ticket, hint: 'A registration ticket is with which user register for the conference.'

View file

@ -104,6 +104,8 @@
= humanized_money @total_price_per_ticket[ticket_id]
%br
- if @tickets.any?
.btn-group
= link_to 'View all tickets', conference_physical_tickets_path(@conference.short_title), class: "btn btn-success"
= link_to 'Get more tickets', conference_tickets_path(@conference.short_title), class: "btn btn-default"
- else
You haven't bought any tickets.

View file

@ -31,12 +31,7 @@
= @user.email
.col-md-5.col-md-offset-2.box.well
- if @conference.picture?
- width = @conference.picture.image[:width]
- height = @conference.picture.image[:height]
- if 10 * width > 15 * height
= image_tag(@conference.picture_url, width: '150')
- else
= image_tag(@conference.picture_url, height: '100')
= image_tag(@conference.picture.ticket.url, class: 'img-responsive')
- else
= image_tag('/img/osem-logo.png', class: 'img-responsive')
%p.text-left

View file

@ -36,8 +36,10 @@
.col-md-8
%h4
= link_to speaker.name, user_path(speaker.id)
%br
- if speaker.email_public?
= "(#{speaker.email})"
= mail_to "#{ speaker.email }" do
%i.fa.fa-envelope-o.fa-2x
- if speaker.affiliation?
.text-muted
from

View file

@ -54,6 +54,7 @@ elif [[ "$ID" == "centos" || "$VERSION" == "7" ]]; then
tar jxvf /tmp/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C /tmp/ phantomjs-2.1.1-linux-x86_64/bin/phantomjs
mv /tmp/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin
pushd /vagrant
fi
echo -e "\ninstalling your bundle...\n"
@ -64,7 +65,7 @@ if [ ! -f /vagrant/config/database.yml ] && [ -f /vagrant/config/database.yml.ex
echo -e "\nSetting up your database from config/database.yml...\n"
cp config/database.yml.example config/database.yml
if [ ! -f db/development.sqlite3 ] && [ ! -f db/test.sqlite3 ]; then
bundle exec rake db:setup
su - vagrant -c "cd /vagrant/; bundle exec rake db:setup"
else
echo -e "\n\nWARNING: You have already have a development/test database."
echo -e "WARNING: Please make sure this database works in this vagrant box!\n\n"

View file

@ -9,6 +9,35 @@ development:
pool: 5
timeout: 5000
## PostgreSQL
## gem install pg
##
## Ensure the postgres gem is defined in your Gemfile
## gem 'pg'
## Update with your database name and login credentials
# development:
# adapter: postgresql
# encoding: unicode
# database: database_name
# pool: 5
# username: username
# password: password
## MySQL
## gem install mysql2
##
## Ensure the mysql gem is defined in your Gemfile
## gem 'mysql2'
## Update with your database name and login credentials
# development:
# adapter: mysql2
# encoding: utf8
# database: database_name
# pool: 5
# username: username
# password: password
# socket: /tmp/mysql.sock
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.

View file

@ -98,6 +98,7 @@ Osem::Application.routes.draw do
end
resources :event_types
resources :difficulty_levels
post 'mass_upload_commercials' => 'commercials#mass_upload'
resources :events do
member do
patch :toggle_attendance

View file

@ -0,0 +1,5 @@
class AddEnabledToEventSchedules < ActiveRecord::Migration
def change
add_column :event_schedules, :enabled, :boolean, default: true
end
end

View file

@ -0,0 +1,9 @@
class RebuildConferencePictures < ActiveRecord::Migration
def up
Conference.all.each do |conference|
conference.picture.recreate_versions!
end
end
def down; end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20171118113113) do
ActiveRecord::Schema.define(version: 20171130172334) do
create_table "ahoy_events", force: :cascade do |t|
t.integer "visit_id"
@ -217,6 +217,7 @@ ActiveRecord::Schema.define(version: 20171118113113) do
t.datetime "start_time"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "enabled", default: true
t.index ["event_id", "schedule_id"], name: "index_event_schedules_on_event_id_and_schedule_id", unique: true
t.index ["event_id"], name: "index_event_schedules_on_event_id"
t.index ["room_id"], name: "index_event_schedules_on_room_id"
@ -494,7 +495,7 @@ ActiveRecord::Schema.define(version: 20171118113113) do
t.integer "user_id"
t.integer "payment_id"
t.integer "week"
t.float "amount_paid", default: 0.0
t.float "amount_paid"
end
create_table "ticket_scannings", force: :cascade do |t|

View file

@ -37,6 +37,9 @@ dockerize -wait tcp://$DATABASE_HOST:$DATABASE_PORT -timeout 60s true
if [ $(echo "show tables;" | mysql --host $DATABASE_HOST --port $DATABASE_PORT $MYSQL_DATABASE | wc -l) -le 1 ]; then
echo ">>> Initializing database..."
bundle exec rake db:schema:load
echo ">>> Seed database..."
bundle exec rake db:seed
fi
echo ">>> Upgrading database..."

View file

@ -2,7 +2,7 @@
FactoryGirl.define do
factory :commercial do
url 'https://www.youtube.com/watch?v=BTTygyxuGj8'
sequence(:url) { |n| "https://www.youtube.com/watch?v=BTTygyxuGj#{n}" }
factory :conference_commercial do
association :commercialable, factory: :conference

View file

@ -98,7 +98,8 @@ feature Commercial do
scenario 'does not update a commercial of an event with invalid data', feature: true, versioning: true, js: true do
commercial = create(:commercial,
commercialable_id: event.id,
commercialable_type: 'Event')
commercialable_type: 'Event',
url: 'https://www.youtube.com/watch?v=BTTygyxuGj8')
visit edit_conference_program_proposal_path(conference.short_title, event.id)
click_link 'Commercials'
fill_in "commercial_url_#{commercial.id}", with: 'invalid_commercial_url'

View file

@ -1704,4 +1704,8 @@ describe Conference do
it { is_expected.to eq [past_conference1, past_conference2] }
end
it 'should have a picture format for tickets' do
expect(create(:conference).picture.ticket.url)
end
end

View file

@ -345,24 +345,34 @@ describe User do
end
describe 'proposals methods' do
let(:submitter) { create(:submitter, user: user) }
let(:submitter) { create(:user) }
let(:speaker) { create(:user) }
let(:event1) { create(:event, program: conference.program) }
let(:event2) { create(:event, program: conference.program) }
before do
event1.event_users << create(:event_user, user: user, event_role: 'submitter')
event2.event_users << create(:event_user, user: user, event_role: 'submitter')
event1.event_users << create(:event_user, user: submitter, event_role: 'submitter')
event2.event_users << create(:event_user, user: submitter, event_role: 'submitter')
event1.event_users << create(:event_user, user: speaker, event_role: 'speaker')
end
describe '#proposals' do
it 'returns events submitted by user' do
expect(user.proposals(conference)).to match [event1, event2]
expect(submitter.proposals(conference)).to match [event1, event2]
end
it 'returns events in which user is a speaker' do
expect(speaker.proposals(conference)).to match [event1]
end
end
describe '#proposal_count' do
it 'returns number of events submitted by user' do
expect(user.proposal_count(conference)).to eq 2
expect(submitter.proposal_count(conference)).to eq 2
end
it 'returns number of events in which the user is a speaker' do
expect(speaker.proposal_count(conference)).to eq 1
end
end
end