diff --git a/Gemfile b/Gemfile index 6be4ccc8..e7593f2f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,10 @@ source 'https://rubygems.org' +# rails-assets requires >= 1.8.4 +if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4') + abort "Bundler version >= 1.8.4 is required" +end + # as web framework gem 'rails', '~> 4.2' @@ -82,6 +87,10 @@ source 'https://rails-assets.org' do gem 'rails-assets-waypoints' # for displaying maps gem 'rails-assets-leaflet' + # for markdown editors + gem 'rails-assets-bootstrap-markdown' + gem 'rails-assets-to-markdown' + gem 'rails-assets-markdown' end # as date picker @@ -94,7 +103,7 @@ gem 'chart-js-rails' gem 'gravtastic' # for country selects -gem 'country_select', github: 'stefanpenner/country_select' +gem 'country_select' # for upload management gem 'paperclip' @@ -163,6 +172,8 @@ group :development do gem 'sqlite3' # Use letter_opener to open mails in development gem 'letter_opener' + # Use letter_opener_web to open mails in browser (e.g. necessary for Vagrant) + gem 'letter_opener_web' # mina is a blazing fast deployment system gem 'mina' gem 'web-console', '~> 2.0' @@ -182,7 +193,7 @@ group :test do # Extracted from RSpec 3 stub_model and mock_model gem 'rspec-activemodel-mocks' gem 'timecop' - # Mock external requests + # for mocking external requests gem 'webmock' end diff --git a/Gemfile.lock b/Gemfile.lock index 436ed447..5af62e75 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,3 @@ -GIT - remote: git://github.com/stefanpenner/country_select.git - revision: 585e9538a01ae9878e92f12a98261a09842ed015 - specs: - country_select (2.1.0) - countries (~> 0.9, >= 0.9.3) - GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ @@ -28,8 +21,8 @@ GEM erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - active_model_serializers (0.8.1) - activemodel (>= 3.0) + active_model_serializers (0.9.4) + activemodel (>= 3.2) activejob (4.2.5.2) activesupport (= 4.2.5.2) globalid (>= 0.3.0) @@ -92,7 +85,7 @@ GEM byebug (3.1.2) columnize (~> 0.8) debugger-linecache (~> 1.2) - cancancan (1.8.4) + cancancan (1.13.1) capybara (2.2.1) mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -122,8 +115,12 @@ GEM execjs coffee-script-source (1.10.0) columnize (0.8.9) - countries (0.9.3) + countries (1.2.5) currencies (~> 0.4.2) + i18n_data (~> 0.7.0) + country_select (2.5.2) + countries (~> 1.2.0) + sort_alphabetical (~> 1.0) coveralls (0.7.0) multi_json (~> 1.3) rest-client @@ -197,6 +194,7 @@ GEM builder htmlentities (4.3.1) i18n (0.7.0) + i18n_data (0.7.0) inversion (0.12.3) loggability (~> 0.4) jquery-datatables-rails (2.2.3) @@ -211,6 +209,10 @@ GEM addressable (~> 2.3) letter_opener (1.2.0) launchy (~> 2.2) + letter_opener_web (1.3.0) + actionmailer (>= 3.2) + letter_opener (~> 1.0) + railties (>= 3.2) listen (2.7.2) celluloid (>= 0.15.2) celluloid-io (>= 0.15.0) @@ -329,16 +331,22 @@ GEM bundler (>= 1.3.0, < 2.0) railties (= 4.2.5.2) sprockets-rails + rails-assets-bootstrap (3.3.6) + rails-assets-jquery (>= 1.9.1, < 3) + rails-assets-bootstrap-markdown (2.10.0) + rails-assets-bootstrap (~> 3) rails-assets-date.format (1.2.3) - rails-assets-holderjs (2.9.1) - rails-assets-jquery (2.2.0) + rails-assets-holderjs (2.9.3) + rails-assets-jquery (2.2.1) rails-assets-jquery-smooth-scroll (1.7.2) rails-assets-jquery (>= 1.4.2) rails-assets-leaflet (0.7.7) + rails-assets-markdown (0.5.0) rails-assets-momentjs (2.11.2) rails-assets-spectrum (1.8.0) rails-assets-jquery (>= 1.7.2) rails-assets-tinycolor (1.3.0) + rails-assets-to-markdown (1.3.0) rails-assets-trianglify (0.4.0) rails-assets-waypoints (4.0.0) rails-deprecated_sanitizer (1.0.3) @@ -376,7 +384,7 @@ GEM rest-client (1.7.3) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) - rolify (3.4.0) + rolify (5.0.0) rspec (3.0.0) rspec-core (~> 3.0.0) rspec-expectations (~> 3.0.0) @@ -427,6 +435,8 @@ GEM simplecov-html (0.8.0) sixarm_ruby_unaccent (1.1.1) slop (3.6.0) + sort_alphabetical (1.0.2) + unicode_utils (>= 1.2.2) spring (1.6.3) spring-commands-rspec (1.0.4) spring (>= 0.9.1) @@ -458,6 +468,7 @@ GEM execjs (>= 0.3.0) json (>= 1.8.0) unicode-display_width (0.3.1) + unicode_utils (1.4.0) unobtrusive_flash (3.1.0) railties user_agent_parser (2.1.5) @@ -500,7 +511,7 @@ DEPENDENCIES capybara chart-js-rails cocoon - country_select! + country_select coveralls daemons database_cleaner @@ -518,6 +529,7 @@ DEPENDENCIES jquery-datatables-rails (~> 2.2.1) jquery-rails letter_opener + letter_opener_web mina money-rails mysql2 @@ -534,13 +546,16 @@ DEPENDENCIES prawn_rails quiet_assets rails (~> 4.2) + rails-assets-bootstrap-markdown! rails-assets-date.format! rails-assets-holderjs! rails-assets-jquery-smooth-scroll! rails-assets-leaflet! + rails-assets-markdown! rails-assets-momentjs! rails-assets-spectrum! rails-assets-tinycolor! + rails-assets-to-markdown! rails-assets-trianglify! rails-assets-waypoints! rails-observers diff --git a/INSTALL.md b/INSTALL.md index a44ac3a6..e9e031cd 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -26,27 +26,38 @@ We are using [Vagrant](https://www.vagrantup.com/) to create our development env vagrant up ``` -7. Start your OSEM rails app: +5. Start your OSEM rails app: ``` vagrant exec rails server -b 0.0.0.0 ``` -8. Check out your OSEM rails app: +6. Check out your OSEM rails app: You can access the app [localhost:3000](http://localhost:3000). Whatever you change in your cloned repository will have effect in the development environment. Sign up, the first user will be automatically assigned the admin role. -9. Changed something? Test your changes!: +7. Changed something? Test your changes!: ``` vagrant exec rake test ``` -10. Explore the development environment: +8. Explore the development environment: ``` vagrant ssh ``` +9. Or issue any standard `rails`/`rake`/`bundler` command by prepending `vagrant exec` + + ``` + vagrant exec rake db:migrate + ``` + +**Note**: We use [letter_opener](https://github.com/ryanb/letter_opener) in development environment. +However, letter_opener uses launchy to present the emails in your browser which doesn't work in combination with Vagrant. +Therefore we use [letter_open_web](https://github.com/fgrehm/letter_opener_web). +You can check out your mails by visiting [localhost:3000/letter_opener](http://localhost:3000/letter_opener) if you use Vagrant. + ### Run OSEM in production We recommend to run OSEM in production with [mod_passenger](https://www.phusionpassenger.com/download/#open_source) and the [apache web-server](https://www.apache.org/). There are tons of guides on how to deploy rails apps on various @@ -56,8 +67,8 @@ base operating systems. Check Google ;-) In order to use the OpenID feature you need to register your application with the providers (Google and Facebook) and enter their API keys in config/secrets.yml file, changing the existing sample values. -You can register as a devoloper with Google from https://code.google.com/apis/console#:access -You can register as a devoloper with Facebook from https://developers.facebook.com/, +You can register as a developer with Google from https://code.google.com/apis/console#:access +You can register as a developer with Facebook from https://developers.facebook.com/, by selecting from the top menu the option 'Apps' -> 'Create a New App' Unless you add the key and secret for each provider, you will not be able to see the image that diff --git a/README.md b/README.md index 6dff3394..36ffecfd 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,9 @@ Travis run its testing routine. If you want to run it locally just `bundle exec You can read through current enabled rules in `.rubocop.yml` file. Explanations of the defined [rules](http://rubydoc.info/github/bbatsov/rubocop/master/frames) can be found in modules [Cop::Lint](http://rubydoc.info/github/bbatsov/rubocop/master/Rubocop/Cop/Lint) and [Cop::Style](http://rubydoc.info/github/bbatsov/rubocop/master/Rubocop/Cop/Style). Additionally you can read through [community ruby style-guide](https://github.com/bbatsov/ruby-style-guide) to better understand core principles. +# Translation +Please refer to our [TRANSLATION guide] (TRANSLATION.md) + # Communication GitHub issues are the primary way for communicating about specific proposed changes to this project. If you have other questions feel free to subscribe to diff --git a/TRANSLATION.md b/TRANSLATION.md new file mode 100644 index 00000000..09723a76 --- /dev/null +++ b/TRANSLATION.md @@ -0,0 +1,53 @@ +# Translation +We are using [Transifex] (https://www.transifex.com/opensuse-community/osem/) to manage our translations. + +We are also using the _Live_ feature of Transifex. That means that all strings from OSEM instances are automatically collected and are available for translating. +>Automated collection only works if you use the API key (See at the end of this file) + +## 1. Translate + * Start translating: + + 1. Navigate to the [project's page] (https://www.transifex.com/organization/opensuse-community/dashboard/osem) + 2. Click **translation** button + 3. Select **language** + 4. Select **resource** (events.opensuse.org) + +Eg. Assuming you have signed up yourself as a translator for OSEM, to translate in German, for example, you go to: https://www.transifex.com/projects/p/osem/translate/#de_DE/eventsopensuseorg/31056760 + + * Request a new language + + If you want to translate OSEM into a language that does not already exist, you can request a new language from the Transifex interface. Your request will have to be approved by an admin of the OSEM project in Transifex. + +## 2. Publish translations + * How to make translations visible (if you have the proper access): + 1. Visit https://www.transifex.com/projects/p/osem/live/#en/events.opensuse.org + 2. Click **Publish** (from right sidebar menu) + 3. Select the language(s) + 4. Click **Publish** + + * How to request to publish translated strings + + After you make sure that you have properly reviewed the newly translated strings (they need to be marked as **reviewed** otherwise they won't go live), you can open a [new issue] (https://github.com/openSUSE/osem/issues/new) with the following information: + + Title: [Transifex] Publish translation for EN + + Content: Publish new reviewed strings for language EN + + (You substitute EN with the initials of the language you want to publish) + +> Note: We only publish **reviewed** translated strings + +## 3. Use translations +You can view OSEM in other languages by selecting the language you want from the language selector icon (bottom right corner). + +## 4. API key + When you run your own instance of OSEM, if you want to have the translations available you need to add the necessary [code] (http://docs.transifex.com/live/webmasters/#api) from Transifex: + ``` + :javascript + window.liveSettings = { + api_key: "cf866a61277842b39c897c5a0b5ec075", + picker: "bottom-right", + detectlang: true, + autocollect: true + }; +``` diff --git a/Vagrantfile b/Vagrantfile index 45c04c4c..827cb8ed 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -12,7 +12,7 @@ Vagrant.configure(2) do |config| # Every Vagrant development environment requires a box. You can search for # boxes at https://atlas.hashicorp.com/search. - config.vm.box = "webhippie/opensuse-13.2" + config.vm.box = "opensuse/openSUSE-42.1-x86_64" # Disable automatic box update checking. If you disable this, then # boxes will only be checked for updates when the user runs diff --git a/app/assets/javascripts/osem-datatables.js b/app/assets/javascripts/osem-datatables.js index 9e8d67e4..c2b3b75e 100644 --- a/app/assets/javascripts/osem-datatables.js +++ b/app/assets/javascripts/osem-datatables.js @@ -2,6 +2,7 @@ $(function () { $(document).ready(function() { $('.datatable').DataTable({ // ajax: ..., + stateSave: true, autoWidth: false, pagingType: 'full_numbers', "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]] diff --git a/app/assets/javascripts/osem-tickets.js b/app/assets/javascripts/osem-tickets.js index 51926a3f..ea99a349 100644 --- a/app/assets/javascripts/osem-tickets.js +++ b/app/assets/javascripts/osem-tickets.js @@ -22,4 +22,7 @@ $( document ).ready(function() { $('.quantity').change(function() { update_price($(this)); }); + $(function () { + $('[data-toggle="tooltip"]').tooltip() + }); }); diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 9a771225..d0447354 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -10,7 +10,7 @@ *= require osem-splash *= require font-awesome *= require osem-fonts - *= require bootstrap-markdown.min + *= require bootstrap-markdown *= require bootstrap-datetimepicker *= require leaflet *= require bootstrap3-switch diff --git a/app/assets/stylesheets/bootstrap-markdown.min.css b/app/assets/stylesheets/bootstrap-markdown.min.css deleted file mode 100644 index ac71e895..00000000 --- a/app/assets/stylesheets/bootstrap-markdown.min.css +++ /dev/null @@ -1 +0,0 @@ -.md-editor{display:block;border:1px solid #ddd}.md-editor>.md-header,.md-editor .md-footer{display:block;padding:6px 4px;background:#fff}.md-editor>.md-header{margin: 0;}.md-editor>.md-preview{background:#fff;border-top:1px dashed #ddd;border-bottom:1px dashed #ddd;min-height:10px;overflow:auto}.md-editor>textarea{font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:14px;outline:0;outline:thin dotted \9;margin:0;display:block;padding:0;width:100%;border:0;border-top:1px dashed #ddd;border-bottom:1px dashed #ddd;border-radius:0;box-shadow:none;background:#eee}.md-editor>textarea:focus{box-shadow:none;background:#fff}.md-editor.active{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,0.6)} \ No newline at end of file diff --git a/app/assets/stylesheets/osem.css.scss b/app/assets/stylesheets/osem.css.scss index 2f44ba19..58ffbc34 100644 --- a/app/assets/stylesheets/osem.css.scss +++ b/app/assets/stylesheets/osem.css.scss @@ -18,8 +18,6 @@ body { position: absolute; bottom: 0; width: 100%; - /* Set the fixed height of the footer here */ - height: 60px; background-color: #f5f5f5; .container { padding: 15px; diff --git a/app/controllers/admin/call_for_papers_controller.rb b/app/controllers/admin/call_for_papers_controller.rb index 657c2134..abd2a2c9 100644 --- a/app/controllers/admin/call_for_papers_controller.rb +++ b/app/controllers/admin/call_for_papers_controller.rb @@ -34,8 +34,8 @@ module Admin if @cfp.update_attributes(call_for_paper_params) Mailbot.delay.send_on_call_for_papers_dates_updated(@conference) if send_mail_on_cfp_dates_updated Mailbot.delay.send_on_schedule_public(@conference) if send_mail_on_schedule_public - redirect_to(admin_conference_call_for_paper_path(@conference.short_title), - notice: 'Call for papers successfully updated.') + redirect_to admin_conference_call_for_paper_path(@conference.short_title), + notice: 'Call for papers successfully updated.' else flash[:error] = "Updating call for papers failed. #{@cfp.errors.to_a.join('. ')}." render :new diff --git a/app/controllers/admin/campaigns_controller.rb b/app/controllers/admin/campaigns_controller.rb index a7ace352..74d0c0ad 100644 --- a/app/controllers/admin/campaigns_controller.rb +++ b/app/controllers/admin/campaigns_controller.rb @@ -12,8 +12,8 @@ module Admin @campaign.attributes = campaign_params if @conference.save - flash[:notice] = 'Campaign successfully created.' - redirect_to(admin_conference_campaigns_path(conference_id: @conference.short_title)) + redirect_to admin_conference_campaigns_path(conference_id: @conference.short_title), + notice: 'Campaign successfully created.' else flash[:error] = 'Campaign creation failed. ' + @campaign.errors.full_messages.to_sentence render action: 'new' @@ -26,8 +26,8 @@ module Admin def update if @campaign.update_attributes(campaign_params) - flash[:notice] = "Campaign '#{@campaign.name}' successfully updated." - redirect_to(admin_conference_campaigns_path(conference_id: @conference.short_title)) + redirect_to admin_conference_campaigns_path(conference_id: @conference.short_title), + notice: "Campaign '#{@campaign.name}' successfully updated." else flash[:error] = "Campaign update failed. #{@campaign.errors.full_messages.to_sentence}" render action: 'edit' @@ -36,12 +36,12 @@ module Admin def destroy if @campaign.destroy - flash[:notice] = "Campaign '#{@campaign.name}' successfully deleted." - redirect_to(admin_conference_campaigns_path(conference_id: @conference.short_title)) + redirect_to admin_conference_campaigns_path(conference_id: @conference.short_title), + notice: "Campaign '#{@campaign.name}' successfully deleted." else - flash[:error] = "Delete of Campaign for #{@conference.short_title} failed." \ + redirect_to admin_conference_campaigns_path(conference_id: @conference.short_title), + error: "Delete of Campaign for #{@conference.short_title} failed."\ "#{@campaign.errors.full_messages.join('. ')}." - redirect_to(admin_conference_campaigns_path(conference_id: @conference.short_title)) end end diff --git a/app/controllers/admin/cfps_controller.rb b/app/controllers/admin/cfps_controller.rb index 76d2f63a..fadf16fa 100644 --- a/app/controllers/admin/cfps_controller.rb +++ b/app/controllers/admin/cfps_controller.rb @@ -32,8 +32,8 @@ module Admin if @cfp.update_attributes(cfp_params) Mailbot.delay.send_on_cfps_dates_updates(@conference) if send_mail_on_cfp_dates_updates - redirect_to(admin_conference_program_cfp_path(@conference.short_title), - notice: 'Call for papers successfully updated.') + redirect_to admin_conference_program_cfp_path(@conference.short_title), + notice: 'Call for papers successfully updated.' else flash[:error] = "Updating call for papers failed. #{@cfp.errors.to_a.join('. ')}." render :new diff --git a/app/controllers/admin/commercials_controller.rb b/app/controllers/admin/commercials_controller.rb index be365e08..703423fe 100644 --- a/app/controllers/admin/commercials_controller.rb +++ b/app/controllers/admin/commercials_controller.rb @@ -18,8 +18,9 @@ module Admin redirect_to admin_conference_commercials_path, notice: 'Commercial was successfully created.' else - flash[:error] = "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." - redirect_to admin_conference_commercials_path + redirect_to admin_conference_commercials_path, + error: 'An error prohibited this Commercial from being saved: '\ + "#{@commercial.errors.full_messages.join('. ')}." end end @@ -29,8 +30,9 @@ module Admin redirect_to admin_conference_commercials_path, notice: 'Commercial was successfully updated.' else - flash[:error] = "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." - redirect_to admin_conference_commercials_path + redirect_to admin_conference_commercials_path, + error: 'An error prohibited this Commercial from being saved: '\ + "#{@commercial.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/conference_controller.rb b/app/controllers/admin/conference_controller.rb index 1c1045e9..9cdf0846 100644 --- a/app/controllers/admin/conference_controller.rb +++ b/app/controllers/admin/conference_controller.rb @@ -67,12 +67,11 @@ module Admin @conference = Conference.new(conference_params) if @conference.save - flash[:notice] = 'Conference was successfully created.' - # user that creates the conference becomes organizer of that conference current_user.add_role :organizer, @conference - redirect_to admin_conference_path(id: @conference.short_title) + redirect_to admin_conference_path(id: @conference.short_title), + notice: 'Conference was successfully created.' else flash[:error] = 'Could not create conference. ' + @conference.errors.full_messages.to_sentence render action: 'new' @@ -87,12 +86,12 @@ module Admin if @conference.update_attributes(conference_params) Mailbot.delay.conference_date_update_mail(@conference) if send_mail_on_conf_update - redirect_to(edit_admin_conference_path(id: @conference.short_title), - notice: 'Conference was successfully updated.') + redirect_to edit_admin_conference_path(id: @conference.short_title), + notice: 'Conference was successfully updated.' else - redirect_to(edit_admin_conference_path(id: short_title), - alert: 'Updating conference failed. ' \ - "#{@conference.errors.full_messages.join('. ')}.") + redirect_to edit_admin_conference_path(id: short_title), + error: 'Updating conference failed. ' \ + "#{@conference.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/difficulty_levels_controller.rb b/app/controllers/admin/difficulty_levels_controller.rb index 154fd3b6..7056507d 100644 --- a/app/controllers/admin/difficulty_levels_controller.rb +++ b/app/controllers/admin/difficulty_levels_controller.rb @@ -17,8 +17,8 @@ module Admin def create @difficulty_level = @conference.program.difficulty_levels.new(difficulty_level_params) if @difficulty_level.save - flash[:notice] = 'Difficulty level successfully created.' - redirect_to(admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title), + notice: 'Difficulty level successfully created.' else flash[:error] = "Creating difficulty level failed: #{@difficulty_level.errors.full_messages.join('. ')}." render :new @@ -27,8 +27,8 @@ module Admin def update if @difficulty_level.update_attributes(difficulty_level_params) - flash[:notice] = 'Difficulty level successfully updated.' - redirect_to(admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title), + notice: 'Difficulty level successfully updated.' else flash[:error] = "Update difficulty level failed: #{@difficulty_level.errors.full_messages.join('. ')}." render :edit @@ -37,12 +37,12 @@ module Admin def destroy if @difficulty_level.destroy - flash[:notice] = 'Difficulty level successfully deleted.' - redirect_to(admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title), + notice: 'Difficulty level successfully deleted.' else - flash[:error] = 'Deleting difficulty level type failed! ' \ - "#{@difficulty_level.errors.full_messages.join('. ')}." - redirect_to(admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_difficulty_levels_path(conference_id: @conference.short_title), + error: 'Deleting difficulty level type failed! '\ + "#{@difficulty_level.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/emails_controller.rb b/app/controllers/admin/emails_controller.rb index 799918fa..203a74e0 100644 --- a/app/controllers/admin/emails_controller.rb +++ b/app/controllers/admin/emails_controller.rb @@ -5,9 +5,9 @@ module Admin def update @conference.email_settings.update_attributes(email_params) - redirect_to(admin_conference_emails_path( + redirect_to admin_conference_emails_path( @conference.short_title), - notice: 'Settings have been successfully updated.') + notice: 'Settings have been successfully updated.' end def index diff --git a/app/controllers/admin/event_types_controller.rb b/app/controllers/admin/event_types_controller.rb index 18077040..b8b81148 100644 --- a/app/controllers/admin/event_types_controller.rb +++ b/app/controllers/admin/event_types_controller.rb @@ -15,8 +15,8 @@ module Admin def create @event_type = @conference.program.event_types.new(event_type_params) if @event_type.save - flash[:notice] = 'Event type successfully created.' - redirect_to(admin_conference_program_event_types_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_event_types_path(conference_id: @conference.short_title), + notice: 'Event type successfully created.' else flash[:error] = "Creating event type failed: #{@event_type.errors.full_messages.join('. ')}." render :new @@ -25,8 +25,8 @@ module Admin def update if @event_type.update_attributes(event_type_params) - flash[:notice] = 'Event type successfully updated.' - redirect_to(admin_conference_program_event_types_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_event_types_path(conference_id: @conference.short_title), + notice: 'Event type successfully updated.' else flash[:error] = "Update event type failed: #{@event_type.errors.full_messages.join('. ')}." render :edit @@ -35,12 +35,12 @@ module Admin def destroy if @event_type.destroy - flash[:notice] = 'Event type successfully deleted.' - redirect_to(admin_conference_program_event_types_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_event_types_path(conference_id: @conference.short_title), + notice: 'Event type successfully deleted.' else - flash[:error] = 'Destroying event type failed! ' \ - "#{@event_type.errors.full_messages.join('. ')}." - redirect_to(admin_conference_program_event_types_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_event_types_path(conference_id: @conference.short_title), + error: 'Destroying event type failed! '\ + "#{@event_type.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index c131943a..e60d3991 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -94,7 +94,9 @@ module Admin end def comment - comment = Comment.build_from(@event, current_user.id, comment_params) + comment = Comment.new(comment_params) + comment.commentable = @event + comment.user_id = current_user.id comment.save! if !params[:parent].nil? comment.move_to_child_of(params[:parent]) @@ -182,8 +184,9 @@ module Admin def get_event @event = @conference.program.events.find(params[:id]) if !@event - redirect_to(admin_conference_program_events_path(conference_id: @conference.short_title), - alert: 'Error! Could not find event!') && return + redirect_to admin_conference_program_events_path(conference_id: @conference.short_title), + error: 'Error! Could not find event!' + return end @event end diff --git a/app/controllers/admin/lodgings_controller.rb b/app/controllers/admin/lodgings_controller.rb index 000f0310..5e94d53a 100644 --- a/app/controllers/admin/lodgings_controller.rb +++ b/app/controllers/admin/lodgings_controller.rb @@ -13,8 +13,8 @@ module Admin def create @lodging = @conference.lodgings.new(lodging_params) if @lodging.save - redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title), - notice: 'Lodging successfully created.') + redirect_to admin_conference_lodgings_path(conference_id: @conference.short_title), + notice: 'Lodging successfully created.' else flash[:error] = "Creating Lodging failed: #{@lodging.errors.full_messages.join('. ')}." render :new @@ -25,8 +25,8 @@ module Admin def update if @lodging.update_attributes(lodging_params) - redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title), - notice: 'Lodging successfully updated.') + redirect_to admin_conference_lodgings_path(conference_id: @conference.short_title), + notice: 'Lodging successfully updated.' else flash[:error] = "Update Lodging failed: #{@lodging.errors.full_messages.join('. ')}." render :edit @@ -35,12 +35,12 @@ module Admin def destroy if @lodging.destroy - redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title), - notice: 'Lodging successfully deleted.') + redirect_to admin_conference_lodgings_path(conference_id: @conference.short_title), + notice: 'Lodging successfully deleted.' else - redirect_to(admin_conference_lodgings_path(conference_id: @conference.short_title), + redirect_to admin_conference_lodgings_path(conference_id: @conference.short_title), error: 'Deleting lodging failed.' \ - "#{@lodging.errors.full_messages.join('. ')}.") + "#{@lodging.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/programs_controller.rb b/app/controllers/admin/programs_controller.rb index d527a8aa..0e3e5e2c 100644 --- a/app/controllers/admin/programs_controller.rb +++ b/app/controllers/admin/programs_controller.rb @@ -15,8 +15,8 @@ module Admin if @program.update_attributes(program_params) # Mailbot.delay.send_on_schedule_public(@conference) if send_mail_on_schedule_public - redirect_to(admin_conference_program_path(@conference.short_title), - notice: 'The program was successfully updated.') + redirect_to admin_conference_program_path(@conference.short_title), + notice: 'The program was successfully updated.' else flash[:error] = "Updating program failed. #{@program.errors.to_a.join('. ')}." render :new diff --git a/app/controllers/admin/questions_controller.rb b/app/controllers/admin/questions_controller.rb index 590182c3..1a805a32 100644 --- a/app/controllers/admin/questions_controller.rb +++ b/app/controllers/admin/questions_controller.rb @@ -32,8 +32,7 @@ module Admin if @conference.save format.html { redirect_to admin_conference_questions_path, notice: 'Question was successfully created.' } else - flash[:error] = "Oops, couldn't save Question. #{@question.errors.full_messages.join('. ')}" - format.html { redirect_to admin_conference_questions_path } + format.html { redirect_to admin_conference_questions_path, error: "Oops, couldn't save Question. #{@question.errors.full_messages.join('. ')}" } end end end @@ -41,16 +40,16 @@ module Admin # GET questions/1/edit def edit if @question.global - redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), alert: 'Sorry, you cannot edit global questions. Create a new one.') + redirect_to admin_conference_questions_path(conference_id: @conference.short_title), error: 'Sorry, you cannot edit global questions. Create a new one.' end end # PUT questions/1 def update if @question.update_attributes(question_params) - redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Question '#{@question.title}' for #{@conference.short_title} successfully updated.") + redirect_to admin_conference_questions_path(conference_id: @conference.short_title), notice: "Question '#{@question.title}' for #{@conference.short_title} successfully updated." else - redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Update of questions for #{@conference.short_title} failed. #{@question.errors.full_messages.join('. ')}") + redirect_to admin_conference_questions_path(conference_id: @conference.short_title), notice: "Update of questions for #{@conference.short_title} failed. #{@question.errors.full_messages.join('. ')}" end end @@ -58,9 +57,9 @@ module Admin def update_conference authorize! :update, Question.new(conference_id: @conference.id) if @conference.update_attributes(conference_params) - redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Questions for #{@conference.short_title} successfully updated.") + redirect_to admin_conference_questions_path(conference_id: @conference.short_title), notice: "Questions for #{@conference.short_title} successfully updated." else - redirect_to(admin_conference_questions_path(conference_id: @conference.short_title), notice: "Update of questions for #{@conference.short_title} failed.") + redirect_to admin_conference_questions_path(conference_id: @conference.short_title), notice: "Update of questions for #{@conference.short_title} failed." end end diff --git a/app/controllers/admin/registrations_controller.rb b/app/controllers/admin/registrations_controller.rb index 72021e80..38b54ac1 100644 --- a/app/controllers/admin/registrations_controller.rb +++ b/app/controllers/admin/registrations_controller.rb @@ -31,8 +31,8 @@ module Admin redirect_to admin_conference_registrations_path(@conference.short_title), notice: "Deleted registration for #{@user.name}!" else - redirect_to(admin_conference_registrations_path(@conference.short_title), - error: 'You must be an admin to delete a registration.') + redirect_to admin_conference_registrations_path(@conference.short_title), + error: 'You must be an admin to delete a registration.' end end diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb index d99a1b96..1e045b74 100644 --- a/app/controllers/admin/roles_controller.rb +++ b/app/controllers/admin/roles_controller.rb @@ -21,8 +21,8 @@ module Admin role_name = @role.name if @role.update_attributes(role_params) - flash[:notice] = 'Successfully updated role ' + @role.name - redirect_to admin_conference_role_path(@conference.short_title, @role.name) + redirect_to admin_conference_role_path(@conference.short_title, @role.name), + notice: 'Successfully updated role ' + @role.name else @role.name = role_name flash[:error] = 'Could not update role! ' + @role.errors.full_messages.to_sentence @@ -35,14 +35,16 @@ module Admin state = user_params[:state] unless user - flash[:error] = 'Could not find user. Please provide a valid email!' - redirect_to(admin_conference_role_path(@conference.short_title, @role.name)) && return + redirect_to admin_conference_role_path(@conference.short_title, @role.name), + error: 'Could not find user. Please provide a valid email!' + return end # The conference must have at least 1 organizer if @role.name == 'organizer' && state == 'false' && @role.users.count == 1 - flash[:error] = 'The conference must have at least 1 organizer!' - redirect_to(admin_conference_role_path(@conference.short_title, @role.name)) && return + redirect_to admin_conference_role_path(@conference.short_title, @role.name), + error: 'The conference must have at least 1 organizer!' + return end # Remove user diff --git a/app/controllers/admin/rooms_controller.rb b/app/controllers/admin/rooms_controller.rb index 2fda73d6..70cceaf5 100644 --- a/app/controllers/admin/rooms_controller.rb +++ b/app/controllers/admin/rooms_controller.rb @@ -15,8 +15,8 @@ module Admin def create @room = @venue.rooms.new(room_params) if @room.save - flash[:notice] = 'Room successfully created.' - redirect_to(admin_conference_venue_rooms_path(conference_id: @conference.short_title)) + redirect_to admin_conference_venue_rooms_path(conference_id: @conference.short_title), + notice: 'Room successfully created.' else flash[:error] = "Creating Room failed: #{@room.errors.full_messages.join('. ')}." render :new @@ -25,8 +25,8 @@ module Admin def update if @room.update_attributes(room_params) - flash[:notice] = 'Room successfully updated.' - redirect_to(admin_conference_venue_rooms_path(conference_id: @conference.short_title)) + redirect_to admin_conference_venue_rooms_path(conference_id: @conference.short_title), + notice: 'Room successfully updated.' else flash[:error] = "Update Room failed: #{@room.errors.full_messages.join('. ')}." render :edit @@ -35,11 +35,11 @@ module Admin def destroy if @room.destroy - flash[:notice] = 'Room successfully deleted.' - redirect_to(admin_conference_venue_rooms_path(conference_id: @conference.short_title)) + redirect_to admin_conference_venue_rooms_path(conference_id: @conference.short_title), + notice: 'Room successfully deleted.' else - flash[:error] = "Destroying room failed! #{@room.errors.full_messages.join('. ')}." - redirect_to(admin_conference_venue_rooms_path(conference_id: @conference.short_title)) + redirect_to admin_conference_venue_rooms_path(conference_id: @conference.short_title), + error: "Destroying room failed! #{@room.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/splashpages_controller.rb b/app/controllers/admin/splashpages_controller.rb index 9a0f26ff..2745cc8b 100644 --- a/app/controllers/admin/splashpages_controller.rb +++ b/app/controllers/admin/splashpages_controller.rb @@ -35,7 +35,7 @@ module Admin if @splashpage.destroy redirect_to admin_conference_splashpage_path, notice: 'Splashpage was successfully destroyed.' else - redirect_to admin_conference_splashpage_path, alert: 'An error prohibited this Splashpage from being destroyed: '\ + redirect_to admin_conference_splashpage_path, error: 'An error prohibited this Splashpage from being destroyed: '\ "#{@splashpage.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/sponsors_controller.rb b/app/controllers/admin/sponsors_controller.rb index 1aeb1b3d..b7164900 100644 --- a/app/controllers/admin/sponsors_controller.rb +++ b/app/controllers/admin/sponsors_controller.rb @@ -16,8 +16,8 @@ module Admin def create @sponsor = @conference.sponsors.new(sponsor_params) if @sponsor.save - redirect_to(admin_conference_sponsors_path(conference_id: @conference.short_title), - notice: 'Sponsor successfully created.') + redirect_to admin_conference_sponsors_path(conference_id: @conference.short_title), + notice: 'Sponsor successfully created.' else flash[:error] = "Creating sponsor failed: #{@sponsor.errors.full_messages.join('. ')}." render :new @@ -26,9 +26,9 @@ module Admin def update if @sponsor.update_attributes(sponsor_params) - redirect_to(admin_conference_sponsors_path( + redirect_to admin_conference_sponsors_path( conference_id: @conference.short_title), - notice: 'Sponsor successfully updated.') + notice: 'Sponsor successfully updated.' else flash[:error] = "Update sponsor failed: #{@sponsor.errors.full_messages.join('. ')}." render :edit @@ -37,12 +37,12 @@ module Admin def destroy if @sponsor.destroy - redirect_to(admin_conference_sponsors_path(conference_id: @conference.short_title), - notice: 'Sponsor successfully deleted.') + redirect_to admin_conference_sponsors_path(conference_id: @conference.short_title), + notice: 'Sponsor successfully deleted.' else - redirect_to(admin_conference_sponsors_path(conference_id: @conference.short_title), + redirect_to admin_conference_sponsors_path(conference_id: @conference.short_title), error: 'Deleting sponsor failed! ' \ - "#{@sponsor.errors.full_messages.join('. ')}.") + "#{@sponsor.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/sponsorship_levels_controller.rb b/app/controllers/admin/sponsorship_levels_controller.rb index 82d20e4e..e78f8746 100644 --- a/app/controllers/admin/sponsorship_levels_controller.rb +++ b/app/controllers/admin/sponsorship_levels_controller.rb @@ -16,8 +16,8 @@ module Admin def create @sponsorship_level = @conference.sponsorship_levels.new(sponsorship_level_params) if @sponsorship_level.save - redirect_to(admin_conference_sponsorship_levels_path(conference_id: @conference.short_title), - notice: 'Sponsorship level successfully created.') + redirect_to admin_conference_sponsorship_levels_path(conference_id: @conference.short_title), + notice: 'Sponsorship level successfully created.' else flash[:error] = "Creating Sponsorship Level failed: #{@sponsorship_level.errors.full_messages.join('. ')}." render :new @@ -26,9 +26,9 @@ module Admin def update if @sponsorship_level.update_attributes(sponsorship_level_params) - redirect_to(admin_conference_sponsorship_levels_path( + redirect_to admin_conference_sponsorship_levels_path( conference_id: @conference.short_title), - notice: 'Sponsorship level successfully updated.') + notice: 'Sponsorship level successfully updated.' else flash[:error] = "Update Sponsorship level failed: #{@sponsorship_level.errors.full_messages.join('. ')}." render :edit @@ -37,23 +37,23 @@ module Admin def destroy if @sponsorship_level.destroy - redirect_to(admin_conference_sponsorship_levels_path(conference_id: @conference.short_title), - notice: 'Sponsorship level successfully deleted.') + redirect_to admin_conference_sponsorship_levels_path(conference_id: @conference.short_title), + notice: 'Sponsorship level successfully deleted.' else - redirect_to(admin_conference_sponsorship_levels_path(conference_id: @conference.short_title), + redirect_to admin_conference_sponsorship_levels_path(conference_id: @conference.short_title), error: 'Deleting sponsorship level failed! ' \ - "#{@sponsorship_level.errors.full_messages.join('. ')}.") + "#{@sponsorship_level.errors.full_messages.join('. ')}." end end def up @sponsorship_level.move_higher - redirect_to(admin_conference_sponsorship_levels_path(conference_id: @conference.short_title)) + redirect_to admin_conference_sponsorship_levels_path(conference_id: @conference.short_title) end def down @sponsorship_level.move_lower - redirect_to(admin_conference_sponsorship_levels_path(conference_id: @conference.short_title)) + redirect_to admin_conference_sponsorship_levels_path(conference_id: @conference.short_title) end private diff --git a/app/controllers/admin/targets_controller.rb b/app/controllers/admin/targets_controller.rb index 6f73dc0a..f1ffcc66 100644 --- a/app/controllers/admin/targets_controller.rb +++ b/app/controllers/admin/targets_controller.rb @@ -3,9 +3,7 @@ module Admin load_and_authorize_resource :conference, find_by: :short_title load_and_authorize_resource :target, through: :conference - def index - authorize! :update, Target.new(conference_id: @conference.id) - end + def index; end def new @target = @conference.targets.new @@ -14,8 +12,8 @@ module Admin def create @target = @conference.targets.new(target_params) if @target.save(target_params) - redirect_to(admin_conference_targets_path(conference_id: @conference.short_title), - notice: 'Target successfully created.') + redirect_to admin_conference_targets_path(conference_id: @conference.short_title), + notice: 'Target successfully created.' else flash[:error] = "Creating target failed: #{@target.errors.full_messages.join('. ')}." render :new @@ -26,8 +24,8 @@ module Admin def update if @target.update_attributes(target_params) - redirect_to(admin_conference_targets_path(conference_id: @conference.short_title), - notice: 'Target successfully updated.') + redirect_to admin_conference_targets_path(conference_id: @conference.short_title), + notice: 'Target successfully updated.' else flash[:error] = "Target update failed: #{@target.errors.full_messages.join('. ')}." render :edit @@ -36,12 +34,12 @@ module Admin def destroy if @target.destroy - redirect_to(admin_conference_targets_path(conference_id: @conference.short_title), - notice: 'Target successfully destroyed.') + redirect_to admin_conference_targets_path(conference_id: @conference.short_title), + notice: 'Target successfully destroyed.' else - redirect_to(admin_conference_targets_path(conference_id: @conference.short_title), - error: 'Target was successfully destroyed.' \ - "#{@target.errors.full_messages.join('. ')}.") + redirect_to admin_conference_targets_path(conference_id: @conference.short_title), + error: "Could not delete target for #{@conference.title}: "\ + "#{@target.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/tickets_controller.rb b/app/controllers/admin/tickets_controller.rb index ec131971..fb17fc59 100644 --- a/app/controllers/admin/tickets_controller.rb +++ b/app/controllers/admin/tickets_controller.rb @@ -14,8 +14,8 @@ module Admin def create @ticket = @conference.tickets.new(ticket_params) if @ticket.save(ticket_params) - redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title), - notice: 'Ticket successfully created.') + redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), + notice: 'Ticket successfully created.' else flash[:error] = "Creating Ticket failed: #{@ticket.errors.full_messages.join('. ')}." render :new @@ -26,8 +26,8 @@ module Admin def update if @ticket.update_attributes(ticket_params) - redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title), - notice: 'Ticket successfully updated.') + redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), + notice: 'Ticket successfully updated.' else flash[:error] = "Ticket update failed: #{@ticket.errors.full_messages.join('. ')}." render :edit @@ -36,12 +36,12 @@ module Admin def destroy if @ticket.destroy - redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title), - notice: 'Ticket successfully destroyed.') + redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), + notice: 'Ticket successfully destroyed.' else - redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title), + redirect_to admin_conference_tickets_path(conference_id: @conference.short_title), error: 'Ticket was successfully destroyed.' \ - "#{@ticket.errors.full_messages.join('. ')}.") + "#{@ticket.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/tracks_controller.rb b/app/controllers/admin/tracks_controller.rb index 68777913..b7cbf8ec 100644 --- a/app/controllers/admin/tracks_controller.rb +++ b/app/controllers/admin/tracks_controller.rb @@ -20,8 +20,8 @@ module Admin def create @track = @program.tracks.new(track_params) if @track.save - flash[:notice] = 'Track successfully created.' - redirect_to(admin_conference_program_tracks_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), + notice: 'Track successfully created.' else flash[:error] = "Creating Track failed: #{@track.errors.full_messages.join('. ')}." render :new @@ -32,8 +32,8 @@ module Admin def update if @track.update_attributes(track_params) - flash[:notice] = 'Track successfully updated.' - redirect_to(admin_conference_program_tracks_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), + notice: 'Track successfully updated.' else flash[:error] = "Track update failed: #{@track.errors.full_messages.join('. ')}." render :edit @@ -42,11 +42,11 @@ module Admin def destroy if @track.destroy - flash[:notice] = 'Track successfully deleted.' - redirect_to(admin_conference_program_tracks_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), + notice: 'Track successfully deleted.' else - flash[:error] = "Track couldn't be deleted. #{@track.errors.full_messages.join('. ')}." - redirect_to(admin_conference_program_tracks_path(conference_id: @conference.short_title)) + redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title), + error: "Track couldn't be deleted. #{@track.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index af74d3e6..dbd54ffd 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -30,7 +30,7 @@ module Admin if @user.update_attributes(user_params) redirect_to admin_users_path, notice: "Updated #{@user.name} (#{@user.email})!" + message else - redirect_to admin_users_path, alert: "Could not update #{@user.name} (#{@user.email}). #{@user.errors.full_messages.join('. ')}." + redirect_to admin_users_path, error: "Could not update #{@user.name} (#{@user.email}). #{@user.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/venues_controller.rb b/app/controllers/admin/venues_controller.rb index f9efbbe1..903357dc 100644 --- a/app/controllers/admin/venues_controller.rb +++ b/app/controllers/admin/venues_controller.rb @@ -24,8 +24,8 @@ module Admin def update if @venue.update_attributes(venue_params) - redirect_to(admin_conference_venue_path(conference_id: @conference.short_title), - notice: 'Venue was successfully updated.') + redirect_to admin_conference_venue_path(conference_id: @conference.short_title), + notice: 'Venue was successfully updated.' else flash[:error] = "Update venue failed: #{@venue.errors.full_messages.join('. ')}." render :edit @@ -36,7 +36,7 @@ module Admin if @venue.destroy redirect_to admin_conference_venue_path, notice: 'Venue was successfully deleted.' else - redirect_to admin_conference_venue_path, alert: 'An error prohibited this Venue from being destroyed: '\ + redirect_to admin_conference_venue_path, error: 'An error prohibited this Venue from being destroyed: '\ "#{@venue.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/admin/volunteers_controller.rb b/app/controllers/admin/volunteers_controller.rb index 33b5e0de..ec6d7ac7 100644 --- a/app/controllers/admin/volunteers_controller.rb +++ b/app/controllers/admin/volunteers_controller.rb @@ -24,9 +24,9 @@ module Admin def update if @conference.update_attributes(conference_params) - redirect_to(admin_conference_volunteers_info_path(conference_id: params[:conference_id]), notice: 'Volunteering options were successfully updated.') + redirect_to admin_conference_volunteers_info_path(conference_id: params[:conference_id]), notice: 'Volunteering options were successfully updated.' else - redirect_to(admin_conference_volunteers_info_path(conference_id: params[:conference_id]), alert: "Volunteering options update failed: #{@conference.errors.full_messages.join '. '}") + redirect_to admin_conference_volunteers_info_path(conference_id: params[:conference_id]), error: "Volunteering options update failed: #{@conference.errors.full_messages.join '. '}" end end diff --git a/app/controllers/api/v1/rooms_controller.rb b/app/controllers/api/v1/rooms_controller.rb index 7ffd67c8..fe70fcfe 100644 --- a/app/controllers/api/v1/rooms_controller.rb +++ b/app/controllers/api/v1/rooms_controller.rb @@ -5,13 +5,11 @@ module Api respond_to :json def index - if params[:conference_id].blank? - rooms = Room.all + if @conference + respond_with @conference.venue ? @conference.venue.rooms : Room.none else - conference = Conference.find_by_guid(params[:conference_id]) - rooms = conference.venue.rooms if conference.venue + respond_with Room.all end - respond_with rooms end end end diff --git a/app/controllers/api/v1/tracks_controller.rb b/app/controllers/api/v1/tracks_controller.rb index f477cc0c..879713cf 100644 --- a/app/controllers/api/v1/tracks_controller.rb +++ b/app/controllers/api/v1/tracks_controller.rb @@ -5,7 +5,7 @@ module Api respond_to :json def index - @conference ? (tracks = @conference.tracks) : (tracks = Track.all) + tracks = @conference ? @conference.program.tracks : Track.all respond_with tracks end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a0d87498..51dc6772 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,5 +1,6 @@ class ApplicationController < ActionController::Base include ApplicationHelper + add_flash_types :error protect_from_forgery with: :exception before_filter :get_conferences before_filter :store_location @@ -52,16 +53,15 @@ class ApplicationController < ActionController::Base rescue_from IChainRecordNotFound do Rails.logger.debug('IChain Record was not Unique!') sign_out(current_user) - flash[:error] = 'Your E-Mail adress is already registered at OSEM. Please contact the admin if you want to attach your openSUSE Account to OSEM!' - redirect_to root_path + redirect_to root_path, + error: 'Your E-Mail adress is already registered at OSEM. Please contact the admin if you want to attach your openSUSE Account to OSEM!' end rescue_from UserDisabled do Rails.logger.debug('User is disabled!') sign_out(current_user) mail = User.admin.first ? User.admin.first.email : 'the admin!' - flash[:error] = "This User is disabled. Please contact #{mail}!" - redirect_to User.ichain_logout_url + redirect_to User.ichain_logout_url, error: "This User is disabled. Please contact #{mail}!" end def not_found diff --git a/app/controllers/commercials_controller.rb b/app/controllers/commercials_controller.rb index c36feedc..69a235a4 100644 --- a/app/controllers/commercials_controller.rb +++ b/app/controllers/commercials_controller.rb @@ -11,8 +11,8 @@ class CommercialsController < ApplicationController redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), notice: 'Commercial was successfully created.' else - flash[:error] = "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." - redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content') + redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), + error: "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." end end @@ -21,8 +21,8 @@ class CommercialsController < ApplicationController redirect_to edit_conference_program_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), notice: 'Commercial was successfully updated.' else - flash[:error] = "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." - redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content') + redirect_to edit_conference_proposal_path(conference_id: @conference.short_title, id: @event.id, anchor: 'commercials-content'), + error: "An error prohibited this Commercial from being saved: #{@commercial.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/conference_controller.rb b/app/controllers/conference_controller.rb index 64e55e6a..16aa382f 100644 --- a/app/controllers/conference_controller.rb +++ b/app/controllers/conference_controller.rb @@ -1,4 +1,5 @@ class ConferenceController < ApplicationController + protect_from_forgery with: :null_session before_filter :respond_to_options load_and_authorize_resource find_by: :short_title load_resource :program, through: :conference, singleton: true, except: :index diff --git a/app/controllers/conference_registrations_controller.rb b/app/controllers/conference_registrations_controller.rb index c9d7d216..b1ff2539 100644 --- a/app/controllers/conference_registrations_controller.rb +++ b/app/controllers/conference_registrations_controller.rb @@ -21,7 +21,7 @@ class ConferenceRegistrationsController < ApplicationController end if @conference.registration_limit_exceeded? - redirect_to root_path, alert: "Sorry, registration limit exceeded for #{@conference.title}" + redirect_to root_path, error: "Sorry, registration limit exceeded for #{@conference.title}" return end @@ -60,11 +60,12 @@ class ConferenceRegistrationsController < ApplicationController sign_in(@registration.user) end - flash[:notice] = 'You are now registered and will be receiving E-Mail notifications.' if @conference.tickets.any? && !current_user.supports?(@conference) - redirect_to conference_tickets_path(@conference.short_title) + redirect_to conference_tickets_path(@conference.short_title), + notice: 'You are now registered and will be receiving E-Mail notifications.' else - redirect_to conference_conference_registrations_path(@conference.short_title) + redirect_to conference_conference_registrations_path(@conference.short_title), + notice: 'You are now registered and will be receiving E-Mail notifications.' end else flash[:error] = "Could not create your registration for #{@conference.title}: "\ @@ -89,8 +90,8 @@ class ConferenceRegistrationsController < ApplicationController redirect_to root_path, notice: "You are not registered for #{@conference.title} anymore!" else - redirect_to root_path, - error: "Could not update your registration for #{@conference.title}: "\ + redirect_to conference_conference_registrations_path(@conference.short_title), + error: "Could not delete your registration for #{@conference.title}: "\ "#{@registration.errors.full_messages.join('. ')}." end end @@ -100,8 +101,8 @@ class ConferenceRegistrationsController < ApplicationController def set_registration @registration = Registration.find_by(conference: @conference, user: current_user) if !@registration - flash[:alert] = "Can't find a registration for #{@conference.title} for you. Please register." - redirect_to new_conference_conference_registrations_path(@conference.short_title) + redirect_to new_conference_conference_registrations_path(@conference.short_title), + error: "Can't find a registration for #{@conference.title} for you. Please register." end end diff --git a/app/controllers/proposal_controller.rb b/app/controllers/proposal_controller.rb index 95042af5..cac68d4a 100644 --- a/app/controllers/proposal_controller.rb +++ b/app/controllers/proposal_controller.rb @@ -2,9 +2,11 @@ class ProposalController < ApplicationController before_filter :authenticate_user!, except: [:show, :new, :create] load_resource :conference, find_by: :short_title load_resource :program, through: :conference, singleton: true - load_and_authorize_resource :event, parent: false, through: :program + load_and_authorize_resource :event, parent: false, through: :program, except: [:new, :create] def index + @event = @program.events.new + @event.event_users.new(user: current_user, event_role: 'submitter') @events = current_user.proposals(@conference) end @@ -14,6 +16,9 @@ class ProposalController < ApplicationController end def new + @event = @program.events.new + @event.event_users.new(user: current_user, event_role: 'submitter') if current_user + authorize! :new, @event @user = User.new @url = conference_program_proposal_index_path(@conference.short_title) end @@ -46,6 +51,7 @@ class ProposalController < ApplicationController event_role: 'submitter') @event.event_users.new(user: current_user, event_role: 'speaker') + authorize! :new, @event unless @event.save flash[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}" @@ -55,8 +61,7 @@ class ProposalController < ApplicationController ahoy.track 'Event submission', title: 'New submission' - flash[:notice] = 'Proposal was successfully submitted.' - redirect_to conference_program_proposal_index_path(@conference.short_title) + redirect_to conference_program_proposal_index_path(@conference.short_title), notice: 'Proposal was successfully submitted.' end def update @@ -69,8 +74,8 @@ class ProposalController < ApplicationController return end - redirect_to(conference_program_proposal_index_path(conference_id: @conference.short_title), - notice: 'Proposal was successfully updated.') + redirect_to conference_program_proposal_index_path(conference_id: @conference.short_title), + notice: 'Proposal was successfully updated.' end def destroy @@ -80,13 +85,13 @@ class ProposalController < ApplicationController begin @event.withdraw rescue Transitions::InvalidTransition - redirect_to(:back, error: "Event can't be withdrawn") + redirect_to :back, error: "Event can't be withdrawn" return end @event.save(validate: false) - redirect_to(conference_program_proposal_index_path(conference_id: @conference.short_title), - notice: 'Proposal was successfully withdrawn.') + redirect_to conference_program_proposal_index_path(conference_id: @conference.short_title), + notice: 'Proposal was successfully withdrawn.' end def confirm @@ -96,7 +101,7 @@ class ProposalController < ApplicationController begin @event.confirm! rescue Transitions::InvalidTransition - redirect_to(:back, error: "Event can't be confirmed") + redirect_to :back, error: "Event can't be confirmed" return end @@ -107,11 +112,11 @@ class ProposalController < ApplicationController end if @conference.user_registered?(current_user) - redirect_to(conference_program_proposal_index_path(@conference.short_title), - notice: 'The proposal was confirmed.') + redirect_to conference_program_proposal_index_path(@conference.short_title), + notice: 'The proposal was confirmed.' else - redirect_to(new_conference_conference_registrations_path(conference_id: @conference.short_title), - alert: 'The proposal was confirmed. Please register to attend the conference.') + redirect_to new_conference_conference_registrations_path(conference_id: @conference.short_title), + alert: 'The proposal was confirmed. Please register to attend the conference.' end end @@ -122,8 +127,8 @@ class ProposalController < ApplicationController begin @event.restart rescue Transitions::InvalidTransition - redirect_to(conference_program_proposal_index_path(conference_id: @conference.short_title), - error: "The proposal can't be re-submitted.") + redirect_to conference_program_proposal_index_path(conference_id: @conference.short_title), + error: "The proposal can't be re-submitted." return end @@ -133,14 +138,14 @@ class ProposalController < ApplicationController return end - redirect_to(conference_program_proposal_index_path(conference_id: @conference.short_title), - notice: "The proposal was re-submitted. The #{@conference.short_title} organizers will review it again.") + redirect_to conference_program_proposal_index_path(conference_id: @conference.short_title), + notice: "The proposal was re-submitted. The #{@conference.short_title} organizers will review it again." end private def event_params - params.require(:event).permit(:title, :subtitle, :event_type_id, :abstract, :description, :require_registration, :difficulty_level_id) + params.require(:event).permit(:title, :subtitle, :track_id, :event_type_id, :abstract, :description, :require_registration, :difficulty_level_id) end def user_params diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 6d5b7cdf..351f9e9d 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -6,22 +6,18 @@ class SubscriptionsController < ApplicationController def create @subscription = current_user.subscriptions.build(conference_id: @conference.id) if @subscription.save! - flash[:notice] = "You have been subscribed to receive email notifications for #{@conference.short_title}." - redirect_to root_path + redirect_to root_path, notice: "You have been subscribed to receive email notifications for #{@conference.short_title}." else - flash[:error] = subscription.errors.full_messages.to_sentence - redirect_to root_path + redirect_to root_path, error: subscription.errors.full_messages.to_sentence end end def destroy @subscription = current_user.subscriptions.find_by(conference_id: @conference.id) if @subscription.destroy - flash[:notice] = "You have been unsubscribed and now you will not be receiving email notifications for #{@conference.short_title}." - redirect_to root_path + redirect_to root_path, notice: "You have been unsubscribed and now you will not be receiving email notifications for #{@conference.short_title}." else - flash[:error] = @subscription.errors.full_messages.to_sentence - redirect_to root_path + redirect_to root_path, error: @subscription.errors.full_messages.to_sentence end end end diff --git a/app/controllers/ticket_purchases_controller.rb b/app/controllers/ticket_purchases_controller.rb index 395f09ce..d7c476ee 100644 --- a/app/controllers/ticket_purchases_controller.rb +++ b/app/controllers/ticket_purchases_controller.rb @@ -14,7 +14,7 @@ class TicketPurchasesController < ApplicationController end else redirect_to conference_conference_registrations_path(@conference.short_title), - alert: "Oops, something went wrong with your purchase! #{message}" + error: "Oops, something went wrong with your purchase! #{message}" end end @@ -25,7 +25,7 @@ class TicketPurchasesController < ApplicationController notice: 'Ticket successfully deleted.' else redirect_to conference_conference_registrations_path(@conference.short_title), - alert: 'An error prohibited deleting your purchase! '\ + error: 'An error prohibited deleting your purchase! '\ "#{@ticket_purchases.errors.full_messages.join('. ')}." end end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index ec42b3e2..cf6eb6a8 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -28,8 +28,8 @@ module Users openid.save! sign_in user - flash[:notice] = "#{user.email} signed in successfully with #{provider}" - redirect_to request.env['omniauth.origin'] || root_path + redirect_to request.env['omniauth.origin'] || root_path, + notice: "#{user.email} signed in successfully with #{provider}" rescue => e flash[:error] = e.message redirect_back_or_to new_user_registration_path diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ce2fde95..b5216afe 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -181,9 +181,9 @@ module ApplicationHelper # Same as redirect_to(:back) if there is a valid HTTP referer, otherwise redirect_to() def redirect_back_or_to(options = {}, response_status = {}) if request.env['HTTP_REFERER'] - redirect_to(:back) + redirect_to :back else - redirect_to(options, response_status) + redirect_to options, response_status end end diff --git a/app/mailers/mailbot.rb b/app/mailers/mailbot.rb index 5c378e09..1c772eff 100644 --- a/app/mailers/mailbot.rb +++ b/app/mailers/mailbot.rb @@ -9,7 +9,7 @@ class Mailbot < ActionMailer::Base end def acceptance_mail(event) - conference = event.conference + conference = event.program.conference person = event.submitter build_email(conference, person.email, @@ -18,7 +18,7 @@ class Mailbot < ActionMailer::Base end def rejection_mail(event) - conference = event.conference + conference = event.program.conference person = event.submitter build_email(conference, person.email, @@ -27,7 +27,7 @@ class Mailbot < ActionMailer::Base end def confirm_reminder_mail(event) - conference = event.conference + conference = event.program.conference person = event.submitter build_email(conference, person.email, @@ -83,7 +83,7 @@ class Mailbot < ActionMailer::Base def send_notification_email_for_comment(comment) @comment = comment @event = @comment.commentable - @conference = @event.conference + @conference = @event.program.conference recipients = User.comment_notifiable(@conference) # with scope recipients.each do |user| @user = user diff --git a/app/models/ability.rb b/app/models/ability.rb index 16313da9..68f4ad8a 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -76,8 +76,12 @@ class Ability can :manage, Event do |event| event.users.include?(user) end - # can create an event until the last day of a conference - can :create, Event, program_id: Conference.where('end_date >= ?', Date.today).map { |conference| conference.program.id}.compact + + # cannot create an event if program does not have open cfp + cannot [:new, :create], Event do |event| + user_inclusion = event.event_users.map { |event_user| event_user.user.id }.compact.include? user.id + !event.program.cfp_open? || !event.new_record? || !user_inclusion + end # can manage the commercials of their own events can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id) diff --git a/app/models/comment.rb b/app/models/comment.rb index 40d69240..c699f18a 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -41,7 +41,11 @@ class Comment < ActiveRecord::Base } scope :find_since_last_login, lambda { |user| - where(created_at: (user.last_sign_in_at..Time.now)).order(created_at: :desc) + if user.last_sign_in_at + where(created_at: (user.last_sign_in_at..Time.now)).order(created_at: :desc) + else + none + end } # Helper class method to look up a commentable object # given the commentable class name and id diff --git a/app/models/contact.rb b/app/models/contact.rb index 3e45200a..4f904eeb 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -9,7 +9,7 @@ class Contact < ActiveRecord::Base format: URI::regexp(%w(http https)), allow_blank: true def has_social_media? - return true if !facebook.blank? || !twitter.blank? || !googleplus.blank? || !instagram.blank? + return true if !facebook.blank? || !twitter.blank? || !googleplus.blank? || !instagram.blank? || !email.blank? false end end diff --git a/app/models/email_settings.rb b/app/models/email_settings.rb index be1fc1cb..7ce4bb82 100644 --- a/app/models/email_settings.rb +++ b/app/models/email_settings.rb @@ -38,14 +38,14 @@ class EmailSettings < ActiveRecord::Base if event h['eventtitle'] = event.title - h['proposalslink'] = Rails.application.routes.url_helpers.conference_proposal_index_url( + h['proposalslink'] = Rails.application.routes.url_helpers.conference_program_proposal_index_url( conference.short_title, host: CONFIG['url_for_emails']) end h end def generate_event_mail(event, event_template) - values = get_values(event.conference, event.submitter, event) + values = get_values(event.program.conference, event.submitter, event) parse_template(event_template, values) end diff --git a/app/models/event.rb b/app/models/event.rb index 4711d60a..518825bb 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -190,6 +190,7 @@ class Event < ActiveRecord::Base commercials: self.commercials.any?, biography: !self.submitter.biography.blank?, subtitle: !self.subtitle.blank?, + track: !self.track.blank?, difficulty_level: !self.difficulty_level.blank?, title: true, abstract: true diff --git a/app/models/registration.rb b/app/models/registration.rb index 2f2d5c68..d02fa8bb 100644 --- a/app/models/registration.rb +++ b/app/models/registration.rb @@ -29,6 +29,7 @@ class Registration < ActiveRecord::Base validate :registration_limit_not_exceed, on: :create after_create :set_week, :subscribe_to_conference, :send_registration_mail + after_destroy :destroy_purchased_tickets def week created_at.strftime('%W').to_i @@ -36,6 +37,11 @@ class Registration < ActiveRecord::Base private + def destroy_purchased_tickets + ticket_purchased = TicketPurchase.where(conference_id: conference_id, user_id: user.id) + ticket_purchased.destroy_all + end + def subscribe_to_conference Subscription.create(conference_id: conference.id, user_id: user.id) end diff --git a/app/models/role.rb b/app/models/role.rb index 77ffac2b..07c5b29e 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -1,6 +1,6 @@ class Role < ActiveRecord::Base belongs_to :resource, polymorphic: true - has_and_belongs_to_many :users + has_and_belongs_to_many :users, join_table: :users_roles scopify diff --git a/app/models/target.rb b/app/models/target.rb index a1b496a2..ea91b38a 100644 --- a/app/models/target.rb +++ b/app/models/target.rb @@ -64,7 +64,7 @@ class Target < ActiveRecord::Base 'unit' => unit, 'created_at' => created_at, 'progress' => progress, - 'days_left' => days_left, + 'days_left' => days_left } result end diff --git a/app/models/ticket.rb b/app/models/ticket.rb index d3b3d48b..54f5c3d7 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -18,7 +18,7 @@ class Ticket < ActiveRecord::Base end def paid?(user) - ticket_purchases.where(user_id: user.id, paid: false).count == 0 + ticket_purchases.find_by(user: user, paid: true).present? end def quantity_bought_by(user) @@ -48,11 +48,19 @@ class Ticket < ActiveRecord::Base result ? result : Money.new(0, 'USD') end + def tickets_sold + ticket_purchases.sum(:quantity) + end + + def tickets_turnover + tickets_sold * price + end + private def tickets_of_conference_have_same_currency unless Ticket.where(conference_id: conference_id).all?{|t| t.price_currency == self.price_currency } - errors.add(:price_currency, 'Currency is different from the exist ticktes of this conference.') + errors.add(:price_currency, 'is different from the existing tickets of this conference.') end end end diff --git a/app/models/user.rb b/app/models/user.rb index f31beb29..d548853e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,7 +29,6 @@ class User < ActiveRecord::Base devise(*devise_modules) - has_and_belongs_to_many :roles has_many :openids attr_accessor :login @@ -54,6 +53,10 @@ class User < ActiveRecord::Base }, presence: true + def name + self[:name] || username + end + def subscribed? conference self.subscriptions.find_by(conference_id: conference.id).present? end @@ -75,7 +78,9 @@ class User < ActiveRecord::Base raise UserDisabled if user && user.is_disabled if user - user.update_attributes(email: attributes[:email]) + user.update_attributes(email: attributes[:email], + last_sign_in_at: user.current_sign_in_at, + current_sign_in_at: Time.current) else begin user = create!(username: username, email: attributes[:email]) diff --git a/app/serializers/conference_serializer.rb b/app/serializers/conference_serializer.rb index 1bed92d9..9ab51c3f 100644 --- a/app/serializers/conference_serializer.rb +++ b/app/serializers/conference_serializer.rb @@ -4,47 +4,51 @@ class ConferenceSerializer < ActiveModel::Serializer :date_range, :revision def difficulty_levels - object.difficulty_levels.map do |difficulty_level| { id: difficulty_level.id, - title: difficulty_level.title, - description: difficulty_level.description + object.program.difficulty_levels.map do |difficulty_level| { id: difficulty_level.id, + title: difficulty_level.title, + description: difficulty_level.description } end end def event_types - object.event_types.map do |event_type| { id: event_type.id, - title: event_type.title, - length: event_type.length, - description: event_type.description + object.program.event_types.map do |event_type| { id: event_type.id, + title: event_type.title, + length: event_type.length, + description: event_type.description } end end def rooms - object.rooms.includes(:events).map do |room| { id: room.id, - size: room.size, - events: room.events.map do |event| { guid: event.title, - title: event.title, - subtitle: event.subtitle, - abstract: event.abstract, - description: event.description, - is_highlight: event.is_highlight, - require_registration: event.require_registration, - start_time: event.start_time, - event_type_id: event.event_type.id, - difficulty_level_id: event.difficulty_level_id, - track_id: event.track_id, - speaker_names: event.speaker_names - } - end - } + if object.venue + object.venue.rooms.includes(:events).map do |room| { id: room.id, + size: room.size, + events: room.events.map do |event| { guid: event.title, + title: event.title, + subtitle: event.subtitle, + abstract: event.abstract, + description: event.description, + is_highlight: event.is_highlight, + require_registration: event.require_registration, + start_time: event.start_time, + event_type_id: event.event_type.id, + difficulty_level_id: event.difficulty_level_id, + track_id: event.track_id, + speaker_names: event.speaker_names + } + end + } + end + else + [] end end def tracks - object.tracks.map do |track| { 'id' => track.id, - 'name' => track.name, - 'description' => track.description + object.program.tracks.map do |track| { 'id' => track.id, + 'name' => track.name, + 'description' => track.description } end end diff --git a/app/views/admin/events/_nested_comments.html.haml b/app/views/admin/events/_nested_comments.html.haml index de0044d7..0c97a3f0 100644 --- a/app/views/admin/events/_nested_comments.html.haml +++ b/app/views/admin/events/_nested_comments.html.haml @@ -6,10 +6,10 @@ %div %a.pull-right.comment-reply-link{href: "#"} Reply .comment-reply - = form_tag "#{comment_admin_conference_program_event_path(@conference.short_title, comment.commentable_id)}", method: :post do + = semantic_form_for :comment, url: "#{comment_admin_conference_program_event_path(@conference.short_title, comment.commentable_id)}", method: :post do |f| + = f.input :body %input{name: "parent", type: "hidden", value: "#{comment.id}"} %input{name: "authenticity_token", type: "hidden", value: "#{form_authenticity_token}"} - %textarea{name: "comment"} %button.btn.btn-primary.pull-right{name: "button", type: "submit"} Add Reply - comment.children.each do |child| = render "nested_comments", comment: child, padding: 50 diff --git a/app/views/admin/events/_proposal.html.haml b/app/views/admin/events/_proposal.html.haml index 4e51b312..5c66f543 100644 --- a/app/views/admin/events/_proposal.html.haml +++ b/app/views/admin/events/_proposal.html.haml @@ -147,10 +147,11 @@ %ul.media %div .row-fluid - = form_tag(comment_admin_conference_program_event_path(@conference.short_title, @event.id), method: :post) do - = text_area_tag(:comment, '') - = submit_tag 'Add Comment', class: 'btn btn-primary pull-right' + = semantic_form_for :comment, url: comment_admin_conference_program_event_path(@conference.short_title, @event.id), method: :post do |f| + = f.input :body + = f.submit 'Add Comment', class: 'btn btn-primary pull-right' + %br %br - @comments.each do |comment| %div - = render "nested_comments", comment: comment, padding: 0 + = render partial: 'nested_comments', locals: { comment: comment, padding: 0} diff --git a/app/views/admin/programs/show.html.haml b/app/views/admin/programs/show.html.haml index feff0205..c73f5f9b 100644 --- a/app/views/admin/programs/show.html.haml +++ b/app/views/admin/programs/show.html.haml @@ -53,7 +53,7 @@ .row .col-md-12.text-right - - if can? :edit, @progam + - if can? :edit, @program = link_to edit_admin_conference_program_path(@conference.short_title), class: 'btn btn-primary' do Edit - if can? :destroy, @program diff --git a/app/views/admin/roles/index.html.haml b/app/views/admin/roles/index.html.haml index d88dc22f..c6e4c773 100644 --- a/app/views/admin/roles/index.html.haml +++ b/app/views/admin/roles/index.html.haml @@ -7,7 +7,7 @@ The available roles for the conference .col-md-12 - %table.table.table-bordered.table-striped.table-hover.datatable#roles + %table.table.table-bordered.table-striped.table-hover#roles %thead %th ID %th Name diff --git a/app/views/admin/tickets/index.html.haml b/app/views/admin/tickets/index.html.haml index acf6915f..2a2bac6d 100644 --- a/app/views/admin/tickets/index.html.haml +++ b/app/views/admin/tickets/index.html.haml @@ -10,9 +10,9 @@ %table.table.table-hover#tickets %thead %th Title - %th Description %th Price %th Sold + %th Turnover %th Actions %tbody - @conference.tickets.each do |ticket| @@ -20,12 +20,12 @@ %td = link_to(admin_conference_ticket_path(@conference.short_title, ticket.id)) do = ticket.title - %td - = truncate(ticket.description) %td = humanized_money_with_symbol ticket.price %td - = ticket.buyers.count + = ticket.tickets_sold + %td + = humanized_money_with_symbol ticket.tickets_turnover %td .btn-group = link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id), diff --git a/app/views/admin/tickets/show.html.haml b/app/views/admin/tickets/show.html.haml index f92b03b6..a672ff2c 100644 --- a/app/views/admin/tickets/show.html.haml +++ b/app/views/admin/tickets/show.html.haml @@ -2,10 +2,11 @@ .col-md-12 .page-header %h1 - = @ticket.title - Ticket - %small - = humanized_money_with_symbol @ticket.price + %div{"data-placement" => "left", "data-toggle" => "tooltip", :title => @ticket.description} + = @ticket.title + Ticket + %small + = humanized_money_with_symbol @ticket.price %p.text-muted People who bought this ticket .row diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 5f7b4d91..7752a41e 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -6,7 +6,7 @@ - if @users = "(#{@users.length})" .row - .col-md-12 + .col-md-12.table-responsive %table.table.table-striped.table-bordered.table-hover.datatable %thead %th ID diff --git a/app/views/conference/_social_media.html.haml b/app/views/conference/_social_media.html.haml index eefcbd0c..29eac688 100644 --- a/app/views/conference/_social_media.html.haml +++ b/app/views/conference/_social_media.html.haml @@ -17,3 +17,6 @@ - unless @conference.contact.googleplus.blank? = link_to "#{ @conference.contact.googleplus }" do %i.fa.fa-google-plus-square.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/proposal/_form.html.haml b/app/views/proposal/_form.html.haml index 7f8ec638..563cf957 100644 --- a/app/views/proposal/_form.html.haml +++ b/app/views/proposal/_form.html.haml @@ -1,45 +1,42 @@ -.container - .row - .col-md-12 - .tabbable - %ul.nav.nav-tabs - %li.active - = link_to 'Proposal', '#proposal-content', 'data-toggle' => 'tab' - %li - = link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab' - .tab-content - #proposal-content.tab-pane.active - = render 'proposal/proposal_form' - #commercials-content.tab-pane - %p.text-muted - You can add commercials for your proposal. These commercials will be displayed on the - = link_to 'public proposal page.', conference_program_proposal_path(@conference.short_title, @event) - If you don't add a commercial, the conference commercial will be displayed! - - if can? :create, @event.commercials.new - .row - .col-md-6 - #resource-content - #resource-placeholder{ style: 'background-color:#d3d3d3; float: left; width: 400px; height: 250px; margin: 5px; border-width: 1px; border-style: solid; border-color: rgba(0,0,0,.2);' } - .row - .col-md-6 - = semantic_form_for(@event.commercials.build, url: conference_program_proposal_commercials_path(conference_id: @conference.short_title, proposal_id: @event)) do |f| - = f.input :url, label: 'URL', as: :string, input_html: { required: 'required', type: 'url' }, - hint: 'Just paste the url of your video/photo provider. Currently supported: YouTube, Vimeo, SpeakerDeck, SlideShare, Instagram, Flickr.' - = f.action :submit, as: :button, button_html: { class: 'btn btn-primary pull-right', disabled: true } - %hr - - @event.commercials.each_slice(3) do |slice| - .row - - slice.each do |commercial| - - if commercial.persisted? - .col-md-4 - .thumbnail - .flexvideo{ id: "resource-content-#{commercial.id}"} - = render partial: 'shared/media_item', locals: { commercial: commercial } - .caption - - if can? :update, commercial - = semantic_form_for commercial, url: conference_program_proposal_commercial_path(conference_id: @conference.short_title, proposal_id: @event, id: commercial) do |f| - = f.input :url, label: 'URL', as: :string, input_html: { id: "commercial_url_#{commercial.id}", required: 'required', type: 'url' } - = f.action :submit, as: :button, button_html: { class: 'btn btn-success' }, label: 'Update' - - if can? :destroy, commercial - = link_to 'Delete', conference_program_proposal_commercial_path(@conference.short_title, @event.id, commercial.id), - :method => :delete, :data => { :confirm => 'Are you sure?' }, class: 'btn btn-danger' +.tabbable + %ul.nav.nav-tabs + %li.active + = link_to 'Proposal', '#proposal-content', 'data-toggle' => 'tab' + %li + = link_to 'Commercials', '#commercials-content', 'data-toggle' => 'tab' + .tab-content + #proposal-content.tab-pane.active + = render 'proposal/proposal_form' + #commercials-content.tab-pane + %p.text-muted + You can add commercials for your proposal. These commercials will be displayed on the + = link_to 'public proposal page.', conference_program_proposal_path(@conference.short_title, @event) + If you don't add a commercial, the conference commercial will be displayed! + - if can? :create, @event.commercials.new + .row + .col-md-6 + #resource-content + #resource-placeholder{ style: 'background-color:#d3d3d3; float: left; width: 400px; height: 250px; margin: 5px; border-width: 1px; border-style: solid; border-color: rgba(0,0,0,.2);' } + .row + .col-md-6 + = semantic_form_for(@event.commercials.build, url: conference_program_proposal_commercials_path(conference_id: @conference.short_title, proposal_id: @event)) do |f| + = f.input :url, label: 'URL', as: :string, input_html: { required: 'required', type: 'url' }, + hint: 'Just paste the url of your video/photo provider. Currently supported: YouTube, Vimeo, SpeakerDeck, SlideShare, Instagram, Flickr.' + = f.action :submit, as: :button, button_html: { class: 'btn btn-primary pull-right', disabled: true } + %hr + - @event.commercials.each_slice(3) do |slice| + .row + - slice.each do |commercial| + - if commercial.persisted? + .col-md-4 + .thumbnail + .flexvideo{ id: "resource-content-#{commercial.id}"} + = render partial: 'shared/media_item', locals: { commercial: commercial } + .caption + - if can? :update, commercial + = semantic_form_for commercial, url: conference_program_proposal_commercial_path(conference_id: @conference.short_title, proposal_id: @event, id: commercial) do |f| + = f.input :url, label: 'URL', as: :string, input_html: { id: "commercial_url_#{commercial.id}", required: 'required', type: 'url' } + = f.action :submit, as: :button, button_html: { class: 'btn btn-success' }, label: 'Update' + - if can? :destroy, commercial + = link_to 'Delete', conference_program_proposal_commercial_path(@conference.short_title, @event.id, commercial.id), + :method => :delete, :data => { :confirm => 'Are you sure?' }, class: 'btn btn-danger' diff --git a/app/views/proposal/_proposal_form.html.haml b/app/views/proposal/_proposal_form.html.haml index d30ad689..5addd7d2 100644 --- a/app/views/proposal/_proposal_form.html.haml +++ b/app/views/proposal/_proposal_form.html.haml @@ -4,6 +4,11 @@ = f.input :subtitle, as: :string + - if @program.tracks.any? + = f.input :track_id, as: :select, + collection: @program.tracks.map {|track| ["#{track.name}", track.id] }, + include_blank: true + = f.input :event_type_id, as: :select, collection: @conference.program.event_types.map {|type| ["#{type.title} - #{show_time(type.length)}", type.id, data: { min_words: type.minimum_abstract_length, max_words: type.maximum_abstract_length }]}, diff --git a/app/views/proposal/_tooltip.html.haml b/app/views/proposal/_tooltip.html.haml index aced298b..dd626209 100644 --- a/app/views/proposal/_tooltip.html.haml +++ b/app/views/proposal/_tooltip.html.haml @@ -3,33 +3,21 @@ %li{'class'=>class_for_todo(progress_status['registered'])} %span{'class'=>icon_for_todo(progress_status['registered'])} - if progress_status['registered'] - = link_to 'Edit your registration', edit_conference_conference_registrations_path(event.program.conference.short_title) + = link_to 'Register to the conference', edit_conference_conference_registrations_path(event.program.conference.short_title) - else = link_to 'Register to the conference', new_conference_conference_registrations_path(event.program.conference.short_title) - %li{'class'=>class_for_todo(progress_status['biography'])} %span{'class'=>icon_for_todo(progress_status['biography'])} - - if progress_status['biography'] - = link_to 'Edit your biography', edit_user_path(event.submitter) - - else - = link_to 'Fill out your biography', edit_user_path(event.submitter) - + = link_to 'Fill out your biography', edit_user_path(event.submitter) %li{'class'=>class_for_todo(progress_status['subtitle'])} %span{'class'=>icon_for_todo(progress_status['subtitle'])} - - if progress_status['subtitle'] - = link_to 'Edit the subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event) - - else - = link_to 'Add a subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event) - + = link_to 'Add a subtitle', edit_conference_program_proposal_path(event.program.conference.short_title, event) %li{'class'=>class_for_todo(progress_status['commercials'])} %span{'class'=>icon_for_todo(progress_status['commercials'])} - - if progress_status['commercials'] - = link_to 'Edit the commercials', edit_conference_program_proposal_path(event.program.conference.short_title, event, anchor: 'commercials-content') - - else - = link_to 'Add a commercial', edit_conference_program_proposal_path(event.program.conference.short_title, event, anchor: 'commercials-content') + = link_to 'Add a commercial', edit_conference_program_proposal_path(event.program.conference.short_title, event, anchor: 'commercials-content') + %li{'class'=>class_for_todo(progress_status['track'])} + %span{'class'=>icon_for_todo(progress_status['track'])} + = link_to 'Add a track', edit_conference_program_proposal_path(event.program.conference.short_title, event) %li{'class'=>class_for_todo(progress_status['difficulty_level'])} %span{'class'=>icon_for_todo(progress_status['difficulty_level'])} - - if progress_status['difficulty_level'] - = link_to 'Change the difficulty level', edit_conference_program_proposal_path(event.program.conference.short_title, event) - - else - = link_to 'Add a difficulty level', edit_conference_program_proposal_path(event.program.conference.short_title, event) + = link_to 'Add a difficulty level', edit_conference_program_proposal_path(event.program.conference.short_title, event) diff --git a/app/views/proposal/edit.html.haml b/app/views/proposal/edit.html.haml index 86842fe7..1f65d485 100644 --- a/app/views/proposal/edit.html.haml +++ b/app/views/proposal/edit.html.haml @@ -1 +1,4 @@ -= render 'form' \ No newline at end of file +.container + .row + .col-md-12 + = render 'form' diff --git a/app/views/proposal/index.html.haml b/app/views/proposal/index.html.haml index 0d87cc45..f1d0d5bd 100644 --- a/app/views/proposal/index.html.haml +++ b/app/views/proposal/index.html.haml @@ -67,12 +67,13 @@ %small.text-muted = event.event_type.title = "(#{event.event_type.length} min)" + = "in #{event.track.name}" if event.track - if event.state == 'confirmed' && event.require_registration == true , Pre-registered: #{pre_registered(event).count} %td.col-md-2{style: "padding:20px 8px 20px 8px;"} - = link_to 'Complete your todo list', 'javascript: void(0)', "type"=>"button", "data-trigger"=>"focus", "data-toggle"=>"popover", "title"=>"Your todo list", "data-content"=>"#{render partial: 'tooltip', locals: { event: event} }" + = link_to 'Complete your proposal', 'javascript: void(0)', "type"=>"button", "data-trigger"=>"focus", "data-toggle"=>"popover", "title"=>"Your todo list", "data-content"=>"#{render partial: 'tooltip', locals: { event: event} }" - progress_percentage = event.calculate_progress .progress @@ -99,5 +100,5 @@ class: 'btn btn-default', id: "edit_proposal_#{event.id}" .row .col-md-12 - - if can? :create, @program.events.new + - if can? :create, @event = link_to "New Proposal", new_conference_program_proposal_path(@conference.short_title), :class => "btn btn-success pull-right" diff --git a/app/views/proposal/show.html.haml b/app/views/proposal/show.html.haml index d14d5acb..909de4c2 100644 --- a/app/views/proposal/show.html.haml +++ b/app/views/proposal/show.html.haml @@ -7,9 +7,10 @@ %br %small = @event.subtitle - = link_to "Schedule", schedule_conference_path(@conference.short_title), :class =>"btn btn-success pull-right" + - if can? :schedule, @conference + = link_to "Schedule", schedule_conference_path(@conference.short_title), :class =>"btn btn-success pull-right" - if can? :edit, @event - = link_to "Edit", edit_admin_conference_program_event_path(@conference.short_title, @event), :class => "btn btn-mini btn-primary pull-right" + = link_to "Edit", edit_conference_program_proposal_path(@conference.short_title, @event), :class => "btn btn-mini btn-primary pull-right" .row .col-md-3 %p diff --git a/config/environments/development.rb b/config/environments/development.rb index e1610a27..14a74d8a 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,8 +1,8 @@ Osem::Application.configure do # Settings specified here will take precedence over those in config/application.rb - # Use letter_opener - config.action_mailer.delivery_method = :letter_opener + # Use letter_opener_web for Vagrant (launchy won't work) + config.action_mailer.delivery_method = ENV['USER'] == 'vagrant' ? :letter_opener_web : :letter_opener # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development diff --git a/config/initializers/rolify.rb b/config/initializers/rolify.rb index 30651dd0..14460ef6 100644 --- a/config/initializers/rolify.rb +++ b/config/initializers/rolify.rb @@ -4,5 +4,5 @@ Rolify.configure do |config| # Dynamic shortcuts for User class (user.is_admin? like methods). Default is: false # Enable this feature _after_ running rake db:migrate as it relies on the roles table - config.use_dynamic_shortcuts + # config.use_dynamic_shortcuts end diff --git a/config/routes.rb b/config/routes.rb index 1df57cbe..b22775e5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,6 +10,11 @@ Osem::Application.routes.draw do path: 'accounts' end + # Use letter_opener_web to open mails in browser (e.g. necessary for Vagrant) + if Rails.env.development? + mount LetterOpenerWeb::Engine, at: "/letter_opener" + end + resources :users, except: [:new, :index, :create, :destroy] namespace :admin do @@ -22,7 +27,6 @@ Osem::Application.routes.draw do resource :schedule, only: [:show, :update] get 'commercials/render_commercial' => 'commercials#render_commercial' resources :commercials, only: [:index, :create, :update, :destroy] - get '/stats' => 'stats#index' get '/dietary_choices' => 'dietchoices#show', as: 'dietary_list' patch '/dietary_choices' => 'dietchoices#update', as: 'dietary_update' get '/volunteers_list' => 'volunteers#show' @@ -102,6 +106,7 @@ Osem::Application.routes.draw do end end + # TODO: change conference_registrations to singular resource resource :conference_registrations, path: 'register' resources :tickets, only: [:index] resources :ticket_purchases, only: [:create, :destroy] diff --git a/db/migrate/20160226133808_rename_roles_users_to_users_roles.rb b/db/migrate/20160226133808_rename_roles_users_to_users_roles.rb new file mode 100644 index 00000000..6f8424b8 --- /dev/null +++ b/db/migrate/20160226133808_rename_roles_users_to_users_roles.rb @@ -0,0 +1,5 @@ +class RenameRolesUsersToUsersRoles < ActiveRecord::Migration + def change + rename_table :roles_users, :users_roles + end +end diff --git a/db/schema.rb b/db/schema.rb index 2ff3289c..69f1f7e3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,13 +11,13 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160201221411) do +ActiveRecord::Schema.define(version: 20160226133808) do create_table "ahoy_events", force: :cascade do |t| t.uuid "visit_id", limit: 16 - t.integer "user_id" - t.string "name" - t.text "properties" + t.integer "user_id", limit: 4 + t.string "name", limit: 255 + t.text "properties", limit: 65535 t.datetime "time" end @@ -26,43 +26,43 @@ ActiveRecord::Schema.define(version: 20160201221411) do add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id" create_table "answers", force: :cascade do |t| - t.string "title" - t.datetime "created_at" - t.datetime "updated_at" + t.string "title", limit: 255 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "campaigns", force: :cascade do |t| - t.integer "conference_id" - t.string "name" - t.string "utm_source" - t.string "utm_medium" - t.string "utm_term" - t.string "utm_content" - t.string "utm_campaign" + t.integer "conference_id", limit: 4 + t.string "name", limit: 255 + t.string "utm_source", limit: 255 + t.string "utm_medium", limit: 255 + t.string "utm_term", limit: 255 + t.string "utm_content", limit: 255 + t.string "utm_campaign", limit: 255 t.datetime "created_at" t.datetime "updated_at" end create_table "cfps", force: :cascade do |t| - t.date "start_date", null: false - t.date "end_date", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.integer "program_id" + t.date "start_date", null: false + t.date "end_date", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "program_id", limit: 4 end create_table "comments", force: :cascade do |t| - t.string "title", limit: 50, default: "" - t.text "body" - t.integer "commentable_id" - t.string "commentable_type" - t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" - t.string "subject" - t.integer "parent_id" - t.integer "lft" - t.integer "rgt" + t.string "title", limit: 50, default: "" + t.text "body", limit: 16777215 + t.integer "commentable_id", limit: 4 + t.string "commentable_type", limit: 255 + t.integer "user_id", limit: 4 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "subject", limit: 255 + t.integer "parent_id", limit: 4 + t.integer "lft", limit: 4 + t.integer "rgt", limit: 4 end add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id" @@ -70,69 +70,69 @@ ActiveRecord::Schema.define(version: 20160201221411) do add_index "comments", ["user_id"], name: "index_comments_on_user_id" create_table "commercials", force: :cascade do |t| - t.string "commercial_id" - t.string "commercial_type" - t.integer "commercialable_id" - t.string "commercialable_type" + t.string "commercial_id", limit: 255 + t.string "commercial_type", limit: 255 + t.integer "commercialable_id", limit: 4 + t.string "commercialable_type", limit: 255 t.datetime "created_at" t.datetime "updated_at" - t.string "url" + t.string "url", limit: 255 end create_table "conferences", force: :cascade do |t| - t.string "guid", null: false - t.string "title", null: false - t.string "short_title", null: false - t.string "timezone", null: false - t.string "html_export_path" - t.date "start_date", null: false - t.date "end_date", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.string "logo_file_name" - t.string "logo_content_type" - t.integer "logo_file_size" + t.string "guid", limit: 255, null: false + t.string "title", limit: 255, null: false + t.string "short_title", limit: 255, null: false + t.string "timezone", limit: 255, null: false + t.string "html_export_path", limit: 255 + t.date "start_date", null: false + t.date "end_date", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "logo_file_name", limit: 255 + t.string "logo_content_type", limit: 255 + t.integer "logo_file_size", limit: 4 t.datetime "logo_updated_at" - t.boolean "use_dietary_choices", default: false - t.integer "revision" - t.boolean "use_vpositions", default: false - t.boolean "use_vdays", default: false - t.boolean "use_difficulty_levels", default: false + t.boolean "use_dietary_choices", default: false + t.integer "revision", limit: 4 + t.boolean "use_vpositions", default: false + t.boolean "use_vdays", default: false + t.boolean "use_difficulty_levels", default: false t.boolean "use_volunteers" - t.string "color" - t.text "events_per_week" - t.text "description" - t.integer "registration_limit", default: 0 + t.string "color", limit: 255 + t.text "events_per_week", limit: 65535 + t.text "description", limit: 65535 + t.integer "registration_limit", limit: 4, default: 0 end create_table "conferences_questions", id: false, force: :cascade do |t| - t.integer "conference_id" - t.integer "question_id" + t.integer "conference_id", limit: 4 + t.integer "question_id", limit: 4 end create_table "contacts", force: :cascade do |t| - t.string "social_tag" - t.string "email" - t.string "facebook" - t.string "googleplus" - t.string "twitter" - t.string "instagram" - t.integer "conference_id" + t.string "social_tag", limit: 255 + t.string "email", limit: 255 + t.string "facebook", limit: 255 + t.string "googleplus", limit: 255 + t.string "twitter", limit: 255 + t.string "instagram", limit: 255 + t.integer "conference_id", limit: 4 t.datetime "created_at" t.datetime "updated_at" - t.string "sponsor_email" + t.string "sponsor_email", limit: 255 end create_table "delayed_jobs", force: :cascade do |t| - t.integer "priority", default: 0, null: false - t.integer "attempts", default: 0, null: false - t.text "handler", null: false - t.text "last_error" + t.integer "priority", limit: 4, default: 0, null: false + t.integer "attempts", limit: 4, default: 0, null: false + t.text "handler", limit: 65535, null: false + t.text "last_error", limit: 65535 t.datetime "run_at" t.datetime "locked_at" t.datetime "failed_at" - t.string "locked_by" - t.string "queue" + t.string "locked_by", limit: 255 + t.string "queue", limit: 255 t.datetime "created_at" t.datetime "updated_at" end @@ -140,178 +140,178 @@ ActiveRecord::Schema.define(version: 20160201221411) do add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority" create_table "dietary_choices", force: :cascade do |t| - t.integer "conference_id" - t.string "title", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.integer "conference_id", limit: 4 + t.string "title", limit: 255, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "difficulty_levels", force: :cascade do |t| - t.string "title" - t.text "description" - t.string "color" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "program_id" + t.string "title", limit: 255 + t.text "description", limit: 65535 + t.string "color", limit: 255 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "program_id", limit: 4 end create_table "email_settings", force: :cascade do |t| - t.integer "conference_id" - t.boolean "send_on_registration", default: false - t.boolean "send_on_accepted", default: false - t.boolean "send_on_rejected", default: false - t.boolean "send_on_confirmed_without_registration", default: false - t.text "registration_body" - t.text "accepted_body" - t.text "rejected_body" - t.text "confirmed_without_registration_body" - t.datetime "created_at" - t.datetime "updated_at" - t.string "registration_subject" - t.string "accepted_subject" - t.string "rejected_subject" - t.string "confirmed_without_registration_subject" - t.boolean "send_on_conference_dates_updated", default: false - t.string "conference_dates_updated_subject" - t.text "conference_dates_updated_body" - t.boolean "send_on_conference_registration_dates_updated", default: false - t.string "conference_registration_dates_updated_subject" - t.text "conference_registration_dates_updated_body" - t.boolean "send_on_venue_updated", default: false - t.string "venue_updated_subject" - t.text "venue_updated_body" - t.boolean "send_on_cfp_dates_updated", default: false - t.boolean "send_on_program_schedule_public", default: false - t.string "program_schedule_public_subject" - t.string "cfp_dates_updated_subject" - t.text "program_schedule_public_body" - t.text "cfp_dates_updated_body" + t.integer "conference_id", limit: 4 + t.boolean "send_on_registration", default: false + t.boolean "send_on_accepted", default: false + t.boolean "send_on_rejected", default: false + t.boolean "send_on_confirmed_without_registration", default: false + t.text "registration_body", limit: 16777215 + t.text "accepted_body", limit: 16777215 + t.text "rejected_body", limit: 16777215 + t.text "confirmed_without_registration_body", limit: 16777215 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "registration_subject", limit: 255 + t.string "accepted_subject", limit: 255 + t.string "rejected_subject", limit: 255 + t.string "confirmed_without_registration_subject", limit: 255 + t.boolean "send_on_conference_dates_updated", default: false + t.string "conference_dates_updated_subject", limit: 255 + t.text "conference_dates_updated_body", limit: 65535 + t.boolean "send_on_conference_registration_dates_updated", default: false + t.string "conference_registration_dates_updated_subject", limit: 255 + t.text "conference_registration_dates_updated_body", limit: 65535 + t.boolean "send_on_venue_updated", default: false + t.string "venue_updated_subject", limit: 255 + t.text "venue_updated_body", limit: 65535 + t.boolean "send_on_cfp_dates_updated", default: false + t.boolean "send_on_program_schedule_public", default: false + t.string "program_schedule_public_subject", limit: 255 + t.string "cfp_dates_updated_subject", limit: 255 + t.text "program_schedule_public_body", limit: 65535 + t.text "cfp_dates_updated_body", limit: 65535 end create_table "event_types", force: :cascade do |t| - t.string "title", null: false - t.integer "length", default: 30 - t.integer "minimum_abstract_length", default: 0 - t.integer "maximum_abstract_length", default: 500 - t.string "color" - t.string "description" - t.integer "program_id" + t.string "title", limit: 255, null: false + t.integer "length", limit: 4, default: 30 + t.integer "minimum_abstract_length", limit: 4, default: 0 + t.integer "maximum_abstract_length", limit: 4, default: 500 + t.string "color", limit: 255 + t.string "description", limit: 255 + t.integer "program_id", limit: 4 end create_table "event_users", force: :cascade do |t| - t.integer "user_id" - t.integer "event_id" - t.string "event_role", default: "participant", null: false - t.string "comment" + t.integer "user_id", limit: 4 + t.integer "event_id", limit: 4 + t.string "event_role", limit: 255, default: "participant", null: false + t.string "comment", limit: 255 t.datetime "created_at" t.datetime "updated_at" end create_table "events", force: :cascade do |t| - t.string "guid", null: false - t.integer "event_type_id" - t.string "title", null: false - t.string "subtitle" - t.integer "time_slots" - t.string "state", default: "new", null: false - t.string "progress", default: "new", null: false - t.string "language" + t.string "guid", limit: 255, null: false + t.integer "event_type_id", limit: 4 + t.string "title", limit: 255, null: false + t.string "subtitle", limit: 255 + t.integer "time_slots", limit: 4 + t.string "state", limit: 255, default: "new", null: false + t.string "progress", limit: 255, default: "new", null: false + t.string "language", limit: 255 t.datetime "start_time" - t.text "abstract" - t.text "description" - t.boolean "public", default: true - t.string "logo_file_name" - t.string "logo_content_type" - t.integer "logo_file_size" + t.text "abstract", limit: 16777215 + t.text "description", limit: 16777215 + t.boolean "public", default: true + t.string "logo_file_name", limit: 255 + t.string "logo_content_type", limit: 255 + t.integer "logo_file_size", limit: 4 t.datetime "logo_updated_at" - t.text "proposal_additional_speakers" - t.integer "track_id" - t.integer "room_id" - t.datetime "created_at" - t.datetime "updated_at" + t.text "proposal_additional_speakers", limit: 16777215 + t.integer "track_id", limit: 4 + t.integer "room_id", limit: 4 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "require_registration" - t.integer "difficulty_level_id" - t.integer "week" - t.boolean "is_highlight", default: false - t.integer "program_id" + t.integer "difficulty_level_id", limit: 4 + t.integer "week", limit: 4 + t.boolean "is_highlight", default: false + t.integer "program_id", limit: 4 end create_table "events_registrations", id: false, force: :cascade do |t| - t.integer "registration_id" - t.integer "event_id" + t.integer "registration_id", limit: 4 + t.integer "event_id", limit: 4 end create_table "lodgings", force: :cascade do |t| - t.string "name" - t.text "description" - t.string "photo_file_name" - t.string "photo_content_type" - t.integer "photo_file_size" + t.string "name", limit: 255 + t.text "description", limit: 65535 + t.string "photo_file_name", limit: 255 + t.string "photo_content_type", limit: 255 + t.integer "photo_file_size", limit: 4 t.datetime "photo_updated_at" t.datetime "created_at" t.datetime "updated_at" - t.string "website_link" - t.integer "conference_id" + t.string "website_link", limit: 255 + t.integer "conference_id", limit: 4 end create_table "openids", force: :cascade do |t| - t.string "provider" - t.string "email" - t.string "uid" - t.integer "user_id" + t.string "provider", limit: 255 + t.string "email", limit: 255 + t.string "uid", limit: 255 + t.integer "user_id", limit: 4 t.datetime "created_at" t.datetime "updated_at" end create_table "photos", force: :cascade do |t| - t.text "description" - t.string "picture_file_name" - t.string "picture_content_type" - t.integer "picture_file_size" + t.text "description", limit: 65535 + t.string "picture_file_name", limit: 255 + t.string "picture_content_type", limit: 255 + t.integer "picture_file_size", limit: 4 t.datetime "picture_updated_at" - t.integer "conference_id" + t.integer "conference_id", limit: 4 t.datetime "created_at" t.datetime "updated_at" end create_table "programs", force: :cascade do |t| - t.integer "conference_id" - t.integer "rating", default: 0 - t.boolean "schedule_public", default: false - t.boolean "schedule_fluid", default: false + t.integer "conference_id", limit: 4 + t.integer "rating", limit: 4, default: 0 + t.boolean "schedule_public", default: false + t.boolean "schedule_fluid", default: false t.datetime "created_at" t.datetime "updated_at" end create_table "qanswers", force: :cascade do |t| - t.integer "question_id" - t.integer "answer_id" + t.integer "question_id", limit: 4 + t.integer "answer_id", limit: 4 t.datetime "created_at" t.datetime "updated_at" end create_table "qanswers_registrations", id: false, force: :cascade do |t| - t.integer "registration_id", null: false - t.integer "qanswer_id", null: false + t.integer "registration_id", limit: 4, null: false + t.integer "qanswer_id", limit: 4, null: false end create_table "question_types", force: :cascade do |t| - t.string "title" - t.datetime "created_at" - t.datetime "updated_at" + t.string "title", limit: 255 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "questions", force: :cascade do |t| - t.string "title" - t.integer "question_type_id" - t.integer "conference_id" + t.string "title", limit: 255 + t.integer "question_type_id", limit: 4 + t.integer "conference_id", limit: 4 t.boolean "global" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "registration_periods", force: :cascade do |t| - t.integer "conference_id" + t.integer "conference_id", limit: 4 t.date "start_date" t.date "end_date" t.datetime "created_at" @@ -319,65 +319,58 @@ ActiveRecord::Schema.define(version: 20160201221411) do end create_table "registrations", force: :cascade do |t| - t.integer "conference_id" + t.integer "conference_id", limit: 4 t.datetime "arrival" t.datetime "departure" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "dietary_choice_id" - t.text "other_dietary_choice" - t.text "other_special_needs" - t.boolean "attended", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "dietary_choice_id", limit: 4 + t.text "other_dietary_choice", limit: 16777215 + t.text "other_special_needs", limit: 16777215 + t.boolean "attended", default: false t.boolean "volunteer" - t.integer "user_id" - t.integer "week" + t.integer "user_id", limit: 4 + t.integer "week", limit: 4 end create_table "registrations_social_events", id: false, force: :cascade do |t| - t.integer "registration_id" - t.integer "social_event_id" + t.integer "registration_id", limit: 4 + t.integer "social_event_id", limit: 4 end create_table "registrations_vchoices", id: false, force: :cascade do |t| - t.integer "registration_id" - t.integer "vchoice_id" + t.integer "registration_id", limit: 4 + t.integer "vchoice_id", limit: 4 end create_table "roles", force: :cascade do |t| - t.string "name" - t.datetime "created_at" - t.datetime "updated_at" - t.string "description" - t.integer "resource_id" - t.string "resource_type" + t.string "name", limit: 255 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "description", limit: 255 + t.integer "resource_id", limit: 4 + t.string "resource_type", limit: 255 end add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id" add_index "roles", ["name"], name: "index_roles_on_name" - create_table "roles_users", id: false, force: :cascade do |t| - t.integer "role_id" - t.integer "user_id" - end - - add_index "roles_users", ["user_id", "role_id"], name: "index_roles_users_on_user_id_and_role_id" - create_table "rooms", force: :cascade do |t| - t.string "guid", null: false - t.string "name", null: false - t.integer "size" - t.integer "venue_id", null: false + t.string "guid", limit: 255, null: false + t.string "name", limit: 255, null: false + t.integer "size", limit: 4 + t.integer "venue_id", limit: 4, null: false end create_table "social_events", force: :cascade do |t| - t.integer "conference_id" - t.string "title" - t.text "description" + t.integer "conference_id", limit: 4 + t.string "title", limit: 255 + t.text "description", limit: 65535 t.date "date" end create_table "splashpages", force: :cascade do |t| - t.integer "conference_id" + t.integer "conference_id", limit: 4 t.boolean "public" t.boolean "include_tracks" t.boolean "include_program" @@ -389,108 +382,108 @@ ActiveRecord::Schema.define(version: 20160201221411) do t.boolean "include_lodgings" t.datetime "created_at" t.datetime "updated_at" - t.boolean "include_cfp", default: false + t.boolean "include_cfp", default: false end create_table "sponsors", force: :cascade do |t| - t.string "name" - t.text "description" - t.string "website_url" - t.string "logo_file_name" - t.string "logo_content_type" - t.integer "logo_file_size" + t.string "name", limit: 255 + t.text "description", limit: 65535 + t.string "website_url", limit: 255 + t.string "logo_file_name", limit: 255 + t.string "logo_content_type", limit: 255 + t.integer "logo_file_size", limit: 4 t.datetime "logo_updated_at" - t.integer "sponsorship_level_id" - t.integer "conference_id" + t.integer "sponsorship_level_id", limit: 4 + t.integer "conference_id", limit: 4 t.datetime "created_at" t.datetime "updated_at" end create_table "sponsorship_levels", force: :cascade do |t| - t.string "title" - t.integer "conference_id" + t.string "title", limit: 255 + t.integer "conference_id", limit: 4 t.datetime "created_at" t.datetime "updated_at" - t.integer "position" + t.integer "position", limit: 4 end create_table "subscriptions", force: :cascade do |t| - t.integer "user_id" - t.integer "conference_id" + t.integer "user_id", limit: 4 + t.integer "conference_id", limit: 4 t.datetime "created_at" t.datetime "updated_at" end create_table "targets", force: :cascade do |t| - t.integer "conference_id" - t.integer "campaign_id" + t.integer "conference_id", limit: 4 + t.integer "campaign_id", limit: 4 t.date "due_date" - t.integer "target_count" - t.string "unit" + t.integer "target_count", limit: 4 + t.string "unit", limit: 255 t.datetime "created_at" t.datetime "updated_at" end create_table "ticket_purchases", force: :cascade do |t| - t.integer "ticket_id" - t.integer "conference_id" - t.boolean "paid", default: false + t.integer "ticket_id", limit: 4 + t.integer "conference_id", limit: 4 + t.boolean "paid", default: false t.datetime "created_at" - t.integer "quantity", default: 1 - t.integer "user_id" + t.integer "quantity", limit: 4, default: 1 + t.integer "user_id", limit: 4 end create_table "tickets", force: :cascade do |t| - t.integer "conference_id" - t.string "title", null: false - t.text "description" - t.integer "price_cents", default: 0, null: false - t.string "price_currency", default: "USD", null: false + t.integer "conference_id", limit: 4 + t.string "title", limit: 255, null: false + t.text "description", limit: 65535 + t.integer "price_cents", limit: 4, default: 0, null: false + t.string "price_currency", limit: 255, default: "USD", null: false end create_table "tracks", force: :cascade do |t| - t.string "guid", null: false - t.string "name", null: false - t.text "description" - t.string "color" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "program_id" + t.string "guid", limit: 255, null: false + t.string "name", limit: 255, null: false + t.text "description", limit: 16777215 + t.string "color", limit: 255 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "program_id", limit: 4 end create_table "users", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" + t.string "email", limit: 255, default: "", null: false + t.string "encrypted_password", limit: 255, default: "", null: false + t.string "reset_password_token", limit: 255 t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", limit: 4, default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" - t.string "confirmation_token" + t.string "current_sign_in_ip", limit: 255 + t.string "last_sign_in_ip", limit: 255 + t.string "confirmation_token", limit: 255 t.datetime "confirmed_at" t.datetime "confirmation_sent_at" - t.string "unconfirmed_email" - t.datetime "created_at" - t.datetime "updated_at" - t.string "name" + t.string "unconfirmed_email", limit: 255 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name", limit: 255 t.boolean "email_public" - t.text "biography" - t.string "nickname" - t.string "affiliation" - t.string "avatar_file_name" - t.string "avatar_content_type" - t.integer "avatar_file_size" + t.text "biography", limit: 65535 + t.string "nickname", limit: 255 + t.string "affiliation", limit: 255 + t.string "avatar_file_name", limit: 255 + t.string "avatar_content_type", limit: 255 + t.integer "avatar_file_size", limit: 4 t.datetime "avatar_updated_at" - t.string "mobile" - t.string "tshirt" - t.string "languages" - t.text "volunteer_experience" - t.boolean "is_admin", default: false - t.string "username" - t.boolean "is_disabled", default: false + t.string "mobile", limit: 255 + t.string "tshirt", limit: 255 + t.string "languages", limit: 255 + t.text "volunteer_experience", limit: 65535 + t.boolean "is_admin", default: false + t.string "username", limit: 255 + t.boolean "is_disabled", default: false end add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true @@ -498,46 +491,53 @@ ActiveRecord::Schema.define(version: 20160201221411) do add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true add_index "users", ["username"], name: "index_users_on_username", unique: true + create_table "users_roles", id: false, force: :cascade do |t| + t.integer "role_id", limit: 4 + t.integer "user_id", limit: 4 + end + + add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id" + create_table "vchoices", force: :cascade do |t| - t.integer "vday_id" - t.integer "vposition_id" + t.integer "vday_id", limit: 4 + t.integer "vposition_id", limit: 4 end create_table "vdays", force: :cascade do |t| - t.integer "conference_id" + t.integer "conference_id", limit: 4 t.date "day" - t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.text "description", limit: 65535 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "venues", force: :cascade do |t| - t.string "guid" - t.string "name" - t.string "website" - t.text "description" - t.datetime "created_at" - t.datetime "updated_at" - t.string "photo_file_name" - t.string "photo_content_type" - t.integer "photo_file_size" + t.string "guid", limit: 255 + t.string "name", limit: 255 + t.string "website", limit: 255 + t.text "description", limit: 65535 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "photo_file_name", limit: 255 + t.string "photo_content_type", limit: 255 + t.integer "photo_file_size", limit: 4 t.datetime "photo_updated_at" - t.string "street" - t.string "postalcode" - t.string "city" - t.string "country" - t.string "latitude" - t.string "longitude" - t.integer "conference_id" + t.string "street", limit: 255 + t.string "postalcode", limit: 255 + t.string "city", limit: 255 + t.string "country", limit: 255 + t.string "latitude", limit: 255 + t.string "longitude", limit: 255 + t.integer "conference_id", limit: 4 end create_table "versions", force: :cascade do |t| - t.string "item_type", null: false - t.integer "item_id", null: false - t.string "event", null: false - t.string "whodunnit" - t.text "object" - t.text "object_changes" + t.string "item_type", limit: 255, null: false + t.integer "item_id", limit: 4, null: false + t.string "event", limit: 255, null: false + t.string "whodunnit", limit: 255 + t.text "object", limit: 16777215 + t.text "object_changes", limit: 16777215 t.datetime "created_at" end @@ -545,43 +545,43 @@ ActiveRecord::Schema.define(version: 20160201221411) do create_table "visits", force: :cascade do |t| t.uuid "visitor_id", limit: 16 - t.string "ip" - t.text "user_agent" - t.text "referrer" - t.text "landing_page" - t.integer "user_id" - t.string "referring_domain" - t.string "search_keyword" - t.string "browser" - t.string "os" - t.string "device_type" - t.string "country" - t.string "region" - t.string "city" - t.string "utm_source" - t.string "utm_medium" - t.string "utm_term" - t.string "utm_content" - t.string "utm_campaign" + t.string "ip", limit: 255 + t.text "user_agent", limit: 65535 + t.text "referrer", limit: 65535 + t.text "landing_page", limit: 65535 + t.integer "user_id", limit: 4 + t.string "referring_domain", limit: 255 + t.string "search_keyword", limit: 255 + t.string "browser", limit: 255 + t.string "os", limit: 255 + t.string "device_type", limit: 255 + t.string "country", limit: 255 + t.string "region", limit: 255 + t.string "city", limit: 255 + t.string "utm_source", limit: 255 + t.string "utm_medium", limit: 255 + t.string "utm_term", limit: 255 + t.string "utm_content", limit: 255 + t.string "utm_campaign", limit: 255 t.datetime "started_at" end add_index "visits", ["user_id"], name: "index_visits_on_user_id" create_table "votes", force: :cascade do |t| - t.integer "event_id" - t.integer "rating" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "user_id" + t.integer "event_id", limit: 4 + t.integer "rating", limit: 4 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "user_id", limit: 4 end create_table "vpositions", force: :cascade do |t| - t.integer "conference_id" - t.string "title", null: false - t.text "description" - t.datetime "created_at" - t.datetime "updated_at" + t.integer "conference_id", limit: 4 + t.string "title", limit: 255, null: false + t.text "description", limit: 65535 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end end diff --git a/lib/tasks/factory_girl.rake b/lib/tasks/factory_girl.rake index b922b0ef..bccc1b66 100644 --- a/lib/tasks/factory_girl.rake +++ b/lib/tasks/factory_girl.rake @@ -1,12 +1,9 @@ -require_relative '../../spec/support/external_request' - namespace :factory_girl do desc "Verify that all FactoryGirl factories are valid" task lint: :environment do if Rails.env.test? begin DatabaseCleaner.start - mock_commercial_request FactoryGirl.lint ensure DatabaseCleaner.clean diff --git a/spec/controllers/admin/comments_controller_spec.rb b/spec/controllers/admin/comments_controller_spec.rb index 6cf3ff9a..5429dabd 100644 --- a/spec/controllers/admin/comments_controller_spec.rb +++ b/spec/controllers/admin/comments_controller_spec.rb @@ -4,7 +4,6 @@ describe Admin::CommentsController, type: :controller do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } - let!(:first_user) { create(:user) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id, last_sign_in_at: Time.now - 1.day) } let(:participant) { create(:user) } diff --git a/spec/controllers/admin/conferences_controller_spec.rb b/spec/controllers/admin/conferences_controller_spec.rb index ac3a6b2a..9ad97cac 100644 --- a/spec/controllers/admin/conferences_controller_spec.rb +++ b/spec/controllers/admin/conferences_controller_spec.rb @@ -4,7 +4,6 @@ describe Admin::ConferenceController do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference, end_date: Date.new(2014, 05, 26) + 15) } - let!(:first_user) { create(:user) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id) } @@ -57,7 +56,7 @@ describe Admin::ConferenceController do short_title: nil) conference.reload - expect(flash[:alert]). + expect(flash[:error]). to eq("Updating conference failed. Short title can't be blank.") expect(conference.title).to eq('The dog and pony show') expect(conference.short_title).to eq("#{conference.short_title}") @@ -68,7 +67,7 @@ describe Admin::ConferenceController do attributes_for(:conference, title: 'Example Con', short_title: nil) - expect(flash[:alert]). + expect(flash[:error]). to eq("Updating conference failed. Short title can't be blank.") expect(response).to redirect_to edit_admin_conference_path( conference.short_title) diff --git a/spec/controllers/admin/programs_controller_spec.rb b/spec/controllers/admin/programs_controller_spec.rb index f65ad5d5..3ad98071 100644 --- a/spec/controllers/admin/programs_controller_spec.rb +++ b/spec/controllers/admin/programs_controller_spec.rb @@ -4,7 +4,6 @@ describe Admin::ProgramsController, type: :controller do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } - let!(:first_user) { create(:user) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id, last_sign_in_at: Time.now - 1.day) } diff --git a/spec/controllers/admin/registration_periods_controller_spec.rb b/spec/controllers/admin/registration_periods_controller_spec.rb index 6daf08d8..6177fde7 100644 --- a/spec/controllers/admin/registration_periods_controller_spec.rb +++ b/spec/controllers/admin/registration_periods_controller_spec.rb @@ -4,7 +4,6 @@ describe Admin::RegistrationPeriodsController do # It is necessary to use bang version of let to build roles before user let(:conference) { create(:conference) } - let!(:first_user) { create(:user) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:organizer) { create(:user, role_ids: organizer_role.id) } diff --git a/spec/controllers/admin/roles_controller_spec.rb b/spec/controllers/admin/roles_controller_spec.rb index 5b9fdb62..964346ef 100644 --- a/spec/controllers/admin/roles_controller_spec.rb +++ b/spec/controllers/admin/roles_controller_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' describe Admin::RolesController do let(:conference) { create(:conference) } - let!(:first_user) { create(:user) } let(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } let(:admin) { create(:admin) } diff --git a/spec/controllers/admin/rooms_controller_spec.rb b/spec/controllers/admin/rooms_controller_spec.rb new file mode 100644 index 00000000..dc8c3d2e --- /dev/null +++ b/spec/controllers/admin/rooms_controller_spec.rb @@ -0,0 +1,171 @@ +require 'spec_helper' + +describe Admin::RoomsController do + let!(:admin) { create(:admin) } + let(:conference) { create(:conference) } + let!(:venue) { create(:venue, conference: conference) } + let(:room) { create(:room, venue: venue, size: 4) } + + context 'admin is signed in' do + before { sign_in admin } + + describe 'GET #index' do + before { get :index, conference_id: conference.short_title } + + it 'assigns conference, venue and rooms variables' do + expect(assigns(:conference)).to eq conference + expect(assigns(:venue)).to eq venue + expect(assigns(:rooms)).to eq [room] + end + + it 'renders index template' do + expect(response).to render_template('index') + end + end + + describe 'GET #edit' do + before { get :edit, conference_id: conference.short_title, id: room.id } + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'assigns room variable' do + expect(assigns(:room)).to eq room + end + end + + describe 'GET #new' do + before { get :new, conference_id: conference.short_title } + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'assigns room variable' do + expect(assigns(:room)).to be_instance_of(Room) + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before do + post :create, room: attributes_for(:room), conference_id: conference.short_title + end + + it 'redirects to admin room index path' do + expect(response).to redirect_to admin_conference_venue_rooms_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Room successfully created.') + end + + it 'creates new room' do + expect(Room.count).to eq 1 + end + end + + context 'save fails' do + before do + allow_any_instance_of(Room).to receive(:save).and_return(false) + post :create, room: attributes_for(:room), conference_id: conference.short_title + end + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating Room failed: #{room.errors.full_messages.join('. ')}.") + end + + it 'does not create new room' do + expect(Room.count).to eq 0 + end + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before do + patch :update, room: attributes_for(:room, size: 2), + conference_id: conference.short_title, + id: room.id + end + + it 'redirects to admin room index path' do + expect(response).to redirect_to admin_conference_venue_rooms_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Room successfully updated.') + end + + it 'updates the room' do + room.reload + expect(room.size).to eq 2 + end + end + + context 'update fails' do + before do + allow_any_instance_of(Room).to receive(:save).and_return(false) + patch :update, room: attributes_for(:room, size: 2), + conference_id: conference.short_title, + id: room.id + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Update Room failed: #{room.errors.full_messages.join('. ')}.") + end + + it 'does not update room' do + room.reload + expect(room.size).to eq 4 + end + end + end + + describe 'DELETE #destroy' do + context 'deletes successfully' do + before { delete :destroy, conference_id: conference.short_title, id: room.id } + + it 'redirects to admin room index path' do + expect(response).to redirect_to admin_conference_venue_rooms_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Room successfully deleted.') + end + + it 'deletes the room' do + expect(Room.count).to eq 0 + end + end + + context 'delete fails' do + before do + allow_any_instance_of(Room).to receive(:destroy).and_return(false) + delete :destroy, conference_id: conference.short_title, id: room.id + end + + it 'redirects to admin room index path' do + expect(response).to redirect_to admin_conference_venue_rooms_path(conference_id: conference.short_title) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Destroying room failed! #{room.errors.full_messages.join('. ')}.") + end + + it 'does not delete room' do + expect(Room.count).to eq 1 + end + end + end + end +end diff --git a/spec/controllers/admin/sponsorship_levels_controller_spec.rb b/spec/controllers/admin/sponsorship_levels_controller_spec.rb new file mode 100644 index 00000000..058c703c --- /dev/null +++ b/spec/controllers/admin/sponsorship_levels_controller_spec.rb @@ -0,0 +1,209 @@ +require 'spec_helper' + +describe Admin::SponsorshipLevelsController do + let(:admin) { create(:admin) } + let(:conference) { create(:conference) } + let(:sponsorship_level) { create(:sponsorship_level, conference: conference) } + + context 'admin is signed in' do + before { sign_in admin } + + describe 'GET #index' do + before { get :index, conference_id: conference.short_title } + + it 'assigns conference and sponsorship_levels variables' do + expect(assigns(:conference)).to eq conference + expect(assigns(:sponsorship_levels)).to eq [sponsorship_level] + end + + it 'renders index template' do + expect(response).to render_template('index') + end + end + + describe 'GET #edit' do + before { get :edit, conference_id: conference.short_title, id: sponsorship_level.id } + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'assigns sponsorship_level variable' do + expect(assigns(:sponsorship_level)).to eq sponsorship_level + end + end + + describe 'GET #new' do + before { get :new, conference_id: conference.short_title } + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'assigns sponsorship_level variable' do + expect(assigns(:sponsorship_level)).to be_instance_of(SponsorshipLevel) + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before(:each, run: true) do + post :create, sponsorship_level: attributes_for(:sponsorship_level), + conference_id: conference.short_title + end + + it 'redirects to admin sponsorship_level index path', run: true do + expect(response).to redirect_to admin_conference_sponsorship_levels_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice', run: true do + expect(flash[:notice]).to match('Sponsorship level successfully created.') + end + + it 'creates new sponsorship_level' do + expect do + post :create, sponsorship_level: attributes_for(:sponsorship_level), + conference_id: conference.short_title + end.to change{ conference.sponsorship_levels.count }.from(0).to(1) + end + end + + context 'save fails' do + before do + allow_any_instance_of(SponsorshipLevel).to receive(:save).and_return(false) + post :create, sponsorship_level: attributes_for(:sponsorship_level), + conference_id: conference.short_title + end + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating Sponsorship Level failed: #{sponsorship_level.errors.full_messages.join('. ')}.") + end + + it 'does not create new sponsorship_level' do + expect(SponsorshipLevel.count).to eq 0 + end + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before do + patch :update, sponsorship_level: attributes_for(:sponsorship_level, title: 'Gold'), + conference_id: conference.short_title, + id: sponsorship_level.id + end + + it 'redirects to admin sponsorship_level index path' do + expect(response).to redirect_to admin_conference_sponsorship_levels_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Sponsorship level successfully updated.') + end + + it 'updates the sponsorship_level' do + sponsorship_level.reload + expect(sponsorship_level.title).to eq 'Gold' + end + end + + context 'update fails' do + before do + allow_any_instance_of(SponsorshipLevel).to receive(:save).and_return(false) + patch :update, sponsorship_level: attributes_for(:sponsorship_level, title: 'Gold'), + conference_id: conference.short_title, + id: sponsorship_level.id + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Update Sponsorship level failed: #{sponsorship_level.errors.full_messages.join('. ')}.") + end + + it 'does not update sponsorship_level' do + sponsorship_level.reload + expect(sponsorship_level.title).not_to eq 'Gold' + end + end + end + + describe 'DELETE #destroy' do + context 'deletes successfully' do + before(:each, run: true) do + delete :destroy, conference_id: conference.short_title, id: sponsorship_level.id + end + + it 'redirects to admin sponsorship_level index path', run: true do + expect(response).to redirect_to admin_conference_sponsorship_levels_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice', run: true do + expect(flash[:notice]).to match('Sponsorship level successfully deleted.') + end + + it 'deletes the sponsorship_level' do + sponsorship_level + expect do + delete :destroy, conference_id: conference.short_title, id: sponsorship_level.id + end.to change{ conference.sponsorship_levels.count }.from(1).to(0) + end + end + + context 'delete fails' do + before do + allow_any_instance_of(SponsorshipLevel).to receive(:destroy).and_return(false) + delete :destroy, conference_id: conference.short_title, id: sponsorship_level.id + end + + it 'redirects to admin sponsorship_level index path' do + expect(response).to redirect_to admin_conference_sponsorship_levels_path(conference_id: conference.short_title) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Deleting sponsorship level failed! #{sponsorship_level.errors.full_messages.join('. ')}.") + end + + it 'does not delete sponsorship_level' do + expect(conference.sponsorship_levels.count).to eq 1 + end + end + end + + describe 'PATCH #up' do + before do + sponsorship_level + @second_sponsorship_level = create(:sponsorship_level, conference: conference) + patch :up, conference_id: conference.short_title, id: @second_sponsorship_level.id + end + + it 'moves sponsorship_level up by one position' do + sponsorship_level.reload + @second_sponsorship_level.reload + expect(sponsorship_level.position).to eq 2 + expect(@second_sponsorship_level.position).to eq 1 + end + end + + describe 'PATCH #down' do + before do + sponsorship_level + @second_sponsorship_level = create(:sponsorship_level, conference: conference) + patch :down, conference_id: conference.short_title, id: sponsorship_level.id + end + + it 'moves sponsorship_level down by one position' do + sponsorship_level.reload + @second_sponsorship_level.reload + expect(sponsorship_level.position).to eq 2 + expect(@second_sponsorship_level.position).to eq 1 + end + end + end +end diff --git a/spec/controllers/admin/targets_controller_spec.rb b/spec/controllers/admin/targets_controller_spec.rb new file mode 100644 index 00000000..2b8b5dd4 --- /dev/null +++ b/spec/controllers/admin/targets_controller_spec.rb @@ -0,0 +1,168 @@ +require 'spec_helper' + +describe Admin::TargetsController, type: :controller do + let(:admin) { create(:admin) } + let(:conference) { create(:conference) } + let(:target) { create(:target, conference: conference, target_count: 100) } + + context 'user is admin' do + before { sign_in admin } + + describe 'GET #index' do + before { get :index, conference_id: conference.short_title } + + it 'renders index template' do + expect(response).to render_template('index') + end + + it 'assigns targets and conference variables' do + expect(assigns(:conference)).to eq conference + expect(assigns(:targets)).to eq [target] + end + end + + describe 'GET #new' do + before { get :new, conference_id: conference.short_title } + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'assigns target variable' do + expect(assigns(:target)).to be_instance_of(Target) + end + end + + describe 'POST #create' do + context 'saves successfuly' do + before do + post :create, target: attributes_for(:target), conference_id: conference.short_title + end + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Target successfully created.') + end + + it 'creates new target' do + expect(Target.count).to eq 1 + end + end + + context 'save fails' do + before do + allow_any_instance_of(Target).to receive(:save).and_return(false) + post :create, target: attributes_for(:target), conference_id: conference.short_title + end + + it 'renders new template' do + expect(response).to render_template('new') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Creating target failed: #{target.errors.full_messages.join('. ')}.") + end + + it 'does not create new target' do + expect(Target.count).to eq 0 + end + end + end + + describe 'GET #edit' do + before { get :edit, conference_id: conference.short_title, id: target.id } + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'assigns target variable' do + expect(assigns(:target)).to eq target + end + end + + describe 'PATCH #update' do + context 'updates successfully' do + before do + patch :update, target: attributes_for(:target, target_count: 2), + conference_id: conference.short_title, + id: target.id + end + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Target successfully updated.') + end + + it 'updates the target' do + target.reload + expect(target.target_count).to eq 2 + end + end + + context 'update fails' do + before do + allow_any_instance_of(Target).to receive(:save).and_return(false) + patch :update, target: attributes_for(:target, target_count: 2), + conference_id: conference.short_title, + id: target.id + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Target update failed: #{target.errors.full_messages.join('. ')}.") + end + + it 'does not update target' do + expect(target.target_count).to eq 100 + end + end + end + + describe 'DELETE #destroy' do + context 'deletes successfully' do + before { delete :destroy, conference_id: conference.short_title, id: target.id } + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Target successfully destroyed.') + end + + it 'deletes target' do + expect(Target.count).to eq 0 + end + end + + context 'delete fails' do + before do + allow_any_instance_of(Target).to receive(:destroy).and_return(false) + delete :destroy, conference_id: conference.short_title, id: target.id + end + + it 'redirects to admin target index path' do + expect(response).to redirect_to admin_conference_targets_path(conference_id: conference.short_title) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match("Could not delete target for #{conference.title}: #{target.errors.full_messages.join('. ')}.") + end + + it 'does not delete target' do + expect(Target.count).to eq 1 + end + end + end + end +end diff --git a/spec/controllers/api/v1/rooms_controller_spec.rb b/spec/controllers/api/v1/rooms_controller_spec.rb new file mode 100644 index 00000000..48a8db98 --- /dev/null +++ b/spec/controllers/api/v1/rooms_controller_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe Api::V1::RoomsController do + let!(:conference) { create(:conference) } + let!(:venue) { create(:venue, conference: conference) } + let!(:conference_room) { create(:room, name: 'Conference Room', venue: venue) } + let!(:room) { create(:room, name: 'Test Room') } + + describe 'GET #index' do + context 'without conference scope' do + it 'returns all rooms' do + + get :index, format: :json + json = JSON.parse(response.body)['rooms'] + + expect(response).to be_success + + expect(json.length).to eq(2) + expect(json[0]['name']).to eq('Conference Room') + expect(json[1]['name']).to eq('Test Room') + end + end + + context 'with conference scope' do + it 'returns all rooms of conference' do + + get :index, conference_id: conference.short_title, format: :json + json = JSON.parse(response.body)['rooms'] + + expect(response).to be_success + + expect(json.length).to eq(1) + expect(json[0]['name']).to eq('Conference Room') + end + end + end +end diff --git a/spec/controllers/api/v1/tracks_controller_spec.rb b/spec/controllers/api/v1/tracks_controller_spec.rb new file mode 100644 index 00000000..a1424ce3 --- /dev/null +++ b/spec/controllers/api/v1/tracks_controller_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +describe Api::V1::TracksController do + let!(:conference) { create(:conference) } + let!(:conference_track) { create(:track, name: 'Conference Track', program_id: conference.program.id) } + let!(:track) { create(:track, name: 'Test Track') } + + describe 'GET #index' do + context 'without conference scope' do + it 'returns all tracks' do + + get :index, format: :json + json = JSON.parse(response.body)['tracks'] + + expect(response).to be_success + + expect(json.length).to eq(2) + expect(json[0]['name']).to eq('Conference Track') + expect(json[1]['name']).to eq('Test Track') + end + end + + context 'with conference scope' do + it 'returns all rooms of conference' do + + get :index, conference_id: conference.short_title, format: :json + json = JSON.parse(response.body)['tracks'] + + expect(response).to be_success + + expect(json.length).to eq(1) + expect(json[0]['name']).to eq('Conference Track') + end + end + end +end diff --git a/spec/controllers/conference_registration_controller_spec.rb b/spec/controllers/conference_registration_controller_spec.rb new file mode 100644 index 00000000..0a00d3dc --- /dev/null +++ b/spec/controllers/conference_registration_controller_spec.rb @@ -0,0 +1,169 @@ +require 'spec_helper' + +describe ConferenceRegistrationsController, type: :controller do + let(:conference) { create(:conference) } + let(:user) { create(:user) } + + context 'user is signed in' do + before { sign_in(user) } + + describe 'GET #show' do + before do + @registration = create(:registration, conference: conference, user: user) + end + + context 'successful request' do + before do + get :show, conference_id: conference.short_title + end + + it 'assigns conference, registration and workshops variables' do + expect(assigns(:conference)).to eq conference + expect(assigns(:registration)).to eq @registration + expect(assigns(:workshops)).to eq @registration.workshops + end + + it 'renders the show template' do + expect(response).to render_template('show') + end + end + + context 'user has purchased a ticket' do + before do + @ticket = create(:ticket, conference: conference) + @purchased_ticket = create(:ticket_purchase, conference: conference, + user: user, + ticket: @ticket) + get :show, conference_id: conference.short_title + end + + it 'assigns price of purchased tickets to total_price and purchased tickets to tickets' do + expect(assigns(:total_price)).to eq Money.new(10000, 'USD') + expect(assigns(:tickets)).to match_array [@purchased_ticket] + end + end + + context 'user has not purchased any ticket' do + before do + get :show, conference_id: conference.short_title + end + + it 'assigns 0 dollars to total_price and empty array to tickets variables' do + expect(assigns(:total_price)).to eq Money.new(0, 'USD') + expect(assigns(:tickets)).to match_array [] + end + end + end + + describe 'GET #edit' do + before do + @registration = create(:registration, conference: conference, user: user) + get :edit, conference_id: conference.short_title + end + + it 'assigns conference and registration variable' do + expect(assigns(:conference)).to eq conference + expect(assigns(:registration)).to eq @registration + end + + it 'renders the edit template' do + expect(response).to render_template('edit') + end + end + + describe 'PATCH #update' do + before do + @registration = create(:registration, + conference: conference, + user: user, + arrival: Date.new(2014, 04, 25)) + end + + context 'updates successfully' do + before do + patch :update, registration: attributes_for(:registration, arrival: Date.new(2014, 04, 29)), + conference_id: conference.short_title + end + + it 'redirects to registration show path' do + expect(response).to redirect_to conference_conference_registrations_path(conference.short_title) + end + + it 'shows success message in flash notice' do + expect(flash[:notice]).to match('Registration was successfully updated.') + end + + it 'updates the registration' do + @registration.reload + expect(@registration.arrival).to eq Date.new(2014, 04, 29) + end + end + + context 'update fails' do + before do + allow_any_instance_of(Registration).to receive(:update_attributes).and_return(false) + patch :update, registration: attributes_for(:registration, arrival: Date.new(2014, 04, 27)), + conference_id: conference.short_title + end + + it 'renders edit template' do + expect(response).to render_template('edit') + end + + it 'shows error in flash message' do + expect(flash[:error]).to match "Could not update your registration for The dog and pony show: #{@registration.errors.full_messages.join('. ')}." + end + + it 'does not update the registration' do + @registration.reload + expect(@registration.arrival).to eq Date.new(2014, 04, 25) + end + end + end + + describe 'DELETE #destroy' do + before do + @registration = create(:registration, conference: conference, user: user) + end + + context 'deletes successfully' do + before(:each, run: true) do + delete :destroy, conference_id: conference.short_title + end + + it 'redirects to root path', run: true do + expect(response).to redirect_to root_path + end + + it 'shows success message in flash notice', run: true do + expect(flash[:notice]).to match('You are not registered for The dog and pony show anymore!') + end + + it 'deletes the registration' do + expect do + delete :destroy, conference_id: conference.short_title + end.to change{ Registration.count }.from(1).to(0) + end + end + + context 'delete fails' do + before do + allow_any_instance_of(Registration).to receive(:destroy).and_return(false) + delete :destroy, conference_id: conference.short_title + end + + it 'redirects to registration show path' do + expect(response).to redirect_to conference_conference_registrations_path(conference.short_title) + end + + it 'shows error in flash message' do + expect(flash[:error]).to match "Could not delete your registration for The dog and pony show: #{@registration.errors.full_messages.join('. ')}." + end + + it 'does not delete the registration' do + expect(assigns(:registration)).to eq @registration + end + end + end + end +end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb new file mode 100644 index 00000000..e46e134c --- /dev/null +++ b/spec/controllers/users_controller_spec.rb @@ -0,0 +1,66 @@ +require 'spec_helper' + +describe UsersController do + let!(:first_user) { create(:user) } + let!(:user) { create(:user, name: 'My Name') } + + describe 'GET #show' do + before :each do + get :show, id: user.id + end + + it 'renders show template' do + expect(response).to render_template :show + end + + it 'assigns the right value to @user' do + expect(assigns(:user)).to eq user + end + + it 'assigns [] to @events, when user does not have any submissions' do + expect(assigns(:events)).to eq [] + end + + it 'assigns the correct value to @events, when the user has submissions' do + conference = create(:conference) + event = create(:event, state: 'confirmed', program: conference.program) + event.event_users << create(:event_user, user: user, event_role: 'submitter') + + expect(assigns(:events)).to eq [event] + end + end + + describe 'GET #edit' do + it 'assigns the right value to @user' do + sign_in user + get :edit, id: user.id + expect(assigns(:user)).to eq user + end + end + + describe 'PATCH #update' do + context 'with valid attributes' do + before :each do + sign_in user + patch :update, id: user.id, user: attributes_for(:user, name: 'My Test Name') + user.reload + end + + it 'assigns the right value to @user' do + expect(assigns(:user)).to eq user + end + + it 'changes user attributes' do + expect(user.name).to eq 'My Test Name' + end + + it 'redirects to show' do + expect(response).to redirect_to(user_path(user)) + end + + it 'shows flash message' do + expect(flash[:notice]).to eq 'User was successfully updated.' + end + end + end +end diff --git a/spec/factories/events.rb b/spec/factories/events.rb index ce8e46db..f3999da8 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -31,7 +31,7 @@ FactoryGirl.define do libero quis porta ultricies. Fusce pulvinar accumsan lobortis. EOS after(:build) do |event| - event.event_users << build(:submitter) + event.event_users << build(:submitter) unless event.submitter # so that we don't have two submitters # set an event_type if none is passed to the factory. # needs to be created here because otherwise it doesn't belong to the # same conference as the event diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 1886b955..c7ed7ca1 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -1,4 +1,18 @@ # Read about factories at https://github.com/thoughtbot/factory_girl + +# It is a feature of our app that first signed up user is admin. This property +# is set in a before create callback `setup_role` in user model. +# We want to override this behavior when we create user factories. We want +# `create(:user)` to create non-admin user by default. We are enforcing it +# with `after create` blocks in following factories. +# +# Following commands won't work: +# `create(:user, is_admin: true)` +# `create(:admin, is_admin: false)` +# +# For a non-admin user, use: `create(:user)` +# For an admin user, use: `create(:admin) + FactoryGirl.define do factory :user do sequence(:email) { |n| "example#{n}@example.com" } @@ -16,8 +30,19 @@ FactoryGirl.define do gravida. EOS + after(:create) do |user| + user.is_admin = false + # save with bang cause we want change in DB and not just in object instance + user.save! + end + factory :admin do - is_admin true + # admin factory needs its own after create block or else after create + # of user factory will override `is_admin` value. + after(:create) do |user| + user.is_admin = true + user.save! + end end end end diff --git a/spec/features/ability_spec.rb b/spec/features/ability_spec.rb index 5330c4bb..fac2e4e7 100644 --- a/spec/features/ability_spec.rb +++ b/spec/features/ability_spec.rb @@ -20,7 +20,6 @@ feature 'Has correct abilities' do let(:user_volunteer_coordinator) { create(:user, role_ids: [role_volunteer_coordinator.id]) } scenario 'when user has no role' do - user.is_admin = false sign_in user visit admin_conference_path(conference1.short_title) @@ -29,7 +28,6 @@ feature 'Has correct abilities' do end scenario 'when user is organizer' do - user_organizer.is_admin = false sign_in user_organizer visit admin_conference_path(conference1.short_title) @@ -107,7 +105,6 @@ feature 'Has correct abilities' do end scenario 'when user is cfp' do - user_cfp.is_admin = false sign_in user_cfp visit admin_conference_path(conference2.short_title) @@ -182,7 +179,6 @@ feature 'Has correct abilities' do end scenario 'when user is info desk' do - user_info_desk.is_admin = false sign_in user_info_desk visit admin_conference_path(conference3.short_title) diff --git a/spec/features/base_controller_spec.rb b/spec/features/base_controller_spec.rb index d271c47c..366327a2 100644 --- a/spec/features/base_controller_spec.rb +++ b/spec/features/base_controller_spec.rb @@ -23,7 +23,6 @@ feature 'BaseController' do end it 'not an admin it redirects to root_path' do - user.is_admin = false visit admin_conference_index_path expect(current_path).to eq root_path expect(flash).to eq 'You are not authorized to access this area!' @@ -36,28 +35,24 @@ feature 'BaseController' do end it 'an organizer he can access the admin area' do - user.is_admin = false user.role_ids = organizer_role.id visit admin_conference_index_path expect(current_path).to eq admin_conference_index_path end it 'a volunteers_coordinator he can access the admin area' do - user.is_admin = false user.role_ids = volunteers_coordinator_role.id visit admin_conference_index_path expect(current_path).to eq admin_conference_index_path end it 'a cfp he can access the admin area' do - user.is_admin = false user.role_ids = cfp_role.id visit admin_conference_index_path expect(current_path).to eq admin_conference_index_path end it 'an info_desk he can access the admin area' do - user.is_admin = false user.role_ids = info_desk_role.id visit admin_conference_index_path expect(current_path).to eq admin_conference_index_path diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 71e11171..a4a8ace6 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -3,8 +3,7 @@ require 'cancan/matchers' describe 'User' do describe 'Abilities' do - # automatically becomes admin - let!(:first_user) { create(:user) } + let!(:admin) { create(:admin) } # see https://github.com/CanCanCommunity/cancancan/wiki/Testing-Abilities subject(:ability){ Ability.new(user) } @@ -13,7 +12,7 @@ describe 'User' do let!(:my_conference) { create(:full_conference) } let!(:my_cfp) { create(:cfp, program: my_conference.program) } let(:my_venue) { my_conference.venue || create(:venue, conference: my_conference) } - let(:my_registration) { create(:registration, conference: my_conference, user: first_user) } + let(:my_registration) { create(:registration, conference: my_conference, user: admin) } let(:other_registration) { create(:registration, conference: conference_public) } let(:my_event) { create(:event_full, program: my_conference.program) } @@ -33,6 +32,9 @@ describe 'User' do let(:registration) { create(:registration) } + let(:program_with_cfp) { create(:program, cfp: create(:cfp)) } + let(:program_without_cfp) { create(:program) } + # Test abilities for not signed in users context 'when user is not signed in' do it{ should be_able_to(:index, Conference)} @@ -59,7 +61,9 @@ describe 'User' do it{ should be_able_to(:show, Registration.new)} it{ should_not be_able_to(:manage, registration)} - it{ should be_able_to(:create, Event)} + it{ should be_able_to(:new, Event.new(program: program_with_cfp)) } + it{ should_not be_able_to(:new, Event.new(program: program_without_cfp)) } + it{ should_not be_able_to(:create, Event.new(program: program_without_cfp))} it{ should be_able_to(:show, Event.new)} it{ should_not be_able_to(:manage, :any)} @@ -69,12 +73,14 @@ describe 'User' do context 'when user is signed in' do let(:user) { create(:user) } let(:user2) { create(:user) } + let(:event_user2) { create(:submitter, user: user2) } + let(:subscription) { create(:subscription, user: user) } let(:registration_public) { create(:registration, conference: conference_public, user: user) } let(:registration_not_public) { create(:registration, conference: conference_not_public, user: user) } - let(:user_event) { create(:event, users: [user]) } - let(:user_commercial) { create(:commercial, commercialable: user_event) } + let(:user_event_with_cfp) { create(:event, users: [user], program: program_with_cfp) } + let(:user_commercial) { create(:commercial, commercialable: user_event_with_cfp) } it{ should be_able_to(:manage, user) } @@ -87,11 +93,15 @@ describe 'User' do it{ should be_able_to(:create, Subscription.new(user_id: user.id)) } it{ should be_able_to(:destroy, subscription) } - it{ should be_able_to(:create, Event) } - it{ should be_able_to(:manage, user_event) } + it{ should be_able_to(:manage, user_event_with_cfp) } + it{ should_not be_able_to(:new, Event.new(program: program_without_cfp)) } + it{ should_not be_able_to(:create, Event.new(program: program_without_cfp)) } + it{ should_not be_able_to(:new, Event.new(program: program_with_cfp, event_users: [event_user2])) } + it{ should_not be_able_to(:create, Event.new(program: program_with_cfp, event_users: [event_user2])) } + it{ should_not be_able_to(:manage, event_unconfirmed) } - it{ should be_able_to(:create, user_event.commercials.new) } + it{ should be_able_to(:create, user_event_with_cfp.commercials.new) } it{ should be_able_to(:manage, user_commercial) } it{ should_not be_able_to(:manage, commercial_event_unconfirmed) } end @@ -109,7 +119,7 @@ describe 'User' do context 'when user has the role organizer' do let!(:my_conference) { create(:full_conference) } let(:role) { Role.find_by(name: 'organizer', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id], is_admin: false) } + let(:user) { create(:user, role_ids: [role.id]) } it{ should_not be_able_to(:destroy, my_conference.program) } it 'when there is a room assigned to an event' do @@ -175,7 +185,7 @@ describe 'User' do context 'when user has the role cfp' do let!(:my_conference) { create(:full_conference) } let(:role) { Role.find_by(name: 'cfp', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id], is_admin: false) } + let(:user) { create(:user, role_ids: [role.id]) } it{ should_not be_able_to([:create, :new], Conference.new) } it{ should_not be_able_to(:manage, my_conference) } @@ -230,7 +240,7 @@ describe 'User' do context 'when user has the role info_desk' do let!(:my_conference) { create(:full_conference) } let(:role) { Role.find_by(name: 'info_desk', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id], is_admin: false) } + let(:user) { create(:user, role_ids: [role.id]) } it{ should_not be_able_to([:create, :new], Conference.new) } it{ should_not be_able_to(:manage, my_conference) } @@ -285,7 +295,7 @@ describe 'User' do context 'when user has the role volunteers_coordinator' do let!(:my_conference) { create(:full_conference) } let(:role) { Role.find_by(name: 'volunteers_coordinator', resource: my_conference) } - let(:user) { create(:user, role_ids: [role.id], is_admin: false) } + let(:user) { create(:user, role_ids: [role.id]) } it{ should_not be_able_to([:create, :new], Conference.new) } it{ should_not be_able_to(:manage, my_conference) } diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb new file mode 100644 index 00000000..94cb6372 --- /dev/null +++ b/spec/models/comment_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe Commercial do + + describe '.find_since_last_login' do + it 'returns none if last_sign_in_at is nil' do + expect(Comment.find_since_last_login(create(:user))).to eq(Comment.none) + end + end +end diff --git a/spec/models/registration_spec.rb b/spec/models/registration_spec.rb index 1bf9e88f..af94a6ad 100644 --- a/spec/models/registration_spec.rb +++ b/spec/models/registration_spec.rb @@ -1,25 +1,92 @@ -#!/bin/env ruby -# encoding: utf-8 require 'spec_helper' describe 'Registration' do - describe 'validations' do + subject { create(:registration) } + let!(:user) { create(:user) } + let!(:conference) { create(:conference) } + let!(:registration1) { create(:registration, conference: conference, user: user) } + + describe 'validation' do it 'has a valid factory' do expect(build(:registration)).to be_valid end + it { is_expected.to validate_presence_of(:user) } + + it 'validates uniqueness of user in scope of conference' do + expect(build(:registration, conference: subject.conference, user: subject.user)).not_to be_valid + end + describe 'registration_limit_not_exceed' do it 'is not valid when limit exceeded' do - conference = build(:conference) conference.registration_limit = 1 - registration1 = build(:registration, conference: conference) - registration1.save - registration2 = build(:registration, conference: conference) - registration2.save - expect(conference.registrations.size).to be 1 - expect(registration2.valid?).to be false - expect(registration2.errors.full_messages).to eq(['Registration limit exceeded']) + expect { create(:registration, conference: conference, user: user) }.to raise_error + expect(user.registrations.size).to be 1 end end end + + describe 'association' do + it { is_expected.to belong_to(:user) } + it { is_expected.to belong_to(:conference) } + it { is_expected.to belong_to(:dietary_choice) } + it { is_expected.to have_and_belong_to_many(:social_events) } + it { is_expected.to have_and_belong_to_many(:events) } + it { is_expected.to have_and_belong_to_many(:qanswers) } + it { is_expected.to have_and_belong_to_many(:vchoices) } + it { is_expected.to have_many(:events_registrations) } + it { is_expected.to have_many(:workshops) } + end + + describe 'after create' do + after { subject.run_callbacks(:create) } + + # set_week and subscribe_to_conference are private methods + describe '#set_week' do + before { subject.created_at = Time.utc(2014, 5, 10) } + + it 'sets week of registration' do + expect(subject).to receive(:set_week) + expect(subject.week).to eq 18 + end + end + + describe '#subscribe_to_conference' do + it 'subscribes to conference' do + expect(subject).to receive(:subscribe_to_conference) + expect(subject.user.subscribed?(subject.conference)).to be true + end + end + + it 'sends registrations mail' do + expect(subject).to receive(:send_registration_mail) + end + end + + describe '#week' do + before { subject.created_at = Date.new(2014, 06, 30) } + + it 'returns week number of created_at' do + expect(subject.week).to eq(26) + end + end + + describe '#destroy_purchased_tickets' do + it 'destroys purchased tickets if tickets are purchased' do + create(:ticket_purchase, conference: conference, user: user) + expect(user.registrations.size).to be 1 + expect(user.ticket_purchases.size).to be 1 + registration1.destroy + expect(user.registrations.size).to be 0 + expect(user.ticket_purchases.size).to be 0 + end + + it 'destroys no tickets if no tickets are purchased' do + expect(user.registrations.size).to be 1 + expect(user.ticket_purchases.size).to be 0 + registration1.destroy + expect(user.registrations.size).to be 0 + expect(user.ticket_purchases.size).to be 0 + end + end end diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb new file mode 100644 index 00000000..9220416b --- /dev/null +++ b/spec/models/room_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe Room do + subject { create(:room) } + + describe 'validation' do + it { should validate_presence_of(:name) } + it { should validate_presence_of(:venue_id) } + it { should validate_numericality_of(:size).only_integer.is_greater_than(0).allow_nil } + end + + describe 'association' do + it { should belong_to(:venue) } + it { should have_many(:events).dependent(:nullify) } + end + + describe 'callback' do + after { subject.run_callbacks(:create) } + + it '#generate_guid' do + regex_base64 = %r{^(?:[A-Za-z_\-0-9+\/]{4}\n?)*(?:[A-Za-z_\-0-9+\/]{2}|[A-Za-z_\-0-9+\/]{3}=)?$} + expect(subject).to receive(:generate_guid) + expect(subject.guid).to match regex_base64 + end + end +end diff --git a/spec/models/sponsorship_level_spec.rb b/spec/models/sponsorship_level_spec.rb index 1ca073e1..9ca74b47 100644 --- a/spec/models/sponsorship_level_spec.rb +++ b/spec/models/sponsorship_level_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe SponsorshipLevel do - describe 'validations' do + describe 'validation' do it 'has a valid factory' do expect(build(:sponsorship_level)).to be_valid @@ -11,4 +11,31 @@ describe SponsorshipLevel do should validate_presence_of(:title) end end + + describe 'association' do + it { is_expected.to belong_to(:conference) } + it { is_expected.to have_many(:sponsors) } + end + + describe 'acts_as_list' do + let(:conference) { create(:conference) } + + before do + @first_sponsorship_level = create(:sponsorship_level, conference: conference) + @second_sponsorship_level = create(:sponsorship_level, conference: conference) + @second_sponsorship_level.move_higher + @third_sponsorship_level = create(:sponsorship_level, conference: conference) + end + + it 'is positions sponsorship_levels in order' do + expect(SponsorshipLevel.where(conference_id: conference.id).order(:position).map(&:id)) + .to eq [2, 1, 3] + end + + it 'maintains order after deleting one element' do + @first_sponsorship_level.destroy + expect(SponsorshipLevel.where(conference_id: conference.id).order(:position).map(&:id)) + .to eq [2, 3] + end + end end diff --git a/spec/models/target_spec.rb b/spec/models/target_spec.rb index 50a4103f..5297cabc 100644 --- a/spec/models/target_spec.rb +++ b/spec/models/target_spec.rb @@ -1,8 +1,11 @@ require 'spec_helper' describe Target do + let(:registration_target) { create(:target, target_count: 10, unit: Target.units[:registrations]) } + let(:submission_target) { create(:target, target_count: 10, unit: Target.units[:submissions]) } + let(:program_minutes_target) { create(:target, target_count: 300, unit: Target.units[:program_minutes]) } - describe 'validations' do + describe 'validation' do it 'has a valid factory' do expect(build(:target)).to be_valid end @@ -32,74 +35,130 @@ describe Target do end end + describe 'default scope' do + before do + @first_target = create(:target, due_date: 2.days.from_now) + @second_target = create(:target, due_date: 3.days.from_now) + end + + it 'orders by ascending due_date' do + expect(Target.all).to match_array [@first_target, @second_target] + end + end + + describe 'association' do + it { should belong_to(:conference) } + it { should belong_to(:campaign) } + end + describe '#get_progress' do - it 'returns zero if there are no registrations' do - conference = build(:conference) - target = build(:target, target_count: 10, unit: Target.units[:registrations]) - conference.targets = [target] - - expect(target.get_progress).to eq('0') + it 'returns zero, when there are no registrations' do + expect(registration_target.get_progress).to eq('0') end - it 'returns 10 if there one registrations of 10' do - conference = create(:conference) - target = create(:target, target_count: 10, unit: Target.units[:registrations]) - registration = create(:registration) + it 'returns 10, when there is 1 registration and the target is 10' do + create(:registration, conference: registration_target.conference) - conference.targets = [target] - conference.registrations = [registration] - - expect(target.get_progress).to eq('10') + expect(registration_target.get_progress).to eq('10') end - it 'returns zero if there are no submissions' do - conference = create(:conference) - target = build(:target, target_count: 10, unit: Target.units[:submissions]) - conference.targets = [target] - - expect(target.get_progress).to eq('0') + it 'returns zero, when there are no submissions' do + expect(submission_target.get_progress).to eq('0') end - it 'returns 10 if there one submissions of 10' do - conference = create(:conference) - target = create(:target, target_count: 10, unit: Target.units[:submissions]) - event = create(:event) + it 'returns 10, when there is 1 submission and the target is 10' do + create(:event, program: submission_target.conference.program) - conference.targets = [target] - conference.program.events = [event] - - expect(target.get_progress).to eq('10') + expect(submission_target.get_progress).to eq('10') end - it 'returns zero if there are no program minutes' do - conference = create(:conference) - target = build(:target, target_count: 10, unit: Target.units[:program_minutes]) - conference.targets = [target] - - expect(target.get_progress).to eq('0') + it 'returns zero, when there are no program minutes' do + expect(program_minutes_target.get_progress).to eq('0') end - it 'returns 10 if there are 30 program minutes of 300' do - conference = create(:conference) - target = create(:target, target_count: 300, unit: Target.units[:program_minutes]) - event = create(:event) + it 'returns 10, when there are 30 program minutes and the target is 300' do + create(:event, program: program_minutes_target.conference.program) - conference.targets = [target] - conference.program.events = [event] + expect(program_minutes_target.get_progress).to eq('10') + end + end - expect(target.get_progress).to eq('10') + describe '#get_campaign' do + context 'submissions' do + before do + submission_target.campaign = create(:campaign, name: 'Submission Campaign', conference: submission_target.conference) + submission_target.created_at = Time.utc(2014, 5, 10) + submission_target.due_date = Date.today + 4.days + allow(submission_target.campaign).to receive(:submissions_count) { 20 } + end + + it 'returns a hash with values of the corresponding campaign submissions' do + result = { + 'target_name' => "10 Submissions by #{Date.today + 4.days}", + 'campaign_name' => 'Submission Campaign', + 'value' => 20, + 'unit' => 'Submission', + 'created_at' => Time.utc(2014, 5, 10).in_time_zone, + 'progress' => '200', + 'days_left' => 4 + } + + expect(submission_target.get_campaign).to eq result + end + end + + context 'registrations' do + before do + registration_target.campaign = create(:campaign, name: 'Registration Campaign', conference: registration_target.conference) + registration_target.created_at = Time.utc(2014, 5, 10) + registration_target.due_date = Date.today + 4.days + allow(registration_target.campaign).to receive(:registrations_count) { 20 } + end + + it 'returns a hash with values of the corresponding campaign registrations' do + result = { + 'target_name' => "10 Registrations by #{Date.today + 4.days}", + 'campaign_name' => 'Registration Campaign', + 'value' => 20, + 'unit' => 'Registration', + 'created_at' => Time.utc(2014, 5, 10).in_time_zone, + 'progress' => '200', + 'days_left' => 4 + } + + expect(registration_target.get_campaign).to eq result + end + end + + context 'program_minutes' do + before do + program_minutes_target.campaign = create(:campaign, name: 'Program Campaign', conference: program_minutes_target.conference) + program_minutes_target.created_at = Time.utc(2014, 5, 10) + program_minutes_target.due_date = Date.today + 4.days + allow(program_minutes_target.conference).to receive(:current_program_minutes) { 20 } + end + + it 'returns a hash with values of the corresponding campaign program minutes' do + result = { + 'target_name' => "300 Program minutes by #{Date.today + 4.days}", + 'campaign_name' => 'Program Campaign', + 'value' => 20, + 'unit' => 'Program minute', + 'created_at' => Time.utc(2014, 5, 10).in_time_zone, + 'progress' => '7', + 'days_left' => 4 + } + + expect(program_minutes_target.get_campaign).to eq result + end end end describe '#to_s' do it 'returns a string in the correct format' do - conference = build(:conference) - target = build(:target, target_count: 10, unit: Target.units[:registrations]) - conference.targets = [target] - result = "10 Registrations by #{14.days.from_now.to_date}" - expect(target.to_s).to eq(result) + expect(registration_target.to_s).to eq(result) end end end diff --git a/spec/models/ticket_spec.rb b/spec/models/ticket_spec.rb index 2b673fbb..fc67ff3d 100644 --- a/spec/models/ticket_spec.rb +++ b/spec/models/ticket_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' describe Ticket do let(:conference) { create(:conference) } - let(:ticket) { create(:ticket, price: 50, conference: conference) } + let(:ticket) { create(:ticket, price: 50, price_currency: 'USD', conference: conference) } let(:user) { create(:user) } - describe 'validations' do + describe 'validation' do it 'has a valid factory' do expect(build(:ticket)).to be_valid end @@ -33,6 +33,22 @@ describe Ticket do it 'is valid with a price_cents greater than zero' do should allow_value(1).for(:price_cents) end + + it 'is not valid if tickets of conference do not have same currency' do + conflicting_currency_ticket = build(:ticket, + conference: ticket.conference, + price_currency: 'INR') + expected_error_message = 'Price currency is different from the existing tickets of this conference.' + + expect(conflicting_currency_ticket).not_to be_valid + expect(conflicting_currency_ticket.errors.full_messages).to eq([expected_error_message]) + end + end + + describe 'association' do + it { should belong_to(:conference) } + it { should have_many(:ticket_purchases).dependent(:destroy) } + it { should have_many(:buyers).through(:ticket_purchases).source(:user) } end describe '#bought?' do @@ -43,11 +59,29 @@ describe Ticket do expect(ticket.bought?(user)).to eq(true) end - it 'returns true if the user has bought this ticket' do + it 'returns false if the user has not bought this ticket' do expect(ticket.bought?(user)).to eq(false) end end + describe '#paid?' do + let!(:ticket_purchase) { create(:ticket_purchase, user: user, ticket: ticket) } + + context 'user has paid' do + before { ticket_purchase.update_attributes(paid: true) } + + it 'returns true' do + expect(ticket.paid?(user)).to eq(true) + end + end + + context 'user has not paid' do + it 'returns false' do + expect(ticket.paid?(user)).to eq(false) + end + end + end + describe '#quantity_bought_by' do it 'returns the correct value if the user has bought this ticket' do create(:ticket_purchase, @@ -68,7 +102,7 @@ describe Ticket do user: user, ticket: ticket, quantity: 20) - expect(ticket.total_price(user)).to eq(Money.new(20 * ticket.price_cents, 'USD')) + expect(ticket.total_price(user)).to eq(Money.new(100000, 'USD')) end it 'returns zero if the user has not bought this ticket' do @@ -76,17 +110,37 @@ describe Ticket do end end - describe 'self#total_price' do - it 'returns the correct value if the user has bought this ticket' do - create(:ticket_purchase, - user: user, - ticket: ticket, - quantity: 20) - expect(Ticket.total_price(conference, user)).to eq(Money.new(20 * ticket.price_cents, 'USD')) - end + describe 'self.total_price' do + let(:diversity_supporter_ticket) { create(:ticket, conference: conference, price: 500) } - it 'returns zero if the user has not bought this ticket' do - expect(Ticket.total_price(conference, user)).to eq(Money.new(0, 'USD')) + describe 'user has bought' do + context 'no tickets' do + it 'returns zero' do + expect(Ticket.total_price(conference, user)).to eq(Money.new(0, 'USD')) + end + end + + context 'one type of ticket' do + before do + create(:ticket_purchase, ticket: ticket, user: user, quantity: 20) + end + + it 'returns the correct total price' do + expect(Ticket.total_price(conference, user)).to eq(Money.new(100000, 'USD')) + end + end + + context 'multiple types of tickets' do + before do + create(:ticket_purchase, ticket: ticket, user: user, quantity: 20) + create(:ticket_purchase, ticket: diversity_supporter_ticket, user: user, quantity: 2) + end + + it 'returns the correct total price' do + total_price = Money.new(200000, 'USD') + expect(Ticket.total_price(conference, user)).to eq(total_price) + end + end end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 36c6153a..bbfd5f1d 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe User do # It is necessary to use bang version of let to build roles before user - let!(:user_admin) { create(:user) } + let!(:user_admin) { create(:admin) } let!(:conference) { create(:conference) } let!(:organizer_role) { Role.find_by(name: 'organizer', resource: conference) } let!(:cfp_role) { Role.find_by(name: 'cfp', resource: conference) } @@ -33,6 +33,13 @@ describe User do expect(another_user.roles[1]).to eq(cfp_role) end + describe '#name' do + it 'returns the username as name if there is not name' do + user = create(:user, name: nil) + expect(user.name).to eq(user.username) + end + end + describe '#has_role?' do describe 'when user has a role' do it 'returns true when the user has the role' do @@ -59,7 +66,7 @@ describe User do deleted_user = create(:user, email: 'deleted@localhost.osem', name: 'User deleted') expect(deleted_user.is_admin).to be false - user_after_deleted = create(:user) + user_after_deleted = create(:admin) expect(user_after_deleted.is_admin).to be true end end diff --git a/vendor/assets/javascripts/bootstrap-markdown.js b/vendor/assets/javascripts/bootstrap-markdown.js deleted file mode 100644 index 2256df64..00000000 --- a/vendor/assets/javascripts/bootstrap-markdown.js +++ /dev/null @@ -1,1293 +0,0 @@ -/* =================================================== - * bootstrap-markdown.js v2.5.0 - * http://github.com/toopay/bootstrap-markdown - * =================================================== - * Copyright 2013 Taufan Aditya - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ========================================================== */ - -!function ($) { - - "use strict"; // jshint ;_; - - - /* MARKDOWN CLASS DEFINITION - * ========================== */ - - var Markdown = function (element, options) { - // Class Properties - this.$ns = 'bootstrap-markdown' - this.$element = $(element) - this.$editable = {el:null, type:null,attrKeys:[], attrValues:[], content:null} - this.$options = $.extend(true, {}, $.fn.markdown.defaults, options, this.$element.data(), this.$element.data('options')) - this.$oldContent = null - this.$isPreview = false - this.$editor = null - this.$textarea = null - this.$handler = [] - this.$callback = [] - this.$nextTab = [] - - this.showEditor() - } - - Markdown.prototype = { - - constructor: Markdown - - , __alterButtons: function(name,alter) { - var handler = this.$handler, isAll = (name == 'all'),that = this - - $.each(handler,function(k,v) { - var halt = true - if (isAll) { - halt = false - } else { - halt = v.indexOf(name) < 0 - } - - if (halt == false) { - alter(that.$editor.find('button[data-handler="'+v+'"]')) - } - }) - } - - , __buildButtons: function(buttonsArray, container) { - var i, - ns = this.$ns, - handler = this.$handler, - callback = this.$callback - - for (i=0;i', { - 'class': 'btn-group' - }) - - for (z=0;z ' - +this.__localize(btnText) - +'') - - // Register handler and callback - handler.push(buttonHandler) - callback.push(button.callback) - } - - // Attach the button group into container dom - container.append(btnGroupContainer) - } - } - - return container - } - , __setListener: function() { - // Set size and resizable Properties - var hasRows = typeof this.$textarea.attr('rows') != 'undefined', - maxRows = this.$textarea.val().split("\n").length > 5 ? this.$textarea.val().split("\n").length : '5', - rowsVal = hasRows ? this.$textarea.attr('rows') : maxRows - - this.$textarea.attr('rows',rowsVal) - if (this.$options.resize) { - this.$textarea.css('resize',this.$options.resize) - } - - this.$textarea - .on('focus', $.proxy(this.focus, this)) - .on('keypress', $.proxy(this.keypress, this)) - .on('keyup', $.proxy(this.keyup, this)) - .on('change', $.proxy(this.change, this)) - - if (this.eventSupported('keydown')) { - this.$textarea.on('keydown', $.proxy(this.keydown, this)) - } - - // Re-attach markdown data - this.$textarea.data('markdown',this) - } - - , __handle: function(e) { - var target = $(e.currentTarget), - handler = this.$handler, - callback = this.$callback, - handlerName = target.attr('data-handler'), - callbackIndex = handler.indexOf(handlerName), - callbackHandler = callback[callbackIndex] - - // Trigger the focusin - $(e.currentTarget).focus() - - callbackHandler(this) - - // Trigger onChange for each button handle - this.change(this); - - // Unless it was the save handler, - // focusin the textarea - if (handlerName.indexOf('cmdSave') < 0) { - this.$textarea.focus() - } - - e.preventDefault() - } - - , __localize: function(string) { - var messages = $.fn.markdown.messages, - language = this.$options.language - if ( - typeof messages !== 'undefined' && - typeof messages[language] !== 'undefined' && - typeof messages[language][string] !== 'undefined' - ) { - return messages[language][string]; - } - return string; - } - - , showEditor: function() { - var instance = this, - textarea, - ns = this.$ns, - container = this.$element, - originalHeigth = container.css('height'), - originalWidth = container.css('width'), - editable = this.$editable, - handler = this.$handler, - callback = this.$callback, - options = this.$options, - editor = $( '
', { - 'class': 'md-editor', - click: function() { - instance.focus() - } - }) - - // Prepare the editor - if (this.$editor == null) { - // Create the panel - var editorHeader = $('
', { - 'class': 'md-header btn-toolbar' - }) - - // Merge the main & additional button groups together - var allBtnGroups = [] - if (options.buttons.length > 0) allBtnGroups = allBtnGroups.concat(options.buttons[0]) - if (options.additionalButtons.length > 0) allBtnGroups = allBtnGroups.concat(options.additionalButtons[0]) - - // Reduce and/or reorder the button groups - if (options.reorderButtonGroups.length > 0) { - allBtnGroups = allBtnGroups - .filter(function(btnGroup) { - return options.reorderButtonGroups.indexOf(btnGroup.name) > -1 - }) - .sort(function(a, b) { - if (options.reorderButtonGroups.indexOf(a.name) < options.reorderButtonGroups.indexOf(b.name)) return -1 - if (options.reorderButtonGroups.indexOf(a.name) > options.reorderButtonGroups.indexOf(b.name)) return 1 - return 0 - }) - } - - // Build the buttons - if (allBtnGroups.length > 0) { - editorHeader = this.__buildButtons([allBtnGroups], editorHeader) - } - - editor.append(editorHeader) - - // Wrap the textarea - if (container.is('textarea')) { - container.before(editor) - textarea = container - textarea.addClass('md-input') - editor.append(textarea) - } else { - var rawContent = (typeof toMarkdown == 'function') ? toMarkdown(container.html()) : container.html(), - currentContent = $.trim(rawContent) - - // This is some arbitrary content that could be edited - textarea = $('