diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..7c1e13a680 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.rubocop.yml b/.rubocop.yml index c7d1bf7d37..230d34d45d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,11 +1,14 @@ +require: rubocop-performance + AllCops: TargetRubyVersion: 2.5 Exclude: - "bin/**/*" - "db/schema.rb" - "db/migrate/**/*" + - "node_modules/**/*" -FrozenStringLiteralComment: +Layout: Enabled: false Metrics/LineLength: @@ -25,34 +28,8 @@ Metrics/BlockLength: Exclude: - "**/*_spec.rb" -Style/AndOr: - Enabled: false - -Style/Documentation: - Enabled: false - -Style/SymbolProc: - Enabled: false - -# I'm a fan of defining convenience methods in single lines -Style/SingleLineMethods: - Enabled: false - -# https://anti-pattern.com/always-use-double-quoted-strings-in-ruby -# All future updates should use double quotes, don't enforce so there aren't a ton of errors -Style/StringLiterals: - EnforcedStyle: double_quotes # Always do it, lower cost cognitively - Enabled: false - -Style/NumericPredicate: - Enabled: false - -Layout/EmptyLineAfterGuardClause: - Enabled: false - -NumericLiterals: - Enabled: false - -ParameterLists: +Metrics/ParameterLists: CountKeywordArgs: false +Style: + Enabled: false diff --git a/Gemfile b/Gemfile index 8136b30cef..84af2e58d8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,124 +1,124 @@ -source 'https://rubygems.org' -# If you bump the Ruby version, make sure to update the Vagrantfile appropriately +source "https://rubygems.org" +# If you bump the Ruby version, make sure to update the Vagrantfile appropriately ruby "2.5.1" gem "rails", "4.2.11" -gem 'pg' -gem 'jquery-rails' -gem 'bcrypt', '~> 3.1.7' -gem 'active_model_serializers', '~> 0.9.3' -gem 'aws-sdk', '~> 1.33' +gem "active_model_serializers", "~> 0.9.3" +gem "aws-sdk", "~> 1.33" +gem "bcrypt", "~> 3.1.7" +gem "jquery-rails" +gem "pg" # Speed -gem 'fast_blank', '~> 1.0' +gem "fast_blank", "~> 1.0" # Redis and redis dependents gem "hiredis" gem "redis", ">= 3.2.0", require: ["redis", "redis/connection/hiredis"] +gem "rollout" # Feature flags gem "sidekiq", "~> 5.1.0" # Background processing gem "sidekiq-failures" -gem 'rollout' # Feature flags -gem 'soulheart', '~> 0.3.0' - -gem 'rack-contrib' -gem 'unicorn' # Use Puma as the app server -gem 'unicorn-worker-killer' -gem 'geocoder' -gem 'money-rails' -gem 'i18n' -gem 'hamlit' -gem 'journey', '~> 1.0.3' -gem 'kramdown' # Markdown -gem 'redcarpet' # Something to do with swagger? Guess we needed another markdown parser -gem 'kaminari' # pagination -gem 'pg_search' -gem 'nokogiri', '~> 1.8.1' +gem "soulheart", "~> 0.3.0" + gem "carrierwave", "~> 0.11.2" gem "carrierwave_backgrounder" -gem 'rmagick' -gem 'mini_magick' # a smaller implementation of rmagick, required for rqrcode -gem 'rqrcode-rails3' -gem 'libv8', '~> 3.16.14.7' -gem "stripe" -gem 'high_voltage' -gem 'omniauth-facebook' -gem 'omniauth-strava' -gem 'omniauth', '~> 1.3.1' +gem "dalli" +gem "draper", require: false +gem "eventmachine" gem "fog-aws" -gem 'dalli' -gem 'draper', require: false -gem 'eventmachine' -gem 'httparty' +gem "geocoder" +gem "hamlit" +gem "high_voltage" +gem "httparty" +gem "i18n" +gem "journey", "~> 1.0.3" +gem "kaminari" # pagination +gem "kramdown" # Markdown +gem "libv8", "~> 3.16.14.7" +gem "mini_magick" # a smaller implementation of rmagick, required for rqrcode +gem "money-rails" +gem "nokogiri", "~> 1.8.1" +gem "omniauth", "~> 1.3.1" +gem "omniauth-facebook" +gem "omniauth-strava" +gem "paranoia" +gem "pg_search" +gem "rack-contrib" +gem "redcarpet" # Something to do with swagger? Guess we needed another markdown parser +gem "rmagick" +gem "rqrcode-rails3" gem "sitemap_generator", "~> 6" -gem 'paranoia' +gem "stripe" +gem "unicorn" # Use Puma as the app server +gem "unicorn-worker-killer" # Making other files -gem "wkhtmltopdf-binary" -gem "wicked_pdf" gem "axlsx" # Write Excel files - OrganizationExports +gem "wicked_pdf" +gem "wkhtmltopdf-binary" # Rails upgrade gem "where-or" # backports rails 5 or query support - TODO: Rails 5 update, remove # API wrappers -gem 'twitter' # Twitter. For rendering tweets -gem 'simple_spark' # Sparkpost gem - we use it to send newsletters +gem "simple_spark" # Sparkpost gem - we use it to send newsletters +gem "twitter" # Twitter. For rendering tweets # OAuth provider, Grape, associated parts of API V2 -gem 'doorkeeper', '~> 3.1.0' -gem 'wine_bouncer' -gem 'grape', '~> 0.14.0' -gem 'grape-active_model_serializers', '~> 1.4.0' -gem 'grape-swagger', '~> 0.10.4' -gem 'swagger-ui_rails' -gem 'api-pagination' +gem "api-pagination" +gem "doorkeeper", "~> 3.1.0" +gem "grape", "~> 0.14.0" +gem "grape-active_model_serializers", "~> 1.4.0" +gem "grape-swagger", "~> 0.10.4" +gem "swagger-ui_rails" +gem "wine_bouncer" # Secure things -gem 'rack-throttle' -gem 'secure_headers', '~> 2.5.0' +gem "rack-throttle" +gem "secure_headers", "~> 2.5.0" # Frontend -gem 'sprockets-rails', '~> 3.0.4' -gem 'coffee-rails' -gem 'therubyracer' -gem 'uglifier' -gem 'premailer-rails' # Inline styles for email -gem 'backbone-on-rails', '~>0.9.10.0' # Legacy js -gem 'chartkick' # Display charts -gem 'groupdate' # Required for charts -gem 'bootstrap', '~> 4.0.0.alpha3' # Bootstrap 4 - used for revised stylesheets -gem 'jquery-datatables-rails', '~>3.4.0' -gem 'webpacker', '~> 4.x' +gem "backbone-on-rails", "~>0.9.10.0" # Legacy js +gem "bootstrap", "~> 4.0.0.alpha3" # Bootstrap 4 - used for revised stylesheets +gem "chartkick" # Display charts +gem "coffee-rails" +gem "groupdate" # Required for charts +gem "jquery-datatables-rails", "~>3.4.0" +gem "premailer-rails" # Inline styles for email +gem "sprockets-rails", "~> 3.0.4" +gem "therubyracer" +gem "uglifier" +gem "webpacker", "~> 4.x" # Show performance metrics -gem 'stackprof', require: false -gem 'memory_profiler', require: false -gem 'flamegraph', require: false -gem 'rack-mini-profiler', require: false # If you can't see it you can't make it better - -gem 'responders', '~> 2.0' # required because of class level respond_to blocks (API v1) -gem 'thor', '0.19.1' # Locking it; http://stackoverflow.com/questions/40986923/meaning-of-expected-string-default-value-for-on-ruby-on-rails - -gem 'bundler', '>= 1.8.4' # required for rails-assets.org - JS and CSS assets -source 'https://rails-assets.org' do # JS land is crazy, so lock everything - gem 'rails-assets-lodash', '~> 4.9.0' - gem 'rails-assets-tether', '~> 1.1.0' # Required by bootstrap 4, but not included :( - gem 'rails-assets-mustache', '~> 2.2.1' - gem 'rails-assets-jquery.dirtyforms', '~> 2.0.0' # Alert on attempts to leave with dirt on forms - gem 'rails-assets-selectize', '~> 0.12.1' # Manually configured scss - gem 'rails-assets-select2', '~> 4.0.3' # Use select2 for a few things, it's a bit better sometimes - gem 'rails-assets-Stickyfill', '~> 1.1.3' # Affix bike edit menu - gem 'rails-assets-mailcheck', '~> 1.1.2' # Check for common email errors - gem 'rails-assets-waypoints', '~> 3.1.1' # For documentation pages - gem 'rails-assets-moment', '~> 2.18.1' # Javascript Time - localizing :) - gem 'rails-assets-moment-timezone', '~> 0.5.13' # Timezones for moment +gem "flamegraph", require: false +gem "memory_profiler", require: false +gem "rack-mini-profiler", require: false # If you can't see it you can't make it better +gem "stackprof", require: false + +gem "responders", "~> 2.0" # required because of class level respond_to blocks (API v1) +gem "thor", "0.19.1" # Locking it; http://stackoverflow.com/questions/40986923/meaning-of-expected-string-default-value-for-on-ruby-on-rails + +gem "bundler", ">= 1.8.4" # required for rails-assets.org - JS and CSS assets +source "https://rails-assets.org" do # JS land is crazy, so lock everything + gem "rails-assets-jquery.dirtyforms", "~> 2.0.0" # Alert on attempts to leave with dirt on forms + gem "rails-assets-lodash", "~> 4.9.0" + gem "rails-assets-mailcheck", "~> 1.1.2" # Check for common email errors + gem "rails-assets-moment", "~> 2.18.1" # Javascript Time - localizing :) + gem "rails-assets-moment-timezone", "~> 0.5.13" # Timezones for moment + gem "rails-assets-mustache", "~> 2.2.1" + gem "rails-assets-select2", "~> 4.0.3" # Use select2 for a few things, it's a bit better sometimes + gem "rails-assets-selectize", "~> 0.12.1" # Manually configured scss + gem "rails-assets-Stickyfill", "~> 1.1.3" # Affix bike edit menu + gem "rails-assets-tether", "~> 1.1.0" # Required by bootstrap 4, but not included :( + gem "rails-assets-waypoints", "~> 3.1.1" # For documentation pages # Sortable breaks assets:precompile, so it's included manually # gem 'rails-assets-jquery-sortable', '~> 0.9.12' # Sort photo order end -gem 'grape_logging' # Grape logging. Also how we pass it to lograge. Always used, not just in Prod -gem 'lograge' # Structure log data, put it in single lines to improve the functionality -gem 'logstash-event' # Use logstash format for logging data +gem "grape_logging" # Grape logging. Also how we pass it to lograge. Always used, not just in Prod +gem "lograge" # Structure log data, put it in single lines to improve the functionality +gem "logstash-event" # Use logstash format for logging data group :production do gem "honeybadger", "~> 2.0" # Error monitoring @@ -127,31 +127,34 @@ end group :development do # gem 'test-unit', '~> 3.0' - gem 'rerun' - gem 'bullet' + gem "bullet" + gem "rerun" # gem 'pry-rails' end group :development, :test do + gem "database_cleaner" + gem "dotenv-rails" + gem "foreman" gem "rb-fsevent", "~> 0.9.1" gem "rspec", "~> 3.3.0" gem "rspec-rails", "~> 3.3.0" gem "rspec_junit_formatter" # For circle ci + gem "rubocop", "~> 0.67", require: false + gem "rubocop-daemon", "~> 0.3.1", require: false + gem "rubocop-performance", "~> 1.1.0", require: false + gem "rufo", "~> 0.6.0", require: false gem "shoulda-matchers", "~> 2.8.0" - gem "foreman" - gem "database_cleaner" - gem "dotenv-rails" end group :test do - gem "simplecov", require: false + gem "airborne" gem "factory_bot_rails" - gem "rspec-sidekiq" gem "guard" gem "guard-rspec" - gem "rubocop", require: false gem "guard-rubocop", require: false + gem "rspec-sidekiq" + gem "simplecov", require: false gem "vcr" # Stub external HTTP requests gem "webmock" # mocking for VCR - gem "airborne" end diff --git a/Gemfile.lock b/Gemfile.lock index eb254fef81..9014446a9b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -315,17 +315,16 @@ GEM omniauth-strava (0.0.6) omniauth (~> 1.0) omniauth-oauth2 (~> 1.0) - parallel (1.14.0) + parallel (1.17.0) paranoia (2.1.5) activerecord (~> 4.0) - parser (2.6.0.0) + parser (2.6.2.1) ast (~> 2.4.0) pg (0.18.4) pg_search (1.0.6) activerecord (>= 3.1) activesupport (>= 3.1) arel - powerpack (0.1.2) premailer (1.8.7) css_parser (>= 1.4.5) htmlentities (>= 4.0.0) @@ -447,18 +446,22 @@ GEM rspec-support (3.3.0) rspec_junit_formatter (0.4.1) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.65.0) + rubocop (0.67.2) jaro_winkler (~> 1.5.1) parallel (~> 1.10) parser (>= 2.5, != 2.5.1.1) - powerpack (~> 0.1) psych (>= 3.1.0) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.4.0) + unicode-display_width (>= 1.4.0, < 1.6) + rubocop-daemon (0.3.1) + rubocop + rubocop-performance (1.1.0) + rubocop (>= 0.67.0) ruby-progressbar (1.10.0) ruby_dep (1.5.0) rubyzip (1.0.0) + rufo (0.6.0) safe_yaml (1.0.4) sass (3.4.22) sass-rails (5.0.4) @@ -533,7 +536,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.5) - unicode-display_width (1.4.1) + unicode-display_width (1.5.0) unicorn (5.4.1) kgio (~> 2.6) raindrops (~> 0.7) @@ -655,7 +658,10 @@ DEPENDENCIES rspec-rails (~> 3.3.0) rspec-sidekiq rspec_junit_formatter - rubocop + rubocop (~> 0.67) + rubocop-daemon (~> 0.3.1) + rubocop-performance (~> 1.1.0) + rufo (~> 0.6.0) secure_headers (~> 2.5.0) shoulda-matchers (~> 2.8.0) sidekiq (~> 5.1.0) diff --git a/README.markdown b/README.markdown index 2ac72ff317..7cdc11ef4c 100644 --- a/README.markdown +++ b/README.markdown @@ -51,20 +51,64 @@ This explanation assumes you're familiar with developing Ruby on Rails applicati ## Testing - + We use [RSpec](https://github.com/rspec/rspec) and [Guard](https://github.com/guard/guard) for testing. - + - Run the test suit in the background with `bundle exec guard` - You may have to manually add the fuzzystrmatch extension, which we use for near serial searches, to your databases. The migration should take care of this but sometimes doesn't. Open the databases in postgres (`psql bikeindex_development` and `psql bikeindex_test`) and add the extension. - + ``` CREATE EXTENSION fuzzystrmatch; ``` +## Code Hygiene + +We use the following tools to automate code formatting and linting: + +- [EditorConfig](https://editorconfig.org/) +- [Rufo](https://github.com/ruby-formatter/rufo) +- [Rubocop](https://github.com/rubocop-hq/rubocop) +- [ESlint](https://eslint.org/) + +### EditorConfig + +EditorConfig ensures whitespace consistency. See the [Download a +Plugin][editorconfig-plugin] section of the EditorConfig docs to find a plugin +appropriate to your editor. + +[editorconfig-plugin]: https://editorconfig.org/#download + +### Rufo + +Rufo is an opinionated Ruby formatter we use to maintain consistent style with +minimum configuration. See the [Editor support][rufo-plugin] section of the +project README to find a suitable editor plugin. + +[rufo-plugin]: https://github.com/ruby-formatter/rufo#editor-support + +### RuboCop + +RuboCop is configured to ignore Ruby style and layout (deferring to Rufo) and focus +on code complexity, performance, and suggested best practices. + +To run it from the command line, issue `bundle exec rubocop`, optionally passing +a specific file(s). For a performance boost, you can also start a rubocop daemon +with `bundle exec rubocop-daemon start`, in which case you'd lint with +`bundle exec rubocop-daemon exec`. + +See the [Editor integration][rubocop-editor] section of the rubocop docs to find +an appropriate plugin for on-the-fly linting. + +[rubocop-editor]: https://rubocop.readthedocs.io/en/latest/integration_with_other_tools/#editor-integration + +### ESLint + +ESlint is configured to run on project JavaScript. To run it, issue `yarn lint`. + ## Vagrant development box -In general, we recommend installing and running the app without Vagrant for local development +In general, we recommend installing and running the app without Vagrant for local development If, however, you would prefer to have a virtual environment, this repository contains a Vagrantfile which is used to automatically set up and configure a virtual local (Ubuntu Xenial) development environment with all of the required dependencies preinstalled. diff --git a/Rakefile b/Rakefile index 08a15f6779..189fb6be8c 100644 --- a/Rakefile +++ b/Rakefile @@ -2,15 +2,16 @@ # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. -require File.expand_path('../config/application', __FILE__) +require File.expand_path("../config/application", __FILE__) -require 'sitemap_generator/tasks' +require "sitemap_generator/tasks" module TempFixForRakeLastComment def last_comment last_description end end + Rake::Application.send :include, TempFixForRakeLastComment Bikeindex::Application.load_tasks diff --git a/app/assets/javascripts/bike_index.js.coffee b/app/assets/javascripts/bike_index.js.coffee index db39abe020..cdbd5e41a4 100644 --- a/app/assets/javascripts/bike_index.js.coffee +++ b/app/assets/javascripts/bike_index.js.coffee @@ -31,7 +31,7 @@ updateInvoiceCalculations = -> if recurring.length > 0 recurringCost = recurring.reduce (x,y) -> x+y else - recurringCost = 0 + recurringCost = 0 oneTime = $(".paidFeatureCheck input.oneTime:checked").get().map (i) -> parseInt($(i).attr("data-amount"), 10) if oneTime.length > 0 oneTimeCost = oneTime.reduce (x,y) -> x+y @@ -60,9 +60,9 @@ $(document).ready -> new BikeIndex.Views.Global if document.getElementById('home_headies') - new BikeIndex.Views.Home + new BikeIndex.Views.Home if document.getElementById('news_display') - new BikeIndex.Views.NewsDisplay + new BikeIndex.Views.NewsDisplay else if document.getElementById('documentation-menu') new BikeIndex.Views.DocumentationIndex @@ -72,7 +72,7 @@ $(document).ready -> new BikeIndex.Views.ContentWhere if document.getElementById('manufacturers-list') new BikeIndex.Views.ContentManufacturers - + else if document.getElementById('choose-registration-type') new BikeIndex.Views.BikesChooseRegistration @@ -90,7 +90,7 @@ $(document).ready -> else if document.getElementById('user-home-page') new BikeIndex.Views.DataTables - + else if document.getElementById('edit-bike-form') new BikeIndex.Views.BikesEdit @@ -117,10 +117,10 @@ $(document).ready -> new BikeIndex.Views.AdminGraphs else if document.getElementById('invoiceForm') initializeInvoiceForm() - + else if document.getElementById('photo-page') new BikeIndex.Views.PhotosIndex if document.getElementById('multi_serial_search') new BikeIndex.Views.StolenMultiSerialSearch - + diff --git a/app/assets/javascripts/external_scripts/are-you-sure.js.coffee b/app/assets/javascripts/external_scripts/are-you-sure.js.coffee index 29b58496b9..b922d67ed1 100644 --- a/app/assets/javascripts/external_scripts/are-you-sure.js.coffee +++ b/app/assets/javascripts/external_scripts/are-you-sure.js.coffee @@ -9,7 +9,7 @@ # * Author: chris.dance@papercut.com # * Version: 1.5.0 # * Date: 15th Nov 2013 -# +# (($) -> $.fn.areYouSure = (options) -> settings = $.extend( @@ -48,7 +48,7 @@ isDirty = false $form = $(this).parents("form") - + # Test on the target first as it's the most likely to be dirty. isDirty = true if isFieldDirty($(evt.target)) unless isDirty @@ -63,7 +63,7 @@ markDirty = ($form, isDirty) -> changed = isDirty isnt $form.hasClass(settings.dirtyClass) $form.toggleClass settings.dirtyClass, isDirty - + # Fire change event if required if changed settings.change.call $form, $form if settings.change @@ -86,7 +86,7 @@ unless settings.silent $(window).bind "beforeunload", -> $dirtyForms = $("form").filter("." + settings.dirtyClass) - + # $dirtyForms.removeClass(settings.dirtyClass); // Prevent multiple calls? settings.message if $dirtyForms.length > 0 @@ -99,7 +99,7 @@ $form.bind "reset", -> markDirty $form, false - + # Add a custom events $form.bind "rescan.areYouSure", rescan $form.bind "reinitialize.areYouSure", reinitialize diff --git a/app/assets/javascripts/external_scripts/embed_script.js.coffee b/app/assets/javascripts/external_scripts/embed_script.js.coffee index 6006a27731..08d6add07b 100644 --- a/app/assets/javascripts/external_scripts/embed_script.js.coffee +++ b/app/assets/javascripts/external_scripts/embed_script.js.coffee @@ -72,7 +72,7 @@ updateSerial = (e) -> if $(e.target).prop('checked') == true $('#bike_serial_number').val('absent').addClass('absent-serial') else - $('#bike_serial_number').val('').removeClass('absent-serial') + $('#bike_serial_number').val('').removeClass('absent-serial') optionalFormUpdate = (e) -> # $(@).find('a').data('target') @@ -93,7 +93,7 @@ otherManufacturerDisplay = (current_value) -> if current_value == expand_value # show the bugger! hidden_other.slideDown().addClass('unhidden') - else + else # if it's visible, clear it and slide up if hidden_other.hasClass('unhidden') hidden_other.find('input').selectize()[0].selectize.setValue('') @@ -131,7 +131,7 @@ $(document).ready -> $('#bike_has_no_serial').change (e) -> updateSerial(e) - + $('#alert-block .close').click -> $('#alert-block').fadeOut('fast') @@ -162,9 +162,9 @@ $(document).ready -> # Update any hidden fields with current timezone window.timezone ||= moment.tz.guess() $(".hiddenFieldTimezone").val(window.timezone) - + # prevent double posting - $('#new_bike').submit -> + $('#new_bike').submit -> $this = $(this) if $this.data().isSubmitted return false diff --git a/app/assets/javascripts/external_scripts/embed_user_script.js.coffee b/app/assets/javascripts/external_scripts/embed_user_script.js.coffee index f5278c97fb..ee1ac88a21 100644 --- a/app/assets/javascripts/external_scripts/embed_user_script.js.coffee +++ b/app/assets/javascripts/external_scripts/embed_user_script.js.coffee @@ -3,7 +3,7 @@ next = document.getElementById('bi-slide-next') if document.contains(prev) slider = document.getElementById('slider') slider.className += " swipe" - window.mySwipe = new Swipe(slider, + window.mySwipe = new Swipe(slider, auto: 4000 ) if document.body.addEventListener @@ -16,4 +16,3 @@ if document.contains(prev) mySwipe.prev() next.attachEvent "click", -> mySwipe.next() - \ No newline at end of file diff --git a/app/assets/javascripts/revised/components/alerts.coffee b/app/assets/javascripts/revised/components/alerts.coffee index d83e53c45e..1f2c336fab 100644 --- a/app/assets/javascripts/revised/components/alerts.coffee +++ b/app/assets/javascripts/revised/components/alerts.coffee @@ -52,7 +52,7 @@ class @Alerts storeAlert: (alert_type, alert_body, callback) -> # Store the alert and then run the callback (that we assume reloads the page) - stored_alert = + stored_alert = alert_type: alert_type alert_body: alert_body localStorage.setItem('stored_alert', JSON.stringify(stored_alert)) diff --git a/app/assets/javascripts/revised/components/check_email.coffee b/app/assets/javascripts/revised/components/check_email.coffee index e4c3d4283c..8c4def547d 100644 --- a/app/assets/javascripts/revised/components/check_email.coffee +++ b/app/assets/javascripts/revised/components/check_email.coffee @@ -13,7 +13,7 @@ class @CheckEmail # Use mailcheck to find emails with problems $("##{msg_selector}").slideUp 'fast', -> $("##{msg_selector}").remove() @runMailcheck($target) - + runMailcheck: ($target) -> Mailcheck.run diff --git a/app/assets/javascripts/revised/pages/bikes/edit_drivetrain.coffee b/app/assets/javascripts/revised/pages/bikes/edit_drivetrain.coffee index 1e4d69f37f..678af04c84 100644 --- a/app/assets/javascripts/revised/pages/bikes/edit_drivetrain.coffee +++ b/app/assets/javascripts/revised/pages/bikes/edit_drivetrain.coffee @@ -12,7 +12,7 @@ class BikeIndex.BikesEditDrivetrain extends BikeIndex $('#edit_drivetrain select').change (e) => @updateDrivetrainValue(e) - # + # # Wheels updateDiamsFromStandardChange: (e) -> current_val = e.target.value @@ -36,7 +36,7 @@ class BikeIndex.BikesEditDrivetrain extends BikeIndex $all_diams_btn.trigger('click', false) - # + # # Drivetrain toggleDrivetrainChecks: (e) -> $target = $(e.target) @@ -48,7 +48,7 @@ class BikeIndex.BikesEditDrivetrain extends BikeIndex @setDrivetrainValue('front_gear_select') if id == 'rear_gear_select_internal' @setDrivetrainValue('rear_gear_select') - + toggleFixed: (is_fixed) -> fixed_values = {} for side in ['front', 'rear'] @@ -83,7 +83,7 @@ class BikeIndex.BikesEditDrivetrain extends BikeIndex else position = $(event.target).attr('id') @setDrivetrainValue(position) - + setInitialGears: -> if $('#fixed_gear_check').prop('checked') == true @toggleFixed(true) diff --git a/app/assets/javascripts/revised/pages/bikes/edit_photos.coffee b/app/assets/javascripts/revised/pages/bikes/edit_photos.coffee index e7edb47247..efa67a8db0 100644 --- a/app/assets/javascripts/revised/pages/bikes/edit_photos.coffee +++ b/app/assets/javascripts/revised/pages/bikes/edit_photos.coffee @@ -55,7 +55,7 @@ class BikeIndex.BikesEditPhotos extends BikeIndex sortable_list_items = $sortable_container.children('li') # This is a list comprehension for the list of all the sortable items, to make an array array_of_photo_ids = ($(list_item).prop('id') for list_item in sortable_list_items) - new_item_order = + new_item_order = list_of_photos: array_of_photo_ids # list_of_items is an array containing the ordered list of image_ids # Then we post the result of the list comprehension to the url to update diff --git a/app/assets/javascripts/revised/pages/bikes/edit_root.coffee b/app/assets/javascripts/revised/pages/bikes/edit_root.coffee index 298a9c5031..f296eba3ce 100644 --- a/app/assets/javascripts/revised/pages/bikes/edit_root.coffee +++ b/app/assets/javascripts/revised/pages/bikes/edit_root.coffee @@ -47,7 +47,7 @@ class BikeIndex.BikesEditRoot extends BikeIndex if size == 'cm' or size == 'in' $('#bike_frame_size_unit').val(size) unless $hidden_other.hasClass('unhidden') - $hidden_other.slideDown 'fast', -> + $hidden_other.slideDown 'fast', -> $hidden_other.addClass('unhidden') $('.ordinal-sizes .btn').removeClass('active') $('.frame-sizes').removeClass('unexpanded-unit-size') # For small display setup. Remove space after appear diff --git a/app/assets/javascripts/revised/pages/info/where.coffee b/app/assets/javascripts/revised/pages/info/where.coffee index 50fac2fcef..bc135fc0ce 100644 --- a/app/assets/javascripts/revised/pages/info/where.coffee +++ b/app/assets/javascripts/revised/pages/info/where.coffee @@ -6,12 +6,12 @@ class BikeIndex.InfoWhere extends BikeIndex initializeEventListeners: -> $('a.where-shop-location').click (e) => @updateMapLocation(e) - $('html').animate( + $('html').animate( scrollTop: "#{$('#map_canvas').offset().top - 100}px", 'fast' ) - + initializeMap: -> - # Ideally we'll use the localstorage location information about the user + # Ideally we'll use the localstorage location information about the user # Which is what we'll use for bike proximity searching for the user createMap(40.111689,-96.81839,4) diff --git a/app/assets/javascripts/revised/pages/legacy_stolen_index.coffee b/app/assets/javascripts/revised/pages/legacy_stolen_index.coffee index cbfbc3014b..2bfd33494b 100644 --- a/app/assets/javascripts/revised/pages/legacy_stolen_index.coffee +++ b/app/assets/javascripts/revised/pages/legacy_stolen_index.coffee @@ -41,10 +41,10 @@ class BikeIndex.LegacyStolenIndex extends BikeIndex unlockSearch: -> $('#multiserial_fuzzy, #search_serials').addClass('ms_unlocked') - + searchForSerials: -> return true unless $('#search_serials').hasClass('ms_unlocked') - $('#search_serials').removeClass('ms_unlocked') + $('#search_serials').removeClass('ms_unlocked') $('#multiserial_fuzzy').fadeIn() $('#bikes_returned, #serials_submitted').empty() serials = $('#multi_serial_search').val().split(/,|\n/) @@ -67,12 +67,12 @@ class BikeIndex.LegacyStolenIndex extends BikeIndex s_i = $("#serials_submitted li[name='#{serial}']").addClass('ms-nomatch') else that.appendBikes(data.bikes, serial) - + bikeList: (bikes) -> list = '' for bike in bikes list += "
  • " - + list += 'Stolen' if bike.stolen list += """ #{bike.title} @@ -92,9 +92,9 @@ class BikeIndex.LegacyStolenIndex extends BikeIndex setTimeout (-> s_i.find('a').removeClass('blink-class') ), 500 - + results = if (bikes.length > 19) then 'First 20 of many' else bikes.length - if fuzzy + if fuzzy html = "

    Close to serial " else html = "

    " @@ -108,7 +108,7 @@ class BikeIndex.LegacyStolenIndex extends BikeIndex for li in $('#serials_submitted li') serial = $(li).attr('name') @getFuzzySerialResponse(serial) - + getFuzzySerialResponse: (serial) -> base_url = $('#multiserial_fuzzy').attr('data-target') diff --git a/app/assets/javascripts/revised/sections/bike_boxes.coffee b/app/assets/javascripts/revised/sections/bike_boxes.coffee index fefea97f6d..8664dbfd7d 100644 --- a/app/assets/javascripts/revised/sections/bike_boxes.coffee +++ b/app/assets/javascripts/revised/sections/bike_boxes.coffee @@ -22,7 +22,7 @@ class BikeIndex.BikeBoxes extends BikeIndex # Manually replace the image url with src for medium images - brittle... # but we don't want to have to query every bikes public images data = - title: $target.parents('.bike-box-item').find('.title-link').text() + title: $target.parents('.bike-box-item').find('.title-link').text() img_src: $target.find('img').prop('src').replace /\/small_/, '/medium_' $target.append Mustache.to_html(window.hoverExpandBlockTemplate, data) diff --git a/app/assets/javascripts/revised/sections/bike_search_bar.coffee b/app/assets/javascripts/revised/sections/bike_search_bar.coffee index 623e857e02..e188468b16 100644 --- a/app/assets/javascripts/revised/sections/bike_search_bar.coffee +++ b/app/assets/javascripts/revised/sections/bike_search_bar.coffee @@ -101,7 +101,7 @@ class BikeIndex.BikeSearchBar extends BikeIndex # window.bike_search_submit = true $('.bikes-search-form .select2-selection').on 'keyup', (e) -> # Only trigger submit on enter if: - # - Enter key pressed last (13) + # - Enter key pressed last (13) # - Escape key pressed last (27) # - no keys have been pressed (selected with the mouse, instantiated true) return window.bike_search_submit = true if e.keyCode == 27 diff --git a/app/assets/javascripts/views/admin/admin_bikes_edit.js.coffee b/app/assets/javascripts/views/admin/admin_bikes_edit.js.coffee index 11ba549937..dae92f0d9d 100644 --- a/app/assets/javascripts/views/admin/admin_bikes_edit.js.coffee +++ b/app/assets/javascripts/views/admin/admin_bikes_edit.js.coffee @@ -2,7 +2,7 @@ class BikeIndex.Views.AdminBikesEdit extends Backbone.View events: 'click #frame-sizer button': 'updateFrameSize' 'keyup': 'submitOnControlEnter' - + initialize: -> window.root_url = $('#bike_edit_root_url').attr('data-url') @setElement($('#body')) @@ -17,7 +17,7 @@ class BikeIndex.Views.AdminBikesEdit extends Backbone.View if $('.fast-attr-update').length > 0 $('#bike_cycle_type_id').focus() @setFrameSize() - + initializeFrameMaker: (target) -> $target = $(target) initial_opts = [] diff --git a/app/assets/javascripts/views/admin/admin_blogs_edit.js.coffee b/app/assets/javascripts/views/admin/admin_blogs_edit.js.coffee index 7eb3985676..f24f9e4fbb 100644 --- a/app/assets/javascripts/views/admin/admin_blogs_edit.js.coffee +++ b/app/assets/javascripts/views/admin/admin_blogs_edit.js.coffee @@ -4,19 +4,19 @@ class BikeIndex.Views.AdminBlogsEdit extends Backbone.View 'click #change_published_date': 'editDate' 'change .index-image-select input': 'setIndexImage' - + initialize: -> @setElement($('#body')) $('#public_image_image').attr('name', "public_image[image]") @publicImageFileUpload() if $('#new_public_image').length > 0 @listicleEdit() if $('#listicle_image').length > 0 $('.edit_blog').areYouSure() - + # Set the current index image $(".index_image_#{$('#blog_index_image_id').val()}").prop('checked', true) - - + + publicImageFileUpload: -> # runSortableImages = @sortableImages($('#public_images')) $('#new_public_image').fileupload @@ -56,7 +56,7 @@ class BikeIndex.Views.AdminBlogsEdit extends Backbone.View $('#blog-date').slideDown() - listicleEdit: -> + listicleEdit: -> for image in $('#listicle_image .list-image') block_number = $(image).attr('data-order') $(".page_number_#{block_number}").prepend($(image)) diff --git a/app/assets/javascripts/views/admin/admin_graphs.js.coffee b/app/assets/javascripts/views/admin/admin_graphs.js.coffee index 38839c28f0..1c53aaf6a8 100644 --- a/app/assets/javascripts/views/admin/admin_graphs.js.coffee +++ b/app/assets/javascripts/views/admin/admin_graphs.js.coffee @@ -1,8 +1,8 @@ class BikeIndex.Views.AdminGraphs extends Backbone.View - + initialize: -> $('#admin-content .receptacle').css('max-width', '100%') - + # if $('#graphy').length > 0 # @initialize_graph() # else @@ -17,7 +17,7 @@ class BikeIndex.Views.AdminGraphs extends Backbone.View # scaleOverlay : true # # scaleOverride: true # # scaleSteps: 2 - + # if $('#graphy').attr('data-values2') # data_values2 = $('#graphy').data('values2') # data = @@ -47,8 +47,8 @@ class BikeIndex.Views.AdminGraphs extends Backbone.View # ] # ctx = document.getElementById("graphy").getContext("2d") # new Chart(ctx).Line data, options - + # initialize_review: -> # data_values1 = $('#review-graph').data('values1') # data_labels = $('#review-graph').data('labels') - # \ No newline at end of file + # \ No newline at end of file diff --git a/app/assets/javascripts/views/admin/admin_organizations_edit.js.coffee b/app/assets/javascripts/views/admin/admin_organizations_edit.js.coffee index 9882647ace..ba75bd66b7 100644 --- a/app/assets/javascripts/views/admin/admin_organizations_edit.js.coffee +++ b/app/assets/javascripts/views/admin/admin_organizations_edit.js.coffee @@ -1,11 +1,11 @@ class BikeIndex.Views.AdminOrganizationsEdit extends Backbone.View - + initialize: -> @setElement($('#body')) @adminLocations() @loadNotifications() $('.chosen-select select').select2() - + adminLocations: -> $('form').on 'click', '.remove_fields', (event) -> # We don't need to do anything except slide the input up, because the label is on it. @@ -24,9 +24,9 @@ class BikeIndex.Views.AdminOrganizationsEdit extends Backbone.View for name in names n = $(name) n.val($('#organization_name').val()) unless n.val().length > 0 - + $('.chosen-select select').select2() - + loadNotifications: -> $('#show_notification a').click (e) -> e.preventDefault() diff --git a/app/assets/javascripts/views/admin/admin_recoveries.js.coffee b/app/assets/javascripts/views/admin/admin_recoveries.js.coffee index 3ced975b09..ec6276aaa2 100644 --- a/app/assets/javascripts/views/admin/admin_recoveries.js.coffee +++ b/app/assets/javascripts/views/admin/admin_recoveries.js.coffee @@ -4,7 +4,7 @@ class BikeIndex.Views.AdminRecoveries extends Backbone.View 'change #stolen_record_recovery_tweet': 'updateTweetLength' 'keydown #stolen_record_recovery_tweet': 'updateTweetLength' 'click #use_image_for_display': 'useBikeImageForDisplay' - + initialize: -> @setElement($('#body')) diff --git a/app/assets/javascripts/views/bikes/bikes_choose_registration.js.coffee b/app/assets/javascripts/views/bikes/bikes_choose_registration.js.coffee index b2ba27d9f3..7b4c57ac44 100644 --- a/app/assets/javascripts/views/bikes/bikes_choose_registration.js.coffee +++ b/app/assets/javascripts/views/bikes/bikes_choose_registration.js.coffee @@ -1,7 +1,7 @@ class BikeIndex.Views.BikesChooseRegistration extends Backbone.View events: 'click a.choose-type': 'updateBikeLink' - + initialize: -> @setElement($('#body')) @SetInitialRegistrationType() diff --git a/app/assets/javascripts/views/bikes/bikes_edit.js.coffee b/app/assets/javascripts/views/bikes/bikes_edit.js.coffee index 374341ae8f..4fbea41b1b 100644 --- a/app/assets/javascripts/views/bikes/bikes_edit.js.coffee +++ b/app/assets/javascripts/views/bikes/bikes_edit.js.coffee @@ -25,11 +25,11 @@ class BikeIndex.Views.BikesEdit extends Backbone.View 'click #hide_bike_toggle': 'toggleBikeHidden' 'change #mark_recovered_we_helped': 'toggleCanWeTell' - + initialize: -> @setElement($('#body')) window.root_url = $('#root_url').attr('data-url') - menu_height = $('#edit-menu').offset().top + menu_height = $('#edit-menu').offset().top scroll_height = $(window).height() * .4 @setDefaultCountryAndState() $('#body').attr('data-spy', "scroll").attr('data-target', '#edit-menu') @@ -56,8 +56,8 @@ class BikeIndex.Views.BikesEdit extends Backbone.View scrollToMenuTarget: (event) -> event.preventDefault() target = $(event.target).attr('href') - $('body').animate( - scrollTop: ($(target).offset().top - 20), 'fast' + $('body').animate( + scrollTop: ($(target).offset().top - 20), 'fast' ) publicImageFileUpload: -> @@ -102,7 +102,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View sortable_list_items = sortable_container.children('li') # This is a list comprehension for the list of all the sortable items, to make an array array_of_photo_ids = ($(list_item).attr('id') for list_item in sortable_list_items) - new_item_order = + new_item_order = list_of_photos: array_of_photo_ids # list_of_items is an array containing the ordered list of image_ids # Then we post the result of the list comprehension to the url to update @@ -138,7 +138,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View other = target.parents('.control-group').attr('data-hidden') hidden_other = target.parents('article').find(other) else - expand_value = group.find('.other-value').text() + expand_value = group.find('.other-value').text() hidden_other = group.find('.hidden-other') @expandIfMatches(hidden_other, current_value, expand_value) @@ -152,7 +152,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View other = selector.parents('.control-group').attr('data-hidden') hidden_other = selector.parents('article').find(other) else - expand_value = group.find('.other-value').text() + expand_value = group.find('.other-value').text() hidden_other = group.find('.hidden-other') @expandIfMatches(hidden_other, current_value, expand_value) @@ -161,7 +161,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View if parseInt(current_value, 10) == parseInt(expand_value, 10) # show the bugger! hidden_other.slideDown().addClass('unhidden') - else + else # if it's visible, clear it and slide up if hidden_other.hasClass('unhidden') hidden_other.find('input').val('') @@ -194,7 +194,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View standard.find('select').selectize()[0].selectize.setValue(all.find('select').val()) standard.fadeIn() ) - + setWheelDiam: (position) -> wheelDiam = $("#bike_#{position}_wheel_size_id").val() $("##{position}_standard select").selectize()[0].selectize.setValue(wheelDiam) @@ -204,7 +204,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View $("##{position}_standard").hide() $("#show-#{position}-wheel-diams").addClass('currently-hidden').hide() $("#hide-#{position}-wheel-diams").removeClass('currently-hidden').show() - + updateWheelDiam: (event) -> target = $(event.target) cv = target.val() @@ -217,7 +217,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View current_value = $("#cycletype#{$("#bike_cycle_type_id").val()}") $('#cycletype-text').removeClass('long-title') if current_value.hasClass('long-title') - $('#cycletype-text').addClass('long-title') + $('#cycletype-text').addClass('long-title') $('#cycletype-text').text(current_value.text()) showColors: -> @@ -336,19 +336,19 @@ class BikeIndex.Views.BikesEdit extends Backbone.View hidden_other = target.parents('.mnfg-group').find('.hidden-mnfg') if parseInt(target.val(), 10) == parseInt(expand_value, 10) hidden_other.slideDown().addClass('unhidden') - else + else if hidden_other.hasClass('unhidden') hidden_other.find('input').selectize()[0].selectize.setValue('') hidden_other.removeClass('unhidden').slideUp() - + toggleExtraModelField: (event) -> target = $(event.target) hidden_other = target.parents('.input-group').find('.extra-model-fields') - if target.val().length > 1 + if target.val().length > 1 # show the bugger! hidden_other.slideDown().addClass('unhidden') - else + else # if it's visible, clear it and slide up if hidden_other.hasClass('unhidden') hidden_other.find('input').val('') @@ -377,7 +377,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View if hidden_other.hasClass('unhidden') hidden_other.removeClass('unhidden').slideUp('fast') $('#frame-sizer .groupedbtn-group').removeClass('ex-size') - + toggleDrivetrainChecks: (event) -> target = $(event.target) id = target.attr('id') @@ -394,12 +394,12 @@ class BikeIndex.Views.BikesEdit extends Backbone.View @setDrivetrainValue('front_gear_select') if id == 'rear_gear_select_internal' @setDrivetrainValue('rear_gear_select') - + setFixed: -> ffixed = parseInt($('#front_gear_select_value .fixed_value').text(), 10) rfixed = parseInt($('#rear_gear_select_value .fixed_value').text(), 10) $('#edit_drivetrain .not-fixed').slideUp 'medium', -> - $('#rear_gear_select_internal, #front_gear_select_internal').prop('checked', '') + $('#rear_gear_select_internal, #front_gear_select_internal').prop('checked', '') $('#front_gear_select, #rear_gear_select').val('') $("#front_gear_select_value #bike_front_gear_type_id_#{ffixed}").prop('checked', true) $("#rear_gear_select_value #bike_rear_gear_type_id_#{rfixed}").prop('checked', true) @@ -418,7 +418,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View updateDrivetrainValue: (event) -> position = $(event.target).attr('id') @setDrivetrainValue(position) - + setInitialGears: -> if $('#fixed_gear_check').prop('checked') == true @setFixed() @@ -434,7 +434,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View $('#rear_gear_select .placeholder').prop('selected', 'selected') else $('#rear_gear_select').val(rcount) - + toggleUnknownYear: -> year_select = $('#bike_year').selectize()[0].selectize if $('#bike_unknown_year').prop('checked') @@ -443,7 +443,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View else year_select.setValue(new Date().getFullYear()) year_select.enable() - + updateYear: -> if $('#bike_year').val() if $('#bike_year').val().length == 0 @@ -461,8 +461,8 @@ class BikeIndex.Views.BikesEdit extends Backbone.View toggleBikeHidden: -> $('#hide_bike_toggle_group input').val('true') $('form.bikeedit-form-grab').submit() - - + + submitSerialUpdate: (e) -> e.preventDefault() serial = $('#serial_update_serial').val() @@ -482,8 +482,8 @@ class BikeIndex.Views.BikesEdit extends Backbone.View BikeIndex.alertMessage('success', 'Serial correction submitted', "Processing your updated serial now. We review all updates by hand, it could take up to a day before your bike is updated. Thanks!") error: (data, textStatus, jqXHR) -> BikeIndex.alertMessage('error', 'Request failed', "We're unable to process the update! Try again?") - $('#submitSerialCorrection').modal('hide') - + $('#submitSerialCorrection').modal('hide') + else $('#submit-serial-error').slideDown('fast') @@ -506,8 +506,8 @@ class BikeIndex.Views.BikesEdit extends Backbone.View BikeIndex.alertMessage('success', 'Manufacturer correction submitted', "Processing your updated Manufacturer now. We review all updates by hand, it could take up to a day before your bike is updated. Thanks!") error: (data, textStatus, jqXHR) -> BikeIndex.alertMessage('error', 'Request failed', "We're unable to process the update! Try again?") - $('#submitManufacturerCorrection').modal('hide') - + $('#submitManufacturerCorrection').modal('hide') + else $('#submit-manufacturer-error').slideDown('fast') @@ -535,7 +535,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View callback() success: (res) -> callback res.matches.slice(0, per_page) - + requestBikeDelete: (e) -> e.preventDefault() @@ -554,7 +554,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View BikeIndex.alertMessage('success', 'Bike delete submitted', "Deleting your bike now. We delete all bikes by hand, it could take up to a day before your bike is gone. Thanks for your patience!") error: (data, textStatus, jqXHR) -> BikeIndex.alertMessage('error', 'Request failed', "Oh no! Something went wrong and we couldn't send the delete request.") - $('#requestBikeDelete').modal('hide') + $('#requestBikeDelete').modal('hide') else $('#request-delete-error').slideDown('fast') @@ -584,7 +584,7 @@ class BikeIndex.Views.BikesEdit extends Backbone.View can_share_recovery: can_share_recovery success: (data, textStatus, jqXHR) -> # BikeIndex.alertMessage('success', 'Bike marked recovered', "Thanks! We're so glad you got your bike back!") - $('#requestBikeDelete').modal('hide') + $('#requestBikeDelete').modal('hide') $('#bike_stolen').prop('checked', '') $('.bikeedit-form-grab').submit() error: (data, textStatus, jqXHR) -> diff --git a/app/assets/javascripts/views/bikes/bikes_new.js.coffee b/app/assets/javascripts/views/bikes/bikes_new.js.coffee index c1ac3e0c54..c66ed783d3 100644 --- a/app/assets/javascripts/views/bikes/bikes_new.js.coffee +++ b/app/assets/javascripts/views/bikes/bikes_new.js.coffee @@ -3,12 +3,12 @@ class BikeIndex.Views.BikesNew extends Backbone.View 'change #bike_has_no_serial': 'updateSerial' 'click a.optional-form-block': 'optionalFormUpdate' 'change #bike_year': 'updateYear' - 'change #bike_unknown_year': 'toggleUnknownYear' + 'change #bike_unknown_year': 'toggleUnknownYear' 'click #select-cycletype a': 'changeCycleType' 'change #bike_manufacturer_id': 'onManufacturerChange' 'change #country_select_container select': 'updateCountry' - - + + initialize: -> @setElement($('#body')) if $('#bike_has_no_serial').prop('checked') == true @@ -20,10 +20,10 @@ class BikeIndex.Views.BikesNew extends Backbone.View @setDefaultCountry() @updateCycleType() window.root_url = $('#root_url').attr('data-url') - + @initializeFrameMaker("#bike_manufacturer_id") @otherManufacturerDisplay($("#bike_manufacturer_id").val()) - + updateSerial: (event) -> if $(event.target).prop('checked') == true @@ -50,7 +50,7 @@ class BikeIndex.Views.BikesNew extends Backbone.View current_value = $("#cycletype#{$("#bike_cycle_type_id").val()}") $('#cycletype-text').removeClass('long-title') if current_value.hasClass('long-title') - $('#cycletype-text').addClass('long-title') + $('#cycletype-text').addClass('long-title') $('#cycletype-text').text(current_value.text()) @@ -97,7 +97,7 @@ class BikeIndex.Views.BikesNew extends Backbone.View else year_select.setValue(new Date().getFullYear()) year_select.enable() - + updateYear: -> if $('#bike_year').val() if $('#bike_year').val().length == 0 @@ -123,17 +123,17 @@ class BikeIndex.Views.BikesNew extends Backbone.View if current_value == expand_value # show the bugger! hidden_other.slideDown().addClass('unhidden') - else + else # if it's visible, clear it and slide up if hidden_other.hasClass('unhidden') hidden_other.find('input').val('') hidden_other.removeClass('unhidden').slideUp() - + setDefaultCountry: -> # we should geocode the country in here if possible... default_country_id = parseInt($('#us_country_id').text(), 10) $('#country_select_container select').selectize()[0].selectize.setValue(default_country_id) - + updateCountry: -> c_select = $('#country_select_container select') us_val = parseInt($('#country_select_container .other-value').text(), 10) diff --git a/app/assets/javascripts/views/bikes/bikes_show.js.coffee b/app/assets/javascripts/views/bikes/bikes_show.js.coffee index efc764d1b6..97e1726b5d 100644 --- a/app/assets/javascripts/views/bikes/bikes_show.js.coffee +++ b/app/assets/javascripts/views/bikes/bikes_show.js.coffee @@ -2,7 +2,7 @@ class BikeIndex.Views.BikesShow extends Backbone.View events: 'click #thumbnails .clickable-image': 'clickPhoto' 'keyup': 'logKey' - + initialize: -> @setElement($('#body')) if $('#claim-ownership-modal').length > 0 @@ -22,7 +22,7 @@ class BikeIndex.Views.BikesShow extends Backbone.View $(window).scroll -> that.prepPhotos() $(window).unbind('scroll') - + initializePhotoSelector: -> setTimeout ( -> @@ -52,7 +52,7 @@ class BikeIndex.Views.BikesShow extends Backbone.View targetPhoto = $("#thumbnail-photos div[data-id='#{targetPhotoID}']") @photoFadeOut(targetPhotoID, targetPhoto) - + clickPhoto:(event) -> event.preventDefault() @@ -65,7 +65,7 @@ class BikeIndex.Views.BikesShow extends Backbone.View if targetPhotoID == "video_embed" return false else - $('#video_embed').remove() + $('#video_embed').remove() @photoFadeIn(targetPhotoID, targetPhoto) $('#selected-photo .current-photo').addClass('transitioning-photo').removeClass('current-photo') if targetPhotoID == "video_embed" @@ -107,7 +107,7 @@ class BikeIndex.Views.BikesShow extends Backbone.View $('#selected-photo .transitioning-photo').hide() $('#selected-photo .transitioning-photo').removeClass('transitioning-photo current-photo') ), 900 - + # some portrait images are too tall. Let's make em smaller ideal_height = $(window).height() * 0.75 if $("#selected-photo .current-photo").height() > ideal_height diff --git a/app/assets/javascripts/views/documentation/documentation_index.js.coffee b/app/assets/javascripts/views/documentation/documentation_index.js.coffee index 4922aa2914..d049e96ffc 100644 --- a/app/assets/javascripts/views/documentation/documentation_index.js.coffee +++ b/app/assets/javascripts/views/documentation/documentation_index.js.coffee @@ -7,7 +7,7 @@ class BikeIndex.Views.DocumentationIndex extends Backbone.View production = parseInt($('#documentation_head').attr('data-production'), 10) unless production == 1 @createBikes() - + manufacturerCalls: -> $.ajax type: "GET" @@ -16,7 +16,7 @@ class BikeIndex.Views.DocumentationIndex extends Backbone.View $('#manufacturers_frame_makers').text(JSON.stringify(data,undefined,2)) error: (data, textStatus, jqXHR) -> $('#manufacturers_frame_makers').text(JSON.stringify(data,undefined,2)) - + $.ajax type: "GET" url: $('#manufacturers_query').attr('data-url') @@ -24,7 +24,7 @@ class BikeIndex.Views.DocumentationIndex extends Backbone.View $('#manufacturers_query').text(JSON.stringify(data,undefined,2)) error: (data, textStatus, jqXHR) -> console.log(data) - + bikeSearchCall: -> $.ajax type: "GET" @@ -61,7 +61,7 @@ class BikeIndex.Views.DocumentationIndex extends Backbone.View error: (data, textStatus, jqXHR) -> $("##{i}_index").text(data) - createBikes: -> + createBikes: -> component_bike = serial_number: "XOXO :)" manufacturer: "WorkCycles" @@ -92,7 +92,7 @@ class BikeIndex.Views.DocumentationIndex extends Backbone.View $.ajax url: $('#bike_components').attr('data-url') type: "POST" - data: + data: bike: component_bike components: components organization_slug: $('#example_organization').attr('data-slug') @@ -100,20 +100,20 @@ class BikeIndex.Views.DocumentationIndex extends Backbone.View success: (data, textStatus, jqXHR) -> $('#bike_components').text(JSON.stringify(data,undefined,2)) error: (data, textStatus, jqXHR) -> - $('#bike_components').text(JSON.stringify(data,undefined,2)) - - bike = + $('#bike_components').text(JSON.stringify(data,undefined,2)) + + bike = serial_number: "XOXO <3" manufacturer: "Surly" color: "Blue" rear_tire_narrow: false rear_wheel_bsd: "559" owner_email: "new_bike_owner@bikeindex.org" - + $.ajax url: $('#bike_basic').attr('data-url') type: "POST" - data: + data: bike: bike organization_slug: $('#example_organization').attr('data-slug') access_token: $('#example_organization').attr('data-token') @@ -147,7 +147,7 @@ class BikeIndex.Views.DocumentationIndex extends Backbone.View $.ajax url: $('#bike_stolen').attr('data-url') type: "POST" - data: + data: bike: stolen_bike stolen_record: stolen_record organization_slug: $('#example_organization').attr('data-slug') diff --git a/app/assets/javascripts/views/global.js.coffee b/app/assets/javascripts/views/global.js.coffee index 09f4b4a0ae..72b72e3907 100644 --- a/app/assets/javascripts/views/global.js.coffee +++ b/app/assets/javascripts/views/global.js.coffee @@ -8,7 +8,7 @@ class BikeIndex.Views.Global extends Backbone.View 'click .no-tab': 'openNewWindow' 'click #expand_user': 'expandUserNav' 'click #most_recent_stolen_bikes': 'mostRecentStolen' - + initialize: -> # BikeIndex.hideFlash() # not sure that it's something we ever want @setElement($('#body')) @@ -55,7 +55,7 @@ class BikeIndex.Views.Global extends Backbone.View $this.text(moment().format("z")) $this.removeClass("convertTimezone") $(".hiddenFieldTimezone").val(window.timezone) - + openNewWindow: (e) -> e.preventDefault() target = $(e.target) @@ -79,8 +79,8 @@ class BikeIndex.Views.Global extends Backbone.View scrollToRef: (event) -> event.preventDefault() target = $(event.target).attr('href') - $('body').animate( - scrollTop: ($(target).offset().top - 20), 'fast' + $('body').animate( + scrollTop: ($(target).offset().top - 20), 'fast' ) # @@ -175,7 +175,7 @@ class BikeIndex.Views.Global extends Backbone.View item: (item, escape) -> if item.id == 'serial' "
    serial #{item.text}
    " - else + else "
    #{item.text}
    " option_create: (data, escape) -> # For some reason, without … at the end of this it breaks @@ -187,7 +187,7 @@ class BikeIndex.Views.Global extends Backbone.View onType: (str) -> for k in Object.keys(this.options) # If they are serial ids - if k.match /^s\#/ + if k.match /^s\#/ # if the serials are longer than the current str, delete them # Also delete them if we're down to 2 chars delete this.options[k] if (k.length > str + 3) || str.length < 3 @@ -217,8 +217,8 @@ class BikeIndex.Views.Global extends Backbone.View 'entered' "
    #{prefix} " + escape(item.text) + '
    ' - # - # + # + # # Page specific things I've been too lazy to make separate backbone views setLightspeedMovie: -> @@ -235,12 +235,12 @@ class BikeIndex.Views.Global extends Backbone.View dataType: "jsonp", success: (location) -> $('#stolen-proximity #proximity').val("#{location.region_name}") - loadStolenWidget(location) if $('#sbr-body').length > 0 + loadStolenWidget(location) if $('#sbr-body').length > 0 - # - # + # + # # Old layout things. Delete once everything is updated toggleCollapsibleHeader: -> @@ -262,17 +262,17 @@ class BikeIndex.Views.Global extends Backbone.View $('#header-tabs .global-tabs li').removeClass('active') $('#header-tabs').removeClass('visibled') $('#total-top-header').removeClass('header-tabs-in') - else + else # console.log(target) # $('#session_email').focus() if target.hasClass('.expand-sign-in') # console.log('hihih') window.setTimeout (-> $('#session_email').focus() ), 500 - - + + $('#total-top-header').addClass('header-tabs-in') - if $('#header-tabs .tab-content').hasClass('visibled') + if $('#header-tabs .tab-content').hasClass('visibled') target.tab('show') else $('#header-tabs').addClass('visibled') diff --git a/app/assets/javascripts/views/locks/locks_form.js.coffee b/app/assets/javascripts/views/locks/locks_form.js.coffee index 7cb08cbb3b..80a9ae6303 100644 --- a/app/assets/javascripts/views/locks/locks_form.js.coffee +++ b/app/assets/javascripts/views/locks/locks_form.js.coffee @@ -1,12 +1,12 @@ class BikeIndex.Views.LocksForm extends Backbone.View - events: + events: 'change #lock_has_key': 'updateLockFields' 'change #lock_has_combination': 'updateLockFields' 'change input[name="lock_types_select"]': 'updateLockType' 'change .manufacturer-select select': 'showOtherIfRequired' 'click .lock-picture': 'openLockPicture' - - + + initialize: -> @setElement($('#body')) @selectCorrectLock() @@ -32,15 +32,15 @@ class BikeIndex.Views.LocksForm extends Backbone.View hidden_other = $(event.target).parents('.input-field').find('.hidden-other') if parseInt(current_value) == parseInt(other_value) hidden_other.slideDown().addClass('unhidden') - else + else if hidden_other.hasClass('unhidden') hidden_other.find('input').val('') hidden_other.removeClass('unhidden').slideUp() - + updateLockType: -> lock_type = $('input[name="lock_types_select"]:checked').data("value") $('#lock_lock_type_id').val(lock_type) - + updateLockFields: -> if $('input[name="lock[has_key]"]:checked').length > 0 diff --git a/app/assets/javascripts/views/organizations/content/where.js.coffee b/app/assets/javascripts/views/organizations/content/where.js.coffee index ceba29b364..ec4686b962 100644 --- a/app/assets/javascripts/views/organizations/content/where.js.coffee +++ b/app/assets/javascripts/views/organizations/content/where.js.coffee @@ -8,14 +8,14 @@ class BikeIndex.Views.ContentWhere extends Backbone.View @setElement($('#body')) google.maps.event.addDomListener(window, 'load', @initializeMap); - + initializeMap: -> createMap(40.111689,-96.81839,4) updateMapLocation: (event) -> target = $(event.target) - $('body').animate( - scrollTop: ($('#where-bike-index').offset().top - 20), 'fast' + $('body').animate( + scrollTop: ($('#where-bike-index').offset().top - 20), 'fast' ) latLng = new google.maps.LatLng(target.attr('data-lat'), target.attr('data-long')) window.map.setZoom(13) diff --git a/app/assets/javascripts/views/organizations_show.js.coffee b/app/assets/javascripts/views/organizations_show.js.coffee index 5e4df8e16d..4eefcb7964 100644 --- a/app/assets/javascripts/views/organizations_show.js.coffee +++ b/app/assets/javascripts/views/organizations_show.js.coffee @@ -3,14 +3,13 @@ class BikeIndex.Views.OrganizationsShow extends Backbone.View 'click #show-developer-info': 'showDeveloperInfo' 'click #show-lightspeed-info': 'showLightspeedInfo' - initialize: -> @setElement($('#body')) # Later we can seperate these, for now though here is good enough if $('#org-bikes-table').length > 0 @loadDataTable('#org-bikes-table') else if $('#org-users-table').length > 0 - @loadDataTable('#org-users-table') + @loadDataTable('#org-users-table') if $('#edit-organization-page').length > 0 @initializeLocationEdit() $('.chosen-select select').select2() @@ -33,7 +32,7 @@ class BikeIndex.Views.OrganizationsShow extends Backbone.View event.preventDefault() $('#lightspeed-info').slideToggle() $(event.target).toggleClass('shown') - + initializeLocationEdit: -> $('form').on 'click', '.remove_fields', (event) -> # We don't need to do anything except slide the input up, because the label is on it. @@ -52,5 +51,5 @@ class BikeIndex.Views.OrganizationsShow extends Backbone.View for name in names n = $(name) n.val($('#organization_name').val()) unless n.val().length > 0 - - $('.chosen-select select').select2() \ No newline at end of file + + $('.chosen-select select').select2() diff --git a/app/assets/javascripts/views/photos/photos_index.js.coffee b/app/assets/javascripts/views/photos/photos_index.js.coffee index 328295c52e..daef5741d1 100644 --- a/app/assets/javascripts/views/photos/photos_index.js.coffee +++ b/app/assets/javascripts/views/photos/photos_index.js.coffee @@ -1,5 +1,5 @@ class BikeIndex.Views.PhotosIndex extends Backbone.View - + initialize: -> @initializeFlipPhotos() @@ -16,7 +16,7 @@ class BikeIndex.Views.PhotosIndex extends Backbone.View for num in photo_numbers delay = delay + (200*Math.random()) @photoFlip(num, delay) - + photoFlip: (photo_number, delay) -> if $("#photo#{photo_number}").length > 0 @@ -25,10 +25,10 @@ class BikeIndex.Views.PhotosIndex extends Backbone.View $("#photo#{photo_number} .back").html("") setTimeout ( -> $("#photo#{photo_number}").fadeTo(200, 1) - setTimeout ( -> + setTimeout ( -> $("#photo#{photo_number}").addClass('uncover') ), 300 - setTimeout ( -> + setTimeout ( -> # $("#photo#{photo_number} .front-behind").fadeIn() $("#photo#{photo_number} .front-behind").append("").fadeIn() ), 900 diff --git a/app/assets/javascripts/views/stolen/stolen_multi_serial_search.js.coffee b/app/assets/javascripts/views/stolen/stolen_multi_serial_search.js.coffee index 8722ae2de5..fa3db7e024 100644 --- a/app/assets/javascripts/views/stolen/stolen_multi_serial_search.js.coffee +++ b/app/assets/javascripts/views/stolen/stolen_multi_serial_search.js.coffee @@ -4,7 +4,7 @@ class BikeIndex.Views.StolenMultiSerialSearch extends Backbone.View 'change #multi_serial_search': 'unlockSearch' 'click #search_serials': 'searchForSerials' 'click #multiserial_fuzzy': 'searchSerialsFuzzy' - + initialize: -> @setElement($('body')) @toggleMultiSearch() if window.location.href.match(/multi.?serial.?search/i) @@ -31,11 +31,11 @@ class BikeIndex.Views.StolenMultiSerialSearch extends Backbone.View unlockSearch: -> $('#multiserial_fuzzy, #search_serials').addClass('ms_unlocked') - + searchForSerials: (event) -> event.preventDefault() return true unless $('#search_serials').hasClass('ms_unlocked') - $('#search_serials').removeClass('ms_unlocked') + $('#search_serials').removeClass('ms_unlocked') $('#multiserial_fuzzy').fadeIn() $('#bikes_returned, #serials_submitted').empty() serials = $('#multi_serial_search').val().split(/,|\n/) @@ -58,12 +58,12 @@ class BikeIndex.Views.StolenMultiSerialSearch extends Backbone.View s_i = $("#serials_submitted li[name='#{serial}']").addClass('ms-nomatch') else that.appendBikes(data.bikes, serial) - + bikeList: (bikes) -> list = '' for bike in bikes list += "
  • " - + list += 'Stolen' if bike.stolen list += """ #{bike.title} @@ -83,9 +83,9 @@ class BikeIndex.Views.StolenMultiSerialSearch extends Backbone.View setTimeout (-> s_i.find('a').removeClass('blink-class') ), 500 - + results = if (bikes.length > 19) then 'First 20 of many' else bikes.length - if fuzzy + if fuzzy html = "

    Close to serial " else html = "

    " @@ -100,7 +100,7 @@ class BikeIndex.Views.StolenMultiSerialSearch extends Backbone.View for li in $('#serials_submitted li') serial = $(li).attr('name') @getFuzzySerialResponse(serial) - + getFuzzySerialResponse: (serial) -> base_url = $('#multiserial_fuzzy').attr('data-target') diff --git a/app/assets/javascripts/views/users/users_edit.js.coffee b/app/assets/javascripts/views/users/users_edit.js.coffee index 8e35f78fff..3f63a1d6cf 100644 --- a/app/assets/javascripts/views/users/users_edit.js.coffee +++ b/app/assets/javascripts/views/users/users_edit.js.coffee @@ -1,5 +1,5 @@ class BikeIndex.Views.UsersEdit extends Backbone.View - + initialize: -> @setElement($('#body')) @loadUserForm() diff --git a/app/assets/javascripts/views/welcome/login_signup.js.coffee b/app/assets/javascripts/views/welcome/login_signup.js.coffee index 8d346cbce8..cf2294845d 100644 --- a/app/assets/javascripts/views/welcome/login_signup.js.coffee +++ b/app/assets/javascripts/views/welcome/login_signup.js.coffee @@ -1,5 +1,5 @@ class BikeIndex.Views.LoginSignup extends Backbone.View - + initialize: -> @initializeFlipPhotos() @@ -14,13 +14,13 @@ class BikeIndex.Views.LoginSignup extends Backbone.View # then run different while statements for each line delay = 1000 photo_numbers = [0..17] - + if $('#new_user').length > 0 Array::push.apply photo_numbers, [18..23] for num in photo_numbers delay = delay + (200*Math.random()) @photoFlip(num, delay) - + photoFlip: (photo_number, delay) -> if $("#photo#{photo_number}").length > 0 @@ -29,10 +29,10 @@ class BikeIndex.Views.LoginSignup extends Backbone.View $("#photo#{photo_number} .back").html("") setTimeout ( -> $("#photo#{photo_number}").fadeTo(200, 1) - setTimeout ( -> + setTimeout ( -> $("#photo#{photo_number}").addClass('uncover') ), 300 - setTimeout ( -> + setTimeout ( -> # $("#photo#{photo_number} .front-behind").fadeIn() $("#photo#{photo_number} .front-behind").append("").fadeIn() ), 900 diff --git a/app/assets/javascripts/views/welcome/news_display.js.coffee b/app/assets/javascripts/views/welcome/news_display.js.coffee index b2d3bf4d27..8bbac3d369 100644 --- a/app/assets/javascripts/views/welcome/news_display.js.coffee +++ b/app/assets/javascripts/views/welcome/news_display.js.coffee @@ -1,5 +1,5 @@ class BikeIndex.Views.NewsDisplay extends Backbone.View - + initialize: -> @setElement($('#body')) @setAds() diff --git a/app/assets/javascripts/views/welcome/user_home.js.coffee b/app/assets/javascripts/views/welcome/user_home.js.coffee index e089c27b1c..ecf19ce408 100644 --- a/app/assets/javascripts/views/welcome/user_home.js.coffee +++ b/app/assets/javascripts/views/welcome/user_home.js.coffee @@ -3,7 +3,7 @@ class BikeIndex.Views.UserHome extends Backbone.View @setElement($('#body')) if $('#user-bikes-table').length > 0 @loadDataTable('#user-bikes-table') - + loadDataTable:(table_id) -> $(table_id).dataTable( diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 04ae57721b..dc768855ce 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -7,15 +7,19 @@ overflow-x: scroll; margin-left: -15px; margin-right: -15px; + &.small-fixed-width { table { table-layout: fixed; + .date-recovered-cell { width: 6em; } + .sm-cell { width: 2em; } + .sm-cell-hide { display: none; } @@ -38,19 +42,23 @@ thead.sortable { th { font-weight: normal; + a.sortable-link { display: block; position: relative; + // To give a spot for the sortable direction &.active { padding-right: 1.5rem; } + span.sortable-direction { display: block; position: absolute; right: 0; top: 0; } + &.active { font-weight: strong; text-decoration: underline; @@ -71,6 +79,7 @@ thead.sortable { line-height: 1em; border-radius: 0.5em; } + .paid-org-icon { display: inline-block; color: white; @@ -93,20 +102,26 @@ thead.sortable { margin-bottom: 1rem; background-color: transparent; border-collapse: collapse; + tbody tr:nth-of-type(2n + 1) { background-color: rgba(0, 0, 0, 0.05); } + td { border-width: 1px; border-style: solid; border-color: rgb(222, 226, 230); border-image: initial; } + tr td:first-child { font-size: 80%; font-style: italic; } + tr td:last-child { - width: 85%; // This is effectively min-width for tables + width: 85%; + + // This is effectively min-width for tables } } diff --git a/app/assets/stylesheets/documentation_v2.scss b/app/assets/stylesheets/documentation_v2.scss index 32888b3f1d..4680656d76 100644 --- a/app/assets/stylesheets/documentation_v2.scss +++ b/app/assets/stylesheets/documentation_v2.scss @@ -1,3 +1,7991 @@ // = require swagger-ui -#grid-overlay{position:fixed;height:100%;width:100%;z-index:99999}#grid-overlay .grid-receptacle{padding:0;height:100%}#grid-overlay .inner-recep{height:100%}#grid-overlay .column{float:left;width:6.5%;height:100%;margin-left:2%;border:1px solid #b2dec1;border-top:none;border-bottom:none}#grid-overlay .inner-recep .column:first-of-type{margin-left:0}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.hidden{display:none!important;visibility:hidden!important}.padded{padding-top:20px}@media (max-width: 599px){.padded{padding-top:10px}}.margined{margin-top:20px}@media (max-width: 599px){.margined{margin-top:10px}}.with-divider{border-top:1px solid #e6e6e6}body .selectize-dropdown [data-selectable] .highlight{background:rgba(52,152,219,0.2)}body .selectize-dropdown .active{background-color:#d8d8d8}.selectize-control.plugin-drag_drop.multi>.selectize-input>div.ui-sortable-placeholder{visibility:visible!important;background:#f2f2f2!important;background:rgba(0,0,0,0.06)!important;border:0 none!important;-webkit-box-shadow:inset 0 0 12px 4px #ffffff;box-shadow:inset 0 0 12px 4px #ffffff}.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after{content:'!';visibility:hidden}.selectize-control.plugin-drag_drop .ui-sortable-helper{-webkit-box-shadow:0 2px 5px rgba(0,0,0,0.2);box-shadow:0 2px 5px rgba(0,0,0,0.2)}.selectize-dropdown-header{position:relative;padding:3px 12px;border-bottom:1px solid #d0d0d0;background:#f8f8f8;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.selectize-dropdown-header-close{position:absolute;right:12px;top:50%;color:#333333;opacity:0.4;margin-top:-12px;line-height:20px;font-size:20px!important}.selectize-dropdown-header-close:hover{color:#000000}.selectize-dropdown.plugin-optgroup_columns .optgroup{border-right:1px solid #f2f2f2;border-top:0 none;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child{border-right:0 none}.selectize-dropdown.plugin-optgroup_columns .optgroup:before{display:none}.selectize-dropdown.plugin-optgroup_columns .optgroup-header{border-top:0 none}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:24px!important}.selectize-control.plugin-remove_button [data-value] .remove{z-index:1;position:absolute;top:0;right:0;bottom:0;width:17px;text-align:center;font-weight:bold;font-size:12px;color:inherit;text-decoration:none;vertical-align:middle;display:inline-block;padding:1px 0 0 0;border-left:1px solid transparent;-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-control.plugin-remove_button [data-value] .remove:hover{background:rgba(0,0,0,0.05)}.selectize-control.plugin-remove_button [data-value].active .remove{border-left-color:transparent}.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover{background:none}.selectize-control.plugin-remove_button .disabled [data-value] .remove{border-left-color:rgba(77,77,77,0)}.selectize-control{position:relative}.selectize-dropdown,.selectize-input,.selectize-input input{color:#333333;font-family:inherit;font-size:inherit;line-height:20px;-webkit-font-smoothing:inherit}.selectize-input,.selectize-control.single .selectize-input.input-active{background:#ffffff;cursor:text;display:inline-block}.selectize-input{border:1px solid #cccccc;padding:6px 12px;display:inline-block;width:100%;overflow:hidden;position:relative;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:none;box-shadow:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.selectize-control.multi .selectize-input.has-items{padding:5px 12px 2px}.selectize-input.full{background-color:#ffffff}.selectize-input.disabled,.selectize-input.disabled *{cursor:default!important}.selectize-input.focus{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.15)}.selectize-input.dropdown-active{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.selectize-input>*{vertical-align:baseline;display:-moz-inline-stack;display:inline-block;zoom:1;*display:inline}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:0 3px 3px 0;padding:1px 3px;background:#efefef;color:#333333;border:0 solid transparent}.selectize-control.multi .selectize-input>div.active{background:#428bca;color:#ffffff;border:0 solid transparent}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:#808080;background:#ffffff;border:0 solid rgba(77,77,77,0)}.selectize-input>input{display:inline-block!important;padding:0!important;min-height:0!important;max-height:none!important;max-width:100%!important;margin:0!important;text-indent:0!important;border:0 none!important;background:none!important;line-height:inherit!important;-webkit-user-select:auto!important;-webkit-box-shadow:none!important;box-shadow:none!important}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:none!important}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#ffffff;height:1px;bottom:0;left:0;right:0}.selectize-dropdown{position:absolute;z-index:10;border:1px solid #d0d0d0;background:#ffffff;margin:-1px 0 0 0;border-top:0 none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1);-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(255,237,40,0.4);-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px}.selectize-dropdown [data-selectable],.selectize-dropdown .optgroup-header{padding:3px 12px}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0 none}.selectize-dropdown .optgroup-header{color:#777777;background:#ffffff;cursor:default}.selectize-dropdown .active{background-color:#f5f5f5;color:#262626}.selectize-dropdown .active.create{color:#262626}.selectize-dropdown .create{color:rgba(51,51,51,0.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:17px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#333333 transparent transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px 5px;border-color:transparent transparent #333333 transparent}.selectize-control.rtl.single .selectize-input:after{left:17px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px!important}.selectize-control .selectize-input.disabled{opacity:0.5;background-color:#ffffff}.selectize-dropdown,.selectize-dropdown.form-control{height:auto;padding:0;margin:2px 0 0 0;z-index:1000;background:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175)}.selectize-dropdown .optgroup-header{font-size:12px;line-height:1.42857143}.selectize-dropdown .optgroup:first-child:before{display:none}.selectize-dropdown .optgroup:before{content:' ';display:block;height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5;margin-left:-12px;margin-right:-12px}.selectize-dropdown-content{padding:5px 0}.selectize-dropdown-header{padding:6px 12px}.selectize-input{min-height:34px}.selectize-input.dropdown-active{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.selectize-input.dropdown-active::before{display:none}.selectize-input.focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.has-error .selectize-input{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .selectize-input:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.selectize-control.multi .selectize-input.has-items{padding-left:9px;padding-right:9px}.selectize-control.multi .selectize-input>div{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.form-control.selectize-control{padding:0;height:auto;border:none;background:none;-webkit-box-shadow:none;box-shadow:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.slick-slider{position:relative;display:block;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}.slick-list{position:relative;overflow:hidden;display:block;margin:0;padding:0}.slick-list:focus{outline:none}.slick-loading .slick-list{background:#fff url(/assets/ajax-loader-ee7ed79371d6a288e40fad18ff68ffb0.gif) center center no-repeat}.slick-list.dragging{cursor:pointer;cursor:hand}.slick-slider .slick-track{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.slick-track{position:relative;left:0;top:0;display:block}.slick-track:before,.slick-track:after{content:"";display:table}.slick-track:after{clear:both}.slick-loading .slick-track{visibility:hidden}.slick-slide{float:left;height:100%;min-height:1px;display:none}[dir="rtl"] .slick-slide{float:right}.slick-slide img{display:block}.slick-slide.slick-loading img{display:none}.slick-slide.dragging img{pointer-events:none}.slick-initialized .slick-slide{display:block}.slick-loading .slick-slide{visibility:hidden}.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}.slick-prev,.slick-next{position:absolute;display:block;height:40px;width:20px;line-height:0;font-size:0;cursor:pointer;background:transparent;color:transparent;top:50%;margin-top:-20px;padding:0;border:none;outline:none}.slick-prev:hover,.slick-prev:focus,.slick-next:hover,.slick-next:focus{outline:none;background:transparent;color:transparent}.slick-prev:hover:before,.slick-prev:focus:before,.slick-next:hover:before,.slick-next:focus:before{opacity:1}.slick-prev.slick-disabled,.slick-next.slick-disabled{opacity:0}.slick-prev:before,.slick-next:before{font-family:"Courier";font-size:40px;line-height:1;color:#fff;opacity:.75;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-prev{left:-25px}[dir="rtl"] .slick-prev{left:auto;right:-25px}.slick-prev:before{content:"("}[dir="rtl"] .slick-prev:before{content:")"}.slick-next{right:-25px}[dir="rtl"] .slick-next{left:-25px;right:auto}.slick-next:before{content:")"}[dir="rtl"] .slick-next:before{content:"("}.slick-slider{margin-bottom:30px}.slick-dots{position:absolute;bottom:-45px;list-style:none;display:block;text-align:center;padding:0;width:100%}.slick-dots li{position:relative;display:inline-block;height:20px;width:20px;margin:0 5px;padding:0;cursor:pointer}.slick-dots li button{border:0;background:transparent;display:block;height:20px;width:20px;outline:none;line-height:0;font-size:0;color:transparent;padding:5px;cursor:pointer}.slick-dots li button:hover,.slick-dots li button:focus{outline:none}.slick-dots li button:hover:before,.slick-dots li button:focus:before{opacity:1}.slick-dots li button:before{position:absolute;top:0;left:0;content:"•";width:20px;height:20px;font-family:"Courier";font-size:6px;line-height:20px;text-align:center;color:#000;opacity:.25;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.slick-dots li.slick-active button:before{color:#000;opacity:.75}@media (min-width: 899px){.slick-prev,.slick-next{display:none}}img[data-action="zoom"]{cursor:zoom-in;cursor:-webkit-zoom-in;cursor:-moz-zoom-in}.zoom-img,.zoom-img-wrap{position:relative;z-index:666;-webkit-transition:all 300ms;-o-transition:all 300ms;transition:all 300ms}img.zoom-img{cursor:zoom-out;cursor:-webkit-zoom-out;cursor:-moz-zoom-out}.zoom-overlay{z-index:420;background:#2c3e50;position:fixed;top:0;left:0;right:0;bottom:0;pointer-events:none;filter:"alpha(opacity=0)";opacity:0;-webkit-transition:opacity 300ms;-o-transition:opacity 300ms;transition:opacity 300ms}.zoom-overlay-open .zoom-overlay{filter:"alpha(opacity=80)";opacity:.8}.zoom-overlay-open,.zoom-overlay-transitioning{cursor:default}.bcontainer{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.bcontainer:before,.bcontainer:after{content:" ";display:table}.bcontainer:after{clear:both}@media (min-width: 768px){.bcontainer{width:750px}}@media (min-width: 992px){.bcontainer{width:970px}}@media (min-width: 1200px){.bcontainer{width:1230px}}.bcontainer-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.bcontainer-fluid:before,.bcontainer-fluid:after{content:" ";display:table}.bcontainer-fluid:after{clear:both}.row{margin-left:-15px;margin-right:-15px}.row:before,.row:after{content:" ";display:table}.row:after{clear:both}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-1{width:8.33333%}.col-xs-2{width:16.66667%}.col-xs-3{width:25%}.col-xs-4{width:33.33333%}.col-xs-5{width:41.66667%}.col-xs-6{width:50%}.col-xs-7{width:58.33333%}.col-xs-8{width:66.66667%}.col-xs-9{width:75%}.col-xs-10{width:83.33333%}.col-xs-11{width:91.66667%}.col-xs-12{width:100%}.col-xs-pull-0{right:auto}.col-xs-pull-1{right:8.33333%}.col-xs-pull-2{right:16.66667%}.col-xs-pull-3{right:25%}.col-xs-pull-4{right:33.33333%}.col-xs-pull-5{right:41.66667%}.col-xs-pull-6{right:50%}.col-xs-pull-7{right:58.33333%}.col-xs-pull-8{right:66.66667%}.col-xs-pull-9{right:75%}.col-xs-pull-10{right:83.33333%}.col-xs-pull-11{right:91.66667%}.col-xs-pull-12{right:100%}.col-xs-push-0{left:auto}.col-xs-push-1{left:8.33333%}.col-xs-push-2{left:16.66667%}.col-xs-push-3{left:25%}.col-xs-push-4{left:33.33333%}.col-xs-push-5{left:41.66667%}.col-xs-push-6{left:50%}.col-xs-push-7{left:58.33333%}.col-xs-push-8{left:66.66667%}.col-xs-push-9{left:75%}.col-xs-push-10{left:83.33333%}.col-xs-push-11{left:91.66667%}.col-xs-push-12{left:100%}.col-xs-offset-0{margin-left:0%}.col-xs-offset-1{margin-left:8.33333%}.col-xs-offset-2{margin-left:16.66667%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-4{margin-left:33.33333%}.col-xs-offset-5{margin-left:41.66667%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-7{margin-left:58.33333%}.col-xs-offset-8{margin-left:66.66667%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-10{margin-left:83.33333%}.col-xs-offset-11{margin-left:91.66667%}.col-xs-offset-12{margin-left:100%}@media (min-width: 768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-1{width:8.33333%}.col-sm-2{width:16.66667%}.col-sm-3{width:25%}.col-sm-4{width:33.33333%}.col-sm-5{width:41.66667%}.col-sm-6{width:50%}.col-sm-7{width:58.33333%}.col-sm-8{width:66.66667%}.col-sm-9{width:75%}.col-sm-10{width:83.33333%}.col-sm-11{width:91.66667%}.col-sm-12{width:100%}.col-sm-pull-0{right:auto}.col-sm-pull-1{right:8.33333%}.col-sm-pull-2{right:16.66667%}.col-sm-pull-3{right:25%}.col-sm-pull-4{right:33.33333%}.col-sm-pull-5{right:41.66667%}.col-sm-pull-6{right:50%}.col-sm-pull-7{right:58.33333%}.col-sm-pull-8{right:66.66667%}.col-sm-pull-9{right:75%}.col-sm-pull-10{right:83.33333%}.col-sm-pull-11{right:91.66667%}.col-sm-pull-12{right:100%}.col-sm-push-0{left:auto}.col-sm-push-1{left:8.33333%}.col-sm-push-2{left:16.66667%}.col-sm-push-3{left:25%}.col-sm-push-4{left:33.33333%}.col-sm-push-5{left:41.66667%}.col-sm-push-6{left:50%}.col-sm-push-7{left:58.33333%}.col-sm-push-8{left:66.66667%}.col-sm-push-9{left:75%}.col-sm-push-10{left:83.33333%}.col-sm-push-11{left:91.66667%}.col-sm-push-12{left:100%}.col-sm-offset-0{margin-left:0%}.col-sm-offset-1{margin-left:8.33333%}.col-sm-offset-2{margin-left:16.66667%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-4{margin-left:33.33333%}.col-sm-offset-5{margin-left:41.66667%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-7{margin-left:58.33333%}.col-sm-offset-8{margin-left:66.66667%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-10{margin-left:83.33333%}.col-sm-offset-11{margin-left:91.66667%}.col-sm-offset-12{margin-left:100%}}@media (min-width: 992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-1{width:8.33333%}.col-md-2{width:16.66667%}.col-md-3{width:25%}.col-md-4{width:33.33333%}.col-md-5{width:41.66667%}.col-md-6{width:50%}.col-md-7{width:58.33333%}.col-md-8{width:66.66667%}.col-md-9{width:75%}.col-md-10{width:83.33333%}.col-md-11{width:91.66667%}.col-md-12{width:100%}.col-md-pull-0{right:auto}.col-md-pull-1{right:8.33333%}.col-md-pull-2{right:16.66667%}.col-md-pull-3{right:25%}.col-md-pull-4{right:33.33333%}.col-md-pull-5{right:41.66667%}.col-md-pull-6{right:50%}.col-md-pull-7{right:58.33333%}.col-md-pull-8{right:66.66667%}.col-md-pull-9{right:75%}.col-md-pull-10{right:83.33333%}.col-md-pull-11{right:91.66667%}.col-md-pull-12{right:100%}.col-md-push-0{left:auto}.col-md-push-1{left:8.33333%}.col-md-push-2{left:16.66667%}.col-md-push-3{left:25%}.col-md-push-4{left:33.33333%}.col-md-push-5{left:41.66667%}.col-md-push-6{left:50%}.col-md-push-7{left:58.33333%}.col-md-push-8{left:66.66667%}.col-md-push-9{left:75%}.col-md-push-10{left:83.33333%}.col-md-push-11{left:91.66667%}.col-md-push-12{left:100%}.col-md-offset-0{margin-left:0%}.col-md-offset-1{margin-left:8.33333%}.col-md-offset-2{margin-left:16.66667%}.col-md-offset-3{margin-left:25%}.col-md-offset-4{margin-left:33.33333%}.col-md-offset-5{margin-left:41.66667%}.col-md-offset-6{margin-left:50%}.col-md-offset-7{margin-left:58.33333%}.col-md-offset-8{margin-left:66.66667%}.col-md-offset-9{margin-left:75%}.col-md-offset-10{margin-left:83.33333%}.col-md-offset-11{margin-left:91.66667%}.col-md-offset-12{margin-left:100%}}@media (min-width: 1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-1{width:8.33333%}.col-lg-2{width:16.66667%}.col-lg-3{width:25%}.col-lg-4{width:33.33333%}.col-lg-5{width:41.66667%}.col-lg-6{width:50%}.col-lg-7{width:58.33333%}.col-lg-8{width:66.66667%}.col-lg-9{width:75%}.col-lg-10{width:83.33333%}.col-lg-11{width:91.66667%}.col-lg-12{width:100%}.col-lg-pull-0{right:auto}.col-lg-pull-1{right:8.33333%}.col-lg-pull-2{right:16.66667%}.col-lg-pull-3{right:25%}.col-lg-pull-4{right:33.33333%}.col-lg-pull-5{right:41.66667%}.col-lg-pull-6{right:50%}.col-lg-pull-7{right:58.33333%}.col-lg-pull-8{right:66.66667%}.col-lg-pull-9{right:75%}.col-lg-pull-10{right:83.33333%}.col-lg-pull-11{right:91.66667%}.col-lg-pull-12{right:100%}.col-lg-push-0{left:auto}.col-lg-push-1{left:8.33333%}.col-lg-push-2{left:16.66667%}.col-lg-push-3{left:25%}.col-lg-push-4{left:33.33333%}.col-lg-push-5{left:41.66667%}.col-lg-push-6{left:50%}.col-lg-push-7{left:58.33333%}.col-lg-push-8{left:66.66667%}.col-lg-push-9{left:75%}.col-lg-push-10{left:83.33333%}.col-lg-push-11{left:91.66667%}.col-lg-push-12{left:100%}.col-lg-offset-0{margin-left:0%}.col-lg-offset-1{margin-left:8.33333%}.col-lg-offset-2{margin-left:16.66667%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-4{margin-left:33.33333%}.col-lg-offset-5{margin-left:41.66667%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-7{margin-left:58.33333%}.col-lg-offset-8{margin-left:66.66667%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-10{margin-left:83.33333%}.col-lg-offset-11{margin-left:91.66667%}.col-lg-offset-12{margin-left:100%}}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.stolen-color{color:#C0392B}.safe-color{color:#2ECC71}#alert-block{z-index:99999;position:fixed;top:100px;left:0;width:100%;margin:0 auto}#alert-block .alert{-webkit-box-shadow:-2px 2px 4px rgba(0,0,0,0.2);box-shadow:-2px 2px 4px rgba(0,0,0,0.2);-ms-filter:"progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color='#000000')";z-index:99999;position:absolute;right:0;top:20px;opacity:.95}@media (min-width: 899px){#alert-block .alert{width:380px;margin:0 50px 0 0}}@media (max-width: 599px){#alert-block .alert{width:90%;margin:0;right:5%}}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success,.alert-notice{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr,.alert-notice hr{border-top-color:#c9e2b3}.alert-success .alert-link,.alert-notice .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger,.alert-error{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr,.alert-error hr{border-top-color:#e4b9c0}.alert-danger .alert-link,.alert-error .alert-link{color:#843534}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;src:local("Open Sans Light"),local("OpenSans-Light"),url(https://themes.googleusercontent.com/static/fonts/opensans/v8/DXI1ORHCpsQm3Vp6mXoaTaRDOzjiPcYnFooOUGCOsRk.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;src:local("Open Sans Light Italic"),local("OpenSansLight-Italic"),url(https://themes.googleusercontent.com/static/fonts/opensans/v8/PRmiXeptR36kaC0GEAetxvR_54zmj3SbGZQh3vCOwvY.woff) format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:bold;src:local("Open Sans"),local("OpenSans"),url(https://themes.googleusercontent.com/static/fonts/opensans/v8/cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff) format("woff")}@font-face{font-family:'Klinic';src:url("/assets/KlinicSlabBook.otf");font-weight:normal;font-style:normal}@font-face{font-family:'Klinic';src:url("/assets/KlinicSlabBookIt.otf");font-weight:normal;font-style:italic}@font-face{font-family:'Klinic';src:url("/assets/KlinicSlabMedium.otf");font-weight:bold;font-style:normal}h1{font-size:40px}@media (max-width: 899px){h1{font-size:30px}}@media (max-width: 599px){h1{font-size:23px}}h3{font-size:22px}@media (max-width: 599px){h3{font-size:20px}}h4{font-size:20px}@media (max-width: 599px){h4{font-size:18px}}header.with-subtitle{padding-bottom:20px;padding-top:20px}header.with-subtitle:before,header.with-subtitle:after{content:" ";display:table}header.with-subtitle:after{clear:both}@media (max-width: 599px){header.with-subtitle{padding-bottom:10px}}header.with-subtitle h1,header.with-subtitle h2,header.with-subtitle h3,header.with-subtitle h4{margin:0}header.with-subtitle p{display:inline-block;float:right;margin-top:0;padding-top:0;margin-left:.25em}@media (min-width: 899px){header.with-subtitle h1,header.with-subtitle h2,header.with-subtitle h3,header.with-subtitle h4{float:left;max-width:74.5%}header.with-subtitle p{max-width:23.5%;padding-top:10px}}@media (min-width: 1199px){header.with-subtitle h1,header.with-subtitle h2,header.with-subtitle h3,header.with-subtitle h4{max-width:83%}header.with-subtitle p{max-width:15%}}.btn,.swagger-section input.submit{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.swagger-section input.submit:focus,.btn:active:focus,.swagger-section input.submit:active:focus,.btn.active:focus,.swagger-section input.active.submit:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.swagger-section input.submit:hover,.btn:focus,.swagger-section input.submit:focus{color:#333;text-decoration:none}.btn:active,.swagger-section input.submit:active,.btn.active,.swagger-section input.active.submit{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 3px rgba(0,0,0,0.125);box-shadow:inset 0 3px 3px rgba(0,0,0,0.125)}.btn.disabled,.swagger-section input.disabled.submit,.btn[disabled],.swagger-section input[disabled].submit,fieldset[disabled] .btn,fieldset[disabled] .swagger-section input.submit,.swagger-section fieldset[disabled] input.submit{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open>.btn-default.dropdown-toggle{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.btn-default.dropdown-toggle{background-image:none}.btn-default.disabled,.btn-default.disabled:hover,.btn-default.disabled:focus,.btn-default.disabled:active,.btn-default.disabled.active,.btn-default[disabled],.btn-default[disabled]:hover,.btn-default[disabled]:focus,.btn-default[disabled]:active,.btn-default[disabled].active,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default:hover,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open>.btn-primary.dropdown-toggle{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.btn-primary.dropdown-toggle{background-image:none}.btn-primary.disabled,.btn-primary.disabled:hover,.btn-primary.disabled:focus,.btn-primary.disabled:active,.btn-primary.disabled.active,.btn-primary[disabled],.btn-primary[disabled]:hover,.btn-primary[disabled]:focus,.btn-primary[disabled]:active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary:hover,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open>.btn-success.dropdown-toggle{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.btn-success.dropdown-toggle{background-image:none}.btn-success.disabled,.btn-success.disabled:hover,.btn-success.disabled:focus,.btn-success.disabled:active,.btn-success.disabled.active,.btn-success[disabled],.btn-success[disabled]:hover,.btn-success[disabled]:focus,.btn-success[disabled]:active,.btn-success[disabled].active,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success:hover,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open>.btn-info.dropdown-toggle{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.btn-info.dropdown-toggle{background-image:none}.btn-info.disabled,.btn-info.disabled:hover,.btn-info.disabled:focus,.btn-info.disabled:active,.btn-info.disabled.active,.btn-info[disabled],.btn-info[disabled]:hover,.btn-info[disabled]:focus,.btn-info[disabled]:active,.btn-info[disabled].active,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info:hover,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open>.btn-warning.dropdown-toggle{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.btn-warning.dropdown-toggle{background-image:none}.btn-warning.disabled,.btn-warning.disabled:hover,.btn-warning.disabled:focus,.btn-warning.disabled:active,.btn-warning.disabled.active,.btn-warning[disabled],.btn-warning[disabled]:hover,.btn-warning[disabled]:focus,.btn-warning[disabled]:active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning:hover,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open>.btn-danger.dropdown-toggle{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.btn-danger.dropdown-toggle{background-image:none}.btn-danger.disabled,.btn-danger.disabled:hover,.btn-danger.disabled:focus,.btn-danger.disabled:active,.btn-danger.disabled.active,.btn-danger[disabled],.btn-danger[disabled]:hover,.btn-danger[disabled]:focus,.btn-danger[disabled]:active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger:hover,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#3498DB;font-weight:normal;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:hover,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.binxbtn-lg,.btn.binxbtn.binxbtn-lg,.swagger-section input.binxbtn-lg.submit,.btn.binxbtn-primary.binxbtn-lg,.btn.binxbtn-default.binxbtn-lg,.btn.binxbtn-danger.binxbtn-lg{padding:.25em 1em;font-size:20px}.btn.binxbtn,.swagger-section input.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;border:none;background:#2ECC71;color:#fff;padding:.5em 1em;font-weight:400;box-shadow:-0.01em 0.01em 0px #27AE60,-.006em .006em 0 #27AE60,-.012em .012em 0 #27AE60,-.018em .018em 0 #27AE60,-.024em .024em 0 #27AE60,-.03em .03em 0 #27AE60,-.036em .036em 0 #27AE60,-.042em .042em 0 #27AE60,-.048em .048em 0 #27AE60,-.054em .054em 0 #27AE60,-.06em .06em 0 #27AE60,-.066em .066em 0 #27AE60,-.072em .072em 0 #27AE60,-.078em .078em 0 #27AE60,-.084em .084em 0 #27AE60,-.09em .09em 0 #27AE60;font-size:16px;font-family:"Open Sans",sans-serif}.btn.binxbtn:hover,.swagger-section input.submit:hover,.btn.binxbtn:focus,.swagger-section input.submit:focus,.btn.binxbtn:active,.swagger-section input.submit:active,.btn.binxbtn.active,.swagger-section input.active.submit,.open>.btn.binxbtn.dropdown-toggle,.swagger-section .open>input.dropdown-toggle.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;background:#62D994;color:#fff}.btn.binxbtn:active,.swagger-section input.submit:active{background:#2ECC71}.btn.binxbtn-primary,.swagger-section input.binxbtn-primary.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;border:none;background:#3498DB;color:#fff;padding:.5em 1em;font-weight:400;box-shadow:-0.01em 0.01em 0px #2574A0,-.006em .006em 0 #2574A0,-.012em .012em 0 #2574A0,-.018em .018em 0 #2574A0,-.024em .024em 0 #2574A0,-.03em .03em 0 #2574A0,-.036em .036em 0 #2574A0,-.042em .042em 0 #2574A0,-.048em .048em 0 #2574A0,-.054em .054em 0 #2574A0,-.06em .06em 0 #2574A0,-.066em .066em 0 #2574A0,-.072em .072em 0 #2574A0,-.078em .078em 0 #2574A0,-.084em .084em 0 #2574A0,-.09em .09em 0 #2574A0;font-size:16px;font-family:"Open Sans",sans-serif}.btn.binxbtn-primary:hover,.swagger-section input.binxbtn-primary.submit:hover,.btn.binxbtn-primary:focus,.swagger-section input.binxbtn-primary.submit:focus,.btn.binxbtn-primary:active,.swagger-section input.binxbtn-primary.submit:active,.btn.binxbtn-primary.active,.swagger-section input.binxbtn-primary.active.submit,.open>.btn.binxbtn-primary.dropdown-toggle,.swagger-section .open>input.binxbtn-primary.dropdown-toggle.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;background:#67B2E4;color:#fff}.btn.binxbtn-primary:active,.swagger-section input.binxbtn-primary.submit:active{background:#3498DB}.btn.binxbtn-default,.swagger-section input.binxbtn-default.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;border:none;background:#ECF0F1;color:#111;padding:.5em 1em;font-weight:400;box-shadow:-0.01em 0.01em 0px #acacac,-.006em .006em 0 #acacac,-.012em .012em 0 #acacac,-.018em .018em 0 #acacac,-.024em .024em 0 #acacac,-.03em .03em 0 #acacac,-.036em .036em 0 #acacac,-.042em .042em 0 #acacac,-.048em .048em 0 #acacac,-.054em .054em 0 #acacac,-.06em .06em 0 #acacac,-.066em .066em 0 #acacac,-.072em .072em 0 #acacac,-.078em .078em 0 #acacac,-.084em .084em 0 #acacac,-.09em .09em 0 #acacac;font-size:16px;font-family:"Open Sans",sans-serif}.btn.binxbtn-default:hover,.swagger-section input.binxbtn-default.submit:hover,.btn.binxbtn-default:focus,.swagger-section input.binxbtn-default.submit:focus,.btn.binxbtn-default:active,.swagger-section input.binxbtn-default.submit:active,.btn.binxbtn-default.active,.swagger-section input.binxbtn-default.active.submit,.open>.btn.binxbtn-default.dropdown-toggle,.swagger-section .open>input.binxbtn-default.dropdown-toggle.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;background:#F4F6F7;color:#111}.btn.binxbtn-default:active,.swagger-section input.binxbtn-default.submit:active{background:#ECF0F1}.btn.binxbtn-danger,.swagger-section input.binxbtn-danger.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;border:none;background:#E85546;color:#fff;padding:.5em 1em;font-weight:400;box-shadow:-0.01em 0.01em 0px #c0392b,-.006em .006em 0 #c0392b,-.012em .012em 0 #c0392b,-.018em .018em 0 #c0392b,-.024em .024em 0 #c0392b,-.03em .03em 0 #c0392b,-.036em .036em 0 #c0392b,-.042em .042em 0 #c0392b,-.048em .048em 0 #c0392b,-.054em .054em 0 #c0392b,-.06em .06em 0 #c0392b,-.066em .066em 0 #c0392b,-.072em .072em 0 #c0392b,-.078em .078em 0 #c0392b,-.084em .084em 0 #c0392b,-.09em .09em 0 #c0392b;font-size:16px;font-family:"Open Sans",sans-serif}.btn.binxbtn-danger:hover,.swagger-section input.binxbtn-danger.submit:hover,.btn.binxbtn-danger:focus,.swagger-section input.binxbtn-danger.submit:focus,.btn.binxbtn-danger:active,.swagger-section input.binxbtn-danger.submit:active,.btn.binxbtn-danger.active,.swagger-section input.binxbtn-danger.active.submit,.open>.btn.binxbtn-danger.dropdown-toggle,.swagger-section .open>input.binxbtn-danger.dropdown-toggle.submit{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;background:#ED796D;color:#fff}.btn.binxbtn-danger:active,.swagger-section input.binxbtn-danger.submit:active{background:#E85546}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;text-rendering:optimizeLegibility}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857;color:#555}.form-control{display:block;width:100%;height:auto;font-weight:400;font-size:16px;font-family:"Open Sans",sans-serif;line-height:1.2em;color:#111;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:2px;padding:.5em .5em .3em;-webkit-transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;-o-transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;-webkit-box-shadow:none;box-shadow:none}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:0 0 2px rgba(102,175,233,0.6);box-shadow:0 0 2px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#C4C6C6;opacity:1}.form-control:-ms-input-placeholder{color:#C4C6C6}.form-control::-webkit-input-placeholder{color:#C4C6C6}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{line-height:34px;line-height:1.42857 \0}input[type="date"].input-sm,.form-horizontal .form-group-sm input[type="date"].form-control,input[type="time"].input-sm,.form-horizontal .form-group-sm input[type="time"].form-control,input[type="datetime-local"].input-sm,.form-horizontal .form-group-sm input[type="datetime-local"].form-control,input[type="month"].input-sm,.form-horizontal .form-group-sm input[type="month"].form-control{line-height:30px}input[type="date"].input-lg,.form-horizontal .form-group-lg input[type="date"].form-control,input[type="time"].input-lg,.form-horizontal .form-group-lg input[type="time"].form-control,input[type="datetime-local"].input-lg,.form-horizontal .form-group-lg input[type="datetime-local"].form-control,input[type="month"].input-lg,.form-horizontal .form-group-lg input[type="month"].form-control{line-height:46px}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;min-height:20px;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="radio"].disabled,fieldset[disabled] input[type="radio"],input[type="checkbox"][disabled],input[type="checkbox"].disabled,fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,fieldset[disabled] .radio-inline,.checkbox-inline.disabled,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,fieldset[disabled] .radio label,.checkbox.disabled label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-horizontal .form-group-lg .form-control-static.form-control,.form-control-static.input-sm,.form-horizontal .form-group-sm .form-control-static.form-control{padding-left:0;padding-right:0}.input-sm,.form-horizontal .form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,.form-horizontal .form-group-sm select.form-control{height:30px;line-height:30px}textarea.input-sm,.form-horizontal .form-group-sm textarea.form-control,select[multiple].input-sm,.form-horizontal .form-group-sm select[multiple].form-control{height:auto}.input-lg,.form-horizontal .form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,.form-horizontal .form-group-lg select.form-control{height:46px;line-height:46px}textarea.input-lg,.form-horizontal .form-group-lg textarea.form-control,select[multiple].input-lg,.form-horizontal .form-group-lg select[multiple].form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:25px;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}.input-lg+.form-control-feedback,.form-horizontal .form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.form-horizontal .form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:none;box-shadow:none}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.075);box-shadow:inset 0 1px 2px rgba(0,0,0,0.075)}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:none;box-shadow:none}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.075);box-shadow:inset 0 1px 2px rgba(0,0,0,0.075)}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:none;box-shadow:none}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.075);box-shadow:inset 0 1px 2px rgba(0,0,0,0.075)}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#515151}@media (min-width: 768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}@media (min-width: 768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}@media (min-width: 768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width: 768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.select2-choices{font-size:16px;border-radius:2px;min-height:29px}.select2-container-multi .select2-choices .select2-search-choice{margin-top:5px}.select2-container-multi .select2-choices .select2-search-field input,.select2-container-multi,.select2-container-multi input,.select2-choices,.select2-results{font-family:"Open Sans",sans-serif;font-size:1em}label{cursor:pointer}.label-with-tip{position:relative}.label-with-tip:before,.label-with-tip:after{content:" ";display:table}.label-with-tip:after{clear:both}.label-with-tip p{float:left;margin:0;width:120px}.formtip{display:block;position:relative;margin-top:-.2em;cursor:help;color:#217dbb;padding:.2em .5em;width:20px;text-decoration:none;float:left}.formtip a,.formtip a:hover{position:absolute;top:0;left:0;width:100%;height:100%;z-index:100}.control-group.actions input{float:left}.form-suggestion{margin-top:.5em}@media (min-width: 480px){.control-group.actions{width:98%;max-width:650px;padding-left:370px;margin-left:2%}}@media (max-width: 600px){.control-group.actions{padding-left:0}.control-group.actions input{float:right}}.well{padding-top:20px;padding-bottom:20px;padding-left:20px;padding-right:20px;min-height:20px;background-color:#EEF2F3;border:1px solid #ECF0F1;border-radius:2px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}@media (max-width: 599px){.well{padding-top:10px}}@media (max-width: 599px){.well{padding-bottom:10px}}@media (max-width: 599px){.well{padding-left:10px}}@media (max-width: 599px){.well{padding-right:10px}}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open .dropdown-menu{z-index:2050}.modal-open .dropdown.open{*z-index:2050}.modal-open .popover{z-index:2110}.modal-open .tooltip{z-index:2120}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:black}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;border-radius:4px;box-shadow:0 3px 7px rgba(0,0,0,0.3);position:fixed;top:50%;left:50%;z-index:1050;overflow:auto;width:560px;margin:-250px 0 0 -280px;background-color:white;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999}.modal.fade{-webkit-transition:opacity 0.3s linear,top 0.3s ease-out;-o-transition:opacity 0.3s linear,top 0.3s ease-out;transition:opacity 0.3s linear,top 0.3s ease-out;top:-25%}.modal.fade.in{top:50%}.modal-header{border-bottom:1px solid #ECF0F1;padding:9px 15px}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{overflow-y:auto;max-height:80%;padding:15px}@media (max-width: 700px){.modal-body{max-height:300px}}@media (min-width: 768px){.modal{max-height:70%}}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#F4F6F7;border-top:1px solid #ECF0F1}.modal-footer:before,.modal-footer:after{content:" ";display:table}.modal-footer:after{clear:both}.modal-footer .btn+.btn,.modal-footer .swagger-section input.submit+.btn,.swagger-section .modal-footer input.submit+.btn,.modal-footer .swagger-section .btn+input.submit,.swagger-section .modal-footer .btn+input.submit,.modal-footer .swagger-section input.submit+input.submit,.swagger-section .modal-footer input.submit+input.submit{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn,.modal-footer .btn-group .swagger-section input.submit+.btn,.swagger-section .modal-footer .btn-group input.submit+.btn,.modal-footer .btn-group .swagger-section .btn+input.submit,.swagger-section .modal-footer .btn-group .btn+input.submit,.modal-footer .btn-group .swagger-section input.submit+input.submit,.swagger-section .modal-footer .btn-group input.submit+input.submit{margin-left:-1px}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}@media (max-width: 899px){.modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media (max-width: 599px){.modal{top:10px;left:10px;right:10px}.modal-header .close{padding:10px;margin:-10px}}.horizontal-list{margin:0;padding:0;list-style-type:none}.horizontal-list:before,.horizontal-list:after{content:" ";display:table}.horizontal-list:after{clear:both}.horizontal-list li{float:left}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857}dt{font-weight:bold}dd{margin-left:0}.dl-horizontal dd:before,.dl-horizontal dd:after{content:" ";display:table}.dl-horizontal dd:after{clear:both}@media (min-width: 768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}table .less-strong-hold{position:relative}table .less-strong-right{color:#bebebe;position:absolute;right:-.3em;bottom:-.5em;font-size:.8em}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}table{background-color:transparent}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>thead>tr>td,.table>tbody>tr>th,.table>tbody>tr>td,.table>tfoot>tr>th,.table>tfoot>tr>td{padding:8px;line-height:1.42857;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>th,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>thead>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>thead>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>thead>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>thead>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>thead>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media screen and (max-width: 767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:auto;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}.partner-block{clear:top;position:relative}.partner-block a{display:block}.partner-block .partner-text{float:left;position:relative}.partner-block h3,.partner-block p{color:#34495E;font-family:"Open Sans",sans-serif}.partner-block h3{margin:0}.partner-block p{margin:.5em 0 0}.partner-block .partner-image{position:relative;float:right}.partner-block .partner-image img{width:100%;height:auto;display:block}.partner-block .ad-label{display:block;position:absolute;bottom:0;right:0;background:rgba(153,203,237,0.5);color:#EBF5FB;padding:.25em .5em;z-index:20;border-radius:4px 0 0 0;font-size:12px}.container.partner-block-container,#grid-overlay .partner-block-container.grid-receptacle,.partner-block-container.content-container{padding-top:30px;padding-bottom:50px}@media (max-width: 599px){.container.partner-block-container,#grid-overlay .partner-block-container.grid-receptacle,.partner-block-container.content-container{padding-top:10px}}@media (max-width: 550px){.container.partner-block-container,#grid-overlay .partner-block-container.grid-receptacle,.partner-block-container.content-container{padding-bottom:20px}.partner-block h3{font-size:20px}.partner-block p{font-size:.9em;margin-top:.25em}}@media (max-width: 767px){.container.partner-block-container,#grid-overlay .partner-block-container.grid-receptacle,.partner-block-container.content-container{display:none}}@media (min-width: 768px){.partner-block{float:right}}@media (min-width: 950px){.container.partner-block-container,#grid-overlay .partner-block-container.grid-receptacle,.partner-block-container.content-container{padding-top:0}}@media (min-width: 1000px){.container.partner-block-container,#grid-overlay .partner-block-container.grid-receptacle,.partner-block-container.content-container{margin-top:-12px}}@media (min-width: 768px) and (max-width: 1199px){.partner-block{width:728px}.partner-block .partner-text{width:63%}.partner-block .partner-image{width:35%;margin-left:2%}}@media (min-width: 1200px){.container.partner-block-container,#grid-overlay .partner-block-container.grid-receptacle,.partner-block-container.content-container{margin-top:-30px}.partner-block{width:66%}.partner-block .partner-text{width:61.3575%}.partner-block .partner-image{width:35.6025%;margin-left:3.03%}}.sharing-section:before,.sharing-section:after{content:" ";display:table}.sharing-section:after{clear:both}.sharing-section .sharing-buttons{float:right}.sharing-section .twitter-share-button{display:block;float:right;margin-right:10px}.sharing-section .fb-like{display:block;float:right;overflow:visible;margin-top:2px}*{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;text-rendering:optimizeLegibility}html{width:100%;max-width:100%;margin:0;padding:0;background:#ECF0F1}body{width:100%;max-width:100%;position:relative;background:#fff;color:#111;font-size:16px;font-family:"Open Sans",sans-serif;font-weight:300;margin:0;padding:0}.bodywrap{position:relative;width:100%;height:100%;overflow:hidden}a{color:#3498DB;text-decoration:none;font-weight:300}a:hover{text-decoration:none;color:#1d6fa5}h1,h2,h3,h4{font-weight:400;line-height:1.2em;margin:0 0 .5em;padding:0}h1 strong,h2 strong,h3 strong,h4 strong{font-weight:bold}p{margin:.5em 0 0}#old-browser-warning{width:100%;background:#EEF2F3;border-bottom:1px solid #ECF0F1;z-index:9999;padding:10px;position:fixed;top:0;left:0;text-align:center}#old-browser-warning h4{color:#C0392B}.global-header{position:relative;display:block;width:100%}@media (min-width: 600px){.global-header{padding-top:20px}}.bikes-nav{width:100%;max-width:1200px;margin:0 auto;position:relative}@media (min-width: 600px){.top-logo{display:block;width:15%;position:relative;float:left;z-index:10}.top-logo .logo{display:block;width:100%;height:auto;position:relative}.top-logo .stripey{display:block;position:absolute;z-index:0;left:-350%;width:400%;height:100%;background:image-url("updated/stripes.svg") repeat-x;background-size:100% 100%}.top-logo .top-stripes{height:100%;display:block;position:absolute;z-index:0;left:-50%}}.small-header .hamburglar{display:none;position:absolute;width:6.5%;top:10px;height:41px;left:10px}.small-header .hamburglar img{display:block;height:100%;width:auto}@media (max-width: 599px){.container.bikes-nav,#grid-overlay .bikes-nav.grid-receptacle,.bikes-nav.content-container{padding:3px 0}.small-header{width:100%;position:relative;display:block;background:url("/assets/updated/stripes.png") repeat-x;background-size:100% 100%;height:60px;overflow:visible}.small-header .top-logo{display:block;width:100px;position:relative;margin:0 auto;z-index:10}.small-header .top-logo img{display:inline-block;width:70px;height:auto;margin-top:-3px}.small-header .hamburglar{display:block}}@media (min-width: 1500px){.top-logo .stripey{width:1000%;left:-950%}}@media (min-width: 600px){.top-user-nav{position:relative;float:left;width:83%;margin-left:2%}.top-user-nav ul{margin:0;padding:0;list-style-type:none;min-height:1.2em}.top-user-nav ul:before,.top-user-nav ul:after{content:" ";display:table}.top-user-nav ul:after{clear:both}.top-user-nav ul li{float:right;width:7.8325%;margin-right:2.4%;text-align:center}.top-user-nav ul li.double-width{width:18%}.top-user-nav ul li.first-link{margin-right:0}.top-user-nav ul a{color:#2C3E50}.top-user-nav ul a.low-priority{color:#a7a7a7}.top-user-nav ul a:hover{color:#3498DB}}@media (max-width: 599px){.top-user-nav{display:none}.top-user-nav ul{list-style-type:none;margin:0;padding:.5em 0 0;background:#2C3E50;position:relative}.top-user-nav ul li{width:100%;position:relative}.top-user-nav ul li:nth-of-type(2n) a{background:#354b60}.top-user-nav ul li a{display:block;padding:.5em 1em;width:100%;color:#fff;background:none}.top-user-nav ul li a:hover{background:#3498DB}}.bike-search-form{margin-top:20px;display:block;position:relative}@media (max-width: 599px){.bike-search-form{margin-top:10px}}.bike-search-form:before,.bike-search-form:after{content:" ";display:table}.bike-search-form:after{clear:both}.bike-search-form .searchit,.bike-search-form .search-text-field{font-size:18px;display:block;position:relative;float:left;padding:4px 0}.bike-search-form .search-text-field{font-size:18px;border:none;padding:0;border-radius:2px 0 0 2px}.bike-search-form .search-text-field .selectize-input{line-height:1.5em!important;border-radius:2px 0 0 2px;height:2.5em}.bike-search-form .search-text-field .selectize-input>div{background:none;border:1px solid rgba(52,152,219,0.8);font-size:18px;line-height:1em;padding-top:.4em;padding-left:.4em;padding-bottom:.4em}.bike-search-form .search-text-field .selectize-dropdown.multi.form-control{top:-.1em!important}.bike-search-form .search-text-field .selectize-dropdown .sch_ .highlight{background:none}.bike-search-form .search-text-field .selectize-dropdown .selectize-dropdown-content .active{background:rgba(52,152,219,0.3)}.bike-search-form .searchit{-webkit-transition:background ease-in-out 0.1s;-o-transition:background ease-in-out 0.1s;transition:background ease-in-out 0.1s;border-radius:0 2px 2px 0;margin-left:0;background:#2C3E50;height:2.5em}.bike-search-form .searchit img{display:block;height:100%;width:auto;margin:0 auto}.bike-search-form .searchit:hover,.bike-search-form .searchit:active,.bike-search-form .searchit:focus{-webkit-transition:background ease-in-out 0.1s;-o-transition:background ease-in-out 0.1s;transition:background ease-in-out 0.1s;background:#3498DB;box-shadow:none}.bike-search-form .stolen-search-link{clear:both}.bike-search-form .stolen-search-link a{padding:.5em 0 .5em .8em;color:rgba(52,152,219,0.6);display:block}.bike-search-form .stolen-search-link a:hover{color:#3498DB}.bike-search-form .stolen-search-fields{display:none;padding:.5em 0;clear:both}.bike-search-form .stolen-search-fields:before,.bike-search-form .stolen-search-fields:after{content:" ";display:table}.bike-search-form .stolen-search-fields:after{clear:both}.bike-search-form .stolen-search-fields input,.bike-search-form .stolen-search-fields span{display:block;float:right;padding:.25em .5em}.bike-search-form .stolen-search-fields input{background:#ECF0F1;border-radius:2px;border:none}.bike-search-form .stolen-search-fields .stolen-radius{width:4.2em}.bike-search-form .stolen-search-fields .stolen-proximity{width:30%}.bike-search-form .stolen-search-fields span{color:#bebebe}@media (max-width: 599px){.bike-search-form{width:100%;float:none;padding:0 10px}.bike-search-form .search-text-field{width:85%}.bike-search-form .searchit{width:15%}}@media (min-width: 600px){.bike-search-form{width:74.5%;float:right}.bike-search-form .search-text-field{width:91.256%}.bike-search-form .searchit{width:8.723%}}#bikes-search{display:none}.selectize-dropdown-content{background:#F4F6F7;border:1px solid #ECF0F1;border-top:1px solid rgba(236,240,241,0.5);font-size:18px;border-radius:0 0 2px 2px}.selectize-dropdown-content .select2-results{padding:0;margin-right:0;max-height:300px}.selectize-dropdown-content .select2-result-label{padding:.35em 7px}.selectize-dropdown-content .select2-highlighted .sch_s{color:#ccc}.selectize-dropdown-content .sch_s{display:inline-block}.selectize-dropdown-content .sch_m,.selectize-dropdown-content .sch_{color:#ccc}.selectize-dropdown-content .sch_c{color:#bbb;display:inline-block}.selectize-dropdown-content .sch_special{border-bottom:1px solid #ddd}.sclr{border-radius:3px;display:inline-block;width:24px;height:24px;border:1px solid white;line-height:.8em;margin:0 6px 0 0;font-size:.5em;text-align:center;padding-top:1em}@media (max-width: 600px){.selectize-dropdown-content .select2-results{max-height:200px}.selectize-dropdown-content .sch_s,.selectize-dropdown-content .sch_m,.selectize-dropdown-content .sch_{font-size:14px}.selectize-dropdown-content .sch_s span,.selectize-dropdown-content .sch_m span,.selectize-dropdown-content .sch_ span{display:none}}.search_span_s,.search_span_m{color:#bbb;margin-left:0;margin-right:3px;display:inline}.container,#grid-overlay .grid-receptacle,.content-container{position:relative;width:100%;max-width:1200px;margin:0 auto;padding:0}.container:before,#grid-overlay .grid-receptacle:before,.content-container:before,.container:after,#grid-overlay .grid-receptacle:after,.content-container:after{content:" ";display:table}.container:after,#grid-overlay .grid-receptacle:after,.content-container:after{clear:both}@media (max-width: 1199px){.container,#grid-overlay .grid-receptacle,.content-container{padding-left:20px;padding-right:20px}}@media (max-width: 1199px) and (max-width: 599px){.container,#grid-overlay .grid-receptacle,.content-container{padding-left:10px}}@media (max-width: 1199px) and (max-width: 599px){.container,#grid-overlay .grid-receptacle,.content-container{padding-right:10px}}.content-container{min-height:400px}.global-footer{position:relative;z-index:1;padding:75px 0 30px;background:#ECF0F1}.global-footer a:hover{text-decoration:underline}.global-footer p{text-align:center;color:#bebebe;font-size:.8em;margin-top:30px}.global-footer p a{color:#99CBED}.global-footer .footer-links{list-style-type:none;padding:0 0 1em;margin:0}.global-footer .footer-links:before,.global-footer .footer-links:after{content:" ";display:table}.global-footer .footer-links:after{clear:both}.global-footer .footer-links>li{position:relative;width:23.5%;margin-right:2%;float:left}.global-footer .footer-links>li:last-of-type{margin-right:0}.global-footer .footer-links a{display:block;width:100%;color:#34495E;font-size:22px}.global-footer .footer-links ul{list-style-type:none;margin:0;padding:0}.global-footer .footer-links ul li{padding:.3em 0 0}.global-footer .footer-links ul a{font-family:"Open Sans",sans-serif;font-size:14px;color:#95A5A5}.global-footer .footer-links .social ul:before,.global-footer .footer-links .social ul:after{content:" ";display:table}.global-footer .footer-links .social ul:after{clear:both}.global-footer .footer-links .social li{position:relative;width:28%;margin-right:8%;float:left;padding:0;cursor:pointer}.global-footer .footer-links .social li:last-of-type{margin-right:0}.global-footer .footer-links .social a{border-radius:4px;margin:0 auto;margin:0;background-clip:padding-box}.global-footer .footer-links .social a.footer-facebook,.global-footer .footer-links .social a.footer-instagram{background:#2C3E50}.global-footer .footer-links .social a.footer-facebook:hover,.global-footer .footer-links .social a.footer-instagram:hover{background:#507192}.global-footer .footer-links .social a.footer-twitter{background:#3498DB}.global-footer .footer-links .social a.footer-twitter:hover{background:#8bc4ea}.global-footer .footer-links .social a img{display:block;width:100%;height:auto}.global-footer .footer-links .social a:hover{-webkit-transition:background 0.15s linear;-o-transition:background 0.15s linear;transition:background 0.15s linear}.global-footer .footer-links .social a:active{-webkit-transform:translate(1px,1px);-ms-transform:translate(1px,1px);-o-transform:translate(1px,1px);transform:translate(1px,1px)}@media (max-width: 650px){.global-footer .footer-links>li{width:49%;margin-bottom:1.5em}.global-footer .footer-links>li:nth-of-type(2){margin-right:0}.global-footer .footer-links>li:nth-of-type(3){clear:both}.global-footer .footer-links .social li{width:30%;margin-right:4%}}@media (min-width: 1200px){.global-footer .footer-links .social a{width:80px;border-radius:40px}}.paginate-container,.paginate-container-bottom{padding-top:20px;padding-bottom:20px;width:100%;clear:both}.paginate-container:before,.paginate-container-bottom:before,.paginate-container:after,.paginate-container-bottom:after{content:" ";display:table}.paginate-container:after,.paginate-container-bottom:after{clear:both}@media (max-width: 599px){.paginate-container,.paginate-container-bottom{padding-top:10px}}@media (max-width: 599px){.paginate-container,.paginate-container-bottom{padding-bottom:10px}}.paginate-container-bottom{margin-top:20px;margin-bottom:40px}@media (max-width: 599px){.paginate-container-bottom{margin-top:10px}}.pagination{cursor:default;margin:0}.pagination:before,.pagination:after{content:" ";display:table}.pagination:after{clear:both}.pagination ul{float:right;margin:0;padding:0;list-style-type:none}.pagination ul li{float:left}.pagination a,.pagination span,.pagination em{border-radius:2px;background:#99CBED;padding:0.5em 1em;line-height:1.2em;display:block;float:left;margin-left:.5em;margin-bottom:.5em;font-weight:200;color:#fff;border:none}.pagination .previous_page{margin-left:0}.pagination .previous_page,.pagination .next_page{font-weight:normal}.pagination .disabled{display:none}.pagination .current,.pagination .active a{font-style:normal;font-weight:bold;background:#3498DB}.pagination a:hover,.pagination a:focus{color:#000033;background:#EBF5FB}.pagination .page_info{background:#2e6ab1;color:white;padding:0.4em 0.6em;width:22em;margin-bottom:0.3em;text-align:center}.pagination .page_info b{color:#000033;background:#6aa6ed;padding:0.1em 0.25em}@media (max-width: 599px){.pagination a,.pagination span,.pagination em{padding:.5em .7em}}.bike-pagination-counted{float:left}.serial-text{font-family:Courier;text-transform:uppercase;font-size:1.1em}.attr-title{display:inline-block;margin-right:.4em}.attr-list{list-style-type:none;margin:0;padding:0;position:relative}.attr-list:before,.attr-list:after{content:" ";display:table}.attr-list:after{clear:both}.attr-list li{width:100%;padding:.5em 1em}.attr-list li:nth-of-type(2n-1){background:#ECF0F1}.attr-list li .attr-title{font-weight:700}.bikes-search-type-tabs{border-bottom:1px solid #cdcdcd}.bikes-search-type-tabs ul{list-style-type:none;padding:0;margin:0;width:100%;position:relative}.bikes-search-type-tabs ul:before,.bikes-search-type-tabs ul:after{content:" ";display:table}.bikes-search-type-tabs ul:after{clear:both}.bikes-search-type-tabs li{float:left;margin-left:1%;max-width:32%}.bikes-search-type-tabs li:first-of-type{margin-left:1.5%}.bikes-search-type-tabs a{border-radius:4px 4px 0 0;border-bottom:1px solid transparent;display:block;padding:1em;position:relative}.bikes-search-type-tabs a:hover{background:#EEF2F3}.bikes-search-type-tabs a.active{border:1px solid #cdcdcd;background:#fff;border-bottom:2px solid #fff;margin-bottom:-2px;z-index:10}.bikes-search-type-tabs .bottom-cover{width:100%;background:#fff;border-top:1px solid #cdcdcd;height:2em;z-index:1;position:relative;display:none}@media (max-width: 1199px){.bikes-search-type-tabs{border-bottom:none;padding-top:30px}.bikes-search-type-tabs .bottom-cover{display:block}.bikes-search-type-tabs .container,.bikes-search-type-tabs #grid-overlay .grid-receptacle,#grid-overlay .bikes-search-type-tabs .grid-receptacle,.bikes-search-type-tabs .content-container{padding:0}.bikes-search-type-tabs a{margin-bottom:-2px;padding:.5em;text-align:center;height:4.2em}}.bike-boxes{padding:0 0 40px;padding-top:20px;margin:0;display:block;list-style-type:none;position:relative;width:100%}@media (max-width: 599px){.bike-boxes{padding-top:10px}}.bike-boxes li{width:100%;max-width:1250px;margin:5px auto 0;position:relative;display:block;padding:0;width:100%}.bike-boxes li:nth-of-type(2n){background:#EBF5FB}@media (max-width: 1199px){.bike-boxes li{padding-left:20px;padding-right:20px}}@media (max-width: 1199px) and (max-width: 599px){.bike-boxes li{padding-left:10px}}@media (max-width: 1199px) and (max-width: 599px){.bike-boxes li{padding-right:10px}}.bike-box{padding:0;padding-top:20px;padding-bottom:20px;max-width:1200px;margin:0 auto;position:relative}.bike-box:before,.bike-box:after{content:" ";display:table}.bike-box:after{clear:both}@media (max-width: 599px){.bike-box{padding-top:10px}}@media (max-width: 599px){.bike-box{padding-bottom:10px}}.bike-box .image-holder{display:block;float:left;width:23.5%;margin-left:2%}.bike-box .image-holder img{display:block;width:100%;height:auto}.bike-box .information-holder{float:left;width:74.5%;position:relative}.bike-box .information-holder .bike-information,.bike-box .information-holder .theft-information{display:block;margin:0}.bike-box .information-holder .theft-information{color:#C0392B}.bike-box .information-holder .theft-information h3{margin:.5em 0 .2em}.bike-box .information-holder h3{margin:0}.bike-box .information-holder h3 a{padding-bottom:.2em;position:relative;display:block}.bike-box .information-holder a{color:#111}.bike-box .information-holder a:hover{color:#3498DB}.bike-box .information-holder p{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:.25em 0 0}@media (min-width: 899px){.bike-box .image-holder{width:8.5%;position:absolute;float:none;right:0;top:50%;height:100%;margin-left:0}.bike-box .image-holder img{margin-top:-50%}.bike-box .information-holder{float:none;width:91.5%}.bike-box .information-holder:before,.bike-box .information-holder:after{content:" ";display:table}.bike-box .information-holder:after{clear:both}.bike-box .information-holder .bike-information,.bike-box .information-holder .theft-information{float:left;width:53.41%}.bike-box .information-holder .theft-information{width:44.145%;margin-left:2.18%}.bike-box .information-holder .theft-information h3{margin:0 0 .5em}.bike-box h3 a{padding-bottom:.5em}}.no-results{padding:2em 0 3em;text-align:center}.secondary-bikes{padding:1em 0;margin-top:20px;text-align:center;color:#2C3E50;border-top:1px solid #ECF0F1}@media (max-width: 599px){.secondary-bikes{margin-top:10px}}.show-bike-edit{-webkit-box-shadow:0 0 2px rgba(0,0,0,0.2);box-shadow:0 0 2px rgba(0,0,0,0.2);padding-top:20px;padding-bottom:20px;padding-left:20px;padding-right:20px;position:fixed;bottom:0;width:100%;background:rgba(52,152,219,0.92);border-left:0;border-right:0;z-index:555}@media (max-width: 599px){.show-bike-edit{padding-top:10px}}@media (max-width: 599px){.show-bike-edit{padding-bottom:10px}}@media (max-width: 599px){.show-bike-edit{padding-left:10px}}@media (max-width: 599px){.show-bike-edit{padding-right:10px}}.show-bike-edit p{text-align:center;margin:0;color:white}.show-bike-edit .btn,.show-bike-edit .swagger-section input.submit,.swagger-section .show-bike-edit input.submit{margin-left:20px}.single-bike-show{padding-bottom:60px}@media (max-width: 599px){.single-bike-show{padding-bottom:40px}}.bike-show-main .bike-photos{position:relative}.bike-show-main .bike-photos img{display:block;width:100%;height:auto}.bike-show-main .attr-list{margin-top:20px}@media (max-width: 599px){.bike-show-main .attr-list{margin-top:10px}}@media (min-width: 599px){.bike-show-main:before,.bike-show-main:after{content:" ";display:table}.bike-show-main:after{clear:both}.bike-show-main .bike-photos,.bike-show-main .attr-list{float:right;width:49%}.bike-show-main .attr-list{float:left;margin-top:0}}.bike-show-description{clear:both}.bike-show-components{clear:both}.bike-show-components:before,.bike-show-components:after{content:" ";display:table}.bike-show-components:after{clear:both}.bike-show-components .comp-group{padding-top:20px}@media (max-width: 599px){.bike-show-components .comp-group{padding-top:10px}}.bike-show-components .comp-group h3{margin-bottom:.25em}@media (min-width: 599px){.bike-show-components .comp-group{position:relative;width:49%;float:left}.bike-show-components .comp-group:nth-of-type(2n){margin-left:2%}.bike-show-components .comp-group:nth-of-type(2n+1){clear:left}}.bike-show-stolen h2{font-size:28px;font-weight:700;margin-bottom:.25em}.bike-show-stolen #map_canvas{width:100%;height:400px}.bike-show-stolen .stolen-map{margin-top:20px}@media (max-width: 599px){.bike-show-stolen .stolen-map{margin-top:10px}}@media (min-width: 599px){.bike-show-stolen:before,.bike-show-stolen:after{content:" ";display:table}.bike-show-stolen:after{clear:both}.bike-show-stolen h2{font-size:35px}.bike-show-stolen .stolen-map,.bike-show-stolen .attr-list{float:right;width:49%}.bike-show-stolen .stolen-map{float:left;margin-top:0}}.bike-show-stolen-contact{margin-top:20px;padding-top:20px;padding-bottom:20px;padding-left:20px;padding-right:20px;clear:both;border:1px solid #dde4e6;border-radius:2px;background-color:#F4F6F7}@media (max-width: 599px){.bike-show-stolen-contact{margin-top:10px}}@media (max-width: 599px){.bike-show-stolen-contact{padding-top:10px}}@media (max-width: 599px){.bike-show-stolen-contact{padding-bottom:10px}}@media (max-width: 599px){.bike-show-stolen-contact{padding-left:10px}}@media (max-width: 599px){.bike-show-stolen-contact{padding-right:10px}}.bike-show-stolen-contact .send-message{padding-top:10px}.bike-show-stolen-contact .send-message:before,.bike-show-stolen-contact .send-message:after{content:" ";display:table}.bike-show-stolen-contact .send-message:after{clear:both}.bike-show-stolen-contact .send-message .btn,.bike-show-stolen-contact .send-message .swagger-section input.submit,.swagger-section .bike-show-stolen-contact .send-message input.submit{float:right}.bike-photos .image-holder{z-index:1}.bike-photos .image-holder a{display:block}.bike-photos .image-holder img{-webkit-transition:opacity ease-in-out 0.3s;-o-transition:opacity ease-in-out 0.3s;transition:opacity ease-in-out 0.3s;cursor:pointer;opacity:0;margin:0 auto}.bike-photos .image-holder .current-photo img{-webkit-transition:opacity ease-in 1s;-o-transition:opacity ease-in 1s;transition:opacity ease-in 1s;opacity:1}.bike-photos .image-holder .current-photo .transitioning-photo,.bike-photos .image-holder .transitioning-photo{position:absolute;top:0;left:0;width:100%}.thumbnail-shadow,.thumbnail-shadow-r{display:none;position:absolute;bottom:-2px;height:122px;width:10px;z-index:20}.overflown .thumbnail-shadow,.overflown .thumbnail-shadow-r{display:block}.overflown .photo-list ul{left:-2px}.thumbnail-shadow{left:0;box-shadow:inset 8px 0 6px -8px rgba(236,240,241,0.95)}.thumbnail-shadow-r{right:0;box-shadow:inset -8px 0 6px -8px rgba(236,240,241,0.95)}.photo-list{border-radius:0 0 2px 2px;margin-top:10px;clear:both;position:relative;height:120px;background:#fff;width:100%;margin:0;padding:0;overflow-y:hidden;overflow-x:scroll;z-index:10}.photo-list:before,.photo-list:after{content:" ";display:table}.photo-list:after{clear:both}.photo-list ul{list-style-type:none;position:absolute;left:0;top:0;overflow:visible;height:100%;margin:0;padding:5px 0;border:none}.photo-list li{position:relative;margin:0;float:left;height:100%;width:178px;margin:0 10px 5px 0}.photo-list li:last-of-type{margin-right:0;border-right:none}.photo-list a{height:100%;width:100%;overflow:hidden;display:block}.photo-list img{padding:0;width:100%;height:auto}.photo-list .clickable-image{-webkit-transition:all ease-in-out 0.2s;-o-transition:all ease-in-out 0.2s;transition:all ease-in-out 0.2s;border-radius:2px;box-shadow:none;position:relative;padding:0;margin:0;display:block;border:1px solid #F4F6F7}.photo-list .clickable-image.current-thumb{-webkit-transition:all ease-in-out 0.2s;-o-transition:all ease-in-out 0.2s;transition:all ease-in-out 0.2s;border-color:#3498DB;box-shadow:0 0 2px rgba(52,152,219,0.8)}.photo-list .video-overlay{display:block;position:absolute;top:50%;left:50%;width:34px;height:34px;margin:-17px 0 0 -17px;border:0}.stock-photo{position:absolute;top:0;left:0;padding:20px;padding-left:20px;padding-right:20px;background:rgba(44,62,80,0.85);box-shadow:0 0 2px rgba(0,0,0,0.2);border-radius:2px;border:1px solid #3e5871;border-left:none;border-right:none;width:100%;font-size:24px;color:white;text-align:center}@media (max-width: 599px){.stock-photo{padding-left:10px}}@media (max-width: 599px){.stock-photo{padding-right:10px}}.stock-photo strong{font-weight:700}.stock-photo span{display:block;color:rgba(255,255,255,0.8);font-style:italic}.welcome-page{background:#ECF0F1}.welcome-page .bike-search-form .search-text-field.select2-container.select2-container-multi{background:#fff}.welcome-page .mainsrchdr{background:#f9f9f9;border:1px solid #a7a7a7;border-top:1px solid rgba(236,240,241,0.5)}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.home-header h1{padding:40px 0 25px;margin:0;text-align:center;font-size:40px;font-weight:300;color:#2C3E50;font-weight:700;font-family:"Open Sans",sans-serif;text-transform:uppercase}.home-header h1 span{display:block}.home-header h1 a{width:100%;height:2em;left:0;position:absolute}.home-header h3{font-size:20px;text-align:center;margin:0 auto;color:#2C3E50}@media (max-width: 599px){.home-header h1{text-shadow:-2px 2px 0 #3498DB}.home-header h1 a{height:4em}}@media (min-width: 600px){.home-header h1{padding:30px 0 35px;font-size:50px;font-weight:600;line-height:1em;text-shadow:-0.01em 0.01em 0px #3498DB,-.004em .004em 0 #3498DB,-.008em .008em 0 #3498DB,-.012em .012em 0 #3498DB,-.016em .016em 0 #3498DB,-.02em .02em 0 #3498DB,-.024em .024em 0 #3498DB,-.028em .028em 0 #3498DB,-.032em .032em 0 #3498DB,-.036em .036em 0 #3498DB,-.04em .04em 0 #3498DB,-.044em .044em 0 #3498DB,-.048em .048em 0 #3498DB,-.052em .052em 0 #3498DB,-.056em .056em 0 #3498DB,-.06em .06em 0 #3498DB}.home-header h3{font-size:32px}}@media (min-width: 901px){.home-header h1{font-size:75px}}.register-container{display:block;width:100%;position:absolute;left:0;top:35%;z-index:20;width:100%;text-align:center}.register-container .btn.binxbtn,.register-container .swagger-section input.submit,.swagger-section .register-container input.submit{font-size:40px}@media (max-width: 599px){.register-container .btn,.register-container .swagger-section input.submit,.swagger-section .register-container input.submit{font-size:30px}}.wheeled{padding:20px 0 0;position:relative}.wheel-holder{display:block;width:90%;margin:0 auto;overflow:hidden;min-height:250px}.wheel-holder img{-webkit-transition:all ease-in-out 1.5s;-o-transition:all ease-in-out 1.5s;transition:all ease-in-out 1.5s;-webkit-transform:translate3d(0,0,0);-webkit-backface-visibility:hidden;display:block;width:100%;height:auto}.wheel-holder img.spun{-webkit-transition:all ease-out 1.5s;-o-transition:all ease-out 1.5s;transition:all ease-out 1.5s;-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}@media (min-width: 600px){.wheeled{-webkit-transition:margin ease-in-out 0.5s;-o-transition:margin ease-in-out 0.5s;transition:margin ease-in-out 0.5s;margin-top:-40px;padding-top:0}}@media (min-width: 899px){.wheel-holder{width:70%}}.home-subhead,.how-it-works{background:#fff;padding:60px 0 50px;text-align:center}.home-subhead h2,.how-it-works h2{font-size:44px}.home-subhead p,.home-subhead h3,.how-it-works p,.how-it-works h3{margin:.5em auto 0;font-size:22px;font-family:"Open Sans",sans-serif;font-weight:300}.home-subhead p,.how-it-works p{text-align:left;margin-top:1.25em;font-weight:200}.how-it-works{border-top:10px solid #34495E;border-bottom:10px solid #34495E;background:#3498DB;color:white}.how-it-works a{color:rgba(255,255,255,0.8);text-decoration:underline}.how-it-works a:hover{color:#1d6fa5}@media (min-width: 599px){.how-it-works{padding:70px 0 100px}}@media (min-width: 899px){.home-subhead p,.home-subhead h3{width:83%}}@media (max-width: 599px){.home-subhead,.how-it-works{padding:40px 0}.home-subhead h2,.how-it-works h2{font-size:30px}.home-subhead p,.home-subhead h3,.how-it-works p,.how-it-works h3{font-size:18px}}.home-blank-container{width:100%;height:300px;background:#fff}.info-blocks{padding-top:20px;padding-bottom:20px;width:100%;background:#fff}@media (max-width: 599px){.info-blocks{padding-top:10px}}@media (max-width: 599px){.info-blocks{padding-bottom:10px}}.info-blocks article{position:relative;width:90%;margin:0 auto}.info-blocks article img{display:block;width:40%;height:auto;margin:0 auto}.info-blocks article h2{text-align:center;margin:0;padding:20px 0 0}.info-blocks article p{padding:.5em 0 20px;margin:0 auto;width:80%;text-align:center}@media (min-width: 599px){.info-blocks .container,.info-blocks #grid-overlay .grid-receptacle,#grid-overlay .info-blocks .grid-receptacle,.info-blocks .content-container{padding:30px 0 20px}.info-blocks article{float:left;width:23.5%;margin:0;margin-left:8.5%;padding-bottom:20px}.info-blocks article img{width:60%}.info-blocks article:first-of-type{margin-left:4.25%}.info-blocks article p{width:100%}}.bike-background{width:100%}.bike-background.scrolled{background:url("/assets/updated/home/bikes_mosaic_small.jpg") fixed}@media (min-width: 1200px){.bike-background.scrolled{background:url("/assets/updated/home/bikes_mosaic_large.jpg") fixed}}.bike-background.scrolled .supporters{display:block}.supporters{display:none;-webkit-box-shadow:inset 0 0 2px rgba(0,0,0,0.6);box-shadow:inset 0 0 2px rgba(0,0,0,0.6);position:relative;min-height:15em;padding:40px 0 4em}.supporters h2{font-size:30px;margin:.75em 0;text-shadow:1px 1px 2px rgba(0,0,0,0.3);color:white}.supporters .horizontal-list li{width:32.8%;margin-left:0.2%;padding:15px}.supporters .horizontal-list li:first-of-type{margin-left:0}.supporters .horizontal-list li a{display:block;width:100%}.supporters .horizontal-list li img{width:100%}.and-many-more{bottom:0;left:3%;width:94%;font-size:18px;color:#fff;text-align:right;margin:0;padding:1.5em 0 .25em}.and-many-more a{font-weight:400;color:#cae4f6}.and-many-more a:hover{color:#3498DB}@media (min-width: 625px){.supporters{padding-bottom:5em}.supporters h2{font-size:40px}.supporters .horizontal-list li{width:16.46%;padding:0}.supporters .five-supporters li:first-of-type{margin-left:8.23%}}@media (min-width: 700px){.supporters .and-many-more{font-size:28px}}@media (min-width: 1000px){.supporters h2{font-size:50px}}@media (min-width: 1300px){.supporters h2{margin-left:-5%}}.testimonial-container{width:100%;position:relative}.testimonial-block:before,.testimonial-block:after{content:" ";display:table}.testimonial-block:after{clear:both}.testimonial-block h3,.testimonial-block h4,.testimonial-block p{margin:0}.testimonial-block .testimonial-user{display:block;position:relative;margin:0 0 0 2%;float:right}.testimonial-block .testimonial-user:before,.testimonial-block .testimonial-user:after{content:" ";display:table}.testimonial-block .testimonial-user:after{clear:both}.testimonial-block img{display:block;margin:0;width:20%;font-size:16px;height:auto;float:right;padding-bottom:.5em}.testimonial-block .h3testimonial{margin:.25em 0 0;font-size:18px;display:block;font-weight:normal}.testimonial-block .h4testimonial{font-size:14px;display:block;font-family:"Open Sans",sans-serif}.testimonial-block .h3testimonial,.testimonial-block .h4testimonial{float:left;text-align:right;margin-left:4.166%;width:75.834%}.testimonial-block .testimonial-quote{float:left;position:relative;width:74.5%;margin:0;background:#fff;padding:1em;line-height:1.3em}.testimonial-block .testimonial-quote:before{content:"";height:0;width:0;right:-14px;position:absolute;border-bottom:22.5px solid transparent;border-left:15px solid #fff}.testimonial-block .testimonial-quote .ptestimonial{margin:0;line-height:1.2em}@media (min-width: 600px){.testimonial-block .testimonial-user{width:23%;padding-top:.5em}.testimonial-block .h3testimonial,.testimonial-block .h4testimonial{margin-left:0}.testimonial-block .no-image-spacer{display:block;width:100%;padding:10px}.testimonial-block img{width:100%}.testimonial-block .h3testimonial{padding-top:1em}.testimonial-block .h3testimonial,.testimonial-block .h4testimonial{width:100%;float:none;text-align:center}.testimonial-block .testimonial-quote{margin-top:40px;font-size:18px;border-radius:4px 0px 4px 4px}.testimonial-block .testimonial-quote:before{top:0}}@media (min-width: 1199px){.testimonial-block .h3testimonial{font-size:24px}.testimonial-block .h4testimonial{font-size:14px}.testimonial-block.testmonial-2{padding:20px 0}.testimonial-block .testimonial-user{width:14.5%}.testimonial-block .testimonial-quote{width:83%;font-size:20px}}@media (max-width: 899px) and (min-width: 599px){.testimonial-block .testimonial-user{padding-top:1em;padding-left:.5em}.testimonial-block .h4testimonial .recovery-date{display:block;margin-top:-.25em}}@media (max-width: 599px){.testimonial-block .testimonial-user{width:100%;padding:20px 0 0;margin-left:0}.testimonial-block .h3testimonial{margin-top:1em}.testimonial-block .h3testimonial,.testimonial-block .h4testimonial{text-align:right;margin-right:2%;margin-left:0}.testimonial-block img{float:right}.testimonial-block .testimonial-quote{width:99%;margin:0 .5%;position:relative;border-radius:4px 4px 0 4px}.testimonial-block .testimonial-quote:before{right:0;bottom:-15px;border-left:15px solid transparent;border-bottom:22.5px solid transparent;border-right:15px solid #fff}}.stolen-bike-merge-alert{margin:30px auto;max-width:600px}.sbr-wrap{background:#f9f9f9;color:#7a7a7a}.sbr-wrap .list-stolen-bike{margin-top:3px;float:right}.sbr-wrap section{border-bottom:1px solid #bebebe;padding:30px 0}.sbr-wrap section:nth-of-type(2n){background:#fff}.sbr-main-section .alert h4{font-size:24px}.sbr-main-section .stolen-registry-logo{width:200px;margin:0 auto;padding:2.5em 0 30px}.sbr-main-section .stolen-registry-logo img{display:block;width:100%;height:auto}.sbr-main-section h1{font-size:30px;text-align:center;color:#3a3a3a;padding:0 0 40px}@media (min-width: 600px){.sbr-main-section h1{font-size:40px}.sbr-main-section .stolen-registry-logo{width:280px;padding-top:0}}@media (min-width: 1000px){.sbr-main-section{padding:50px 0 40px}.sbr-main-section .stolen-registry-logo{margin-top:50px}.sbr-main-section h1{font-size:50px}.sbr-main-section .list-stolen-bike{font-size:1.5em}}.sbr-search-fields{max-width:800px;margin:0 auto;padding-bottom:40px}.sbr-search-fields:before,.sbr-search-fields:after{content:" ";display:table}.sbr-search-fields:after{clear:both}.sbr-search-fields input{box-shadow:none;border:1px solid #cccdc8;background:#fff;color:#474747;margin-bottom:.75em}.sbr-search-fields input:focus{box-shadow:none;border-color:#cccdc8}.sbr-search-fields .proximity{clear:both}.sbr-search-fields .proximity input{background:none;border:none;box-shadow:none;margin:2px 0 .1em .1em;padding:0;line-height:1em;color:#7a7a7a;width:10em;border-bottom:1px dashed #cccdc8}.sbr-search-fields .sbr-search-inputs{position:relative}.sbr-search-fields .sbr-bike-search{box-shadow:none;padding:.4em .7em;width:100%;float:left;border-radius:2px;margin-top:5px}.sbr-search-fields .search-type-tab{background:#E6E6E6;padding:5px 10px 3px 10px;color:#7a7a7a;margin-left:5px;border:1px solid #cccdc8;border-radius:2px 2px 0 0;border-bottom:none;position:relative;z-index:10}.sbr-search-fields .search-type-tab:first-of-type{margin-left:10px}.sbr-search-fields .search-type-tab.active{background:#fff;padding-bottom:5px;border-bottom:1px solid #fff}.sbr-search-fields .search-type-tab.active:hover{background:#fff}.sbr-search-fields .search-type-tab:hover{background:#f9f9f9;text-decoration:none}.sbrbtn{height:1.9em;position:absolute;top:.36em;right:.2em;border:none;padding:3px;background:none;font-size:19px;border-radius:2px}.sbrbtn img{display:block;height:100%;width:auto}.sbrbtn:hover,.sbrbtn:active,.sbrbtn:focus{background:#DC7D59;box-shadow:none;border:none;outline:none}.sbrbtn:active{background:#D25627}@media (max-width: 600px){.sbr-search-fields .sbrbtn{top:.4em}.sbr-search-fields .proximity input{width:8em}}.sbr-banner{width:100%;padding:1em 0;text-align:center;background:#3B97D3;color:#fff}.sbr-get-involved .banner{text-align:center;padding:20px 0 60px;font-weight:400;font-size:20px}.sbr-get-involved:before,.sbr-get-involved:after{content:" ";display:table}.sbr-get-involved:after{clear:both}.sbr-get-involved h1{text-align:center;margin:0 0 1em}.involve-report-form{background:#6EB2DF;border:1px solid #3B97D3;border-radius:4px;padding:20px 10px;color:#fff}.involve-report-form form{margin:0}.involve-report-form input{background:#fff}.involve-report-form input[type="email"],.involve-report-form textarea{font-size:16px;box-shadow:none;border-radius:2px;border:1px solid #cccdc8;background:#f9f9f9;color:#474747;margin-bottom:.75em}.involve-report-form .contact-text{padding-top:1em;width:100%;position:relative}.involve-report-form .contact-text textarea{display:block;width:100%;resize:none;padding:.5em}.involve-report-form .contact-actions{width:100%;position:relative}.involve-report-form .contact-actions:before,.involve-report-form .contact-actions:after{content:" ";display:table}.involve-report-form .contact-actions:after{clear:both}.involve-report-form .contact-actions input[type="email"]{display:block;width:70%;float:left;padding-left:.5em;padding-right:.5em}.involve-report-form .contact-actions .btn,.involve-report-form .contact-actions .swagger-section input.submit,.swagger-section .involve-report-form .contact-actions input.submit{font-size:16px;display:block;float:left;width:28%;margin:0 0 0 2%}.involve-yerself{padding-top:1em}.report-type label{font-size:19px}.report-type label input{margin:-.25em .5em 0 0}#binx_stolen_widget{height:350px}@media (min-width: 800px){.involve-yerself{padding-bottom:60px}.involve-yerself:before,.involve-yerself:after{content:" ";display:table}.involve-yerself:after{clear:both}.involve-yerself h3{margin-top:0}.involve-report{width:60%;float:left}.involve-report .involve-report-form{height:350px}.involve-widget{width:38%;float:left;margin-left:2%}}.contribute-sbr{margin:.5em 0 1em;text-align:center}.sticker-wells{margin:30px 0}.sticker-well select{margin-top:.5em}.sticker-well .sticker-image{-webkit-box-shadow:1px 1px 2px rgba(0,0,0,0.4);box-shadow:1px 1px 2px rgba(0,0,0,0.4);margin-bottom:1em}@media (min-width: 800px){.sticker-wells:before,.sticker-wells:after{content:" ";display:table}.sticker-wells:after{clear:both}.sticker-well{width:49%;float:left;min-height:350px}.sticker-well:nth-of-type(2){margin-left:2%}}.multiserial-form{position:relative;width:100%;max-width:800px;margin:0 auto;padding:0 0 30px}.multiserial-form:before,.multiserial-form:after{content:" ";display:table}.multiserial-form:after{clear:both}.multiserial-form h3{text-align:center;margin:0;padding:0 0 1em;font-size:24px}.multiserial-form textarea{border-radius:3px;font-family:courier;box-shadow:none;display:block;width:100%;height:8em;margin:0;padding:.5em .5em .6em;background:#fff;resize:none}.multiserial-form .sbrbtn{top:7.8em}.multiserial-response{min-height:10em}.multiserials-list{list-style-type:none;margin:0;padding:10px 0 30px}.multiserials-list:before,.multiserials-list:after{content:" ";display:table}.multiserials-list:after{clear:both}.multiserials-list li{border-radius:2px;-webkit-transition:all linear 0.5s;-o-transition:all linear 0.5s;transition:all linear 0.5s;float:left;position:relative;padding:.2em .5em;background:#f7f7f7;margin:0 5px 5px 0}.multiserials-list li.ms-nomatch{text-decoration:line-through}.multiserials-list li.ms-match{background:#3498DB;color:#fff}.multiserials-list li a{-webkit-transition:all ease-in 0.2s;-o-transition:all ease-in 0.2s;transition:all ease-in 0.2s;position:absolute;width:100%;height:100%;left:0;top:0;cursor:pointer;opacity:.9}.multiserials-list li a.blink-class{background:#e1f0fa}.multiserial-fuzzy-box{text-align:center}.multiserial-fuzzy-box a{display:none}.multiserial-fuzzy-box a span{display:none}.multiserial-fuzzy-box a .ms-short-fuzzy{display:inline-block}@media (min-width: 800px){.multiserial-results div{width:48%;float:left;margin-right:4%}.multiserial-fuzzy-box a span{display:inline-block}.multiserial-fuzzy-box a .ms-short-fuzzy{display:none}}.multiserial-results{position:relative;border:1px solid #ECF0F1;padding:20px 10px;margin:1em 0}.multiserial-results:before,.multiserial-results:after{content:" ";display:table}.multiserial-results:after{clear:both}.multiserial-results h3{margin-top:0}.multiserial-results .serial-text{font-size:.9em;color:#a7a7a7}.multiserial-results li .serial-text{padding-left:.5em}.multiserial-results .multiserial-fuzzy-result{margin-right:0}.multiserial-results .multiserial-fuzzy-result h3{color:#a7a7a7}.multiserial-results .multiserial-fuzzy-result h3 .serial-text{color:#ECF0F1}#ms_form_section,#ms_search_section{display:none}.multi-search-toggle{font-size:20px;margin:0 0 1em}.multi-search-toggle a{text-decoration:none;color:#99CBED}.multi-search-toggle a:hover{color:#3498DB}.multi-search-toggle .multi{display:inline-block}.doorkeeper{background:white}.doorkeeper body .global-header{background:#ECF0F1}@media (min-width: 600px){.doorkeeper .global-header{padding-bottom:20px}}.doorkeeper-container{padding-top:80px;padding-bottom:80px;background:white}.doorkeeper-container h1,.doorkeeper-container h2,.doorkeeper-container h3,.doorkeeper-container h4,.doorkeeper-container h5{margin:.4em 0}.doorkeeper-container .authorize-application-section .actions form{float:left;position:relative;width:49%}.doorkeeper-container .authorize-application-section .actions form:last-of-type{margin-left:2%}.doorkeeper-container .form-group:before,.doorkeeper-container .form-group:after{content:" ";display:table}.doorkeeper-container .form-group:after{clear:both}.payments-page{padding:40px 0 60px}.payments-page form .binxbtn,.payments-page form .swagger-section input.submit,.swagger-section .payments-page form input.submit{margin:0 auto;display:block;font-size:20px;max-width:200px}.payment-types-list{position:relative;list-style-type:none;margin:0;padding:30px 0}.payment-types-list:before,.payment-types-list:after{content:" ";display:table}.payment-types-list:after{clear:both}.payment-types-list li{display:block;float:left;position:relative}.payment-types-list li a{-webkit-transition:all ease-out 0.1s;-o-transition:all ease-out 0.1s;transition:all ease-out 0.1s;border-radius:4px;display:block;width:100%;padding:1.5em 1em}.payment-types-list li .unselected{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;border:none;background:#ECF0F1;color:rgba(17,17,17,0.9);padding:.5em 1em;font-weight:400;box-shadow:-0.01em 0.01em 0px #acacac,-.015em .015em 0 #acacac,-.03em .03em 0 #acacac,-.045em .045em 0 #acacac,-.06em .06em 0 #acacac,-.075em .075em 0 #acacac,-.09em .09em 0 #acacac,-.105em .105em 0 #acacac,-.12em .12em 0 #acacac,-.135em .135em 0 #acacac,-.15em .15em 0 #acacac,-.165em .165em 0 #acacac,-.18em .18em 0 #acacac,-.195em .195em 0 #acacac,-.21em .21em 0 #acacac,-.225em .225em 0 #acacac}.payment-types-list li .unselected:hover,.payment-types-list li .unselected:focus,.payment-types-list li .unselected:active,.payment-types-list li .unselected.active,.open>.payment-types-list li .unselected.dropdown-toggle{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;background:#F4F6F7;color:rgba(17,17,17,0.9)}.payment-types-list li .unselected:active{background:#ECF0F1}.payment-types-list li .active{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;border:none;background:#3498DB;color:rgba(255,255,255,0.9);padding:.5em 1em;font-weight:400;box-shadow:-0.01em 0.01em 0px #2574A0,-.015em .015em 0 #2574A0,-.03em .03em 0 #2574A0,-.045em .045em 0 #2574A0,-.06em .06em 0 #2574A0,-.075em .075em 0 #2574A0,-.09em .09em 0 #2574A0,-.105em .105em 0 #2574A0,-.12em .12em 0 #2574A0,-.135em .135em 0 #2574A0,-.15em .15em 0 #2574A0,-.165em .165em 0 #2574A0,-.18em .18em 0 #2574A0,-.195em .195em 0 #2574A0,-.21em .21em 0 #2574A0,-.225em .225em 0 #2574A0}.payment-types-list li .active:hover,.payment-types-list li .active:focus,.payment-types-list li .active:active,.payment-types-list li .active.active,.open>.payment-types-list li .active.dropdown-toggle{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;background:#67B2E4;color:rgba(255,255,255,0.9)}.payment-types-list li .active:active{background:#3498DB}.payment-types-list li .active hr{border-bottom:1px solid rgba(255,255,255,0.15)}.payment-types-list li .active .donation input{background:#67B2E4;color:white}.payment-types-list li h3{padding-top:1em;color:#34495E;font-size:20px}.payment-types-list li hr{margin:1em 0;border:none;border-top:1px solid rgba(0,0,0,0.1);border-bottom:1px solid rgba(255,255,255,0.8)}.payment-types-list li .perks{min-height:7em}.payment-types-list li .donation{min-height:3em;padding:0 1em;text-align:center}.payment-types-list li .donation input{width:100%;text-align:center;background:#F4F6F7}.container.payments-page .payment-types-list.just-one li,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li,.payments-page.content-container .payment-types-list.just-one li{min-width:50%;margin:0 auto;display:block;float:none}.container.payments-page .payment-types-list.just-one li a,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a,.payments-page.content-container .payment-types-list.just-one li a{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;border:none;background:#ECF0F1;color:rgba(17,17,17,0.9);padding:.5em 1em;font-weight:400;box-shadow:-0.01em 0.01em 0px #acacac,-.015em .015em 0 #acacac,-.03em .03em 0 #acacac,-.045em .045em 0 #acacac,-.06em .06em 0 #acacac,-.075em .075em 0 #acacac,-.09em .09em 0 #acacac,-.105em .105em 0 #acacac,-.12em .12em 0 #acacac,-.135em .135em 0 #acacac,-.15em .15em 0 #acacac,-.165em .165em 0 #acacac,-.18em .18em 0 #acacac,-.195em .195em 0 #acacac,-.21em .21em 0 #acacac,-.225em .225em 0 #acacac}.container.payments-page .payment-types-list.just-one li a:hover,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a:hover,.payments-page.content-container .payment-types-list.just-one li a:hover,.container.payments-page .payment-types-list.just-one li a:focus,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a:focus,.payments-page.content-container .payment-types-list.just-one li a:focus,.container.payments-page .payment-types-list.just-one li a:active,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a:active,.payments-page.content-container .payment-types-list.just-one li a:active,.container.payments-page .payment-types-list.just-one li a.active,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a.active,.payments-page.content-container .payment-types-list.just-one li a.active,.open>.container.payments-page .payment-types-list.just-one li a.dropdown-toggle,#grid-overlay .open>.payments-page.grid-receptacle .payment-types-list.just-one li a.dropdown-toggle,.open>.payments-page.content-container .payment-types-list.just-one li a.dropdown-toggle{-webkit-transition:background ease-out 0.1s;-o-transition:background ease-out 0.1s;transition:background ease-out 0.1s;background:#F4F6F7;color:rgba(17,17,17,0.9)}.container.payments-page .payment-types-list.just-one li a:active,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a:active,.payments-page.content-container .payment-types-list.just-one li a:active{background:#ECF0F1}.container.payments-page .payment-types-list.just-one li a .donation input,#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a .donation input,.payments-page.content-container .payment-types-list.just-one li a .donation input{background:#fff;color:#111}@media (min-width: 900px){.payments-page{padding:60px 0 100px}.payment-types-list li{margin:0 0 0 1%;width:19%}.payment-types-list li:first-of-type{margin-left:0}}@media (max-width: 899px){.payment-types-list li{margin:20px 0 0 2%;width:47%}.payment-types-list li:nth-of-type(5){margin-left:26%}}.swagger-ui-wrap ul{margin:0}.swagger-ui-wrap select.parameter{width:100%}.content-header{background:#ECF0F1;border-top:1px solid #f2f5f5;border-bottom:1px solid #d7e0e2}@media (min-width: 600px){.content-header{padding:10px 0}.content-header .top-logo{width:6.5%}}#header{position:fixed;top:0;left:0;width:100%;z-index:1000;background:#ECF0F1;padding:0;-webkit-transition:transform 200ms linear;-o-transition:transform 200ms linear;transition:transform 200ms linear}#header.headroom--pinned{-webkit-transform:translate(0,0%);-ms-transform:translate(0,0%);-o-transform:translate(0,0%);transform:translate(0,0%)}#header.headroom--unpinned{-webkit-transform:translate(0,-100%);-ms-transform:translate(0,-100%);-o-transform:translate(0,-100%);transform:translate(0,-100%)}.swagger-section .content-header a#logo{font-size:1.5em;font-weight:bold;text-decoration:none;background:transparent url("/assets/documentation_v2/logo_small.png") no-repeat left center;padding:20px 0 20px 40px;color:white}.swagger-section .content-header form#api_selector{display:block;width:100%;position:relative;padding-top:1em}.swagger-section .content-header form#api_selector:before,.swagger-section .content-header form#api_selector:after{content:" ";display:table}.swagger-section .content-header form#api_selector:after{clear:both}.swagger-section .content-header .api-header-group{padding:0 10px .25em}.swagger-section .content-header .api-header-group label{font-weight:400;color:#bebebe;margin-bottom:.3em}.swagger-section .content-header .api-header-group input{box-shadow:none}.swagger-section .content-header .api-header-url input{background:none;border:none}.swagger-section .content-header a#explore{color:white;float:right;margin:.25em 10px 10px 0}.swagger-section{padding-top:60px}.swagger-section .content{min-height:10px}.swagger-section .sandbox_header{padding:5px 2px}@media (min-width: 1200px){.swagger-section .container-fluid{max-width:1230px;margin:0 auto}}@media (min-width: 599px){.swagger-section #header form#api_selector{width:91.5%;float:left;padding-top:.3em}.swagger-section #header form#api_selector .api-header-group{float:left;margin-right:2%;position:relative;padding:0}.swagger-section #header form#api_selector .api-header-url{width:33%}.swagger-section #header form#api_selector .api-header-url label{padding-left:.5em}.swagger-section #header form#api_selector .api-header-key{width:53%}.swagger-section #header form#api_selector a#explore{float:left;width:10%;margin:1.2em 0 0;padding-left:0;padding-right:0}}.start-of-swagger-ui{padding-top:40px}@media (min-width: 899px){.start-of-swagger-ui{padding-top:80px}}.swagger-ui-wrap .operations .content>ul{list-style-type:square}.swagger-ui-wrap .operations .content>ul br{display:none}.swagger-ui-wrap ul#resources li.resource div.heading h2{font-weight:normal}.swagger-ui-wrap ul#resources li.resource div.heading h2 a{font-size:1.1em}.swagger-ui-wrap ul#resources>li.resource{margin-bottom:30px;border-top:1px solid #dddddd;border-bottom:0}.swagger-section .container h2,.swagger-section #grid-overlay .grid-receptacle h2,#grid-overlay .swagger-section .grid-receptacle h2,.swagger-section .content-container h2{font-size:24px}.swagger-section .container strong,.swagger-section #grid-overlay .grid-receptacle strong,#grid-overlay .swagger-section .grid-receptacle strong,.swagger-section .content-container strong{font-weight:bold}.swagger-section .container .alert,.swagger-section #grid-overlay .grid-receptacle .alert,#grid-overlay .swagger-section .grid-receptacle .alert,.swagger-section .content-container .alert{line-height:1.2em}.swagger-section .container p,.swagger-section #grid-overlay .grid-receptacle p,#grid-overlay .swagger-section .grid-receptacle p,.swagger-section .content-container p{padding-bottom:.5em}.swagger-section .container pre,.swagger-section #grid-overlay .grid-receptacle pre,#grid-overlay .swagger-section .grid-receptacle pre,.swagger-section .content-container pre{margin:.5em 0 2em}.swagger-section .container pre code,.swagger-section #grid-overlay .grid-receptacle pre code,#grid-overlay .swagger-section .grid-receptacle pre code,.swagger-section .content-container pre code{background:none}.swagger-section .container .access-tokens,.swagger-section #grid-overlay .grid-receptacle .access-tokens,#grid-overlay .swagger-section .grid-receptacle .access-tokens,.swagger-section .content-container .access-tokens{margin-left:.25em}.swagger-section .container .access-tokens li,.swagger-section #grid-overlay .grid-receptacle .access-tokens li,#grid-overlay .swagger-section .grid-receptacle .access-tokens li,.swagger-section .content-container .access-tokens li{background:white;border-radius:4px;padding:.25em .5em;margin:0 0 .25em}.swagger-section .container .access-tokens p,.swagger-section #grid-overlay .grid-receptacle .access-tokens p,#grid-overlay .swagger-section .grid-receptacle .access-tokens p,.swagger-section .content-container .access-tokens p{margin:0;padding:.1em 0}.swagger-section .container ol,.swagger-section #grid-overlay .grid-receptacle ol,#grid-overlay .swagger-section .grid-receptacle ol,.swagger-section .content-container ol{list-style-type:decimal;padding-left:2em}.swagger-section .container .less-strong,.swagger-section #grid-overlay .grid-receptacle .less-strong,#grid-overlay .swagger-section .grid-receptacle .less-strong,.swagger-section .content-container .less-strong{color:#bebebe;font-size:.8em}.swagger-section .container .authentication-notes,.swagger-section #grid-overlay .grid-receptacle .authentication-notes,#grid-overlay .swagger-section .grid-receptacle .authentication-notes,.swagger-section .content-container .authentication-notes{margin-top:40px}.swagger-section .container .authentication-notes h3,.swagger-section #grid-overlay .grid-receptacle .authentication-notes h3,#grid-overlay .swagger-section .grid-receptacle .authentication-notes h3,.swagger-section .content-container .authentication-notes h3{margin-top:1.5em}.applications-panel{margin-top:60px;padding:30px 0;background:#F4F6F7;border-top:1px solid #ECF0F1;border-bottom:1px solid #ECF0F1}.applications-panel .applications-list{margin:0}.applications-panel .applications-list li{padding:.5em 1em .25em;background:white;margin:1em 0 0;border-radius:4px}.applications-panel .applications-list .authorize-new-explain{margin:0;padding:1em 0 0 0}.applications-panel .application-info{padding-bottom:.5em;position:relative}.applications-panel .application-info .tokens-table{margin-bottom:0}.applications-panel .application-info .tokens-table pre,.applications-panel .application-info .tokens-table .btn,.applications-panel .application-info .tokens-table .swagger-section input.submit,.swagger-section .applications-panel .application-info .tokens-table input.submit{margin:0;padding:.25em .5em}.applications-panel .application-info .tokens-table .binxbtn-primary{margin-bottom:.25em}.applications-panel .listed-app-name{margin:0;display:block;width:90%}.applications-panel .listed-app-name span{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);margin-right:.75em;-webkit-transition:all .1s ease-out;-moz-transition:all .1s ease-out;-o-transition:all .1s ease-out;transition:all .1s ease-out;float:left;display:block;font-size:10px;font-family:helvetica}.applications-panel .listed-app-name a:active span{-webkit-transition:all .1s ease-out;-moz-transition:all .1s ease-out;-o-transition:all .1s ease-out;transition:all .1s ease-out}.applications-panel .listed-app-name .listed-app-name:active span,.applications-panel .listed-app-name.uncollapsed span{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}.swagger-section #api_info{display:none}.api-info-header{padding-top:20px}.api-info-header h1,.api-info-footer h1{margin-top:.75em}.api-info-header h1,.api-info-header h2,.api-info-header h3,.api-info-footer h1,.api-info-footer h2,.api-info-footer h3{margin-bottom:5px}.api-info-header p,.api-info-footer p{margin:0;padding:0 0 .5em 1em}.ref{padding-bottom:10px;display:inline-block}.api-info-footer{padding:40px 0}#resources_container .toggleEndpointList{font-weight:700}.access-tokens li .btn,.access-tokens li .swagger-section input.submit,.swagger-section .access-tokens li input.submit{padding:.25em .5em;margin-left:.5em}.add-token-form label{font-weight:400;margin-right:.5em}.accstr{color:#c0392b;font-size:18px;line-height:0}.protected-endpoint-img{margin:0 auto;display:block}.docs-section-list{display:none}@media (min-width: 1000px){.swagger-section{padding-left:12%}.docs-section-list{display:block;position:fixed;left:0;top:0;width:12%;height:100%;background:#ECF0F1;border-bottom:1px solid #d7e0e2;padding:120px 10px 0}.docs-section-list a{color:#111}.docs-section-list a.scrltrgt,.docs-section-list a:hover{color:#3498DB;text-decoration:underline}.docs-section-list ul{margin-left:.75em}.docs-section-list ul a{font-size:.9em}} +#grid-overlay { + position: fixed; + height: 100%; + width: 100%; + z-index: 99999; +} + +#grid-overlay .grid-receptacle { + padding: 0; + height: 100%; +} + +#grid-overlay .inner-recep { + height: 100%; +} + +#grid-overlay .column { + float: left; + width: 6.5%; + height: 100%; + margin-left: 2%; + border: 1px solid #b2dec1; + border-top: none; + border-bottom: none; +} + +#grid-overlay .inner-recep .column:first-of-type { + margin-left: 0; +} + +.clearfix:before, +.clearfix:after { + content: " "; + display: table; +} + +.clearfix:after { + clear: both; +} + +.pull-right { + float: right !important; +} + +.pull-left { + float: left !important; +} + +.hide { + display: none !important; +} + +.show { + display: block !important; +} + +.invisible { + visibility: hidden; +} + +.hidden { + display: none !important; + visibility: hidden !important; +} + +.padded { + padding-top: 20px; +} + +@media (max-width: 599px) { + .padded { + padding-top: 10px; + } +} + +.margined { + margin-top: 20px; +} + +@media (max-width: 599px) { + .margined { + margin-top: 10px; + } +} + +.with-divider { + border-top: 1px solid #e6e6e6; +} + +body .selectize-dropdown [data-selectable] .highlight { + background: rgba(52, 152, 219, 0.2); +} + +body .selectize-dropdown .active { + background-color: #d8d8d8; +} + +.selectize-control.plugin-drag_drop.multi + > .selectize-input + > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #ffffff; + box-shadow: inset 0 0 12px 4px #ffffff; +} + +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: "!"; + visibility: hidden; +} + +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} + +.selectize-dropdown-header { + position: relative; + padding: 3px 12px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.selectize-dropdown-header-close { + position: absolute; + right: 12px; + top: 50%; + color: #333333; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} + +.selectize-dropdown-header-close:hover { + color: #000000; +} + +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} + +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} + +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} + +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} + +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 1px 0 0 0; + border-left: 1px solid transparent; + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} + +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: transparent; +} + +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} + +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: rgba(77, 77, 77, 0); +} + +.selectize-control { + position: relative; +} + +.selectize-dropdown, +.selectize-input, +.selectize-input input { + color: #333333; + font-family: inherit; + font-size: inherit; + line-height: 20px; + -webkit-font-smoothing: inherit; +} + +.selectize-input, +.selectize-control.single .selectize-input.input-active { + background: #ffffff; + cursor: text; + display: inline-block; +} + +.selectize-input { + border: 1px solid #cccccc; + padding: 6px 12px; + display: inline-block; + width: 100%; + overflow: hidden; + position: relative; + z-index: 1; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.selectize-control.multi .selectize-input.has-items { + padding: 5px 12px 2px; +} + +.selectize-input.full { + background-color: #ffffff; +} + +.selectize-input.disabled, +.selectize-input.disabled * { + cursor: default !important; +} + +.selectize-input.focus { + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); +} + +.selectize-input.dropdown-active { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.selectize-input > * { + vertical-align: baseline; + display: -moz-inline-stack; + display: inline-block; + zoom: 1; + *display: inline; +} + +.selectize-control.multi .selectize-input > div { + cursor: pointer; + margin: 0 3px 3px 0; + padding: 1px 3px; + background: #efefef; + color: #333333; + border: 0 solid transparent; +} + +.selectize-control.multi .selectize-input > div.active { + background: #428bca; + color: #ffffff; + border: 0 solid transparent; +} + +.selectize-control.multi .selectize-input.disabled > div, +.selectize-control.multi .selectize-input.disabled > div.active { + color: #808080; + background: #ffffff; + border: 0 solid rgba(77, 77, 77, 0); +} + +.selectize-input > input { + display: inline-block !important; + padding: 0 !important; + min-height: 0 !important; + max-height: none !important; + max-width: 100% !important; + margin: 0 !important; + text-indent: 0 !important; + border: 0 none !important; + background: none !important; + line-height: inherit !important; + -webkit-user-select: auto !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +.selectize-input > input::-ms-clear { + display: none; +} + +.selectize-input > input:focus { + outline: none !important; +} + +.selectize-input::after { + content: " "; + display: block; + clear: left; +} + +.selectize-input.dropdown-active::before { + content: " "; + display: block; + position: absolute; + background: #ffffff; + height: 1px; + bottom: 0; + left: 0; + right: 0; +} + +.selectize-dropdown { + position: absolute; + z-index: 10; + border: 1px solid #d0d0d0; + background: #ffffff; + margin: -1px 0 0 0; + border-top: 0 none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.selectize-dropdown [data-selectable] { + cursor: pointer; + overflow: hidden; +} + +.selectize-dropdown [data-selectable] .highlight { + background: rgba(255, 237, 40, 0.4); + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; +} + +.selectize-dropdown [data-selectable], +.selectize-dropdown .optgroup-header { + padding: 3px 12px; +} + +.selectize-dropdown .optgroup:first-child .optgroup-header { + border-top: 0 none; +} + +.selectize-dropdown .optgroup-header { + color: #777777; + background: #ffffff; + cursor: default; +} + +.selectize-dropdown .active { + background-color: #f5f5f5; + color: #262626; +} + +.selectize-dropdown .active.create { + color: #262626; +} + +.selectize-dropdown .create { + color: rgba(51, 51, 51, 0.5); +} + +.selectize-dropdown-content { + overflow-y: auto; + overflow-x: hidden; + max-height: 200px; +} + +.selectize-control.single .selectize-input, +.selectize-control.single .selectize-input input { + cursor: pointer; +} + +.selectize-control.single .selectize-input.input-active, +.selectize-control.single .selectize-input.input-active input { + cursor: text; +} + +.selectize-control.single .selectize-input:after { + content: " "; + display: block; + position: absolute; + top: 50%; + right: 17px; + margin-top: -3px; + width: 0; + height: 0; + border-style: solid; + border-width: 5px 5px 0 5px; + border-color: #333333 transparent transparent transparent; +} + +.selectize-control.single .selectize-input.dropdown-active:after { + margin-top: -4px; + border-width: 0 5px 5px 5px; + border-color: transparent transparent #333333 transparent; +} + +.selectize-control.rtl.single .selectize-input:after { + left: 17px; + right: auto; +} + +.selectize-control.rtl .selectize-input > input { + margin: 0 4px 0 -2px !important; +} + +.selectize-control .selectize-input.disabled { + opacity: 0.5; + background-color: #ffffff; +} + +.selectize-dropdown, +.selectize-dropdown.form-control { + height: auto; + padding: 0; + margin: 2px 0 0 0; + z-index: 1000; + background: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); +} + +.selectize-dropdown .optgroup-header { + font-size: 12px; + line-height: 1.42857143; +} + +.selectize-dropdown .optgroup:first-child:before { + display: none; +} + +.selectize-dropdown .optgroup:before { + content: " "; + display: block; + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; + margin-left: -12px; + margin-right: -12px; +} + +.selectize-dropdown-content { + padding: 5px 0; +} + +.selectize-dropdown-header { + padding: 6px 12px; +} + +.selectize-input { + min-height: 34px; +} + +.selectize-input.dropdown-active { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.selectize-input.dropdown-active::before { + display: none; +} + +.selectize-input.focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(102, 175, 233, 0.6); +} + +.has-error .selectize-input { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.has-error .selectize-input:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; +} + +.selectize-control.multi .selectize-input.has-items { + padding-left: 9px; + padding-right: 9px; +} + +.selectize-control.multi .selectize-input > div { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.form-control.selectize-control { + padding: 0; + height: auto; + border: none; + background: none; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.slick-slider { + position: relative; + display: block; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -ms-touch-action: pan-y; + touch-action: pan-y; + -webkit-tap-highlight-color: transparent; +} + +.slick-list { + position: relative; + overflow: hidden; + display: block; + margin: 0; + padding: 0; +} + +.slick-list:focus { + outline: none; +} + +.slick-loading .slick-list { + background: #fff url(/assets/ajax-loader-ee7ed79371d6a288e40fad18ff68ffb0.gif) + center center no-repeat; +} + +.slick-list.dragging { + cursor: pointer; + cursor: hand; +} + +.slick-slider .slick-track { + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} + +.slick-track { + position: relative; + left: 0; + top: 0; + display: block; +} + +.slick-track:before, +.slick-track:after { + content: ""; + display: table; +} + +.slick-track:after { + clear: both; +} + +.slick-loading .slick-track { + visibility: hidden; +} + +.slick-slide { + float: left; + height: 100%; + min-height: 1px; + display: none; +} + +[dir="rtl"] .slick-slide { + float: right; +} + +.slick-slide img { + display: block; +} + +.slick-slide.slick-loading img { + display: none; +} + +.slick-slide.dragging img { + pointer-events: none; +} + +.slick-initialized .slick-slide { + display: block; +} + +.slick-loading .slick-slide { + visibility: hidden; +} + +.slick-vertical .slick-slide { + display: block; + height: auto; + border: 1px solid transparent; +} + +.slick-prev, +.slick-next { + position: absolute; + display: block; + height: 40px; + width: 20px; + line-height: 0; + font-size: 0; + cursor: pointer; + background: transparent; + color: transparent; + top: 50%; + margin-top: -20px; + padding: 0; + border: none; + outline: none; +} + +.slick-prev:hover, +.slick-prev:focus, +.slick-next:hover, +.slick-next:focus { + outline: none; + background: transparent; + color: transparent; +} + +.slick-prev:hover:before, +.slick-prev:focus:before, +.slick-next:hover:before, +.slick-next:focus:before { + opacity: 1; +} + +.slick-prev.slick-disabled, +.slick-next.slick-disabled { + opacity: 0; +} + +.slick-prev:before, +.slick-next:before { + font-family: "Courier"; + font-size: 40px; + line-height: 1; + color: #fff; + opacity: 0.75; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.slick-prev { + left: -25px; +} + +[dir="rtl"] .slick-prev { + left: auto; + right: -25px; +} + +.slick-prev:before { + content: "("; +} + +[dir="rtl"] .slick-prev:before { + content: ")"; +} + +.slick-next { + right: -25px; +} + +[dir="rtl"] .slick-next { + left: -25px; + right: auto; +} + +.slick-next:before { + content: ")"; +} + +[dir="rtl"] .slick-next:before { + content: "("; +} + +.slick-slider { + margin-bottom: 30px; +} + +.slick-dots { + position: absolute; + bottom: -45px; + list-style: none; + display: block; + text-align: center; + padding: 0; + width: 100%; +} + +.slick-dots li { + position: relative; + display: inline-block; + height: 20px; + width: 20px; + margin: 0 5px; + padding: 0; + cursor: pointer; +} + +.slick-dots li button { + border: 0; + background: transparent; + display: block; + height: 20px; + width: 20px; + outline: none; + line-height: 0; + font-size: 0; + color: transparent; + padding: 5px; + cursor: pointer; +} + +.slick-dots li button:hover, +.slick-dots li button:focus { + outline: none; +} + +.slick-dots li button:hover:before, +.slick-dots li button:focus:before { + opacity: 1; +} + +.slick-dots li button:before { + position: absolute; + top: 0; + left: 0; + content: "•"; + width: 20px; + height: 20px; + font-family: "Courier"; + font-size: 6px; + line-height: 20px; + text-align: center; + color: #000; + opacity: 0.25; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.slick-dots li.slick-active button:before { + color: #000; + opacity: 0.75; +} + +@media (min-width: 899px) { + .slick-prev, + .slick-next { + display: none; + } +} + +img[data-action="zoom"] { + cursor: zoom-in; + cursor: -webkit-zoom-in; + cursor: -moz-zoom-in; +} + +.zoom-img, +.zoom-img-wrap { + position: relative; + z-index: 666; + -webkit-transition: all 300ms; + -o-transition: all 300ms; + transition: all 300ms; +} + +img.zoom-img { + cursor: zoom-out; + cursor: -webkit-zoom-out; + cursor: -moz-zoom-out; +} + +.zoom-overlay { + z-index: 420; + background: #2c3e50; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; + filter: "alpha(opacity=0)"; + opacity: 0; + -webkit-transition: opacity 300ms; + -o-transition: opacity 300ms; + transition: opacity 300ms; +} + +.zoom-overlay-open .zoom-overlay { + filter: "alpha(opacity=80)"; + opacity: 0.8; +} + +.zoom-overlay-open, +.zoom-overlay-transitioning { + cursor: default; +} + +.bcontainer { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} + +.bcontainer:before, +.bcontainer:after { + content: " "; + display: table; +} + +.bcontainer:after { + clear: both; +} + +@media (min-width: 768px) { + .bcontainer { + width: 750px; + } +} + +@media (min-width: 992px) { + .bcontainer { + width: 970px; + } +} + +@media (min-width: 1200px) { + .bcontainer { + width: 1230px; + } +} + +.bcontainer-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} + +.bcontainer-fluid:before, +.bcontainer-fluid:after { + content: " "; + display: table; +} + +.bcontainer-fluid:after { + clear: both; +} + +.row { + margin-left: -15px; + margin-right: -15px; +} + +.row:before, +.row:after { + content: " "; + display: table; +} + +.row:after { + clear: both; +} + +.col-xs-1, +.col-sm-1, +.col-md-1, +.col-lg-1, +.col-xs-2, +.col-sm-2, +.col-md-2, +.col-lg-2, +.col-xs-3, +.col-sm-3, +.col-md-3, +.col-lg-3, +.col-xs-4, +.col-sm-4, +.col-md-4, +.col-lg-4, +.col-xs-5, +.col-sm-5, +.col-md-5, +.col-lg-5, +.col-xs-6, +.col-sm-6, +.col-md-6, +.col-lg-6, +.col-xs-7, +.col-sm-7, +.col-md-7, +.col-lg-7, +.col-xs-8, +.col-sm-8, +.col-md-8, +.col-lg-8, +.col-xs-9, +.col-sm-9, +.col-md-9, +.col-lg-9, +.col-xs-10, +.col-sm-10, +.col-md-10, +.col-lg-10, +.col-xs-11, +.col-sm-11, +.col-md-11, +.col-lg-11, +.col-xs-12, +.col-sm-12, +.col-md-12, +.col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} + +.col-xs-1, +.col-xs-2, +.col-xs-3, +.col-xs-4, +.col-xs-5, +.col-xs-6, +.col-xs-7, +.col-xs-8, +.col-xs-9, +.col-xs-10, +.col-xs-11, +.col-xs-12 { + float: left; +} + +.col-xs-1 { + width: 8.33333%; +} + +.col-xs-2 { + width: 16.66667%; +} + +.col-xs-3 { + width: 25%; +} + +.col-xs-4 { + width: 33.33333%; +} + +.col-xs-5 { + width: 41.66667%; +} + +.col-xs-6 { + width: 50%; +} + +.col-xs-7 { + width: 58.33333%; +} + +.col-xs-8 { + width: 66.66667%; +} + +.col-xs-9 { + width: 75%; +} + +.col-xs-10 { + width: 83.33333%; +} + +.col-xs-11 { + width: 91.66667%; +} + +.col-xs-12 { + width: 100%; +} + +.col-xs-pull-0 { + right: auto; +} + +.col-xs-pull-1 { + right: 8.33333%; +} + +.col-xs-pull-2 { + right: 16.66667%; +} + +.col-xs-pull-3 { + right: 25%; +} + +.col-xs-pull-4 { + right: 33.33333%; +} + +.col-xs-pull-5 { + right: 41.66667%; +} + +.col-xs-pull-6 { + right: 50%; +} + +.col-xs-pull-7 { + right: 58.33333%; +} + +.col-xs-pull-8 { + right: 66.66667%; +} + +.col-xs-pull-9 { + right: 75%; +} + +.col-xs-pull-10 { + right: 83.33333%; +} + +.col-xs-pull-11 { + right: 91.66667%; +} + +.col-xs-pull-12 { + right: 100%; +} + +.col-xs-push-0 { + left: auto; +} + +.col-xs-push-1 { + left: 8.33333%; +} + +.col-xs-push-2 { + left: 16.66667%; +} + +.col-xs-push-3 { + left: 25%; +} + +.col-xs-push-4 { + left: 33.33333%; +} + +.col-xs-push-5 { + left: 41.66667%; +} + +.col-xs-push-6 { + left: 50%; +} + +.col-xs-push-7 { + left: 58.33333%; +} + +.col-xs-push-8 { + left: 66.66667%; +} + +.col-xs-push-9 { + left: 75%; +} + +.col-xs-push-10 { + left: 83.33333%; +} + +.col-xs-push-11 { + left: 91.66667%; +} + +.col-xs-push-12 { + left: 100%; +} + +.col-xs-offset-0 { + margin-left: 0%; +} + +.col-xs-offset-1 { + margin-left: 8.33333%; +} + +.col-xs-offset-2 { + margin-left: 16.66667%; +} + +.col-xs-offset-3 { + margin-left: 25%; +} + +.col-xs-offset-4 { + margin-left: 33.33333%; +} + +.col-xs-offset-5 { + margin-left: 41.66667%; +} + +.col-xs-offset-6 { + margin-left: 50%; +} + +.col-xs-offset-7 { + margin-left: 58.33333%; +} + +.col-xs-offset-8 { + margin-left: 66.66667%; +} + +.col-xs-offset-9 { + margin-left: 75%; +} + +.col-xs-offset-10 { + margin-left: 83.33333%; +} + +.col-xs-offset-11 { + margin-left: 91.66667%; +} + +.col-xs-offset-12 { + margin-left: 100%; +} + +@media (min-width: 768px) { + .col-sm-1, + .col-sm-2, + .col-sm-3, + .col-sm-4, + .col-sm-5, + .col-sm-6, + .col-sm-7, + .col-sm-8, + .col-sm-9, + .col-sm-10, + .col-sm-11, + .col-sm-12 { + float: left; + } + + .col-sm-1 { + width: 8.33333%; + } + + .col-sm-2 { + width: 16.66667%; + } + + .col-sm-3 { + width: 25%; + } + + .col-sm-4 { + width: 33.33333%; + } + + .col-sm-5 { + width: 41.66667%; + } + + .col-sm-6 { + width: 50%; + } + + .col-sm-7 { + width: 58.33333%; + } + + .col-sm-8 { + width: 66.66667%; + } + + .col-sm-9 { + width: 75%; + } + + .col-sm-10 { + width: 83.33333%; + } + + .col-sm-11 { + width: 91.66667%; + } + + .col-sm-12 { + width: 100%; + } + + .col-sm-pull-0 { + right: auto; + } + + .col-sm-pull-1 { + right: 8.33333%; + } + + .col-sm-pull-2 { + right: 16.66667%; + } + + .col-sm-pull-3 { + right: 25%; + } + + .col-sm-pull-4 { + right: 33.33333%; + } + + .col-sm-pull-5 { + right: 41.66667%; + } + + .col-sm-pull-6 { + right: 50%; + } + + .col-sm-pull-7 { + right: 58.33333%; + } + + .col-sm-pull-8 { + right: 66.66667%; + } + + .col-sm-pull-9 { + right: 75%; + } + + .col-sm-pull-10 { + right: 83.33333%; + } + + .col-sm-pull-11 { + right: 91.66667%; + } + + .col-sm-pull-12 { + right: 100%; + } + + .col-sm-push-0 { + left: auto; + } + + .col-sm-push-1 { + left: 8.33333%; + } + + .col-sm-push-2 { + left: 16.66667%; + } + + .col-sm-push-3 { + left: 25%; + } + + .col-sm-push-4 { + left: 33.33333%; + } + + .col-sm-push-5 { + left: 41.66667%; + } + + .col-sm-push-6 { + left: 50%; + } + + .col-sm-push-7 { + left: 58.33333%; + } + + .col-sm-push-8 { + left: 66.66667%; + } + + .col-sm-push-9 { + left: 75%; + } + + .col-sm-push-10 { + left: 83.33333%; + } + + .col-sm-push-11 { + left: 91.66667%; + } + + .col-sm-push-12 { + left: 100%; + } + + .col-sm-offset-0 { + margin-left: 0%; + } + + .col-sm-offset-1 { + margin-left: 8.33333%; + } + + .col-sm-offset-2 { + margin-left: 16.66667%; + } + + .col-sm-offset-3 { + margin-left: 25%; + } + + .col-sm-offset-4 { + margin-left: 33.33333%; + } + + .col-sm-offset-5 { + margin-left: 41.66667%; + } + + .col-sm-offset-6 { + margin-left: 50%; + } + + .col-sm-offset-7 { + margin-left: 58.33333%; + } + + .col-sm-offset-8 { + margin-left: 66.66667%; + } + + .col-sm-offset-9 { + margin-left: 75%; + } + + .col-sm-offset-10 { + margin-left: 83.33333%; + } + + .col-sm-offset-11 { + margin-left: 91.66667%; + } + + .col-sm-offset-12 { + margin-left: 100%; + } +} + +@media (min-width: 992px) { + .col-md-1, + .col-md-2, + .col-md-3, + .col-md-4, + .col-md-5, + .col-md-6, + .col-md-7, + .col-md-8, + .col-md-9, + .col-md-10, + .col-md-11, + .col-md-12 { + float: left; + } + + .col-md-1 { + width: 8.33333%; + } + + .col-md-2 { + width: 16.66667%; + } + + .col-md-3 { + width: 25%; + } + + .col-md-4 { + width: 33.33333%; + } + + .col-md-5 { + width: 41.66667%; + } + + .col-md-6 { + width: 50%; + } + + .col-md-7 { + width: 58.33333%; + } + + .col-md-8 { + width: 66.66667%; + } + + .col-md-9 { + width: 75%; + } + + .col-md-10 { + width: 83.33333%; + } + + .col-md-11 { + width: 91.66667%; + } + + .col-md-12 { + width: 100%; + } + + .col-md-pull-0 { + right: auto; + } + + .col-md-pull-1 { + right: 8.33333%; + } + + .col-md-pull-2 { + right: 16.66667%; + } + + .col-md-pull-3 { + right: 25%; + } + + .col-md-pull-4 { + right: 33.33333%; + } + + .col-md-pull-5 { + right: 41.66667%; + } + + .col-md-pull-6 { + right: 50%; + } + + .col-md-pull-7 { + right: 58.33333%; + } + + .col-md-pull-8 { + right: 66.66667%; + } + + .col-md-pull-9 { + right: 75%; + } + + .col-md-pull-10 { + right: 83.33333%; + } + + .col-md-pull-11 { + right: 91.66667%; + } + + .col-md-pull-12 { + right: 100%; + } + + .col-md-push-0 { + left: auto; + } + + .col-md-push-1 { + left: 8.33333%; + } + + .col-md-push-2 { + left: 16.66667%; + } + + .col-md-push-3 { + left: 25%; + } + + .col-md-push-4 { + left: 33.33333%; + } + + .col-md-push-5 { + left: 41.66667%; + } + + .col-md-push-6 { + left: 50%; + } + + .col-md-push-7 { + left: 58.33333%; + } + + .col-md-push-8 { + left: 66.66667%; + } + + .col-md-push-9 { + left: 75%; + } + + .col-md-push-10 { + left: 83.33333%; + } + + .col-md-push-11 { + left: 91.66667%; + } + + .col-md-push-12 { + left: 100%; + } + + .col-md-offset-0 { + margin-left: 0%; + } + + .col-md-offset-1 { + margin-left: 8.33333%; + } + + .col-md-offset-2 { + margin-left: 16.66667%; + } + + .col-md-offset-3 { + margin-left: 25%; + } + + .col-md-offset-4 { + margin-left: 33.33333%; + } + + .col-md-offset-5 { + margin-left: 41.66667%; + } + + .col-md-offset-6 { + margin-left: 50%; + } + + .col-md-offset-7 { + margin-left: 58.33333%; + } + + .col-md-offset-8 { + margin-left: 66.66667%; + } + + .col-md-offset-9 { + margin-left: 75%; + } + + .col-md-offset-10 { + margin-left: 83.33333%; + } + + .col-md-offset-11 { + margin-left: 91.66667%; + } + + .col-md-offset-12 { + margin-left: 100%; + } +} + +@media (min-width: 1200px) { + .col-lg-1, + .col-lg-2, + .col-lg-3, + .col-lg-4, + .col-lg-5, + .col-lg-6, + .col-lg-7, + .col-lg-8, + .col-lg-9, + .col-lg-10, + .col-lg-11, + .col-lg-12 { + float: left; + } + + .col-lg-1 { + width: 8.33333%; + } + + .col-lg-2 { + width: 16.66667%; + } + + .col-lg-3 { + width: 25%; + } + + .col-lg-4 { + width: 33.33333%; + } + + .col-lg-5 { + width: 41.66667%; + } + + .col-lg-6 { + width: 50%; + } + + .col-lg-7 { + width: 58.33333%; + } + + .col-lg-8 { + width: 66.66667%; + } + + .col-lg-9 { + width: 75%; + } + + .col-lg-10 { + width: 83.33333%; + } + + .col-lg-11 { + width: 91.66667%; + } + + .col-lg-12 { + width: 100%; + } + + .col-lg-pull-0 { + right: auto; + } + + .col-lg-pull-1 { + right: 8.33333%; + } + + .col-lg-pull-2 { + right: 16.66667%; + } + + .col-lg-pull-3 { + right: 25%; + } + + .col-lg-pull-4 { + right: 33.33333%; + } + + .col-lg-pull-5 { + right: 41.66667%; + } + + .col-lg-pull-6 { + right: 50%; + } + + .col-lg-pull-7 { + right: 58.33333%; + } + + .col-lg-pull-8 { + right: 66.66667%; + } + + .col-lg-pull-9 { + right: 75%; + } + + .col-lg-pull-10 { + right: 83.33333%; + } + + .col-lg-pull-11 { + right: 91.66667%; + } + + .col-lg-pull-12 { + right: 100%; + } + + .col-lg-push-0 { + left: auto; + } + + .col-lg-push-1 { + left: 8.33333%; + } + + .col-lg-push-2 { + left: 16.66667%; + } + + .col-lg-push-3 { + left: 25%; + } + + .col-lg-push-4 { + left: 33.33333%; + } + + .col-lg-push-5 { + left: 41.66667%; + } + + .col-lg-push-6 { + left: 50%; + } + + .col-lg-push-7 { + left: 58.33333%; + } + + .col-lg-push-8 { + left: 66.66667%; + } + + .col-lg-push-9 { + left: 75%; + } + + .col-lg-push-10 { + left: 83.33333%; + } + + .col-lg-push-11 { + left: 91.66667%; + } + + .col-lg-push-12 { + left: 100%; + } + + .col-lg-offset-0 { + margin-left: 0%; + } + + .col-lg-offset-1 { + margin-left: 8.33333%; + } + + .col-lg-offset-2 { + margin-left: 16.66667%; + } + + .col-lg-offset-3 { + margin-left: 25%; + } + + .col-lg-offset-4 { + margin-left: 33.33333%; + } + + .col-lg-offset-5 { + margin-left: 41.66667%; + } + + .col-lg-offset-6 { + margin-left: 50%; + } + + .col-lg-offset-7 { + margin-left: 58.33333%; + } + + .col-lg-offset-8 { + margin-left: 66.66667%; + } + + .col-lg-offset-9 { + margin-left: 75%; + } + + .col-lg-offset-10 { + margin-left: 83.33333%; + } + + .col-lg-offset-11 { + margin-left: 91.66667%; + } + + .col-lg-offset-12 { + margin-left: 100%; + } +} + +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} + +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} + +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +kbd kbd { + padding: 0; + font-size: 100%; + box-shadow: none; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857; + word-break: break-all; + word-wrap: break-word; + color: #333; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} + +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.stolen-color { + color: #c0392b; +} + +.safe-color { + color: #2ecc71; +} + +#alert-block { + z-index: 99999; + position: fixed; + top: 100px; + left: 0; + width: 100%; + margin: 0 auto; +} + +#alert-block .alert { + -webkit-box-shadow: (-2px) 2px 4px rgba(0, 0, 0, 0.2); + box-shadow: (-2px) 2px 4px rgba(0, 0, 0, 0.2); + -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color='#000000')"; + z-index: 99999; + position: absolute; + right: 0; + top: 20px; + opacity: 0.95; +} + +@media (min-width: 899px) { + #alert-block .alert { + width: 380px; + margin: 0 50px 0 0; + } +} + +@media (max-width: 599px) { + #alert-block .alert { + width: 90%; + margin: 0; + right: 5%; + } +} + +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} + +.alert h4 { + margin-top: 0; + color: inherit; +} + +.alert .alert-link { + font-weight: bold; +} + +.alert > p, +.alert > ul { + margin-bottom: 0; +} + +.alert > p + p { + margin-top: 5px; +} + +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} + +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} + +.alert-success, +.alert-notice { + background-color: #dff0d8; + border-color: #d6e9c6; + color: #3c763d; +} + +.alert-success hr, +.alert-notice hr { + border-top-color: #c9e2b3; +} + +.alert-success .alert-link, +.alert-notice .alert-link { + color: #2b542c; +} + +.alert-info { + background-color: #d9edf7; + border-color: #bce8f1; + color: #31708f; +} + +.alert-info hr { + border-top-color: #a6e1ec; +} + +.alert-info .alert-link { + color: #245269; +} + +.alert-warning { + background-color: #fcf8e3; + border-color: #faebcc; + color: #8a6d3b; +} + +.alert-warning hr { + border-top-color: #f7e1b5; +} + +.alert-warning .alert-link { + color: #66512c; +} + +.alert-danger, +.alert-error { + background-color: #f2dede; + border-color: #ebccd1; + color: #a94442; +} + +.alert-danger hr, +.alert-error hr { + border-top-color: #e4b9c0; +} + +.alert-danger .alert-link, +.alert-error .alert-link { + color: #843534; +} + +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 300; + src: local("Open Sans Light"), local("OpenSans-Light"), + url(https://themes.googleusercontent.com/static/fonts/opensans/v8/DXI1ORHCpsQm3Vp6mXoaTaRDOzjiPcYnFooOUGCOsRk.woff) + format("woff"); +} + +@font-face { + font-family: "Open Sans"; + font-style: italic; + font-weight: 300; + src: local("Open Sans Light Italic"), local("OpenSansLight-Italic"), + url(https://themes.googleusercontent.com/static/fonts/opensans/v8/PRmiXeptR36kaC0GEAetxvR_54zmj3SbGZQh3vCOwvY.woff) + format("woff"); +} + +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: bold; + src: local("Open Sans"), local("OpenSans"), + url(https://themes.googleusercontent.com/static/fonts/opensans/v8/cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff) + format("woff"); +} + +@font-face { + font-family: "Klinic"; + src: url("/assets/KlinicSlabBook.otf"); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: "Klinic"; + src: url("/assets/KlinicSlabBookIt.otf"); + font-weight: normal; + font-style: italic; +} + +@font-face { + font-family: "Klinic"; + src: url("/assets/KlinicSlabMedium.otf"); + font-weight: bold; + font-style: normal; +} + +h1 { + font-size: 40px; +} + +@media (max-width: 899px) { + h1 { + font-size: 30px; + } +} + +@media (max-width: 599px) { + h1 { + font-size: 23px; + } +} + +h3 { + font-size: 22px; +} + +@media (max-width: 599px) { + h3 { + font-size: 20px; + } +} + +h4 { + font-size: 20px; +} + +@media (max-width: 599px) { + h4 { + font-size: 18px; + } +} + +header.with-subtitle { + padding-bottom: 20px; + padding-top: 20px; +} + +header.with-subtitle:before, +header.with-subtitle:after { + content: " "; + display: table; +} + +header.with-subtitle:after { + clear: both; +} + +@media (max-width: 599px) { + header.with-subtitle { + padding-bottom: 10px; + } +} + +header.with-subtitle h1, +header.with-subtitle h2, +header.with-subtitle h3, +header.with-subtitle h4 { + margin: 0; +} + +header.with-subtitle p { + display: inline-block; + float: right; + margin-top: 0; + padding-top: 0; + margin-left: 0.25em; +} + +@media (min-width: 899px) { + header.with-subtitle h1, + header.with-subtitle h2, + header.with-subtitle h3, + header.with-subtitle h4 { + float: left; + max-width: 74.5%; + } + + header.with-subtitle p { + max-width: 23.5%; + padding-top: 10px; + } +} + +@media (min-width: 1199px) { + header.with-subtitle h1, + header.with-subtitle h2, + header.with-subtitle h3, + header.with-subtitle h4 { + max-width: 83%; + } + + header.with-subtitle p { + max-width: 15%; + } +} + +.btn, +.swagger-section input.submit { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.btn:focus, +.swagger-section input.submit:focus, +.btn:active:focus, +.swagger-section input.submit:active:focus, +.btn.active:focus, +.swagger-section input.active.submit:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn:hover, +.swagger-section input.submit:hover, +.btn:focus, +.swagger-section input.submit:focus { + color: #333; + text-decoration: none; +} + +.btn:active, +.swagger-section input.submit:active, +.btn.active, +.swagger-section input.active.submit { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 3px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 3px rgba(0, 0, 0, 0.125); +} + +.btn.disabled, +.swagger-section input.disabled.submit, +.btn[disabled], +.swagger-section input[disabled].submit, +fieldset[disabled] .btn, +fieldset[disabled] .swagger-section input.submit, +.swagger-section fieldset[disabled] input.submit { + cursor: not-allowed; + pointer-events: none; + opacity: 0.65; + filter: alpha(opacity = 65); + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} + +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open > .btn-default.dropdown-toggle { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +.btn-default:active, +.btn-default.active, +.open > .btn-default.dropdown-toggle { + background-image: none; +} + +.btn-default.disabled, +.btn-default.disabled:hover, +.btn-default.disabled:focus, +.btn-default.disabled:active, +.btn-default.disabled.active, +.btn-default[disabled], +.btn-default[disabled]:hover, +.btn-default[disabled]:focus, +.btn-default[disabled]:active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default, +fieldset[disabled] .btn-default:hover, +fieldset[disabled] .btn-default:focus, +fieldset[disabled] .btn-default:active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} + +.btn-default .badge { + color: #fff; + background-color: #333; +} + +.btn-primary { + color: #fff; + background-color: #428bca; + border-color: #357ebd; +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #3071a9; + border-color: #285e8e; +} + +.btn-primary:active, +.btn-primary.active, +.open > .btn-primary.dropdown-toggle { + background-image: none; +} + +.btn-primary.disabled, +.btn-primary.disabled:hover, +.btn-primary.disabled:focus, +.btn-primary.disabled:active, +.btn-primary.disabled.active, +.btn-primary[disabled], +.btn-primary[disabled]:hover, +.btn-primary[disabled]:focus, +.btn-primary[disabled]:active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary, +fieldset[disabled] .btn-primary:hover, +fieldset[disabled] .btn-primary:focus, +fieldset[disabled] .btn-primary:active, +fieldset[disabled] .btn-primary.active { + background-color: #428bca; + border-color: #357ebd; +} + +.btn-primary .badge { + color: #428bca; + background-color: #fff; +} + +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open > .btn-success.dropdown-toggle { + color: #fff; + background-color: #449d44; + border-color: #398439; +} + +.btn-success:active, +.btn-success.active, +.open > .btn-success.dropdown-toggle { + background-image: none; +} + +.btn-success.disabled, +.btn-success.disabled:hover, +.btn-success.disabled:focus, +.btn-success.disabled:active, +.btn-success.disabled.active, +.btn-success[disabled], +.btn-success[disabled]:hover, +.btn-success[disabled]:focus, +.btn-success[disabled]:active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success, +fieldset[disabled] .btn-success:hover, +fieldset[disabled] .btn-success:focus, +fieldset[disabled] .btn-success:active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} + +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} + +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open > .btn-info.dropdown-toggle { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} + +.btn-info:active, +.btn-info.active, +.open > .btn-info.dropdown-toggle { + background-image: none; +} + +.btn-info.disabled, +.btn-info.disabled:hover, +.btn-info.disabled:focus, +.btn-info.disabled:active, +.btn-info.disabled.active, +.btn-info[disabled], +.btn-info[disabled]:hover, +.btn-info[disabled]:focus, +.btn-info[disabled]:active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info, +fieldset[disabled] .btn-info:hover, +fieldset[disabled] .btn-info:focus, +fieldset[disabled] .btn-info:active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} + +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} + +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open > .btn-warning.dropdown-toggle { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} + +.btn-warning:active, +.btn-warning.active, +.open > .btn-warning.dropdown-toggle { + background-image: none; +} + +.btn-warning.disabled, +.btn-warning.disabled:hover, +.btn-warning.disabled:focus, +.btn-warning.disabled:active, +.btn-warning.disabled.active, +.btn-warning[disabled], +.btn-warning[disabled]:hover, +.btn-warning[disabled]:focus, +.btn-warning[disabled]:active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning, +fieldset[disabled] .btn-warning:hover, +fieldset[disabled] .btn-warning:focus, +fieldset[disabled] .btn-warning:active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} + +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} + +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} + +.btn-danger:active, +.btn-danger.active, +.open > .btn-danger.dropdown-toggle { + background-image: none; +} + +.btn-danger.disabled, +.btn-danger.disabled:hover, +.btn-danger.disabled:focus, +.btn-danger.disabled:active, +.btn-danger.disabled.active, +.btn-danger[disabled], +.btn-danger[disabled]:hover, +.btn-danger[disabled]:focus, +.btn-danger[disabled]:active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger, +fieldset[disabled] .btn-danger:hover, +fieldset[disabled] .btn-danger:focus, +fieldset[disabled] .btn-danger:active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} + +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} + +.btn-link { + color: #3498db; + font-weight: normal; + cursor: pointer; + border-radius: 0; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} + +.btn-link:hover, +.btn-link:focus { + color: #2a6496; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:hover, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} + +.btn-lg { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +.btn-sm { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.binxbtn-lg, +.btn.binxbtn.binxbtn-lg, +.swagger-section input.binxbtn-lg.submit, +.btn.binxbtn-primary.binxbtn-lg, +.btn.binxbtn-default.binxbtn-lg, +.btn.binxbtn-danger.binxbtn-lg { + padding: 0.25em 1em; + font-size: 20px; +} + +.btn.binxbtn, +.swagger-section input.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + border: none; + background: #2ecc71; + color: #fff; + padding: 0.5em 1em; + font-weight: 400; + box-shadow: -0.01em 0.01em 0px #27ae60, -0.006em 0.006em 0 #27ae60, + -0.012em 0.012em 0 #27ae60, -0.018em 0.018em 0 #27ae60, + -0.024em 0.024em 0 #27ae60, -0.03em 0.03em 0 #27ae60, + -0.036em 0.036em 0 #27ae60, -0.042em 0.042em 0 #27ae60, + -0.048em 0.048em 0 #27ae60, -0.054em 0.054em 0 #27ae60, + -0.06em 0.06em 0 #27ae60, -0.066em 0.066em 0 #27ae60, + -0.072em 0.072em 0 #27ae60, -0.078em 0.078em 0 #27ae60, + -0.084em 0.084em 0 #27ae60, -0.09em 0.09em 0 #27ae60; + font-size: 16px; + font-family: "Open Sans", sans-serif; +} + +.btn.binxbtn:hover, +.swagger-section input.submit:hover, +.btn.binxbtn:focus, +.swagger-section input.submit:focus, +.btn.binxbtn:active, +.swagger-section input.submit:active, +.btn.binxbtn.active, +.swagger-section input.active.submit, +.open > .btn.binxbtn.dropdown-toggle, +.swagger-section .open > input.dropdown-toggle.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + background: #62d994; + color: #fff; +} + +.btn.binxbtn:active, +.swagger-section input.submit:active { + background: #2ecc71; +} + +.btn.binxbtn-primary, +.swagger-section input.binxbtn-primary.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + border: none; + background: #3498db; + color: #fff; + padding: 0.5em 1em; + font-weight: 400; + box-shadow: -0.01em 0.01em 0px #2574a0, -0.006em 0.006em 0 #2574a0, + -0.012em 0.012em 0 #2574a0, -0.018em 0.018em 0 #2574a0, + -0.024em 0.024em 0 #2574a0, -0.03em 0.03em 0 #2574a0, + -0.036em 0.036em 0 #2574a0, -0.042em 0.042em 0 #2574a0, + -0.048em 0.048em 0 #2574a0, -0.054em 0.054em 0 #2574a0, + -0.06em 0.06em 0 #2574a0, -0.066em 0.066em 0 #2574a0, + -0.072em 0.072em 0 #2574a0, -0.078em 0.078em 0 #2574a0, + -0.084em 0.084em 0 #2574a0, -0.09em 0.09em 0 #2574a0; + font-size: 16px; + font-family: "Open Sans", sans-serif; +} + +.btn.binxbtn-primary:hover, +.swagger-section input.binxbtn-primary.submit:hover, +.btn.binxbtn-primary:focus, +.swagger-section input.binxbtn-primary.submit:focus, +.btn.binxbtn-primary:active, +.swagger-section input.binxbtn-primary.submit:active, +.btn.binxbtn-primary.active, +.swagger-section input.binxbtn-primary.active.submit, +.open > .btn.binxbtn-primary.dropdown-toggle, +.swagger-section .open > input.binxbtn-primary.dropdown-toggle.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + background: #67b2e4; + color: #fff; +} + +.btn.binxbtn-primary:active, +.swagger-section input.binxbtn-primary.submit:active { + background: #3498db; +} + +.btn.binxbtn-default, +.swagger-section input.binxbtn-default.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + border: none; + background: #ecf0f1; + color: #111; + padding: 0.5em 1em; + font-weight: 400; + box-shadow: -0.01em 0.01em 0px #acacac, -0.006em 0.006em 0 #acacac, + -0.012em 0.012em 0 #acacac, -0.018em 0.018em 0 #acacac, + -0.024em 0.024em 0 #acacac, -0.03em 0.03em 0 #acacac, + -0.036em 0.036em 0 #acacac, -0.042em 0.042em 0 #acacac, + -0.048em 0.048em 0 #acacac, -0.054em 0.054em 0 #acacac, + -0.06em 0.06em 0 #acacac, -0.066em 0.066em 0 #acacac, + -0.072em 0.072em 0 #acacac, -0.078em 0.078em 0 #acacac, + -0.084em 0.084em 0 #acacac, -0.09em 0.09em 0 #acacac; + font-size: 16px; + font-family: "Open Sans", sans-serif; +} + +.btn.binxbtn-default:hover, +.swagger-section input.binxbtn-default.submit:hover, +.btn.binxbtn-default:focus, +.swagger-section input.binxbtn-default.submit:focus, +.btn.binxbtn-default:active, +.swagger-section input.binxbtn-default.submit:active, +.btn.binxbtn-default.active, +.swagger-section input.binxbtn-default.active.submit, +.open > .btn.binxbtn-default.dropdown-toggle, +.swagger-section .open > input.binxbtn-default.dropdown-toggle.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + background: #f4f6f7; + color: #111; +} + +.btn.binxbtn-default:active, +.swagger-section input.binxbtn-default.submit:active { + background: #ecf0f1; +} + +.btn.binxbtn-danger, +.swagger-section input.binxbtn-danger.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + border: none; + background: #e85546; + color: #fff; + padding: 0.5em 1em; + font-weight: 400; + box-shadow: -0.01em 0.01em 0px #c0392b, -0.006em 0.006em 0 #c0392b, + -0.012em 0.012em 0 #c0392b, -0.018em 0.018em 0 #c0392b, + -0.024em 0.024em 0 #c0392b, -0.03em 0.03em 0 #c0392b, + -0.036em 0.036em 0 #c0392b, -0.042em 0.042em 0 #c0392b, + -0.048em 0.048em 0 #c0392b, -0.054em 0.054em 0 #c0392b, + -0.06em 0.06em 0 #c0392b, -0.066em 0.066em 0 #c0392b, + -0.072em 0.072em 0 #c0392b, -0.078em 0.078em 0 #c0392b, + -0.084em 0.084em 0 #c0392b, -0.09em 0.09em 0 #c0392b; + font-size: 16px; + font-family: "Open Sans", sans-serif; +} + +.btn.binxbtn-danger:hover, +.swagger-section input.binxbtn-danger.submit:hover, +.btn.binxbtn-danger:focus, +.swagger-section input.binxbtn-danger.submit:focus, +.btn.binxbtn-danger:active, +.swagger-section input.binxbtn-danger.submit:active, +.btn.binxbtn-danger.active, +.swagger-section input.binxbtn-danger.active.submit, +.open > .btn.binxbtn-danger.dropdown-toggle, +.swagger-section .open > input.binxbtn-danger.dropdown-toggle.submit { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + background: #ed796d; + color: #fff; +} + +.btn.binxbtn-danger:active, +.swagger-section input.binxbtn-danger.submit:active { + background: #e85546; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} + +input[type="search"] { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + text-rendering: optimizeLegibility; +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} + +input[type="file"] { + display: block; +} + +input[type="range"] { + display: block; + width: 100%; +} + +select[multiple], +select[size] { + height: auto; +} + +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857; + color: #555; +} + +.form-control { + display: block; + width: 100%; + height: auto; + font-weight: 400; + font-size: 16px; + font-family: "Open Sans", sans-serif; + line-height: 1.2em; + color: #111; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 2px; + padding: 0.5em 0.5em 0.3em; + -webkit-transition: border-color ease-in-out 0.15s, + box-shadow ease-in-out 0.15s; + -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + -webkit-box-shadow: none; + box-shadow: none; +} + +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: 0 0 2px rgba(102, 175, 233, 0.6); + box-shadow: 0 0 2px rgba(102, 175, 233, 0.6); +} + +.form-control::-moz-placeholder { + color: #c4c6c6; + opacity: 1; +} + +.form-control:-ms-input-placeholder { + color: #c4c6c6; +} + +.form-control::-webkit-input-placeholder { + color: #c4c6c6; +} + +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; + opacity: 1; +} + +textarea.form-control { + height: auto; +} + +input[type="search"] { + -webkit-appearance: none; +} + +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + line-height: 34px; + line-height: 1.42857 \0; +} + +input[type="date"].input-sm, +.form-horizontal .form-group-sm input[type="date"].form-control, +input[type="time"].input-sm, +.form-horizontal .form-group-sm input[type="time"].form-control, +input[type="datetime-local"].input-sm, +.form-horizontal .form-group-sm input[type="datetime-local"].form-control, +input[type="month"].input-sm, +.form-horizontal .form-group-sm input[type="month"].form-control { + line-height: 30px; +} + +input[type="date"].input-lg, +.form-horizontal .form-group-lg input[type="date"].form-control, +input[type="time"].input-lg, +.form-horizontal .form-group-lg input[type="time"].form-control, +input[type="datetime-local"].input-lg, +.form-horizontal .form-group-lg input[type="datetime-local"].form-control, +input[type="month"].input-lg, +.form-horizontal .form-group-lg input[type="month"].form-control { + line-height: 46px; +} + +.form-group { + margin-bottom: 15px; +} + +.radio, +.checkbox { + position: relative; + display: block; + min-height: 20px; + margin-top: 10px; + margin-bottom: 10px; +} + +.radio label, +.checkbox label { + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} + +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} + +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} + +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} + +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} + +input[type="radio"][disabled], +input[type="radio"].disabled, +fieldset[disabled] input[type="radio"], +input[type="checkbox"][disabled], +input[type="checkbox"].disabled, +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} + +.radio-inline.disabled, +fieldset[disabled] .radio-inline, +.checkbox-inline.disabled, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} + +.radio.disabled label, +fieldset[disabled] .radio label, +.checkbox.disabled label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} + +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} + +.form-control-static.input-lg, +.form-horizontal .form-group-lg .form-control-static.form-control, +.form-control-static.input-sm, +.form-horizontal .form-group-sm .form-control-static.form-control { + padding-left: 0; + padding-right: 0; +} + +.input-sm, +.form-horizontal .form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +select.input-sm, +.form-horizontal .form-group-sm select.form-control { + height: 30px; + line-height: 30px; +} + +textarea.input-sm, +.form-horizontal .form-group-sm textarea.form-control, +select[multiple].input-sm, +.form-horizontal .form-group-sm select[multiple].form-control { + height: auto; +} + +.input-lg, +.form-horizontal .form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} + +select.input-lg, +.form-horizontal .form-group-lg select.form-control { + height: 46px; + line-height: 46px; +} + +textarea.input-lg, +.form-horizontal .form-group-lg textarea.form-control, +select[multiple].input-lg, +.form-horizontal .form-group-lg select[multiple].form-control { + height: auto; +} + +.has-feedback { + position: relative; +} + +.has-feedback .form-control { + padding-right: 42.5px; +} + +.form-control-feedback { + position: absolute; + top: 25px; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; +} + +.input-lg + .form-control-feedback, +.form-horizontal .form-group-lg .form-control + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} + +.input-sm + .form-control-feedback, +.form-horizontal .form-group-sm .form-control + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} + +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #3c763d; +} + +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: none; + box-shadow: none; +} + +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); +} + +.has-success .input-group-addon { + color: #3c763d; + border-color: #3c763d; + background-color: #dff0d8; +} + +.has-success .form-control-feedback { + color: #3c763d; +} + +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #8a6d3b; +} + +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: none; + box-shadow: none; +} + +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); +} + +.has-warning .input-group-addon { + color: #8a6d3b; + border-color: #8a6d3b; + background-color: #fcf8e3; +} + +.has-warning .form-control-feedback { + color: #8a6d3b; +} + +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #a94442; +} + +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: none; + box-shadow: none; +} + +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075); +} + +.has-error .input-group-addon { + color: #a94442; + border-color: #a94442; + background-color: #f2dede; +} + +.has-error .form-control-feedback { + color: #a94442; +} + +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} + +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #515151; +} + +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + + .form-inline .input-group > .form-control { + width: 100%; + } + + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} + +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; +} + +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} + +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 7px; + } +} + +.form-horizontal .has-feedback .form-control-feedback { + top: 0; + right: 15px; +} + +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.3px; + } +} + +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + } +} + +.select2-choices { + font-size: 16px; + border-radius: 2px; + min-height: 29px; +} + +.select2-container-multi .select2-choices .select2-search-choice { + margin-top: 5px; +} + +.select2-container-multi .select2-choices .select2-search-field input, +.select2-container-multi, +.select2-container-multi input, +.select2-choices, +.select2-results { + font-family: "Open Sans", sans-serif; + font-size: 1em; +} + +label { + cursor: pointer; +} + +.label-with-tip { + position: relative; +} + +.label-with-tip:before, +.label-with-tip:after { + content: " "; + display: table; +} + +.label-with-tip:after { + clear: both; +} + +.label-with-tip p { + float: left; + margin: 0; + width: 120px; +} + +.formtip { + display: block; + position: relative; + margin-top: -0.2em; + cursor: help; + color: #217dbb; + padding: 0.2em 0.5em; + width: 20px; + text-decoration: none; + float: left; +} + +.formtip a, +.formtip a:hover { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; +} + +.control-group.actions input { + float: left; +} + +.form-suggestion { + margin-top: 0.5em; +} + +@media (min-width: 480px) { + .control-group.actions { + width: 98%; + max-width: 650px; + padding-left: 370px; + margin-left: 2%; + } +} + +@media (max-width: 600px) { + .control-group.actions { + padding-left: 0; + } + + .control-group.actions input { + float: right; + } +} + +.well { + padding-top: 20px; + padding-bottom: 20px; + padding-left: 20px; + padding-right: 20px; + min-height: 20px; + background-color: #eef2f3; + border: 1px solid #ecf0f1; + border-radius: 2px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +@media (max-width: 599px) { + .well { + padding-top: 10px; + } +} + +@media (max-width: 599px) { + .well { + padding-bottom: 10px; + } +} + +@media (max-width: 599px) { + .well { + padding-left: 10px; + } +} + +@media (max-width: 599px) { + .well { + padding-right: 10px; + } +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: 0.2; + filter: alpha(opacity = 20); +} + +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity = 50); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open .dropdown-menu { + z-index: 2050; +} + +.modal-open .dropdown.open { + *z-index: 2050; +} + +.modal-open .popover { + z-index: 2110; +} + +.modal-open .tooltip { + z-index: 2120; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: black; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity = 80); +} + +.modal { + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; + border-radius: 4px; + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + position: fixed; + top: 50%; + left: 50%; + z-index: 1050; + overflow: auto; + width: 560px; + margin: -250px 0 0 -280px; + background-color: white; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; +} + +.modal.fade { + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; + top: -25%; +} + +.modal.fade.in { + top: 50%; +} + +.modal-header { + border-bottom: 1px solid #ecf0f1; + padding: 9px 15px; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + overflow-y: auto; + max-height: 80%; + padding: 15px; +} + +@media (max-width: 700px) { + .modal-body { + max-height: 300px; + } +} + +@media (min-width: 768px) { + .modal { + max-height: 70%; + } +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f4f6f7; + border-top: 1px solid #ecf0f1; +} + +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn, +.modal-footer .swagger-section input.submit + .btn, +.swagger-section .modal-footer input.submit + .btn, +.modal-footer .swagger-section .btn + input.submit, +.swagger-section .modal-footer .btn + input.submit, +.modal-footer .swagger-section input.submit + input.submit, +.swagger-section .modal-footer input.submit + input.submit { + margin-left: 5px; + margin-bottom: 0; +} + +.modal-footer .btn-group .btn + .btn, +.modal-footer .btn-group .swagger-section input.submit + .btn, +.swagger-section .modal-footer .btn-group input.submit + .btn, +.modal-footer .btn-group .swagger-section .btn + input.submit, +.swagger-section .modal-footer .btn-group .btn + input.submit, +.modal-footer .btn-group .swagger-section input.submit + input.submit, +.swagger-section .modal-footer .btn-group input.submit + input.submit { + margin-left: -1px; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +@media (max-width: 899px) { + .modal { + position: fixed; + top: 20px; + left: 20px; + right: 20px; + width: auto; + margin: 0; + } + + .modal.fade { + top: -100px; + } + + .modal.fade.in { + top: 20px; + } +} + +@media (max-width: 599px) { + .modal { + top: 10px; + left: 10px; + right: 10px; + } + + .modal-header .close { + padding: 10px; + margin: -10px; + } +} + +.horizontal-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.horizontal-list:before, +.horizontal-list:after { + content: " "; + display: table; +} + +.horizontal-list:after { + clear: both; +} + +.horizontal-list li { + float: left; +} + +dl { + margin-top: 0; + margin-bottom: 20px; +} + +dt, +dd { + line-height: 1.42857; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 0; +} + +.dl-horizontal dd:before, +.dl-horizontal dd:after { + content: " "; + display: table; +} + +.dl-horizontal dd:after { + clear: both; +} + +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .dl-horizontal dd { + margin-left: 180px; + } +} + +table .less-strong-hold { + position: relative; +} + +table .less-strong-right { + color: #bebebe; + position: absolute; + right: -0.3em; + bottom: -0.5em; + font-size: 0.8em; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +table { + background-color: transparent; +} + +th { + text-align: left; +} + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} + +.table > thead > tr > th, +.table > thead > tr > td, +.table > tbody > tr > th, +.table > tbody > tr > td, +.table > tfoot > tr > th, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857; + vertical-align: top; + border-top: 1px solid #ddd; +} + +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} + +.table > caption + thead > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > th, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} + +.table > tbody + tbody { + border-top: 2px solid #ddd; +} + +.table .table { + background-color: #fff; +} + +.table-condensed > thead > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > th, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > th, +.table-condensed > tfoot > tr > td { + padding: 5px; +} + +.table-bordered { + border: 1px solid #ddd; +} + +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > th, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > th, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} + +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} + +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} + +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} + +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} + +.table > thead > tr > td.active, +.table > thead > tr > th.active, +.table > thead > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr > td.active, +.table > tbody > tr > th.active, +.table > tbody > tr.active > td, +.table > tbody > tr.active > th, +.table > tfoot > tr > td.active, +.table > tfoot > tr > th.active, +.table > tfoot > tr.active > td, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} + +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} + +.table > thead > tr > td.success, +.table > thead > tr > th.success, +.table > thead > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr > td.success, +.table > tbody > tr > th.success, +.table > tbody > tr.success > td, +.table > tbody > tr.success > th, +.table > tfoot > tr > td.success, +.table > tfoot > tr > th.success, +.table > tfoot > tr.success > td, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} + +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} + +.table > thead > tr > td.info, +.table > thead > tr > th.info, +.table > thead > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr > td.info, +.table > tbody > tr > th.info, +.table > tbody > tr.info > td, +.table > tbody > tr.info > th, +.table > tfoot > tr > td.info, +.table > tfoot > tr > th.info, +.table > tfoot > tr.info > td, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} + +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} + +.table > thead > tr > td.warning, +.table > thead > tr > th.warning, +.table > thead > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr > td.warning, +.table > tbody > tr > th.warning, +.table > tbody > tr.warning > td, +.table > tbody > tr.warning > th, +.table > tfoot > tr > td.warning, +.table > tfoot > tr > th.warning, +.table > tfoot > tr.warning > td, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} + +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} + +.table > thead > tr > td.danger, +.table > thead > tr > th.danger, +.table > thead > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr > td.danger, +.table > tbody > tr > th.danger, +.table > tbody > tr.danger > td, +.table > tbody > tr.danger > th, +.table > tfoot > tr > td.danger, +.table > tfoot > tr > th.danger, +.table > tfoot > tr.danger > td, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} + +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} + +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-y: hidden; + overflow-x: auto; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + -webkit-overflow-scrolling: touch; + } + + .table-responsive > .table { + margin-bottom: 0; + } + + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + + .table-responsive > .table-bordered { + border: 0; + } + + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} + +.partner-block { + clear: top; + position: relative; +} + +.partner-block a { + display: block; +} + +.partner-block .partner-text { + float: left; + position: relative; +} + +.partner-block h3, +.partner-block p { + color: #34495e; + font-family: "Open Sans", sans-serif; +} + +.partner-block h3 { + margin: 0; +} + +.partner-block p { + margin: 0.5em 0 0; +} + +.partner-block .partner-image { + position: relative; + float: right; +} + +.partner-block .partner-image img { + width: 100%; + height: auto; + display: block; +} + +.partner-block .ad-label { + display: block; + position: absolute; + bottom: 0; + right: 0; + background: rgba(153, 203, 237, 0.5); + color: #ebf5fb; + padding: 0.25em 0.5em; + z-index: 20; + border-radius: 4px 0 0 0; + font-size: 12px; +} + +.container.partner-block-container, +#grid-overlay .partner-block-container.grid-receptacle, +.partner-block-container.content-container { + padding-top: 30px; + padding-bottom: 50px; +} + +@media (max-width: 599px) { + .container.partner-block-container, + #grid-overlay .partner-block-container.grid-receptacle, + .partner-block-container.content-container { + padding-top: 10px; + } +} + +@media (max-width: 550px) { + .container.partner-block-container, + #grid-overlay .partner-block-container.grid-receptacle, + .partner-block-container.content-container { + padding-bottom: 20px; + } + + .partner-block h3 { + font-size: 20px; + } + + .partner-block p { + font-size: 0.9em; + margin-top: 0.25em; + } +} + +@media (max-width: 767px) { + .container.partner-block-container, + #grid-overlay .partner-block-container.grid-receptacle, + .partner-block-container.content-container { + display: none; + } +} + +@media (min-width: 768px) { + .partner-block { + float: right; + } +} + +@media (min-width: 950px) { + .container.partner-block-container, + #grid-overlay .partner-block-container.grid-receptacle, + .partner-block-container.content-container { + padding-top: 0; + } +} + +@media (min-width: 1000px) { + .container.partner-block-container, + #grid-overlay .partner-block-container.grid-receptacle, + .partner-block-container.content-container { + margin-top: -12px; + } +} + +@media (min-width: 768px) and (max-width: 1199px) { + .partner-block { + width: 728px; + } + + .partner-block .partner-text { + width: 63%; + } + + .partner-block .partner-image { + width: 35%; + margin-left: 2%; + } +} + +@media (min-width: 1200px) { + .container.partner-block-container, + #grid-overlay .partner-block-container.grid-receptacle, + .partner-block-container.content-container { + margin-top: -30px; + } + + .partner-block { + width: 66%; + } + + .partner-block .partner-text { + width: 61.3575%; + } + + .partner-block .partner-image { + width: 35.6025%; + margin-left: 3.03%; + } +} + +.sharing-section:before, +.sharing-section:after { + content: " "; + display: table; +} + +.sharing-section:after { + clear: both; +} + +.sharing-section .sharing-buttons { + float: right; +} + +.sharing-section .twitter-share-button { + display: block; + float: right; + margin-right: 10px; +} + +.sharing-section .fb-like { + display: block; + float: right; + overflow: visible; + margin-top: 2px; +} + +* { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + text-rendering: optimizeLegibility; +} + +html { + width: 100%; + max-width: 100%; + margin: 0; + padding: 0; + background: #ecf0f1; +} + +body { + width: 100%; + max-width: 100%; + position: relative; + background: #fff; + color: #111; + font-size: 16px; + font-family: "Open Sans", sans-serif; + font-weight: 300; + margin: 0; + padding: 0; +} + +.bodywrap { + position: relative; + width: 100%; + height: 100%; + overflow: hidden; +} + +a { + color: #3498db; + text-decoration: none; + font-weight: 300; +} + +a:hover { + text-decoration: none; + color: #1d6fa5; +} + +h1, +h2, +h3, +h4 { + font-weight: 400; + line-height: 1.2em; + margin: 0 0 0.5em; + padding: 0; +} + +h1 strong, +h2 strong, +h3 strong, +h4 strong { + font-weight: bold; +} + +p { + margin: 0.5em 0 0; +} + +#old-browser-warning { + width: 100%; + background: #eef2f3; + border-bottom: 1px solid #ecf0f1; + z-index: 9999; + padding: 10px; + position: fixed; + top: 0; + left: 0; + text-align: center; +} + +#old-browser-warning h4 { + color: #c0392b; +} + +.global-header { + position: relative; + display: block; + width: 100%; +} + +@media (min-width: 600px) { + .global-header { + padding-top: 20px; + } +} + +.bikes-nav { + width: 100%; + max-width: 1200px; + margin: 0 auto; + position: relative; +} + +@media (min-width: 600px) { + .top-logo { + display: block; + width: 15%; + position: relative; + float: left; + z-index: 10; + } + + .top-logo .logo { + display: block; + width: 100%; + height: auto; + position: relative; + } + + .top-logo .stripey { + display: block; + position: absolute; + z-index: 0; + left: -350%; + width: 400%; + height: 100%; + background: image-url("updated/stripes.svg") repeat-x; + background-size: 100% 100%; + } + + .top-logo .top-stripes { + height: 100%; + display: block; + position: absolute; + z-index: 0; + left: -50%; + } +} + +.small-header .hamburglar { + display: none; + position: absolute; + width: 6.5%; + top: 10px; + height: 41px; + left: 10px; +} + +.small-header .hamburglar img { + display: block; + height: 100%; + width: auto; +} + +@media (max-width: 599px) { + .container.bikes-nav, + #grid-overlay .bikes-nav.grid-receptacle, + .bikes-nav.content-container { + padding: 3px 0; + } + + .small-header { + width: 100%; + position: relative; + display: block; + background: url("/assets/updated/stripes.png") repeat-x; + background-size: 100% 100%; + height: 60px; + overflow: visible; + } + + .small-header .top-logo { + display: block; + width: 100px; + position: relative; + margin: 0 auto; + z-index: 10; + } + + .small-header .top-logo img { + display: inline-block; + width: 70px; + height: auto; + margin-top: -3px; + } + + .small-header .hamburglar { + display: block; + } +} + +@media (min-width: 1500px) { + .top-logo .stripey { + width: 1000%; + left: -950%; + } +} + +@media (min-width: 600px) { + .top-user-nav { + position: relative; + float: left; + width: 83%; + margin-left: 2%; + } + + .top-user-nav ul { + margin: 0; + padding: 0; + list-style-type: none; + min-height: 1.2em; + } + + .top-user-nav ul:before, + .top-user-nav ul:after { + content: " "; + display: table; + } + + .top-user-nav ul:after { + clear: both; + } + + .top-user-nav ul li { + float: right; + width: 7.8325%; + margin-right: 2.4%; + text-align: center; + } + + .top-user-nav ul li.double-width { + width: 18%; + } + + .top-user-nav ul li.first-link { + margin-right: 0; + } + + .top-user-nav ul a { + color: #2c3e50; + } + + .top-user-nav ul a.low-priority { + color: #a7a7a7; + } + + .top-user-nav ul a:hover { + color: #3498db; + } +} + +@media (max-width: 599px) { + .top-user-nav { + display: none; + } + + .top-user-nav ul { + list-style-type: none; + margin: 0; + padding: 0.5em 0 0; + background: #2c3e50; + position: relative; + } + + .top-user-nav ul li { + width: 100%; + position: relative; + } + + .top-user-nav ul li:nth-of-type(2n) a { + background: #354b60; + } + + .top-user-nav ul li a { + display: block; + padding: 0.5em 1em; + width: 100%; + color: #fff; + background: none; + } + + .top-user-nav ul li a:hover { + background: #3498db; + } +} + +.bike-search-form { + margin-top: 20px; + display: block; + position: relative; +} + +@media (max-width: 599px) { + .bike-search-form { + margin-top: 10px; + } +} + +.bike-search-form:before, +.bike-search-form:after { + content: " "; + display: table; +} + +.bike-search-form:after { + clear: both; +} + +.bike-search-form .searchit, +.bike-search-form .search-text-field { + font-size: 18px; + display: block; + position: relative; + float: left; + padding: 4px 0; +} + +.bike-search-form .search-text-field { + font-size: 18px; + border: none; + padding: 0; + border-radius: 2px 0 0 2px; +} + +.bike-search-form .search-text-field .selectize-input { + line-height: 1.5em !important; + border-radius: 2px 0 0 2px; + height: 2.5em; +} + +.bike-search-form .search-text-field .selectize-input > div { + background: none; + border: 1px solid rgba(52, 152, 219, 0.8); + font-size: 18px; + line-height: 1em; + padding-top: 0.4em; + padding-left: 0.4em; + padding-bottom: 0.4em; +} + +.bike-search-form .search-text-field .selectize-dropdown.multi.form-control { + top: (-0.1em) !important; +} + +.bike-search-form .search-text-field .selectize-dropdown .sch_ .highlight { + background: none; +} + +.bike-search-form + .search-text-field + .selectize-dropdown + .selectize-dropdown-content + .active { + background: rgba(52, 152, 219, 0.3); +} + +.bike-search-form .searchit { + -webkit-transition: background ease-in-out 0.1s; + -o-transition: background ease-in-out 0.1s; + transition: background ease-in-out 0.1s; + border-radius: 0 2px 2px 0; + margin-left: 0; + background: #2c3e50; + height: 2.5em; +} + +.bike-search-form .searchit img { + display: block; + height: 100%; + width: auto; + margin: 0 auto; +} + +.bike-search-form .searchit:hover, +.bike-search-form .searchit:active, +.bike-search-form .searchit:focus { + -webkit-transition: background ease-in-out 0.1s; + -o-transition: background ease-in-out 0.1s; + transition: background ease-in-out 0.1s; + background: #3498db; + box-shadow: none; +} + +.bike-search-form .stolen-search-link { + clear: both; +} + +.bike-search-form .stolen-search-link a { + padding: 0.5em 0 0.5em 0.8em; + color: rgba(52, 152, 219, 0.6); + display: block; +} + +.bike-search-form .stolen-search-link a:hover { + color: #3498db; +} + +.bike-search-form .stolen-search-fields { + display: none; + padding: 0.5em 0; + clear: both; +} + +.bike-search-form .stolen-search-fields:before, +.bike-search-form .stolen-search-fields:after { + content: " "; + display: table; +} + +.bike-search-form .stolen-search-fields:after { + clear: both; +} + +.bike-search-form .stolen-search-fields input, +.bike-search-form .stolen-search-fields span { + display: block; + float: right; + padding: 0.25em 0.5em; +} + +.bike-search-form .stolen-search-fields input { + background: #ecf0f1; + border-radius: 2px; + border: none; +} + +.bike-search-form .stolen-search-fields .stolen-radius { + width: 4.2em; +} + +.bike-search-form .stolen-search-fields .stolen-proximity { + width: 30%; +} + +.bike-search-form .stolen-search-fields span { + color: #bebebe; +} + +@media (max-width: 599px) { + .bike-search-form { + width: 100%; + float: none; + padding: 0 10px; + } + + .bike-search-form .search-text-field { + width: 85%; + } + + .bike-search-form .searchit { + width: 15%; + } +} + +@media (min-width: 600px) { + .bike-search-form { + width: 74.5%; + float: right; + } + + .bike-search-form .search-text-field { + width: 91.256%; + } + + .bike-search-form .searchit { + width: 8.723%; + } +} + +#bikes-search { + display: none; +} + +.selectize-dropdown-content { + background: #f4f6f7; + border: 1px solid #ecf0f1; + border-top: 1px solid rgba(236, 240, 241, 0.5); + font-size: 18px; + border-radius: 0 0 2px 2px; +} + +.selectize-dropdown-content .select2-results { + padding: 0; + margin-right: 0; + max-height: 300px; +} + +.selectize-dropdown-content .select2-result-label { + padding: 0.35em 7px; +} + +.selectize-dropdown-content .select2-highlighted .sch_s { + color: #ccc; +} + +.selectize-dropdown-content .sch_s { + display: inline-block; +} + +.selectize-dropdown-content .sch_m, +.selectize-dropdown-content .sch_ { + color: #ccc; +} + +.selectize-dropdown-content .sch_c { + color: #bbb; + display: inline-block; +} + +.selectize-dropdown-content .sch_special { + border-bottom: 1px solid #ddd; +} + +.sclr { + border-radius: 3px; + display: inline-block; + width: 24px; + height: 24px; + border: 1px solid white; + line-height: 0.8em; + margin: 0 6px 0 0; + font-size: 0.5em; + text-align: center; + padding-top: 1em; +} + +@media (max-width: 600px) { + .selectize-dropdown-content .select2-results { + max-height: 200px; + } + + .selectize-dropdown-content .sch_s, + .selectize-dropdown-content .sch_m, + .selectize-dropdown-content .sch_ { + font-size: 14px; + } + + .selectize-dropdown-content .sch_s span, + .selectize-dropdown-content .sch_m span, + .selectize-dropdown-content .sch_ span { + display: none; + } +} + +.search_span_s, +.search_span_m { + color: #bbb; + margin-left: 0; + margin-right: 3px; + display: inline; +} + +.container, +#grid-overlay .grid-receptacle, +.content-container { + position: relative; + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0; +} + +.container:before, +#grid-overlay .grid-receptacle:before, +.content-container:before, +.container:after, +#grid-overlay .grid-receptacle:after, +.content-container:after { + content: " "; + display: table; +} + +.container:after, +#grid-overlay .grid-receptacle:after, +.content-container:after { + clear: both; +} + +@media (max-width: 1199px) { + .container, + #grid-overlay .grid-receptacle, + .content-container { + padding-left: 20px; + padding-right: 20px; + } +} + +@media (max-width: 1199px) and (max-width: 599px) { + .container, + #grid-overlay .grid-receptacle, + .content-container { + padding-left: 10px; + } +} + +@media (max-width: 1199px) and (max-width: 599px) { + .container, + #grid-overlay .grid-receptacle, + .content-container { + padding-right: 10px; + } +} + +.content-container { + min-height: 400px; +} + +.global-footer { + position: relative; + z-index: 1; + padding: 75px 0 30px; + background: #ecf0f1; +} + +.global-footer a:hover { + text-decoration: underline; +} + +.global-footer p { + text-align: center; + color: #bebebe; + font-size: 0.8em; + margin-top: 30px; +} + +.global-footer p a { + color: #99cbed; +} + +.global-footer .footer-links { + list-style-type: none; + padding: 0 0 1em; + margin: 0; +} + +.global-footer .footer-links:before, +.global-footer .footer-links:after { + content: " "; + display: table; +} + +.global-footer .footer-links:after { + clear: both; +} + +.global-footer .footer-links > li { + position: relative; + width: 23.5%; + margin-right: 2%; + float: left; +} + +.global-footer .footer-links > li:last-of-type { + margin-right: 0; +} + +.global-footer .footer-links a { + display: block; + width: 100%; + color: #34495e; + font-size: 22px; +} + +.global-footer .footer-links ul { + list-style-type: none; + margin: 0; + padding: 0; +} + +.global-footer .footer-links ul li { + padding: 0.3em 0 0; +} + +.global-footer .footer-links ul a { + font-family: "Open Sans", sans-serif; + font-size: 14px; + color: #95a5a5; +} + +.global-footer .footer-links .social ul:before, +.global-footer .footer-links .social ul:after { + content: " "; + display: table; +} + +.global-footer .footer-links .social ul:after { + clear: both; +} + +.global-footer .footer-links .social li { + position: relative; + width: 28%; + margin-right: 8%; + float: left; + padding: 0; + cursor: pointer; +} + +.global-footer .footer-links .social li:last-of-type { + margin-right: 0; +} + +.global-footer .footer-links .social a { + border-radius: 4px; + margin: 0 auto; + margin: 0; + background-clip: padding-box; +} + +.global-footer .footer-links .social a.footer-facebook, +.global-footer .footer-links .social a.footer-instagram { + background: #2c3e50; +} + +.global-footer .footer-links .social a.footer-facebook:hover, +.global-footer .footer-links .social a.footer-instagram:hover { + background: #507192; +} + +.global-footer .footer-links .social a.footer-twitter { + background: #3498db; +} + +.global-footer .footer-links .social a.footer-twitter:hover { + background: #8bc4ea; +} + +.global-footer .footer-links .social a img { + display: block; + width: 100%; + height: auto; +} + +.global-footer .footer-links .social a:hover { + -webkit-transition: background 0.15s linear; + -o-transition: background 0.15s linear; + transition: background 0.15s linear; +} + +.global-footer .footer-links .social a:active { + -webkit-transform: translate(1px, 1px); + -ms-transform: translate(1px, 1px); + -o-transform: translate(1px, 1px); + transform: translate(1px, 1px); +} + +@media (max-width: 650px) { + .global-footer .footer-links > li { + width: 49%; + margin-bottom: 1.5em; + } + + .global-footer .footer-links > li:nth-of-type(2) { + margin-right: 0; + } + + .global-footer .footer-links > li:nth-of-type(3) { + clear: both; + } + + .global-footer .footer-links .social li { + width: 30%; + margin-right: 4%; + } +} + +@media (min-width: 1200px) { + .global-footer .footer-links .social a { + width: 80px; + border-radius: 40px; + } +} + +.paginate-container, +.paginate-container-bottom { + padding-top: 20px; + padding-bottom: 20px; + width: 100%; + clear: both; +} + +.paginate-container:before, +.paginate-container-bottom:before, +.paginate-container:after, +.paginate-container-bottom:after { + content: " "; + display: table; +} + +.paginate-container:after, +.paginate-container-bottom:after { + clear: both; +} + +@media (max-width: 599px) { + .paginate-container, + .paginate-container-bottom { + padding-top: 10px; + } +} + +@media (max-width: 599px) { + .paginate-container, + .paginate-container-bottom { + padding-bottom: 10px; + } +} + +.paginate-container-bottom { + margin-top: 20px; + margin-bottom: 40px; +} + +@media (max-width: 599px) { + .paginate-container-bottom { + margin-top: 10px; + } +} + +.pagination { + cursor: default; + margin: 0; +} + +.pagination:before, +.pagination:after { + content: " "; + display: table; +} + +.pagination:after { + clear: both; +} + +.pagination ul { + float: right; + margin: 0; + padding: 0; + list-style-type: none; +} + +.pagination ul li { + float: left; +} + +.pagination a, +.pagination span, +.pagination em { + border-radius: 2px; + background: #99cbed; + padding: 0.5em 1em; + line-height: 1.2em; + display: block; + float: left; + margin-left: 0.5em; + margin-bottom: 0.5em; + font-weight: 200; + color: #fff; + border: none; +} + +.pagination .previous_page { + margin-left: 0; +} + +.pagination .previous_page, +.pagination .next_page { + font-weight: normal; +} + +.pagination .disabled { + display: none; +} + +.pagination .current, +.pagination .active a { + font-style: normal; + font-weight: bold; + background: #3498db; +} + +.pagination a:hover, +.pagination a:focus { + color: #000033; + background: #ebf5fb; +} + +.pagination .page_info { + background: #2e6ab1; + color: white; + padding: 0.4em 0.6em; + width: 22em; + margin-bottom: 0.3em; + text-align: center; +} + +.pagination .page_info b { + color: #000033; + background: #6aa6ed; + padding: 0.1em 0.25em; +} + +@media (max-width: 599px) { + .pagination a, + .pagination span, + .pagination em { + padding: 0.5em 0.7em; + } +} + +.bike-pagination-counted { + float: left; +} + +.serial-text { + font-family: Courier; + text-transform: uppercase; + font-size: 1.1em; +} + +.attr-title { + display: inline-block; + margin-right: 0.4em; +} + +.attr-list { + list-style-type: none; + margin: 0; + padding: 0; + position: relative; +} + +.attr-list:before, +.attr-list:after { + content: " "; + display: table; +} + +.attr-list:after { + clear: both; +} + +.attr-list li { + width: 100%; + padding: 0.5em 1em; +} + +.attr-list li:nth-of-type(2n-1) { + background: #ecf0f1; +} + +.attr-list li .attr-title { + font-weight: 700; +} + +.bikes-search-type-tabs { + border-bottom: 1px solid #cdcdcd; +} + +.bikes-search-type-tabs ul { + list-style-type: none; + padding: 0; + margin: 0; + width: 100%; + position: relative; +} + +.bikes-search-type-tabs ul:before, +.bikes-search-type-tabs ul:after { + content: " "; + display: table; +} + +.bikes-search-type-tabs ul:after { + clear: both; +} + +.bikes-search-type-tabs li { + float: left; + margin-left: 1%; + max-width: 32%; +} + +.bikes-search-type-tabs li:first-of-type { + margin-left: 1.5%; +} + +.bikes-search-type-tabs a { + border-radius: 4px 4px 0 0; + border-bottom: 1px solid transparent; + display: block; + padding: 1em; + position: relative; +} + +.bikes-search-type-tabs a:hover { + background: #eef2f3; +} + +.bikes-search-type-tabs a.active { + border: 1px solid #cdcdcd; + background: #fff; + border-bottom: 2px solid #fff; + margin-bottom: -2px; + z-index: 10; +} + +.bikes-search-type-tabs .bottom-cover { + width: 100%; + background: #fff; + border-top: 1px solid #cdcdcd; + height: 2em; + z-index: 1; + position: relative; + display: none; +} + +@media (max-width: 1199px) { + .bikes-search-type-tabs { + border-bottom: none; + padding-top: 30px; + } + + .bikes-search-type-tabs .bottom-cover { + display: block; + } + + .bikes-search-type-tabs .container, + .bikes-search-type-tabs #grid-overlay .grid-receptacle, + #grid-overlay .bikes-search-type-tabs .grid-receptacle, + .bikes-search-type-tabs .content-container { + padding: 0; + } + + .bikes-search-type-tabs a { + margin-bottom: -2px; + padding: 0.5em; + text-align: center; + height: 4.2em; + } +} + +.bike-boxes { + padding: 0 0 40px; + padding-top: 20px; + margin: 0; + display: block; + list-style-type: none; + position: relative; + width: 100%; +} + +@media (max-width: 599px) { + .bike-boxes { + padding-top: 10px; + } +} + +.bike-boxes li { + width: 100%; + max-width: 1250px; + margin: 5px auto 0; + position: relative; + display: block; + padding: 0; + width: 100%; +} + +.bike-boxes li:nth-of-type(2n) { + background: #ebf5fb; +} + +@media (max-width: 1199px) { + .bike-boxes li { + padding-left: 20px; + padding-right: 20px; + } +} + +@media (max-width: 1199px) and (max-width: 599px) { + .bike-boxes li { + padding-left: 10px; + } +} + +@media (max-width: 1199px) and (max-width: 599px) { + .bike-boxes li { + padding-right: 10px; + } +} + +.bike-box { + padding: 0; + padding-top: 20px; + padding-bottom: 20px; + max-width: 1200px; + margin: 0 auto; + position: relative; +} + +.bike-box:before, +.bike-box:after { + content: " "; + display: table; +} + +.bike-box:after { + clear: both; +} + +@media (max-width: 599px) { + .bike-box { + padding-top: 10px; + } +} + +@media (max-width: 599px) { + .bike-box { + padding-bottom: 10px; + } +} + +.bike-box .image-holder { + display: block; + float: left; + width: 23.5%; + margin-left: 2%; +} + +.bike-box .image-holder img { + display: block; + width: 100%; + height: auto; +} + +.bike-box .information-holder { + float: left; + width: 74.5%; + position: relative; +} + +.bike-box .information-holder .bike-information, +.bike-box .information-holder .theft-information { + display: block; + margin: 0; +} + +.bike-box .information-holder .theft-information { + color: #c0392b; +} + +.bike-box .information-holder .theft-information h3 { + margin: 0.5em 0 0.2em; +} + +.bike-box .information-holder h3 { + margin: 0; +} + +.bike-box .information-holder h3 a { + padding-bottom: 0.2em; + position: relative; + display: block; +} + +.bike-box .information-holder a { + color: #111; +} + +.bike-box .information-holder a:hover { + color: #3498db; +} + +.bike-box .information-holder p { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin: 0.25em 0 0; +} + +@media (min-width: 899px) { + .bike-box .image-holder { + width: 8.5%; + position: absolute; + float: none; + right: 0; + top: 50%; + height: 100%; + margin-left: 0; + } + + .bike-box .image-holder img { + margin-top: -50%; + } + + .bike-box .information-holder { + float: none; + width: 91.5%; + } + + .bike-box .information-holder:before, + .bike-box .information-holder:after { + content: " "; + display: table; + } + + .bike-box .information-holder:after { + clear: both; + } + + .bike-box .information-holder .bike-information, + .bike-box .information-holder .theft-information { + float: left; + width: 53.41%; + } + + .bike-box .information-holder .theft-information { + width: 44.145%; + margin-left: 2.18%; + } + + .bike-box .information-holder .theft-information h3 { + margin: 0 0 0.5em; + } + + .bike-box h3 a { + padding-bottom: 0.5em; + } +} + +.no-results { + padding: 2em 0 3em; + text-align: center; +} + +.secondary-bikes { + padding: 1em 0; + margin-top: 20px; + text-align: center; + color: #2c3e50; + border-top: 1px solid #ecf0f1; +} + +@media (max-width: 599px) { + .secondary-bikes { + margin-top: 10px; + } +} + +.show-bike-edit { + -webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); + padding-top: 20px; + padding-bottom: 20px; + padding-left: 20px; + padding-right: 20px; + position: fixed; + bottom: 0; + width: 100%; + background: rgba(52, 152, 219, 0.92); + border-left: 0; + border-right: 0; + z-index: 555; +} + +@media (max-width: 599px) { + .show-bike-edit { + padding-top: 10px; + } +} + +@media (max-width: 599px) { + .show-bike-edit { + padding-bottom: 10px; + } +} + +@media (max-width: 599px) { + .show-bike-edit { + padding-left: 10px; + } +} + +@media (max-width: 599px) { + .show-bike-edit { + padding-right: 10px; + } +} + +.show-bike-edit p { + text-align: center; + margin: 0; + color: white; +} + +.show-bike-edit .btn, +.show-bike-edit .swagger-section input.submit, +.swagger-section .show-bike-edit input.submit { + margin-left: 20px; +} + +.single-bike-show { + padding-bottom: 60px; +} + +@media (max-width: 599px) { + .single-bike-show { + padding-bottom: 40px; + } +} + +.bike-show-main .bike-photos { + position: relative; +} + +.bike-show-main .bike-photos img { + display: block; + width: 100%; + height: auto; +} + +.bike-show-main .attr-list { + margin-top: 20px; +} + +@media (max-width: 599px) { + .bike-show-main .attr-list { + margin-top: 10px; + } +} + +@media (min-width: 599px) { + .bike-show-main:before, + .bike-show-main:after { + content: " "; + display: table; + } + + .bike-show-main:after { + clear: both; + } + + .bike-show-main .bike-photos, + .bike-show-main .attr-list { + float: right; + width: 49%; + } + + .bike-show-main .attr-list { + float: left; + margin-top: 0; + } +} + +.bike-show-description { + clear: both; +} + +.bike-show-components { + clear: both; +} + +.bike-show-components:before, +.bike-show-components:after { + content: " "; + display: table; +} + +.bike-show-components:after { + clear: both; +} + +.bike-show-components .comp-group { + padding-top: 20px; +} + +@media (max-width: 599px) { + .bike-show-components .comp-group { + padding-top: 10px; + } +} + +.bike-show-components .comp-group h3 { + margin-bottom: 0.25em; +} + +@media (min-width: 599px) { + .bike-show-components .comp-group { + position: relative; + width: 49%; + float: left; + } + + .bike-show-components .comp-group:nth-of-type(2n) { + margin-left: 2%; + } + + .bike-show-components .comp-group:nth-of-type(2n + 1) { + clear: left; + } +} + +.bike-show-stolen h2 { + font-size: 28px; + font-weight: 700; + margin-bottom: 0.25em; +} + +.bike-show-stolen #map_canvas { + width: 100%; + height: 400px; +} + +.bike-show-stolen .stolen-map { + margin-top: 20px; +} + +@media (max-width: 599px) { + .bike-show-stolen .stolen-map { + margin-top: 10px; + } +} + +@media (min-width: 599px) { + .bike-show-stolen:before, + .bike-show-stolen:after { + content: " "; + display: table; + } + + .bike-show-stolen:after { + clear: both; + } + + .bike-show-stolen h2 { + font-size: 35px; + } + + .bike-show-stolen .stolen-map, + .bike-show-stolen .attr-list { + float: right; + width: 49%; + } + + .bike-show-stolen .stolen-map { + float: left; + margin-top: 0; + } +} + +.bike-show-stolen-contact { + margin-top: 20px; + padding-top: 20px; + padding-bottom: 20px; + padding-left: 20px; + padding-right: 20px; + clear: both; + border: 1px solid #dde4e6; + border-radius: 2px; + background-color: #f4f6f7; +} + +@media (max-width: 599px) { + .bike-show-stolen-contact { + margin-top: 10px; + } +} + +@media (max-width: 599px) { + .bike-show-stolen-contact { + padding-top: 10px; + } +} + +@media (max-width: 599px) { + .bike-show-stolen-contact { + padding-bottom: 10px; + } +} + +@media (max-width: 599px) { + .bike-show-stolen-contact { + padding-left: 10px; + } +} + +@media (max-width: 599px) { + .bike-show-stolen-contact { + padding-right: 10px; + } +} + +.bike-show-stolen-contact .send-message { + padding-top: 10px; +} + +.bike-show-stolen-contact .send-message:before, +.bike-show-stolen-contact .send-message:after { + content: " "; + display: table; +} + +.bike-show-stolen-contact .send-message:after { + clear: both; +} + +.bike-show-stolen-contact .send-message .btn, +.bike-show-stolen-contact .send-message .swagger-section input.submit, +.swagger-section .bike-show-stolen-contact .send-message input.submit { + float: right; +} + +.bike-photos .image-holder { + z-index: 1; +} + +.bike-photos .image-holder a { + display: block; +} + +.bike-photos .image-holder img { + -webkit-transition: opacity ease-in-out 0.3s; + -o-transition: opacity ease-in-out 0.3s; + transition: opacity ease-in-out 0.3s; + cursor: pointer; + opacity: 0; + margin: 0 auto; +} + +.bike-photos .image-holder .current-photo img { + -webkit-transition: opacity ease-in 1s; + -o-transition: opacity ease-in 1s; + transition: opacity ease-in 1s; + opacity: 1; +} + +.bike-photos .image-holder .current-photo .transitioning-photo, +.bike-photos .image-holder .transitioning-photo { + position: absolute; + top: 0; + left: 0; + width: 100%; +} + +.thumbnail-shadow, +.thumbnail-shadow-r { + display: none; + position: absolute; + bottom: -2px; + height: 122px; + width: 10px; + z-index: 20; +} + +.overflown .thumbnail-shadow, +.overflown .thumbnail-shadow-r { + display: block; +} + +.overflown .photo-list ul { + left: -2px; +} + +.thumbnail-shadow { + left: 0; + box-shadow: inset 8px 0 6px -8px rgba(236, 240, 241, 0.95); +} + +.thumbnail-shadow-r { + right: 0; + box-shadow: inset -8px 0 6px -8px rgba(236, 240, 241, 0.95); +} + +.photo-list { + border-radius: 0 0 2px 2px; + margin-top: 10px; + clear: both; + position: relative; + height: 120px; + background: #fff; + width: 100%; + margin: 0; + padding: 0; + overflow-y: hidden; + overflow-x: scroll; + z-index: 10; +} + +.photo-list:before, +.photo-list:after { + content: " "; + display: table; +} + +.photo-list:after { + clear: both; +} + +.photo-list ul { + list-style-type: none; + position: absolute; + left: 0; + top: 0; + overflow: visible; + height: 100%; + margin: 0; + padding: 5px 0; + border: none; +} + +.photo-list li { + position: relative; + margin: 0; + float: left; + height: 100%; + width: 178px; + margin: 0 10px 5px 0; +} + +.photo-list li:last-of-type { + margin-right: 0; + border-right: none; +} + +.photo-list a { + height: 100%; + width: 100%; + overflow: hidden; + display: block; +} + +.photo-list img { + padding: 0; + width: 100%; + height: auto; +} + +.photo-list .clickable-image { + -webkit-transition: all ease-in-out 0.2s; + -o-transition: all ease-in-out 0.2s; + transition: all ease-in-out 0.2s; + border-radius: 2px; + box-shadow: none; + position: relative; + padding: 0; + margin: 0; + display: block; + border: 1px solid #f4f6f7; +} + +.photo-list .clickable-image.current-thumb { + -webkit-transition: all ease-in-out 0.2s; + -o-transition: all ease-in-out 0.2s; + transition: all ease-in-out 0.2s; + border-color: #3498db; + box-shadow: 0 0 2px rgba(52, 152, 219, 0.8); +} + +.photo-list .video-overlay { + display: block; + position: absolute; + top: 50%; + left: 50%; + width: 34px; + height: 34px; + margin: -17px 0 0 -17px; + border: 0; +} + +.stock-photo { + position: absolute; + top: 0; + left: 0; + padding: 20px; + padding-left: 20px; + padding-right: 20px; + background: rgba(44, 62, 80, 0.85); + box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); + border-radius: 2px; + border: 1px solid #3e5871; + border-left: none; + border-right: none; + width: 100%; + font-size: 24px; + color: white; + text-align: center; +} + +@media (max-width: 599px) { + .stock-photo { + padding-left: 10px; + } +} + +@media (max-width: 599px) { + .stock-photo { + padding-right: 10px; + } +} + +.stock-photo strong { + font-weight: 700; +} + +.stock-photo span { + display: block; + color: rgba(255, 255, 255, 0.8); + font-style: italic; +} + +.welcome-page { + background: #ecf0f1; +} + +.welcome-page + .bike-search-form + .search-text-field.select2-container.select2-container-multi { + background: #fff; +} + +.welcome-page .mainsrchdr { + background: #f9f9f9; + border: 1px solid #a7a7a7; + border-top: 1px solid rgba(236, 240, 241, 0.5); +} + +.visuallyhidden { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} + +.home-header h1 { + padding: 40px 0 25px; + margin: 0; + text-align: center; + font-size: 40px; + font-weight: 300; + color: #2c3e50; + font-weight: 700; + font-family: "Open Sans", sans-serif; + text-transform: uppercase; +} + +.home-header h1 span { + display: block; +} + +.home-header h1 a { + width: 100%; + height: 2em; + left: 0; + position: absolute; +} + +.home-header h3 { + font-size: 20px; + text-align: center; + margin: 0 auto; + color: #2c3e50; +} + +@media (max-width: 599px) { + .home-header h1 { + text-shadow: -2px 2px 0 #3498db; + } + + .home-header h1 a { + height: 4em; + } +} + +@media (min-width: 600px) { + .home-header h1 { + padding: 30px 0 35px; + font-size: 50px; + font-weight: 600; + line-height: 1em; + text-shadow: -0.01em 0.01em 0px #3498db, -0.004em 0.004em 0 #3498db, + -0.008em 0.008em 0 #3498db, -0.012em 0.012em 0 #3498db, + -0.016em 0.016em 0 #3498db, -0.02em 0.02em 0 #3498db, + -0.024em 0.024em 0 #3498db, -0.028em 0.028em 0 #3498db, + -0.032em 0.032em 0 #3498db, -0.036em 0.036em 0 #3498db, + -0.04em 0.04em 0 #3498db, -0.044em 0.044em 0 #3498db, + -0.048em 0.048em 0 #3498db, -0.052em 0.052em 0 #3498db, + -0.056em 0.056em 0 #3498db, -0.06em 0.06em 0 #3498db; + } + + .home-header h3 { + font-size: 32px; + } +} + +@media (min-width: 901px) { + .home-header h1 { + font-size: 75px; + } +} + +.register-container { + display: block; + width: 100%; + position: absolute; + left: 0; + top: 35%; + z-index: 20; + width: 100%; + text-align: center; +} + +.register-container .btn.binxbtn, +.register-container .swagger-section input.submit, +.swagger-section .register-container input.submit { + font-size: 40px; +} + +@media (max-width: 599px) { + .register-container .btn, + .register-container .swagger-section input.submit, + .swagger-section .register-container input.submit { + font-size: 30px; + } +} + +.wheeled { + padding: 20px 0 0; + position: relative; +} + +.wheel-holder { + display: block; + width: 90%; + margin: 0 auto; + overflow: hidden; + min-height: 250px; +} + +.wheel-holder img { + -webkit-transition: all ease-in-out 1.5s; + -o-transition: all ease-in-out 1.5s; + transition: all ease-in-out 1.5s; + -webkit-transform: translate3d(0, 0, 0); + -webkit-backface-visibility: hidden; + display: block; + width: 100%; + height: auto; +} + +.wheel-holder img.spun { + -webkit-transition: all ease-out 1.5s; + -o-transition: all ease-out 1.5s; + transition: all ease-out 1.5s; + -webkit-transform: rotate(30deg); + -ms-transform: rotate(30deg); + -o-transform: rotate(30deg); + transform: rotate(30deg); +} + +@media (min-width: 600px) { + .wheeled { + -webkit-transition: margin ease-in-out 0.5s; + -o-transition: margin ease-in-out 0.5s; + transition: margin ease-in-out 0.5s; + margin-top: -40px; + padding-top: 0; + } +} + +@media (min-width: 899px) { + .wheel-holder { + width: 70%; + } +} + +.home-subhead, +.how-it-works { + background: #fff; + padding: 60px 0 50px; + text-align: center; +} + +.home-subhead h2, +.how-it-works h2 { + font-size: 44px; +} + +.home-subhead p, +.home-subhead h3, +.how-it-works p, +.how-it-works h3 { + margin: 0.5em auto 0; + font-size: 22px; + font-family: "Open Sans", sans-serif; + font-weight: 300; +} + +.home-subhead p, +.how-it-works p { + text-align: left; + margin-top: 1.25em; + font-weight: 200; +} + +.how-it-works { + border-top: 10px solid #34495e; + border-bottom: 10px solid #34495e; + background: #3498db; + color: white; +} + +.how-it-works a { + color: rgba(255, 255, 255, 0.8); + text-decoration: underline; +} + +.how-it-works a:hover { + color: #1d6fa5; +} + +@media (min-width: 599px) { + .how-it-works { + padding: 70px 0 100px; + } +} + +@media (min-width: 899px) { + .home-subhead p, + .home-subhead h3 { + width: 83%; + } +} + +@media (max-width: 599px) { + .home-subhead, + .how-it-works { + padding: 40px 0; + } + + .home-subhead h2, + .how-it-works h2 { + font-size: 30px; + } + + .home-subhead p, + .home-subhead h3, + .how-it-works p, + .how-it-works h3 { + font-size: 18px; + } +} + +.home-blank-container { + width: 100%; + height: 300px; + background: #fff; +} + +.info-blocks { + padding-top: 20px; + padding-bottom: 20px; + width: 100%; + background: #fff; +} + +@media (max-width: 599px) { + .info-blocks { + padding-top: 10px; + } +} + +@media (max-width: 599px) { + .info-blocks { + padding-bottom: 10px; + } +} + +.info-blocks article { + position: relative; + width: 90%; + margin: 0 auto; +} + +.info-blocks article img { + display: block; + width: 40%; + height: auto; + margin: 0 auto; +} + +.info-blocks article h2 { + text-align: center; + margin: 0; + padding: 20px 0 0; +} + +.info-blocks article p { + padding: 0.5em 0 20px; + margin: 0 auto; + width: 80%; + text-align: center; +} + +@media (min-width: 599px) { + .info-blocks .container, + .info-blocks #grid-overlay .grid-receptacle, + #grid-overlay .info-blocks .grid-receptacle, + .info-blocks .content-container { + padding: 30px 0 20px; + } + + .info-blocks article { + float: left; + width: 23.5%; + margin: 0; + margin-left: 8.5%; + padding-bottom: 20px; + } + + .info-blocks article img { + width: 60%; + } + + .info-blocks article:first-of-type { + margin-left: 4.25%; + } + + .info-blocks article p { + width: 100%; + } +} + +.bike-background { + width: 100%; +} + +.bike-background.scrolled { + background: url("/assets/updated/home/bikes_mosaic_small.jpg") fixed; +} + +@media (min-width: 1200px) { + .bike-background.scrolled { + background: url("/assets/updated/home/bikes_mosaic_large.jpg") fixed; + } +} + +.bike-background.scrolled .supporters { + display: block; +} + +.supporters { + display: none; + -webkit-box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.6); + box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.6); + position: relative; + min-height: 15em; + padding: 40px 0 4em; +} + +.supporters h2 { + font-size: 30px; + margin: 0.75em 0; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); + color: white; +} + +.supporters .horizontal-list li { + width: 32.8%; + margin-left: 0.2%; + padding: 15px; +} + +.supporters .horizontal-list li:first-of-type { + margin-left: 0; +} + +.supporters .horizontal-list li a { + display: block; + width: 100%; +} + +.supporters .horizontal-list li img { + width: 100%; +} + +.and-many-more { + bottom: 0; + left: 3%; + width: 94%; + font-size: 18px; + color: #fff; + text-align: right; + margin: 0; + padding: 1.5em 0 0.25em; +} + +.and-many-more a { + font-weight: 400; + color: #cae4f6; +} + +.and-many-more a:hover { + color: #3498db; +} + +@media (min-width: 625px) { + .supporters { + padding-bottom: 5em; + } + + .supporters h2 { + font-size: 40px; + } + + .supporters .horizontal-list li { + width: 16.46%; + padding: 0; + } + + .supporters .five-supporters li:first-of-type { + margin-left: 8.23%; + } +} + +@media (min-width: 700px) { + .supporters .and-many-more { + font-size: 28px; + } +} + +@media (min-width: 1000px) { + .supporters h2 { + font-size: 50px; + } +} + +@media (min-width: 1300px) { + .supporters h2 { + margin-left: -5%; + } +} + +.testimonial-container { + width: 100%; + position: relative; +} + +.testimonial-block:before, +.testimonial-block:after { + content: " "; + display: table; +} + +.testimonial-block:after { + clear: both; +} + +.testimonial-block h3, +.testimonial-block h4, +.testimonial-block p { + margin: 0; +} + +.testimonial-block .testimonial-user { + display: block; + position: relative; + margin: 0 0 0 2%; + float: right; +} + +.testimonial-block .testimonial-user:before, +.testimonial-block .testimonial-user:after { + content: " "; + display: table; +} + +.testimonial-block .testimonial-user:after { + clear: both; +} + +.testimonial-block img { + display: block; + margin: 0; + width: 20%; + font-size: 16px; + height: auto; + float: right; + padding-bottom: 0.5em; +} + +.testimonial-block .h3testimonial { + margin: 0.25em 0 0; + font-size: 18px; + display: block; + font-weight: normal; +} + +.testimonial-block .h4testimonial { + font-size: 14px; + display: block; + font-family: "Open Sans", sans-serif; +} + +.testimonial-block .h3testimonial, +.testimonial-block .h4testimonial { + float: left; + text-align: right; + margin-left: 4.166%; + width: 75.834%; +} + +.testimonial-block .testimonial-quote { + float: left; + position: relative; + width: 74.5%; + margin: 0; + background: #fff; + padding: 1em; + line-height: 1.3em; +} + +.testimonial-block .testimonial-quote:before { + content: ""; + height: 0; + width: 0; + right: -14px; + position: absolute; + border-bottom: 22.5px solid transparent; + border-left: 15px solid #fff; +} + +.testimonial-block .testimonial-quote .ptestimonial { + margin: 0; + line-height: 1.2em; +} + +@media (min-width: 600px) { + .testimonial-block .testimonial-user { + width: 23%; + padding-top: 0.5em; + } + + .testimonial-block .h3testimonial, + .testimonial-block .h4testimonial { + margin-left: 0; + } + + .testimonial-block .no-image-spacer { + display: block; + width: 100%; + padding: 10px; + } + + .testimonial-block img { + width: 100%; + } + + .testimonial-block .h3testimonial { + padding-top: 1em; + } + + .testimonial-block .h3testimonial, + .testimonial-block .h4testimonial { + width: 100%; + float: none; + text-align: center; + } + + .testimonial-block .testimonial-quote { + margin-top: 40px; + font-size: 18px; + border-radius: 4px 0px 4px 4px; + } + + .testimonial-block .testimonial-quote:before { + top: 0; + } +} + +@media (min-width: 1199px) { + .testimonial-block .h3testimonial { + font-size: 24px; + } + + .testimonial-block .h4testimonial { + font-size: 14px; + } + + .testimonial-block.testmonial-2 { + padding: 20px 0; + } + + .testimonial-block .testimonial-user { + width: 14.5%; + } + + .testimonial-block .testimonial-quote { + width: 83%; + font-size: 20px; + } +} + +@media (max-width: 899px) and (min-width: 599px) { + .testimonial-block .testimonial-user { + padding-top: 1em; + padding-left: 0.5em; + } + + .testimonial-block .h4testimonial .recovery-date { + display: block; + margin-top: -0.25em; + } +} + +@media (max-width: 599px) { + .testimonial-block .testimonial-user { + width: 100%; + padding: 20px 0 0; + margin-left: 0; + } + + .testimonial-block .h3testimonial { + margin-top: 1em; + } + + .testimonial-block .h3testimonial, + .testimonial-block .h4testimonial { + text-align: right; + margin-right: 2%; + margin-left: 0; + } + + .testimonial-block img { + float: right; + } + + .testimonial-block .testimonial-quote { + width: 99%; + margin: 0 0.5%; + position: relative; + border-radius: 4px 4px 0 4px; + } + + .testimonial-block .testimonial-quote:before { + right: 0; + bottom: -15px; + border-left: 15px solid transparent; + border-bottom: 22.5px solid transparent; + border-right: 15px solid #fff; + } +} + +.stolen-bike-merge-alert { + margin: 30px auto; + max-width: 600px; +} + +.sbr-wrap { + background: #f9f9f9; + color: #7a7a7a; +} + +.sbr-wrap .list-stolen-bike { + margin-top: 3px; + float: right; +} + +.sbr-wrap section { + border-bottom: 1px solid #bebebe; + padding: 30px 0; +} + +.sbr-wrap section:nth-of-type(2n) { + background: #fff; +} + +.sbr-main-section .alert h4 { + font-size: 24px; +} + +.sbr-main-section .stolen-registry-logo { + width: 200px; + margin: 0 auto; + padding: 2.5em 0 30px; +} + +.sbr-main-section .stolen-registry-logo img { + display: block; + width: 100%; + height: auto; +} + +.sbr-main-section h1 { + font-size: 30px; + text-align: center; + color: #3a3a3a; + padding: 0 0 40px; +} + +@media (min-width: 600px) { + .sbr-main-section h1 { + font-size: 40px; + } + + .sbr-main-section .stolen-registry-logo { + width: 280px; + padding-top: 0; + } +} + +@media (min-width: 1000px) { + .sbr-main-section { + padding: 50px 0 40px; + } + + .sbr-main-section .stolen-registry-logo { + margin-top: 50px; + } + + .sbr-main-section h1 { + font-size: 50px; + } + + .sbr-main-section .list-stolen-bike { + font-size: 1.5em; + } +} + +.sbr-search-fields { + max-width: 800px; + margin: 0 auto; + padding-bottom: 40px; +} + +.sbr-search-fields:before, +.sbr-search-fields:after { + content: " "; + display: table; +} + +.sbr-search-fields:after { + clear: both; +} + +.sbr-search-fields input { + box-shadow: none; + border: 1px solid #cccdc8; + background: #fff; + color: #474747; + margin-bottom: 0.75em; +} + +.sbr-search-fields input:focus { + box-shadow: none; + border-color: #cccdc8; +} + +.sbr-search-fields .proximity { + clear: both; +} + +.sbr-search-fields .proximity input { + background: none; + border: none; + box-shadow: none; + margin: 2px 0 0.1em 0.1em; + padding: 0; + line-height: 1em; + color: #7a7a7a; + width: 10em; + border-bottom: 1px dashed #cccdc8; +} + +.sbr-search-fields .sbr-search-inputs { + position: relative; +} + +.sbr-search-fields .sbr-bike-search { + box-shadow: none; + padding: 0.4em 0.7em; + width: 100%; + float: left; + border-radius: 2px; + margin-top: 5px; +} + +.sbr-search-fields .search-type-tab { + background: #e6e6e6; + padding: 5px 10px 3px 10px; + color: #7a7a7a; + margin-left: 5px; + border: 1px solid #cccdc8; + border-radius: 2px 2px 0 0; + border-bottom: none; + position: relative; + z-index: 10; +} + +.sbr-search-fields .search-type-tab:first-of-type { + margin-left: 10px; +} + +.sbr-search-fields .search-type-tab.active { + background: #fff; + padding-bottom: 5px; + border-bottom: 1px solid #fff; +} + +.sbr-search-fields .search-type-tab.active:hover { + background: #fff; +} + +.sbr-search-fields .search-type-tab:hover { + background: #f9f9f9; + text-decoration: none; +} + +.sbrbtn { + height: 1.9em; + position: absolute; + top: 0.36em; + right: 0.2em; + border: none; + padding: 3px; + background: none; + font-size: 19px; + border-radius: 2px; +} + +.sbrbtn img { + display: block; + height: 100%; + width: auto; +} + +.sbrbtn:hover, +.sbrbtn:active, +.sbrbtn:focus { + background: #dc7d59; + box-shadow: none; + border: none; + outline: none; +} + +.sbrbtn:active { + background: #d25627; +} + +@media (max-width: 600px) { + .sbr-search-fields .sbrbtn { + top: 0.4em; + } + + .sbr-search-fields .proximity input { + width: 8em; + } +} + +.sbr-banner { + width: 100%; + padding: 1em 0; + text-align: center; + background: #3b97d3; + color: #fff; +} + +.sbr-get-involved .banner { + text-align: center; + padding: 20px 0 60px; + font-weight: 400; + font-size: 20px; +} + +.sbr-get-involved:before, +.sbr-get-involved:after { + content: " "; + display: table; +} + +.sbr-get-involved:after { + clear: both; +} + +.sbr-get-involved h1 { + text-align: center; + margin: 0 0 1em; +} + +.involve-report-form { + background: #6eb2df; + border: 1px solid #3b97d3; + border-radius: 4px; + padding: 20px 10px; + color: #fff; +} + +.involve-report-form form { + margin: 0; +} + +.involve-report-form input { + background: #fff; +} + +.involve-report-form input[type="email"], +.involve-report-form textarea { + font-size: 16px; + box-shadow: none; + border-radius: 2px; + border: 1px solid #cccdc8; + background: #f9f9f9; + color: #474747; + margin-bottom: 0.75em; +} + +.involve-report-form .contact-text { + padding-top: 1em; + width: 100%; + position: relative; +} + +.involve-report-form .contact-text textarea { + display: block; + width: 100%; + resize: none; + padding: 0.5em; +} + +.involve-report-form .contact-actions { + width: 100%; + position: relative; +} + +.involve-report-form .contact-actions:before, +.involve-report-form .contact-actions:after { + content: " "; + display: table; +} + +.involve-report-form .contact-actions:after { + clear: both; +} + +.involve-report-form .contact-actions input[type="email"] { + display: block; + width: 70%; + float: left; + padding-left: 0.5em; + padding-right: 0.5em; +} + +.involve-report-form .contact-actions .btn, +.involve-report-form .contact-actions .swagger-section input.submit, +.swagger-section .involve-report-form .contact-actions input.submit { + font-size: 16px; + display: block; + float: left; + width: 28%; + margin: 0 0 0 2%; +} + +.involve-yerself { + padding-top: 1em; +} + +.report-type label { + font-size: 19px; +} + +.report-type label input { + margin: -0.25em 0.5em 0 0; +} + +#binx_stolen_widget { + height: 350px; +} + +@media (min-width: 800px) { + .involve-yerself { + padding-bottom: 60px; + } + + .involve-yerself:before, + .involve-yerself:after { + content: " "; + display: table; + } + + .involve-yerself:after { + clear: both; + } + + .involve-yerself h3 { + margin-top: 0; + } + + .involve-report { + width: 60%; + float: left; + } + + .involve-report .involve-report-form { + height: 350px; + } + + .involve-widget { + width: 38%; + float: left; + margin-left: 2%; + } +} + +.contribute-sbr { + margin: 0.5em 0 1em; + text-align: center; +} + +.sticker-wells { + margin: 30px 0; +} + +.sticker-well select { + margin-top: 0.5em; +} + +.sticker-well .sticker-image { + -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.4); + margin-bottom: 1em; +} + +@media (min-width: 800px) { + .sticker-wells:before, + .sticker-wells:after { + content: " "; + display: table; + } + + .sticker-wells:after { + clear: both; + } + + .sticker-well { + width: 49%; + float: left; + min-height: 350px; + } + + .sticker-well:nth-of-type(2) { + margin-left: 2%; + } +} + +.multiserial-form { + position: relative; + width: 100%; + max-width: 800px; + margin: 0 auto; + padding: 0 0 30px; +} + +.multiserial-form:before, +.multiserial-form:after { + content: " "; + display: table; +} + +.multiserial-form:after { + clear: both; +} + +.multiserial-form h3 { + text-align: center; + margin: 0; + padding: 0 0 1em; + font-size: 24px; +} + +.multiserial-form textarea { + border-radius: 3px; + font-family: courier; + box-shadow: none; + display: block; + width: 100%; + height: 8em; + margin: 0; + padding: 0.5em 0.5em 0.6em; + background: #fff; + resize: none; +} + +.multiserial-form .sbrbtn { + top: 7.8em; +} + +.multiserial-response { + min-height: 10em; +} + +.multiserials-list { + list-style-type: none; + margin: 0; + padding: 10px 0 30px; +} + +.multiserials-list:before, +.multiserials-list:after { + content: " "; + display: table; +} + +.multiserials-list:after { + clear: both; +} + +.multiserials-list li { + border-radius: 2px; + -webkit-transition: all linear 0.5s; + -o-transition: all linear 0.5s; + transition: all linear 0.5s; + float: left; + position: relative; + padding: 0.2em 0.5em; + background: #f7f7f7; + margin: 0 5px 5px 0; +} + +.multiserials-list li.ms-nomatch { + text-decoration: line-through; +} + +.multiserials-list li.ms-match { + background: #3498db; + color: #fff; +} + +.multiserials-list li a { + -webkit-transition: all ease-in 0.2s; + -o-transition: all ease-in 0.2s; + transition: all ease-in 0.2s; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + cursor: pointer; + opacity: 0.9; +} + +.multiserials-list li a.blink-class { + background: #e1f0fa; +} + +.multiserial-fuzzy-box { + text-align: center; +} + +.multiserial-fuzzy-box a { + display: none; +} + +.multiserial-fuzzy-box a span { + display: none; +} + +.multiserial-fuzzy-box a .ms-short-fuzzy { + display: inline-block; +} + +@media (min-width: 800px) { + .multiserial-results div { + width: 48%; + float: left; + margin-right: 4%; + } + + .multiserial-fuzzy-box a span { + display: inline-block; + } + + .multiserial-fuzzy-box a .ms-short-fuzzy { + display: none; + } +} + +.multiserial-results { + position: relative; + border: 1px solid #ecf0f1; + padding: 20px 10px; + margin: 1em 0; +} + +.multiserial-results:before, +.multiserial-results:after { + content: " "; + display: table; +} + +.multiserial-results:after { + clear: both; +} + +.multiserial-results h3 { + margin-top: 0; +} + +.multiserial-results .serial-text { + font-size: 0.9em; + color: #a7a7a7; +} + +.multiserial-results li .serial-text { + padding-left: 0.5em; +} + +.multiserial-results .multiserial-fuzzy-result { + margin-right: 0; +} + +.multiserial-results .multiserial-fuzzy-result h3 { + color: #a7a7a7; +} + +.multiserial-results .multiserial-fuzzy-result h3 .serial-text { + color: #ecf0f1; +} + +#ms_form_section, +#ms_search_section { + display: none; +} + +.multi-search-toggle { + font-size: 20px; + margin: 0 0 1em; +} + +.multi-search-toggle a { + text-decoration: none; + color: #99cbed; +} + +.multi-search-toggle a:hover { + color: #3498db; +} + +.multi-search-toggle .multi { + display: inline-block; +} + +.doorkeeper { + background: white; +} + +.doorkeeper body .global-header { + background: #ecf0f1; +} + +@media (min-width: 600px) { + .doorkeeper .global-header { + padding-bottom: 20px; + } +} + +.doorkeeper-container { + padding-top: 80px; + padding-bottom: 80px; + background: white; +} + +.doorkeeper-container h1, +.doorkeeper-container h2, +.doorkeeper-container h3, +.doorkeeper-container h4, +.doorkeeper-container h5 { + margin: 0.4em 0; +} + +.doorkeeper-container .authorize-application-section .actions form { + float: left; + position: relative; + width: 49%; +} + +.doorkeeper-container + .authorize-application-section + .actions + form:last-of-type { + margin-left: 2%; +} + +.doorkeeper-container .form-group:before, +.doorkeeper-container .form-group:after { + content: " "; + display: table; +} + +.doorkeeper-container .form-group:after { + clear: both; +} + +.payments-page { + padding: 40px 0 60px; +} + +.payments-page form .binxbtn, +.payments-page form .swagger-section input.submit, +.swagger-section .payments-page form input.submit { + margin: 0 auto; + display: block; + font-size: 20px; + max-width: 200px; +} + +.payment-types-list { + position: relative; + list-style-type: none; + margin: 0; + padding: 30px 0; +} + +.payment-types-list:before, +.payment-types-list:after { + content: " "; + display: table; +} + +.payment-types-list:after { + clear: both; +} + +.payment-types-list li { + display: block; + float: left; + position: relative; +} + +.payment-types-list li a { + -webkit-transition: all ease-out 0.1s; + -o-transition: all ease-out 0.1s; + transition: all ease-out 0.1s; + border-radius: 4px; + display: block; + width: 100%; + padding: 1.5em 1em; +} + +.payment-types-list li .unselected { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + border: none; + background: #ecf0f1; + color: rgba(17, 17, 17, 0.9); + padding: 0.5em 1em; + font-weight: 400; + box-shadow: -0.01em 0.01em 0px #acacac, -0.015em 0.015em 0 #acacac, + -0.03em 0.03em 0 #acacac, -0.045em 0.045em 0 #acacac, + -0.06em 0.06em 0 #acacac, -0.075em 0.075em 0 #acacac, + -0.09em 0.09em 0 #acacac, -0.105em 0.105em 0 #acacac, + -0.12em 0.12em 0 #acacac, -0.135em 0.135em 0 #acacac, + -0.15em 0.15em 0 #acacac, -0.165em 0.165em 0 #acacac, + -0.18em 0.18em 0 #acacac, -0.195em 0.195em 0 #acacac, + -0.21em 0.21em 0 #acacac, -0.225em 0.225em 0 #acacac; +} + +.payment-types-list li .unselected:hover, +.payment-types-list li .unselected:focus, +.payment-types-list li .unselected:active, +.payment-types-list li .unselected.active, +.open > .payment-types-list li .unselected.dropdown-toggle { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + background: #f4f6f7; + color: rgba(17, 17, 17, 0.9); +} + +.payment-types-list li .unselected:active { + background: #ecf0f1; +} + +.payment-types-list li .active { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + border: none; + background: #3498db; + color: rgba(255, 255, 255, 0.9); + padding: 0.5em 1em; + font-weight: 400; + box-shadow: -0.01em 0.01em 0px #2574a0, -0.015em 0.015em 0 #2574a0, + -0.03em 0.03em 0 #2574a0, -0.045em 0.045em 0 #2574a0, + -0.06em 0.06em 0 #2574a0, -0.075em 0.075em 0 #2574a0, + -0.09em 0.09em 0 #2574a0, -0.105em 0.105em 0 #2574a0, + -0.12em 0.12em 0 #2574a0, -0.135em 0.135em 0 #2574a0, + -0.15em 0.15em 0 #2574a0, -0.165em 0.165em 0 #2574a0, + -0.18em 0.18em 0 #2574a0, -0.195em 0.195em 0 #2574a0, + -0.21em 0.21em 0 #2574a0, -0.225em 0.225em 0 #2574a0; +} + +.payment-types-list li .active:hover, +.payment-types-list li .active:focus, +.payment-types-list li .active:active, +.payment-types-list li .active.active, +.open > .payment-types-list li .active.dropdown-toggle { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + background: #67b2e4; + color: rgba(255, 255, 255, 0.9); +} + +.payment-types-list li .active:active { + background: #3498db; +} + +.payment-types-list li .active hr { + border-bottom: 1px solid rgba(255, 255, 255, 0.15); +} + +.payment-types-list li .active .donation input { + background: #67b2e4; + color: white; +} + +.payment-types-list li h3 { + padding-top: 1em; + color: #34495e; + font-size: 20px; +} + +.payment-types-list li hr { + margin: 1em 0; + border: none; + border-top: 1px solid rgba(0, 0, 0, 0.1); + border-bottom: 1px solid rgba(255, 255, 255, 0.8); +} + +.payment-types-list li .perks { + min-height: 7em; +} + +.payment-types-list li .donation { + min-height: 3em; + padding: 0 1em; + text-align: center; +} + +.payment-types-list li .donation input { + width: 100%; + text-align: center; + background: #f4f6f7; +} + +.container.payments-page .payment-types-list.just-one li, +#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li, +.payments-page.content-container .payment-types-list.just-one li { + min-width: 50%; + margin: 0 auto; + display: block; + float: none; +} + +.container.payments-page .payment-types-list.just-one li a, +#grid-overlay .payments-page.grid-receptacle .payment-types-list.just-one li a, +.payments-page.content-container .payment-types-list.just-one li a { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + border: none; + background: #ecf0f1; + color: rgba(17, 17, 17, 0.9); + padding: 0.5em 1em; + font-weight: 400; + box-shadow: -0.01em 0.01em 0px #acacac, -0.015em 0.015em 0 #acacac, + -0.03em 0.03em 0 #acacac, -0.045em 0.045em 0 #acacac, + -0.06em 0.06em 0 #acacac, -0.075em 0.075em 0 #acacac, + -0.09em 0.09em 0 #acacac, -0.105em 0.105em 0 #acacac, + -0.12em 0.12em 0 #acacac, -0.135em 0.135em 0 #acacac, + -0.15em 0.15em 0 #acacac, -0.165em 0.165em 0 #acacac, + -0.18em 0.18em 0 #acacac, -0.195em 0.195em 0 #acacac, + -0.21em 0.21em 0 #acacac, -0.225em 0.225em 0 #acacac; +} + +.container.payments-page .payment-types-list.just-one li a:hover, +#grid-overlay + .payments-page.grid-receptacle + .payment-types-list.just-one + li + a:hover, +.payments-page.content-container .payment-types-list.just-one li a:hover, +.container.payments-page .payment-types-list.just-one li a:focus, +#grid-overlay + .payments-page.grid-receptacle + .payment-types-list.just-one + li + a:focus, +.payments-page.content-container .payment-types-list.just-one li a:focus, +.container.payments-page .payment-types-list.just-one li a:active, +#grid-overlay + .payments-page.grid-receptacle + .payment-types-list.just-one + li + a:active, +.payments-page.content-container .payment-types-list.just-one li a:active, +.container.payments-page .payment-types-list.just-one li a.active, +#grid-overlay + .payments-page.grid-receptacle + .payment-types-list.just-one + li + a.active, +.payments-page.content-container .payment-types-list.just-one li a.active, +.open + > .container.payments-page + .payment-types-list.just-one + li + a.dropdown-toggle, +#grid-overlay + .open + > .payments-page.grid-receptacle + .payment-types-list.just-one + li + a.dropdown-toggle, +.open + > .payments-page.content-container + .payment-types-list.just-one + li + a.dropdown-toggle { + -webkit-transition: background ease-out 0.1s; + -o-transition: background ease-out 0.1s; + transition: background ease-out 0.1s; + background: #f4f6f7; + color: rgba(17, 17, 17, 0.9); +} + +.container.payments-page .payment-types-list.just-one li a:active, +#grid-overlay + .payments-page.grid-receptacle + .payment-types-list.just-one + li + a:active, +.payments-page.content-container .payment-types-list.just-one li a:active { + background: #ecf0f1; +} + +.container.payments-page .payment-types-list.just-one li a .donation input, +#grid-overlay + .payments-page.grid-receptacle + .payment-types-list.just-one + li + a + .donation + input, +.payments-page.content-container + .payment-types-list.just-one + li + a + .donation + input { + background: #fff; + color: #111; +} + +@media (min-width: 900px) { + .payments-page { + padding: 60px 0 100px; + } + + .payment-types-list li { + margin: 0 0 0 1%; + width: 19%; + } + + .payment-types-list li:first-of-type { + margin-left: 0; + } +} + +@media (max-width: 899px) { + .payment-types-list li { + margin: 20px 0 0 2%; + width: 47%; + } + + .payment-types-list li:nth-of-type(5) { + margin-left: 26%; + } +} + +.swagger-ui-wrap ul { + margin: 0; +} + +.swagger-ui-wrap select.parameter { + width: 100%; +} + +.content-header { + background: #ecf0f1; + border-top: 1px solid #f2f5f5; + border-bottom: 1px solid #d7e0e2; +} + +@media (min-width: 600px) { + .content-header { + padding: 10px 0; + } + + .content-header .top-logo { + width: 6.5%; + } +} + +#header { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 1000; + background: #ecf0f1; + padding: 0; + -webkit-transition: transform 200ms linear; + -o-transition: transform 200ms linear; + transition: transform 200ms linear; +} + +#header.headroom--pinned { + -webkit-transform: translate(0, 0%); + -ms-transform: translate(0, 0%); + -o-transform: translate(0, 0%); + transform: translate(0, 0%); +} + +#header.headroom--unpinned { + -webkit-transform: translate(0, -100%); + -ms-transform: translate(0, -100%); + -o-transform: translate(0, -100%); + transform: translate(0, -100%); +} + +.swagger-section .content-header a#logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + background: transparent url("/assets/documentation_v2/logo_small.png") + no-repeat left center; + padding: 20px 0 20px 40px; + color: white; +} + +.swagger-section .content-header form#api_selector { + display: block; + width: 100%; + position: relative; + padding-top: 1em; +} + +.swagger-section .content-header form#api_selector:before, +.swagger-section .content-header form#api_selector:after { + content: " "; + display: table; +} + +.swagger-section .content-header form#api_selector:after { + clear: both; +} + +.swagger-section .content-header .api-header-group { + padding: 0 10px 0.25em; +} + +.swagger-section .content-header .api-header-group label { + font-weight: 400; + color: #bebebe; + margin-bottom: 0.3em; +} + +.swagger-section .content-header .api-header-group input { + box-shadow: none; +} + +.swagger-section .content-header .api-header-url input { + background: none; + border: none; +} + +.swagger-section .content-header a#explore { + color: white; + float: right; + margin: 0.25em 10px 10px 0; +} + +.swagger-section { + padding-top: 60px; +} + +.swagger-section .content { + min-height: 10px; +} + +.swagger-section .sandbox_header { + padding: 5px 2px; +} + +@media (min-width: 1200px) { + .swagger-section .container-fluid { + max-width: 1230px; + margin: 0 auto; + } +} + +@media (min-width: 599px) { + .swagger-section #header form#api_selector { + width: 91.5%; + float: left; + padding-top: 0.3em; + } + + .swagger-section #header form#api_selector .api-header-group { + float: left; + margin-right: 2%; + position: relative; + padding: 0; + } + + .swagger-section #header form#api_selector .api-header-url { + width: 33%; + } + + .swagger-section #header form#api_selector .api-header-url label { + padding-left: 0.5em; + } + + .swagger-section #header form#api_selector .api-header-key { + width: 53%; + } + + .swagger-section #header form#api_selector a#explore { + float: left; + width: 10%; + margin: 1.2em 0 0; + padding-left: 0; + padding-right: 0; + } +} + +.start-of-swagger-ui { + padding-top: 40px; +} + +@media (min-width: 899px) { + .start-of-swagger-ui { + padding-top: 80px; + } +} + +.swagger-ui-wrap .operations .content > ul { + list-style-type: square; +} + +.swagger-ui-wrap .operations .content > ul br { + display: none; +} + +.swagger-ui-wrap ul#resources li.resource div.heading h2 { + font-weight: normal; +} + +.swagger-ui-wrap ul#resources li.resource div.heading h2 a { + font-size: 1.1em; +} + +.swagger-ui-wrap ul#resources > li.resource { + margin-bottom: 30px; + border-top: 1px solid #dddddd; + border-bottom: 0; +} + +.swagger-section .container h2, +.swagger-section #grid-overlay .grid-receptacle h2, +#grid-overlay .swagger-section .grid-receptacle h2, +.swagger-section .content-container h2 { + font-size: 24px; +} + +.swagger-section .container strong, +.swagger-section #grid-overlay .grid-receptacle strong, +#grid-overlay .swagger-section .grid-receptacle strong, +.swagger-section .content-container strong { + font-weight: bold; +} + +.swagger-section .container .alert, +.swagger-section #grid-overlay .grid-receptacle .alert, +#grid-overlay .swagger-section .grid-receptacle .alert, +.swagger-section .content-container .alert { + line-height: 1.2em; +} + +.swagger-section .container p, +.swagger-section #grid-overlay .grid-receptacle p, +#grid-overlay .swagger-section .grid-receptacle p, +.swagger-section .content-container p { + padding-bottom: 0.5em; +} + +.swagger-section .container pre, +.swagger-section #grid-overlay .grid-receptacle pre, +#grid-overlay .swagger-section .grid-receptacle pre, +.swagger-section .content-container pre { + margin: 0.5em 0 2em; +} + +.swagger-section .container pre code, +.swagger-section #grid-overlay .grid-receptacle pre code, +#grid-overlay .swagger-section .grid-receptacle pre code, +.swagger-section .content-container pre code { + background: none; +} + +.swagger-section .container .access-tokens, +.swagger-section #grid-overlay .grid-receptacle .access-tokens, +#grid-overlay .swagger-section .grid-receptacle .access-tokens, +.swagger-section .content-container .access-tokens { + margin-left: 0.25em; +} + +.swagger-section .container .access-tokens li, +.swagger-section #grid-overlay .grid-receptacle .access-tokens li, +#grid-overlay .swagger-section .grid-receptacle .access-tokens li, +.swagger-section .content-container .access-tokens li { + background: white; + border-radius: 4px; + padding: 0.25em 0.5em; + margin: 0 0 0.25em; +} + +.swagger-section .container .access-tokens p, +.swagger-section #grid-overlay .grid-receptacle .access-tokens p, +#grid-overlay .swagger-section .grid-receptacle .access-tokens p, +.swagger-section .content-container .access-tokens p { + margin: 0; + padding: 0.1em 0; +} + +.swagger-section .container ol, +.swagger-section #grid-overlay .grid-receptacle ol, +#grid-overlay .swagger-section .grid-receptacle ol, +.swagger-section .content-container ol { + list-style-type: decimal; + padding-left: 2em; +} + +.swagger-section .container .less-strong, +.swagger-section #grid-overlay .grid-receptacle .less-strong, +#grid-overlay .swagger-section .grid-receptacle .less-strong, +.swagger-section .content-container .less-strong { + color: #bebebe; + font-size: 0.8em; +} + +.swagger-section .container .authentication-notes, +.swagger-section #grid-overlay .grid-receptacle .authentication-notes, +#grid-overlay .swagger-section .grid-receptacle .authentication-notes, +.swagger-section .content-container .authentication-notes { + margin-top: 40px; +} + +.swagger-section .container .authentication-notes h3, +.swagger-section #grid-overlay .grid-receptacle .authentication-notes h3, +#grid-overlay .swagger-section .grid-receptacle .authentication-notes h3, +.swagger-section .content-container .authentication-notes h3 { + margin-top: 1.5em; +} + +.applications-panel { + margin-top: 60px; + padding: 30px 0; + background: #f4f6f7; + border-top: 1px solid #ecf0f1; + border-bottom: 1px solid #ecf0f1; +} + +.applications-panel .applications-list { + margin: 0; +} + +.applications-panel .applications-list li { + padding: 0.5em 1em 0.25em; + background: white; + margin: 1em 0 0; + border-radius: 4px; +} + +.applications-panel .applications-list .authorize-new-explain { + margin: 0; + padding: 1em 0 0 0; +} + +.applications-panel .application-info { + padding-bottom: 0.5em; + position: relative; +} + +.applications-panel .application-info .tokens-table { + margin-bottom: 0; +} + +.applications-panel .application-info .tokens-table pre, +.applications-panel .application-info .tokens-table .btn, +.applications-panel + .application-info + .tokens-table + .swagger-section + input.submit, +.swagger-section + .applications-panel + .application-info + .tokens-table + input.submit { + margin: 0; + padding: 0.25em 0.5em; +} + +.applications-panel .application-info .tokens-table .binxbtn-primary { + margin-bottom: 0.25em; +} + +.applications-panel .listed-app-name { + margin: 0; + display: block; + width: 90%; +} + +.applications-panel .listed-app-name span { + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); + margin-right: 0.75em; + -webkit-transition: all 0.1s ease-out; + -moz-transition: all 0.1s ease-out; + -o-transition: all 0.1s ease-out; + transition: all 0.1s ease-out; + float: left; + display: block; + font-size: 10px; + font-family: helvetica; +} + +.applications-panel .listed-app-name a:active span { + -webkit-transition: all 0.1s ease-out; + -moz-transition: all 0.1s ease-out; + -o-transition: all 0.1s ease-out; + transition: all 0.1s ease-out; +} + +.applications-panel .listed-app-name .listed-app-name:active span, +.applications-panel .listed-app-name.uncollapsed span { + -webkit-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); +} + +.swagger-section #api_info { + display: none; +} + +.api-info-header { + padding-top: 20px; +} + +.api-info-header h1, +.api-info-footer h1 { + margin-top: 0.75em; +} + +.api-info-header h1, +.api-info-header h2, +.api-info-header h3, +.api-info-footer h1, +.api-info-footer h2, +.api-info-footer h3 { + margin-bottom: 5px; +} + +.api-info-header p, +.api-info-footer p { + margin: 0; + padding: 0 0 0.5em 1em; +} + +.ref { + padding-bottom: 10px; + display: inline-block; +} + +.api-info-footer { + padding: 40px 0; +} + +#resources_container .toggleEndpointList { + font-weight: 700; +} + +.access-tokens li .btn, +.access-tokens li .swagger-section input.submit, +.swagger-section .access-tokens li input.submit { + padding: 0.25em 0.5em; + margin-left: 0.5em; +} + +.add-token-form label { + font-weight: 400; + margin-right: 0.5em; +} + +.accstr { + color: #c0392b; + font-size: 18px; + line-height: 0; +} + +.protected-endpoint-img { + margin: 0 auto; + display: block; +} + +.docs-section-list { + display: none; +} + +@media (min-width: 1000px) { + .swagger-section { + padding-left: 12%; + } + + .docs-section-list { + display: block; + position: fixed; + left: 0; + top: 0; + width: 12%; + height: 100%; + background: #ecf0f1; + border-bottom: 1px solid #d7e0e2; + padding: 120px 10px 0; + } + + .docs-section-list a { + color: #111; + } + + .docs-section-list a.scrltrgt, + .docs-section-list a:hover { + color: #3498db; + text-decoration: underline; + } + + .docs-section-list ul { + margin-left: 0.75em; + } + + .docs-section-list ul a { + font-size: 0.9em; + } +} diff --git a/app/assets/stylesheets/email.scss b/app/assets/stylesheets/email.scss index 565cd9101f..00fd8baf85 100644 --- a/app/assets/stylesheets/email.scss +++ b/app/assets/stylesheets/email.scss @@ -27,4 +27,4 @@ $email-light-bg: #ddd; max-width: 100%; height: auto; margin: 24px auto; -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/embed_styles.css.scss b/app/assets/stylesheets/embed_styles.css.scss index 6583dc7658..f85d16d1b6 100644 --- a/app/assets/stylesheets/embed_styles.css.scss +++ b/app/assets/stylesheets/embed_styles.css.scss @@ -1,15 +1,20 @@ @import "legacy_includes/selectize_bootstrap3.scss"; -.control-group .selectize-control { width: 210px; } + +.control-group .selectize-control { + width: 210px; +} + @import "legacy_includes/_colors.scss"; @import "legacy_includes/_variables.scss"; @import "legacy_includes/_mixins.scss"; @import "legacy_includes/component-animations.scss"; @import "legacy_includes/dropdowns.scss"; @import "legacy_includes/embed_form_styles.scss"; -$newStolenColor: #D25627; + +$newStolenColor: #d25627; #email_check_message { - font-size: .8em; + font-size: 0.8em; color: #f0ad4e; cursor: pointer; display: none; @@ -21,7 +26,7 @@ $newStolenColor: #D25627; max-width: 800px; margin: 0; position: relative; - + * { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; @@ -29,7 +34,9 @@ $newStolenColor: #D25627; text-rendering: optimizeLegibility; } - #new_bike { margin: 0; } + #new_bike { + margin: 0; + } select, textarea, @@ -49,13 +56,16 @@ $newStolenColor: #D25627; input[type="color"], .uneditable-input { @include border-radius(2px); + height: auto; font-size: 1em; - margin-top: -.25em; + margin-top: -0.25em; line-height: 1.3em; } + .select2-choices { @include border-radius(2px); + font-size: 16px; min-height: 29px; } @@ -65,27 +75,36 @@ $newStolenColor: #D25627; background: darken(white, 10%); color: $grayLight; cursor: default; - &:active, &:focus { + + &:active, + &:focus { border: 1px solid #ccc; + @include box-shadow(none); } } + a { color: $linkColor; } -.button-blue, .button-submit { +.button-blue, +.button-submit { @include border-radius(4px); + display: block; - padding: .5em 1em; - margin-bottom: .25em; + padding: 0.5em 1em; + margin-bottom: 0.25em; color: white; text-decoration: none; text-align: center; background: $linkColor; border: 1px solid darken($linkColor, 5%); - &:active { @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); } + &:active { + @include box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.125)); + } + &:hover { background: darken($linkColor, 5%); border: 1px solid darken($linkColor, 12%); @@ -94,59 +113,76 @@ a { .button-submit { @extend .button-blue; + background: $btnSuccess; border: 1px solid $btnSuccessBorder; - &:active { @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); } + &:active { + @include box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.125)); + } + &:hover { background: darken($btnSuccess, 5%); border: 1px solid darken($btnSuccessBorder, 5%); } } - .input-group { @include clearfix; + position: relative; - padding: .5em 2em .5em 1em; + padding: 0.5em 2em 0.5em 1em; border-bottom: 1px solid $grayLightish; } + .input-group.add-additional { .add-component-fields { padding-bottom: 30px; } + .hidden-other.unhidden { - padding: .5em 0 0; + padding: 0.5em 0 0; } + padding-left: 0; padding-right: 0; padding-bottom: 60px; + .button-blue { position: absolute; bottom: 15px; right: 20px; } } + .control-group { float: left; max-width: 300px; margin-bottom: 0; - select { margin-top: .1em; } + + select { + margin-top: 0.1em; + } } + .with-optional-blocks { @include clearfix; + .hidden-other.unhidden { clear: both; padding-bottom: 0; width: 100%; + .field { float: left; display: block; } + .optional-form-block { margin: 0 0 0 1.25em; } } + .wheel-diameter { clear: both; } @@ -159,38 +195,55 @@ a { margin-top: 1em; text-align: right; } + .has-no-serial { margin: 24px 0 0 10px; float: left; position: relative; - input { margin: 0 .5em 0 0;} + + input { + margin: 0 0.5em 0 0; + } + label { cursor: pointer; width: 100%; margin: 0 15px 0 0; + // width: 105px; - } + } + .stolen { display: none; } } -.select2-container-disabled .select2-choice { color: $grayMed; } + +.select2-container-disabled .select2-choice { + color: $grayMed; +} + .unknown-year { - margin: 24px 0 0 10px; float: left; position: relative; - input { margin: 0 .5em 0 0;} + + input { + margin: 0 0.5em 0 0; + } + label { cursor: pointer; width: 100%; margin: 0 15px 0 0; + // width: 105px; - } + } } + .form-save { display: block; text-align: center; + input { text-align: center; float: none; @@ -198,10 +251,14 @@ a { } } -.hidden-other, .edit-bike-fields .hidden-other, -.currently-hidden, .edit-bike-fields .currently-hidden, -.hidden-other, .new-bike-fields .optional-form-block.hidden-other, -.currently-hidden, .new-bike-fields .optional-form-block.currently-hidden { +.hidden-other, +.edit-bike-fields .hidden-other, +.currently-hidden, +.edit-bike-fields .currently-hidden, +.hidden-other, +.new-bike-fields .optional-form-block.hidden-other, +.currently-hidden, +.new-bike-fields .optional-form-block.currently-hidden { display: none; padding: 1em 0; } @@ -213,69 +270,95 @@ a { .form-foot { border-bottom: 0; + @include clearfix; } -.form-photo-group { padding-bottom: 30px; } + +.form-photo-group { + padding-bottom: 30px; +} + .optional-group { border-bottom: none; border-top: 1px solid $grayLightish; - .filefield-button { float: left; } - span { float: left; color: $grayMed;} + + .filefield-button { + float: left; + } + + span { + float: left; + color: $grayMed; + } } .submit-registration { clear: both; padding-top: 1.25em; - select { margin: 0; } + + select { + margin: 0; + } + input.button-submit { float: left; font-size: 1.3em; - margin: -.6em 0 .5em; + margin: -0.6em 0 0.5em; } - .what-you-register { + + .what-you-register { color: $grayLight; display: inline-block; - margin: 0 .5em; + margin: 0 0.5em; } } .select-jsonified .select2-container, -.chosen-select .controls .select2-container { width: 210px;} +.chosen-select .controls .select2-container { + width: 210px; +} -.typeahead .dropdown-menu { max-width: 300px; } +.typeahead .dropdown-menu { + max-width: 300px; +} .other-value { display: none; } - #alert-block { z-index: 100; position: fixed; - top: 100px; left: 0; + top: 100px; + left: 0; + // margin: 10px; width: 100%; + // @include clearfix; margin: 0 auto; + .alert { - @include box-shadow(-2px 2px 4px rgba(black,.2)); - // For IE 8 + @include box-shadow((-2px) 2px 4px rgba(black, 0.2)); + + // For IE 8 -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color='#000000')"; z-index: 100; position: absolute; left: 10%; width: 80%; top: 20px; - opacity: .95; + opacity: 0.95; } } - .alert { @include border-radius(1px); + padding: 15px 35px 20px 14px; margin-bottom: $baseLineHeight; - text-shadow: 0 1px 0 rgba(255,255,255,.5); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + // background-color: $warningBackground; // border: 1px solid $warningBorder; // color: $warningText; @@ -284,6 +367,7 @@ a { border: 1px solid darken($warningBorder, 7%); color: darken($warningText, 20%); } + &.alert-success { background-color: darken($blue, 2%); border: 1px solid darken($blue-lighter, 7%); @@ -292,7 +376,7 @@ a { } .alert h4 { - margin: 0 0 .5em; + margin: 0 0 0.5em; } // Adjust close link position @@ -306,87 +390,123 @@ a { cursor: pointer; color: $grayLight; z-index: 10000; + &:hover { - text-shadow: 0 0 2px rgba(black,.2); + text-shadow: 0 0 2px rgba(black, 0.2); color: $grayMed; } } .alert-success { @extend .alert; + background-color: $successBackground; border-color: $successBorder; color: $successText; } + .alert-danger, .alert-error { @extend .alert; + background-color: $errorBackground; border-color: $errorBorder; color: $errorText; } + .alert-info { @extend .alert; + background-color: $infoBackground; border-color: $infoBorder; color: $infoText; } -// +// // STOLEN FIELDS -// -// -#stolen_fields_store { display: none; } +// +// +#stolen_fields_store { + display: none; +} #stolen_fields_container { display: none; - .input-group { border-left: 3px solid $newStolenColor; } + + .input-group { + border-left: 3px solid $newStolenColor; + } +} + +.extra-group { + clear: both; } -.extra-group { clear: both; } .large-text { max-width: 100%; width: 100%; - .controls textarea { width: 100% } + + .controls textarea { + width: 100%; + } } + .stolen-phone-groups { clear: both; width: 100%; max-width: 100%; + .phone-group { float: left; + label { margin: 4px 0 0 15px; } - input { margin: 0 3px 0 0; } + + input { + margin: 0 3px 0 0; + } } } -#stolen-bike-location .chosen-select { margin-bottom: 5px; } -.stolen-suggestion { margin: 0 0 5px; } -.stolen-color { color: $newStolenColor; } +#stolen-bike-location .chosen-select { + margin-bottom: 5px; +} + +.stolen-suggestion { + margin: 0 0 5px; +} +.stolen-color { + color: $newStolenColor; +} + +.receive-group { + max-width: 100%; +} -.receive-group { max-width: 100%; } .receive-notifications { // width: 100%; padding-left: 25px; position: relative; + input { position: absolute; left: 0; - top: .75em; + top: 0.75em; + } + + label { + font-size: 1em; } - label { font-size: 1em; } + span { display: block; color: $grayLight; - font-size: .9em; + font-size: 0.9em; } } - - #registration-type-tabs { // position: absolute; // top: 5px; right: 5px; @@ -395,17 +515,24 @@ a { .registration-type-tab { @include border-radius(4px); + display: none; - padding: .5em 1em; - margin-bottom: .25em; + padding: 0.5em 1em; + margin-bottom: 0.25em; color: white; text-decoration: none; text-align: center; background: $linkColor; border: 1px solid darken($linkColor, 5%); - &.current-type { display: block; } - &:active { @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); } + &.current-type { + display: block; + } + + &:active { + @include box-shadow(inset 0 3px 5px rgba(0, 0, 0, 0.125)); + } + &:hover { background: darken($linkColor, 5%); border: 1px solid darken($linkColor, 12%); @@ -414,12 +541,14 @@ a { &.stolen { background: $newStolenColor; border: 1px solid darken($newStolenColor, 5%); + &:hover { background: darken($newStolenColor, 2%); border: 1px solid darken($newStolenColor, 8%); } } } + // .registration-type-tab { // background: #E6E6E6; // padding: 5px 10px 3px 10px; @@ -447,28 +576,35 @@ a { } @media (max-width: 500px) { - #registration-type-tabs { - position: relative; - padding-bottom: 10px; - margin-top: -10px; - } + #registration-type-tabs { + position: relative; + padding-bottom: 10px; + margin-top: -10px; + } } .embed-success-block { padding: 20px; - h1, h3 { + + h1, + h3 { font-weight: 200; font-family: $sansFontFamily; } - h1 { text-align: center; } + + h1 { + text-align: center; + } + // h3 { text-align: right; } p { font-family: $sansFontFamily; text-align: center; } + img { width: 35%; display: block; height: auto; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/embed_user_styles.css.scss b/app/assets/stylesheets/embed_user_styles.css.scss index 10516827dd..a444aea02a 100644 --- a/app/assets/stylesheets/embed_user_styles.css.scss +++ b/app/assets/stylesheets/embed_user_styles.css.scss @@ -1,12 +1,13 @@ @import "legacy_includes/_colors.scss"; @import "legacy_includes/_mixins.scss"; -#bi_user_embed { +#bi_user_embed { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 200; margin: 0; padding: 0; + * { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; @@ -16,31 +17,38 @@ .bi-embed-box { @include border-radius(3px 3px 2px 2px); - @include box-shadow(0 0 2px rgba(black,.2)); + + @include box-shadow(0 0 2px rgba(black, 0.2)); + max-width: 200px; margin: 0; - border: 2px solid $blueDarker; + border: 2px solid $blueDarker; background: $blueDarker; position: relative; overflow: hidden; + .bike-photo { display: block; width: 100%; height: auto; } + .no-bike-photo { display: block; position: absolute; - left: 0; top: 1em; + left: 0; + top: 1em; width: 100%; text-align: center; - color: rgba($blueDarker, .4); + color: rgba($blueDarker, 0.4); } + .bikey-slide { width: 100%; position: relative; background: $grayLighter; } + .bi-bike-link { display: block; position: absolute; @@ -48,31 +56,46 @@ width: 100%; height: 100%; } - .bi-title { + + .bi-title { width: 100%; position: absolute; - bottom: 0; left: 0; + bottom: 0; + left: 0; padding: 5px 2px; - background: rgba(black,.4); + background: rgba(black, 0.4); color: $grayLighter; cursor: pointer; - border-top: 1px solid rgba(black,.1); - -webkit-transition: all .2s linear; - -moz-transition: all .2s linear; - -o-transition: all .2s linear; - transition: all .2s linear; + border-top: 1px solid rgba(black, 0.1); + -webkit-transition: all 0.2s linear; + -moz-transition: all 0.2s linear; + -o-transition: all 0.2s linear; + transition: all 0.2s linear; } + &:hover { - .bi-title { color: $grayLighterer;} - .bi-slide-over { display: none; } - #bi-slide-prev { left: -1.5em; } - #bi-slide-next { right: -1.5em; } + .bi-title { + color: $grayLighterer; + } + + .bi-slide-over { + display: none; + } + + #bi-slide-prev { + left: -1.5em; + } + + #bi-slide-next { + right: -1.5em; + } } } .bikes-registered { - @include box-shadow(0 0 2px rgba(black,.4)); - border-bottom: 1px solid rgba(black,.1); + @include box-shadow(0 0 2px rgba(black, 0.4)); + + border-bottom: 1px solid rgba(black, 0.1); position: relative; z-index: 10; width: 100%; @@ -84,46 +107,59 @@ .bi-slide-over { position: absolute; - top: 0; left: 0; + top: 0; + left: 0; width: 100%; height: 100%; z-index: 10; - -moz-box-shadow: inset 0 0 2px rgba(black,.3); - -webkit-box-shadow: inset 0 0 2px rgba(black,.3); - box-shadow: inset 0 0 2px rgba(black,.3); + -moz-box-shadow: inset 0 0 2px rgba(black, 0.3); + -webkit-box-shadow: inset 0 0 2px rgba(black, 0.3); + box-shadow: inset 0 0 2px rgba(black, 0.3); } .controleys { @include border-radius(1em); + cursor: pointer; position: absolute; top: 50%; - background: rgba(white,.5); + background: rgba(white, 0.5); padding: 1em; margin-top: -1.5em; color: $grayMed; z-index: 50; - -webkit-transition: all .15s linear; - -moz-transition: all .15s linear; - -o-transition: all .15s linear; - transition: all .15s linear; - &:hover { background: rgba(white,.8); color: $grayDark} + -webkit-transition: all 0.15s linear; + -moz-transition: all 0.15s linear; + -o-transition: all 0.15s linear; + transition: all 0.15s linear; + + &:hover { + background: rgba(white, 0.8); + color: $grayDark; + } } #bi-slide-prev { - &:active { @include translate(-1px,2px); } + &:active { + @include translate(-1px, 2px); + } + left: -4em; padding-left: 2em; } + #bi-slide-next { - &:active { @include translate(1px,2px); } + &:active { + @include translate(1px, 2px); + } + right: -4em; padding-right: 2em; } .swipe { - max-width:500px; - margin:0 auto; + max-width: 500px; + margin: 0 auto; overflow: hidden; visibility: hidden; position: relative; @@ -139,4 +175,4 @@ width: 100%; position: relative; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/legacy_includes/_colors.scss b/app/assets/stylesheets/legacy_includes/_colors.scss index 42e8ee3a2c..1c8a4f1934 100644 --- a/app/assets/stylesheets/legacy_includes/_colors.scss +++ b/app/assets/stylesheets/legacy_includes/_colors.scss @@ -5,26 +5,26 @@ //________________________ $blueLight: #85a4b0; -$blue-light: #99CBED; -$blue-lighter: #EBF5FB; -$blue: rgb(52,152,219); -$blueDark: rgb(41,128,185); -$blueDarker: rgb(53,73,94); -$blueDarkerer: rgb(44,62,80); -$turquoise: rgb(26,188,56); -$turquoiseDark: rgb(22,160,133); -$green: rgb(46,204,113); -$greenDark: rgb(39,174,96); -$purple: rgb(155,89,182); -$purpleDark: rgb(142,168,173); -$yellow: rgb(241,196,15); -$YellowDark: rgb(243,156,18); -$orange: rgb(230,126,34); -$orangeDark: rgb(211,84,0); -$red: rgb(231,76,60); -$redDark: rgb(192,57,43); -$yellowPale: rgb(231,220,188); -$concrete: #95A5A7; +$blue-light: #99cbed; +$blue-lighter: #ebf5fb; +$blue: rgb(52, 152, 219); +$blueDark: rgb(41, 128, 185); +$blueDarker: rgb(53, 73, 94); +$blueDarkerer: rgb(44, 62, 80); +$turquoise: rgb(26, 188, 56); +$turquoiseDark: rgb(22, 160, 133); +$green: rgb(46, 204, 113); +$greenDark: rgb(39, 174, 96); +$purple: rgb(155, 89, 182); +$purpleDark: rgb(142, 168, 173); +$yellow: rgb(241, 196, 15); +$YellowDark: rgb(243, 156, 18); +$orange: rgb(230, 126, 34); +$orangeDark: rgb(211, 84, 0); +$red: rgb(231, 76, 60); +$redDark: rgb(192, 57, 43); +$yellowPale: rgb(231, 220, 188); +$concrete: #95a5a7; $linkColor: $blue; $linkColorHover: darken($blueDark, 10%); @@ -48,14 +48,16 @@ $grayMed: #bebebe; $grayDark: #636466; $grayDarker: #555555; -$biYellow: rgb(255,181,34); +$biYellow: rgb(255, 181, 34); $bi-stripes: rgb(255, 232, 188); $biGreen: #2e9f67; $imageBorder: $grayMed; -$tableBackgroundAccent: #f5f5f5 !default; // for striping +$tableBackgroundAccent: #f5f5f5 !default; + +// for striping //________________________ // @@ -63,11 +65,17 @@ $tableBackgroundAccent: #f5f5f5 !default; // for striping // //________________________ -.red-text { color: $redDark; } -.blue-text { color: $purpleDark; } -.table-error { color: $redDark; } +.red-text { + color: $redDark; +} +.blue-text { + color: $purpleDark; +} +.table-error { + color: $redDark; +} //________________________ // @@ -75,9 +83,11 @@ $tableBackgroundAccent: #f5f5f5 !default; // for striping // //________________________ -$btnBackground: white !default; -$btnBackgroundHighlight: darken(white, 10%) !default; -$btnBorder: $grayDark; // #bbb !default +$btnBackground: white !default; +$btnBackgroundHighlight: darken(white, 10%) !default; +$btnBorder: $grayDark; + +// #bbb !default $btnAction: $blue; $btnActionBorder: darken($blue, 10%); @@ -91,11 +101,6 @@ $btnWarningBorder: darken($yellow, 5%); $btnDanger: $red; $btnDangerBorder: darken($red, 10%); - - - - - //________________________ // // Backgrounds @@ -104,11 +109,14 @@ $btnDangerBorder: darken($red, 10%); $searchBackground: image-url("/background-granite.jpg") repeat repeat; $searchBackgroundLight: image-url("/background-granite-light.jpg") repeat repeat; -$searchBorder: darken(rgb(234,234,234), 5%); +$searchBorder: darken(rgb(234, 234, 234), 5%); $searchBorderLight: #ebebeb; + // $footerBackground: url("/background-diagonal.png") repeat repeat; -$footerBackground: rgb(249,249,249); +$footerBackground: rgb(249, 249, 249); + // $bodyBackground: url("/background-paper.jpg") repeat repeat; $bodyBackground: #fff; -$stolenBackground: image-url("/background-stolen.jpg") repeat repeat;; -// Tint on about who page: #f0f5fa \ No newline at end of file +$stolenBackground: image-url("/background-stolen.jpg") repeat repeat; + +// Tint on about who page: #f0f5fa diff --git a/app/assets/stylesheets/legacy_includes/_component-animations.scss b/app/assets/stylesheets/legacy_includes/_component-animations.scss index 8ffef1f23b..b99dfa6339 100644 --- a/app/assets/stylesheets/legacy_includes/_component-animations.scss +++ b/app/assets/stylesheets/legacy_includes/_component-animations.scss @@ -2,10 +2,11 @@ // Component animations // -------------------------------------------------- - .fade { opacity: 0; - @include transition(opacity .15s linear); + + @include transition(opacity 0.15s linear); + &.in { opacity: 1; } @@ -16,8 +17,10 @@ height: 0; overflow: hidden !important; overflow: visible \9; - @include transition(height .35s ease); + + @include transition(height 0.35s ease); + &.in { height: auto; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/legacy_includes/_dropdowns.scss b/app/assets/stylesheets/legacy_includes/_dropdowns.scss index 7273fd972c..1f7afbe9d3 100644 --- a/app/assets/stylesheets/legacy_includes/_dropdowns.scss +++ b/app/assets/stylesheets/legacy_includes/_dropdowns.scss @@ -2,16 +2,17 @@ // Dropdown menus // -------------------------------------------------- - // Use the .menu class on any
  • element within the topbar or ul.tabs and you'll get some superfancy dropdowns .dropup, .dropdown { position: relative; } + .dropdown-toggle { // The caret makes the toggle a bit too tall in IE7 *margin-bottom: -3px; } + .dropdown-toggle:active, .open .dropdown-toggle { outline: 0; @@ -24,9 +25,9 @@ width: 0; height: 0; vertical-align: top; - border-top: 4px solid $white; + border-top: 4px solid $white; border-right: 4px solid transparent; - border-left: 4px solid transparent; + border-left: 4px solid transparent; content: ""; } @@ -43,19 +44,28 @@ top: 100%; right: 0; z-index: $zindexDropdown; - display: none; // none by default, but block on "open" of the menu + display: none; + + // none by default, but block on "open" of the menu float: left; min-width: 160px; padding: 5px 0; - margin: 2px 0 0; // override default ul + margin: 2px 0 0; + + // override default ul list-style: none; background-color: $dropdownBackground; - border: 1px solid #ccc; // Fallback for IE7-8 + border: 1px solid #ccc; + + // Fallback for IE7-8 border: 1px solid $dropdownBorder; *border-right-width: 2px; *border-bottom-width: 2px; + @include border-radius(2px); - @include box-shadow(0 5px 10px rgba(0,0,0,.2)); + + @include box-shadow(0 5px 10px rgba(0, 0, 0, 0.2)); + background-clip: padding-box; // Aligns the dropdown menu to right @@ -89,7 +99,11 @@ text-decoration: none; color: $dropdownLinkColorHover; background-color: $dropdownLinkBackgroundHover; - @include gradient-vertical($dropdownLinkBackgroundHover, darken($dropdownLinkBackgroundHover, 5%)); + + @include gradient-vertical( + $dropdownLinkBackgroundHover, + darken($dropdownLinkBackgroundHover, 5%) + ); } // Active state @@ -100,7 +114,11 @@ text-decoration: none; outline: 0; background-color: $dropdownLinkBackgroundActive; - @include gradient-vertical($dropdownLinkBackgroundActive, darken($dropdownLinkBackgroundActive, 5%)); + + @include gradient-vertical( + $dropdownLinkBackgroundActive, + darken($dropdownLinkBackgroundActive, 5%) + ); } // Disabled state @@ -110,6 +128,7 @@ .dropdown-menu .disabled > a:hover { color: $grayLight; } + // Nuke hover effects .dropdown-menu .disabled > a:hover { text-decoration: none; @@ -148,6 +167,7 @@ border-bottom: 4px solid $black; content: "\2191"; } + // Different positioning for bottom up menu .dropdown-menu { top: auto; @@ -161,15 +181,17 @@ .dropdown-submenu { position: relative; } + .dropdown-submenu > .dropdown-menu { top: 0; left: 100%; margin-top: -6px; margin-left: -1px; -webkit-border-radius: 0 6px 6px 6px; - -moz-border-radius: 0 6px 6px 6px; - border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; } + .dropdown-submenu:hover .dropdown-menu { display: block; } @@ -187,11 +209,11 @@ margin-top: 5px; margin-right: -10px; } + .dropdown-submenu:hover > a:after { border-left-color: $dropdownLinkColorHover; } - // Tweak nav headers // ----------------- // Increase padding from 15px to 20px on sides @@ -203,6 +225,8 @@ // Typeahead // --------- .typeahead { - margin-top: 2px; // give it some space to breathe + margin-top: 2px; + + // give it some space to breathe @include border-radius(4px); -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/legacy_includes/_mixins.scss b/app/assets/stylesheets/legacy_includes/_mixins.scss index 98124b9af6..4d12e9ed98 100644 --- a/app/assets/stylesheets/legacy_includes/_mixins.scss +++ b/app/assets/stylesheets/legacy_includes/_mixins.scss @@ -2,34 +2,40 @@ // Mixins // -------------------------------------------------- - // UTILITY MIXINS // -------------------------------------------------- // Clearfix // -------- // For clearing floats like a boss h5bp.com/q -@mixin clearfix() { +@mixin clearfix { *zoom: 1; + &:before, &:after { display: table; content: ""; + // Fixes Opera/contenteditable bug: // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 line-height: 0; } + &:after { clear: both; } } -.clearfix { @include clearfix(); } + +.clearfix { + @include clearfix; +} // Webkit-style focus // ------------------ -@mixin tab-focus() { +@mixin tab-focus { // Default outline: thin dotted #333; + // Webkit outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; @@ -37,7 +43,7 @@ // Center-align a block level element // ---------------------------------- -@mixin center-block() { +@mixin center-block { display: block; margin-left: auto; margin-right: auto; @@ -45,8 +51,10 @@ // IE7 inline-block // ---------------- -@mixin ie7-inline-block() { - *display: inline; /* IE7 inline-block hack */ +@mixin ie7-inline-block { + *display: inline; + + /* IE7 inline-block hack */ *zoom: 1; } @@ -56,16 +64,16 @@ // right version is for icons, which come before. Applying both is ok, but it will // mean that space between those elements will be .6em (~2 space characters) in IE7, // instead of the 1 space in other browsers. -@mixin ie7-restore-left-whitespace() { - *margin-left: .3em; +@mixin ie7-restore-left-whitespace { + *margin-left: 0.3em; &:first-child { *margin-left: 0; } } -@mixin ie7-restore-right-whitespace() { - *margin-right: .3em; +@mixin ie7-restore-right-whitespace { + *margin-right: 0.3em; } // Sizing shortcuts @@ -74,6 +82,7 @@ width: $width; height: $height; } + @mixin square($size) { @include size($size, $size); } @@ -84,9 +93,11 @@ &:-moz-placeholder { color: $color; } + &:-ms-input-placeholder { color: $color; } + &::-webkit-input-placeholder { color: $color; } @@ -95,7 +106,7 @@ // Text overflow // ------------------------- // Requires inline-block or block for proper styling -@mixin text-overflow() { +@mixin text-overflow { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -104,7 +115,7 @@ // CSS image replacement // ------------------------- // Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757 -@mixin hide-text() { +@mixin hide-text { font: 0/0 a; color: transparent; text-shadow: none; @@ -112,58 +123,88 @@ border: 0; } - // FONTS // -------------------------------------------------- -@mixin font-family-serif() { +@mixin font-family-serif { font-family: $serifFontFamily; } -@mixin font-family-sans-serif() { + +@mixin font-family-sans-serif { font-family: $sansFontFamily; } -@mixin font-family-monospace() { + +@mixin font-family-monospace { font-family: $monoFontFamily; } -@mixin font-shorthand($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { + +@mixin font-shorthand( + $size: $baseFontSize, + $weight: normal, + $lineHeight: $baseLineHeight +) { font-size: $size; font-weight: $weight; line-height: $lineHeight; } -@mixin font-serif($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { - @include font-family-serif(); + +@mixin font-serif( + $size: $baseFontSize, + $weight: normal, + $lineHeight: $baseLineHeight +) { + @include font-family-serif; + @include font-shorthand($size, $weight, $lineHeight); } -@mixin font-sans-serif($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { - @include font-family-sans-serif(); + +@mixin font-sans-serif( + $size: $baseFontSize, + $weight: normal, + $lineHeight: $baseLineHeight +) { + @include font-family-sans-serif; + @include font-shorthand($size, $weight, $lineHeight); } -@mixin font-monospace($size: $baseFontSize, $weight: normal, $lineHeight: $baseLineHeight) { - @include font-family-monospace(); + +@mixin font-monospace( + $size: $baseFontSize, + $weight: normal, + $lineHeight: $baseLineHeight +) { + @include font-family-monospace; + @include font-shorthand($size, $weight, $lineHeight); } - // FORMS // -------------------------------------------------- // Block level inputs -@mixin input-block-level() { +@mixin input-block-level { display: block; width: 100%; - min-height: 30px; // Make inputs at least the height of their button counterpart - @include box-sizing(border-box); // Makes inputs behave like true block-level elements -} + min-height: 30px; + // Make inputs at least the height of their button counterpart + @include box-sizing(border-box); + // Makes inputs behave like true block-level elements +} // Mixin for form field states -@mixin formFieldState($textColor: #555, $borderColor: #ccc, $backgroundColor: #f5f5f5) { +@mixin formFieldState( + $textColor: #555, + $borderColor: #ccc, + $backgroundColor: #f5f5f5 +) { // Set the text color > label, .help-block, .help-inline { color: $textColor; } + // Style inputs accordingly .checkbox, .radio, @@ -172,15 +213,23 @@ textarea { color: $textColor; border-color: $borderColor; - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work + + @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, 0.075)); + + // Redeclare so transitions work &:focus { border-color: darken($borderColor, 10%); + // Write out in full since the lighten() function isn't easily escaped - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($borderColor, 20%); - -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($borderColor, 20%); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten($borderColor, 20%); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 6px lighten($borderColor, 20%); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 6px lighten($borderColor, 20%); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 6px lighten($borderColor, 20%); } } + // Give a small background color for input-prepend/-append .input-prepend .add-on, .input-append .add-on { @@ -190,177 +239,192 @@ } } - - // CSS3 PROPERTIES // -------------------------------------------------- // Border Radius @mixin border-radius($radius) { -webkit-border-radius: $radius; - -moz-border-radius: $radius; - border-radius: $radius; + -moz-border-radius: $radius; + border-radius: $radius; } // Single Corner Border Radius @mixin border-top-left-radius($radius) { -webkit-border-top-left-radius: $radius; - -moz-border-radius-topleft: $radius; - border-top-left-radius: $radius; + -moz-border-radius-topleft: $radius; + border-top-left-radius: $radius; } + @mixin border-top-right-radius($radius) { -webkit-border-top-right-radius: $radius; - -moz-border-radius-topright: $radius; - border-top-right-radius: $radius; + -moz-border-radius-topright: $radius; + border-top-right-radius: $radius; } + @mixin border-bottom-right-radius($radius) { -webkit-border-bottom-right-radius: $radius; - -moz-border-radius-bottomright: $radius; - border-bottom-right-radius: $radius; + -moz-border-radius-bottomright: $radius; + border-bottom-right-radius: $radius; } + @mixin border-bottom-left-radius($radius) { -webkit-border-bottom-left-radius: $radius; - -moz-border-radius-bottomleft: $radius; - border-bottom-left-radius: $radius; + -moz-border-radius-bottomleft: $radius; + border-bottom-left-radius: $radius; } // Single Side Border Radius @mixin border-top-radius($radius) { @include border-top-right-radius($radius); + @include border-top-left-radius($radius); } + @mixin border-right-radius($radius) { @include border-top-right-radius($radius); + @include border-bottom-right-radius($radius); } + @mixin border-bottom-radius($radius) { @include border-bottom-right-radius($radius); + @include border-bottom-left-radius($radius); } + @mixin border-left-radius($radius) { @include border-top-left-radius($radius); + @include border-bottom-left-radius($radius); } // Drop shadows @mixin box-shadow($shadow) { -webkit-box-shadow: $shadow; - -moz-box-shadow: $shadow; - box-shadow: $shadow; + -moz-box-shadow: $shadow; + box-shadow: $shadow; } // Transitions @mixin transition($transition) { -webkit-transition: $transition; - -moz-transition: $transition; - -o-transition: $transition; - transition: $transition; + -moz-transition: $transition; + -o-transition: $transition; + transition: $transition; } // Transformations @mixin rotate($degrees) { -webkit-transform: rotate($degrees); - -moz-transform: rotate($degrees); - -ms-transform: rotate($degrees); - -o-transform: rotate($degrees); - transform: rotate($degrees); + -moz-transform: rotate($degrees); + -ms-transform: rotate($degrees); + -o-transform: rotate($degrees); + transform: rotate($degrees); } + @mixin scale($ratio) { -webkit-transform: scale($ratio); - -moz-transform: scale($ratio); - -ms-transform: scale($ratio); - -o-transform: scale($ratio); - transform: scale($ratio); + -moz-transform: scale($ratio); + -ms-transform: scale($ratio); + -o-transform: scale($ratio); + transform: scale($ratio); } + @mixin translate($x, $y) { -webkit-transform: translate($x, $y); - -moz-transform: translate($x, $y); - -ms-transform: translate($x, $y); - -o-transform: translate($x, $y); - transform: translate($x, $y); + -moz-transform: translate($x, $y); + -ms-transform: translate($x, $y); + -o-transform: translate($x, $y); + transform: translate($x, $y); } + @mixin skew($x, $y) { -webkit-transform: skew($x, $y); - -moz-transform: skew($x, $y); - -ms-transform: skew($x, $y); - -o-transform: skew($x, $y); - transform: skew($x, $y); + -moz-transform: skew($x, $y); + -ms-transform: skew($x, $y); + -o-transform: skew($x, $y); + transform: skew($x, $y); } + @mixin translate3d($x, $y, $z) { -webkit-transform: translate3d($x, $y, $z); - -moz-transform: translate3d($x, $y, $z); - -o-transform: translate3d($x, $y, $z); - transform: translate3d($x, $y, $z); + -moz-transform: translate3d($x, $y, $z); + -o-transform: translate3d($x, $y, $z); + transform: translate3d($x, $y, $z); } // Backface visibility // Prevent browsers from flickering when using CSS 3D transforms. // Default value is `visible`, but can be changed to `hidden // See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples -@mixin backface-visibility($visibility){ - -webkit-backface-visibility: $visibility; - -moz-backface-visibility: $visibility; - backface-visibility: $visibility; +@mixin backface-visibility($visibility) { + -webkit-backface-visibility: $visibility; + -moz-backface-visibility: $visibility; + backface-visibility: $visibility; } // Background clipping // Heads up: FF 3.6 and under need "padding" instead of "padding-box" @mixin background-clip($clip) { -webkit-background-clip: $clip; - -moz-background-clip: $clip; - background-clip: $clip; + -moz-background-clip: $clip; + background-clip: $clip; } // Background sizing -@mixin background-size($size){ +@mixin background-size($size) { -webkit-background-size: $size; - -moz-background-size: $size; - -o-background-size: $size; - background-size: $size; + -moz-background-size: $size; + -o-background-size: $size; + background-size: $size; } - // Box sizing @mixin box-sizing($boxmodel) { -webkit-box-sizing: $boxmodel; - -moz-box-sizing: $boxmodel; - box-sizing: $boxmodel; + -moz-box-sizing: $boxmodel; + box-sizing: $boxmodel; } // User select // For selecting text on the page @mixin user-select($select) { -webkit-user-select: $select; - -moz-user-select: $select; - -ms-user-select: $select; - -o-user-select: $select; - user-select: $select; + -moz-user-select: $select; + -ms-user-select: $select; + -o-user-select: $select; + user-select: $select; } // Resize anything @mixin resizable($direction) { - resize: $direction; // Options: horizontal, vertical, both - overflow: auto; // Safari fix + resize: $direction; + + // Options: horizontal, vertical, both + overflow: auto; + + // Safari fix } // CSS3 Content Columns @mixin content-columns($columnCount, $columnGap: $gridGutterWidth) { -webkit-column-count: $columnCount; - -moz-column-count: $columnCount; - column-count: $columnCount; + -moz-column-count: $columnCount; + column-count: $columnCount; -webkit-column-gap: $columnGap; - -moz-column-gap: $columnGap; - column-gap: $columnGap; + -moz-column-gap: $columnGap; + column-gap: $columnGap; } // Optional hyphenation @mixin hyphens($mode: auto) { word-wrap: break-word; -webkit-hyphens: $mode; - -moz-hyphens: $mode; - -ms-hyphens: $mode; - -o-hyphens: $mode; - hyphens: $mode; + -moz-hyphens: $mode; + -ms-hyphens: $mode; + -o-hyphens: $mode; + hyphens: $mode; } // Opacity @@ -369,92 +433,243 @@ filter: alpha(opacity=#{$opacity * 100}); } - - // BACKGROUNDS // -------------------------------------------------- // Add an alphatransparency value to any background or border color (via Elyse Holladay) @mixin translucent-background($color: $white, $alpha: 1) { - background-color: hsla(hue($color), saturation($color), lightness($color), $alpha); + background-color: hsla( + hue($color), + saturation($color), + lightness($color), + $alpha + ); } + @mixin translucent-border($color: $white, $alpha: 1) { - border-color: hsla(hue($color), saturation($color), lightness($color), $alpha); + border-color: hsla( + hue($color), + saturation($color), + lightness($color), + $alpha + ); + @include background-clip(padding-box); } // Gradient Bar Colors for buttons and alerts -@mixin gradientBar($primaryColor, $secondaryColor, $textColor: #fff, $textShadow: 0 -1px 0 rgba(0,0,0,.25)) { +@mixin gradientBar( + $primaryColor, + $secondaryColor, + $textColor: #fff, + $textShadow: 0 -1px 0 rgba(0, 0, 0, 0.25) +) { color: $textColor; text-shadow: $textShadow; + @include gradient-vertical($primaryColor, $secondaryColor); + border-color: $secondaryColor $secondaryColor darken($secondaryColor, 15%); - border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%); + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) + fadein(rgba(0, 0, 0, 0.1), 15%); } // Gradients @mixin gradient-horizontal($startColor: #555, $endColor: #333) { background-color: $endColor; - background-image: -moz-linear-gradient(left, $startColor, $endColor); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 100% 0, from($startColor), to($endColor)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(left, $startColor, $endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(left, $startColor, $endColor); // Opera 11.10 - background-image: linear-gradient(to right, $startColor, $endColor); // Standard, IE10 + background-image: -moz-linear-gradient(left, $startColor, $endColor); + + // FF 3.6+ + background-image: -webkit-gradient( + linear, + 0 0, + 100% 0, + from($startColor), + to($endColor) + ); + + // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(left, $startColor, $endColor); + + // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(left, $startColor, $endColor); + + // Opera 11.10 + background-image: linear-gradient(to right, $startColor, $endColor); + + // Standard, IE10 background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=1); // IE9 and down + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=1); + + // IE9 and down } + @mixin gradient-vertical($startColor: #555, $endColor: #333) { background-color: mix($startColor, $endColor, 60%); - background-image: -moz-linear-gradient(top, $startColor, $endColor); // FF 3.6+ - background-image: -webkit-gradient(linear, 0 0, 0 100%, from($startColor), to($endColor)); // Safari 4+, Chrome 2+ - background-image: -webkit-linear-gradient(top, $startColor, $endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient(top, $startColor, $endColor); // Opera 11.10 - background-image: linear-gradient(to bottom, $startColor, $endColor); // Standard, IE10 + background-image: -moz-linear-gradient(top, $startColor, $endColor); + + // FF 3.6+ + background-image: -webkit-gradient( + linear, + 0 0, + 0 100%, + from($startColor), + to($endColor) + ); + + // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(top, $startColor, $endColor); + + // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(top, $startColor, $endColor); + + // Opera 11.10 + background-image: linear-gradient(to bottom, $startColor, $endColor); + + // Standard, IE10 background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=0); // IE9 and down + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=0); + + // IE9 and down } + @mixin gradient-directional($startColor: #555, $endColor: #333, $deg: 45deg) { background-color: $endColor; background-repeat: repeat-x; - background-image: -moz-linear-gradient($deg, $startColor, $endColor); // FF 3.6+ - background-image: -webkit-linear-gradient($deg, $startColor, $endColor); // Safari 5.1+, Chrome 10+ - background-image: -o-linear-gradient($deg, $startColor, $endColor); // Opera 11.10 - background-image: linear-gradient($deg, $startColor, $endColor); // Standard, IE10 + background-image: -moz-linear-gradient($deg, $startColor, $endColor); + + // FF 3.6+ + background-image: -webkit-linear-gradient($deg, $startColor, $endColor); + + // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient($deg, $startColor, $endColor); + + // Opera 11.10 + background-image: linear-gradient($deg, $startColor, $endColor); + + // Standard, IE10 } -@mixin gradient-vertical-three-colors($startColor: #00b3ee, $midColor: #7a43b6, $colorStop: 50%, $endColor: #c3325f) { + +@mixin gradient-vertical-three-colors( + $startColor: #00b3ee, + $midColor: #7a43b6, + $colorStop: 50%, + $endColor: #c3325f +) { background-color: mix($midColor, $endColor, 80%); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from($startColor), color-stop($colorStop, $midColor), to($endColor)); - background-image: -webkit-linear-gradient($startColor, $midColor $colorStop, $endColor); - background-image: -moz-linear-gradient(top, $startColor, $midColor $colorStop*100%, $endColor); - background-image: -o-linear-gradient($startColor, $midColor $colorStop, $endColor); - background-image: linear-gradient($startColor, $midColor $colorStop, $endColor); + background-image: -webkit-gradient( + linear, + 0 0, + 0 100%, + from($startColor), + color-stop($colorStop, $midColor), + to($endColor) + ); + background-image: -webkit-linear-gradient( + $startColor, + $midColor $colorStop, + $endColor + ); + background-image: -moz-linear-gradient( + top, + $startColor, + $midColor ($colorStop * 100%), + $endColor + ); + background-image: -o-linear-gradient( + $startColor, + $midColor $colorStop, + $endColor + ); + background-image: linear-gradient( + $startColor, + $midColor $colorStop, + $endColor + ); background-repeat: no-repeat; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($startColor)}', endColorstr='#{ie-hex-str($endColor)}', GradientType=0); + + // IE9 and down, gets no color-stop at all for proper fallback } -@mixin gradient-radial($innerColor: #555, $outerColor: #333) { + +@mixin gradient-radial($innerColor: #555, $outerColor: #333) { background-color: $outerColor; - background-image: -webkit-gradient(radial, center center, 0, center center, 460, from($innerColor), to($outerColor)); + background-image: -webkit-gradient( + radial, + center center, + 0, + center center, + 460, + from($innerColor), + to($outerColor) + ); background-image: -webkit-radial-gradient(circle, $innerColor, $outerColor); background-image: -moz-radial-gradient(circle, $innerColor, $outerColor); background-image: -o-radial-gradient(circle, $innerColor, $outerColor); background-repeat: no-repeat; } + @mixin gradient-striped($color, $angle: 45deg) { background-color: $color; - background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); - background-image: -webkit-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -moz-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient($angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); - background-image: linear-gradient($angle, rgba(255,255,255,.15) 25%, rgba(0,0,0, 0.0) 25%, rgba(0,0,0, 0.0) 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, rgba(0,0,0, 0.0) 75%, rgba(0,0,0, 0.0)); + background-image: -webkit-gradient( + linear, + 0 100%, + 100% 0, + color-stop(0.25, rgba(255, 255, 255, 0.15)), + color-stop(0.25, transparent), + color-stop(0.5, transparent), + color-stop(0.5, rgba(255, 255, 255, 0.15)), + color-stop(0.75, rgba(255, 255, 255, 0.15)), + color-stop(0.75, transparent), + to(transparent) + ); + background-image: -webkit-linear-gradient( + $angle, + rgba(255, 255, 255, 0.15) 25%, + transparent 25%, + transparent 50%, + rgba(255, 255, 255, 0.15) 50%, + rgba(255, 255, 255, 0.15) 75%, + transparent 75%, + transparent + ); + background-image: -moz-linear-gradient( + $angle, + rgba(255, 255, 255, 0.15) 25%, + transparent 25%, + transparent 50%, + rgba(255, 255, 255, 0.15) 50%, + rgba(255, 255, 255, 0.15) 75%, + transparent 75%, + transparent + ); + background-image: -o-linear-gradient( + $angle, + rgba(255, 255, 255, 0.15) 25%, + transparent 25%, + transparent 50%, + rgba(255, 255, 255, 0.15) 50%, + rgba(255, 255, 255, 0.15) 75%, + transparent 75%, + transparent + ); + background-image: linear-gradient( + $angle, + rgba(255, 255, 255, 0.15) 25%, + rgba(0, 0, 0, 0) 25%, + rgba(0, 0, 0, 0) 50%, + rgba(255, 255, 255, 0.15) 50%, + rgba(255, 255, 255, 0.15) 75%, + rgba(0, 0, 0, 0) 75%, + rgba(0, 0, 0, 0) + ); } // Reset filters for IE -@mixin reset-filter() { +@mixin reset-filter { filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); } - - // COMPONENT MIXINS // -------------------------------------------------- @@ -468,7 +683,9 @@ // to negative-margin away, but so it goes. *width: 100%; height: 1px; - margin: (($baseLineHeight / 2) - 1) 1px; // 8px 1px + margin: ($baseLineHeight / 2 - 1) 1px; + + // 8px 1px *margin: -5px 0 5px; overflow: hidden; background-color: $top; @@ -477,14 +694,26 @@ // Button backgrounds // ------------------ -@mixin buttonBackground($startColor, $endColor, $textColor: #fff, $textShadow: 0 -1px 0 rgba(0,0,0,.25)) { +@mixin buttonBackground( + $startColor, + $endColor, + $textColor: #fff, + $textShadow: 0 -1px 0 rgba(0, 0, 0, 0.25) +) { // gradientBar will set the background to a pleasing blend of these, to support IE<=9 @include gradientBar($startColor, $endColor, $textColor, $textShadow); - *background-color: $endColor; /* Darken IE7 buttons by default so they stand out more given they won't have borders */ - @include reset-filter(); + + *background-color: $endColor; + + /* Darken IE7 buttons by default so they stand out more given they won't have borders */ + @include reset-filter; // in these cases the gradient won't cover the background, so we override - &:hover, &:active, &.active, &.disabled, &[disabled] { + &:hover, + &:active, + &.active, + &.disabled, + &[disabled] { color: $textColor; background-color: $endColor; *background-color: darken($endColor, 5%); @@ -505,42 +734,52 @@ margin-top: ($navbarHeight - $elementHeight) / 2; } - - // Grid System // ----------- // Centered container element -@mixin container-fixed() { +@mixin container-fixed { margin-right: auto; margin-left: auto; - @include clearfix(); + + @include clearfix; } // Table columns @mixin tableColumns($columnSpan: 1) { - float: none; // undo default grid column styles - width: (($gridColumnWidth) * $columnSpan) + ($gridGutterWidth * ($columnSpan - 1)) - 16; // 16 is total padding on left and right of table cells - margin-left: 0; // undo default grid column styles + float: none; + + // undo default grid column styles + width: $gridColumnWidth * $columnSpan + $gridGutterWidth * ($columnSpan - 1) - + 16; + + // 16 is total padding on left and right of table cells + margin-left: 0; + + // undo default grid column styles } // Make a Grid // Use .makeRow and .makeColumn to assign semantic layouts grid system behavior -@mixin makeRow() { +@mixin makeRow { margin-left: $gridGutterWidth * -1; - @include clearfix(); + + @include clearfix; } + @mixin makeColumn($columns: 1, $offset: 0) { float: left; - margin-left: ($gridColumnWidth * $offset) + ($gridGutterWidth * ($offset - 1)) + ($gridGutterWidth * 2); - width: ($gridColumnWidth * $columns) + ($gridGutterWidth * ($columns - 1)); + margin-left: $gridColumnWidth * $offset + $gridGutterWidth * ($offset - 1) + + $gridGutterWidth * 2; + width: $gridColumnWidth * $columns + $gridGutterWidth * ($columns - 1); } // The Grid @mixin grid-core($gridColumnWidth, $gridGutterWidth) { .row { margin-left: $gridGutterWidth * -1; - @include clearfix(); + + @include clearfix; } [class*="span"] { @@ -552,71 +791,102 @@ .container, .navbar-static-top .container, .navbar-fixed-top .container, - .navbar-fixed-bottom .container { @include grid-core-span($gridColumns, $gridColumnWidth, $gridGutterWidth); } + .navbar-fixed-bottom .container { + @include grid-core-span($gridColumns, $gridColumnWidth, $gridGutterWidth); + } @include grid-core-spanX($gridColumns, $gridColumnWidth, $gridGutterWidth); + @include grid-core-offsetX($gridColumns, $gridColumnWidth, $gridGutterWidth); } + @mixin grid-core-spanX($cols, $columnWidth, $gutterWidth) { @for $i from 1 through $cols { - .span#{$i} { @include grid-core-span($i, $columnWidth, $gutterWidth) }; + .span#{$i} { + @include grid-core-span($i, $columnWidth, $gutterWidth); + } } } + @mixin grid-core-span($columns, $columnWidth, $gutterWidth) { - width: ($columnWidth * $columns) + ($gutterWidth * ($columns - 1)); + width: $columnWidth * $columns + $gutterWidth * ($columns - 1); } + @mixin grid-core-offsetX($cols, $columnWidth, $gutterWidth) { @for $i from 1 through $cols { - .offset#{$i} { @include grid-core-offset($i, $columnWidth, $gutterWidth) }; + .offset#{$i} { + @include grid-core-offset($i, $columnWidth, $gutterWidth); + } } } + @mixin grid-core-offset($columns, $columnWidth, $gutterWidth) { - margin-left: ($columnWidth * $columns) + ($gutterWidth * ($columns + 1)); + margin-left: $columnWidth * $columns + $gutterWidth * ($columns + 1); } -@mixin grid-fluid ($columnWidth, $gutterWidth) { +@mixin grid-fluid($columnWidth, $gutterWidth) { .row-fluid { width: 100%; - @include clearfix(); + + @include clearfix; + [class*="span"] { - @include input-block-level(); + @include input-block-level; + float: left; margin-left: $gutterWidth; - *margin-left: $gutterWidth - (.5px / $gridRowWidth * 100 * 1%); + *margin-left: $gutterWidth - 0.5px / $gridRowWidth * 100 * 1%; } + [class*="span"]:first-child { margin-left: 0; } // generate .spanX and .offsetX @for $i from 1 through $gridColumns { - .span#{$i} { @include grid-fluid-span($i, $columnWidth, $gutterWidth); } - .offset#{$i} { @include grid-fluid-offset($i, $columnWidth, $gutterWidth); } - .offset#{$i}:first-child { @include grid-fluid-offsetFirstChild($i, $columnWidth, $gutterWidth); } + .span#{$i} { + @include grid-fluid-span($i, $columnWidth, $gutterWidth); + } + + .offset#{$i} { + @include grid-fluid-offset($i, $columnWidth, $gutterWidth); + } + + .offset#{$i}:first-child { + @include grid-fluid-offsetFirstChild($i, $columnWidth, $gutterWidth); + } } } } -@mixin grid-fluid-span($columns, $columnWidth, $gutterWidth){ - width: ($columnWidth * $columns) + ($gutterWidth * ($columns - 1)); - *width: ($columnWidth * $columns) + ($gutterWidth * ($columns - 1)) - (.5px / $gridRowWidth * 100 * 1%); +@mixin grid-fluid-span($columns, $columnWidth, $gutterWidth) { + width: $columnWidth * $columns + $gutterWidth * ($columns - 1); + *width: $columnWidth * $columns + $gutterWidth * ($columns - 1) - 0.5px / + $gridRowWidth * 100 * 1%; } @mixin grid-fluid-offset($columns, $columnWidth, $gutterWidth) { - margin-left: ($columnWidth * $columns) + ($gutterWidth * ($columns - 1)) + ($gutterWidth*2); - *margin-left: ($columnWidth * $columns) + ($gutterWidth * ($columns - 1)) - (.5px / $gridRowWidth * 100 * 1%) + ($gutterWidth * 2) - (.5px / $gridRowWidth * 100 * 1%); + margin-left: $columnWidth * $columns + $gutterWidth * ($columns - 1) + + $gutterWidth * 2; + *margin-left: $columnWidth * $columns + $gutterWidth * ($columns - 1) - 0.5px / + $gridRowWidth * 100 * 1% + $gutterWidth * 2 - 0.5px / $gridRowWidth * 100 * + 1%; } @mixin grid-fluid-offsetFirstChild($columns, $columnWidth, $gutterWidth) { - margin-left: ($columnWidth * $columns) + ($gutterWidth * ($columns - 1)) + ($gutterWidth); - *margin-left: ($columnWidth * $columns) + ($gutterWidth * ($columns - 1)) - (.5px / $gridRowWidth * 100 * 1%) + $gutterWidth - (.5px / $gridRowWidth * 100 * 1%); + margin-left: $columnWidth * $columns + $gutterWidth * ($columns - 1) + + $gutterWidth; + *margin-left: $columnWidth * $columns + $gutterWidth * ($columns - 1) - 0.5px / + $gridRowWidth * 100 * 1% + $gutterWidth - 0.5px / $gridRowWidth * 100 * 1%; } @mixin grid-input($columnWidth, $gutterWidth) { input, textarea, .uneditable-input { - margin-left: 0; // override margin-left from core grid system + margin-left: 0; + + // override margin-left from core grid system } // Space grid-sized controls properly if multiple per line @@ -625,10 +895,14 @@ } @for $i from 1 through $gridColumns { - input.span#{$i}, textarea.span#{$i}, .uneditable-input.span#{$i} { @include grid-input-span($i, $columnWidth, $gutterWidth); } + input.span#{$i}, + textarea.span#{$i}, + .uneditable-input.span#{$i} { + @include grid-input-span($i, $columnWidth, $gutterWidth); + } } } @mixin grid-input-span($columns, $columnWidth, $gutterWidth) { - width: (($columnWidth) * $columns) + ($gutterWidth * ($columns - 1)) - 14; -} \ No newline at end of file + width: $columnWidth * $columns + $gutterWidth * ($columns - 1) - 14; +} diff --git a/app/assets/stylesheets/legacy_includes/_reset.scss b/app/assets/stylesheets/legacy_includes/_reset.scss index e5ccc68ef1..50ea8d6ebe 100644 --- a/app/assets/stylesheets/legacy_includes/_reset.scss +++ b/app/assets/stylesheets/legacy_includes/_reset.scss @@ -3,7 +3,6 @@ // Adapted from http://github.com/necolas/normalize.css // -------------------------------------------------- - // Display in IE6-9 and FF3 // ------------------------- @@ -35,7 +34,7 @@ video { // ------------------------- audio:not([controls]) { - display: none; + display: none; } // Base settings @@ -44,12 +43,14 @@ audio:not([controls]) { html { font-size: 100%; -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; } + // Focus states a:focus { - @include tab-focus(); + @include tab-focus; } + // Hover & Active a:hover, a:active { @@ -66,9 +67,11 @@ sup { line-height: 0; vertical-align: baseline; } + sup { top: -0.5em; } + sub { bottom: -0.25em; } @@ -77,8 +80,12 @@ sub { // ------------------------- img { - max-width: 100%; // Make images inherently responsive - height: auto; // Make images inherently responsive + max-width: 100%; + + // Make images inherently responsive + height: auto; + + // Make images inherently responsive vertical-align: middle; border: 0; -ms-interpolation-mode: bicubic; @@ -101,34 +108,56 @@ textarea { font-size: 100%; vertical-align: middle; } + button, input { - *overflow: visible; // Inner spacing ie IE6/7 - line-height: normal; // FF3/4 have !important on line-height in UA stylesheet + *overflow: visible; + + // Inner spacing ie IE6/7 + line-height: normal; + + // FF3/4 have !important on line-height in UA stylesheet } + button::-moz-focus-inner, -input::-moz-focus-inner { // Inner padding and border oddities in FF3/4 +input::-moz-focus-inner { + // Inner padding and border oddities in FF3/4 padding: 0; border: 0; } + button, input[type="button"], input[type="reset"], input[type="submit"] { - cursor: pointer; // Cursors on all buttons applied consistently - -webkit-appearance: button; // Style clickable inputs in iOS + cursor: pointer; + + // Cursors on all buttons applied consistently + -webkit-appearance: button; + + // Style clickable inputs in iOS } -input[type="search"] { // Appearance in Safari/Chrome + +input[type="search"] { + // Appearance in Safari/Chrome -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; -webkit-appearance: textfield; } + input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5 + -webkit-appearance: none; + + // Inner-padding issues in Chrome OSX, Safari 5 } + textarea { - overflow: auto; // Remove vertical scrollbar in IE6-9 - vertical-align: top; // Readability and alignment cross-browser -} \ No newline at end of file + overflow: auto; + + // Remove vertical scrollbar in IE6-9 + vertical-align: top; + + // Readability and alignment cross-browser +} diff --git a/app/assets/stylesheets/legacy_includes/_utility_classes.scss b/app/assets/stylesheets/legacy_includes/_utility_classes.scss index 1d0cc051aa..f67fbb8981 100644 --- a/app/assets/stylesheets/legacy_includes/_utility_classes.scss +++ b/app/assets/stylesheets/legacy_includes/_utility_classes.scss @@ -12,14 +12,21 @@ margin: 0 auto; padding: 0 $singlePad; } + .inner-recep { @include clearfix; + position: relative; - width: 100% ; + width: 100%; } -.overfloating { overflow: visible; } -label { cursor: pointer; } +.overfloating { + overflow: visible; +} + +label { + cursor: pointer; +} .pull-left { float: left; @@ -31,10 +38,12 @@ label { cursor: pointer; } .footnote-ref { color: $blueLight; - font-size: .9em; + font-size: 0.9em; } + .footnotes { padding: 40px 0 60px; + li { line-height: 1.3em; margin: 1em 0; @@ -49,7 +58,9 @@ label { cursor: pointer; } padding-bottom: 200px; } -.placeholder { color: $placeholder; } +.placeholder { + color: $placeholder; +} .subheading-text { display: block; @@ -60,27 +71,42 @@ label { cursor: pointer; } } // Visibility -.invisible { visibility: hidden; } +.invisible { + visibility: hidden; +} // For Affix plugin -.affix { position: fixed; } +.affix { + position: fixed; +} -.clickable, .no-tab { cursor: pointer; } +.clickable, +.no-tab { + cursor: pointer; +} -.unclickable { cursor: default; } +.unclickable { + cursor: default; +} -.less-strong { color: darken($grayMed, 5%); } +.less-strong { + color: darken($grayMed, 5%); +} input.less-strong { border: none; background: transparent; - font-size: .8em; + font-size: 0.8em; box-shadow: none; } -.overflow-text { @include text-overflow();} +.overflow-text { + @include text-overflow; +} -.initially-hidden, .hidden, .hide { +.initially-hidden, +.hidden, +.hide { display: none; } @@ -93,9 +119,11 @@ hr { .horizontal-list { @include clearfix; + margin: 0; padding: 0; list-style-type: none; + li { float: left; } @@ -103,30 +131,34 @@ hr { .delineated-horizontal-list { @extend .horizontal-list; + li { margin: 0; } + a { display: inline-block; line-height: 1em; - padding: 0 .4em; + padding: 0 0.4em; text-decoration: none; color: $textColor; border-right: 1px solid $grayDarker; + &:hover { text-decoration: underline; } } + & li:last-of-type a { border-right: 0; } } .short-transition { - -webkit-transition: all .1s linear; - -moz-transition: all .1s linear; - -o-transition: all .1s linear; - transition: all .1s linear; + -webkit-transition: all 0.1s linear; + -moz-transition: all 0.1s linear; + -o-transition: all 0.1s linear; + transition: all 0.1s linear; } .hide-text { @@ -139,10 +171,9 @@ hr { text-decoration: none; } - - .logo { display: block; + h1 { display: none; } @@ -154,26 +185,31 @@ hr { // //________________________ - - .dl-horizontal { - dd { - font-weight: normal; + dd { + font-weight: normal; } + dt { font-weight: normal; text-align: left; margin-bottom: 6px; color: #999; } - dd { + + dd { font-weight: normal; + // max-width: 460px; margin-bottom: 6px; - textarea {width: 100%;} + + textarea { + width: 100%; + } + .highlight { display: inline-block; - padding: .5em .5em .25em; + padding: 0.5em 0.5em 0.25em; background: $grayLighter; } } @@ -182,27 +218,33 @@ hr { @media (min-width: 768px) { .dl-holder { @include clearfix; + position: relative; + .dl-horizontal { width: $sixColumn; float: left; margin-left: $gutterW; - &:nth-of-type(2n+1) { + + &:nth-of-type(2n + 1) { margin-left: 0; clear: left; } } + dl:first-of-type { margin-left: 0; } + dd { margin: 0 0 6px 0; padding-left: 30%; } + dt { width: 30%; padding-right: 5%; - margin: 0 0 .3em 0; + margin: 0 0 0.3em 0; } } } @@ -210,21 +252,25 @@ hr { @media (max-width: 767px) { .dl-holder { @include clearfix; + position: relative; + .dl-horizontal { width: 100%; float: none; margin-left: 0; } + dd { width: 70%; - margin: 0 0 .3em 0; + margin: 0 0 0.3em 0; float: left; } + dt { width: 29%; padding-right: 2%; - margin: 0 0 .3em 0; + margin: 0 0 0.3em 0; float: left; } } @@ -234,24 +280,31 @@ hr { .dl-holder { dt { width: 35%; + // margin-bottom: 0; } + dd { width: 65%; + // margin-bottom: .5em; } } } - @media (min-width: 768px) { - .dl-holder .dl-wider-dt, .dl-wider-dt { - dt { width: 28%; } - dd { margin-left: 30%; } + .dl-holder .dl-wider-dt, + .dl-wider-dt { + dt { + width: 28%; + } + + dd { + margin-left: 30%; + } } } - // dt, dd { // width: 100%; // padding: 0; @@ -266,31 +319,46 @@ hr { header.with-subtitle { padding-bottom: 0; + @include clearfix; - h1, h2, h3 { + + h1, + h2, + h3 { float: left; font-size: $standardFontSize * 2.5; } + p { display: inline-block; margin: 1.85em 0 0 1em; } + .sharing-links { display: block; float: right; margin: 1.85em 0 0 1em; } + .sharing-section { float: right; width: 250px; } + .subtitle-form { @include clearfix; + float: right; width: 257px; margin-top: 22px; - form { margin: 0; } - input { margin: 0;} + + form { + margin: 0; + } + + input { + margin: 0; + } } } @@ -300,9 +368,11 @@ header.with-subtitle { float: none; clear: both; } + p { - margin: 0 0 10px .5em; + margin: 0 0 10px 0.5em; } + .sharing-links { float: right; margin: 0 0 10px 1em; @@ -312,20 +382,27 @@ header.with-subtitle { @media (max-width: 800px) { header.with-subtitle { - h1, h2, h3 { font-size: $standardFontSize * 2; } + h1, + h2, + h3 { + font-size: $standardFontSize * 2; + } } } - @media (max-width: 650px) { header.with-subtitle { - h1, h2, h3 { font-size: $standardFontSize * 1.5; } + h1, + h2, + h3 { + font-size: $standardFontSize * 1.5; + } } } - .well-yellow { @include border-radius(2px); + background: $bi-stripes; border: 1px solid $biYellow; padding: 10px; @@ -334,6 +411,7 @@ header.with-subtitle { .well-blue { @include border-radius(2px); + background: $blueLight; border: 1px solid $blue; color: white; @@ -345,27 +423,39 @@ header.with-subtitle { background: $stolenBackground; } -.stolen-color { color: $stolenColor; } +.stolen-color { + color: $stolenColor; +} -.recovered-color { color: $stolenColor; } +.recovered-color { + color: $stolenColor; +} .smaller-text { - font-size: .8em; + font-size: 0.8em; } -.centered-form-well { margin: 0 auto; float: none; } +.centered-form-well { + margin: 0 auto; + float: none; +} @media (max-width: 480px) { .form-horizontal.form-horizontal-collapse { - .control-label { float: none; text-align: left; } - } + .control-label { + float: none; + text-align: left; + } + } } @media (min-width: 480px) { .form-horizontal.form-horizontal-collapse { .controls { - select, input { max-width: 80%; } + select, + input { + max-width: 80%; + } } } } - diff --git a/app/assets/stylesheets/legacy_includes/_variables.scss b/app/assets/stylesheets/legacy_includes/_variables.scss index 4d3d729d77..604fcc7880 100644 --- a/app/assets/stylesheets/legacy_includes/_variables.scss +++ b/app/assets/stylesheets/legacy_includes/_variables.scss @@ -2,21 +2,18 @@ // Variables // -------------------------------------------------- - // Global values // -------------------------------------------------- - // Grays // ------------------------- -$black: #000 !default; -$grayDarker: #222 !default; -$grayDark: #333 !default; -$gray: #555 !default; -$grayLight: #999 !default; -$grayLighter: #eee !default; -$white: #fff !default; - +$black: #000 !default; +$grayDarker: #222 !default; +$grayDark: #333 !default; +$gray: #555 !default; +$grayLight: #999 !default; +$grayLighter: #eee !default; +$white: #fff !default; // Accent colors // ------------------------- @@ -29,93 +26,101 @@ $white: #fff !default; // $pink: #c3325f !default; // $purple: #7a43b6 !default; - // Scaffolding // ------------------------- -$bodyBackground: $white !default; -$textColor: $grayDark !default; - +$bodyBackground: $white !default; +$textColor: $grayDark !default; // Links // ------------------------- // $linkColor: #08c !default; // $linkColorHover: darken($linkColor, 15%) !default; - // Typography // ------------------------- -$sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif !default; -$serifFontFamily: Georgia, "Times New Roman", Times, serif !default; -$monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace !default; +$sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif !default; +$serifFontFamily: Georgia, "Times New Roman", Times, serif !default; +$monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace !default; + +$baseFontSize: 14px !default; +$baseFontFamily: $sansFontFamily !default; +$baseLineHeight: 20px !default; +$altFontFamily: $serifFontFamily !default; -$baseFontSize: 14px !default; -$baseFontFamily: $sansFontFamily !default; -$baseLineHeight: 20px !default; -$altFontFamily: $serifFontFamily !default; +$headingsFontFamily: inherit !default; -$headingsFontFamily: inherit !default; // empty to use BS default, $baseFontFamily -$headingsFontWeight: bold !default; // instead of browser default, bold -$headingsColor: inherit !default; // empty to use BS default, $textColor +// empty to use BS default, $baseFontFamily +$headingsFontWeight: bold !default; +// instead of browser default, bold +$headingsColor: inherit !default; + +// empty to use BS default, $textColor // Tables // ------------------------- -$tableBackground: transparent !default; // overall background-color -$tableBackgroundAccent: #f9f9f9 !default; // for striping -$tableBackgroundHover: #f5f5f5 !default; // for hover -$tableBorder: #ddd !default; // table and cell border +$tableBackground: transparent !default; + +// overall background-color +$tableBackgroundAccent: #f9f9f9 !default; + +// for striping +$tableBackgroundHover: #f5f5f5 !default; + +// for hover +$tableBorder: #ddd !default; +// table and cell border // Buttons // ------------------------- -$btnBackground: $white !default; -$btnBackgroundHighlight: darken($white, 10%) !default; -$btnBorder: #bbb !default; +$btnBackground: $white !default; +$btnBackgroundHighlight: darken($white, 10%) !default; +$btnBorder: #bbb !default; -$btnPrimaryBackground: $linkColor !default; -$btnPrimaryBackgroundHighlight: adjust-hue($btnPrimaryBackground, 20%) !default; +$btnPrimaryBackground: $linkColor !default; +$btnPrimaryBackgroundHighlight: adjust-hue($btnPrimaryBackground, 20%) !default; -$btnInfoBackground: #5bc0de !default; -$btnInfoBackgroundHighlight: #2f96b4 !default; +$btnInfoBackground: #5bc0de !default; +$btnInfoBackgroundHighlight: #2f96b4 !default; -$btnSuccessBackground: #62c462 !default; -$btnSuccessBackgroundHighlight: #51a351 !default; +$btnSuccessBackground: #62c462 !default; +$btnSuccessBackgroundHighlight: #51a351 !default; -$btnWarningBackground: lighten($orange, 15%) !default; -$btnWarningBackgroundHighlight: $orange !default; +$btnWarningBackground: lighten($orange, 15%) !default; +$btnWarningBackgroundHighlight: $orange !default; -$btnDangerBackground: #ee5f5b !default; -$btnDangerBackgroundHighlight: #bd362f !default; - -$btnInverseBackground: #444 !default; -$btnInverseBackgroundHighlight: $grayDarker !default; +$btnDangerBackground: #ee5f5b !default; +$btnDangerBackgroundHighlight: #bd362f !default; +$btnInverseBackground: #444 !default; +$btnInverseBackgroundHighlight: $grayDarker !default; // Forms // ------------------------- -$inputBackground: $white !default; -$inputBorder: #ccc !default; -$inputBorderRadius: 3px !default; -$inputDisabledBackground: $grayLighter !default; -$formActionsBackground: #f5f5f5 !default; -$inputHeight: $baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border +$inputBackground: $white !default; +$inputBorder: #ccc !default; +$inputBorderRadius: 3px !default; +$inputDisabledBackground: $grayLighter !default; +$formActionsBackground: #f5f5f5 !default; +$inputHeight: $baseLineHeight + 10px; + +// base line-height + 8px vertical padding + 2px top/bottom border // Dropdowns // ------------------------- -$dropdownBackground: $white !default; -$dropdownBorder: rgba(0,0,0,.2) !default; -$dropdownDividerTop: #e5e5e5 !default; -$dropdownDividerBottom: $white !default; - -$dropdownLinkColor: $grayDark !default; +$dropdownBackground: $white !default; +$dropdownBorder: rgba(0, 0, 0, 0.2) !default; +$dropdownDividerTop: #e5e5e5 !default; +$dropdownDividerBottom: $white !default; -$dropdownLinkColorActive: $dropdownLinkColor !default; -$dropdownLinkBackgroundActive: $linkColor !default; - -$dropdownLinkColorHover: $white !default; -$dropdownLinkBackgroundHover: $dropdownLinkBackgroundActive !default; +$dropdownLinkColor: $grayDark !default; +$dropdownLinkColorActive: $dropdownLinkColor !default; +$dropdownLinkBackgroundActive: $linkColor !default; +$dropdownLinkColorHover: $white !default; +$dropdownLinkBackgroundHover: $dropdownLinkBackgroundActive !default; // COMPONENT VARIABLES // -------------------------------------------------- @@ -124,155 +129,153 @@ $dropdownLinkBackgroundHover: $dropdownLinkBackgroundActive !default; // ------------------------- // Used for a bird's eye view of components dependent on the z-axis // Try to avoid customizing these :) -$zindexDropdown: 1000 !default; -$zindexPopover: 1010 !default; -$zindexTooltip: 1030 !default; -$zindexFixedNavbar: 1030 !default; -$zindexModalBackdrop: 1040 !default; -$zindexModal: 1050 !default; - +$zindexDropdown: 1000 !default; +$zindexPopover: 1010 !default; +$zindexTooltip: 1030 !default; +$zindexFixedNavbar: 1030 !default; +$zindexModalBackdrop: 1040 !default; +$zindexModal: 1050 !default; // Sprite icons path // ------------------------- // $iconSpritePath: asset-url("glyphicons-halflings.png", image) !default; // $iconWhiteSpritePath: asset-url("glyphicons-halflings-white.png", image) !default; - // Input placeholder text color // ------------------------- -$placeholderText: $grayLight !default; - +$placeholderText: $grayLight !default; // Hr border color // ------------------------- -$hrBorder: $grayLighter !default; - +$hrBorder: $grayLighter !default; // Wells // ------------------------- -$wellBackground: #f5f5f5 !default; - +$wellBackground: #f5f5f5 !default; // Navbar // ------------------------- -$navbarCollapseWidth: 979px !default; +$navbarCollapseWidth: 979px !default; -$navbarHeight: 40px !default; -$navbarBackgroundHighlight: #ffffff !default; -$navbarBackground: darken($navbarBackgroundHighlight, 5%) !default; -$navbarBorder: darken($navbarBackground, 12%) !default; +$navbarHeight: 40px !default; +$navbarBackgroundHighlight: #ffffff !default; +$navbarBackground: darken($navbarBackgroundHighlight, 5%) !default; +$navbarBorder: darken($navbarBackground, 12%) !default; -$navbarText: $gray !default; -$navbarLinkColor: $gray !default; -$navbarLinkColorHover: $grayDark !default; -$navbarLinkColorActive: $gray !default; -$navbarLinkBackgroundHover: transparent !default; -$navbarLinkBackgroundActive: darken($navbarBackground, 5%) !default; +$navbarText: $gray !default; +$navbarLinkColor: $gray !default; +$navbarLinkColorHover: $grayDark !default; +$navbarLinkColorActive: $gray !default; +$navbarLinkBackgroundHover: transparent !default; +$navbarLinkBackgroundActive: darken($navbarBackground, 5%) !default; -$navbarBrandColor: $navbarLinkColor !default; +$navbarBrandColor: $navbarLinkColor !default; // Inverted navbar -$navbarInverseBackground: #111111 !default; -$navbarInverseBackgroundHighlight: #222222 !default; -$navbarInverseBorder: #252525 !default; - -$navbarInverseText: $grayLight !default; -$navbarInverseLinkColor: $grayLight !default; -$navbarInverseLinkColorHover: $white !default; -$navbarInverseLinkColorActive: $navbarInverseLinkColorHover !default; -$navbarInverseLinkBackgroundHover: transparent !default; -$navbarInverseLinkBackgroundActive: $navbarInverseBackground !default; +$navbarInverseBackground: #111111 !default; +$navbarInverseBackgroundHighlight: #222222 !default; +$navbarInverseBorder: #252525 !default; -$navbarInverseSearchBackground: lighten($navbarInverseBackground, 25%) !default; -$navbarInverseSearchBackgroundFocus: $white !default; -$navbarInverseSearchBorder: $navbarInverseBackground !default; -$navbarInverseSearchPlaceholderColor: #ccc !default; +$navbarInverseText: $grayLight !default; +$navbarInverseLinkColor: $grayLight !default; +$navbarInverseLinkColorHover: $white !default; +$navbarInverseLinkColorActive: $navbarInverseLinkColorHover !default; +$navbarInverseLinkBackgroundHover: transparent !default; +$navbarInverseLinkBackgroundActive: $navbarInverseBackground !default; -$navbarInverseBrandColor: $navbarInverseLinkColor !default; +$navbarInverseSearchBackground: lighten($navbarInverseBackground, 25%) !default; +$navbarInverseSearchBackgroundFocus: $white !default; +$navbarInverseSearchBorder: $navbarInverseBackground !default; +$navbarInverseSearchPlaceholderColor: #ccc !default; +$navbarInverseBrandColor: $navbarInverseLinkColor !default; // Pagination // ------------------------- -$paginationBackground: #fff !default; -$paginationBorder: #ddd !default; -$paginationActiveBackground: #f5f5f5 !default; - +$paginationBackground: #fff !default; +$paginationBorder: #ddd !default; +$paginationActiveBackground: #f5f5f5 !default; // Hero unit // ------------------------- -$heroUnitBackground: $grayLighter !default; -$heroUnitHeadingColor: inherit !default; -$heroUnitLeadColor: inherit !default; - +$heroUnitBackground: $grayLighter !default; +$heroUnitHeadingColor: inherit !default; +$heroUnitLeadColor: inherit !default; // Form states and alerts // ------------------------- -$warningText: #c09853 !default; -$warningBackground: #fcf8e3 !default; -$warningBorder: darken(adjust-hue($warningBackground, -10), 3%) !default; +$warningText: #c09853 !default; +$warningBackground: #fcf8e3 !default; +$warningBorder: darken(adjust-hue($warningBackground, -10), 3%) !default; -$errorText: #b94a48 !default; -$errorBackground: #f2dede !default; -$errorBorder: darken(adjust-hue($errorBackground, -10), 3%) !default; +$errorText: #b94a48 !default; +$errorBackground: #f2dede !default; +$errorBorder: darken(adjust-hue($errorBackground, -10), 3%) !default; -$successText: #468847 !default; -$successBackground: #dff0d8 !default; -$successBorder: darken(adjust-hue($successBackground, -10), 5%) !default; - -$infoText: #3a87ad !default; -$infoBackground: #d9edf7 !default; -$infoBorder: darken(adjust-hue($infoBackground, -10), 7%) !default; +$successText: #468847 !default; +$successBackground: #dff0d8 !default; +$successBorder: darken(adjust-hue($successBackground, -10), 5%) !default; +$infoText: #3a87ad !default; +$infoBackground: #d9edf7 !default; +$infoBorder: darken(adjust-hue($infoBackground, -10), 7%) !default; // Tooltips and popovers // ------------------------- -$tooltipColor: #fff !default; -$tooltipBackground: #000 !default; -$tooltipArrowWidth: 5px !default; -$tooltipArrowColor: $tooltipBackground !default; +$tooltipColor: #fff !default; +$tooltipBackground: #000 !default; +$tooltipArrowWidth: 5px !default; +$tooltipArrowColor: $tooltipBackground !default; -$popoverBackground: #fff !default; -$popoverArrowWidth: 10px !default; -$popoverArrowColor: #fff !default; -$popoverTitleBackground: darken($popoverBackground, 3%) !default; +$popoverBackground: #fff !default; +$popoverArrowWidth: 10px !default; +$popoverArrowColor: #fff !default; +$popoverTitleBackground: darken($popoverBackground, 3%) !default; // Special enhancement for popovers -$popoverArrowOuterWidth: $popoverArrowWidth + 1 !default; -$popoverArrowOuterColor: rgba(0,0,0,.25) !default; - - +$popoverArrowOuterWidth: $popoverArrowWidth + 1 !default; +$popoverArrowOuterColor: rgba(0, 0, 0, 0.25) !default; // GRID // -------------------------------------------------- - // Default 940px grid // ------------------------- -$gridColumns: 12 !default; -$gridColumnWidth: 60px !default; -$gridGutterWidth: 20px !default; -$gridRowWidth: ($gridColumns * $gridColumnWidth) + ($gridGutterWidth * ($gridColumns - 1)) !default; +$gridColumns: 12 !default; +$gridColumnWidth: 60px !default; +$gridGutterWidth: 20px !default; +$gridRowWidth: $gridColumns * $gridColumnWidth + $gridGutterWidth * + ($gridColumns - 1) !default; // 1200px min -$gridColumnWidth1200: 70px !default; -$gridGutterWidth1200: 30px !default; -$gridRowWidth1200: ($gridColumns * $gridColumnWidth1200) + ($gridGutterWidth1200 * ($gridColumns - 1)) !default; +$gridColumnWidth1200: 70px !default; +$gridGutterWidth1200: 30px !default; +$gridRowWidth1200: $gridColumns * $gridColumnWidth1200 + $gridGutterWidth1200 * + ($gridColumns - 1) !default; // 768px-979px -$gridColumnWidth768: 42px !default; -$gridGutterWidth768: 20px !default; -$gridRowWidth768: ($gridColumns * $gridColumnWidth768) + ($gridGutterWidth768 * ($gridColumns - 1)) !default; - +$gridColumnWidth768: 42px !default; +$gridGutterWidth768: 20px !default; +$gridRowWidth768: $gridColumns * $gridColumnWidth768 + $gridGutterWidth768 * + ($gridColumns - 1) !default; // Fluid grid // ------------------------- -$fluidGridColumnWidth: percentage($gridColumnWidth/$gridRowWidth) !default; -$fluidGridGutterWidth: percentage($gridGutterWidth/$gridRowWidth) !default; +$fluidGridColumnWidth: percentage($gridColumnWidth / $gridRowWidth) !default; +$fluidGridGutterWidth: percentage($gridGutterWidth / $gridRowWidth) !default; // 1200px min -$fluidGridColumnWidth1200: percentage($gridColumnWidth1200/$gridRowWidth1200) !default; -$fluidGridGutterWidth1200: percentage($gridGutterWidth1200/$gridRowWidth1200) !default; +$fluidGridColumnWidth1200: percentage( + $gridColumnWidth1200 / $gridRowWidth1200 +) !default; +$fluidGridGutterWidth1200: percentage( + $gridGutterWidth1200 / $gridRowWidth1200 +) !default; // 768px-979px -$fluidGridColumnWidth768: percentage($gridColumnWidth768/$gridRowWidth768) !default; -$fluidGridGutterWidth768: percentage($gridGutterWidth768/$gridRowWidth768) !default; \ No newline at end of file +$fluidGridColumnWidth768: percentage( + $gridColumnWidth768 / $gridRowWidth768 +) !default; +$fluidGridGutterWidth768: percentage( + $gridGutterWidth768 / $gridRowWidth768 +) !default; diff --git a/app/assets/stylesheets/legacy_includes/embed_form_styles.scss b/app/assets/stylesheets/legacy_includes/embed_form_styles.scss index a0516e3561..108da1f2f2 100644 --- a/app/assets/stylesheets/legacy_includes/embed_form_styles.scss +++ b/app/assets/stylesheets/legacy_includes/embed_form_styles.scss @@ -2,80 +2,82 @@ // Variables // -------------------------------------------------- - // Global values // -------------------------------------------------- - // Grays // ------------------------- -$black: #000 !default; -$grayDarker: #222 !default; -$grayDark: #333 !default; -$gray: #555 !default; -$grayLight: #999 !default; -$grayLighter: #eee !default; -$white: #fff !default; - +$black: #000 !default; +$grayDarker: #222 !default; +$grayDark: #333 !default; +$gray: #555 !default; +$grayLight: #999 !default; +$grayLighter: #eee !default; +$white: #fff !default; // Links // ------------------------- // $linkColor: #08c !default; // $linkColorHover: darken($linkColor, 15%) !default; - // Typography // ------------------------- -$sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif !default; -$serifFontFamily: Georgia, "Times New Roman", Times, serif !default; -$monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace !default; +$sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif !default; +$serifFontFamily: Georgia, "Times New Roman", Times, serif !default; +$monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace !default; + +$baseFontSize: 14px !default; +$baseFontFamily: $sansFontFamily !default; +$baseLineHeight: 20px !default; +$altFontFamily: $serifFontFamily !default; -$baseFontSize: 14px !default; -$baseFontFamily: $sansFontFamily !default; -$baseLineHeight: 20px !default; -$altFontFamily: $serifFontFamily !default; +$headingsFontFamily: inherit !default; -$headingsFontFamily: inherit !default; // empty to use BS default, $baseFontFamily -$headingsFontWeight: bold !default; // instead of browser default, bold -$headingsColor: inherit !default; // empty to use BS default, $textColor +// empty to use BS default, $baseFontFamily +$headingsFontWeight: bold !default; +// instead of browser default, bold +$headingsColor: inherit !default; + +// empty to use BS default, $textColor // Forms // ------------------------- -$inputBackground: $white !default; -$inputBorder: #ccc !default; -$inputBorderRadius: 3px !default; -$inputDisabledBackground: $grayLighter !default; -$formActionsBackground: #f5f5f5 !default; -$inputHeight: $baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border +$inputBackground: $white !default; +$inputBorder: #ccc !default; +$inputBorderRadius: 3px !default; +$inputDisabledBackground: $grayLighter !default; +$formActionsBackground: #f5f5f5 !default; +$inputHeight: $baseLineHeight + 10px; + +// base line-height + 8px vertical padding + 2px top/bottom border // Input placeholder text color // ------------------------- -$placeholderText: $grayLight !default; +$placeholderText: $grayLight !default; // Form states and alerts // ------------------------- -$warningText: #c09853 !default; -$warningBackground: #fcf8e3 !default; -$warningBorder: darken(adjust-hue($warningBackground, -10), 3%) !default; +$warningText: #c09853 !default; +$warningBackground: #fcf8e3 !default; +$warningBorder: darken(adjust-hue($warningBackground, -10), 3%) !default; -$errorText: #b94a48 !default; -$errorBackground: #f2dede !default; -$errorBorder: darken(adjust-hue($errorBackground, -10), 3%) !default; +$errorText: #b94a48 !default; +$errorBackground: #f2dede !default; +$errorBorder: darken(adjust-hue($errorBackground, -10), 3%) !default; -$successText: #468847 !default; -$successBackground: #dff0d8 !default; -$successBorder: darken(adjust-hue($successBackground, -10), 5%) !default; +$successText: #468847 !default; +$successBackground: #dff0d8 !default; +$successBorder: darken(adjust-hue($successBackground, -10), 5%) !default; -$infoText: #3a87ad !default; -$infoBackground: #d9edf7 !default; -$infoBorder: darken(adjust-hue($infoBackground, -10), 7%) !default; +$infoText: #3a87ad !default; +$infoBackground: #d9edf7 !default; +$infoBorder: darken(adjust-hue($infoBackground, -10), 7%) !default; // // Forms // -------------------------------------------------- - // GENERAL STYLES // -------------- @@ -104,7 +106,7 @@ legend { // Small small { - font-size: $baseLineHeight * .75; + font-size: $baseLineHeight * 0.75; color: $grayLight; } } @@ -115,13 +117,18 @@ input, button, select, textarea { - @include font-shorthand($baseFontSize,normal,$baseLineHeight); // Set size, weight, line-height here + @include font-shorthand($baseFontSize, normal, $baseLineHeight); + + // Set size, weight, line-height here } + input, button, select, textarea { - font-family: $baseFontFamily; // And only set font-family here for those that need it (note the missing label element) + font-family: $baseFontFamily; + + // And only set font-family here for those that need it (note the missing label element) } // Identify controls by their labels @@ -159,6 +166,7 @@ input[type="color"], font-size: $baseFontSize; line-height: $baseLineHeight; color: $gray; + @include border-radius($inputBorderRadius); } @@ -168,10 +176,12 @@ input, textarea { width: 210px; } + // Reset height since textareas have rows textarea { height: auto; } + // Everything else textarea, input[type="text"], @@ -191,15 +201,22 @@ input[type="color"], .uneditable-input { background-color: $inputBackground; border: 1px solid $inputBorder; - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); - @include transition(#{border linear .2s, box-shadow linear .2s}); + + @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, 0.075)); + + @include transition(#{border linear 0.2s, box-shadow linear 0.2s}); // Focus state &:focus { - border-color: rgba(82,168,236,.8); + border-color: rgba(82, 168, 236, 0.8); outline: 0; - outline: thin dotted \9; /* IE6-9 */ - @include box-shadow(#{inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)}); + outline: thin dotted \9; + + /* IE6-9 */ + @include box-shadow( + #{inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(82, 168, 236, 0.6)} + ); } } @@ -207,8 +224,12 @@ input[type="color"], input[type="radio"], input[type="checkbox"] { margin: 4px 0 0; - *margin-top: 0; /* IE7 */ - margin-top: 1px \9; /* IE8-9 */ + *margin-top: 0; + + /* IE7 */ + margin-top: 1px \9; + + /* IE8-9 */ line-height: normal; cursor: pointer; } @@ -221,22 +242,32 @@ input[type="reset"], input[type="button"], input[type="radio"], input[type="checkbox"] { - width: auto; // Override of generic input selector + width: auto; + + // Override of generic input selector } // Set the height of select and file controls to match text inputs select, input[type="file"] { - height: 30px; /* In IE7, the height of the select element cannot be changed by height, only font-size */ - *margin-top: 4px; /* For IE7, add top margin to align select with labels */ + height: 30px; + + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + *margin-top: 4px; + + /* For IE7, add top margin to align select with labels */ line-height: 30px; } // Make select elements obey height by applying a border select { - width: 220px; // default input width + 10px of padding that doesn't get applied + width: 220px; + + // default input width + 10px of padding that doesn't get applied border: 1px solid #bbb; - background-color: $inputBackground; // Chrome on Linux and Mobile Safari need background-color + background-color: $inputBackground; + + // Chrome on Linux and Mobile Safari need background-color } // Make multiple select elements height not fixed @@ -250,10 +281,9 @@ select:focus, input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { - @include tab-focus(); + @include tab-focus; } - // Uneditable inputs // ------------------------- @@ -263,13 +293,17 @@ input[type="checkbox"]:focus { color: $grayLight; background-color: darken($inputBackground, 1%); border-color: $inputBorder; - @include box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); + + @include box-shadow(inset 0 1px 2px rgba(0, 0, 0, 0.025)); + cursor: not-allowed; } // For text that needs to appear as an input but should not be an input .uneditable-input { - overflow: hidden; // prevent text from wrapping, but still cut it off like an input does + overflow: hidden; + + // prevent text from wrapping, but still cut it off like an input does white-space: nowrap; } @@ -279,26 +313,27 @@ input[type="checkbox"]:focus { height: auto; } - // Placeholder // ------------------------- // Placeholder text gets special styles; can't be bundled together though for some reason input, textarea { - @include placeholder(); + @include placeholder; } - // CHECKBOXES & RADIOS // ------------------- // Indent the labels to position radios/checkboxes as hanging .radio, .checkbox { - min-height: 18px; // clear the floating input if there is no label text + min-height: 18px; + + // clear the floating input if there is no label text padding-left: 18px; } + .radio input[type="radio"], .checkbox input[type="checkbox"] { float: left; @@ -308,7 +343,9 @@ textarea { // Move the options list down to align with labels .controls > .radio:first-child, .controls > .checkbox:first-child { - padding-top: 5px; // has to be padding because margin collaspes + padding-top: 5px; + + // has to be padding because margin collaspes } // Radios and checkboxes on same line @@ -320,30 +357,47 @@ textarea { margin-bottom: 0; vertical-align: middle; } + .radio.inline + .radio.inline, .checkbox.inline + .checkbox.inline { - margin-left: 10px; // space out consecutive inline controls -} - + margin-left: 10px; + // space out consecutive inline controls +} // INPUT SIZES // ----------- // General classes for quick sizes -.input-mini { width: 60px; } -.input-small { width: 90px; } -.input-medium { width: 150px; } -.input-large { width: 210px; } -.input-xlarge { width: 270px; } -.input-xxlarge { width: 530px; } +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} // Grid style input sizes input[class*="span"], select[class*="span"], textarea[class*="span"], .uneditable-input[class*="span"], -// Redeclare since the fluid row class is more specific .row-fluid input[class*="span"], .row-fluid select[class*="span"], .row-fluid textarea[class*="span"], @@ -351,6 +405,7 @@ textarea[class*="span"], float: none; margin-left: 0; } + // Ensure input-prepend/append never wraps .input-append input[class*="span"], .input-append .uneditable-input[class*="span"], @@ -365,21 +420,21 @@ textarea[class*="span"], display: inline-block; } - - // GRID SIZING FOR INPUTS // ---------------------- // Control row for multiple inputs per line .controls-row { - @include clearfix(); // Clear the float from controls -} -.controls-row [class*="span"] { - float: left; // Float to collapse white-space for proper grid alignment -} + @include clearfix; + // Clear the float from controls +} +.controls-row [class*="span"] { + float: left; + // Float to collapse white-space for proper grid alignment +} // DISABLED STATE // -------------- @@ -394,6 +449,7 @@ textarea[readonly] { cursor: not-allowed; background-color: $inputDisabledBackground; } + // Explicitly reset the colors here input[type="radio"][disabled], input[type="checkbox"][disabled], @@ -402,9 +458,6 @@ input[type="checkbox"][readonly] { background-color: transparent; } - - - // FORM FIELD FEEDBACK STATES // -------------------------- @@ -412,10 +465,12 @@ input[type="checkbox"][readonly] { .control-group.warning { @include formFieldState($warningText, $warningText, $warningBackground); } + // Error .control-group.error { @include formFieldState($errorText, $errorText, $errorBackground); } + // Success .control-group.success { @include formFieldState($successText, $successText, $successBackground); @@ -428,14 +483,14 @@ textarea:focus:required:invalid, select:focus:required:invalid { color: #b94a48; border-color: #ee5f5b; + &:focus { border-color: darken(#ee5f5b, 10%); + @include box-shadow(0 0 6px lighten(#ee5f5b, 20%)); } } - - // FORM ACTIONS // ------------ @@ -445,34 +500,39 @@ select:focus:required:invalid { margin-bottom: $baseLineHeight; background-color: $formActionsBackground; border-top: 1px solid #e5e5e5; - @include clearfix(); // Adding clearfix to allow for .pull-right button containers -} + @include clearfix; + // Adding clearfix to allow for .pull-right button containers +} // HELP TEXT // --------- .help-block, .help-inline { - color: $grayLight; // lighten the text some for contrast - font-size: .8em; + color: $grayLight; + + // lighten the text some for contrast + font-size: 0.8em; } .help-block { - display: block; // account for any element using help-block + display: block; + + // account for any element using help-block margin-bottom: $baseLineHeight / 2; } .help-inline { display: inline-block; - @include ie7-inline-block(); + + @include ie7-inline-block; + vertical-align: middle; padding-left: 5px; } - - // INPUT GROUPS // ------------ @@ -481,29 +541,40 @@ select:focus:required:invalid { .input-prepend { margin-bottom: 5px; font-size: 0; - white-space: nowrap; // Prevent span and input from separating + white-space: nowrap; + + // Prevent span and input from separating input, select, .uneditable-input { - position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness - margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms + position: relative; + + // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness + margin-bottom: 0; + + // prevent bottom margin from screwing up alignment in stacked forms *margin-left: 0; font-size: $baseFontSize; vertical-align: top; + @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); + // Make input on top when focused so blue border and shadow always show &:focus { z-index: 2; } } + .add-on { display: inline-block; width: auto; height: auto; + // height: $baseLineHeight; min-width: 16px; padding: 4px 5px; + // font-size: $standardFontSize; font-weight: normal; text-align: center; @@ -512,38 +583,46 @@ select:focus:required:invalid { color: $textColor; border: 1px solid #ccc; } + .add-on, .btn { margin-left: -1px; vertical-align: top; + @include border-radius(0); } + .active { background-color: lighten($green, 30); border-color: $green; } } + .input-prepend { .add-on, .btn { margin-right: -1px; } + .add-on:first-child, .btn:first-child { @include border-radius($inputBorderRadius 0 0 $inputBorderRadius); } } + .input-append { input, select, .uneditable-input { @include border-radius($inputBorderRadius 0 0 $inputBorderRadius); } + .add-on:last-child, .btn:last-child { @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); } } + // Remove all border-radius for inputs with both prepend and append .input-prepend.input-append { input, @@ -551,20 +630,22 @@ select:focus:required:invalid { .uneditable-input { @include border-radius(0); } + .add-on:first-child, .btn:first-child { margin-right: -1px; + @include border-radius($inputBorderRadius 0 0 $inputBorderRadius); } + .add-on:last-child, .btn:last-child { margin-left: -1px; + @include border-radius(0 $inputBorderRadius $inputBorderRadius 0); } } - - // SEARCH FORM // ----------- @@ -572,32 +653,39 @@ input.search-query { padding-right: 14px; padding-right: 4px \9; padding-left: 14px; - padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ - margin-bottom: 0; // Remove the default margin on all inputs + padding-left: 4px \9; + + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + margin-bottom: 0; + + // Remove the default margin on all inputs @include border-radius(15px); } /* Allow for input prepend/append in search forms */ .form-search .input-append .search-query, .form-search .input-prepend .search-query { - @include border-radius(0); // Override due to specificity + @include border-radius(0); + + // Override due to specificity } + .form-search .input-append .search-query { - @include border-radius(14px 0 0 14px) + @include border-radius(14px 0 0 14px); } + .form-search .input-append .btn { - @include border-radius(0 14px 14px 0) + @include border-radius(0 14px 14px 0); } + .form-search .input-prepend .search-query { - @include border-radius(0 14px 14px 0) + @include border-radius(0 14px 14px 0); } + .form-search .input-prepend .btn { - @include border-radius(14px 0 0 14px) + @include border-radius(14px 0 0 14px); } - - - // HORIZONTAL & VERTICAL FORMS // --------------------------- @@ -615,21 +703,26 @@ input.search-query { .input-prepend, .input-append { display: inline-block; - @include ie7-inline-block(); + + @include ie7-inline-block; + margin-bottom: 0; vertical-align: middle; } + // Re-hide hidden elements due to specifity .hide { display: none; } } + .form-search label, .form-inline label, .form-search .btn-group, .form-inline .btn-group { display: inline-block; } + // Remove margin for input-prepend/-append .form-search .input-append, .form-inline .input-append, @@ -637,6 +730,7 @@ input.search-query { .form-inline .input-prepend { margin-bottom: 0; } + // Inline checkbox/radio labels (remove padding on left) .form-search .radio, .form-search .checkbox, @@ -646,6 +740,7 @@ input.search-query { margin-bottom: 0; vertical-align: middle; } + // Remove float and margin, set to inline-block .form-search .radio input[type="radio"], .form-search .checkbox input[type="checkbox"], @@ -656,7 +751,6 @@ input.search-query { margin-left: 0; } - // Margin to space out fieldsets .control-group { margin-bottom: $baseLineHeight / 2; @@ -675,8 +769,10 @@ legend + .control-group { // Increase spacing between groups .control-group { margin-bottom: $baseLineHeight; - @include clearfix(); + + @include clearfix; } + // Float the labels left .control-label { float: left; @@ -684,6 +780,7 @@ legend + .control-group { padding-top: 5px; text-align: right; } + // Move over all input controls and content .controls { // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend @@ -692,17 +789,20 @@ legend + .control-group { *padding-left: 20px; margin-left: 160px; *margin-left: 0; + &:first-child { *padding-left: 160px; } } + // Remove bottom margin on block level help text since that's accounted for on .control-group .help-block { margin-top: $baseLineHeight / 2; margin-bottom: 0; } + // Move over buttons in .form-actions to align with .controls .form-actions { padding-left: 160px; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/legacy_includes/selectize_bootstrap3.scss b/app/assets/stylesheets/legacy_includes/selectize_bootstrap3.scss index 9013bf12bd..77842551d6 100644 --- a/app/assets/stylesheets/legacy_includes/selectize_bootstrap3.scss +++ b/app/assets/stylesheets/legacy_includes/selectize_bootstrap3.scss @@ -5,11 +5,14 @@ */ body .selectize-dropdown [data-selectable] .highlight { - background: rgba(#3498DB, 0.2); // Bike Index blue ;) -} + background: rgba(#3498db, 0.2); -body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } + // Bike Index blue ;) +} +body .selectize-dropdown .active { + background-color: lighten(#bebebe, 10%); +} /** * selectize.bootstrap3.css (v0.12.1) - Bootstrap 3 Theme @@ -26,7 +29,9 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } * * @author Brian Reavis */ -.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { +.selectize-control.plugin-drag_drop.multi + > .selectize-input + > div.ui-sortable-placeholder { visibility: visible !important; background: #f2f2f2 !important; background: rgba(0, 0, 0, 0.06) !important; @@ -34,14 +39,17 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -webkit-box-shadow: inset 0 0 12px 4px #ffffff; box-shadow: inset 0 0 12px 4px #ffffff; } + .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { - content: '!'; + content: "!"; visibility: hidden; } + .selectize-control.plugin-drag_drop .ui-sortable-helper { -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } + .selectize-dropdown-header { position: relative; padding: 3px 12px; @@ -51,6 +59,7 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -moz-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; } + .selectize-dropdown-header-close { position: absolute; right: 12px; @@ -61,9 +70,11 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } line-height: 20px; font-size: 20px !important; } + .selectize-dropdown-header-close:hover { color: #000000; } + .selectize-dropdown.plugin-optgroup_columns .optgroup { border-right: 1px solid #f2f2f2; border-top: 0 none; @@ -72,21 +83,27 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -moz-box-sizing: border-box; box-sizing: border-box; } + .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { border-right: 0 none; } + .selectize-dropdown.plugin-optgroup_columns .optgroup:before { display: none; } + .selectize-dropdown.plugin-optgroup_columns .optgroup-header { border-top: 0 none; } + .selectize-control.plugin-remove_button [data-value] { position: relative; padding-right: 24px !important; } + .selectize-control.plugin-remove_button [data-value] .remove { z-index: 1; + /* fixes ie bug (see #392) */ position: absolute; top: 0; @@ -109,21 +126,27 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -moz-box-sizing: border-box; box-sizing: border-box; } + .selectize-control.plugin-remove_button [data-value] .remove:hover { background: rgba(0, 0, 0, 0.05); } + .selectize-control.plugin-remove_button [data-value].active .remove { border-left-color: rgba(0, 0, 0, 0); } + .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { background: none; } + .selectize-control.plugin-remove_button .disabled [data-value] .remove { border-left-color: rgba(77, 77, 77, 0); } + .selectize-control { position: relative; } + .selectize-dropdown, .selectize-input, .selectize-input input { @@ -133,12 +156,14 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } line-height: 20px; -webkit-font-smoothing: inherit; } + .selectize-input, .selectize-control.single .selectize-input.input-active { background: #ffffff; cursor: text; display: inline-block; } + .selectize-input { border: 1px solid #cccccc; padding: 6px 12px; @@ -156,25 +181,31 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -moz-border-radius: 4px; border-radius: 4px; } + .selectize-control.multi .selectize-input.has-items { padding: 5px 12px 2px; } + .selectize-input.full { background-color: #ffffff; } + .selectize-input.disabled, .selectize-input.disabled * { cursor: default !important; } + .selectize-input.focus { -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); } + .selectize-input.dropdown-active { -webkit-border-radius: 4px 4px 0 0; -moz-border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0; } + .selectize-input > * { vertical-align: baseline; display: -moz-inline-stack; @@ -182,6 +213,7 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } zoom: 1; *display: inline; } + .selectize-control.multi .selectize-input > div { cursor: pointer; margin: 0 3px 3px 0; @@ -190,17 +222,20 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } color: #333333; border: 0 solid rgba(0, 0, 0, 0); } + .selectize-control.multi .selectize-input > div.active { background: #428bca; color: #ffffff; border: 0 solid rgba(0, 0, 0, 0); } + .selectize-control.multi .selectize-input.disabled > div, .selectize-control.multi .selectize-input.disabled > div.active { color: #808080; background: #ffffff; border: 0 solid rgba(77, 77, 77, 0); } + .selectize-input > input { display: inline-block !important; padding: 0 !important; @@ -216,19 +251,23 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -webkit-box-shadow: none !important; box-shadow: none !important; } + .selectize-input > input::-ms-clear { display: none; } + .selectize-input > input:focus { outline: none !important; } + .selectize-input::after { - content: ' '; + content: " "; display: block; clear: left; } + .selectize-input.dropdown-active::before { - content: ' '; + content: " "; display: block; position: absolute; background: #ffffff; @@ -237,6 +276,7 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } left: 0; right: 0; } + .selectize-dropdown { position: absolute; z-index: 10; @@ -253,53 +293,65 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -moz-border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px; } + .selectize-dropdown [data-selectable] { cursor: pointer; overflow: hidden; } + .selectize-dropdown [data-selectable] .highlight { background: rgba(255, 237, 40, 0.4); -webkit-border-radius: 1px; -moz-border-radius: 1px; border-radius: 1px; } + .selectize-dropdown [data-selectable], .selectize-dropdown .optgroup-header { padding: 3px 12px; } + .selectize-dropdown .optgroup:first-child .optgroup-header { border-top: 0 none; } + .selectize-dropdown .optgroup-header { color: #777777; background: #ffffff; cursor: default; } + .selectize-dropdown .active { background-color: #f5f5f5; color: #262626; } + .selectize-dropdown .active.create { color: #262626; } + .selectize-dropdown .create { color: rgba(51, 51, 51, 0.5); } + .selectize-dropdown-content { overflow-y: auto; overflow-x: hidden; max-height: 200px; } + .selectize-control.single .selectize-input, .selectize-control.single .selectize-input input { cursor: pointer; } + .selectize-control.single .selectize-input.input-active, .selectize-control.single .selectize-input.input-active input { cursor: text; } + .selectize-control.single .selectize-input:after { - content: ' '; + content: " "; display: block; position: absolute; top: 50%; @@ -311,22 +363,27 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } border-width: 5px 5px 0 5px; border-color: #333333 transparent transparent transparent; } + .selectize-control.single .selectize-input.dropdown-active:after { margin-top: -4px; border-width: 0 5px 5px 5px; border-color: transparent transparent #333333 transparent; } + .selectize-control.rtl.single .selectize-input:after { left: 17px; right: auto; } + .selectize-control.rtl .selectize-input > input { margin: 0 4px 0 -2px !important; } + .selectize-control .selectize-input.disabled { opacity: 0.5; background-color: #ffffff; } + .selectize-dropdown, .selectize-dropdown.form-control { height: auto; @@ -342,15 +399,18 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); } + .selectize-dropdown .optgroup-header { font-size: 12px; line-height: 1.42857143; } + .selectize-dropdown .optgroup:first-child:before { display: none; } + .selectize-dropdown .optgroup:before { - content: ' '; + content: " "; display: block; height: 1px; margin: 9px 0; @@ -359,48 +419,61 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } margin-left: -12px; margin-right: -12px; } + .selectize-dropdown-content { padding: 5px 0; } + .selectize-dropdown-header { padding: 6px 12px; } + .selectize-input { min-height: 34px; } + .selectize-input.dropdown-active { -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } + .selectize-input.dropdown-active::before { display: none; } + .selectize-input.focus { 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); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), + 0 0 8px rgba(102, 175, 233, 0.6); } + .has-error .selectize-input { border-color: #a94442; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } + .has-error .selectize-input:focus { border-color: #843534; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483; } + .selectize-control.multi .selectize-input.has-items { padding-left: 9px; padding-right: 9px; } + .selectize-control.multi .selectize-input > div { -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; } + .form-control.selectize-control { padding: 0; height: auto; @@ -411,4 +484,4 @@ body .selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -webkit-border-radius: 0; -moz-border-radius: 0; border-radius: 0; -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/legacy_includes/slick.scss b/app/assets/stylesheets/legacy_includes/slick.scss index dd97201603..3ec25e2a4a 100644 --- a/app/assets/stylesheets/legacy_includes/slick.scss +++ b/app/assets/stylesheets/legacy_includes/slick.scss @@ -8,144 +8,147 @@ $slick-loader-path: "/assets/" !default; $slick-arrow-color: white !default; $slick-dot-color: black !default; $slick-dot-color-active: $slick-dot-color !default; -$slick-prev-character: '<' !default; -$slick-next-character: '>' !default; -$slick-dot-character: '\2022' !default; +$slick-prev-character: "<" !default; +$slick-next-character: ">" !default; +$slick-dot-character: "•" !default; $slick-dot-size: 6px !default; -$slick-opacity-default: .75 !default; +$slick-opacity-default: 0.75 !default; $slick-opacity-on-hover: 1 !default; -$slick-opacity-not-active: .25 !default; - +$slick-opacity-not-active: 0.25 !default; @function slick-image-url($url) { @if function-exists(image-url) { @return image-url($url); - } - @else { - @return url($slick-loader-path + $url); + } @else { + @return url($slick-loader-path+$url); } } @function slick-font-url($url) { @if function-exists(font-url) { @return font-url($url); - } - @else { - @return url($slick-font-path + $url); + } @else { + @return url($slick-font-path+$url); } } /* Slider */ .slick-slider { - position: relative; - display: block; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -ms-touch-action: pan-y; - touch-action: pan-y; - -webkit-tap-highlight-color: transparent; + position: relative; + display: block; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -ms-touch-action: pan-y; + touch-action: pan-y; + -webkit-tap-highlight-color: transparent; } + .slick-list { - position: relative; - overflow: hidden; - display: block; - margin: 0; - padding: 0; + position: relative; + overflow: hidden; + display: block; + margin: 0; + padding: 0; - &:focus { - outline: none; - } + &:focus { + outline: none; + } - .slick-loading & { - background: #fff slick-image-url("ajax-loader.gif") center center no-repeat; - } + .slick-loading & { + background: #fff slick-image-url("ajax-loader.gif") center center no-repeat; + } - &.dragging { - cursor: pointer; - cursor: hand; - } + &.dragging { + cursor: pointer; + cursor: hand; + } } + .slick-slider .slick-track { - -webkit-transform: translate3d(0, 0, 0); - -moz-transform: translate3d(0, 0, 0); - -ms-transform: translate3d(0, 0, 0); - -o-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); } .slick-track { - position: relative; - left: 0; - top: 0; - display: block; + position: relative; + left: 0; + top: 0; + display: block; - &:before, - &:after { - content: ""; - display: table; - } + &:before, + &:after { + content: ""; + display: table; + } - &:after { - clear: both; - } + &:after { + clear: both; + } - .slick-loading & { - visibility: hidden; - } + .slick-loading & { + visibility: hidden; + } } + .slick-slide { - float: left; - height: 100%; - min-height: 1px; - [dir="rtl"] & { - float: right; - } - img { - display: block; - } - &.slick-loading img { - display: none; - } + float: left; + height: 100%; + min-height: 1px; + + [dir="rtl"] & { + float: right; + } + + img { + display: block; + } + &.slick-loading img { display: none; + } - &.dragging img { - pointer-events: none; - } + display: none; - .slick-initialized & { - display: block; - } + &.dragging img { + pointer-events: none; + } - .slick-loading & { - visibility: hidden; - } + .slick-initialized & { + display: block; + } - .slick-vertical & { - display: block; - height: auto; - border: 1px solid transparent; - } + .slick-loading & { + visibility: hidden; + } + + .slick-vertical & { + display: block; + height: auto; + border: 1px solid transparent; + } } /* Icons */ @if $slick-font-family == "slick" { @font-face { - font-family:"slick"; - src: slick-font-url("slick.eot"); - src: slick-font-url("slick.eot?#iefix") format("embedded-opentype"), - slick-font-url("slick.woff") format("woff"), - slick-font-url("slick.ttf") format("truetype"), - slick-font-url("slick.svg#slick") format("svg"); - font-weight: normal; - font-style: normal; + font-family: "slick"; + src: slick-font-url("slick.eot"); + src: slick-font-url("slick.eot?#iefix") format("embedded-opentype"), + slick-font-url("slick.woff") format("woff"), + slick-font-url("slick.ttf") format("truetype"), + slick-font-url("slick.svg#slick") format("svg"); + font-weight: normal; + font-style: normal; } } @@ -153,134 +156,149 @@ $slick-opacity-not-active: .25 !default; .slick-prev, .slick-next { - position: absolute; - display: block; - height: 40px; - width: 20px; - line-height: 0; - font-size: 0; - cursor: pointer; + position: absolute; + display: block; + height: 40px; + width: 20px; + line-height: 0; + font-size: 0; + cursor: pointer; + background: transparent; + color: transparent; + top: 50%; + margin-top: -20px; + padding: 0; + border: none; + outline: none; + + &:hover, + &:focus { + outline: none; background: transparent; color: transparent; - top: 50%; - margin-top: -20px; - padding: 0; - border: none; - outline: none; - &:hover, &:focus { - outline: none; - background: transparent; - color: transparent; - &:before { - opacity: $slick-opacity-on-hover; - } - } - &.slick-disabled { - opacity: 0; + &:before { + opacity: $slick-opacity-on-hover; } + } + + &.slick-disabled { + opacity: 0; + } } -.slick-prev:before, .slick-next:before { - font-family: $slick-font-family; - font-size: 40px; - line-height: 1; - color: $slick-arrow-color; - opacity: $slick-opacity-default; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; +.slick-prev:before, +.slick-next:before { + font-family: $slick-font-family; + font-size: 40px; + line-height: 1; + color: $slick-arrow-color; + opacity: $slick-opacity-default; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + .slick-prev { - left: -25px; + left: -25px; + + [dir="rtl"] & { + left: auto; + right: -25px; + } + + &:before { + content: $slick-prev-character; + [dir="rtl"] & { - left: auto; - right: -25px; - } - &:before { - content: $slick-prev-character; - [dir="rtl"] & { - content: $slick-next-character; - } + content: $slick-next-character; } + } } + .slick-next { - right: -25px; + right: -25px; + + [dir="rtl"] & { + left: -25px; + right: auto; + } + + &:before { + content: $slick-next-character; + [dir="rtl"] & { - left: -25px; - right: auto; - } - &:before { - content: $slick-next-character; - [dir="rtl"] & { - content: $slick-prev-character; - } + content: $slick-prev-character; } + } } /* Dots */ .slick-slider { - margin-bottom: 30px; + margin-bottom: 30px; } + .slick-dots { - position: absolute; - bottom: -45px; - list-style: none; - display: block; - text-align: center; + position: absolute; + bottom: -45px; + list-style: none; + display: block; + text-align: center; + padding: 0; + width: 100%; + + li { + position: relative; + display: inline-block; + height: 20px; + width: 20px; + margin: 0 5px; padding: 0; - width: 100%; + cursor: pointer; - li { - position: relative; - display: inline-block; - height: 20px; - width: 20px; - margin: 0 5px; - padding: 0; - cursor: pointer; - - button { - border: 0; - background: transparent; - display: block; - height: 20px; - width: 20px; - outline: none; - line-height: 0; - font-size: 0; - color: transparent; - padding: 5px; - cursor: pointer; - &:hover, &:focus { - outline: none; - &:before { - opacity: $slick-opacity-on-hover; - } - } - - &:before { - position: absolute; - top: 0; - left: 0; - content: $slick-dot-character; - width: 20px; - height: 20px; - font-family: $slick-font-family; - font-size: $slick-dot-size; - line-height: 20px; - text-align: center; - color: $slick-dot-color; - opacity: $slick-opacity-not-active; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } + button { + border: 0; + background: transparent; + display: block; + height: 20px; + width: 20px; + outline: none; + line-height: 0; + font-size: 0; + color: transparent; + padding: 5px; + cursor: pointer; - } + &:hover, + &:focus { + outline: none; - &.slick-active button:before { - color: $slick-dot-color-active; - opacity: $slick-opacity-default; + &:before { + opacity: $slick-opacity-on-hover; } + } + + &:before { + position: absolute; + top: 0; + left: 0; + content: $slick-dot-character; + width: 20px; + height: 20px; + font-family: $slick-font-family; + font-size: $slick-dot-size; + line-height: 20px; + text-align: center; + color: $slick-dot-color; + opacity: $slick-opacity-not-active; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + } + + &.slick-active button:before { + color: $slick-dot-color-active; + opacity: $slick-opacity-default; } -} \ No newline at end of file + } +} diff --git a/app/assets/stylesheets/legacy_includes/zoom.scss b/app/assets/stylesheets/legacy_includes/zoom.scss index 3cdc3b5755..4d40e721d1 100644 --- a/app/assets/stylesheets/legacy_includes/zoom.scss +++ b/app/assets/stylesheets/legacy_includes/zoom.scss @@ -3,19 +3,22 @@ img[data-action="zoom"] { cursor: -webkit-zoom-in; cursor: -moz-zoom-in; } + .zoom-img, .zoom-img-wrap { position: relative; z-index: 666; -webkit-transition: all 300ms; - -o-transition: all 300ms; - transition: all 300ms; + -o-transition: all 300ms; + transition: all 300ms; } + img.zoom-img { cursor: zoom-out; cursor: -webkit-zoom-out; cursor: -moz-zoom-out; } + .zoom-overlay { z-index: 420; background: #2c3e50; @@ -27,15 +30,17 @@ img.zoom-img { pointer-events: none; filter: "alpha(opacity=0)"; opacity: 0; - -webkit-transition: opacity 300ms; - -o-transition: opacity 300ms; - transition: opacity 300ms; + -webkit-transition: opacity 300ms; + -o-transition: opacity 300ms; + transition: opacity 300ms; } + .zoom-overlay-open .zoom-overlay { filter: "alpha(opacity=80)"; - opacity: .8; + opacity: 0.8; } + .zoom-overlay-open, .zoom-overlay-transitioning { cursor: default; -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/registrations.scss b/app/assets/stylesheets/registrations.scss index a957c227d6..fcb24da30e 100644 --- a/app/assets/stylesheets/registrations.scss +++ b/app/assets/stylesheets/registrations.scss @@ -17,23 +17,27 @@ // Core variables and mixins @import "bootstrap/variables"; -// + +// // Overrides -$border-radius: 1px; -$border-radius-lg: 1px; -$border-radius-sm: 1px; +$border-radius: 1px; +$border-radius-lg: 1px; +$border-radius-sm: 1px; + @import "revised/mixins/colors"; -// +// // More bootstrap @import "bootstrap/mixins"; // Reset and dependencies @import "bootstrap/normalize"; + // @import "bootstrap/print"; // Core CSS @import "bootstrap/reboot"; + // @import "bootstrap/type"; // @import "bootstrap/images"; // @import "bootstrap/code"; @@ -59,6 +63,7 @@ $border-radius-sm: 1px; // @import "bootstrap/grid"; // @import "bootstrap/tables"; @import "bootstrap/forms"; + // @import "bootstrap/buttons"; // Override buttons with our own buttons // Components @@ -67,6 +72,7 @@ $border-radius-sm: 1px; // @import "bootstrap/button-group"; @import "bootstrap/input-group"; @import "bootstrap/custom-forms"; + // @import "bootstrap/nav"; // @import "bootstrap/navbar"; // @import "bootstrap/card"; @@ -92,7 +98,6 @@ $border-radius-sm: 1px; // Utility classes @import "bootstrap/utilities"; - /*! * Bike Index styles * for revised style in 2016 @@ -104,6 +109,7 @@ $border-radius-sm: 1px; // Bootstrap overrides @import "revised/mixins/buttons"; + // @import "revised/sections/modals"; @import "revised/sections/alerts"; @import "revised/sections/forms"; @@ -184,21 +190,39 @@ $border-radius-sm: 1px; // html { background: $black-off; } // .currently-hidden { display: none; } -img { max-width: 100%; } // don't break random stuff images! +img { + max-width: 100%; +} + +// don't break random stuff images! // body { min-height: 400px; } -// +// // External overrides -// +// // Bike Index selectize overrides -.selectize-dropdown [data-selectable] .highlight { background: rgba($blue, 0.2); } -.selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } +.selectize-dropdown [data-selectable] .highlight { + background: rgba($blue, 0.2); +} + +.selectize-dropdown .active { + background-color: lighten(#bebebe, 10%); +} + // Make selectize inputs the same size as form inputs -.form-group .selectize-control .selectize-input { padding: 0.475rem 0.75rem; } +.form-group .selectize-control .selectize-input { + padding: 0.475rem 0.75rem; +} + // Make placeholder text the same as other placeholders -.registration-widget .selectize-input.not-full > input { font-style: italic; } -.registration-widget .selectize-input.not-full.input-active > input { font-style: normal; } +.registration-widget .selectize-input.not-full > input { + font-style: italic; +} + +.registration-widget .selectize-input.not-full.input-active > input { + font-style: normal; +} // // Pickaday overrides // .pika-button:hover { background: $blue; } @@ -209,31 +233,39 @@ img { max-width: 100%; } // don't break random stuff images! // .slick-next { display: none; } // } - // ------------------------------ -// +// -// +// // REGISTRATION FORM SPECIFIC STYLES -// +// #binx_registration_widget { margin: 0 auto; position: relative; border-radius: $border-radius; - width: 100%; // max width set on body element in reg embed + width: 100%; + + // max width set on body element in reg embed border: 1px solid $gray-lightish; background: $gray-lighter; + h2 { font-size: 30px; - margin: $vertical-height 0 1.5*$vertical-height; + margin: $vertical-height 0 (1.5 * $vertical-height); + } + + p, + h2 { + text-align: center; } - p, h2 { text-align: center; } + header { border-radius: $border-radius $border-radius 0 0; display: block; background: $gray-dark; position: relative; padding: $vertical-height; + h3 { color: #fff; margin: 0; @@ -241,36 +273,65 @@ img { max-width: 100%; } // don't break random stuff images! font-size: 21px; } } + header.reg-header { - background: image-url('revised/spokebg.png'); + background: image-url("revised/spokebg.png"); background-size: cover; background-position: center center; padding: $vertical-height 0; + .reg-header-logo { display: block; width: 15%; height: auto; margin: 0 auto; } + h2 { color: $reversed-font-color; margin: $vertical-height 0; } + p { margin: 0; color: #fff; - em { color: $blue; } + + em { + color: $blue; + } } } + .registration-widget-body { - padding: 22px 2*$vertical-height 21px; - p { padding: 0 10%; } + padding: 22px (2 * $vertical-height) 21px; + + p { + padding: 0 10%; + } + } + + .registration-widget-body > form { + margin: 0 auto; + } + + input[type="email"], + select, + .form-control { + width: 100%; } - .registration-widget-body > form { margin: 0 auto; } - input[type='email'], select, .form-control { width: 100%; } - .below-input-help { padding: 0 6px; } - .fancy-select .selectize-control { width: 100%; } - label { line-height: 1.2em; } + + .below-input-help { + padding: 0 6px; + } + + .fancy-select .selectize-control { + width: 100%; + } + + label { + line-height: 1.2em; + } + .submit-wrapper .btn { display: block; margin: 0; @@ -280,15 +341,26 @@ img { max-width: 100%; } // don't break random stuff images! // Per organization settings &.umd { - .submit-wrapper .btn { background: #e03a3e; } + .submit-wrapper .btn { + background: #e03a3e; + } } + &.uw { - .submit-wrapper .btn { background: #4b2e83; } + .submit-wrapper .btn { + background: #4b2e83; + } } + &.upitt { - .submit-wrapper .btn { background: #102F59; } + .submit-wrapper .btn { + background: #102f59; + } } + &.psu { - .submit-wrapper .btn { background: #074378; } + .submit-wrapper .btn { + background: #074378; + } } } diff --git a/app/assets/stylesheets/revised.scss b/app/assets/stylesheets/revised.scss index 0918b472ae..78dd46f3db 100644 --- a/app/assets/stylesheets/revised.scss +++ b/app/assets/stylesheets/revised.scss @@ -14,13 +14,18 @@ // Core variables and mixins @import "bootstrap/variables"; -$enable-flex: true; // Flexbox!! + +$enable-flex: true; + +// Flexbox!! $half-gutter: $grid-gutter-width / 2; + // // Overrides $border-radius: 1px; $border-radius-lg: 1px; $border-radius-sm: 1px; + @import "revised/mixins/colors"; // @@ -33,9 +38,11 @@ $border-radius-sm: 1px; // Core CSS @import "bootstrap/reboot"; + // @import "bootstrap/type"; @import "bootstrap/images"; @import "bootstrap/code"; + .code { .code-label { border-radius: $border-radius $border-radius 0 0; @@ -48,6 +55,7 @@ $border-radius-sm: 1px; font-size: 15px; font-weight: bold; } + pre { border-radius: 0 0 $border-radius $border-radius; box-shadow: inset 0 0 1px rgba(black, 0.2); @@ -55,12 +63,16 @@ $border-radius-sm: 1px; border-top: 0; } } + @import "bootstrap/grid"; @import "bootstrap/tables"; + .table-compact-long { line-height: 1.2em; } + @import "bootstrap/forms"; + // @import "bootstrap/buttons"; // Override buttons with our own buttons // Components @@ -73,9 +85,11 @@ $border-radius-sm: 1px; @import "bootstrap/navbar"; @import "bootstrap/card"; @import "bootstrap/breadcrumb"; + // @import "bootstrap/pagination"; // Overriden with our own // @import "bootstrap/tags"; @import "bootstrap/jumbotron"; + // @import "bootstrap/alert"; // Overriden with our own @import "bootstrap/progress"; @import "bootstrap/media"; @@ -86,6 +100,7 @@ $border-radius-sm: 1px; // Components w/ JavaScript $modal-backdrop-bg: $blue-dark; $modal-backdrop-opacity: 0.8; + @import "bootstrap/modal"; @import "bootstrap/tooltip"; @import "bootstrap/popover"; @@ -97,10 +112,13 @@ $modal-backdrop-opacity: 0.8; // // Other (non-bootstrap) external styles @import "legacy_includes/zoom.scss"; + $zoom-img-wrap-z-index: $zindex-navbar-fixed + 100; + .zoom-overlay { z-index: $zindex-navbar-fixed + 99; } + .zoom-img-wrap { z-index: $zoom-img-wrap-z-index; } @@ -148,12 +166,15 @@ $zoom-img-wrap-z-index: $zindex-navbar-fixed + 100; @import "revised/sections/side_boxes"; @import "revised/sections/tables"; @import "revised/sections/embeded_tweet"; + // Shared organized styles @import "revised/pages/organized/forms"; @import "revised/pages/organized/shared"; @import "revised/pages/organized/messages"; @import "revised/pages/organized/exports"; -@import "revised/sections/organized_menu"; // left hand organized menu +@import "revised/sections/organized_menu"; + +// left hand organized menu // // Page styles @@ -171,13 +192,19 @@ $zoom-img-wrap-z-index: $zindex-navbar-fixed + 100; // Bike show & search pages @import "revised/pages/bikes/index"; @import "revised/pages/bikes/show"; -@import "revised/pages/bikes/show_photo"; // separated because it's a lot +@import "revised/pages/bikes/show_photo"; + +// separated because it's a lot @import "revised/pages/bikes/multi_serial_search"; // User pages @import "revised/pages/user/home"; -@import "revised/pages/user/edit"; // my_account page -@import "revised/pages/user/show"; // public show page +@import "revised/pages/user/edit"; + +// my_account page +@import "revised/pages/user/show"; + +// public show page // Error pages @import "revised/pages/errors"; @@ -211,19 +238,27 @@ $zoom-img-wrap-z-index: $zindex-navbar-fixed + 100; @import "revised/pages/landing/recoveries"; // LEGACY PAGES general styles - replace as soon as all pages have been restyled -@import "revised/sections/legacy_content"; // general legacy content styles -@import "revised/pages/legacy_stolen"; // legacy stolen page - including multi-serial search +@import "revised/sections/legacy_content"; + +// general legacy content styles +@import "revised/pages/legacy_stolen"; + +// legacy stolen page - including multi-serial search @import "revised/sections/oauth"; html { background: $black-off; } + .currently-hidden { display: none; } + img { max-width: 100%; -} // don't break random stuff images! +} + +// don't break random stuff images! body { min-height: 400px; } @@ -242,9 +277,11 @@ body { bottom: 0; left: 0; text-align: center; + p { margin: 0; } + h4 { color: $red; margin: 0 0 $vertical-height; @@ -255,26 +292,33 @@ body { .text-right { text-align: right; } + .mt-4 { margin-top: 2 * $vertical-height; } + .mt-2 { margin-top: $vertical-height; } + .mb-4 { margin-bottom: 2 * $vertical-height; } + .mb-2 { margin-bottom: $vertical-height; } + .small { @extend small; } + // pull-right and pull-left should be replaced by float-right and float-left .float-right, .pull-right { float: right; } + .float-left, .pull-left { float: right; @@ -283,6 +327,7 @@ body { .text-right { text-align: right; } + .text-left { text-align: left; } diff --git a/app/assets/stylesheets/revised/_vars.scss b/app/assets/stylesheets/revised/_vars.scss index 774045bb17..1459669d7b 100644 --- a/app/assets/stylesheets/revised/_vars.scss +++ b/app/assets/stylesheets/revised/_vars.scss @@ -1,4 +1,3 @@ - // Because Mike Oleon is obsessed with the imperial system // or something wack like that $vertical-height: 12px; @@ -9,7 +8,7 @@ $grid-breakpoint-sm: 544px; $grid-breakpoint-md: 768px; $grid-breakpoint-lg: 992px; $grid-breakpoint-xl: 1200px; -$grid-sizes: 'xs', 'sm', 'md', 'lg', 'xl'; -$grid-breakpoints-var: $grid-breakpoint-xs, $grid-breakpoint-sm, $grid-breakpoint-md, $grid-breakpoint-lg, $grid-breakpoint-xl; +$grid-sizes: "xs", "sm", "md", "lg", "xl"; +$grid-breakpoints-var: $grid-breakpoint-xs, $grid-breakpoint-sm, + $grid-breakpoint-md, $grid-breakpoint-lg, $grid-breakpoint-xl; $row-side-padding: 0.9375rem; - diff --git a/app/assets/stylesheets/revised/emails/email_bike_display.scss b/app/assets/stylesheets/revised/emails/email_bike_display.scss index 22cc0fed5c..fa777f00dc 100644 --- a/app/assets/stylesheets/revised/emails/email_bike_display.scss +++ b/app/assets/stylesheets/revised/emails/email_bike_display.scss @@ -1,32 +1,43 @@ .bike-display { position: relative; width: 96%; - margin: $vertical-height auto 2*$vertical-height; + margin: $vertical-height auto (2 * $vertical-height); padding: $vertical-height; border: 1px solid $gray-light; clear: both; + .image-holder { margin: 0; float: left; width: 35%; position: relative; padding: 0; + a { display: block; position: relative; } + img { width: 100%; display: block; margin: 0 auto; height: auto; } + &.placeholder { background: $email-light-bg; - a { padding: $vertical-height 0; } - img { width: 70%; } + + a { + padding: $vertical-height 0; + } + + img { + width: 70%; + } } } + .info-holder { float: left; margin: 0 0 0 7%; @@ -34,14 +45,18 @@ width: 58%; list-style-type: none; display: block; + li { - margin: .5*$vertical-height 0 0 0; + margin: (0.5 * $vertical-height) 0 0 0; padding: 0 0 0 0; text-indent: -5%; display: block; list-style: none; line-height: 1.5em; - &:first-of-type { margin-top: 0; } + + &:first-of-type { + margin-top: 0; + } } } } diff --git a/app/assets/stylesheets/revised/emails/email_body.scss b/app/assets/stylesheets/revised/emails/email_body.scss index 5139f38e36..fa61320545 100644 --- a/app/assets/stylesheets/revised/emails/email_body.scss +++ b/app/assets/stylesheets/revised/emails/email_body.scss @@ -1,9 +1,16 @@ +#outlook a { + padding: 0; +} -#outlook a{ padding:0; } /* Force Outlook to provide a "view in browser" button. */ +/* Force Outlook to provide a "view in browser" button. */ body { - width:100% !important; /* Force Hotmail to display emails at full width */ - -webkit-text-size-adjust:none; /* Prevent Webkit platforms from changing default text sizes. */ + width: 100% !important; + + /* Force Hotmail to display emails at full width */ + -webkit-text-size-adjust: none; + + /* Prevent Webkit platforms from changing default text sizes. */ margin: 0; padding: 0; background: #fff; @@ -11,36 +18,52 @@ body { color: $gray; font-size: $font-size; line-height: 2em; + a { color: $link-color; text-decoration: none; - &:hover, &:active, &.active { + + &:hover, + &:active, + &.active { text-decoration: underline; color: $link-color; } } } -h1, h2, h3, h4, h5 { +h1, +h2, +h3, +h4, +h5 { line-height: 1.2em; margin: 0; font-family: sans-serif; } -h1, h2, h3 { +h1, +h2, +h3 { color: $gray-darker; text-transform: uppercase; } -h1 { font-weight: 200; } +h1 { + font-weight: 200; +} hr { display: block; - margin: 2*$vertical-height 0; + margin: (2 * $vertical-height) 0; border: none; border-top: 1px inset $gray-light; } -.center-text { text-align: center; } +.center-text { + text-align: center; +} -.less-strong { color: $gray-light; } \ No newline at end of file +.less-strong { + color: $gray-light; +} diff --git a/app/assets/stylesheets/revised/emails/email_components.scss b/app/assets/stylesheets/revised/emails/email_components.scss index 1974501391..329c53e4ca 100644 --- a/app/assets/stylesheets/revised/emails/email_components.scss +++ b/app/assets/stylesheets/revised/emails/email_components.scss @@ -12,26 +12,35 @@ } .donate-message { - h5, p { text-align: center; } - h5 { font-size: 16px; } + h5, + p { + text-align: center; + } + + h5 { + font-size: 16px; + } + p { line-height: 1.5em; margin: 8px 0 0; - opacity: .8; + opacity: 0.8; font-size: 15px; font-style: italic; } + padding: $vertical-height 0; border-top: 1px solid $red; border-bottom: 1px solid $red; - margin: 0 0 2.5*$vertical-height; + margin: 0 0 (2.5 * $vertical-height); } .locking-demonstration { border: solid $vertical-height $email-light-bg; width: 100%; - margin: 2*$vertical-height 0 0; + margin: (2 * $vertical-height) 0 0; position: relative; + img { display: block; width: 80%; @@ -45,9 +54,10 @@ list-style-type: disc; margin: 1em 0; padding: 0 0 0 40px; + li { line-height: 1.5em; - margin-top: .5*$vertical-height; + margin-top: 0.5 * $vertical-height; } } diff --git a/app/assets/stylesheets/revised/emails/email_partners.scss b/app/assets/stylesheets/revised/emails/email_partners.scss index 4d5c8258dc..d07b64e35f 100644 --- a/app/assets/stylesheets/revised/emails/email_partners.scss +++ b/app/assets/stylesheets/revised/emails/email_partners.scss @@ -1,20 +1,22 @@ .organized-partnership-header { text-align: center; + p { color: #000; font-style: italic; margin: 0; } + img { display: inline-block; - margin-left: 2*$vertical-height; + margin-left: 2 * $vertical-height; max-width: 60%; vertical-align: middle; } } .organized-partnership-main { - padding: 2*$vertical-height $vertical-height; + padding: (2 * $vertical-height) $vertical-height; border: 1px solid $gray; - margin: 2*$vertical-height 0; -} \ No newline at end of file + margin: (2 * $vertical-height) 0; +} diff --git a/app/assets/stylesheets/revised/emails/email_sections.scss b/app/assets/stylesheets/revised/emails/email_sections.scss index d7d437dd66..556051ba99 100644 --- a/app/assets/stylesheets/revised/emails/email_sections.scss +++ b/app/assets/stylesheets/revised/emails/email_sections.scss @@ -14,19 +14,24 @@ height: $header-height; width: 100%; background: $gray-darker; + img { display: block; - margin: 0.5 * $vertical-height 1.5 * $vertical-height 0 0; + margin: (0.5 * $vertical-height) (1.5 * $vertical-height) 0 0; float: right; - height: $header-height - $vertical-height; // This is also manually set in HTML attrs because of outlook + height: $header-height - $vertical-height; + + // This is also manually set in HTML attrs because of outlook max-height: $header-height - $vertical-height; width: auto; } + .partner-logo-wrapper { display: block; float: left; background: #fff; height: 84px; + .logo-plus { color: $gray-darker; font-size: 40px; @@ -34,11 +39,16 @@ line-height: 1; margin: 17px 12px 0; } + .partner-header-logo { float: left; - margin-top: 21px; // Margin calculated above is 6px + margin-top: 21px; + + // Margin calculated above is 6px margin-right: 0; - height: 45px; // This is also manually set in HTML attrs because of outlook + height: 45px; + + // This is also manually set in HTML attrs because of outlook } } } @@ -49,21 +59,27 @@ font-weight: 400; line-height: 1.2em; } + span { font-family: Verdana, sans-serif; font-size: 30px; + &:nth-of-type(1) { color: #f46767; } + &:nth-of-type(2) { color: #ffed40; } + &:nth-of-type(3) { color: #c7e775; } + &:nth-of-type(4) { color: #3498db; } + &:nth-of-type(5) { color: #cea9f7; } @@ -71,9 +87,11 @@ } $foot-padding: 0.5 * ($header-height - $font-size); + .binx-footer { background: $gray-darker; padding: $foot-padding; + h5 { color: $gray-light; font-weight: 600; diff --git a/app/assets/stylesheets/revised/fonts.scss b/app/assets/stylesheets/revised/fonts.scss index 8cf3266655..f0d37a6b3c 100644 --- a/app/assets/stylesheets/revised/fonts.scss +++ b/app/assets/stylesheets/revised/fonts.scss @@ -23,15 +23,19 @@ $btn-font-size: 15px; line-height: 2em; color: $body-font-color; text-transform: none; + em { font-style: italic; } + strong { font-weight: $strong-font-weight; } + a { color: $link-color; text-decoration: none; + &:hover, &:active, &.active { @@ -44,6 +48,7 @@ $btn-font-size: 15px; .light-italic { font-weight: $light-italic-weight; font-style: italic; + strong { font-style: normal; font-weight: $strong-font-weight; @@ -56,12 +61,14 @@ body { p { @extend .body-font; - margin: 0 0 2 * $vertical-height; + + margin: 0 0 (2 * $vertical-height); } // p.intro on typecast h5 { @extend .body-font; + font-size: $h5-font-size; font-weight: normal; line-height: 1.5em; @@ -69,6 +76,7 @@ h5 { .pullquote { @extend .body-font; + font-weight: 300; font-style: italic; font-size: 18px; @@ -81,11 +89,14 @@ h5 { font-style: normal; text-transform: uppercase; color: $header-font-color; + strong { font-weight: $strong-font-weight; } + a { color: $link-color; + &:hover, &:active, &.active { @@ -97,6 +108,7 @@ h5 { .header-font-alt { @extend .header-font; + font-family: $body-font-family; color: $body-font-color; text-transform: none !important; @@ -104,10 +116,12 @@ h5 { h1 { @extend .header-font; - margin: 0 0 2 * $vertical-height; + + margin: 0 0 (2 * $vertical-height); letter-spacing: -1px; font-size: $h1-font-size; line-height: 1.12em; + @include media-breakpoint-down(md) { font-size: $h1-font-size-md; } @@ -115,9 +129,11 @@ h1 { h2 { @extend .header-font; - margin: 0 0 2 * $vertical-height; + + margin: 0 0 (2 * $vertical-height); font-size: $h2-font-size; line-height: 1em; + @include media-breakpoint-down(md) { font-size: $h2-font-size-md; } @@ -125,7 +141,8 @@ h2 { h3 { @extend .header-font; - margin: 0 0 2 * $vertical-height; + + margin: 0 0 (2 * $vertical-height); font-size: $h3-font-size; line-height: 1em; } @@ -133,7 +150,8 @@ h3 { // Primary menu header height h4 { @extend .header-font; - margin: 0 0 2 * $vertical-height; + + margin: 0 0 (2 * $vertical-height); font-size: $h4-font-size; line-height: 18px; } diff --git a/app/assets/stylesheets/revised/mixins/_buttons.scss b/app/assets/stylesheets/revised/mixins/_buttons.scss index 98e275b35f..e763e72534 100644 --- a/app/assets/stylesheets/revised/mixins/_buttons.scss +++ b/app/assets/stylesheets/revised/mixins/_buttons.scss @@ -1,4 +1,4 @@ -// +// // Mixins // Button variants @@ -13,43 +13,66 @@ color: $color; background-color: $background; border-color: $border; + @include box-shadow($btn-box-shadow); - &:not([href]):not([tabindex]) { color: $color; } // Stop inheriting body color if no href! + &:not([href]):not([tabindex]) { + color: $color; + } + + // Stop inheriting body color if no href! @include hover { color: $color; - &:not([href]):not([tabindex]) { color: $color; } + + &:not([href]):not([tabindex]) { + color: $color; + } + background-color: $active-background; - border-color: $active-border; + border-color: $active-border; } &:focus, &.focus { color: $color; - &:not([href]):not([tabindex]) { color: $color; } + + &:not([href]):not([tabindex]) { + color: $color; + } + background-color: $active-background; - border-color: $active-border; + border-color: $active-border; } &:active, &.active, .open > &.dropdown-toggle { color: $color; - &:not([href]):not([tabindex]) { color: $color; } + + &:not([href]):not([tabindex]) { + color: $color; + } + background-color: $active-background; - border-color: $active-border; + border-color: $active-border; + // Remove the gradient for the pressed/active state background-image: none; + @include box-shadow($btn-active-box-shadow); &:hover, &:focus, &.focus { color: $color; - &:not([href]):not([tabindex]) { color: $color; } + + &:not([href]):not([tabindex]) { + color: $color; + } + background-color: darken($background, 17%); - border-color: darken($border, 25%); + border-color: darken($border, 25%); } } @@ -58,11 +81,12 @@ &:focus, &.focus { background-color: $background; - border-color: $border; + border-color: $border; } + @include hover { background-color: $background; - border-color: $border; + border-color: $border; } } } @@ -72,37 +96,58 @@ background-image: none; background-color: transparent; border-color: $color; - &:not([href]):not([tabindex]) { color: $color; } // Stop inheriting body color if no href! + + &:not([href]):not([tabindex]) { + color: $color; + } + + // Stop inheriting body color if no href! @include hover { color: #fff; - &:not([href]):not([tabindex]) { color: #fff; } + + &:not([href]):not([tabindex]) { + color: #fff; + } + background-color: $color; - border-color: $color; + border-color: $color; } &:focus, &.focus { color: #fff; - &:not([href]):not([tabindex]) { color: #fff; } + + &:not([href]):not([tabindex]) { + color: #fff; + } + background-color: $color; - border-color: $color; + border-color: $color; } &:active, &.active, .open > &.dropdown-toggle { color: #fff; - &:not([href]):not([tabindex]) { color: #fff; } + + &:not([href]):not([tabindex]) { + color: #fff; + } + background-color: $color; - border-color: $color; + border-color: $color; &:hover, &:focus, &.focus { color: #fff; - &:not([href]):not([tabindex]) { color: #fff; } + + &:not([href]):not([tabindex]) { + color: #fff; + } + background-color: darken($color, 17%); - border-color: darken($color, 25%); + border-color: darken($color, 25%); } } @@ -112,6 +157,7 @@ &.focus { border-color: lighten($color, 20%); } + @include hover { border-color: lighten($color, 20%); } @@ -122,61 +168,62 @@ @mixin button-size($padding-y, $padding-x, $font-size, $border-radius) { padding: $padding-y $padding-x; font-size: $font-size; + @include border-radius($border-radius); } - -// +// // Variables -$btn-padding-x: 1rem !default; -$btn-padding-y: .5rem !default; -$btn-line-height: 1.25 !default; -$btn-font-weight: normal !default; -$btn-box-shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075) !default; -$btn-active-box-shadow: inset 0 3px 5px rgba(0,0,0,.125) !default; +$btn-padding-x: 1rem !default; +$btn-padding-y: 0.5rem !default; +$btn-line-height: 1.25 !default; +$btn-font-weight: normal !default; +$btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), + 0 1px 1px rgba(0, 0, 0, 0.075) !default; +$btn-active-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125) !default; -$btn-primary-color: #fff; -$btn-primary-bg: $blue; -$btn-primary-border: $blue; +$btn-primary-color: #fff; +$btn-primary-bg: $blue; +$btn-primary-border: $blue; -$btn-secondary-color: $gray-dark !default; -$btn-secondary-bg: #fff !default; -$btn-secondary-border: #ccc !default; +$btn-secondary-color: $gray-dark !default; +$btn-secondary-bg: #fff !default; +$btn-secondary-border: #ccc !default; -$btn-info-color: #fff !default; -$btn-info-bg: $brand-info !default; -$btn-info-border: $btn-info-bg !default; +$btn-info-color: #fff !default; +$btn-info-bg: $brand-info !default; +$btn-info-border: $btn-info-bg !default; -$btn-success-color: #fff !default; -$btn-success-bg: $green !default; -$btn-success-border: $btn-success-bg !default; +$btn-success-color: #fff !default; +$btn-success-bg: $green !default; +$btn-success-border: $btn-success-bg !default; -$btn-warning-color: #fff !default; -$btn-warning-bg: $brand-warning !default; -$btn-warning-border: $btn-warning-bg !default; +$btn-warning-color: #fff !default; +$btn-warning-bg: $brand-warning !default; +$btn-warning-border: $btn-warning-bg !default; -$btn-danger-color: #fff !default; -$btn-danger-bg: $red !default; -$btn-danger-border: $btn-danger-bg !default; +$btn-danger-color: #fff !default; +$btn-danger-bg: $red !default; +$btn-danger-border: $btn-danger-bg !default; -$btn-link-disabled-color: $gray-light !default; +$btn-link-disabled-color: $gray-light !default; -$btn-padding-x-sm: .5rem !default; -$btn-padding-y-sm: .25rem !default; +$btn-padding-x-sm: 0.5rem !default; +$btn-padding-y-sm: 0.25rem !default; -$btn-padding-x-lg: 1.5rem !default; -$btn-padding-y-lg: .75rem !default; +$btn-padding-x-lg: 1.5rem !default; +$btn-padding-y-lg: 0.75rem !default; -$btn-block-spacing-y: 5px !default; -$btn-toolbar-margin: 5px !default; +$btn-block-spacing-y: 5px !default; +$btn-toolbar-margin: 5px !default; -$split-btn-dropdown-toggle-padding-x: 8px !default; +$split-btn-dropdown-toggle-padding-x: 8px !default; $split-btn-lg-dropdown-toggle-padding-x: 12px !default; // Allows for customizing button radius independently from global border radius -$btn-border-radius: 1px; -$btn-border-radius-lg: 1px; -$btn-border-radius-sm: 1px; +$btn-border-radius: 1px; +$btn-border-radius-lg: 1px; +$btn-border-radius-sm: 1px; // // Base styles @@ -195,21 +242,29 @@ $btn-border-radius-sm: 1px; cursor: pointer; user-select: none; border: $input-btn-border-width solid transparent; - @include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-border-radius); - @include transition(all .2s ease-in-out); + + @include button-size( + $btn-padding-y, + $btn-padding-x, + $btn-font-size, + $btn-border-radius + ); + + @include transition(all 0.2s ease-in-out); &, &:active, &.active { &:focus, &.focus { - @include tab-focus(); + @include tab-focus; } } @include hover-focus { text-decoration: none; } + &.focus { text-decoration: none; } @@ -218,13 +273,15 @@ $btn-border-radius-sm: 1px; &.active { background-image: none; outline: 0; + @include box-shadow($btn-active-box-shadow); } &.disabled, &:disabled { cursor: $cursor-disabled; - opacity: .65; + opacity: 0.65; + @include box-shadow(none); } } @@ -235,54 +292,83 @@ fieldset[disabled] a.btn { pointer-events: none; } - // // Alternate buttons // .btn-primary { - @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); + @include button-variant( + $btn-primary-color, + $btn-primary-bg, + $btn-primary-border + ); } + .btn-primary-offset { @include button-variant($btn-primary-color, $blue-darkish, $blue-darkish); } + .btn-secondary { - @include button-variant($btn-secondary-color, $btn-secondary-bg, $btn-secondary-border); + @include button-variant( + $btn-secondary-color, + $btn-secondary-bg, + $btn-secondary-border + ); } + .btn-info { @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border); } + .btn-success { - @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border); + @include button-variant( + $btn-success-color, + $btn-success-bg, + $btn-success-border + ); } + .btn-warning { - @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border); + @include button-variant( + $btn-warning-color, + $btn-warning-bg, + $btn-warning-border + ); } + .btn-danger { - @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); + @include button-variant( + $btn-danger-color, + $btn-danger-bg, + $btn-danger-border + ); } // Remove all backgrounds .btn-outline-primary { @include button-outline-variant($btn-primary-bg); } + .btn-outline-secondary { @include button-outline-variant($btn-secondary-border); } + .btn-outline-info { @include button-outline-variant($btn-info-bg); } + .btn-outline-success { @include button-outline-variant($btn-success-bg); } + .btn-outline-warning { @include button-outline-variant($btn-warning-bg); } + .btn-outline-danger { @include button-outline-variant($btn-danger-bg); } - // // Link buttons // @@ -298,21 +384,26 @@ fieldset[disabled] a.btn { &.active, &:disabled { background-color: transparent; + @include box-shadow(none); } + &, &:focus, &:active { border-color: transparent; } + @include hover { border-color: transparent; } + @include hover-focus { color: $link-hover-color; text-decoration: $link-hover-decoration; background-color: transparent; } + &:disabled { @include hover-focus { color: $btn-link-disabled-color; @@ -321,21 +412,30 @@ fieldset[disabled] a.btn { } } - // // Button Sizes // .btn-lg { // line-height: ensure even-numbered height of button next to large input - @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size, $btn-border-radius-lg); + @include button-size( + $btn-padding-y-lg, + $btn-padding-x-lg, + $btn-font-size, + $btn-border-radius-lg + ); } + .btn-sm { // line-height: ensure proper height of button next to small input - @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size, $btn-border-radius-sm); + @include button-size( + $btn-padding-y-sm, + $btn-padding-x-sm, + $btn-font-size, + $btn-border-radius-sm + ); } - // // Block button // @@ -357,4 +457,4 @@ input[type="button"] { &.btn-block { width: 100%; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/mixins/_colors.scss b/app/assets/stylesheets/revised/mixins/_colors.scss index 0b6824cf20..71d546a407 100644 --- a/app/assets/stylesheets/revised/mixins/_colors.scss +++ b/app/assets/stylesheets/revised/mixins/_colors.scss @@ -3,15 +3,17 @@ $btn-green: #5cb85c; $red: #e74c3c; $blue-dark: #2c3e50; -$blue-darkish: #2980B9; +$blue-darkish: #2980b9; $blue: #3498db; $blue-light: #92c8ec; $gray-darker: #333333; $gray-dark: #222; $gray: #666; -$gray-light: #A4A4A4; -$gray-lightish: #e4e4e4; // border on things that are gray-lighter +$gray-light: #a4a4a4; +$gray-lightish: #e4e4e4; + +// border on things that are gray-lighter $gray-lighter: #f2f2f2; $form-well-background: $gray-lighter; @@ -31,4 +33,6 @@ $black-off: #111; $primary-nav-background: $black-off; $primary-nav-text-color: $gray-light; -.stolen-color { color: $red; } \ No newline at end of file +.stolen-color { + color: $red; +} diff --git a/app/assets/stylesheets/revised/mixins/_textoverflow.scss b/app/assets/stylesheets/revised/mixins/_textoverflow.scss index f5c509e6e9..15b5f7dac3 100644 --- a/app/assets/stylesheets/revised/mixins/_textoverflow.scss +++ b/app/assets/stylesheets/revised/mixins/_textoverflow.scss @@ -3,4 +3,4 @@ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/mixins/_trash_can_icon.scss b/app/assets/stylesheets/revised/mixins/_trash_can_icon.scss index eaa76d4425..9e8af2e5f7 100644 --- a/app/assets/stylesheets/revised/mixins/_trash_can_icon.scss +++ b/app/assets/stylesheets/revised/mixins/_trash_can_icon.scss @@ -4,22 +4,33 @@ height: $size; position: relative; overflow: hidden; - .trash-lid, .trash-container { + + .trash-lid, + .trash-container { position: absolute; background-color: $color; } - &:hover, &:active, &.active { + + &:hover, + &:active, + &.active { cursor: pointer; - .hover-colorize { background-color: $hover-color; } + + .hover-colorize { + background-color: $hover-color; + } } + .trash-lid { width: 62%; height: 10%; - left: 50%; top: 10.5%; + left: 50%; + top: 10.5%; margin-left: -31%; border-top-left-radius: 80%; border-top-right-radius: 80%; - transform: rotate(-5deg); + transform: rotate(-5deg); + &::after { content: ""; position: absolute; @@ -31,9 +42,10 @@ background-color: inherit; border-top-left-radius: 30%; border-top-right-radius: 30%; - transform: rotate(-1deg); + transform: rotate(-1deg); } } + .trash-container { width: 56%; height: 65%; @@ -42,6 +54,7 @@ bottom: 10%; border-bottom-left-radius: 15%; border-bottom-right-radius: 15%; + &::after { content: ""; width: 110%; @@ -55,6 +68,7 @@ border-bottom-right-radius: 45%; } } + span { width: 4%; height: 50%; @@ -62,8 +76,17 @@ margin-left: -2%; bottom: 17%; background-color: $background; - &:nth-of-type(1) { left: 38%; } - &:nth-of-type(2) { left: 50%; } - &:nth-of-type(3) { left: 62%; } + + &:nth-of-type(1) { + left: 38%; + } + + &:nth-of-type(2) { + left: 50%; + } + + &:nth-of-type(3) { + left: 62%; + } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/mixins/nav_tabs.scss b/app/assets/stylesheets/revised/mixins/nav_tabs.scss index aa975a5d3f..d6491dacd9 100644 --- a/app/assets/stylesheets/revised/mixins/nav_tabs.scss +++ b/app/assets/stylesheets/revised/mixins/nav_tabs.scss @@ -1,4 +1,4 @@ -// Because there are times when we apply this via media queries, +// Because there are times when we apply this via media queries, // these are mixins instead of standard class-selector based styles // You still need to use the bootstrap classes to get nav-tabs @@ -6,35 +6,53 @@ // Apply this mixin to the ul.nav.nav-tabs @mixin binx-nav-tabs { border: none; + .nav-item { margin: 0 0 0 -1px; - &:first-of-type { margin-left: 0; } + + &:first-of-type { + margin-left: 0; + } + a { border: 1px solid $gray-darker; color: $gray-darker; border-radius: $border-radius; - &:hover, &:active, &.active { + + &:hover, + &:active, + &.active { border: 1px solid $gray-darker; color: white; text-decoration: none; } - &:hover { background: $gray; } - &:active, &.active { background: $gray-darker; } + + &:hover { + background: $gray; + } + + &:active, + &.active { + background: $gray-darker; + } } } } -// Generally for use on small screens. +// Generally for use on small screens. // binx-nav-tabs needs to be included as well for this to function // Apply this mixin to the ul.nav.nav-tabs (most likely in a xs-screen media query) @mixin binx-nav-tabs-vertical { - display: block; // ensure we override flex if it's there + display: block; + + // ensure we override flex if it's there .nav-item { width: 100%; margin: -1px 0 0; + a { width: 100%; - padding: .5*$vertical-height $vertical-height; + padding: (0.5 * $vertical-height) $vertical-height; } } } @@ -48,4 +66,4 @@ border: 1px solid $gray-darker; border-top: none; margin-bottom: $vertical-height; -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/bikes/choose_registration.scss b/app/assets/stylesheets/revised/pages/bikes/choose_registration.scss index f54b81da23..3b2d1f1aea 100644 --- a/app/assets/stylesheets/revised/pages/bikes/choose_registration.scss +++ b/app/assets/stylesheets/revised/pages/bikes/choose_registration.scss @@ -1,31 +1,45 @@ #welcome_choose_registration { $choose-reg-font-size: 20px; - .choose-registration-items { align-items: center; } + + .choose-registration-items { + align-items: center; + } + .choose-links ul { margin: 0; padding: 0; list-style-type: none; + a { - transition: border .15s linear; + transition: border 0.15s linear; cursor: pointer; border: 1px solid transparent; padding: 10px 20px; display: block; font-size: $choose-reg-font-size; - &:hover { text-decoration: none; } + + &:hover { + text-decoration: none; + } } - .add-selected { display: none; } + + .add-selected { + display: none; + } + .current-choice { border: 1px dashed $gray; + .add-selected { font-family: courier; float: right; display: block; - font-size: .8em; + font-size: 0.8em; } } } - .btn { + + .btn { font-size: $choose-reg-font-size; width: 100%; display: block; @@ -34,6 +48,9 @@ @media (max-width: $grid-breakpoint-sm - 1px) { #welcome_choose_registration { - .add-bike-column { width: 100%; margin: $vertical-height 0; } + .add-bike-column { + width: 100%; + margin: $vertical-height 0; + } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/bikes/edit_accessories.scss b/app/assets/stylesheets/revised/pages/bikes/edit_accessories.scss index d639237d57..2eb6b9f431 100644 --- a/app/assets/stylesheets/revised/pages/bikes/edit_accessories.scss +++ b/app/assets/stylesheets/revised/pages/bikes/edit_accessories.scss @@ -1,17 +1,25 @@ .edit-bike-page-accessories { // Separate the components - .additional-component { border-top: 1px $form-well-divider-color solid; } + .additional-component { + border-top: 1px $form-well-divider-color solid; + } + // Separator for components that are added to the page with js .add-additional-fields-block .additional-component { border-top: none; border-bottom: 1px $form-well-divider-color solid; } + .remove-part { float: right; + label { cursor: pointer; margin-bottom: 0; } - input { display: none; } + + input { + display: none; + } } } diff --git a/app/assets/stylesheets/revised/pages/bikes/edit_photos.scss b/app/assets/stylesheets/revised/pages/bikes/edit_photos.scss index 2e4a2ac0f1..bbad666136 100644 --- a/app/assets/stylesheets/revised/pages/bikes/edit_photos.scss +++ b/app/assets/stylesheets/revised/pages/bikes/edit_photos.scss @@ -1,10 +1,12 @@ .edit-bike-page-photos { .edit-photo-display-list { @include list-unstyled; + .edit-photo-display-wrap { - padding: 0 0.5 * $vertical-height; + padding: 0 (0.5 * $vertical-height); background: white; border: 1px solid $form-well-border-color; + img { display: block; width: 100%; @@ -12,9 +14,12 @@ min-height: 100px; position: relative; background: white; - z-index: 2; // > than .processing + z-index: 2; + + // > than .processing } } + label.keep-private { width: 100%; text-align: right; @@ -23,10 +28,12 @@ font-size: 11px; color: $gray-light; margin-bottom: 0; + input { margin-left: 0.5em; } } + .processing { position: absolute; left: 0; @@ -36,6 +43,7 @@ color: $gray-light; z-index: 1; } + .trash-can-icon { @include trash-can-icon( $gray-light, @@ -43,16 +51,20 @@ white, 2 * $vertical-height ); + display: inline-block; } + .photo-remove { display: block; position: relative; width: 100%; text-align: center; margin-top: 0.5 * $vertical-height; + // make sure zindex sets it above the "processing" text - so you can click it z-index: 100; + // Hovering anywhere on the link colors the trash-can-icon &:hover, &:active, @@ -63,11 +75,14 @@ } } } + .edit-photo-upload { padding-top: 2 * $vertical-height; + label.file { float: right; } + .file-custom { &::before { content: "Upload Photos"; @@ -99,6 +114,7 @@ // the placeholder that's shown while in motion .placeholder { @extend .edit-photo-display-list-item; + height: 280px; border: 3px dashed #ccc; } @@ -117,13 +133,16 @@ background: white; width: 80%; margin: 10px 10% 0; - padding: $vertical-height 0.5 * $vertical-height; + padding: $vertical-height (0.5 * $vertical-height); + .progress, .alert-success { margin-bottom: 0; } + p { @include textoverflow; + margin-bottom: 0.5 * $vertical-height; } } diff --git a/app/assets/stylesheets/revised/pages/bikes/edit_remove.scss b/app/assets/stylesheets/revised/pages/bikes/edit_remove.scss index b12a3ff92d..51290cc2ab 100644 --- a/app/assets/stylesheets/revised/pages/bikes/edit_remove.scss +++ b/app/assets/stylesheets/revised/pages/bikes/edit_remove.scss @@ -2,22 +2,39 @@ .trash-can-icon { float: left; margin-top: -6px; - @include trash-can-icon($body-font-color, $link-color, $form-well-background, 42px); + + @include trash-can-icon( + $body-font-color, + $link-color, + $form-well-background, + 42px + ); } .delete-from-index a { // Hovering anywhere on the link colors the trash-can-icon - &:hover, &:active, &.active { .hover-colorize { background-color: $link-color; } } + &:hover, + &:active, + &.active { + .hover-colorize { + background-color: $link-color; + } + } } + .delete-from-index { max-width: 300px; margin: 0 auto; display: block; - padding-top: 2*$vertical-height; + padding-top: 2 * $vertical-height; + a { cursor: pointer; color: $body-font-color; - &:hover, &:active, &.active { + + &:hover, + &:active, + &.active { color: $link-color; text-decoration: none; } @@ -26,15 +43,21 @@ .hide-this-bike { @extend .full-width-section; + padding-top: $vertical-height; - .hide-this-bike-link { + + .hide-this-bike-link { width: 100%; + a { color: $body-font-color; display: block; width: 100%; text-align: center; - &:hover, &:active, &.active { + + &:hover, + &:active, + &.active { text-decoration: none; color: $link-color; } diff --git a/app/assets/stylesheets/revised/pages/bikes/edit_root.scss b/app/assets/stylesheets/revised/pages/bikes/edit_root.scss index 35635146f4..c39f98e2f2 100644 --- a/app/assets/stylesheets/revised/pages/bikes/edit_root.scss +++ b/app/assets/stylesheets/revised/pages/bikes/edit_root.scss @@ -1,21 +1,28 @@ .edit-bike-page-root { .frame-sizes { .btn { - transition: all .1s linear; + transition: all 0.1s linear; padding-left: 0; padding-right: 0; width: 3em; - &.active, &:active { + + &.active, + &:active { background: $green; color: white; } } - .ordinal-sizes .btn { max-width: 20%; } // Ensure buttons never overflow onto a second line + + .ordinal-sizes .btn { + max-width: 20%; + } + + // Ensure buttons never overflow onto a second line .frame-size-units { min-width: 6.5em; position: absolute; top: 0; - transition: top .1s linear; + transition: top 0.1s linear; } } } @@ -23,21 +30,32 @@ @media (max-width: $grid-breakpoint-sm - 1px) { .edit-bike-page-root { .frame-sizes { - .right-input-help { flex: 0 0 66.6667%; } + .right-input-help { + flex: 0 0 66.6667%; + } + .frame-size-units { top: 15px; right: 0.9375rem; } - &.unexpanded-unit-size { padding-bottom: 6*$vertical-height; } + + &.unexpanded-unit-size { + padding-bottom: 6 * $vertical-height; + } + } + + .frame-size-other .form-well-input { + @include make-col(5); } - .frame-size-other .form-well-input { @include make-col(5); } } } @media (min-width: $grid-breakpoint-sm) { .edit-bike-page-root { .frame-sizes { - .right-input-help { position: relative; } + .right-input-help { + position: relative; + } } } } diff --git a/app/assets/stylesheets/revised/pages/bikes/index.scss b/app/assets/stylesheets/revised/pages/bikes/index.scss index fe6e3a57ba..0fd20f010d 100644 --- a/app/assets/stylesheets/revised/pages/bikes/index.scss +++ b/app/assets/stylesheets/revised/pages/bikes/index.scss @@ -1,7 +1,11 @@ #bikes_index { .no-exact-results { color: $gray; - padding: 2*$vertical-height 0; + padding: (2 * $vertical-height) 0; } - .no-exact-results, .secondary-matches { text-align: center; } -} \ No newline at end of file + + .no-exact-results, + .secondary-matches { + text-align: center; + } +} diff --git a/app/assets/stylesheets/revised/pages/bikes/multi_serial_search.scss b/app/assets/stylesheets/revised/pages/bikes/multi_serial_search.scss index 43dc78e21b..a0ab413d33 100644 --- a/app/assets/stylesheets/revised/pages/bikes/multi_serial_search.scss +++ b/app/assets/stylesheets/revised/pages/bikes/multi_serial_search.scss @@ -1,18 +1,23 @@ $multserial-textheight: 8em; + #multi-serial-search { .multiserial-form { @include clearfix; + position: relative; width: 100%; max-width: 800px; margin: 0 auto; padding: 0 0 30px; + h3 { text-align: center; margin: 0; padding: 0 0 1em; + // font-size: 24px; } + textarea { border-radius: 3px; font-family: courier; @@ -26,6 +31,7 @@ $multserial-textheight: 8em; resize: none; } } + .multiserialsearch-btn { width: 4rem; } @@ -36,26 +42,34 @@ $multserial-textheight: 8em; .multiserials-list { @include clearfix; + list-style-type: none; margin: 0; padding: 10px 0 30px; + li { border-radius: 2px; + @include transition(all linear 0.5s); + float: left; position: relative; padding: 0.2em 0.5em; background: #f7f7f7; margin: 0 5px 5px 0; + &.ms-nomatch { text-decoration: line-through; } + &.ms-match { background: $link-color; color: #fff; } + a { @include transition(all ease-in 0.2s); + position: absolute; width: 100%; height: 100%; @@ -63,18 +77,23 @@ $multserial-textheight: 8em; top: 0; cursor: pointer; opacity: 0.9; + &.blink-class { background: lighten($link-color, 40%); } } } + .multiserial-fuzzy-box { text-align: center; + a { display: none; + span { display: none; } + .ms-short-fuzzy { display: inline-block; } @@ -83,24 +102,31 @@ $multserial-textheight: 8em; .multiserial-results { @include clearfix; + position: relative; border: 1px solid $gray-lighter; padding: 20px 10px; margin: 1em 0; + h3 { margin-top: 0; } + .serial-text { font-size: 0.9em; color: $gray-light; } + li .serial-text { padding-left: 0.5em; } + .multiserial-fuzzy-result { margin-right: 0; + h3 { color: $gray-light; + .serial-text { color: $gray-lighter; } diff --git a/app/assets/stylesheets/revised/pages/bikes/new.scss b/app/assets/stylesheets/revised/pages/bikes/new.scss index 717b6c6a00..4601d4cd23 100644 --- a/app/assets/stylesheets/revised/pages/bikes/new.scss +++ b/app/assets/stylesheets/revised/pages/bikes/new.scss @@ -1,43 +1,67 @@ #bikes_new { - .form-wrap { padding-bottom: 2*$vertical-height; } // Because submit is below, smaller padding + .form-wrap { + padding-bottom: 2 * $vertical-height; + } + + // Because submit is below, smaller padding .form-control.absent-serial { background: darken(white, 10%); color: $gray-light; cursor: default; + // margin-bottom: 1em; - &:active, &:focus { + &:active, + &:focus { border: 1px solid #ccc; + @include box-shadow(none); } } + #made-without-serial-input { display: none; } + #made-without-serial-help { - .hidden-other { margin-top: .5em; } + .hidden-other { + margin-top: 0.5em; + } + a { cursor: pointer; text-decoration: underline; } } + #made-without-serial-modal { - ul { margin-top: -1em; } // Line height looks better this way... + ul { + margin-top: -1em; + } + + // Line height looks better this way... li.li-or { list-style-type: none; font-style: italic; } } + // On new bike registration, this is the wrapper .new-bike-submit-wrapper { - clear: both; // For full size, ensure break from container + clear: both; + + // For full size, ensure break from container padding-top: $vertical-height; width: 100%; text-align: center; - .btn { min-width: 33.33%; } + + .btn { + min-width: 33.33%; + } } + .new-bike-submit-wrapper { @include media-breakpoint-down(lg) { padding-bottom: $primary-footer-top-margin; } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/bikes/show.scss b/app/assets/stylesheets/revised/pages/bikes/show.scss index 68badcb048..15589d83e9 100644 --- a/app/assets/stylesheets/revised/pages/bikes/show.scss +++ b/app/assets/stylesheets/revised/pages/bikes/show.scss @@ -4,88 +4,112 @@ bottom: 0; width: 100%; z-index: $zindex-navbar-fixed - 1; + p { text-align: center; margin: 0; color: white; } + .btn { margin-left: 20px; } + .bike-edit-overlay { @include box-shadow(0 0 2px rgba(black, 0.2)); + padding: $vertical-height; } } + .bike-edit-overlay { background: rgba($blue, 0.92); } h1 { margin-bottom: 0; + .stolen { display: block; color: $red; font-size: 26px; } } + .social-share-bike { @include clearfix; + padding-bottom: $vertical-height; border-bottom: 1px solid $gray-light; + h4 { margin: 6px 0 0; float: left; } } + .contact-the-owner { background: $gray-darker; border-radius: $border-radius; padding: $vertical-height; margin-top: 2 * $vertical-height; margin-bottom: 2 * $vertical-height; + p, h3 { padding: 0 10px; } + p { color: $gray-light; margin-bottom: $vertical-height; } + h3 { color: white; font-size: 21px; } + .additional-field { margin-top: $vertical-height; } + .send-message { @include clearfix; + margin-top: $vertical-height; + .btn { float: right; } } + #write_them_a_message .btn { display: block; } + .phoneable-by { em { display: block; } + strong { @extend .header-font; + color: white; } } } + .show-bike-details h3 { margin-top: 3 * $vertical-height; } + #map_canvas { width: 100%; height: 400px; } + .bike-photos, .show-bike-details, .ad300x600, @@ -94,32 +118,40 @@ } .organized-access-panel { - margin: 2 * $vertical-height 0; + margin: (2 * $vertical-height) 0; + .card-block { padding: 15px; } + .card-title { p, h3 { margin: 0; } + padding-bottom: 0.5 * $vertical-height; border-bottom: 1px solid $gray-lightish; } + .unstolen-notification-box { @extend .clearfix; + border-left: 1px solid $gray-lightish; padding-bottom: $vertical-height; + .form-control { margin-top: 0.5rem; margin-bottom: 0.5rem; } } + .geomessages-wrap { text-align: center; padding: 8px 15px; background: $gray-lighter; border-top: 1px solid $gray-lightish; + span { display: inline-block; padding-right: 1rem; @@ -133,17 +165,23 @@ #bikes_show { .map-holder { width: 100%; - pointer-events: none; // On small screens, prevent manipulation of map so that it can be scrolled past + pointer-events: none; + + // On small screens, prevent manipulation of map so that it can be scrolled past } + .nav-tabs.component-types { @include binx-nav-tabs; } + .tab-content { @include binx-nav-tab-content; } + .cgroup-name { display: none; } + // contact box is a pull out, rather than full width .organized-access-panel { .unstolen-notification-box { @@ -159,6 +197,7 @@ .nav-tabs.component-types { @include binx-nav-tabs-vertical; } + .tab-content { border: none; } @@ -171,19 +210,26 @@ .nav-tabs.component-types { display: none; } + .tab-content.component-group-wrap { - @include make-row(); + @include make-row; + .component-group { display: block; + // width: 100%; - @include make-col-ready(); + @include make-col-ready; + @include make-col(12); + padding-top: $vertical-height; + h3 { margin: 24px 0 12px; } } } + // more space for ad .ad300x600 { margin-top: 4 * $vertical-height; diff --git a/app/assets/stylesheets/revised/pages/bikes/show_photo.scss b/app/assets/stylesheets/revised/pages/bikes/show_photo.scss index ec99f31655..6134f63fdc 100644 --- a/app/assets/stylesheets/revised/pages/bikes/show_photo.scss +++ b/app/assets/stylesheets/revised/pages/bikes/show_photo.scss @@ -2,37 +2,47 @@ // Stock photo text .stock-photo { position: absolute; - top: 0; left: 0; + top: 0; + left: 0; padding: $vertical-height; - background: rgba($blue-dark,.85); - box-shadow: 0 0 2px rgba(black, .2); + background: rgba($blue-dark, 0.85); + box-shadow: 0 0 2px rgba(black, 0.2); border-radius: $border-radius; border: 1px solid lighten($blue-dark, 10%); - border-left: none; border-right: none; + border-left: none; + border-right: none; width: 100%; color: white; text-align: center; + em { display: block; - color: rgba(white, .8); + color: rgba(white, 0.8); } } + .bike-photos { position: relative; + a { overflow: hidden; display: block; } + .image-holder { z-index: 1; + img { - transition: opacity ease-in-out .3s; + transition: opacity ease-in-out 0.3s; + // cursor: zoom-in; opacity: 0; margin: 0 auto; } + .current-photo { z-index: 10; + img { transition: opacity ease-in 1s; opacity: 1; @@ -40,7 +50,9 @@ display: block; } } - .current-photo .transitioning-photo, .transitioning-photo { + + .current-photo .transitioning-photo, + .transitioning-photo { position: absolute; top: 0; left: 0; @@ -52,101 +64,151 @@ width: 100%; height: auto; } + .clickable-image { - transition: all ease-in-out .2s; + transition: all ease-in-out 0.2s; cursor: pointer; border-radius: $border-radius; box-shadow: none; position: relative; - padding: 0; margin: 0; + padding: 0; + margin: 0; display: block; border: 1px solid $gray-lightest; - overflow: hidden; // because they are square images, and we don't care + overflow: hidden; + + // because they are square images, and we don't care &.current-thumb { - transition: all ease-in-out .2s; + transition: all ease-in-out 0.2s; border-color: $blue; - box-shadow: 0 0 3px rgba($blue, .8); + box-shadow: 0 0 3px rgba($blue, 0.8); } } } + .photo-list { border-radius: $border-radius; position: relative; background: $body-bg; padding: 1px; + ul { list-style-type: none; position: absolute; - left: 0; top: 0; + left: 0; + top: 0; overflow: visible; height: 100%; margin: 0; padding: 0; border: none; - li { position: relative; } + + li { + position: relative; + } } } - .thumbnail-shadow, .thumbnail-shadow-r { + + .thumbnail-shadow, + .thumbnail-shadow-r { display: none; position: absolute; z-index: 20; } + .bike-photos.overflown { - .thumbnail-shadow, .thumbnail-shadow-r { display: block; } + .thumbnail-shadow, + .thumbnail-shadow-r { + display: block; + } } + &.zoom-overlay-open .bike-photos { - z-index: $zoom-img-wrap-z-index; // because of inheritance, otherwise below the zoom mask - .image-holder { overflow: visible; } - .photo-list, .thumbnail-shadow, .thumbnail-shadow-r { opacity: 0; } // Or else they z-indexes over the background too + z-index: $zoom-img-wrap-z-index; + + // because of inheritance, otherwise below the zoom mask + .image-holder { + overflow: visible; + } + + .photo-list, + .thumbnail-shadow, + .thumbnail-shadow-r { + opacity: 0; + } + + // Or else they z-indexes over the background too } } -// +// // Horizontal thumbnail list (below the main image) @media (max-width: $grid-breakpoint-md - 1px) { #bikes_show .bike-photos { $thumbnails-height: 120px; $thumbnails-width: 178px; + // Maybe the below is needed for cross browsers? // .current-photo .transitioning-photo, .transitioning-photo { width: 100%; } - .image-holder { overflow: hidden; } + .image-holder { + overflow: hidden; + } + &.overflown { .photo-list ul { - padding: 1px 5px; // To give space for scrolling, covering shadows - and highlighted current photo - left: -2px; // to line up correctly with the shadows + padding: 1px 5px; + + // To give space for scrolling, covering shadows - and highlighted current photo + left: -2px; + + // to line up correctly with the shadows } } - .thumbnail-shadow, .thumbnail-shadow-r { + + .thumbnail-shadow, + .thumbnail-shadow-r { bottom: -2px; - height: $thumbnails-height+2px; - width: 10px; // shadow width + height: $thumbnails-height + 2px; + width: 10px; + + // shadow width } + .thumbnail-shadow { left: 0; - box-shadow: inset 8px 0 6px -8px rgba($gray-lighter,.95); + box-shadow: inset 8px 0 6px -8px rgba($gray-lighter, 0.95); } + .thumbnail-shadow-r { right: 0; - box-shadow: inset -8px 0 6px -8px rgba($gray-lighter,.95); + box-shadow: inset -8px 0 6px -8px rgba($gray-lighter, 0.95); } + .photo-list { - @include clearfix; + @include clearfix; + clear: both; height: $thumbnails-height; width: 100%; margin: 10px 0 0; overflow-y: hidden; overflow-x: scroll; + li { position: relative; float: left; height: 100%; width: $thumbnails-width; margin: 0 10px 5px 0; - &:last-of-type { margin-right: 0; border-right: none; } + + &:last-of-type { + margin-right: 0; + border-right: none; + } } + a { - height: 100%; + height: 100%; width: 100%; overflow: hidden; display: block; @@ -155,19 +217,24 @@ } } -// +// // Vertical thumbnails (to the right of the main image) @media (min-width: $grid-breakpoint-md) { #bikes_show .bike-photos { $thumbnails-height: 120px; $thumbnails-width: 100%; $thumbnail-list-width: 15%; + display: flex; flex-wrap: wrap; + #selected-photo.image-holder { flex: 0 0 83%; position: relative; - &.just1photo { flex: 0 0 100%; } + + &.just1photo { + flex: 0 0 100%; + } } .photo-list { @@ -175,25 +242,40 @@ margin: 0 0 0 2%; overflow-y: scroll; overflow-x: hidden; + li { width: $thumbnails-width; margin: $vertical-height 0 0; - &:first-of-type { margin-top: 0; } + + &:first-of-type { + margin-top: 0; + } } } - .thumbnail-shadow, .thumbnail-shadow-r { - right: -.5%; + + .thumbnail-shadow, + .thumbnail-shadow-r { + right: -0.5%; width: $thumbnail-list-width + 1%; - height: 10px; // shadow width + height: 10px; + + // shadow width } + .thumbnail-shadow { top: 0; - box-shadow: inset 0 8px 6px -8px rgba($gray-lighter,.95); + box-shadow: inset 0 8px 6px -8px rgba($gray-lighter, 0.95); } + .thumbnail-shadow-r { bottom: 0; - box-shadow: inset 0 -8px 6px -8px rgba($gray-lighter,.95); + box-shadow: inset 0 -8px 6px -8px rgba($gray-lighter, 0.95); } - &.overflown .photo-list ul { padding: 5px 1px; } // To give space for scrolling, covering shadows - and highlighted current photo + + &.overflown .photo-list ul { + padding: 5px 1px; + } + + // To give space for scrolling, covering shadows - and highlighted current photo } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/errors.scss b/app/assets/stylesheets/revised/pages/errors.scss index 14358507dd..bd6e2f240c 100644 --- a/app/assets/stylesheets/revised/pages/errors.scss +++ b/app/assets/stylesheets/revised/pages/errors.scss @@ -4,7 +4,11 @@ font-size: 200px; text-align: center; } - .error-explanation { text-align: center; } + + .error-explanation { + text-align: center; + } + .go-back { cursor: pointer; text-align: center; @@ -12,10 +16,10 @@ } } - @media (max-width: 550px) { +@media (max-width: 550px) { #error-page-wrap { .error-text { font-size: 100px; } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/info/about.scss b/app/assets/stylesheets/revised/pages/info/about.scss index 2aa656b256..68d195742f 100644 --- a/app/assets/stylesheets/revised/pages/info/about.scss +++ b/app/assets/stylesheets/revised/pages/info/about.scss @@ -1,51 +1,70 @@ $initial-about-social-color: $gray-light; $hover-about-social-color: lighten($gray-light, 15%); + #info_about { .about-social { @include clearfix; + margin: 24px 0 60px; + ul { @include list-unstyled; + margin: 0; text-align: center; } + li { display: block; float: left; - width: 8*$vertical-height; + width: 8 * $vertical-height; } + svg { display: inline-block; - max-height: 6*$vertical-height; + max-height: 6 * $vertical-height; } + span.social-link-text { display: block; - margin-top: -.5em; + margin-top: -0.5em; color: $initial-about-social-color; } - .svgpath, span.social-link-text { + + .svgpath, + span.social-link-text { fill: $initial-about-social-color; - transition: all .05s linear; + transition: all 0.05s linear; } + a { display: block; position: relative; - &:hover, &:active { + + &:hover, + &:active { text-decoration: none; color: $hover-about-social-color; - .svgpath { fill: $hover-about-social-color; } + + .svgpath { + fill: $hover-about-social-color; + } } } - } + .about-people { @include list-unstyled; + list-style-type: none; margin-left: 0; + li { @include clearfix; + padding-top: 1em; } + img { max-width: 25%; float: left; @@ -53,30 +72,46 @@ $hover-about-social-color: lighten($gray-light, 15%); } } - .the-alumni { display: none; } - .about-alumni-list { display: none; } + .the-alumni { + display: none; + } + + .about-alumni-list { + display: none; + } .about-list { @include clearfix; + @include list-unstyled; + width: 100%; position: relative; + // max-width: $max-content-width; list-style-type: none; margin: 20px 0 0 0; + li { width: 32%; float: left; margin: 0 0 0 2%; position: relative; - &:first-of-type {margin-left: 0; } + + &:first-of-type { + margin-left: 0; + } + img { display: block; width: 100%; } } + &.final-list { - li:first-of-type { margin-left: 16%; } + li:first-of-type { + margin-left: 16%; + } } } } diff --git a/app/assets/stylesheets/revised/pages/info/protect_your_bike.scss b/app/assets/stylesheets/revised/pages/info/protect_your_bike.scss index e61f5962da..299135e965 100644 --- a/app/assets/stylesheets/revised/pages/info/protect_your_bike.scss +++ b/app/assets/stylesheets/revised/pages/info/protect_your_bike.scss @@ -1,22 +1,31 @@ #info_protect_your_bike { - h2 { @extend h5; } + h2 { + @extend h5; + } + #locking-demonstration { @include border-radius(3px); - @include box-shadow(0 0 2px rgba(black,.2)); + + @include box-shadow(0 0 2px rgba(black, 0.2)); + background: $gray-light; padding: 10px; margin: 0 0 60px; - .locked { + + .locked { @include border-radius(2px); + width: 100%; - background: #FFF; + background: #fff; } + img { display: block; max-width: 100%; margin: 0 auto; max-height: 450px; } + p { text-align: center; font-style: italic; @@ -26,5 +35,4 @@ padding: 10px 10px 0; } } - } diff --git a/app/assets/stylesheets/revised/pages/info/where.scss b/app/assets/stylesheets/revised/pages/info/where.scss index 96354fd40b..4e7776d46b 100644 --- a/app/assets/stylesheets/revised/pages/info/where.scss +++ b/app/assets/stylesheets/revised/pages/info/where.scss @@ -1,6 +1,6 @@ #info_where { h1 { - small { + small { font-size: $h5-font-size; display: block; } @@ -9,44 +9,59 @@ .map-of-shops { position: relative; border: 1px solid $gray-light; + #map_canvas { min-height: 400px; height: 100%; width: 100%; } + h3 { margin: 0; } + h4 { - margin: .5em 0 0 0; + margin: 0.5em 0 0 0; } + p { - margin: .5em 0 0 0; + margin: 0.5em 0 0 0; } - .map-telephone { padding-bottom: .5em; } - } + .map-telephone { + padding-bottom: 0.5em; + } + } .where-shops-list { width: 100%; position: relative; margin: 0; + a.shop-title-link { font-weight: normal; color: $body-font-color; + span { color: $body-font-color; margin-bottom: 2px; } + em { color: $gray-light; - font-size: .9em; + font-size: 0.9em; font-style: normal; } } - .shop-info { margin-left: 27px; } - .shop-info.collapse.in { padding-bottom: .6em; } - + + .shop-info { + margin-left: 27px; + } + + .shop-info.collapse.in { + padding-bottom: 0.6em; + } + .where-shop-location { color: $link-color; } @@ -56,12 +71,19 @@ margin: 0; font-weight: 400; } - p { margin: .5em 0 0; } - .map-window { display: none; } + + p { + margin: 0.5em 0 0; + } + + .map-window { + display: none; + } } ul.state-list { @include clearfix; + width: 100%; margin: 0; padding: 0; @@ -69,7 +91,9 @@ position: relative; } - .where-add-shops { margin: 60px 0 40px; } + .where-add-shops { + margin: 60px 0 40px; + } } @media (min-width: 600px) { @@ -79,6 +103,9 @@ width: 50%; float: left; } - .state-name { margin-top: 1em; } + + .state-name { + margin-top: 1em; + } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/landing/_ambassadors.scss b/app/assets/stylesheets/revised/pages/landing/_ambassadors.scss index e4de2e3b32..fe13fd77ec 100644 --- a/app/assets/stylesheets/revised/pages/landing/_ambassadors.scss +++ b/app/assets/stylesheets/revised/pages/landing/_ambassadors.scss @@ -3,38 +3,50 @@ .banner-header .ribbon .noribbon { height: 1px; } + .ambassadors-blank-footer { padding-bottom: 4 * $vertical-height; + @include media-breakpoint-up(md) { padding-bottom: 10 * $vertical-height; } } + .next-steps-col .next-steps-wrap { padding-top: $vertical-height; } + .trusted-by-next-steps { margin-top: 0; + h3 { padding-top: 18px; font-size: 18px; - margin-bottom: 6px; // because line-height + margin-bottom: 6px; + + // because line-height } + ul { padding-bottom: 1.5 * $vertical-height; margin: 0; } + li { display: block; flex: 0 0 100%; padding: 0; position: relative; + a { display: block; - padding: 0 0 0 2 * $vertical-height; + padding: 0 0 0 (2 * $vertical-height); width: 100%; color: $body-font-color; + &.current { text-decoration: underline; + &:before { position: absolute; left: 8px; @@ -53,87 +65,112 @@ .signup-landing-page-ambassadors-current { .banner-header { .icon-wrapper { - margin: 0 auto 2 * $vertical-height auto; + margin: 0 auto (2 * $vertical-height) auto; } + h1, h3 { width: 100%; text-align: center; } + h1 { margin-bottom: 6px; } + h3 { margin-bottom: 36px; } + .btn { font-size: 18px; margin: 0 auto; } } + .ambassadors-list { padding-top: 4 * $vertical-height; padding-bottom: 4 * $vertical-height; text-align: center; + .row { // Read comment in HTML justify-content: space-around; } + img { display: block; width: 100%; height: auto; - margin: 0 0 2 * $vertical-height; + margin: 0 0 (2 * $vertical-height); clip-path: circle(50%); + &.no-clip { clip-path: none; } } + .ambassador-question { font-weight: bold; margin-bottom: $vertical-height; } + h2, h3, h4 { line-height: 1.2rem; } + h2 { font-size: 24px; } + h3 { @extend .body-font; + font-size: 2 * $vertical-height; } + h3, p { font-style: italic; color: $gray-light; } + h4 { @extend .body-font; + font-weight: bold; } } } -$sponsor-tri-1: 20px; // lifted from _recoveries.scss +$sponsor-tri-1: 20px; + +// lifted from _recoveries.scss $sponsor-border-color: $gray-lighter; + .signup-landing-page-ambassadors-current { .sponsored-by-block { - margin-top: 124px; // gross hack, it looks better to me + margin-top: 124px; + + // gross hack, it looks better to me border: 5px solid $sponsor-border-color; padding: 10px; + p { line-height: 1.5; } + em { text-decoration: none; color: $header-font-color; } + img { margin-bottom: 0; } + &:before { content: ""; height: 0; diff --git a/app/assets/stylesheets/revised/pages/landing/_footer.scss b/app/assets/stylesheets/revised/pages/landing/_footer.scss index 3e8b700fae..97dce29fa6 100644 --- a/app/assets/stylesheets/revised/pages/landing/_footer.scss +++ b/app/assets/stylesheets/revised/pages/landing/_footer.scss @@ -1,44 +1,54 @@ -.signup-landing-page, .root-landing-page { +.signup-landing-page, +.root-landing-page { .banner-footer { background-color: $blue-dark; - margin-top: 5*$vertical-height; + margin-top: 5 * $vertical-height; position: relative; - padding: 2*$vertical-height 0; + padding: (2 * $vertical-height) 0; overflow: hidden; + @include media-breakpoint-up(lg) { - padding: 12*$vertical-height 0 11*$vertical-height; + padding: (12 * $vertical-height) 0 (11 * $vertical-height); } + .chainring-bg { display: block; position: absolute; z-index: 0; - background-image: image-url('landing_pages/chainring_bg.svg'); + background-image: image-url("landing_pages/chainring_bg.svg"); background-size: cover; + @include media-breakpoint-down(md) { width: 95vw; height: 95vw; + &:first-of-type { left: -60vw; bottom: -35vw; } + &:last-of-type { right: -30vw; top: -30vw; } } + @include media-breakpoint-up(lg) { width: 45vw; height: 45vw; + &:first-of-type { left: -10vw; bottom: -15vw; } + &:last-of-type { right: -10vw; top: -10vw; } } } + .footer-overlay { display: block; position: absolute; @@ -46,41 +56,59 @@ width: 100%; height: auto; } + h3.landing-container-label { color: #fff; - margin-bottom: 2*$vertical-height; + margin-bottom: 2 * $vertical-height; + @include media-breakpoint-up(lg) { - margin: - 4*$vertical-height 0 6*$vertical-height; + margin: (-4 * $vertical-height) 0 (6 * $vertical-height); } } + ul { @include list-unstyled; + position: relative; + li { - img, svg { + img, + svg { display: block; width: 100%; margin: 0 auto; } + h4 { color: $gray-darker; font-size: 16px; } - p { color: $gray-light; } - a { width: 100%; } + + p { + color: $gray-light; + } + + a { + width: 100%; + } } } } } @media (max-width: $grid-breakpoint-lg - 1px) { - .signup-landing-page, .root-landing-page { + .signup-landing-page, + .root-landing-page { .banner-footer ul li { - margin: 2*$vertical-height auto 0; + margin: (2 * $vertical-height) auto 0; background: white; padding: $vertical-height; max-width: 450px; - .landing-group-card { @include make-row; } + + .landing-group-card { + @include make-row; + } + a { color: $btn-green; padding: 0; @@ -89,19 +117,24 @@ border: 0; text-align: left; text-decoration: none; - &:active, &:hover, + + &:active, + &:hover, &:focus { - &, &:focus { + &, + &:focus { background: none !important; color: $btn-green !important; text-decoration: underline; } } } + h4 { margin-bottom: 12px; line-height: 1.5em; } + p { margin-bottom: 12px; line-height: 1.5em; @@ -109,44 +142,61 @@ } } } + @media (min-width: $grid-breakpoint-lg) { - .signup-landing-page, .root-landing-page { + .signup-landing-page, + .root-landing-page { .banner-footer ul { @include make-row; + li { - @include make-col-ready(); + @include make-col-ready; + @include make-col(3); - img, svg { width: 60%; } - .col-xs-4, .col-xs-8 { + + img, + svg { + width: 60%; + } + + .col-xs-4, + .col-xs-8 { max-width: 100%; flex: 0 0 100%; } + .landing-group-card { background: white; - padding: 2*$vertical-height; + padding: 2 * $vertical-height; } + h4 { - margin: 2*$vertical-height 0 0; + margin: (2 * $vertical-height) 0 0; text-align: center; min-height: 3em; } + p { min-height: 4em; text-align: center; } - a { padding: 0.75rem 0; } + + a { + padding: 0.75rem 0; + } } } } } - @media (min-width: $grid-breakpoint-lg) and (max-width: $grid-breakpoint-xl) { +@media (min-width: $grid-breakpoint-lg) and (max-width: $grid-breakpoint-xl) { // Between lg & xl, text breaks an extra line and throws everything off // so make it wider ;) - .signup-landing-page, .root-landing-page { + .signup-landing-page, + .root-landing-page { .banner-footer ul li p { width: 130%; margin-left: -15%; } } - } \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/landing/_home.scss b/app/assets/stylesheets/revised/pages/landing/_home.scss index 51bd08bc82..528b57d35e 100644 --- a/app/assets/stylesheets/revised/pages/landing/_home.scss +++ b/app/assets/stylesheets/revised/pages/landing/_home.scss @@ -1,115 +1,181 @@ .root-landing-page { - h3.landing-container-label { text-align: center; } + h3.landing-container-label { + text-align: center; + } + .root-action-btn { display: block; max-width: 30em; width: 80%; - margin: 3*$vertical-height auto 0; + margin: (3 * $vertical-height) auto 0; } } .root-landing-banner-header { - background-image: image-url('landing_pages/header_bg_root-1080.jpg'); + background-image: image-url("landing_pages/header_bg_root-1080.jpg"); width: 100%; - padding-top: 12*$vertical-height; - padding-bottom: 6*$vertical-height; + padding-top: 12 * $vertical-height; + padding-bottom: 6 * $vertical-height; background-size: cover; background-position: center bottom; background-repeat: no-repeat; } -@media screen - and (min-device-width: 1000px) { + +@media screen and (min-device-width: 1000px) { .root-landing-banner-header { - background-image: image-url('landing_pages/header_bg_root-2000.jpg'); - } + background-image: image-url("landing_pages/header_bg_root-2000.jpg"); + } } -@media screen - and (min-device-width: 1000px) - and (-webkit-min-device-pixel-ratio: 2) - and (min-resolution: 192dpi) { + +@media screen and (min-device-width: 1000px) and (-webkit-min-device-pixel-ratio: 2) and (min-resolution: 192dpi) { .root-landing-banner-header { - background-image: image-url('landing_pages/header_bg_root-full.jpg'); + background-image: image-url("landing_pages/header_bg_root-full.jpg"); } } .root-landing-banner-header { .root-landing-header-text { - @include make-col-ready(); + @include make-col-ready; + @include make-col(12); - h1, p { color: white; } + + h1, + p { + color: white; + } + p { font-size: 28px; margin-bottom: 0; - strong { color: $green; } + + strong { + color: $green; + } } + h1 { font-size: 60px; } - .root-action-btn { display: none; } + + .root-action-btn { + display: none; + } } + .root-landing-signup { display: none; + $signup-form-border-radius: 4px; + form { - background: rgba(249,249,249,0.6); - padding: 3*$vertical-height 2*$vertical-height; + background: rgba(249, 249, 249, 0.6); + padding: (3 * $vertical-height) (2 * $vertical-height); } - form, .form-control, .btn { + + form, + .form-control, + .btn { border-radius: $signup-form-border-radius; } - .btn { width: 100%; } - label, .or-block { color: white; } + + .btn { + width: 100%; + } + + label, + .or-block { + color: white; + } + // There needs to be a little bit less spacing between the form controls - .form-group.col-md-6:nth-of-type(1) { padding-right: 7px; } - .form-group.col-md-6:nth-of-type(2) { padding-left: 7px; } + .form-group.col-md-6:nth-of-type(1) { + padding-right: 7px; + } + + .form-group.col-md-6:nth-of-type(2) { + padding-left: 7px; + } + .or-block { line-height: 1em; margin: $vertical-height 0; text-transform: uppercase; text-align: center; position: relative; - &:before, &:after { + + &:before, + &:after { display: block; position: absolute; - content: ''; - top: ($body-font-size/2) - 1px; + content: ""; + top: $body-font-size / 2 - 1px; height: 0; width: 44%; border-top: 1px solid white; } - &:before { left: 0; } - &:after { right: 0; } + + &:before { + left: 0; + } + + &:after { + right: 0; + } } } - input { border-color: transparent; } // so we don't overpower the active border + + input { + border-color: transparent; + } + + // so we don't overpower the active border @include media-breakpoint-down(sm) { .root-landing-header-text { - p { font-size: 20px; } + p { + font-size: 20px; + } + h1 { font-size: 45px; - span { display: block; } + + span { + display: block; + } } } } + @include media-breakpoint-down(md) { .root-landing-header-text { - .root-action-btn { display: block; } + .root-action-btn { + display: block; + } } } + @include media-breakpoint-up(lg) { - padding-top: 20*$vertical-height; - padding-bottom: 12*$vertical-height; + padding-top: 20 * $vertical-height; + padding-bottom: 12 * $vertical-height; + .root-landing-header-text { margin-top: 55px; + @include make-col(7); - p { line-height: 1.3em; } + + p { + line-height: 1.3em; + } } + .root-landing-signup { display: block; - @include make-col-ready(); + + @include make-col-ready; + @include make-col(5); } } + @include media-breakpoint-up(xl) { .root-landing-header-text { margin-top: 85px; @@ -118,45 +184,61 @@ } .root-landing-how-it-works { - padding-top: 4*$vertical-height; - h3.landing-container-label, h4 { color: $header-font-nocolor; } + padding-top: 4 * $vertical-height; + + h3.landing-container-label, + h4 { + color: $header-font-nocolor; + } + .row { - margin-top: 5*$vertical-height; + margin-top: 5 * $vertical-height; + @include media-breakpoint-up(lg) { - margin-top: 7*$vertical-height; + margin-top: 7 * $vertical-height; + &:nth-of-type(2n) .root-landing-how-icon { @include make-col-offset(3); + .root-icon-connector { right: 120%; transform: rotate(45deg); } } + &:nth-of-type(3) .root-landing-how-icon .root-icon-connector { top: 72%; } } + @include media-breakpoint-down(sm) { &:last-of-type .root-landing-explanation { padding-top: 0; } } } + .root-landing-how-icon { padding-right: 0; - svg, img { + + svg, + img { width: 100%; height: auto; display: block; } + @include media-breakpoint-down(sm) { width: 50%; margin: 0 auto; } + .root-icon-connector { display: none; + @include media-breakpoint-up(lg) { display: block; - height: 17*$vertical-height; + height: 17 * $vertical-height; width: auto; position: absolute; right: -32%; @@ -165,49 +247,68 @@ } } } + .root-landing-explanation { .root-landing-explanation-wrap { - padding-top: 2*$vertical-height; + padding-top: 2 * $vertical-height; + // position: relative; // top: 50%; // transform: translateY(-50%); padding-left: 15px; } + h4 { font-size: 21px; margin-bottom: $vertical-height; } + p { color: $gray-light; font-size: 18px; margin-bottom: 0; } + @include media-breakpoint-down(sm) { - padding-top: 4*$vertical-height; - h4, p { text-align: center; } + padding-top: 4 * $vertical-height; + + h4, + p { + text-align: center; + } } } } .root-landing-who { - padding-bottom: 6*$vertical-height; + padding-bottom: 6 * $vertical-height; + h3.landing-container-label { color: $gray-darker; - margin: 2*$vertical-height 0; + margin: (2 * $vertical-height) 0; + @include media-breakpoint-up(lg) { - margin: 4*$vertical-height 0; + margin: (4 * $vertical-height) 0; } } + .root-landing-who-wrap { display: none; flex-wrap: wrap; } + &.scrolled .root-landing-who-wrap { display: flex; - img { display: block; } + + img { + display: block; + } } - .root-landing-who-square, .root-landing-who-rectangle { - padding: $vertical-height 0.5*$vertical-height 2*$vertical-height; + + .root-landing-who-square, + .root-landing-who-rectangle { + padding: $vertical-height (0.5 * $vertical-height) (2 * $vertical-height); + img { display: none; width: 100%; @@ -215,10 +316,22 @@ position: relative; } } - .root-landing-who-square { flex: 0 0 10%; } - .root-landing-who-rectangle { flex: 0 0 20%; } + + .root-landing-who-square { + flex: 0 0 10%; + } + + .root-landing-who-rectangle { + flex: 0 0 20%; + } + @include media-breakpoint-down(sm) { - .root-landing-who-square { flex: 0 0 20%; } - .root-landing-who-rectangle { flex: 0 0 40%; } + .root-landing-who-square { + flex: 0 0 20%; + } + + .root-landing-who-rectangle { + flex: 0 0 40%; + } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/landing/_organizations.scss b/app/assets/stylesheets/revised/pages/landing/_organizations.scss index 42d86247fb..01fc725778 100644 --- a/app/assets/stylesheets/revised/pages/landing/_organizations.scss +++ b/app/assets/stylesheets/revised/pages/landing/_organizations.scss @@ -1,72 +1,132 @@ // Outside of the main block to avoid overriding header and footer styles .organization-landing-page-wrap { - h1, h2, h3, h4, h5, h6 { color: $header-font-nocolor; } + h1, + h2, + h3, + h4, + h5, + h6 { + color: $header-font-nocolor; + } } + // Organization landing pages padding (so there can be a background) -#organized_manage_landing, #landing_pages_show { +#organized_manage_landing, +#landing_pages_show { padding-top: 0; background-size: 100% auto; background-position: center top; background-repeat: no-repeat; + .primary-footer { margin-top: 0; - .primary-footer-nav h4 a { color: $gray-light; } + + .primary-footer-nav h4 a { + color: $gray-light; + } + } + + h1 { + text-align: center; } - h1 { text-align: center; } + h3 { - margin-bottom: 0.5*$vertical-height; + margin-bottom: 0.5 * $vertical-height; font-size: 18px; } + .org-landing-wrapper { - padding-top: 88px; + padding-top: 88px; background: #fff; - padding-bottom: 4*$vertical-height; - .row:nth-of-type(2) { margin-top: 36px; } + padding-bottom: 4 * $vertical-height; + + .row:nth-of-type(2) { + margin-top: 36px; + } } + @include media-breakpoint-up(lg) { padding-top: 0; - h1 { margin-bottom: 4*$vertical-height; } - .org-landing-wrapper { padding-top: 120px; } + + h1 { + margin-bottom: 4 * $vertical-height; + } + + .org-landing-wrapper { + padding-top: 120px; + } } + @include media-breakpoint-up(sm) { .org-landing-wrapper { - padding-left: 3.5*$vertical-height; - padding-right: 3.5*$vertical-height; + padding-left: 3.5 * $vertical-height; + padding-right: 3.5 * $vertical-height; } } + @include media-breakpoint-down(md) { - .org-landing-embed-col { width: 100%; } - .org-landing-embed-facebook { width: 340px; margin: 0 auto; } + .org-landing-embed-col { + width: 100%; + } + + .org-landing-embed-facebook { + width: 340px; + margin: 0 auto; + } } } // Organization landing pages base styles .org-landing-icon-list { @include list-unstyled; + margin: 0; + li { min-height: 96px; + img { display: block; width: 100%; margin: 0 auto; } } + @include media-breakpoint-up(md) { li { @include make-row; - margin-top: 2*$vertical-height; - &:first-of-type { margin-top: $vertical-height; } - .org-landing-icon-list-icon { @include make-col(2); } - .org-landing-icon-list-icon, .org-landing-icon-list-text { @include make-col-ready(); } - .org-landing-icon-list-icon { @include make-col(2); } - .org-landing-icon-list-text { @include make-col(10); } + + margin-top: 2 * $vertical-height; + + &:first-of-type { + margin-top: $vertical-height; + } + + .org-landing-icon-list-icon { + @include make-col(2); + } + + .org-landing-icon-list-icon, + .org-landing-icon-list-text { + @include make-col-ready; + } + + .org-landing-icon-list-icon { + @include make-col(2); + } + + .org-landing-icon-list-text { + @include make-col(10); + } } } + @include media-breakpoint-down(md) { li { .org-landing-icon-list-icon { - width: 16.66667%; // col-2 + width: 16.66667%; + + // col-2 margin: 0 auto $vertical-height; } } @@ -78,20 +138,27 @@ font-size: 21px; margin-bottom: 9px; } + img { display: block; width: 100%; height: auto; - border-bottom: .5*$vertical-height solid $blue-dark; + border-bottom: (0.5 * $vertical-height) solid $blue-dark; margin: 0 0 $vertical-height; } + ul { @include list-unstyled; + margin: 0; display: block; - a { color: $body-font-color; } + + a { + color: $body-font-color; + } } + @include media-breakpoint-down(md) { - margin-bottom: 2*$vertical-height; + margin-bottom: 2 * $vertical-height; } } diff --git a/app/assets/stylesheets/revised/pages/landing/_point_of_sale.scss b/app/assets/stylesheets/revised/pages/landing/_point_of_sale.scss index 91f3c05727..978d40c6f0 100644 --- a/app/assets/stylesheets/revised/pages/landing/_point_of_sale.scss +++ b/app/assets/stylesheets/revised/pages/landing/_point_of_sale.scss @@ -1,7 +1,8 @@ .ascend-image { width: 100%; - margin: 0 0 2 * $vertical-height; + margin: 0 0 (2 * $vertical-height); clear: both; + svg, img { padding-top: 100px; @@ -23,9 +24,9 @@ // margin-right: -20px; // margin-bottom: -44px; background: white; + p { font-weight: bold; text-indent: 20px; } } - diff --git a/app/assets/stylesheets/revised/pages/landing/_recoveries.scss b/app/assets/stylesheets/revised/pages/landing/_recoveries.scss index 05265b60eb..fb1006be66 100644 --- a/app/assets/stylesheets/revised/pages/landing/_recoveries.scss +++ b/app/assets/stylesheets/revised/pages/landing/_recoveries.scss @@ -1,6 +1,6 @@ .root-landing-recovery-stories { background: #f9f9f9; - padding: 4*$vertical-height 0; + padding: (4 * $vertical-height) 0; } #recovery-stories-listing { @@ -13,8 +13,15 @@ width: 90%; margin: 0 auto; position: relative; - .slick-prev { left: -6%; } - .slick-next { right: -6%; } + + .slick-prev { + left: -6%; + } + + .slick-next { + right: -6%; + } + .slick-prev, .slick-next { &:before { @@ -24,25 +31,37 @@ font-family: sans-serif; } } + // Avoid having a flash where all the recoveries are shown &.extras-hidden .recovery-block { - &:nth-of-type(n+2) { display: none; } + &:nth-of-type(n + 2) { + display: none; + } } } $recovery-tri-1: 20px; $recovery-text-bg: #fff; + .recovery-block { @include clearfix; - - h3, h4, p { margin: 0; } + + h3, + h4, + p { + margin: 0; + } + .recovery-user { display: block; + @include clearfix; + position: relative; margin: 0 5% 0 0; float: left; } + img { display: block; margin: 0; @@ -50,25 +69,31 @@ $recovery-text-bg: #fff; font-size: 16px; height: auto; float: right; - padding-bottom: .5em; + padding-bottom: 0.5em; } + .h3recovery { - margin: .25em 0 0; + margin: 0.25em 0 0; font-size: 18px; display: block; font-weight: normal; } + .h4recovery { font-size: 14px; display: block; } - // $row-width: 3.438; // 100/32 - full width over 4 column - $row-width: 2.083; // 100/48 - full width over 4 column - .h3recovery, .h4recovery { + + // $row-width: 3.438; // 100/32 - full width over 4 column + $row-width: 2.083; + + // 100/48 - full width over 4 column + .h3recovery, + .h4recovery { float: left; text-align: right; - margin-left: 2%*$row-width; - width: 80%-2%*$row-width; + margin-left: 2% * $row-width; + width: 80% - 2% * $row-width; } .recovery-quote { @@ -80,29 +105,37 @@ $recovery-text-bg: #fff; padding: 1em 1em 1em 3em; line-height: 1.3em; border: 5px solid $gray; - svg, img { + + svg, + img { width: 1.25em; height: auto; display: block; position: absolute; top: 1em; left: 1em; - .svg-q-p { fill: #3498db; } + + .svg-q-p { + fill: #3498db; + } } + &:before { - content: ''; + content: ""; height: 0; width: 0; - left: -($recovery-tri-1*1.4); + left: -($recovery-tri-1 * 1.4); position: absolute; - border-bottom: $recovery-tri-1 solid transparent; - border-right: ($recovery-tri-1*1.3) solid $gray; + border-bottom: $recovery-tri-1 solid transparent; + border-right: ($recovery-tri-1 * 1.3) solid $gray; } + .precovery { margin: 0; line-height: 1.2em; } } + .see-more-link { font-size: 2rem; display: flex; @@ -121,46 +154,63 @@ $recovery-text-bg: #fff; } } -@media (min-width: $grid-breakpoint-sm+1) { +@media (min-width: $grid-breakpoint-sm + 1) { .recovery-block { .recovery-user { width: 22.5%; } - .h3recovery, .h4recovery { margin-left: 0; } + + .h3recovery, + .h4recovery { + margin-left: 0; + } + .no-image-spacer { display: block; width: 100%; padding: 10px; } + img { width: 100%; } - .h3recovery { padding-top: 1em; } - .h3recovery, .h4recovery { + + .h3recovery { + padding-top: 1em; + } + + .h3recovery, + .h4recovery { width: 100%; float: none; text-align: center; } + .recovery-quote { - font-size: 18px; - &:before { top: 0; } + font-size: 18px; + + &:before { + top: 0; + } } } } @media (min-width: $grid-breakpoint-sm) { - .recovery-block { - .recovery-user { - padding-left: .5em; + .recovery-block { + .recovery-user { + padding-left: 0.5em; } + .h4recovery .recovery-date { - display: block; - margin-top: -.25em; + display: block; + margin-top: -0.25em; } } } $recovery-tri-2: 15px; + @media (max-width: $grid-breakpoint-sm) { .recovery-block { .recovery-user { @@ -168,30 +218,38 @@ $recovery-tri-2: 15px; padding: 20px 5% 0 0; margin: 0; } - .h3recovery { margin-top: 1em; } - .h3recovery, .h4recovery { + + .h3recovery { + margin-top: 1em; + } + + .h3recovery, + .h4recovery { text-align: right; margin-right: 2%; margin-left: 0; } - img { - float: right; + + img { + float: right; } + .recovery-quote { width: 99%; - margin: 0 .5%; + margin: 0 0.5%; position: relative; &:before { left: 90%; bottom: -($recovery-tri-2 + 9px); - border-left: $recovery-tri-2 solid transparent;; - border-bottom: $recovery-tri-2*1.5 solid transparent; + border-left: $recovery-tri-2 solid transparent; + border-bottom: ($recovery-tri-2 * 1.5) solid transparent; border-right: $recovery-tri-2 solid $gray; } } + .see-more-link { margin: 35%; } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/landing/_signup.scss b/app/assets/stylesheets/revised/pages/landing/_signup.scss index 190eb3e913..440361881f 100644 --- a/app/assets/stylesheets/revised/pages/landing/_signup.scss +++ b/app/assets/stylesheets/revised/pages/landing/_signup.scss @@ -3,6 +3,7 @@ .landing-page-body, #welcome_index { padding-top: 0; + .primary-footer { margin-top: 0; } @@ -10,6 +11,7 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", "ambassadors-how-to", "ambassadors-current"; + @each $target in $landing-page-targets { .signup-landing-page-#{$target} { .banner-header { @@ -26,9 +28,11 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", .svgicon-border { fill: #3498db; } + .svgicon-bg { fill: #34495e; } + .svgicon-body { fill: #fff; } @@ -39,20 +43,26 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", .trusted-by { ul { @include list-unstyled; + display: flex; flex-wrap: wrap; } + li { flex: 0 0 20%; + &.partner-logo-rectangle { flex: 0 0 40%; } - padding: $vertical-height 0.5 * $vertical-height 2 * $vertical-height; + + padding: $vertical-height (0.5 * $vertical-height) (2 * $vertical-height); + img { display: block; width: 100%; height: auto; } + &.offset-partner-logo { margin-left: 20%; } @@ -67,14 +77,17 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", background-size: auto 100%; background-position: center top; background-repeat: no-repeat; + // For extra wide screens, make sure we cover the whole screen @include media-breakpoint-up(lg) { background-size: cover; } + .icon-wrapper { width: 100%; margin: 0; clear: both; + svg, img { width: 25%; @@ -82,20 +95,26 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", margin: 0 auto; } } + .banner-text { - @include make-col-ready(); + @include make-col-ready; + @include make-col(12); + margin-top: 2 * $vertical-height; } + h1, h2, h3 { color: white; text-align: center; } + h1 { line-height: 1.4em; } + h2, h3 { font-family: $body-font-family; @@ -105,6 +124,7 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", font-size: 21px; line-height: 1.6em; } + .ribbon { display: none; } @@ -112,33 +132,40 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", @include media-breakpoint-up(md) { padding-top: 17 * $vertical-height; padding-bottom: 0; + .icon-wrapper { // There is a 1/6 overhang to the left (8.33333/6 ~ 1.33333) flex: 0 0 9.66666%; max-width: 9.66666%; margin-left: -1.3333%; + svg, img { width: 100%; } } + .banner-text { @include make-col(7); + margin-top: 0; } + h1, h2, h3 { text-align: left; } + .ribbon { display: block; margin-top: 7 * $vertical-height; background: $gray-darker; + h2 { font-size: 24px; margin: 0; - padding: 2 * $vertical-height 0; + padding: (2 * $vertical-height) 0; } } } @@ -151,17 +178,23 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", flex-direction: column-reverse; } } + .landing-why-col, .next-steps-col { - @include make-col-ready(); + @include make-col-ready; } + .landing-why-col { margin-top: 2 * $vertical-height; + @include make-col(8); + @include media-breakpoint-down(md) { @include make-col(12); + min-height: auto; } + @include media-breakpoint-up(lg) { @include make-col(7); } @@ -172,85 +205,107 @@ $landing-page-targets: "shop", "school", "advocacy", "law_enforcement", } $contact-us-gutter: 30px; + .next-steps-col { margin-top: -9.5 * $vertical-height; + @include make-col(5); + @include media-breakpoint-down(md) { @include make-col(12); + min-height: auto; } + @include media-breakpoint-up(xl) { @include make-col(4); + @include make-col-offset(1); } + .next-steps-wrap { position: -webkit-sticky; position: sticky; top: 0; - padding: 2.5 * $vertical-height $contact-us-gutter; + padding: (2.5 * $vertical-height) $contact-us-gutter; background: $gray-darker; border-radius: $border-radius; } + .form-group.additional-field { display: none !important; } + header { background: $gray; - padding: 2 * $vertical-height 0; + padding: (2 * $vertical-height) 0; color: white; text-align: center; font-size: 30px; line-height: 1; margin-bottom: 2 * $vertical-height; } + .btn { width: 100%; margin-top: 2 * $vertical-height; } } + .trusted-by-next-steps { - margin: 2 * $vertical-height -15px 0; + margin: (2 * $vertical-height) -15px 0; background: white; + h3 { - padding: 2 * $vertical-height 0.5 * $vertical-height 0; + padding: (2 * $vertical-height) (0.5 * $vertical-height) 0; } + ul { @include list-unstyled; + display: flex; flex-wrap: wrap; } + li { flex: 0 0 33%; + &.partner-logo-rectangle { flex: 0 0 66%; } - padding: 0 0.5 * $vertical-height 2 * $vertical-height; + + padding: 0 (0.5 * $vertical-height) (2 * $vertical-height); + img { display: block; width: 100%; height: auto; } } + .hidden-on-trusted-by-next-steps { display: none; } } + .landing-lightspeed-logo { max-width: 280px; - margin: 2 * $vertical-height 0 -1 * $vertical-height 0; + margin: (2 * $vertical-height) 0 (-1 * $vertical-height) 0; display: block; } } .signup-landing-page { .mobile-contact-link { - margin: 2 * $vertical-height 0 4 * $vertical-height; + margin: (2 * $vertical-height) 0 (4 * $vertical-height); + a { display: block; width: 20em; max-width: 100%; margin: 0 auto; } + @include media-breakpoint-up(lg) { display: none; } diff --git a/app/assets/stylesheets/revised/pages/legacy_stolen.scss b/app/assets/stylesheets/revised/pages/legacy_stolen.scss index 6eb9d03684..9877b939a1 100644 --- a/app/assets/stylesheets/revised/pages/legacy_stolen.scss +++ b/app/assets/stylesheets/revised/pages/legacy_stolen.scss @@ -9,10 +9,12 @@ h3 { font-size: $h5-font-size; } + h1 { font-size: $h3-font-size; } } + //________________________ // // Stolen styles @@ -27,15 +29,19 @@ $sbr-background: #f9f9f9; // input { font-family: $headerFont; } background: $sbr-background; color: #7a7a7a; + .list-stolen-bike { margin-top: 3px; float: right; + // color: #7a7a7a; // color: $link-color; } + section { border-bottom: 1px solid $gray; padding: 30px 0; + &:nth-of-type(2n) { background: #fff; } @@ -46,16 +52,19 @@ $sbr-background: #f9f9f9; .alert h4 { font-size: 24px; } + .stolen-registry-logo { width: 200px; margin: 0 auto; padding: 2.5em 0 30px; + img { display: block; width: 100%; height: auto; } } + h1 { font-size: 30px; text-align: center; @@ -63,6 +72,7 @@ $sbr-background: #f9f9f9; padding: 0 0 40px; } } + // @media (min-width: 600px) { // #stolen_index .sbr-main-section { // h1 { font-size: 40px; } @@ -86,22 +96,27 @@ $sbr-background: #f9f9f9; #stolen_index .sbr-search-fields { @include clearfix; + max-width: 800px; margin: 0 auto; padding-bottom: 40px; + input { box-shadow: none; border: 1px solid #cccdc8; background: #fff; color: darken(#7a7a7a, 20%); margin-bottom: 0.75em; + &:focus { box-shadow: none; border-color: #cccdc8; } } + .proximity { clear: both; + input { background: none; border: none; @@ -114,18 +129,22 @@ $sbr-background: #f9f9f9; border-bottom: 1px dashed #cccdc8; } } + .sbr-search-inputs { position: relative; } + .sbr-bike-search { box-shadow: none; padding: 0.4em 0.7em; width: 100%; float: left; border-radius: 2px; + // border-left: none; margin-top: 5px; } + .search-type-tab { background: #e6e6e6; padding: 5px 10px 3px 10px; @@ -136,17 +155,21 @@ $sbr-background: #f9f9f9; border-bottom: none; position: relative; z-index: 10; + &:first-of-type { margin-left: 10px; } + &.active { background: #fff; padding-bottom: 5px; border-bottom: 1px solid #fff; + &:hover { background: #fff; } } + &:hover { // background: darken(#f9f9f9, 10%); background: $sbr-background; @@ -154,6 +177,7 @@ $sbr-background: #f9f9f9; } } } + #stolen_index .sbrbtn { height: 1.9em; position: absolute; @@ -164,11 +188,13 @@ $sbr-background: #f9f9f9; background: none; font-size: 19px; border-radius: 2px; + img { display: block; height: 100%; width: auto; } + &:hover, &:active, &:focus { @@ -177,6 +203,7 @@ $sbr-background: #f9f9f9; border: none; outline: none; } + &:active { background: #d25627; } @@ -187,6 +214,7 @@ $sbr-background: #f9f9f9; .sbrbtn { top: 0.4em; } + .proximity input { width: 8em; } @@ -206,10 +234,13 @@ $sbr-background: #f9f9f9; .banner { text-align: center; padding: 20px 0 60px; + // font-weight: 400; // font-size: 20px; } + @include clearfix; + h1 { text-align: center; margin: 0 0 1em; @@ -222,12 +253,15 @@ $sbr-background: #f9f9f9; border-radius: 4px; padding: 20px 10px; color: #fff; + form { margin: 0; } + input { background: #fff; } + input[type="email"], textarea { // font-size: 16px; @@ -238,15 +272,18 @@ $sbr-background: #f9f9f9; background: $sbr-background; color: darken(#7a7a7a, 20%); margin-bottom: 0.75em; + // &:focus, &:active { // background: #fff; // } // &:focus { box-shadow: none; border-color: #cccdc8; } } + .contact-text { padding-top: 1em; width: 100%; position: relative; + textarea { display: block; width: 100%; @@ -254,10 +291,13 @@ $sbr-background: #f9f9f9; padding: 0.5em; } } + .contact-actions { @include clearfix; + width: 100%; position: relative; + input[type="email"] { display: block; width: 70%; @@ -265,6 +305,7 @@ $sbr-background: #f9f9f9; padding-left: 0.5em; padding-right: 0.5em; } + .btn { // font-size: 16px; // border-radius: 3px; @@ -272,6 +313,7 @@ $sbr-background: #f9f9f9; float: left; width: 28%; margin: 0 0 0 2%; + // padding: .3em .5em; } } @@ -297,14 +339,18 @@ $sbr-background: #f9f9f9; #stolen_index { .involve-yerself { @include clearfix; + padding-bottom: 60px; + h3 { margin-top: 0; } } + .involve-report { width: 60%; float: left; + .involve-report-form { height: 350px; } @@ -316,6 +362,7 @@ $sbr-background: #f9f9f9; margin-left: 2%; } } + // .stolen-recent-widget { // max-height: 350px; // overflow: auto; @@ -336,25 +383,31 @@ $sbr-background: #f9f9f9; .sticker-wells { margin: 30px 0; } + .sticker-well { select { margin-top: 0.5em; } + .sticker-image { @include box-shadow(1px 1px 2px rgba(black, 0.4)); + margin-bottom: 1em; } } } + @media (min-width: 800px) { #stolen_index { .sticker-wells { @include clearfix; } + .sticker-well { width: 49%; float: left; min-height: 350px; + &:nth-of-type(2) { margin-left: 2%; } diff --git a/app/assets/stylesheets/revised/pages/locks/lock_styles.scss b/app/assets/stylesheets/revised/pages/locks/lock_styles.scss index 0cc48d8d2e..c882d6647f 100644 --- a/app/assets/stylesheets/revised/pages/locks/lock_styles.scss +++ b/app/assets/stylesheets/revised/pages/locks/lock_styles.scss @@ -10,24 +10,30 @@ #lock-form { padding: 50px 0 100px; + .control-group { margin-bottom: 0; padding: 1em; } + .submit-button { margin-top: 20px; max-width: 780px; + .btn { float: right; } } + .destroy-button { margin-top: 20px; max-width: 780px; + .btn { float: left; } } + .lock-notes { max-width: 780px; } @@ -42,13 +48,18 @@ .lock-types-select { @include clearfix; } -.lock-type-title { display: none; } + +.lock-type-title { + display: none; +} + .lock-type { position: relative; width: 20%; max-width: 120px; float: left; padding-right: 15px; + span { display: block; width: 100%; @@ -56,6 +67,7 @@ text-align: left; padding-left: 20px; } + div { width: 100%; padding-right: 15px; @@ -72,47 +84,68 @@ height: 100%; padding: 0 22px 40px 0; display: block; - label { text-align: right; cursor: default;} + + label { + text-align: right; + cursor: default; + } } } @media (max-width: 600px) { .lock-type { - span { padding: 1.5em 0 0; text-align: center; } - div { input { display: block; margin: 0 auto;}} + span { + padding: 1.5em 0 0; + text-align: center; + } + + div { + input { + display: block; + margin: 0 auto; + } + } } } .lock-pictures { @extend .alert; + @include clearfix; + width: 100%; max-width: 700px; position: relative; margin: 20px; + h2 { width: 100%; font-size: 24px; } + section { float: left; position: relative; width: 32%; margin-right: 2%; + a { display: block; cursor: pointer; } } + img { width: 100%; height: auto; - margin-bottom: .5em; + margin-bottom: 0.5em; } + p { clear: both; } + section:nth-of-type(3) { margin-right: 0; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/news/index.scss b/app/assets/stylesheets/revised/pages/news/index.scss index 41fd9cc303..684d78c4f1 100644 --- a/app/assets/stylesheets/revised/pages/news/index.scss +++ b/app/assets/stylesheets/revised/pages/news/index.scss @@ -2,9 +2,16 @@ .blog-index-head { a { float: right; - opacity: .4; - &:hover { opacity: 1; } - img { height: .75em; margin-top: -.2em; } + opacity: 0.4; + + &:hover { + opacity: 1; + } + + img { + height: 0.75em; + margin-top: -0.2em; + } } } @@ -14,18 +21,24 @@ list-style-type: none; margin: 0; padding: 0; + li { @include clearfix; + padding: 10px 0 20px; + h2 { font-size: 23px; - margin: 0; padding: 0; + margin: 0; + padding: 0; } + .index-image-link { display: block; width: 15%; float: left; margin-right: 2%; + img { width: 100%; display: block; @@ -39,7 +52,9 @@ @media (max-width: $grid-breakpoint-md) { #news_index { ul.news-index-list li { - h2 { font-size: 19px; } + h2 { + font-size: 19px; + } } } } diff --git a/app/assets/stylesheets/revised/pages/news/show.scss b/app/assets/stylesheets/revised/pages/news/show.scss index bb2488884c..a4b14c2b89 100644 --- a/app/assets/stylesheets/revised/pages/news/show.scss +++ b/app/assets/stylesheets/revised/pages/news/show.scss @@ -8,39 +8,42 @@ .post-image-bordered { @extend .post-image; - @include box-shadow(0 0 1px rgba(black,.4)); + + @include box-shadow(0 0 1px rgba(black, 0.4)); } .post-image-padded { @extend .post-image; + padding: 20px 0; } - .blog-pad { clear: both; display: block; position: relative; width: 100%; - padding: 30px 0 0; + padding: 30px 0 0; } - .blog-index .post-image { display: none; } + .blog-index .post-image { + display: none; + } .blog-subhead { font-weight: normal; font-size: 22px; - margin-top: -.7em; + margin-top: -0.7em; margin-bottom: 1.5em; } - .padded-clear { + .padded-clear { padding-top: 30px; clear: both; } .post-image-float-40 { - float:left; + float: left; max-width: 40%; margin: 0 2% 1em 0; } @@ -62,36 +65,40 @@ border-left: 10px solid #ccc; margin: 1.5em 10px 0; padding: 0.5em 10px; - quotes: "\201C""\201D""\2018""\2019"; - &.beside-float-40 { margin: 0; } + quotes: "“" "”" "‘" "’"; + + &.beside-float-40 { + margin: 0; + } } + blockquote:before { color: #ccc; content: open-quote; font-size: 3em; - vertical-align: -.4em; + vertical-align: -0.4em; line-height: 0.1em; margin-right: 0.25em; } - + blockquote:after { content: close-quote; color: $gray-lighter; font-size: 4px; } - blockquote p { display: inline; } - + blockquote p { + display: inline; + } .blockquote-cite { text-align: right; - padding: .5em 10px 1em 0; + padding: 0.5em 10px 1em 0; color: $gray; font-weight: 200; } } - //________________________ // // Listicles! @@ -100,7 +107,7 @@ .listicle-image-credit { text-align: right; - font-size: .8em; + font-size: 0.8em; } // .list-item-title { @@ -110,16 +117,26 @@ .list-nav-wrap { @include clearfix; + width: 100%; max-width: 320px; - margin: 0 auto; + margin: 0 auto; + a { @extend .btn; + @extend .btn-primary; + width: 45%; - padding: 1em .25em; + padding: 1em 0.25em; + } + + .prev { + float: left; + } + + .next { + float: right; } - .prev { float: left; } - .next { float: right; } } } diff --git a/app/assets/stylesheets/revised/pages/organized/_exports.scss b/app/assets/stylesheets/revised/pages/organized/_exports.scss index 31a50a89a6..9cf0ae9e20 100644 --- a/app/assets/stylesheets/revised/pages/organized/_exports.scss +++ b/app/assets/stylesheets/revised/pages/organized/_exports.scss @@ -7,14 +7,18 @@ padding: 0.5rem 0.75rem; line-height: 1.25; } + .collapsed-fields { display: none; } + .field-collapser { @extend small; + display: block; text-align: right; } + .shownOnAveryExport { display: none; } diff --git a/app/assets/stylesheets/revised/pages/organized/forms.scss b/app/assets/stylesheets/revised/pages/organized/forms.scss index f568f2c8fb..81c3294587 100644 --- a/app/assets/stylesheets/revised/pages/organized/forms.scss +++ b/app/assets/stylesheets/revised/pages/organized/forms.scss @@ -2,19 +2,24 @@ .checkbox input { margin-top: 0.6em; } + .form-well-input { @include media-breakpoint-down(xs) { - @include make-col-ready(); + @include make-col-ready; + @include make-col(12); } } + .org-form-label { @extend .col-sm-4; + @include media-breakpoint-up(sm) { text-align: right; margin-top: 0.25rem; } } + // Because of increasing the margin to align text-box labels, // make the margin larger on non-text box fields .static-form-control, @@ -26,56 +31,72 @@ } } } + .form-submit-button { - @include make-col-ready(); + @include make-col-ready; + @include media-breakpoint-up(sm) { @include make-col(8); + @include make-col-offset(4); } } + .export-included-columns-label { @extend .less-strong; + margin-bottom: 0; + @include media-breakpoint-up(lg) { text-align: right; margin-top: 0.25rem; } } + .locations-where-and-add { padding-bottom: $vertical-height; + .btn { margin-top: -6px; } } + .locations-fieldset-wrapper { @extend .row; + fieldset { display: flex; } + .address-group { label { margin-bottom: 0; } + .selectize-control, input { margin-top: 0.5em; } } + .countrystatezip { @include media-breakpoint-up(sm) { .col-sm-4:first-of-type { padding-right: 0; } + .col-sm-4:last-of-type { padding-left: 0; } } } } + .remove-control { input { display: none; } + label { display: block; text-align: right; @@ -83,6 +104,7 @@ width: auto; color: $link-color; cursor: pointer; + &:hover { text-decoration: underline; } diff --git a/app/assets/stylesheets/revised/pages/organized/messages.scss b/app/assets/stylesheets/revised/pages/organized/messages.scss index 792fdb19b7..a9227d516f 100644 --- a/app/assets/stylesheets/revised/pages/organized/messages.scss +++ b/app/assets/stylesheets/revised/pages/organized/messages.scss @@ -3,62 +3,77 @@ span.plural { display: none; } + &.number-is-plural span.plural { display: inline-block; } } + #map { width: 100%; height: 400px; margin-bottom: 4 * $vertical-height; } + // messages table rows are rendered when you click on a point on the map too - only show the map link when on the table .map-cell { display: none; } + // We don't want to display extended-col-info except on the main table, when the screen is small .extended-col-info { display: none; } + #messages_table { .map-cell { display: table-cell; padding: 0; text-align: center; + a { color: $gray-light; cursor: pointer; display: block; padding: 0.3rem; + &:hover, &:active { color: $link-color; } } } + // For small tables, we want to just have two cells, so that it isn't too wide for the page @include media-breakpoint-down(md) { line-height: 1.25; + .extended-col-info { display: inline-block; } + .msgbikelink { display: block; } + .hidden-sm-cells { display: none; } } } + #placeSearch { max-width: 60%; display: none; + &.searchOnMap { display: block; } + @include media-breakpoint-down(md) { max-width: 50%; } + box-shadow: 0 0 4px rgba(black, 0.1); margin: 9px 9px 0 0; border-radius: 1px; diff --git a/app/assets/stylesheets/revised/pages/organized/shared.scss b/app/assets/stylesheets/revised/pages/organized/shared.scss index f0476be7fd..ad506d26b9 100644 --- a/app/assets/stylesheets/revised/pages/organized/shared.scss +++ b/app/assets/stylesheets/revised/pages/organized/shared.scss @@ -1,5 +1,5 @@ hr.delete-organization-section { - margin: 4 * $vertical-height 0 2 * $vertical-height; + margin: (4 * $vertical-height) 0 (2 * $vertical-height); } // This isn't actually applying styles yet, but will be @@ -9,20 +9,30 @@ hr.delete-organization-section { .organized-list-table { @extend .table; + @extend .table-striped; + @extend .table-bordered; + @extend .table-sm; + tr td:first-child { @extend .less-strong; + font-style: italic; text-align: right; + // A little more whitespace padding-right: 0.5rem; + // Make the text line up with the other side of the table font-size: 0.75rem; line-height: 2rem; } + tr td:last-child { - width: 85%; // This is effectively min-width for tables + width: 85%; + + // This is effectively min-width for tables } } diff --git a/app/assets/stylesheets/revised/pages/payments/payments.scss b/app/assets/stylesheets/revised/pages/payments/payments.scss index 9db9f7fbee..9084173e04 100644 --- a/app/assets/stylesheets/revised/pages/payments/payments.scss +++ b/app/assets/stylesheets/revised/pages/payments/payments.scss @@ -1,112 +1,165 @@ -$payments-page-breakpoint: 'sm'; +$payments-page-breakpoint: "sm"; + .payments-layout-body { - height: 100%; // set in coffeescript to ensure no black bar + height: 100%; + + // set in coffeescript to ensure no black bar @include media-breakpoint-up($payments-page-breakpoint) { - background: image-url('revised/donate_bg.jpg'); + background: image-url("revised/donate_bg.jpg"); background-size: cover; background-position: center center; padding-top: 36px; } + @include media-breakpoint-down($payments-page-breakpoint) { padding-top: 0; background: none; + .payments-top-container { padding-top: 2 * $vertical-height; - background: image-url('revised/donate_bg.jpg'); + background: image-url("revised/donate_bg.jpg"); background-size: cover; background-position: center center; } } - @include media-breakpoint-up('md') { + + @include media-breakpoint-up("md") { padding-bottom: $primary-footer-top-margin; } - .payments-top-container { padding-bottom: 3 * $vertical-height; } + + .payments-top-container { + padding-bottom: 3 * $vertical-height; + } + .payments-logo-line { width: 100%; + a { display: block; width: 6 * $vertical-height; - @include media-breakpoint-up($payments-page-breakpoint) { margin: 0 auto; } + + @include media-breakpoint-up($payments-page-breakpoint) { + margin: 0 auto; + } } + svg { display: block; width: 100%; height: auto; } } + header.payments-header { color: white; text-align: center; - h1, p { color: inherit; } + + h1, + p { + color: inherit; + } + h1 { font-size: 48px; margin: 27px 0 0; line-height: 1; - @include media-breakpoint-down(sm) { font-size: 36px; } - @include media-breakpoint-down(xs) { font-size: 28px; } + + @include media-breakpoint-down(sm) { + font-size: 36px; + } + + @include media-breakpoint-down(xs) { + font-size: 28px; + } } + p { font-size: 24px; line-height: 1.25; margin: 8px 0 0; - span { @include media-breakpoint-down('xs') { display: block; } } + + span { + @include media-breakpoint-down("xs") { + display: block; + } + } } } .donate-block { background: $gray-darker; text-align: center; - padding-bottom: 2 * $vertical-height; // Force at least a little padding on the bottom + padding-bottom: 2 * $vertical-height; + + // Force at least a little padding on the bottom h3 { font-size: 25px; color: white; margin: 0; - padding: 2*$vertical-height $half-gutter; + padding: (2 * $vertical-height) $half-gutter; } + .select-amount { background: #efefef; width: 100%; - padding: 2*$vertical-height $half-gutter; + padding: (2 * $vertical-height) $half-gutter; + @include media-breakpoint-down($payments-page-breakpoint) { border-radius: 1px; } } - p { margin: 0; } + + p { + margin: 0; + } + .amount-list { @include list-unstyled; - li { margin-top: 2 * $vertical-height; } + + li { + margin-top: 2 * $vertical-height; + } + a { font-family: $header-font-family; font-size: 18px; display: block; width: 100%; - border-radius: .25rem; + border-radius: 0.25rem; + } + + .active { + border-color: $blue; } - .active { border-color: $blue; } } .next-step { margin-top: 2 * $vertical-height; + .btn { - border-radius: .25rem; + border-radius: 0.25rem; width: auto; display: block; margin: 0 auto; } } + .nfp-info { margin: 18px 0 -12px; color: $less-strong-font-color; + a { color: $less-strong-font-color; text-decoration: underline; } } + @include media-breakpoint-down($payments-page-breakpoint) { padding-left: 12px; padding-right: 12px; } - @include media-breakpoint-up('md') { + + @include media-breakpoint-up("md") { padding-bottom: 0; max-width: 525px; border-radius: 1px; diff --git a/app/assets/stylesheets/revised/pages/support/faq.scss b/app/assets/stylesheets/revised/pages/support/faq.scss index ba29f67912..6aff5ec9f8 100644 --- a/app/assets/stylesheets/revised/pages/support/faq.scss +++ b/app/assets/stylesheets/revised/pages/support/faq.scss @@ -1,64 +1,79 @@ // Legacy suppport styles -// +// // Only one help page right now, and it's the FAQ .faq-block { margin: 30px 0; + // border: 1px solid $grayLighter; padding: 0; border-radius: 2px; + h3 { // background: $grayLighterer; - padding: .5em 10px; + padding: 0.5em 10px; margin: 0; font-size: 20px; } + dl { padding: 0; margin: 0; + dt { // border-top: 1px solid $grayLighter; } + dd { margin: 0; padding-left: 1.5em; padding-right: 10px; + &.in { - padding: .5em 0 .5em 1.5em; + padding: 0.5em 0 0.5em 1.5em; margin: 0; } } } + form { width: 100%; padding-right: 10px; margin: 20px 0 10px; position: relative; + .searchit { margin-left: 2%; height: 1.5em; position: absolute; - top: -.1em; right: 13px; + top: -0.1em; + right: 13px; border: none; padding: 3px; background: none; font-size: 19px; border-radius: 2px; + img { display: block; height: 100%; width: auto; } - &:hover, &:active, &:focus { + + &:hover, + &:active, + &:focus { // background: $blueDark; box-shadow: none; border: none; - outline: none; + outline: none; } + &:active { // background: $blueDark; } } + .faq-search-search-field { width: 100%; } @@ -69,32 +84,38 @@ a { display: block; position: relative; + // font-family: $headerFont; font-size: 18px; font-weight: normal; width: 100%; - padding: .5em 10px; + padding: 0.5em 10px; + span { transform: rotate(90deg); + // color: $linkColor; - margin-right: .75em; - -webkit-transition: all .1s ease-out; - -moz-transition: all .1s ease-out; - -o-transition: all .1s ease-out; - transition: all .1s ease-out; + margin-right: 0.75em; + -webkit-transition: all 0.1s ease-out; + -moz-transition: all 0.1s ease-out; + -o-transition: all 0.1s ease-out; + transition: all 0.1s ease-out; float: left; display: block; font-size: 10px; font-family: helvetica; } + &:active span { - -webkit-transition: all .1s ease-out; - -moz-transition: all .1s ease-out; - -o-transition: all .1s ease-out; - transition: all .1s ease-out; + -webkit-transition: all 0.1s ease-out; + -moz-transition: all 0.1s ease-out; + -o-transition: all 0.1s ease-out; + transition: all 0.1s ease-out; } - &:active, &.collapsed { - span { + + &:active, + &.collapsed { + span { transform: rotate(0deg); } } diff --git a/app/assets/stylesheets/revised/pages/user/edit.scss b/app/assets/stylesheets/revised/pages/user/edit.scss index 51f274fab2..b76304a6c4 100644 --- a/app/assets/stylesheets/revised/pages/user/edit.scss +++ b/app/assets/stylesheets/revised/pages/user/edit.scss @@ -3,7 +3,8 @@ color: $gray-light; display: block; } + hr { - padding-bottom: 2*$vertical-height; + padding-bottom: 2 * $vertical-height; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/user/home.scss b/app/assets/stylesheets/revised/pages/user/home.scss index 46276f5832..8c31f3efcc 100644 --- a/app/assets/stylesheets/revised/pages/user/home.scss +++ b/app/assets/stylesheets/revised/pages/user/home.scss @@ -1,18 +1,26 @@ #welcome_user_home { .lock-group { @extend .row; - strong { display: block; } + + strong { + display: block; + } + .image-column { @extend .col-xs-2; + padding-right: 0; } } + .user-items-nav { @include binx-nav-tabs; - margin: 0 0 2*$vertical-height; + + margin: 0 0 (2 * $vertical-height); + .nav-item { width: 50%; text-align: center; } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/pages/user/show.scss b/app/assets/stylesheets/revised/pages/user/show.scss index 9ccf130607..a706b143b7 100644 --- a/app/assets/stylesheets/revised/pages/user/show.scss +++ b/app/assets/stylesheets/revised/pages/user/show.scss @@ -1,18 +1,27 @@ #users_show { - img.users-show-avatar { border-radius: 50%; } - .container > .row { margin-top: $vertical-height; } + img.users-show-avatar { + border-radius: 50%; + } + + .container > .row { + margin-top: $vertical-height; + } + .shared-bikes-row { max-width: 940px; margin-left: auto; margin-right: auto; } + .bike-list-image { flex: 0 0 0; display: block; overflow: hidden; } + .personal-page-stolen-tag { @extend .header-font; + font-size: 12px; color: white; background: $red; @@ -23,18 +32,21 @@ top: 77%; right: -22%; } + .card { @include media-breakpoint-up(sm) { flex: 1 0 30%; max-width: 30%; } + @include media-breakpoint-down(sm) { flex: 1 0 40%; max-width: 50%; - margin-right: .625rem; - margin-left: .625rem; + margin-right: 0.625rem; + margin-left: 0.625rem; } } + .card-deck { @include media-breakpoint-down(sm) { display: flex; @@ -43,15 +55,22 @@ margin-right: -0.9375rem; } } + .card-title { margin: 0; padding: 10px; } - .card-title h4 { margin: 0; } + + .card-title h4 { + margin: 0; + } + .card-title h4 a { @extend .body-font; + line-height: 1.2; } + .paginate-container-row { margin-left: auto; margin-right: auto; diff --git a/app/assets/stylesheets/revised/sections/_embeded_tweet.scss b/app/assets/stylesheets/revised/sections/_embeded_tweet.scss index f9a7c3785a..9628c1b8be 100644 --- a/app/assets/stylesheets/revised/sections/_embeded_tweet.scss +++ b/app/assets/stylesheets/revised/sections/_embeded_tweet.scss @@ -1,8 +1,10 @@ .embeded-tweet { $tweet-link-color: #3498dc; $tweet-black: #2c2c2c; + margin-top: 3 * $vertical-height; position: relative; + .tweet-display { position: absolute; display: block; @@ -12,23 +14,28 @@ border: 2px solid $tweet-black; box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); padding: 6px 12px 12px; + &.tweet-align-top-left { left: 2.5%; top: 2.5%; } + &.tweet-align-top-right { right: 2.5%; top: 2.5%; } + &.tweet-align-bottom-left { left: 2.5%; bottom: 5%; } + &.tweet-align-bottom-right { right: 2.5%; bottom: 5%; } } + .tweetor-header { display: block; position: relative; @@ -36,23 +43,28 @@ width: 100%; color: $tweet-black; line-height: 1em; + .tweetor-name { display: inline-block; font-weight: bold; margin-top: 3px; font-size: 90%; } + .tweetor-handle { color: #8b9da8; font-size: 75%; } + &:hover { text-decoration: none; + .tweetor-name { color: $tweet-link-color; text-decoration: underline; } } + img { display: block; float: left; @@ -60,6 +72,7 @@ margin-right: 7px; } } + .tweet-body { clear: both; position: relative; @@ -68,10 +81,12 @@ color: $tweet-black; font-size: 90%; line-height: 1.2em; + a { color: $tweet-link-color; } } + a.body-link { position: absolute; width: 100%; diff --git a/app/assets/stylesheets/revised/sections/ad_blocks.scss b/app/assets/stylesheets/revised/sections/ad_blocks.scss index 9d2120fe8b..9503dc611c 100644 --- a/app/assets/stylesheets/revised/sections/ad_blocks.scss +++ b/app/assets/stylesheets/revised/sections/ad_blocks.scss @@ -7,47 +7,70 @@ } .ad-col { - @include media-breakpoint-down(md) { width: 100%; } + @include media-breakpoint-down(md) { + width: 100%; + } + .ad-block img { margin-bottom: $vertical-height; - &:last-of-type { margin-bottom: 0 } + + &:last-of-type { + margin-bottom: 0; + } } } .ad-block { display: none; width: 100%; + .testing-block { background: $gray-lighter; border: 1px solid $gray-lightish; - h4 { @extend .text-xs-center; } + + h4 { + @extend .text-xs-center; + } } + &.rendered-ad { display: block; - a, img { + + a, + img { display: block; width: 100%; margin: 0 auto; } } + &#top468x60 { @extend .ad468x60; + @include media-breakpoint-down(md) { - display: none; // At least for now... + display: none; + + // At least for now... margin-bottom: $vertical-height; } } + // &#right300x600 { // @extend .ad300x600; // margin-top: $vertical-height; // } h3 { font-size: 21px; - margin: 0 0 0.5*$vertical-height; - &, a { color: $gray-light; } + margin: 0 0 (0.5 * $vertical-height); + + &, + a { + color: $gray-light; + } } } -.additional-ad-space { // For pages with content blocks on the right +.additional-ad-space { + // For pages with content blocks on the right margin-bottom: 3 * $vertical-height; } diff --git a/app/assets/stylesheets/revised/sections/alerts.scss b/app/assets/stylesheets/revised/sections/alerts.scss index b7192dec3c..f588941812 100644 --- a/app/assets/stylesheets/revised/sections/alerts.scss +++ b/app/assets/stylesheets/revised/sections/alerts.scss @@ -20,13 +20,14 @@ font-weight: $alert-link-font-weight; } - // Dismissible alerts // // Expand the right padding and account for the close button's positioning. .alert-dismissible { - padding-right: ($alert-padding + 1.25rem); // 20px to REM + padding-right: $alert-padding + 1.25rem; + + // 20px to REM // Adjust close link position .close { @@ -38,19 +39,24 @@ } // floating top alert block -// +// // Wrapper and stuff .primary-alert-block { position: fixed; z-index: $zindex-navbar-fixed + 10; padding-right: 0.9375rem; padding-left: 0.9375rem; + .alert { width: 100%; clear: both; } - &.faded { display: none; } + + &.faded { + display: none; + } } + @media (max-width: $grid-breakpoint-md - 1px) { .primary-alert-block { width: 83.33333%; @@ -58,6 +64,7 @@ right: 0; } } + @media (min-width: $grid-breakpoint-md) and (max-width: $grid-breakpoint-xl - 1px) { .primary-alert-block { width: 66.66667%; @@ -65,6 +72,7 @@ right: 8.3333%; } } + @media (min-width: $grid-breakpoint-xl) { .primary-alert-block { width: 600px; @@ -73,7 +81,6 @@ } } - // Alternate styles // // Generate contextual modifier classes for colorizing the alert. @@ -82,32 +89,50 @@ border: 1px solid $alert-color; color: $alert-body-color; - p, h1, h2, h3, h4 { + p, + h1, + h2, + h3, + h4 { color: $alert-body-color; - a { color: darken($alert-body-color, 10%); } + + a { + color: darken($alert-body-color, 10%); + } + } + + p:last-of-type { + margin-bottom: 0; } - p:last-of-type { margin-bottom: 0; } + hr { border-top-color: darken($alert-color, 5%); } .close { color: $alert-color; - opacity: .8; - &:hover { opacity: 1; } + opacity: 0.8; + + &:hover { + opacity: 1; + } } } .alert-success { @include binx-alert-variant($green, $green); } -.alert-info, .alert-notice { + +.alert-info, +.alert-notice { @include binx-alert-variant($blue, $blue); } + .alert-warning { @include binx-alert-variant(orange, orange); } -.alert-danger, .alert-error { + +.alert-danger, +.alert-error { @include binx-alert-variant($red, $red); } - diff --git a/app/assets/stylesheets/revised/sections/attr_list.scss b/app/assets/stylesheets/revised/sections/attr_list.scss index d19a69de99..7ab51735c0 100644 --- a/app/assets/stylesheets/revised/sections/attr_list.scss +++ b/app/assets/stylesheets/revised/sections/attr_list.scss @@ -1,40 +1,53 @@ .attr-list { @include clearfix; + list-style-type: none; - margin: 0; padding: 0; + margin: 0; + padding: 0; position: relative; + li { width: 100%; padding: 0; + // &:nth-of-type(2n-1) { background: $gray; } .attr-title { font-weight: $strong-font-weight; - margin-right: .3em; + margin-right: 0.3em; } } + &.separate-lines { - .attr-title { display: block; } + .attr-title { + display: block; + } } } @each $size in $grid-sizes { $i: index($grid-sizes, $size); + // Add a class of "split-$size" to get it to split at any width above that breakpoint // eg .split-sm @media (min-width: nth($grid-breakpoints-var, $i)) { .attr-list.split-#{$size} { - @include make-row(); + @include make-row; + li { - @include make-col-ready(); + @include make-col-ready; + @include make-col(6); } } } + // Add a class of "separate-lines-$size" to get it to split at any width below that breakpoint // eg .separate-lines-xl @media (max-width: nth($grid-breakpoints, $i)) { .attr-list.seperate-lines-#{$size} { - li .attr-title { display: block; } + li .attr-title { + display: block; + } } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/sections/bike_boxes.scss b/app/assets/stylesheets/revised/sections/bike_boxes.scss index 26559f8dbc..5445a25ea1 100644 --- a/app/assets/stylesheets/revised/sections/bike_boxes.scss +++ b/app/assets/stylesheets/revised/sections/bike_boxes.scss @@ -1,97 +1,144 @@ $bike-box-bg: $gray-lighter; + .bike-boxes { margin-top: $vertical-height; + @include list-unstyled; + width: 100%; + .bike-box-item { display: flex; flex-wrap: wrap; - margin: $vertical-height 0 0 0; // Apply the background to just the width of the columns, not full row width + margin: $vertical-height 0 0 0; + + // Apply the background to just the width of the columns, not full row width padding-top: 0; padding-bottom: 0; - &:nth-of-type(2n+1) { background: $bike-box-bg; } + + &:nth-of-type(2n + 1) { + background: $bike-box-bg; + } } + .bike-information { flex: 0 0 75%; padding: $vertical-height 0.9375rem; } + .title-link { font-size: $body-font-size; width: 100%; margin: 0; - a { display: block; } + + a { + display: block; + } } + .hover-expand-block { display: none; position: absolute; - left: 33.3333%; bottom: 33.3333%; + left: 33.3333%; + bottom: 33.3333%; width: 300%; text-align: center; background: $gray-lightish; border: 1px solid $gray; - padding: .5*$vertical-height; + padding: 0.5 * $vertical-height; z-index: $zindex-navbar-fixed - 1; - p { margin: 0; } + + p { + margin: 0; + } + img { display: block; height: auto; width: 100%; } - &:hover { text-decoration: none; } + + &:hover { + text-decoration: none; + } + } + + .img-expanded .hover-expand-block { + display: block; } - .img-expanded .hover-expand-block { display: block; } } -// Outside of bike-boxes because used on the user personal page +// Outside of bike-boxes because used on the user personal page .bike-list-image { flex: 0 0 25%; position: relative; - img { display: block; } + + img { + display: block; + } + .no-image { - padding: 2*$vertical-height; + padding: 2 * $vertical-height; background: $bike-box-bg; } } + .thumb-overlay { position: absolute; width: 100%; height: 100%; background: #c2c2c2; - opacity: .8; + opacity: 0.8; text-align: center; + h4 { margin: 0; color: white; } - img { + + img { width: 50%; max-width: 60px; margin: $vertical-height auto; - display: block + display: block; } } @media (min-width: $grid-breakpoint-md) { .bike-boxes { - .hover-expand-block { width: 200%; } + .hover-expand-block { + width: 200%; + } + .bike-information { @include clearfix; + .attr-list { width: 50%; float: left; + .multi-attr-lists { - &:first-of-type { padding-right: 0.9375rem; } - &:last-of-type { padding-left: 0.9375rem; } + &:first-of-type { + padding-right: 0.9375rem; + } + + &:last-of-type { + padding-left: 0.9375rem; + } } } } } } + @media (min-width: $grid-breakpoint-xl) { .bike-boxes { .thumb-overlay { padding-top: $vertical-height; - h4 { font-size: 21px; } + + h4 { + font-size: 21px; + } } } } diff --git a/app/assets/stylesheets/revised/sections/bike_search_form.scss b/app/assets/stylesheets/revised/sections/bike_search_form.scss index b55c8a08e5..cb237534d0 100644 --- a/app/assets/stylesheets/revised/sections/bike_search_form.scss +++ b/app/assets/stylesheets/revised/sections/bike_search_form.scss @@ -1,50 +1,77 @@ .bikes-search-form { - @include make-row(); - // + @include make-row; + + // // Query field (main search field) .query-field-wrap { flex: 0 0 83.33333%; padding-left: 0.9375rem; + // Space between search bar and button padding-right: 10px; } - .query-field { + + .query-field { width: 100%; - &#serial { margin-top: 0.5*$vertical-height; } + + &#serial { + margin-top: 0.5 * $vertical-height; + } + } + + .select2-container { + margin-bottom: 0; } - .select2-container { margin-bottom: 0; } // If the email field is there too, we want to put the two search bars together for large screens .sidebyside-queries { - .email-field-too { margin-top: 0.5*$vertical-height; } // Always give both fields a top margin + .email-field-too { + margin-top: 0.5 * $vertical-height; + } + + // Always give both fields a top margin @include media-breakpoint-up(md) { display: flex; flex-wrap: wrap; + .email-field-too { width: 49%; - &:last-of-type { margin-left: 2%; } + + &:last-of-type { + margin-left: 2%; + } } } } - .select2-results__options { - .sch_s { display: inline-block; } - .sch_m, .sch_ { color: #ccc; } - .sch_special { border-bottom: 1px solid #ddd; } + .sch_s { + display: inline-block; + } + + .sch_m, + .sch_ { + color: #ccc; + } + + .sch_special { + border-bottom: 1px solid #ddd; + } + .sch_c { color: #bbb; display: inline-block; } + .sclr { border-radius: 3px; display: inline-block; width: 24px; height: 24px; border: 1px solid white; - line-height: .8em; + line-height: 0.8em; margin: 0 6px -6px; - font-size: .5em; + font-size: 0.5em; text-align: center; padding-top: 1em; } @@ -55,77 +82,125 @@ flex: 0 0 16.66667%; padding-right: 0.9375rem; } + .searchit { height: 100%; position: relative; - min-height: 6.6666*$vertical-height; + min-height: 6.6666 * $vertical-height; padding: 0; text-align: center; width: 100%; + svg { height: auto; width: 50%; - max-width: 60px; // so it doesn't break organization search + max-width: 60px; + + // so it doesn't break organization search margin-top: 5%; display: inline-block; } } + // Location fields .stolen-search-fields { - @include make-col-ready(); + @include make-col-ready; + @include make-col(12); - padding-top: .5em; - input, span { + + padding-top: 0.5em; + + input, + span { display: block; float: right; - padding: .25em .5em; + padding: 0.25em 0.5em; } + input { background: $gray-lighter; border-radius: $border-radius; border: none; } - span { color: $gray-light; } - .stolen-radius { width: 4.2em; } - .stolen-proximity { width: 30%; } + + span { + color: $gray-light; + } + + .stolen-radius { + width: 4.2em; + } + + .stolen-proximity { + width: 30%; + } } - // Hide things by default - so that our search is more functional + + // Hide things by default - so that our search is more functional // when JS isn't working - .nojs #query_items { display: none; } + .nojs #query_items { + display: none; + } } @media (max-width: 600px) { .bikes-search-form { .selectize-dropdown-content { - .sch_s, .sch_m, .sch_ { + .sch_s, + .sch_m, + .sch_ { font-size: 14px; - span { display: none; } + + span { + display: none; + } } } } } -// +// // Nav search tabs .search-type-tabs .nav.nav-tabs { @include binx-nav-tabs; + display: flex; flex-wrap: wrap; - margin: 2*$vertical-height 0; + margin: (2 * $vertical-height) 0; text-align: center; font-size: 12px; + li { - a { padding-left: 0; padding-right: 0; } - a.active { font-weight: $strong-font-weight; } - &#stolenness_tab_proximity { flex: 0 0 40%; } // location info takes up the most space - &#stolenness_tab_stolen { flex: 0 0 27%; } - &#stolenness_tab_non { flex: 0 0 33%; } // 'Not marked stolen' is longer than 'Stolen anywhere' + a { + padding-left: 0; + padding-right: 0; + } + + a.active { + font-weight: $strong-font-weight; + } + + &#stolenness_tab_proximity { + flex: 0 0 40%; + } + + // location info takes up the most space + &#stolenness_tab_stolen { + flex: 0 0 27%; + } + + &#stolenness_tab_non { + flex: 0 0 33%; + } + + // 'Not marked stolen' is longer than 'Stolen anywhere' } } -@media(max-width: $grid-breakpoint-lg) { +@media (max-width: $grid-breakpoint-lg) { .search-type-tabs .nav.nav-tabs { - @include binx-nav-tabs-vertical; + @include binx-nav-tabs-vertical; + text-align: left; } } diff --git a/app/assets/stylesheets/revised/sections/content_menu.scss b/app/assets/stylesheets/revised/sections/content_menu.scss index 050fe08505..491ed9d76d 100644 --- a/app/assets/stylesheets/revised/sections/content_menu.scss +++ b/app/assets/stylesheets/revised/sections/content_menu.scss @@ -1,4 +1,5 @@ $horizontal-content-menu-padding: $vertical-height; + .primary-content-menu { .content-nav-group { h3 { @@ -6,16 +7,28 @@ $horizontal-content-menu-padding: $vertical-height; color: white; padding: $vertical-height $horizontal-content-menu-padding; } + ul { @include list-unstyled; - li { padding: 0 $horizontal-content-menu-padding; } + + li { + padding: 0 $horizontal-content-menu-padding; + } + a { display: block; + // padding: $horizontal-content-menu-padding; color: $gray; } } } - @include media-breakpoint-down(md) { width: 100%; } - @include media-breakpoint-down(lg) { padding-top: 3*$vertical-height; } + + @include media-breakpoint-down(md) { + width: 100%; + } + + @include media-breakpoint-down(lg) { + padding-top: 3 * $vertical-height; + } } diff --git a/app/assets/stylesheets/revised/sections/custom_selects.scss b/app/assets/stylesheets/revised/sections/custom_selects.scss index c130db491f..888bf24738 100644 --- a/app/assets/stylesheets/revised/sections/custom_selects.scss +++ b/app/assets/stylesheets/revised/sections/custom_selects.scss @@ -1,30 +1,45 @@ -// +// // Bike Index selectize & select2 overrides -// +// .selectize-dropdown [data-selectable] .highlight { background: rgba($blue, 0.2); } // Selectize styles -.selectize-dropdown .active { background-color: lighten(#bebebe, 10%); } -// Make selectize inputs the same size as form inputs -.form-group .selectize-control .selectize-input { padding: 0.475rem 0.75rem; } +.selectize-dropdown .active { + background-color: lighten(#bebebe, 10%); +} +// Make selectize inputs the same size as form inputs +.form-group .selectize-control .selectize-input { + padding: 0.475rem 0.75rem; +} // Select2 styles // Right now, select2 is only used on bikes search, these styles // make the field on bikes search appear the same as other fields .select2-container .select2-selection--multiple { @extend .form-control; + padding-bottom: 0; } -.select2-dropdown, .select2-container--default.select2-container--focus .select2-selection--multiple { + +.select2-dropdown, +.select2-container--default.select2-container--focus + .select2-selection--multiple { border-color: #66afe9; } -.select2-container--default .select2-selection--multiple .select2-selection__choice, -.select2-container .select2-search--inline .select2-search__field { + +.select2-container--default + .select2-selection--multiple + .select2-selection__choice, +.select2-container .select2-search--inline .select2-search__field { margin-top: 0; } -.select2-container--default .select2-selection--multiple .select2-selection__rendered { padding: 0; } +.select2-container--default + .select2-selection--multiple + .select2-selection__rendered { + padding: 0; +} diff --git a/app/assets/stylesheets/revised/sections/form_well.scss b/app/assets/stylesheets/revised/sections/form_well.scss index 20113b5475..423ccabeaa 100644 --- a/app/assets/stylesheets/revised/sections/form_well.scss +++ b/app/assets/stylesheets/revised/sections/form_well.scss @@ -1,44 +1,62 @@ .form-well { .form-wrap { - padding: 2 * $vertical-height 0 4 * $vertical-height; + padding: (2 * $vertical-height) 0 (4 * $vertical-height); } + .form-well-input-static { - @include make-col-ready(); + @include make-col-ready; + @extend .form-control-static; + font-weight: $strong-font-weight; - line-height: 1.5; // to match the height of inputs - padding-left: 1.6875rem; // static padding: 0.9375 + input padding: 0.75 + line-height: 1.5; + + // to match the height of inputs + padding-left: 1.6875rem; + + // static padding: 0.9375 + input padding: 0.75 padding-right: 1.6875rem; } + .form-well-input-static-full-width { @extend .form-well-input-static; } + .right-input-help.right-text-help { font-style: italic; line-height: 1.2; + a { color: $body-font-color; cursor: pointer; + &:hover, &:active, &.active { color: $link-color; } } + &.full-width { max-width: 100%; margin-top: -0.6rem; } } + .full-width-checkbox-help { @extend .below-input-help; + margin: -1em 0 0 17px; } + .selectize-control { line-height: 0; - } // label isn't lined up + } + + // label isn't lined up .inline-input-help { @extend .form-circle-item; + display: block; border: 2px solid $gray; position: absolute; @@ -47,6 +65,7 @@ font-weight: $strong-font-weight; z-index: 100; transition: all 0.05s linear; + &:hover, &:active, &.active { @@ -55,43 +74,56 @@ color: $link-color; } } + .fancy-select .inline-input-help { right: 2.75em; - } // To not cover up select pointer + } + + // To not cover up select pointer .form-well-label { @extend .form-control-label; + line-height: 1.2em; padding-top: 0.65rem; } + .form-well-label, .form-well-input, .form-well-input-large, .right-input-help { - @include make-col-ready(); + @include make-col-ready; } + .related-fields { .form-group { padding-top: 0.5 * $vertical-height; margin-bottom: 0; + &:first-of-type { padding-top: 0; } } + padding-bottom: 1.5 * $vertical-height; } + .full-width-section { // pad the sides so that it fits the row. padding-left: $row-side-padding; padding-right: $row-side-padding; } + .form-group { clear: both; + .checkbox-inline { padding-top: 0.5em; } + .form-well-input .checkbox-inline { padding-top: 0; } + .radio-inline, .checkbox-inline { input[type="radio"], @@ -100,17 +132,21 @@ } } } + .row.collapse.in { display: flex; } + .full-width-button { - padding: 2 * $vertical-height 0; + padding: (2 * $vertical-height) 0; + .btn { display: block; margin: 0 auto; max-width: 450px; } } + hr { clear: both; margin-top: 3 * $vertical-height; @@ -124,48 +160,64 @@ .form-well-input { @include make-col(8); } + .form-well-label { @include make-col(4); } + .form-well-input-large, .form-well-label-large-input { @include make-col(12); } + .form-well-label-large-input { padding-top: 0; } + .right-input-help { @include make-col-offset(4); + @include make-col(8); + margin-top: -0.5em; + label { padding-top: 0.5em; - } // To pad checkboxes a bit + } + + // To pad checkboxes a bit text-align: right; } + .unnested-field::after, .related-fields::after { content: ""; display: block; - margin: 0 15px 2 * $vertical-height 10%; + margin: 0 15px (2 * $vertical-height) 10%; border-bottom: 1px $form-well-divider-color solid; padding-top: $vertical-height; } + // .related-fields::after aren't the same width as unnessted-fields because they aren't rows // This is a fairly good approximation of their differences is widths - a few px off tho .related-fields::after { width: 90%; } + .unnested-field::after { width: 87.5%; margin-left: 12.5%; } + .no-divider-row::after { display: none; } + hr { margin-top: 5 * $vertical-height; - } // It isn't cleared correctly on small screens + } + + // It isn't cleared correctly on small screens } } @@ -177,15 +229,19 @@ .form-well-input-static { @include make-col(6); } + .form-well-input-large, .form-well-input-static-full-width { @include make-col(8); } + .form-well-label { @include make-col(3); } + .right-input-help { @include make-col(3); + &.full-width { text-align: right; flex: 0 0 100%; @@ -198,10 +254,12 @@ .form-well-container.container { max-width: 100%; background: $form-well-background; + .form-well { width: 100%; } } + // This is the selector we put everything under, don't overpower by including in // .form-well-container.container above - that's for a special case // .form-well { } @@ -211,6 +269,7 @@ .form-well { background: $form-well-background; border: 1px solid $form-well-border-color; + // label is 3 columns. } } @@ -220,16 +279,20 @@ padding-left: 2 * $row-side-padding; padding-right: 2 * $row-side-padding; } + // because we have to use floats instead of flex with sticky (affixing edit menu) .form-well-container.container > .row { display: block; + @include clearfix; + .col-md-8.form-well { display: block; float: right; width: 66.66667%; } } + // To properly space the sides of the containers .form-wrap .row { margin-left: 0; @@ -244,6 +307,7 @@ .form-well-container.container { margin-bottom: -$primary-footer-top-margin; } + // Remove some padding between the forms .form-well { .form-wrap.secondary-form-wrap { @@ -260,6 +324,7 @@ border: none; background: none; } + .form-well { .form-wrap { background: $form-well-background; @@ -267,19 +332,23 @@ padding-top: 4 * $vertical-height; width: 100%; position: relative; + .form-control-label { text-align: right; } + // Add some space between the forms &.secondary-form-wrap { margin-top: 3 * $vertical-height; } } + // label is 3 columns .form-well-input-static { @include make-col(6); } + .form-well-input-static-full-width { @include make-col(9); } diff --git a/app/assets/stylesheets/revised/sections/form_well_additional_field.scss b/app/assets/stylesheets/revised/sections/form_well_additional_field.scss index cf899e687c..f4d677dc4a 100644 --- a/app/assets/stylesheets/revised/sections/form_well_additional_field.scss +++ b/app/assets/stylesheets/revised/sections/form_well_additional_field.scss @@ -2,16 +2,23 @@ // max-width: 300px; margin: 0 auto; display: block; - padding-top: 2*$vertical-height; + padding-top: 2 * $vertical-height; + a { display: block; text-align: center; cursor: pointer; color: $body-font-color; - &:hover, &:active, &.active { + + &:hover, + &:active, + &.active { color: $link-color; text-decoration: none; } } - .add_fields { margin-top: $vertical-height; } -} \ No newline at end of file + + .add_fields { + margin-top: $vertical-height; + } +} diff --git a/app/assets/stylesheets/revised/sections/form_well_header.scss b/app/assets/stylesheets/revised/sections/form_well_header.scss index a881d10320..3018fc1efe 100644 --- a/app/assets/stylesheets/revised/sections/form_well_header.scss +++ b/app/assets/stylesheets/revised/sections/form_well_header.scss @@ -1,11 +1,17 @@ // Main header on Bike Editing .form-well-header .edit-bike-header { margin-bottom: 24px; - h1 { margin-bottom: 0; } + + h1 { + margin-bottom: 0; + } + .edit-bike-title-submenu { margin: 0; + a { color: $body-font-color; + &:hover { color: $link-color; } @@ -15,9 +21,10 @@ // Per page header on bikes and users .form-well-form-header { - h3, h5 { + h3, + h5 { padding: 0 $vertical-height; - margin-bottom: 2*$vertical-height; + margin-bottom: 2 * $vertical-height; } } @@ -25,8 +32,15 @@ // On bike pages, per page header is hidden except on large screens // It's always visible on user edit .form-well-form-header { - display: none; // Hidden on sm screens, shown via mediaquery - @include media-breakpoint-up(lg) { margin-top: -2*$vertical-height; } - @include media-breakpoint-up(md) { display: block; } + display: none; + + // Hidden on sm screens, shown via mediaquery + @include media-breakpoint-up(lg) { + margin-top: -2 * $vertical-height; + } + + @include media-breakpoint-up(md) { + display: block; + } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/sections/form_well_menu.scss b/app/assets/stylesheets/revised/sections/form_well_menu.scss index 365544a04a..254d5a8597 100644 --- a/app/assets/stylesheets/revised/sections/form_well_menu.scss +++ b/app/assets/stylesheets/revised/sections/form_well_menu.scss @@ -1,29 +1,48 @@ $active-bike-edit-border-width: 2px; $menu-select-overlay-line-height: 12px; + .primary-edit-form-well-menu { z-index: 1; - ul { + + ul { display: none; + @include list-unstyled; + margin: 0; + li { display: block; - &:nth-of-type(n+5) { + + &:nth-of-type(n + 5) { border-top: 1px solid $gray-light; } } + a { padding: $vertical-height 0; display: block; width: 100%; + h4 { - padding-left: .25em; + padding-left: 0.25em; margin: 0; border-left: $active-bike-edit-border-width solid transparent; } - &:hover, &:active, &.active, h4 { text-decoration: none; } - &:hover h4 { color: $link-color; } - &:active, &.active { + + &:hover, + &:active, + &.active, + h4 { + text-decoration: none; + } + + &:hover h4 { + color: $link-color; + } + + &:active, + &.active { h4 { border-left: $active-bike-edit-border-width solid $blue; font-weight: $strong-font-weight; @@ -32,15 +51,18 @@ $menu-select-overlay-line-height: 12px; } } } + .edit-form-well-submit-wrapper { .btn { font-size: 15px; width: 100%; } } + .form-well-edit-page-select { float: left; width: 50%; + select { // @extend .c-select; // This style no longer exists...? width: 100%; @@ -52,19 +74,22 @@ $menu-select-overlay-line-height: 12px; border: none; font-size: 15px; line-height: 1em; - padding: 1.25em 1.75rem .55em .75em; + padding: 1.25em 1.75rem 0.55em 0.75em; } + .menu-select-overlay { position: absolute; font-size: $menu-select-overlay-line-height; display: block; margin-left: 9px; line-height: 1em; - left: 0; top: 4px; + left: 0; + top: 4px; } } } -// + +// // Small screen styles @media (max-width: $grid-breakpoint-md - 1px) { // Menu fixed to bottom of the screen @@ -73,22 +98,29 @@ $menu-select-overlay-line-height: 12px; padding: 0; position: fixed; width: 100%; - bottom: 0; left: 0; - box-shadow: 0 -1px 2px rgba(black, .2); + bottom: 0; + left: 0; + box-shadow: 0 -1px 2px rgba(black, 0.2); background: white; + .form-well-edit-page-select { margin-top: $menu-select-overlay-line-height; display: block; } + .edit-form-well-submit-wrapper { width: 50%; float: left; - .btn { border-radius: 0; border: none; } + + .btn { + border-radius: 0; + border: none; + } } } } -// +// // Medium and up screen styles @media (min-width: $grid-breakpoint-md) { .primary-edit-form-well-menu { @@ -96,12 +128,22 @@ $menu-select-overlay-line-height: 12px; width: 33.33333%; position: -webkit-sticky; position: sticky; - top: 8*$vertical-height; // Same as the padding top for body in primary_header_nav - ul { display: block; } - .edit-form-well-submit-wrapper { padding-top: 1em; } + top: 8 * $vertical-height; + + // Same as the padding top for body in primary_header_nav + ul { + display: block; + } + + .edit-form-well-submit-wrapper { + padding-top: 1em; + } } + // Hide with media query so as not to override selectize - .form-well-edit-page-select { display: none; } + .form-well-edit-page-select { + display: none; + } } // XL screens - smaller menu, offset it @@ -109,6 +151,8 @@ $menu-select-overlay-line-height: 12px; .primary-edit-form-well-menu { // because we have to use floats instead of flex with sticky (affixing) width: 25%; - margin-right: 8.3333%; // 1 col margin - Manually set the offset via margin + margin-right: 8.3333%; + + // 1 col margin - Manually set the offset via margin } } diff --git a/app/assets/stylesheets/revised/sections/forms.scss b/app/assets/stylesheets/revised/sections/forms.scss index 217a74c254..7883f0651a 100644 --- a/app/assets/stylesheets/revised/sections/forms.scss +++ b/app/assets/stylesheets/revised/sections/forms.scss @@ -1,12 +1,15 @@ -// +// // Input helpers // .hide-selectize-dropdown-arrow { - .selectize-control.single .selectize-input:after { display: none; } + .selectize-control.single .selectize-input:after { + display: none; + } } -.form-circle-item { // Mixin for help blocks - padding: .5em .25em; +.form-circle-item { + // Mixin for help blocks + padding: 0.5em 0.25em; border-radius: 1em; line-height: 0; cursor: pointer; @@ -17,24 +20,30 @@ .below-input-help { @extend small; + display: block; line-height: 1.5em; - padding-bottom: .5em; + padding-bottom: 0.5em; color: $gray-light; } a.optional-form-block { cursor: pointer; color: $gray; - &:hover { + + &:hover { color: $link-color; text-decoration: none; - .context-display-help { color: $link-color; } + + .context-display-help { + color: $link-color; + } } } .context-display-help { @extend .form-circle-item; + display: inline-block; background: #fff; border: 1px solid $form-well-border-color; @@ -43,6 +52,7 @@ a.optional-form-block { .hidden-other { margin-top: 0; display: none; + &.unhidden { margin-bottom: 1.5rem; display: flex !important; @@ -52,21 +62,37 @@ a.optional-form-block { #email_check_message { cursor: pointer; + @extend .form-control-feedback; + display: none; padding: 0 0.75rem; + // @extend .text-muted; } -// +// // Avatar uploader -// -.avatar-upload-wrapper, .file-upload-wrapper { - img { padding-bottom: $vertical-height; } - label.file { display: block; } +// +.avatar-upload-wrapper, +.file-upload-wrapper { + img { + padding-bottom: $vertical-height; + } + + label.file { + display: block; + } + .file-custom { - .file-upload-text { color: $gray-light; } - &::after { content: ''; } + .file-upload-text { + color: $gray-light; + } + + &::after { + content: ""; + } + &::before { content: "Upload Photo"; font-size: $btn-font-size; @@ -79,12 +105,13 @@ a.optional-form-block { border-color: $green; } } + // Override the content display for files so it says file not photo - &.file-upload-wrapper .file-custom::before { content: "Upload file"; } + &.file-upload-wrapper .file-custom::before { + content: "Upload file"; + } } - - // Old Bootstrap-4 custom file upload css - https://github.com/twbs/bootstrap-rubygem/blob/0bbd14de56ef118c27a42aa89623cca5edeec94c/assets/stylesheets/bootstrap/_custom-forms.scss // Classes changed and broke our useage at 2642b162208bacefa24e6d52a576546392289f46 // We're keeping old functionality and old classes ;) @@ -94,12 +121,14 @@ a.optional-form-block { height: 2.5rem; cursor: pointer; } + .file input { width: 100%; margin: 0; filter: alpha(opacity = 0); opacity: 0; } + .file-custom { position: absolute; top: 0; @@ -107,36 +136,39 @@ a.optional-form-block { left: 0; z-index: 5; height: 2.5rem; - padding: .5rem 1rem; + padding: 0.5rem 1rem; line-height: 1.5; color: #555; user-select: none; background-color: #fff; border: $input-btn-border-width solid #ddd; - border-radius: .25rem; - @include box-shadow(inset 0 .2rem .4rem rgba(0,0,0,.05)); + border-radius: 0.25rem; + + @include box-shadow(inset 0 0.2rem 0.4rem rgba(0, 0, 0, 0.05)); } + .file-custom::after { content: "Choose file..."; } + .file-custom::before { position: absolute; - top: -.075rem; - right: -.075rem; - bottom: -.075rem; + top: -0.075rem; + right: -0.075rem; + bottom: -0.075rem; z-index: 6; display: block; height: 2.5rem; - padding: .5rem 1rem; + padding: 0.5rem 1rem; line-height: 1.5; color: #555; content: "Browse"; background-color: #eee; border: $input-btn-border-width solid #ddd; - border-radius: 0 .25rem .25rem 0; + border-radius: 0 0.25rem 0.25rem 0; } // Focus state .file input:focus ~ .file-custom { - @include box-shadow(0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9); + @include box-shadow(0 0 0 0.075rem #fff, 0 0 0 0.2rem #0074d9); } diff --git a/app/assets/stylesheets/revised/sections/horizontal_lines.scss b/app/assets/stylesheets/revised/sections/horizontal_lines.scss index 0db6c6b9ab..3557614bd7 100644 --- a/app/assets/stylesheets/revised/sections/horizontal_lines.scss +++ b/app/assets/stylesheets/revised/sections/horizontal_lines.scss @@ -2,4 +2,4 @@ hr { display: block; border: none; border-top: $gray-light 1px solid; -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/sections/legacy_content.scss b/app/assets/stylesheets/revised/sections/legacy_content.scss index b37bafe373..dc0c68ac30 100644 --- a/app/assets/stylesheets/revised/sections/legacy_content.scss +++ b/app/assets/stylesheets/revised/sections/legacy_content.scss @@ -1,65 +1,99 @@ // Legacy content styles that apply to multiple legacy content pages .legacy-content-wrap { - .footnotes, .padded { padding-top: 2*$vertical-height; } - .footnote-back-link { font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; } + .footnotes, + .padded { + padding-top: 2 * $vertical-height; + } + + .footnote-back-link { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + } + .fancy-bullets { position: relative; list-style-type: none; padding: 0; margin: 1em 0 0 0; + li { padding-left: 1.25em; position: relative; } } + .bullet-point { - @include border-radius(.3em); - @include box-shadow(1px 1px 1px rgba(black,.2)); + @include border-radius(0.3em); + + @include box-shadow(1px 1px 1px rgba(black, 0.2)); + display: block; position: absolute; - left: 0; top: 1em; - width: .6em; height: .6em; - margin: .3em .6em 0 0; + left: 0; + top: 1em; + width: 0.6em; + height: 0.6em; + margin: 0.3em 0.6em 0 0; background: $blue; border: 1px solid $gray-light; + // background: $linkColor; // border: 1px solid darken($linkColor, 5%); } + .blue-bullet { @include border-radius(1px); - @include box-shadow(1px 1px 1px rgba(black,.2)); + + @include box-shadow(1px 1px 1px rgba(black, 0.2)); + display: block; position: absolute; - left: 0; top: 0; - width: .4em; height: .4em; - margin: .4em .3em 0 0; + left: 0; + top: 0; + width: 0.4em; + height: 0.4em; + margin: 0.4em 0.3em 0 0; background: $blue-dark; - border: 1px solid darken($blue-dark, 10%); + border: 1px solid darken($blue-dark, 10%); } + .green-bullet { @extend .blue-bullet; + background: $green; - border: 1px solid darken($green, 10%); + border: 1px solid darken($green, 10%); } // Used by Serials and also image_resources .serial-pictures { @include list-unstyled; + margin: 30px 0; list-style-type: none; + li { @include clearfix; + margin: 20px 0 0 0; position: relative; width: 100%; + .serial-image { width: 27%; float: left; display: block; position: relative; - img { width: 100%; } - &.blackbg { background: black; } // This, for example, is only image_resources + + img { + width: 100%; + } + + &.blackbg { + background: black; + } + + // This, for example, is only image_resources } + p { float: left; margin-left: 3%; diff --git a/app/assets/stylesheets/revised/sections/legal.scss b/app/assets/stylesheets/revised/sections/legal.scss index 64653acd7c..5e68519c33 100644 --- a/app/assets/stylesheets/revised/sections/legal.scss +++ b/app/assets/stylesheets/revised/sections/legal.scss @@ -1,20 +1,29 @@ .legal-content { max-width: 45em; margin: 0 auto; + header { - h1 { font-size: 28px;} + h1 { + font-size: 28px; + } + hr { margin: 30px 0 40px; } } - h1, h2, h3 { + h1, + h2, + h3 { font-size: 20px; font-weight: normal; line-height: 1.25em; - margin: 1em 0 .75em; + margin: 1em 0 0.75em; + } + + h1 { + margin: 1.5em 0 0.5em; } - h1 { margin: 1.5em 0 .5em; } } .accept-vendor-terms { @@ -23,18 +32,25 @@ left: 0; z-index: 100; width: 100%; - background-color: #FFF; + background-color: #fff; border: 1px solid $gray; - border: 1px solid rgba(0,0,0,.3); - *border: 1px solid $gray; /* IE6-7 */ - box-shadow: 0 0px 4px rgba(0,0,0,0.2); + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid $gray; + + /* IE6-7 */ + box-shadow: 0 0px 4px rgba(0, 0, 0, 0.2); background-clip: padding-box; - form { margin: 0; } + + form { + margin: 0; + } + // label { font-size: $standardFontSize;} .center-accept-terms-button { display: block; margin: 0 auto; } + .center-accept-terms-text { width: 100%; text-align: center; @@ -46,22 +62,29 @@ @media (min-width: 701px) { .accept-vendor-terms { .form-horizontal { - padding: 10px 20px; } + padding: 10px 20px; + } + .agree-action { width: 100%; padding: 15px 20px 20px; margin-bottom: 0; - text-align: right; // right align buttons + text-align: right; + + // right align buttons background-color: #f5f5f5; border-top: 1px solid #ddd; border-radius: 0 0 6px 6px; - box-shadow: inset 0 1px 0 #FFF; + box-shadow: inset 0 1px 0 #fff; - // Properly space out buttons + // Properly space out buttons .btn + .btn { margin-left: 5px; - margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs + margin-bottom: 0; + + // account for input[type="submit"] which gets the bottom margin like all other inputs } + // but override that for button groups .btn-group .btn + .btn { margin-left: -1px; @@ -75,20 +98,23 @@ .control-group { padding: 0 20px; margin-bottom: 5px; + .control-label { width: 20px; margin-right: 10px; } + .controls { margin: 0; } } + .agree-action { padding: 10px 0; + .button-blue { width: 100%; } } } } - diff --git a/app/assets/stylesheets/revised/sections/modals.scss b/app/assets/stylesheets/revised/sections/modals.scss index e86e5460a7..ada56b1d78 100644 --- a/app/assets/stylesheets/revised/sections/modals.scss +++ b/app/assets/stylesheets/revised/sections/modals.scss @@ -1,4 +1,4 @@ -// +// // Unlike bootstrap buttons styles, we're leaving the standard modal code // and extending here @@ -7,14 +7,16 @@ padding-bottom: 0; } -.modal-footer { +.modal-footer { border-top: none; padding-top: 0; } .modal-btn-footer { @extend .modal-footer; + text-align: center; + .btn { display: block; width: 100%; @@ -32,27 +34,31 @@ } } -// +// // DirtyForm dialog box. Make it look like modal btn footer without having to actually // modify the stuff in jquery.dirtyforms.dialogs.bootstrap.min.js #dirty-dialog { .modal-footer { - padding-left: 2*0.9375rem; + padding-left: 2 * 0.9375rem; padding-right: 0.9375rem; } + .btn { display: block; width: 50%; padding-top: 1em; padding-bottom: 1em; } + .btn-danger { margin: 0; float: right; } + .btn-default { @extend .btn-secondary; + float: left; margin-left: -0.9375rem; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/sections/oauth.scss b/app/assets/stylesheets/revised/sections/oauth.scss index ae5b3141b2..7a2ffb458d 100644 --- a/app/assets/stylesheets/revised/sections/oauth.scss +++ b/app/assets/stylesheets/revised/sections/oauth.scss @@ -1,19 +1,37 @@ .doorkeeper-container { @extend .container; - .binxbtn { @extend .btn-primary; } - .binxbtn-danger { @extend .btn-default; } - .bnxbtn-lg { @extend .btn-lg; } + + .binxbtn { + @extend .btn-primary; + } + + .binxbtn-danger { + @extend .btn-default; + } + + .bnxbtn-lg { + @extend .btn-lg; + } // Application authorization pages .authorize-application-section { - &.card { border-color: $gray-light; } + &.card { + border-color: $gray-light; + } + .btn { display: block; width: 100%; } } + #insecure-authorization-modal { - .modal-title { @extend .text-danger; } - .insecure-continuing-explanation hr { margin-top: 5*$vertical-height; } + .modal-title { + @extend .text-danger; + } + + .insecure-continuing-explanation hr { + margin-top: 5 * $vertical-height; + } } } diff --git a/app/assets/stylesheets/revised/sections/organized_menu.scss b/app/assets/stylesheets/revised/sections/organized_menu.scss index 294e4dcd83..cb0e8d139d 100644 --- a/app/assets/stylesheets/revised/sections/organized_menu.scss +++ b/app/assets/stylesheets/revised/sections/organized_menu.scss @@ -1,32 +1,43 @@ $organized-menu-bg: $gray-lighter; + .organized-left-menu { display: none; + .divider-above { border-top: 1px solid #e4e4e4; margin-top: $vertical-height; } + .divider-below { padding-bottom: $vertical-height; border-bottom: 1px solid #e4e4e4; } + li:last-of-type { @extend .divider-below; } + header { margin-top: -2 * $vertical-height; padding: 0 $vertical-height; + @extend .divider-below; + overflow-x: hidden; + h3 { font-size: 18px; line-height: 1.5; + span { display: block; font-weight: bold; color: #2d2d2d; + @extend .header-font-alt; } } + img { width: 70%; max-width: 150px; @@ -40,9 +51,12 @@ $organized-menu-bg: $gray-lighter; @media (min-width: $grid-breakpoint-md) { .organized-body { position: relative; + .primary-footer { position: relative; - } // To make it go over the menu + } + + // To make it go over the menu .organized-left-menu { background: $organized-menu-bg; width: 15%; @@ -50,37 +64,48 @@ $organized-menu-bg: $gray-lighter; position: absolute; top: 0; display: block; + ul { @include list-unstyled; + overflow-x: hidden; + li { padding-top: $vertical-height; } } + .menu-item { width: 100%; display: block; - padding: 0.5 * $vertical-height $vertical-height; + padding: (0.5 * $vertical-height) $vertical-height; color: $header-font-nocolor; text-decoration: none; font-size: 14px; + &:hover { text-decoration: none; font-weight: $strong-font-weight; - padding-right: 0; // Because otherwise the shift to bold can break line + padding-right: 0; + + // Because otherwise the shift to bold can break line } } + .disabled-menu-item { color: $gray-light; display: block; + &:hover { font-weight: normal; } } + .active { color: $blue; position: relative; font-weight: bold; + &:before { content: ""; display: block; @@ -96,6 +121,7 @@ $organized-menu-bg: $gray-lighter; } } } + .organized-wrap { width: 100%; padding-left: 15%; diff --git a/app/assets/stylesheets/revised/sections/pagination.scss b/app/assets/stylesheets/revised/sections/pagination.scss index 4771b72b90..e5044e67c2 100644 --- a/app/assets/stylesheets/revised/sections/pagination.scss +++ b/app/assets/stylesheets/revised/sections/pagination.scss @@ -3,18 +3,23 @@ padding-left: 0; margin-top: $vertical-height; margin-bottom: $vertical-height; - @include border-radius(); + + @include border-radius; } .page-item { - display: inline; // Remove list-style and block-level defaults + display: inline; + + // Remove list-style and block-level defaults &:first-child { .page-link { margin-left: 0; + @include border-left-radius($border-radius); } } + &:last-child { .page-link { @include border-right-radius($border-radius); @@ -28,8 +33,10 @@ cursor: default; background-color: $blue; border-color: $blue; - padding: .5rem 0.75rem; // make it a bit taller - margin-top: -.1rem; + padding: 0.5rem 0.75rem; + + // make it a bit taller + margin-top: -0.1rem; } } @@ -46,8 +53,10 @@ .page-link { position: relative; - float: left; // Collapse white-space - padding: .4rem .5rem; + float: left; + + // Collapse white-space + padding: 0.4rem 0.5rem; margin-left: 3px; color: white; text-decoration: none; @@ -60,7 +69,10 @@ background-color: $gray-dark; border-color: $gray-dark; } - &:active { background: 000; } + + &:active { + background: 000; + } } // @@ -68,32 +80,48 @@ // .pagination-lg { - @include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg); + @include pagination-size( + $pagination-padding-y-lg, + $pagination-padding-x-lg, + $font-size-lg, + $line-height-lg, + $border-radius-lg + ); } .pagination-sm { - @include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm); + @include pagination-size( + $pagination-padding-y-sm, + $pagination-padding-x-sm, + $font-size-sm, + $line-height-sm, + $border-radius-sm + ); } - -// +// // Should be applied to div.pagination when pagination selectors are for prior bootstrap versions @mixin legacy-pagination-override { @extend .pagination; + li { @extend .page-item; - a { @extend .page-link; } + + a { + @extend .page-link; + } } } - // div.paginate-container - our own legacy paginate via kaminari .paginate-container { display: flex; flex: wrap; justify-content: center; - .pagination { + + .pagination { flex: 0 1 auto; + @include legacy-pagination-override; } } @@ -104,4 +132,4 @@ .dataTables_paginate .pagination { @include legacy-pagination-override; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/sections/partner_sign_in_up.scss b/app/assets/stylesheets/revised/sections/partner_sign_in_up.scss index b3b0610267..e0f5024cb0 100644 --- a/app/assets/stylesheets/revised/sections/partner_sign_in_up.scss +++ b/app/assets/stylesheets/revised/sections/partner_sign_in_up.scss @@ -6,6 +6,7 @@ $bikehub-header: #92d149; h2 { color: $bikehub-header; } + p { width: 100%; } @@ -13,29 +14,37 @@ $bikehub-header: #92d149; nav.bikehub-nav { background: #fff; + @include clearfix; + margin-bottom: 40px; padding-top: 0; padding-bottom: 0; + img { display: block; max-width: 100%; } + .bikehub-logo { float: left; position: relative; padding: 16px 0; + img { height: 36px; } } + .primary-logo { float: left; padding: 6px 0; + img { height: 54px; } } + .poweredby p { float: left; padding: 18px 6px 0 24px; @@ -44,10 +53,12 @@ nav.bikehub-nav { color: #000; line-height: 1; } + .primary-logo, .poweredby p { opacity: 0.7; } + .bikehub-nav-item { margin: 0; float: right; @@ -57,16 +68,19 @@ nav.bikehub-nav { font-size: 16px; text-decoration: none; color: #212529; + &:active, &.active, &:hover { color: #fff; background: #82cb39; } + // For some reason, can't select this with :first-of-type, so manually class it &.bikehub-nav-item-first { margin-left: auto; } + &:last-of-type { border-right: 1px solid #ededed; } @@ -85,10 +99,12 @@ nav.bikehub-nav { position: absolute; left: 0; top: 48px; + p { padding-left: 16px; } } + margin-bottom: 60px; } } @@ -98,9 +114,11 @@ nav.bikehub-nav { .bikehub-logo img { height: 24px; } + .primary-logo img { height: 44px; } + .bikehub-nav-item { font-size: 14px; padding: 0.75rem 0.5rem 0; diff --git a/app/assets/stylesheets/revised/sections/primary_footer.scss b/app/assets/stylesheets/revised/sections/primary_footer.scss index 605cfc8eae..f3e6da73e6 100644 --- a/app/assets/stylesheets/revised/sections/primary_footer.scss +++ b/app/assets/stylesheets/revised/sections/primary_footer.scss @@ -1,56 +1,91 @@ -$primary-footer-top-margin: 6*$vertical-height; // Because sometimes we cover this up other places +$primary-footer-top-margin: 6 * $vertical-height; + +// Because sometimes we cover this up other places .primary-footer { margin-top: $primary-footer-top-margin; - .primary-footer-nav, .terms-and-stuff { - padding: 3*$vertical-height 0; + + .primary-footer-nav, + .terms-and-stuff { + padding: (3 * $vertical-height) 0; } + a { text-decoration: none; - &:hover, &:active, &.active { text-decoration: underline; } + + &:hover, + &:active, + &.active { + text-decoration: underline; + } } - .primary-footer-nav h4 a, .terms-and-stuff a { + + .primary-footer-nav h4 a, + .terms-and-stuff a { color: $blue-light; - &:hover, &:active, &.active { color: $blue-light; } + + &:hover, + &:active, + &.active { + color: $blue-light; + } } + .primary-footer-nav { background: $gray-dark; - a { color: $gray-light; } - h4 { - margin-bottom: 0.5*$vertical-height; + + a { + color: $gray-light; + } + + h4 { + margin-bottom: 0.5 * $vertical-height; font-size: 15px; } + ul { @include list-unstyled; + margin: 0; } + .social-nav { text-align: center; + li { display: block; float: left; width: 33.33%; } + svg { display: inline-block; - max-height: 4*$vertical-height; + max-height: 4 * $vertical-height; } - .svgpath { + + .svgpath { fill: $gray-light; - transition: color .05s linear; + transition: color 0.05s linear; } + a { display: block; position: relative; - &:hover, &:active { - .svgpath { fill: lighten($gray-light, 15%); } + + &:hover, + &:active { + .svgpath { + fill: lighten($gray-light, 15%); + } } } } } + .terms-and-stuff { background: $black-off; color: $gray-light; text-align: center; + p { margin: 0; font-size: 12px; @@ -59,10 +94,10 @@ $primary-footer-top-margin: 6*$vertical-height; // Because sometimes we cover th } } -// +// // Small Screen Styles @media (max-width: $grid-breakpoint-lg - 1px) { .primary-footer-nav nav { - margin-top: 3.5*$vertical-height; + margin-top: 3.5 * $vertical-height; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/sections/primary_header_nav.scss b/app/assets/stylesheets/revised/sections/primary_header_nav.scss index 4557845065..bf17c171b5 100644 --- a/app/assets/stylesheets/revised/sections/primary_header_nav.scss +++ b/app/assets/stylesheets/revised/sections/primary_header_nav.scss @@ -4,6 +4,7 @@ body, .organized-left-menu { padding-top: 8 * $vertical-height; } + @media (min-width: $grid-breakpoint-lg) { body, .organized-left-menu { @@ -26,31 +27,39 @@ $mainmenu-open-zindex: 10; left: 0; width: 100%; z-index: $zindex-navbar-fixed; + .primary-logo { position: relative; float: left; padding: $primary-logo-padding 0; + img { display: block; height: 44px; width: auto; } } + .primary-main-menu { @include list-unstyled; + margin: 0; display: block; } + .primary-nav-item { display: block; margin: 0; + a { @extend h4; + margin: 0; cursor: pointer; color: $primary-nav-text-color; display: block; transition: color 0.05s linear; + &:hover, &:active, &.active { @@ -58,10 +67,12 @@ $mainmenu-open-zindex: 10; } } } + .divider-nav-item, .nonprofit-subtitle { display: none; } + .primary-submenu .divider-nav-item, .current-organization-submenu .divider-nav-item { display: block; @@ -69,9 +80,11 @@ $mainmenu-open-zindex: 10; margin: 6px auto; border-top: 1px solid #666; } + .hamburgler { font-family: courier; } + .settings-link svg { display: none; } @@ -83,23 +96,28 @@ $mainmenu-open-zindex: 10; margin: 0 0 0 2rem; padding: $vertical-height 24px 0; transition: padding $mainmenu-transform-speed linear; + a { @extend .header-font; + color: #fff; font-size: 12px; line-height: 18px; cursor: pointer; display: block; padding: 8px 15px; + &:hover, &:active, &.active { color: #fff; + .caret-down { color: #fff; } } } + .caret-down { font-size: 75%; color: darken($primary-nav-text-color, 10%); @@ -108,16 +126,20 @@ $mainmenu-open-zindex: 10; margin-left: 0.2rem; } } + &.headroom--pinned .current-organization-nav-item, &.headroom--unpinned .current-organization-nav-item { padding: $vertical-height 24px 0; + a.active::after { bottom: 0; } } + .open > .current-organization-submenu { display: block; } + .current-organization-submenu { position: absolute; top: 100%; @@ -133,10 +155,12 @@ $mainmenu-open-zindex: 10; border: 1px solid rgba($gray, 0.3); border-radius: $border-radius; z-index: 1; + li { font-size: 80%; } } + .current-organization-submenu a, .primary-submenu a { font-family: $body-font-family; @@ -145,6 +169,7 @@ $mainmenu-open-zindex: 10; font-style: normal; font-size: 15px; text-transform: none; + &:hover, &:active, &.active { @@ -159,21 +184,26 @@ $mainmenu-open-zindex: 10; @media (max-width: $grid-breakpoint-lg - 1px) { .primary-header-nav { transition: transform $mainmenu-transform-speed linear; + &.headroom--pinned { transform: translate(0, 0%); } + &.headroom--unpinned { transform: translate(0, -100%); } + .primary-logo { padding: $primary-logo-padding-mobile 0; } + .hamburgler { float: right; position: relative; transition: padding $mainmenu-transform-speed linear; - padding: 1.5 * $vertical-height 0; + padding: (1.5 * $vertical-height) 0; z-index: $mainmenu-open-zindex + 3; + a { font-size: 36px; display: block; @@ -181,26 +211,32 @@ $mainmenu-open-zindex: 10; color: $gray; background: $primary-nav-background; transition: transform 100ms linear; + &:hover { color: #fff; text-decoration: none; } + &:active { } + &:active, &.active { color: #fff; text-decoration: none; } + &:active, &.active:active { transform: rotate(45deg); } + &.active { transform: rotate(90deg); } } } + .primary-main-menu { display: none; background: $primary-nav-background; @@ -213,20 +249,24 @@ $mainmenu-open-zindex: 10; transition: transform $mainmenu-transform-speed linear; z-index: $mainmenu-open-zindex; overflow-y: auto; - padding: 2 * $vertical-height 0 100px; + padding: (2 * $vertical-height) 0 100px; } + .primary-nav-item { a.primary-nav-link-with-submenu { // headers of lists aren't links on small screens cursor: default; + &:hover, &:active { background: $primary-nav-background; color: $primary-nav-text-color; } } + a { - padding: $vertical-height 2 * $vertical-height; + padding: $vertical-height (2 * $vertical-height); + &:active, &.active { background: $gray-light; @@ -234,15 +274,18 @@ $mainmenu-open-zindex: 10; } } } + .divider-nav-item { display: block; width: 94%; margin: 6px auto; border-top: 1px solid #666; } + .primary-submenu { padding-left: 12px; } + #menu-opened-backdrop { display: none; position: fixed; @@ -254,28 +297,37 @@ $mainmenu-open-zindex: 10; z-index: $mainmenu-open-zindex - 1; } } + // So that mobile browsers don't show it all the time, like assholes .primary-header-nav.enabled .primary-main-menu { display: block; } + // // Mobile menu visible body.menu-in { overflow: hidden; + .current-organization-nav-item { display: none; } } + .current-organization-nav-item { - padding-top: 2px + $vertical-height !important; // Somehow, makes things lineup more + padding-top: (2px + $vertical-height) !important; + + // Somehow, makes things lineup more } + .primary-header-nav.menu-in { #menu-opened-backdrop { display: block; } + .hamburgler { padding-right: $mainmenu-width - 5%; } + .primary-main-menu { transform: translate(0%, 0); } @@ -291,30 +343,38 @@ $mainmenu-open-zindex: 10; .primary-logo img { height: 48px; } + .primary-nav-item { padding: $vertical-height 0 0; + a.active::after { bottom: 0; } } } + .primary-logo img { transition: height $mainmenu-transform-speed linear; } + .hamburgler { display: none; } + .primary-nav-item { float: right; position: relative; transition: padding $mainmenu-transform-speed linear; + a { - padding: 8px 0.5 * $grid-gutter-width; + padding: 8px (0.5 * $grid-gutter-width); + &.active, &:active { text-decoration: none; } } + // Only apply to primary nav items, not submenus & > a.active::after { transition: bottom $mainmenu-transform-speed linear; @@ -326,25 +386,31 @@ $mainmenu-open-zindex: 10; margin-left: -12%; background: $blue; } + // On large screens, the signup link is a button .signup-link { border-radius: 4px; border: 1px solid $link-color; transition: background 0.05s linear; + &:hover { background: rgba(white, 0.1); color: $primary-nav-text-color; } + &.active::after { display: none; } } + .settings-link { padding-top: 0.5 * $vertical-height; padding-bottom: 0.5 * $vertical-height; + .settings-text { display: none; } + svg { display: block; height: 2 * $vertical-height; @@ -353,9 +419,11 @@ $mainmenu-open-zindex: 10; } } } + .open > .primary-submenu { display: block; } + .primary-submenu { position: absolute; top: 100%; @@ -373,10 +441,12 @@ $mainmenu-open-zindex: 10; border: 1px solid rgba($gray, 0.3); border-radius: $border-radius; z-index: 1; + li { font-size: 80%; } } + // To prevent flashing on initial load, before JS arrives .primary-header-nav, .primary-header-nav.headroom--top, @@ -384,11 +454,13 @@ $mainmenu-open-zindex: 10; .primary-logo img { height: $primary-logo-fullsize-height - 2 * $primary-logo-padding; } + .current-organization-nav-item, .primary-nav-item { // nav-items are 34px tall. - padding: 0.5 * ($primary-logo-fullsize-height - 34px) 0 2 * - $vertical-height; + padding: (0.5 * ($primary-logo-fullsize-height - 34px)) 0 + (2 * $vertical-height); + a.active::after { bottom: 2 * $vertical-height; } @@ -413,10 +485,12 @@ $mainmenu-open-zindex: 10; margin: 11px $vertical-height 0 $vertical-height; transition: margin $mainmenu-transform-speed linear; } + &.headroom--pinned .nonprofit-subtitle, &.headroom--unpinned .nonprofit-subtitle { margin-top: 11px; } + // To prevent moving on initial load, before JS arrives .nonprofit-subtitle, &.headroom--top.headroom--pinned .nonprofit-subtitle, diff --git a/app/assets/stylesheets/revised/sections/sharing.scss b/app/assets/stylesheets/revised/sections/sharing.scss index c8e69dae43..7e8f9b55e3 100644 --- a/app/assets/stylesheets/revised/sections/sharing.scss +++ b/app/assets/stylesheets/revised/sections/sharing.scss @@ -2,15 +2,17 @@ float: right; height: 28px; } + .twitter-share-button { display: block; float: right; margin-right: 10px; } + .fb-like { display: block; float: right; overflow: visible; margin-top: 2px; line-height: 1.5; -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/revised/sections/side_boxes.scss b/app/assets/stylesheets/revised/sections/side_boxes.scss index ddd457eaee..f9dfde27df 100644 --- a/app/assets/stylesheets/revised/sections/side_boxes.scss +++ b/app/assets/stylesheets/revised/sections/side_boxes.scss @@ -2,20 +2,32 @@ background: black; color: white; padding: $vertical-height; + .inner { background: white; color: $body-font-color; padding: $vertical-height; - margin: 2*$vertical-height 0; + margin: (2 * $vertical-height) 0; + .btn { display: block; - &:not(:first-child) { margin-top: $vertical-height; } + + &:not(:first-child) { + margin-top: $vertical-height; + } } } + h3 { color: white; - margin: 2*$vertical-height 0; + margin: (2 * $vertical-height) 0; + } + + .first-item { + margin-top: $vertical-height; + } + + .last-item { + margin-bottom: 0; } - .first-item { margin-top: $vertical-height; } - .last-item { margin-bottom: 0; } } diff --git a/app/assets/stylesheets/revised/sections/sign_in_up.scss b/app/assets/stylesheets/revised/sections/sign_in_up.scss index 283ed4cf12..427398a586 100644 --- a/app/assets/stylesheets/revised/sections/sign_in_up.scss +++ b/app/assets/stylesheets/revised/sections/sign_in_up.scss @@ -9,14 +9,17 @@ $sign-in-up-form-bg: $gray-lighter; span { background: $oauth-login-bg; } + &:hover, &:active, &:visited { text-decoration: none; } + &:hover span { background: $oauth-login-bg-hover; } + &:active span { background: darken($oauth-login-bg-hover, 5%); } @@ -26,41 +29,53 @@ $sign-in-up-form-bg: $gray-lighter; .sign-in-up-header h1 { margin-bottom: 4 * $vertical-height; } + .sign-in-up-main-form-header { - padding: 1.5 * $vertical-height 0 $vertical-height; + padding: (1.5 * $vertical-height) 0 $vertical-height; + small { @extend .body-font; + float: right; } } + .sign-in-up-or, .oauth-providers { - @include make-col-ready(); + @include make-col-ready; + margin-top: auto; margin-bottom: auto; } + .sign-in-up-or { display: none; + h3 { margin: 0; text-align: center; } } + .oauth-providers { .facebook-login { @include oauth-login-bar($facebook-login-color); } + .strava-login { @include oauth-login-bar($strava-login-color); + img { padding-top: 6px; } } + a { display: flex; flex-wrap: wrap; margin: $vertical-height 0; } + span { font-family: $header-font-family; font-weight: 400; @@ -69,19 +84,22 @@ $sign-in-up-form-bg: $gray-lighter; color: white; margin-bottom: 0; } + .oauth-logo-block { height: 4 * $vertical-height; border-radius: $border-radius 0 0 $border-radius; flex: 0 0 16.6667%; - padding: $vertical-height 0.5 * $vertical-height; + padding: $vertical-height (0.5 * $vertical-height); } + .oauth-text-block { border-radius: 0 $border-radius $border-radius 0; flex: 0 0 82.6666%; margin-left: 0.66667%; line-height: 1; - padding: 17px 0 0 3 * $vertical-height; + padding: 17px 0 0 (3 * $vertical-height); } + img { display: block; max-height: 100%; @@ -89,21 +107,26 @@ $sign-in-up-form-bg: $gray-lighter; margin: 0 auto; } } + .main-form { - @include make-col-ready(); + @include make-col-ready; + .checkbox input[type="checkbox"] { margin-top: 0.65rem; } + a, h3.sign-in-up-main-form-header a { color: $body-font-color; font-weight: $strong-font-weight; + &:hover, &:active, &.active { color: $body-font-color; } } + .btn { padding-top: $vertical-height; padding-bottom: $vertical-height; @@ -111,10 +134,12 @@ $sign-in-up-form-bg: $gray-lighter; display: block; width: 250px; } + p { - margin: 2 * $vertical-height 0 0; + margin: (2 * $vertical-height) 0 0; } } + .terms-and-conditions a { cursor: pointer; } @@ -125,8 +150,9 @@ $sign-in-up-form-bg: $gray-lighter; background: $sign-in-up-form-bg; border: 1px solid $gray-lightish; border-radius: $border-radius; - padding: 2 * $vertical-height 0.9375rem; + padding: (2 * $vertical-height) 0.9375rem; } + .oauth-providers, .main-form { @include make-col(12); @@ -136,19 +162,27 @@ $sign-in-up-form-bg: $gray-lighter; @mixin large-screen-sign-up { .sign-in-up-or { display: block; - width: 0; // Or else it overflows and breaks everything + width: 0; + + // Or else it overflows and breaks everything @include make-col-push(1); + @include make-col(1); } + .oauth-providers { @include make-col(5); + @include make-col-push(7); } + .sign-in-up-main-form-header { padding: 0; } + .main-form { padding-top: 0; + // Main form gets bg background: $sign-in-up-form-bg; border: 1px solid $gray-lightish; @@ -162,15 +196,19 @@ $sign-in-up-form-bg: $gray-lighter; // Partner sign-in-up is always small screen styled .sign-in-up.with-partner { @include small-screen-sign-up; + max-width: 660px; margin: 0 auto; + // We want to put the omniauth sign up in reverse order .sign-in-up-wrap .row { flex-direction: column-reverse; } + .oauth-providers { margin-top: $vertical-height; } + .terms-and-conditions label { text-indent: -1rem; padding-left: 1rem; @@ -206,6 +244,7 @@ $sign-in-up-form-bg: $gray-lighter; .sign-in-up.not-partner { .main-form { @include make-col(6); + @include make-col-pull(6); } } @@ -218,11 +257,14 @@ $sign-in-up-form-bg: $gray-lighter; .oauth-providers { @include make-col(4); } + .sign-in-up-or { @include make-col-push(2); } + .main-form { @include make-col(5); + @include make-col-pull(4); } } diff --git a/app/assets/stylesheets/revised/sections/sign_out.scss b/app/assets/stylesheets/revised/sections/sign_out.scss index 77e0f38271..373b9bd8c7 100644 --- a/app/assets/stylesheets/revised/sections/sign_out.scss +++ b/app/assets/stylesheets/revised/sections/sign_out.scss @@ -1,3 +1,5 @@ .sign-out { - .sharing-buttons { float: left; } + .sharing-buttons { + float: left; + } } diff --git a/app/assets/stylesheets/revised/sections/tables.scss b/app/assets/stylesheets/revised/sections/tables.scss index 185ea9acc0..f270fc7644 100644 --- a/app/assets/stylesheets/revised/sections/tables.scss +++ b/app/assets/stylesheets/revised/sections/tables.scss @@ -1,19 +1,23 @@ thead.sortable { th { font-weight: normal; + a.sortable-link { display: block; position: relative; + // To give a spot for the sortable direction &.active { padding-right: 1.5rem; } + span.sortable-direction { display: block; position: absolute; right: 0; top: 0; } + &.active { font-weight: strong; text-decoration: underline; diff --git a/app/assets/stylesheets/server_error.css.scss b/app/assets/stylesheets/server_error.css.scss index 1dde6509f1..33a995fdc7 100644 --- a/app/assets/stylesheets/server_error.css.scss +++ b/app/assets/stylesheets/server_error.css.scss @@ -2,7 +2,7 @@ body { font-size: 100%; - background: url('https://files.bikeindex.org/background-diagonal.png'); + background: url("https://files.bikeindex.org/background-diagonal.png"); font-family: "Helvetica", arial, sans-serif; } @@ -10,6 +10,7 @@ a { cursor: pointer; text-decoration: none; color: #08c; + &:hover { text-decoration: underline; color: darken(#08c, 10%); @@ -31,13 +32,14 @@ a { } p { - margin: 0 0 .5em; + margin: 0 0 0.5em; width: 100%; text-align: center; } + h4 { font-size: 1.2em; - margin: .5em 0 1em; + margin: 0.5em 0 1em; text-align: center; } @@ -45,8 +47,9 @@ h4 { .ascii { font-size: 45px; } + h4 { font-size: 1.8em; - margin-bottom: .2em; + margin-bottom: 0.2em; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/spokecard.css.scss b/app/assets/stylesheets/spokecard.css.scss index 609ed6bbb7..7d9458bd27 100644 --- a/app/assets/stylesheets/spokecard.css.scss +++ b/app/assets/stylesheets/spokecard.css.scss @@ -12,29 +12,39 @@ width: 600px; height: 380px; padding: 0; - &>span { + + & > span { border: 1px solid black; - height: 20px; width: 20px; + height: 20px; + width: 20px; position: absolute; display: block; } + .tleft { - top: -20px; left: -20px; + top: -20px; + left: -20px; border-top: 0; border-left: 0; } + .bleft { - bottom: -20px; left: -20px; + bottom: -20px; + left: -20px; border-bottom: 0; border-left: 0; } + .tright { - top: -20px; right: -20px; + top: -20px; + right: -20px; border-right: 0; border-top: 0; } + .bright { - bottom: -20px; right: -20px; + bottom: -20px; + right: -20px; border-right: 0; border-bottom: 0; } @@ -43,22 +53,28 @@ .spokecard-background { display: block; position: absolute; - left: 0; top: 0; + left: 0; + top: 0; width: 100%; z-index: 1; } -.qr-code-f, .qr-code-b { +.qr-code-f, +.qr-code-b { display: block; position: absolute; z-index: 2; - left: 50%; top: 50%; + left: 50%; + top: 50%; background: white; padding: 4px 10px; margin: -87px 0 0 -70px; - img { height: 148px; } + + img { + height: 148px; + } } .qr-code-b { margin: -87px 0 0 -103px; -} \ No newline at end of file +} diff --git a/app/controllers/admin/ads_controller.rb b/app/controllers/admin/ads_controller.rb index f44a6e31ec..59c92a22b2 100644 --- a/app/controllers/admin/ads_controller.rb +++ b/app/controllers/admin/ads_controller.rb @@ -1,7 +1,7 @@ class Admin::AdsController < Admin::BaseController before_filter :find_ad, except: [:index, :new, :create] before_filter :find_organizations, only: [:new, :edit] - layout 'new_admin' + layout "new_admin" def index @ads = Ad.all @@ -12,7 +12,6 @@ def show end def edit - end def update @@ -38,7 +37,6 @@ def create end end - protected def permitted_parameters @@ -52,5 +50,4 @@ def find_ad def find_organizations @organizations = Organization.all end - end diff --git a/app/controllers/admin/bikes_controller.rb b/app/controllers/admin/bikes_controller.rb index 27fa363732..e2cebee191 100644 --- a/app/controllers/admin/bikes_controller.rb +++ b/app/controllers/admin/bikes_controller.rb @@ -17,7 +17,7 @@ def index def missing_manufacturer session[:missing_manufacturer_time_order] = params[:time_ordered] if params[:time_ordered].present? bikes = Bike.unscoped.where(manufacturer_id: Manufacturer.other.id) - bikes = session[:missing_manufacturer_time_order] ? bikes.order('created_at desc') : bikes.order('manufacturer_other ASC') + bikes = session[:missing_manufacturer_time_order] ? bikes.order("created_at desc") : bikes.order("manufacturer_other ASC") page = params[:page] || 1 per_page = params[:per_page] || 100 @bikes = bikes.page(page).per(per_page) @@ -29,10 +29,10 @@ def update_manufacturers params[:bikes_selected].keys.each do |bid| Bike.find(bid).update_attributes(manufacturer_id: manufacturer_id, manufacturer_other: nil) end - flash[:success] = 'Success. Bikes updated' + flash[:success] = "Success. Bikes updated" redirect_to :back and return end - flash[:notice] = 'Sorry, you need to add bikes and a manufacturer' + flash[:notice] = "Sorry, you need to add bikes and a manufacturer" redirect_to :back end @@ -51,7 +51,7 @@ def ignore_duplicate_toggle duplicate_bike_group = DuplicateBikeGroup.find(params[:id]) duplicate_bike_group.ignore = !duplicate_bike_group.ignore duplicate_bike_group.save - flash[:success] = "Successfully marked #{duplicate_bike_group.segment} #{duplicate_bike_group.ignore ? 'ignored' : 'Un-ignored'}" + flash[:success] = "Successfully marked #{duplicate_bike_group.segment} #{duplicate_bike_group.ignore ? "ignored" : "Un-ignored"}" redirect_to :back end @@ -83,7 +83,7 @@ def update @bike.current_stolen_record.add_recovery_information( recovered_description: params[:mark_recovered_reason], index_helped_recovery: params[:mark_recovered_we_helped], - can_share_recovery: params[:can_share_recovery] + can_share_recovery: params[:can_share_recovery], ) end if @bike.update_attributes(permitted_parameters.except(:stolen_records_attributes)) @@ -123,7 +123,7 @@ def permitted_parameters def destroy_bike @bike.destroy AfterBikeSaveWorker.perform_async(@bike.id) - flash[:success] = 'Bike deleted!' + flash[:success] = "Bike deleted!" if params[:multi_delete] redirect_to admin_root_url # redirect_to admin_bikes_url(page: params[:multi_delete], multi_delete: 1) diff --git a/app/controllers/admin/bulk_imports_controller.rb b/app/controllers/admin/bulk_imports_controller.rb index 64a53e666b..e5e24084c0 100644 --- a/app/controllers/admin/bulk_imports_controller.rb +++ b/app/controllers/admin/bulk_imports_controller.rb @@ -1,6 +1,6 @@ class Admin::BulkImportsController < Admin::BaseController before_filter :find_bulk_import, only: [:show, :update] - layout 'new_admin' + layout "new_admin" def index page = params[:page] || 1 diff --git a/app/controllers/admin/ctypes_controller.rb b/app/controllers/admin/ctypes_controller.rb index ac9f256b3d..1ffc9391a0 100644 --- a/app/controllers/admin/ctypes_controller.rb +++ b/app/controllers/admin/ctypes_controller.rb @@ -1,6 +1,6 @@ class Admin::CtypesController < Admin::BaseController before_filter :find_ctypes, only: [:edit, :update, :destroy] - layout 'new_admin' + layout "new_admin" def index @ctypes = Ctype.all @@ -15,7 +15,7 @@ def edit def update if @ctype.update_attributes(permitted_parameters) - flash[:success] = 'Component Type Saved!' + flash[:success] = "Component Type Saved!" redirect_to admin_ctypes_url else render action: :edit @@ -25,7 +25,7 @@ def update def create @ctype = Ctype.create(permitted_parameters) if @ctype.save - flash[:success] = 'Component type created!' + flash[:success] = "Component type created!" redirect_to admin_ctypes_url else render action: :new @@ -37,10 +37,9 @@ def destroy redirect_to admin_ctypes_url end - def import Ctype.import(params[:file]) - flash[:success] = 'Component types imported' + flash[:success] = "Component types imported" redirect_to admin_ctypes_url end @@ -52,6 +51,6 @@ def permitted_parameters def find_ctypes @ctype = Ctype.friendly_find(params[:id]) - raise ActionController::RoutingError.new('Not Found') unless @ctype.present? + raise ActionController::RoutingError.new("Not Found") unless @ctype.present? end end diff --git a/app/controllers/admin/customer_contacts_controller.rb b/app/controllers/admin/customer_contacts_controller.rb index 675bd68a66..608bb7e416 100644 --- a/app/controllers/admin/customer_contacts_controller.rb +++ b/app/controllers/admin/customer_contacts_controller.rb @@ -1,5 +1,4 @@ class Admin::CustomerContactsController < Admin::BaseController - def create @customer_contact = CustomerContact.new(permitted_parameters) if @customer_contact.save diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 5e888f2650..d63c4beb80 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -1,10 +1,10 @@ class Admin::DashboardController < Admin::BaseController def index - @bikes = Bike.unscoped.includes(:creation_organization, :creation_state, :paint).order('created_at desc').limit(10) + @bikes = Bike.unscoped.includes(:creation_organization, :creation_state, :paint).order("created_at desc").limit(10) @users = User.includes(:memberships => [:organization]).limit(5).order("created_at desc") @flavors = FlavorText.all @flavor = FlavorText.new - @duplicate_groups = DuplicateBikeGroup.unignored.order('created_at desc').limit(5) + @duplicate_groups = DuplicateBikeGroup.unignored.order("created_at desc").limit(5) end def invitations @@ -15,23 +15,23 @@ def invitations def maintenance # @bikes here because this is the only one we're using the standard admin bikes table - @bikes = Bike.unscoped.order('created_at desc').where(example: true).limit(10) + @bikes = Bike.unscoped.order("created_at desc").where(example: true).limit(10) mnfg_other_id = Manufacturer.other.id @component_mnfgs = Component.where(manufacturer_id: mnfg_other_id) @bike_mnfgs = Bike.where(manufacturer_id: mnfg_other_id) @component_types = Component.where(ctype_id: Ctype.other.id) @handlebar_types = Bike.where(handlebar_type: Bike.handlebar_types[:other]) - @paint = Paint.where('color_id IS NULL') + @paint = Paint.where("color_id IS NULL") end def bust_z_cache Rails.cache.clear - flash[:success] = 'Z cash WAAAAAS busted!' + flash[:success] = "Z cash WAAAAAS busted!" redirect_to admin_root_url end def destroy_example_bikes - org = Organization.friendly_find('bikeindex') + org = Organization.friendly_find("bikeindex") bikes = Bike.unscoped.where(example: true) # The example bikes for the API docs on production are created by Bike Index Administrators # This way we don't clear them when we clear the rest of the example bikes @@ -46,9 +46,8 @@ def tsvs end def update_tsv_blacklist - new_blacklist = params[:blacklist].split(/\n|\r/).reject{|t| t.blank?} + new_blacklist = params[:blacklist].split(/\n|\r/).reject { |t| t.blank? } FileCacheMaintainer.reset_blacklist_ids(new_blacklist) redirect_to admin_tsvs_path end - end diff --git a/app/controllers/admin/failed_bikes_controller.rb b/app/controllers/admin/failed_bikes_controller.rb index 57634faaef..a9f45bb024 100644 --- a/app/controllers/admin/failed_bikes_controller.rb +++ b/app/controllers/admin/failed_bikes_controller.rb @@ -1,5 +1,6 @@ class Admin::FailedBikesController < Admin::BaseController layout "new_admin" + def index @b_params = BParam.where("created_bike_id IS NOT NULL").order("created_at desc") end @@ -7,5 +8,4 @@ def index def show @b_param = BParam.find(params[:id]) end - end diff --git a/app/controllers/admin/feedbacks_controller.rb b/app/controllers/admin/feedbacks_controller.rb index be6d0d28ff..d1db093d90 100644 --- a/app/controllers/admin/feedbacks_controller.rb +++ b/app/controllers/admin/feedbacks_controller.rb @@ -15,18 +15,17 @@ def show end def graphs - render json: - case params[:start_at] - when 'past_year' - @feedbacks.where('created_at >= ?', Time.now - 1.year) + render json: case params[:start_at] + when "past_year" + @feedbacks.where("created_at >= ?", Time.now - 1.year) .group_by_week(:created_at).count - when 'all_time' + when "all_time" @feedbacks.group_by_month(:created_at).count - when 'past_week' - @feedbacks.where('created_at >= ?', Time.now - 1.week) + when "past_week" + @feedbacks.where("created_at >= ?", Time.now - 1.week) .group_by_hour(:created_at).count else - @feedbacks.where('created_at >= ?', Time.now - 1.month) + @feedbacks.where("created_at >= ?", Time.now - 1.month) .group_by_day(:created_at).count end end @@ -35,7 +34,7 @@ def graphs def find_feedback_for_params if params[:type].present? - @feedbacks = Feedback.where(feedback_type: (params[:type] == 'msg' ? nil : params[:type])) + @feedbacks = Feedback.where(feedback_type: (params[:type] == "msg" ? nil : params[:type])) else @feedbacks = Feedback end diff --git a/app/controllers/admin/flavor_texts_controller.rb b/app/controllers/admin/flavor_texts_controller.rb index 4741985afa..0f7a541ca3 100644 --- a/app/controllers/admin/flavor_texts_controller.rb +++ b/app/controllers/admin/flavor_texts_controller.rb @@ -1,5 +1,4 @@ class Admin::FlavorTextsController < Admin::BaseController - def create @flavor_text = FlavorText.new(permitted_parameters) if @flavor_text.save diff --git a/app/controllers/admin/graphs_controller.rb b/app/controllers/admin/graphs_controller.rb index 39efe5eb5d..32a69604b9 100644 --- a/app/controllers/admin/graphs_controller.rb +++ b/app/controllers/admin/graphs_controller.rb @@ -13,33 +13,33 @@ def variable .group_by_period(@group_period, :created_at, time_zone: @timezone) .count elsif @kind == "payments" - chart_data =[ - {name: "All" , data: Payment.where(created_at: @start_at..@end_at) - .group_by_period(@group_period, :created_at, time_zone: @timezone) - .count}, - {name: "Payments" , data: Payment.where(created_at: @start_at..@end_at, is_payment: true) - .group_by_period(@group_period, :created_at, time_zone: @timezone) - .count}, - {name: "Donations", data: Payment.where(created_at: @start_at..@end_at, is_payment: false) - .group_by_period(@group_period, :created_at, time_zone: @timezone) - .count} - ] - elsif @kind == "bikes" - bikes = Bike.unscoped - chart_data =[ - {name: "Registered" , data: bikes.where(created_at: @start_at..@end_at) - .group_by_period(@group_period, :created_at, time_zone: @timezone) - .count}, - {name: "Stolen bikes" , data: StolenRecord.where(created_at: @start_at..@end_at) - .group_by_period(@group_period, :created_at, time_zone: @timezone) - .count} - ] - elsif @kind == "recoveries" - recoveries = StolenRecord.unscoped - chart_data = recoveries.where(date_recovered: @start_at..@end_at) - .group_by_period(@group_period, :date_recovered, time_zone: @timezone) - .count - end + chart_data = [ + { name: "All", data: Payment.where(created_at: @start_at..@end_at) + .group_by_period(@group_period, :created_at, time_zone: @timezone) + .count }, + { name: "Payments", data: Payment.where(created_at: @start_at..@end_at, is_payment: true) + .group_by_period(@group_period, :created_at, time_zone: @timezone) + .count }, + { name: "Donations", data: Payment.where(created_at: @start_at..@end_at, is_payment: false) + .group_by_period(@group_period, :created_at, time_zone: @timezone) + .count }, + ] + elsif @kind == "bikes" + bikes = Bike.unscoped + chart_data = [ + { name: "Registered", data: bikes.where(created_at: @start_at..@end_at) + .group_by_period(@group_period, :created_at, time_zone: @timezone) + .count }, + { name: "Stolen bikes", data: StolenRecord.where(created_at: @start_at..@end_at) + .group_by_period(@group_period, :created_at, time_zone: @timezone) + .count }, + ] + elsif @kind == "recoveries" + recoveries = StolenRecord.unscoped + chart_data = recoveries.where(date_recovered: @start_at..@end_at) + .group_by_period(@group_period, :date_recovered, time_zone: @timezone) + .count + end if chart_data.present? render json: chart_data.chart_json else @@ -57,24 +57,24 @@ def users def bikes bikes = Bike.unscoped case params[:start_at] - when 'past_year' + when "past_year" range = 1.year.ago.midnight..Time.now else range ||= bike_index_start..Time.now end bgraph = [ - { name: 'Registrations', data: bikes.group_by_month(:created_at, range: range).count }, - { name: 'Stolen', data: bikes.where(stolen: true).group_by_month(:created_at, range: range).count } + { name: "Registrations", data: bikes.group_by_month(:created_at, range: range).count }, + { name: "Stolen", data: bikes.where(stolen: true).group_by_month(:created_at, range: range).count }, ] render json: bgraph.chart_json end def show @graph_type = params[:id] - range = date_range('2013-01-18 21:03:08') + range = date_range("2013-01-18 21:03:08") @xaxis = month_list(range).to_json @values1 = range_values(range, "#{params[:id]}_value").to_json - if params[:id] == 'bikes' + if params[:id] == "bikes" @values2 = range_values(range, "stolen_bike_value").to_json end end @@ -90,7 +90,6 @@ def review days_from_this_week.each do |day| xaxis << day.strftime("%A") - end @xaxis = xaxis.to_json end @@ -99,7 +98,7 @@ def review # Default start time def bike_index_start - Time.zone.parse('2007-01-01 1:00') + Time.zone.parse("2007-01-01 1:00") end def set_variable_graph_kind @@ -128,14 +127,14 @@ def calculated_group_period(start_at, end_at) end def date_range(start_date) - date_from = Date.parse(start_date) - date_to = Date.today + date_from = Date.parse(start_date) + date_to = Date.today date_range = date_from..date_to - date_months = date_range.map {|d| Date.new(d.year, d.month, 1) }.uniq + date_months = date_range.map { |d| Date.new(d.year, d.month, 1) }.uniq end def month_list(range) - range.map {|d| d.strftime "%B" } + range.map { |d| d.strftime "%B" } end def range_values(range, type) diff --git a/app/controllers/admin/mail_snippets_controller.rb b/app/controllers/admin/mail_snippets_controller.rb index 50221bd6b8..7c0c7d2fce 100644 --- a/app/controllers/admin/mail_snippets_controller.rb +++ b/app/controllers/admin/mail_snippets_controller.rb @@ -11,12 +11,11 @@ def show end def edit - end def update if @mail_snippet.update_attributes(permitted_parameters) - flash[:success] = 'Snippet Saved!' + flash[:success] = "Snippet Saved!" redirect_to edit_admin_mail_snippet_url(@mail_snippet) else render action: :edit @@ -30,14 +29,13 @@ def new def create @mail_snippet = MailSnippet.create(permitted_parameters) if @mail_snippet.save - flash[:success] = 'Snippet Created!' + flash[:success] = "Snippet Created!" redirect_to edit_admin_mail_snippet_url(@mail_snippet) else render action: :new end end - protected def permitted_parameters diff --git a/app/controllers/admin/manufacturers_controller.rb b/app/controllers/admin/manufacturers_controller.rb index 6a9d392668..144bc35301 100644 --- a/app/controllers/admin/manufacturers_controller.rb +++ b/app/controllers/admin/manufacturers_controller.rb @@ -1,13 +1,13 @@ class Admin::ManufacturersController < Admin::BaseController before_filter :find_manufacturer, only: [:edit, :update, :destroy, :show] - layout 'new_admin' + layout "new_admin" def index @manufacturers = Manufacturer.all end def show - raise ActionController::RoutingError.new('Not Found') unless @manufacturer.present? + raise ActionController::RoutingError.new("Not Found") unless @manufacturer.present? @manufacturer = @manufacturer.decorate end @@ -20,9 +20,9 @@ def edit def update if @manufacturer.update_attributes(permitted_parameters) - flash[:success] = 'Manufacturer Saved!' - expire_fragment 'header_search' - AutocompleteLoaderWorker.perform_async('load_manufacturers') + flash[:success] = "Manufacturer Saved!" + expire_fragment "header_search" + AutocompleteLoaderWorker.perform_async("load_manufacturers") redirect_to admin_manufacturer_url(@manufacturer) else render action: :edit @@ -32,9 +32,9 @@ def update def create @manufacturer = Manufacturer.create(permitted_parameters) if @manufacturer.save - flash[:success] = 'Manufacturer Created!' - expire_fragment 'header_search' - AutocompleteLoaderWorker.perform_async('load_manufacturers') + flash[:success] = "Manufacturer Created!" + expire_fragment "header_search" + AutocompleteLoaderWorker.perform_async("load_manufacturers") redirect_to admin_manufacturer_url(@manufacturer) else render action: :new @@ -46,14 +46,13 @@ def destroy redirect_to admin_manufacturers_url end - def import if params[:file] Manufacturer.import(params[:file]) - flash[:success] = 'Manufacturers imported' + flash[:success] = "Manufacturers imported" redirect_to admin_manufacturers_url else - flash[:notice] = 'You gotta choose a file to import!' + flash[:notice] = "You gotta choose a file to import!" redirect_to admin_manufacturers_url end end @@ -66,6 +65,6 @@ def permitted_parameters def find_manufacturer @manufacturer = Manufacturer.friendly_find(params[:id]) - raise ActionController::RoutingError.new('Not Found') unless @manufacturer.present? + raise ActionController::RoutingError.new("Not Found") unless @manufacturer.present? end end diff --git a/app/controllers/admin/memberships_controller.rb b/app/controllers/admin/memberships_controller.rb index 3b82b5bfca..02336564ec 100644 --- a/app/controllers/admin/memberships_controller.rb +++ b/app/controllers/admin/memberships_controller.rb @@ -11,7 +11,7 @@ def index page = params[:page] || 1 per_page = params[:per_page] || 50 @memberships = @memberships.order(created_at: :desc) - .page(page).per(per_page) + .page(page).per(per_page) end def show @@ -36,13 +36,13 @@ def update def create user = User.fuzzy_email_find(params[:membership][:invited_email]) unless user.present? - flash[:error] = 'User not found. Perhaps you should invite them instead?' + flash[:error] = "User not found. Perhaps you should invite them instead?" @membership = Membership.new render action: :new and return end @membership = Membership.new(user_id: user.id, - organization_id: params[:membership][:organization_id], - role: params[:membership][:role]) + organization_id: params[:membership][:organization_id], + role: params[:membership][:role]) if @membership.save flash[:success] = "Membership Created!" redirect_to admin_membership_url(@membership) diff --git a/app/controllers/admin/news_controller.rb b/app/controllers/admin/news_controller.rb index 626a2674b6..df05ccf18e 100644 --- a/app/controllers/admin/news_controller.rb +++ b/app/controllers/admin/news_controller.rb @@ -44,7 +44,7 @@ def create user_id: current_user.id, body: "No content yet, write some now!", published_at: Time.now, - is_listicle: false + is_listicle: false, }) if @blog.save flash[:success] = "Blog created!" @@ -64,7 +64,7 @@ def destroy def permitted_parameters params.require(:blog).permit(*%w(title body user_id published_at post_date post_now tags published old_title_slug - timezone description_abbr update_title is_listicle listicles_attributes user_email index_image_id index_image).map(&:to_sym).freeze) + timezone description_abbr update_title is_listicle listicles_attributes user_email index_image_id index_image).map(&:to_sym).freeze) end def set_dignified_name diff --git a/app/controllers/admin/organization_invitations_controller.rb b/app/controllers/admin/organization_invitations_controller.rb index f65a078b0b..c2cd191dd7 100644 --- a/app/controllers/admin/organization_invitations_controller.rb +++ b/app/controllers/admin/organization_invitations_controller.rb @@ -1,11 +1,11 @@ class Admin::OrganizationInvitationsController < Admin::BaseController before_filter :find_organization before_filter :find_organization_invitation, only: [:edit, :update, :destroy] - + def index @organization_invitations = OrganizationInvitation.all end - + def new @organization_invitation = OrganizationInvitation.new @organizations = Organization.all @@ -23,7 +23,7 @@ def edit def update if @organization_invitation.update_attributes(permitted_parameters) - flash[:success] = 'Invitation Saved!' + flash[:success] = "Invitation Saved!" redirect_to admin_organization_invitations_url else render action: :edit @@ -33,7 +33,7 @@ def update def create @organization_invitation = OrganizationInvitation.new(permitted_parameters) @organization_invitation.inviter = current_user - + @organization = @organization_invitation.organization if @organization.available_invitation_count > 0 if @organization_invitation.save @@ -44,7 +44,7 @@ def create redirect_to edit_admin_organization_invitation_url(@organization_invitation.id, organization_id: @organization_invitation.organization.to_param) end else - flash[:error] = 'Oh no! This organization has no more invitations. Email contact@bikeindex.org for help' + flash[:error] = "Oh no! This organization has no more invitations. Email contact@bikeindex.org for help" redirect_to root_url end end diff --git a/app/controllers/admin/organizations/custom_layouts_controller.rb b/app/controllers/admin/organizations/custom_layouts_controller.rb index 0d4685ec38..5970749c53 100644 --- a/app/controllers/admin/organizations/custom_layouts_controller.rb +++ b/app/controllers/admin/organizations/custom_layouts_controller.rb @@ -6,7 +6,7 @@ def index def edit @edit_template = edit_layout_pages.include?(params[:id]) ? params[:id] : edit_layout_pages.first - unless @edit_template == 'landing_page' # Otherwise, we're rendering a snippet + unless @edit_template == "landing_page" # Otherwise, we're rendering a snippet @mail_snippet = @organization.mail_snippets.where(name: @edit_template).first_or_create end end @@ -34,7 +34,7 @@ def edit_layout_pages def find_and_authorize_organization @organization = Organization.friendly_find(params[:organization_id]) unless current_user.developer? - flash[:info] = 'Sorry, you must be a developer to access that page.' + flash[:info] = "Sorry, you must be a developer to access that page." redirect_to admin_organization_url(@organization) and return end unless @organization diff --git a/app/controllers/admin/organizations_controller.rb b/app/controllers/admin/organizations_controller.rb index 0449499e97..7fc8fe935a 100644 --- a/app/controllers/admin/organizations_controller.rb +++ b/app/controllers/admin/organizations_controller.rb @@ -16,7 +16,7 @@ def index def show @locations = @organization.locations.decorate - bikes = Bike.where(creation_organization_id: @organization.id).reorder('created_at desc') + bikes = Bike.where(creation_organization_id: @organization.id).reorder("created_at desc") page = params[:page] || 1 per_page = params[:per_page] || 25 @bikes = bikes.page(page).per(per_page) @@ -45,7 +45,7 @@ def edit def update # Needs to update approved before saving so set_locations_shown is applied on save if @organization.update_attributes(permitted_parameters) - flash[:success] = 'Organization Saved!' + flash[:success] = "Organization Saved!" redirect_to admin_organization_url(@organization) else render action: :edit @@ -56,7 +56,7 @@ def create @organization = Organization.new(permitted_parameters) @organization.approved = true if @organization.save - flash[:success] = 'Organization Created!' + flash[:success] = "Organization Created!" redirect_to edit_admin_organization_url(@organization) else render action: :new diff --git a/app/controllers/admin/ownerships_controller.rb b/app/controllers/admin/ownerships_controller.rb index 4fe5640105..146731892a 100644 --- a/app/controllers/admin/ownerships_controller.rb +++ b/app/controllers/admin/ownerships_controller.rb @@ -7,17 +7,17 @@ def edit def update if params[:ownership] if params[:ownership][:user_email].present? - params[:ownership][:user_id] = User.friendly_id_find(params[:ownership].delete(:user_email)) + params[:ownership][:user_id] = User.friendly_id_find(params[:ownership].delete(:user_email)) end if params[:ownership][:creator_email].present? params[:ownership][:creator_id] = User.friendly_id_find(params[:ownership].delete(:creator_email)) end end - if params[:ownership] && @ownership.update_attributes(permitted_parameters) - flash[:success] = 'Ownership Saved!' + if params[:ownership] && @ownership.update_attributes(permitted_parameters) + flash[:success] = "Ownership Saved!" redirect_to edit_admin_ownership_url(@ownership.id) else - flash[:info] = 'No information updated' + flash[:info] = "No information updated" render action: :edit end end @@ -26,7 +26,7 @@ def update def find_ownership @ownership = Ownership.find(params[:id]) - @bike = Bike.unscoped.find(@ownership.bike_id).decorate + @bike = Bike.unscoped.find(@ownership.bike_id).decorate @users = User.all end diff --git a/app/controllers/admin/paid_features_controller.rb b/app/controllers/admin/paid_features_controller.rb index 54489c5fea..e5e175cb50 100644 --- a/app/controllers/admin/paid_features_controller.rb +++ b/app/controllers/admin/paid_features_controller.rb @@ -1,7 +1,7 @@ class Admin::PaidFeaturesController < Admin::BaseController include SortableTable before_filter :find_paid_feature, only: %i[edit update] - layout 'new_admin' + layout "new_admin" def index @paid_features = PaidFeature.order(sort_column + " " + sort_direction) diff --git a/app/controllers/admin/paints_controller.rb b/app/controllers/admin/paints_controller.rb index 0cfb9cf643..95d3f1c52b 100644 --- a/app/controllers/admin/paints_controller.rb +++ b/app/controllers/admin/paints_controller.rb @@ -1,10 +1,10 @@ class Admin::PaintsController < Admin::BaseController before_filter :find_paint, only: [:show, :edit, :update, :destroy] - layout 'new_admin' + layout "new_admin" def index if params[:name] - paints = Paint.where('name LIKE ?', "%#{params[:name]}%") + paints = Paint.where("name LIKE ?", "%#{params[:name]}%") else paints = Paint.order("bikes_count DESC") end @@ -29,8 +29,8 @@ def edit def update if @paint.update_attributes(permitted_parameters) - black_id = Color.find_by_name('Black').id - flash[:success] = 'Paint updated!' + black_id = Color.find_by_name("Black").id + flash[:success] = "Paint updated!" if @paint.reload.color_id.present? bikes = @paint.bikes.where(primary_frame_color_id: black_id) bikes.each do |bike| @@ -54,7 +54,7 @@ def destroy flash[:error] = "Not allowed! Bikes use that paint! How the fuck did you delete that anyway?" else @paint.destroy - flash[:success] = 'Paint deleted!' + flash[:success] = "Paint deleted!" end redirect_to admin_paints_url end diff --git a/app/controllers/admin/payments_controller.rb b/app/controllers/admin/payments_controller.rb index 797db1a699..9c1828de0c 100644 --- a/app/controllers/admin/payments_controller.rb +++ b/app/controllers/admin/payments_controller.rb @@ -20,7 +20,7 @@ def invoices invoices = Invoice end @invoices = invoices.includes(:organization, :payments) - .reorder(sort_column + " " + sort_direction).page(page).per(per_page) + .reorder(sort_column + " " + sort_direction).page(page).per(per_page) end def new diff --git a/app/controllers/admin/recoveries_controller.rb b/app/controllers/admin/recoveries_controller.rb index 6bb1c0c80f..b46508888c 100644 --- a/app/controllers/admin/recoveries_controller.rb +++ b/app/controllers/admin/recoveries_controller.rb @@ -1,5 +1,6 @@ class Admin::RecoveriesController < Admin::BaseController layout "new_admin" + def index if params[:posted] @posted = true @@ -26,7 +27,7 @@ def edit def update @stolen_record = StolenRecord.unscoped.find(params[:id]) if @stolen_record.update_attributes(permitted_parameters) - flash[:success] = 'Recovery Saved!' + flash[:success] = "Recovery Saved!" redirect_to admin_recoveries_url else raise StandardError @@ -54,7 +55,7 @@ def approve redirect_to admin_recoveries_url else RecoveryNotifyWorker.perform_async(params[:id].to_i) - flash[:success] = 'Recovery notification enqueued.' + flash[:success] = "Recovery notification enqueued." redirect_to admin_recoveries_url end end diff --git a/app/controllers/admin/recovery_displays_controller.rb b/app/controllers/admin/recovery_displays_controller.rb index 08c3e2f205..7c5f2e2171 100644 --- a/app/controllers/admin/recovery_displays_controller.rb +++ b/app/controllers/admin/recovery_displays_controller.rb @@ -33,7 +33,7 @@ def edit def update if @recovery_display.update_attributes(permitted_parameters) clear_index_wrap_cache - flash[:success] = 'Recovery display saved!' + flash[:success] = "Recovery display saved!" redirect_to admin_recovery_displays_url else render action: :edit @@ -44,7 +44,7 @@ def create @recovery_display = RecoveryDisplay.create(permitted_parameters) if @recovery_display.save clear_index_wrap_cache - flash[:success] = 'Recovery display created!' + flash[:success] = "Recovery display created!" redirect_to admin_recovery_displays_url else render action: :new @@ -65,12 +65,12 @@ def permitted_parameters end def clear_index_wrap_cache - expire_fragment 'root_head_wrap' - expire_fragment 'root_body_wrap' + expire_fragment "root_head_wrap" + expire_fragment "root_body_wrap" end def find_recovery_displays @recovery_display = RecoveryDisplay.find(params[:id]) - raise ActionController::RoutingError.new('Not Found') unless @recovery_display.present? + raise ActionController::RoutingError.new("Not Found") unless @recovery_display.present? end end diff --git a/app/controllers/admin/stolen_bikes_controller.rb b/app/controllers/admin/stolen_bikes_controller.rb index ee0ab8e76b..eaa276e40c 100644 --- a/app/controllers/admin/stolen_bikes_controller.rb +++ b/app/controllers/admin/stolen_bikes_controller.rb @@ -6,7 +6,7 @@ def index if params[:unapproved] bikes = Bike.stolen.order("created_at desc") else - bikes = Bike.stolen.where('approved_stolen IS NOT TRUE') + bikes = Bike.stolen.where("approved_stolen IS NOT TRUE") @verified_only = true end page = params[:page] || 1 @@ -18,7 +18,7 @@ def approve @bike.current_stolen_record.update_attribute :approved, true @bike.update_attribute :approved_stolen, true ApproveStolenListingWorker.perform_async(@bike.id) - redirect_to edit_admin_stolen_bike_url(@bike), notice: 'Bike was approved.' + redirect_to edit_admin_stolen_bike_url(@bike), notice: "Bike was approved." end def show @@ -35,8 +35,8 @@ def update BikeUpdator.new(user: current_user, bike: @bike, b_params: { bike: permitted_parameters }).update_ownership @bike = @bike.decorate if @bike.update_attributes(permitted_parameters) - SerialNormalizer.new({serial: @bike.serial_number}).save_segments(@bike.id) - redirect_to edit_admin_stolen_bike_url(@bike), notice: 'Bike was successfully updated.' + SerialNormalizer.new({ serial: @bike.serial_number }).save_segments(@bike.id) + redirect_to edit_admin_stolen_bike_url(@bike), notice: "Bike was successfully updated." else render action: "edit" end diff --git a/app/controllers/admin/stolen_notifications_controller.rb b/app/controllers/admin/stolen_notifications_controller.rb index 582fc1eff6..9b7a407f34 100644 --- a/app/controllers/admin/stolen_notifications_controller.rb +++ b/app/controllers/admin/stolen_notifications_controller.rb @@ -1,9 +1,9 @@ class Admin::StolenNotificationsController < Admin::BaseController before_filter :find_notification, only: [:show, :resend] - layout 'new_admin' + layout "new_admin" def index - stolen_notifications = StolenNotification.order('created_at desc').includes(:bike) + stolen_notifications = StolenNotification.order("created_at desc").includes(:bike) page = params[:page] || 1 per_page = params[:per_page] || 100 @stolen_notifications = stolen_notifications.page(page).per(per_page) @@ -12,10 +12,10 @@ def index def resend if @stolen_notification.send_dates_parsed.count == 0 or params[:pretty_please] EmailStolenNotificationWorker.perform_async(@stolen_notification.id) - flash[:success] = 'Notification resent!' + flash[:success] = "Notification resent!" redirect_to admin_stolen_notifications_url else - flash[:success] = 'Notification has already been resent! If you actually want to resend, click the button on this page' + flash[:success] = "Notification has already been resent! If you actually want to resend, click the button on this page" redirect_to admin_stolen_notification_url(@stolen_notification) end end diff --git a/app/controllers/admin/tweets_controller.rb b/app/controllers/admin/tweets_controller.rb index 33caa8a907..395731d525 100644 --- a/app/controllers/admin/tweets_controller.rb +++ b/app/controllers/admin/tweets_controller.rb @@ -1,5 +1,6 @@ class Admin::TweetsController < Admin::BaseController before_filter :find_tweet, except: [:new, :create, :index] + def index @tweets = Tweet.order(created_at: :desc) end @@ -13,7 +14,7 @@ def edit def update if @tweet.update_attributes(permitted_parameters) - flash[:notice] = 'Tweet saved!' + flash[:notice] = "Tweet saved!" redirect_to edit_admin_tweet_url else render action: :edit diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 2e90dbeddf..a9a8561c34 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -10,7 +10,7 @@ def index else if params[:superusers] users = User.where(superuser: true) - else + else users = User.includes(memberships: [:organization]).order("created_at desc") end @users = users.page(page).per(per_page) @@ -39,7 +39,7 @@ def update @user.can_send_many_stolen_notifications = params[:user][:can_send_many_stolen_notifications] if @user.save @user.confirm(@user.confirmation_token) if params[:user][:confirmed] - redirect_to admin_users_url, notice: 'User Updated' + redirect_to admin_users_url, notice: "User Updated" else bikes = @user.bikes @bikes = BikeDecorator.decorate_collection(bikes) @@ -49,9 +49,8 @@ def update def destroy @user.destroy - redirect_to admin_users_url, notice: 'User Deleted.' + redirect_to admin_users_url, notice: "User Deleted." end - protected @@ -61,6 +60,6 @@ def find_user @user = User.where(id: user_id).first end @user ||= User.find_by_username(user_id) - raise ActionController::RoutingError.new('Not Found') unless @user.present? + raise ActionController::RoutingError.new("Not Found") unless @user.present? end end diff --git a/app/controllers/api/base.rb b/app/controllers/api/base.rb index c7aba525b9..d754747608 100644 --- a/app/controllers/api/base.rb +++ b/app/controllers/api/base.rb @@ -1,10 +1,10 @@ -require 'grape_logging' +require "grape_logging" module GrapeLogging module Loggers class BinxLogger < GrapeLogging::Loggers::Base def parameters(request, _) - { remote_ip: request.env['HTTP_CF_CONNECTING_IP'], format: 'json' } + { remote_ip: request.env["HTTP_CF_CONNECTING_IP"], format: "json" } end end end @@ -12,7 +12,7 @@ def parameters(request, _) module API class Base < Grape::API - use GrapeLogging::Middleware::RequestLogger, instrumentation_key: 'grape_key', + use GrapeLogging::Middleware::RequestLogger, instrumentation_key: "grape_key", include: [GrapeLogging::Loggers::BinxLogger.new, GrapeLogging::Loggers::FilterParameters.new] mount API::V3::RootV3 @@ -25,10 +25,10 @@ def self.respond_to_error(e) opts = { error: message || e.message } opts[:trace] = e.backtrace[0, 10] unless Rails.env.production? Rack::Response.new(opts.to_json, status_code_for(e, eclass), { - 'Content-Type' => 'application/json', - 'Access-Control-Allow-Origin' => '*', - 'Access-Control-Request-Method' => '*' - }).finish + "Content-Type" => "application/json", + "Access-Control-Allow-Origin" => "*", + "Access-Control-Request-Method" => "*", + }).finish end def self.status_code_for(error, eclass) diff --git a/app/controllers/api/v1/api_v1_controller.rb b/app/controllers/api/v1/api_v1_controller.rb index f7cb15c821..324e46b149 100644 --- a/app/controllers/api/v1/api_v1_controller.rb +++ b/app/controllers/api/v1/api_v1_controller.rb @@ -7,7 +7,6 @@ def not_found message = { :'error' => "404 - Couldn't find that shit" } respond_with message, status: 404 end - end end end diff --git a/app/controllers/api/v1/bikes_controller.rb b/app/controllers/api/v1/bikes_controller.rb index 308503d7f4..ed2e0ef486 100644 --- a/app/controllers/api/v1/bikes_controller.rb +++ b/app/controllers/api/v1/bikes_controller.rb @@ -12,17 +12,17 @@ def search_tags tags = [] Color.unscoped.commonness.each { |i| tags << i.name } HandlebarType::NAMES.values.each { |name| tags << name } - FrameMaterial::NAMES.values.each { |name| tags << name } + FrameMaterial::NAMES.values.each { |name| tags << name } WheelSize.unscoped.commonness.each { |i| tags << "#{i.name} wheel" } Manufacturer.all.each { |i| tags << i.name } CycleType::NAMES.values.each { |name| tags << name } - respond_with tags, root: 'tags' + respond_with tags, root: "tags" end def index - if params[:proximity] == 'ip' - if Rails.env == 'production' - params[:proximity] = request.env["HTTP_X_FORWARDED_FOR"].split(',')[0] + if params[:proximity] == "ip" + if Rails.env == "production" + params[:proximity] = request.env["HTTP_X_FORWARDED_FOR"].split(",")[0] else params[:proximity] = request.remote_ip end @@ -50,7 +50,7 @@ def stolen_ids end def close_serials - response = {bikes: []} + response = { bikes: [] } response = BikeSearcher.new(params).close_serials.limit(20) if params[:serial].present? respond_with response end @@ -63,21 +63,21 @@ def create params = de_string_params raise StandardError unless params[:bike].present? params[:bike][:creation_organization_id] = @organization.id - @b_param = BParam.create(creator_id: @organization.auto_user.id, params: permitted_b_params, origin: 'api_v1') + @b_param = BParam.create(creator_id: @organization.auto_user.id, params: permitted_b_params, origin: "api_v1") bike = BikeCreator.new(@b_param).create_bike if @b_param.errors.blank? && @b_param.bike_errors.blank? && bike.present? && bike.errors.blank? - render json: {bike: { web_url: bike_url(bike), api_url: api_v1_bike_url(bike)}} and return + render json: { bike: { web_url: bike_url(bike), api_url: api_v1_bike_url(bike) } } and return else if bike.present? e = bike.errors.full_messages.to_sentence else e = @b_param.errors.full_messages.to_sentence end - Feedback.create(email: 'contact@bikeindex.org', name: 'Error mailer', title: 'API Bike Creation error!', body: e) + Feedback.create(email: "contact@bikeindex.org", name: "Error mailer", title: "API Bike Creation error!", body: e) render json: e, status: :unprocessable_entity and return end end - + def authenticate_organization organization = Organization.friendly_find(params[:organization_slug]) if organization.present? && organization.access_token == params[:access_token] diff --git a/app/controllers/api/v1/colors_controller.rb b/app/controllers/api/v1/colors_controller.rb index 04a6377ba1..d38b52b75e 100644 --- a/app/controllers/api/v1/colors_controller.rb +++ b/app/controllers/api/v1/colors_controller.rb @@ -3,10 +3,10 @@ module V1 class ColorsController < ApiV1Controller before_filter :cors_preflight_check after_filter :cors_set_access_control_headers - + def index respond_with Color.all end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/component_types_controller.rb b/app/controllers/api/v1/component_types_controller.rb index 84946d9544..f45c8bf242 100644 --- a/app/controllers/api/v1/component_types_controller.rb +++ b/app/controllers/api/v1/component_types_controller.rb @@ -3,9 +3,10 @@ module V1 class ComponentTypesController < ApiV1Controller before_filter :cors_preflight_check after_filter :cors_set_access_control_headers + def index respond_with Ctype.all end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/cycle_types_controller.rb b/app/controllers/api/v1/cycle_types_controller.rb index 83ac4fa2a3..3bca43b8b9 100644 --- a/app/controllers/api/v1/cycle_types_controller.rb +++ b/app/controllers/api/v1/cycle_types_controller.rb @@ -9,4 +9,4 @@ def index end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/frame_materials_controller.rb b/app/controllers/api/v1/frame_materials_controller.rb index 5083d5c1aa..af60289ca8 100644 --- a/app/controllers/api/v1/frame_materials_controller.rb +++ b/app/controllers/api/v1/frame_materials_controller.rb @@ -9,4 +9,4 @@ def index end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/handlebar_types_controller.rb b/app/controllers/api/v1/handlebar_types_controller.rb index d4f02b18f0..be0dc478c0 100644 --- a/app/controllers/api/v1/handlebar_types_controller.rb +++ b/app/controllers/api/v1/handlebar_types_controller.rb @@ -9,4 +9,4 @@ def index end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/manufacturers_controller.rb b/app/controllers/api/v1/manufacturers_controller.rb index 4892a27597..e89566fc3f 100644 --- a/app/controllers/api/v1/manufacturers_controller.rb +++ b/app/controllers/api/v1/manufacturers_controller.rb @@ -24,7 +24,6 @@ def show manufacturer = Manufacturer.where(id: params[:id]).first respond_with manufacturer end - end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb index fd1ff373d0..fc3616ecfc 100644 --- a/app/controllers/api/v1/notifications_controller.rb +++ b/app/controllers/api/v1/notifications_controller.rb @@ -2,33 +2,33 @@ module Api module V1 class NotificationsController < ApiV1Controller before_filter :authenticate_notification_permission - skip_before_filter :verify_authenticity_token + skip_before_filter :verify_authenticity_token def create bike = Bike.find(params[:notification_hash][:bike_id]) - if params[:notification_hash][:notification_type].to_s.match('stolen_twitter_alerter').present? + if params[:notification_hash][:notification_type].to_s.match("stolen_twitter_alerter").present? if bike.find_current_stolen_record.present? - customer_contact = CustomerContact.new(body: 'EMPTY', - bike_id: bike.id, - contact_type: 'stolen_twitter_alerter', - title: title_tag(bike), - user_email: bike.owner_email, - creator_email: 'bryan@bikeindex.org', - info_hash: params[:notification_hash]) + customer_contact = CustomerContact.new(body: "EMPTY", + bike_id: bike.id, + contact_type: "stolen_twitter_alerter", + title: title_tag(bike), + user_email: bike.owner_email, + creator_email: "bryan@bikeindex.org", + info_hash: params[:notification_hash]) if customer_contact.save EmailStolenBikeAlertWorker.perform_async(customer_contact.id) render json: { success: true } and return else msg = customer_contact.errors.full_messages.to_sentence - render json: {error: msg}, status: :unprocessable_entity and return + render json: { error: msg }, status: :unprocessable_entity and return end end end - render json: {error: "Unable to send that email, srys"}, status: :unprocessable_entity and return + render json: { error: "Unable to send that email, srys" }, status: :unprocessable_entity and return end - + def authenticate_notification_permission - unless params[:access_token] == ENV['NOTIFICATIONS_API_KEY'] + unless params[:access_token] == ENV["NOTIFICATIONS_API_KEY"] render json: "Not authorized", status: :unauthorized and return end end @@ -40,8 +40,6 @@ def title_tag(bike) "We tweeted about your stolen bike!" end end - end - end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/organizations_controller.rb b/app/controllers/api/v1/organizations_controller.rb index 6bc43f2cf6..3079761b66 100644 --- a/app/controllers/api/v1/organizations_controller.rb +++ b/app/controllers/api/v1/organizations_controller.rb @@ -10,17 +10,17 @@ def show end private + def verify_organizations_token @organization = Organization.friendly_find(params[:id]) redirect_to api_v1_not_found_url and return unless @organization.present? if params[:access_token].present? - return true if params[:access_token] == ENV['ORGANIZATIONS_API_ACCESS_TOKEN'] + return true if params[:access_token] == ENV["ORGANIZATIONS_API_ACCESS_TOKEN"] return true if params[:access_token] == @organization.access_token end message = { :'401' => "Not permitted" } respond_with message, status: :unauthorized and return end - end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/stolen_locking_response_suggestions_controller.rb b/app/controllers/api/v1/stolen_locking_response_suggestions_controller.rb index 3a9f0e42c9..322c14bfdc 100644 --- a/app/controllers/api/v1/stolen_locking_response_suggestions_controller.rb +++ b/app/controllers/api/v1/stolen_locking_response_suggestions_controller.rb @@ -7,10 +7,10 @@ class StolenLockingResponseSuggestionsController < ApiV1Controller def index descriptions = { locking_descriptions: StolenRecord.locking_description, - locking_defeat_descriptions: StolenRecord.locking_defeat_description + locking_defeat_descriptions: StolenRecord.locking_defeat_description, } respond_with descriptions end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index ed2e1237bf..f6de87f9bb 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -2,9 +2,10 @@ module Api module V1 class UsersController < ApiV1Controller before_filter :bust_cache!, only: [:current] + def default_serializer_options { - root: false + root: false, } end @@ -24,7 +25,7 @@ def send_request bike = Bike.find(bike_id) if bike.owner == current_user feedback = Feedback.new(email: current_user.email, body: reason, title: "#{feedback_type.titleize}", feedback_type: feedback_type) - feedback.name = (current_user.name.present? && current_user.name) || 'no name' + feedback.name = (current_user.name.present? && current_user.name) || "no name" feedback.feedback_hash = { bike_id: bike_id } if params[:serial_update_serial].present? bike.current_stolen_record.update_attribute :tsved_at, nil if bike.current_stolen_record.present? @@ -44,15 +45,15 @@ def send_request bike.save feedback.feedback_hash[:new_manufacturer] = bike.manufacturer.name end - elsif feedback_type.match('bike_recovery') + elsif feedback_type.match("bike_recovery") recover_bike(bike, feedback) end feedback.save - success = { success: 'submitted request' } + success = { success: "submitted request" } render json: success and return end end - message = { errors: { not_allowed: 'nuh-uh' } } + message = { errors: { not_allowed: "nuh-uh" } } render json: message, status: 403 end @@ -75,4 +76,4 @@ def recover_bike(bike, feedback) end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v1/wheel_sizes_controller.rb b/app/controllers/api/v1/wheel_sizes_controller.rb index 86782a8c9f..e3db04c92e 100644 --- a/app/controllers/api/v1/wheel_sizes_controller.rb +++ b/app/controllers/api/v1/wheel_sizes_controller.rb @@ -3,9 +3,10 @@ module V1 class WheelSizesController < ApiV1Controller before_filter :cors_preflight_check after_filter :cors_set_access_control_headers + def index respond_with WheelSize.all end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v2/bikes.rb b/app/controllers/api/v2/bikes.rb index 6694d1b572..6056022583 100644 --- a/app/controllers/api/v2/bikes.rb +++ b/app/controllers/api/v2/bikes.rb @@ -15,14 +15,14 @@ class Bikes < API::Base optional :primary_frame_color, type: String, values: COLOR_NAMES, desc: "Main color of frame (case sensitive match)" optional :secondary_frame_color, type: String, values: COLOR_NAMES, desc: "Secondary color (case sensitive match)" optional :tertiary_frame_color, type: String, values: COLOR_NAMES, desc: "Third color (case sensitive match)" - optional :rear_gear_type_slug, type: String, desc: 'rear gears (has to be one of the `selections`)' - optional :front_gear_type_slug, type: String, desc: 'front gears (has to be one of the `selections`)' - optional :handlebar_type_slug, type: String, desc: 'handlebar type (has to be one of the `selections`)' + optional :rear_gear_type_slug, type: String, desc: "rear gears (has to be one of the `selections`)" + optional :front_gear_type_slug, type: String, desc: "front gears (has to be one of the `selections`)" + optional :handlebar_type_slug, type: String, desc: "handlebar type (has to be one of the `selections`)" optional :no_notify, type: Boolean, desc: "On create or ownership change, don't notify the new owner." optional :is_for_sale, type: Boolean optional :frame_material, type: String, values: Bike.frame_materials.keys, desc: "Frame material type" optional :external_image_urls, type: Array, desc: "Image urls to include with registration, if images are already on the internet" - + optional :stolen_record, type: Hash do optional :phone, type: String, desc: "Owner's phone number, **required to create stolen**" optional :city, type: String, desc: "City where stolen
    **required to create stolen**" @@ -32,24 +32,24 @@ class Bikes < API::Base optional :address, type: String, desc: "Public. Use an intersection if you'd prefer the specific address not be revealed" optional :date_stolen, type: Integer, desc: "When was the bike stolen (defaults to current time)" - optional :police_report_number, type: String, desc: 'Police report number' - optional :police_report_department, type: String, desc: 'Police department reported to (include if report number present)' + optional :police_report_number, type: String, desc: "Police report number" + optional :police_report_department, type: String, desc: "Police department reported to (include if report number present)" optional :show_address, type: Boolean, desc: "Display the exact address the theft happened at" - # # link to LOCKING options! - # # optional :locking_description_slug, type: String, desc: 'Locking description. description.' - # # optional :lock_defeat_description_slug, type: String, desc: 'Lock defeat description. One of the values from lock defeat desc' - # # optional :theft_description, type: String, desc: 'stuff' + # # link to LOCKING options! + # # optional :locking_description_slug, type: String, desc: 'Locking description. description.' + # # optional :lock_defeat_description_slug, type: String, desc: 'Lock defeat description. One of the values from lock defeat desc' + # # optional :theft_description, type: String, desc: 'stuff' - # # optional :phone_for_everyone, type: Boolean, default: false, desc: 'Show phone number to non logged in users' - # # optional :phone_for_users, type: Boolean, default: true, desc: 'Show phone to logged in users' + # # optional :phone_for_everyone, type: Boolean, default: false, desc: 'Show phone number to non logged in users' + # # optional :phone_for_users, type: Boolean, default: true, desc: 'Show phone to logged in users' end end - params :components_attrs do + params :components_attrs do optional :manufacturer, type: String, desc: "Manufacturer name or ID" # [Manufacturer name or ID](api_v2#!/manufacturers/GET_version_manufacturers_format) - optional :component_type, type: String, desc: 'Type of component', values: CTYPE_NAMES + optional :component_type, type: String, desc: "Type of component", values: CTYPE_NAMES optional :model, type: String, desc: "Component model" optional :year, type: Integer, desc: "Component year" optional :description, type: String, desc: "Component description" @@ -58,13 +58,13 @@ class Bikes < API::Base end def creation_user_id - if current_user.id == ENV['V2_ACCESSOR_ID'].to_i + if current_user.id == ENV["V2_ACCESSOR_ID"].to_i org = params[:organization_slug].present? && Organization.friendly_find(params[:organization_slug]) if org && current_token.application.owner && current_token.application.owner.admin_of?(org) return org.auto_user_id end error!("Permanent tokens can only be used to create bikes for organizations your are an admin of", 403) - end + end current_user.id end @@ -73,7 +73,7 @@ def creation_state_params is_bulk: params[:is_bulk], is_pos: params[:is_pos], is_new: params[:is_new], - no_duplicate: params[:no_duplicate] + no_duplicate: params[:no_duplicate], } end @@ -81,15 +81,15 @@ def find_bike @bike = Bike.unscoped.find(params[:id]) end - def authorize_bike_for_user(addendum='') + def authorize_bike_for_user(addendum = "") return true if @bike.authorize_for_user!(current_user) error!("You do not own that #{@bike.type}#{addendum}", 403) end def ensure_required_stolen_attrs(hash) - return true unless hash['bike']['stolen'] + return true unless hash["bike"]["stolen"] %w(phone city).each do |k| - error!("Could not create stolen record: missing #{k}", 401) unless hash['stolen_record'][k].present? + error!("Could not create stolen record: missing #{k}", 401) unless hash["stolen_record"][k].present? end end end @@ -97,19 +97,18 @@ def ensure_required_stolen_attrs(hash) resource :bikes do desc "View bike with a given ID" params do - requires :id, type: Integer, desc: 'Bike id' + requires :id, type: Integer, desc: "Bike id" end - get ':id', serializer: BikeV2ShowSerializer, root: 'bike' do + get ":id", serializer: BikeV2ShowSerializer, root: "bike" do find_bike end - desc "Add a bike to the Index!*", { authorizations: { oauth2: [{ scope: :write_bikes }] }, - notes: <<-NOTE + notes: <<-NOTE, **Requires** `write_bikes` **in the access token** you use to create the bike. -
    +
    **Creating test bikes**: To create test bikes, set `test` to true. These bikes: @@ -133,15 +132,15 @@ def ensure_required_stolen_attrs(hash) requires :color, type: String, desc: "Main color or paint - does not have to be one of the accepted colors" optional :test, type: Boolean, desc: "Is this a test bike?" optional :organization_slug, type: String, desc: "Organization bike should be created by. **Only works** if user is a member of the organization" - optional :cycle_type_name, type: String, values: CYCLE_TYPE_NAMES, default: 'bike', desc: "Type of cycle (case sensitive match)" + optional :cycle_type_name, type: String, values: CYCLE_TYPE_NAMES, default: "bike", desc: "Type of cycle (case sensitive match)" use :bike_attrs optional :components, type: Array do use :components_attrs end end - post '/', serializer: BikeV2ShowSerializer, root: 'bike' do + post "/", serializer: BikeV2ShowSerializer, root: "bike" do declared_p = { "declared_params" => declared(params, include_missing: false).merge(creation_state_params) } - b_param = BParam.create(creator_id: creation_user_id, params: declared_p['declared_params'], origin: 'api_v2') + b_param = BParam.create(creator_id: creation_user_id, params: declared_p["declared_params"], origin: "api_v2") ensure_required_stolen_attrs(b_param.params) bike = BikeCreator.new(b_param).create_bike if b_param.errors.blank? && b_param.bike_errors.blank? && bike.present? && bike.errors.blank? @@ -152,17 +151,16 @@ def ensure_required_stolen_attrs(hash) end end - desc "Update a bike owned by the access token*", { authorizations: { oauth2: [{ scope: :write_bikes }] }, - notes: <<-NOTE + notes: <<-NOTE, **Requires** `read_user` **in the access token** you use to send the notification. - + Update a bike owned by the access token you're using. NOTE } - params do + params do requires :id, type: Integer, desc: "Bike ID" use :bike_attrs optional :owner_email, type: String, desc: "Send the bike to a new owner!" @@ -172,12 +170,12 @@ def ensure_required_stolen_attrs(hash) optional :destroy, type: Boolean, desc: "Delete this component (requires an ID)" end end - put ':id', serializer: BikeV2ShowSerializer, root: 'bike' do + put ":id", serializer: BikeV2ShowSerializer, root: "bike" do declared_p = { "declared_params" => declared(params, include_missing: false) } find_bike authorize_bike_for_user - hash = BParam.v2_params(declared_p['declared_params'].as_json) - ensure_required_stolen_attrs(hash) if hash['stolen_record'].present? && @bike.stolen != true + hash = BParam.v2_params(declared_p["declared_params"].as_json) + ensure_required_stolen_attrs(hash) if hash["stolen_record"].present? && @bike.stolen != true @bike.load_external_images(hash["bike"]["external_image_urls"]) if hash.dig("bike", "external_image_urls").present? begin BikeUpdator.new(user: current_user, bike: @bike, b_params: hash).update_available_attributes @@ -189,11 +187,11 @@ def ensure_required_stolen_attrs(hash) desc "Add an image to a bike", { authorizations: { oauth2: [{ scope: :write_bikes }] }, - notes: <<-NOTE + notes: <<-NOTE, To post a file to the API with curl: - `curl -X POST -i -F file=@{test_file.jpg} "#{ENV['BASE_URL']}/api/v2/bikes/{bike_id}/image?access_token={access_token}"` + `curl -X POST -i -F file=@{test_file.jpg} "#{ENV["BASE_URL"]}/api/v2/bikes/{bike_id}/image?access_token={access_token}"` Replace `{text_file.jpg}` with the relative path of the file you're posting. @@ -201,11 +199,11 @@ def ensure_required_stolen_attrs(hash) NOTE } - params do + params do requires :id, type: Integer, desc: "Bike ID" requires :file, :type => Rack::Multipart::UploadedFile, :desc => "Attachment." end - post ':id/image', serializer: PublicImageSerializer, root: 'image' do + post ":id/image", serializer: PublicImageSerializer, root: "image" do declared_p = { "declared_params" => declared(params, include_missing: false) } find_bike authorize_bike_for_user @@ -217,10 +215,9 @@ def ensure_required_stolen_attrs(hash) end end - desc "Send a stolen notification*", { authorizations: { oauth2: [{ scope: :read_user }] }, - notes: <<-NOTE + notes: <<-NOTE, **Requires** `read_user` **in the access token** you use to send the notification.
    @@ -232,23 +229,20 @@ def ensure_required_stolen_attrs(hash) Before your application is approved you can send notifications to yourself (to a bike that you own that's stolen). NOTE } - params do + params do requires :id, type: Integer, desc: "Bike ID. **MUST BE A STOLEN BIKE**" requires :message, type: String, desc: "The message you are sending to the owner" end - post ':id/send_stolen_notification', serializer: StolenNotificationSerializer do + post ":id/send_stolen_notification", serializer: StolenNotificationSerializer do find_bike error!("Bike is not stolen", 400) unless @bike.present? && @bike.stolen # Unless application is authorized.... - authorize_bike_for_user(" (this application is not approved to send notifications)") + authorize_bike_for_user(" (this application is not approved to send notifications)") StolenNotification.create(bike_id: params[:id], - message: params[:message], - sender: current_user - ) + message: params[:message], + sender: current_user) end - end - end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v2/bikes_search.rb b/app/controllers/api/v2/bikes_search.rb index c1ea8d8000..cd7e92281f 100644 --- a/app/controllers/api/v2/bikes_search.rb +++ b/app/controllers/api/v2/bikes_search.rb @@ -3,7 +3,7 @@ module V2 class BikesSearch < API::Base include API::V2::Defaults helpers do - params :search_bikes do + params :search_bikes do optional :colors, type: String, desc: "Comma separated list. Results will match **all** colors" # [View colors we accept](#!/selections/GET_version_selections_format) optional :manufacturer, type: String, desc: "Manufacturer name or ID" @@ -12,8 +12,8 @@ class BikesSearch < API::Base optional :serial, type: String, desc: "Serial number" end - params :stolen_search do - optional :proximity, type: String, desc: "Center of location for proximity search", documentation: { example: '45.521728,-122.67326'} + params :stolen_search do + optional :proximity, type: String, desc: "Center of location for proximity search", documentation: { example: "45.521728,-122.67326" } optional :proximity_square, type: Integer, desc: "Size of the proximity search", default: 100 optional :stolen_before, type: Integer, desc: "Bikes stolen before timestamp" optional :stolen_after, type: Integer, desc: "Bikes stolen after timestamp" @@ -26,16 +26,15 @@ def find_bikes def set_proximity params[:proximity_radius] ||= params[:proximity_square] if params[:proximity_square].present? params[:proximity_radius] ||= 100 - return nil unless params[:proximity] == 'ip' - if Rails.env == 'production' - params[:proximity] = request.env["HTTP_X_FORWARDED_FOR"].split(',')[0] + return nil unless params[:proximity] == "ip" + if Rails.env == "production" + params[:proximity] = request.env["HTTP_X_FORWARDED_FOR"].split(",")[0] end end end - resource :bikes_search, desc: 'Searching for bikes' do - + resource :bikes_search, desc: "Searching for bikes" do desc "All bike search", { - notes: <<-NOTE + notes: <<-NOTE, If you want to find any matching bike, use this endpoint. You can not use location information here, since this includes non_stolen bikes (which don't have location information) NOTE @@ -44,13 +43,13 @@ def set_proximity params do use :search_bikes end - get '/', root: 'bikes', each_serializer: BikeV2Serializer do - { 'declared_params' => declared(params, include_missing: false) } + get "/", root: "bikes", each_serializer: BikeV2Serializer do + { "declared_params" => declared(params, include_missing: false) } paginate find_bikes end desc "Stolen bike search", { - notes: <<-NOTE + notes: <<-NOTE, If you want to search for bikes stolen near a specific location, you need to use this endpoint. Keep in mind that it only returns stolen bikes - so if you do a serial search, and nothing turns up that doesn't mean that the bike isn't registered. **Notes on location searching**: @@ -63,9 +62,9 @@ def set_proximity use :search_bikes use :stolen_search end - get '/stolen', root: 'bikes', each_serializer: BikeV2Serializer do + get "/stolen", root: "bikes", each_serializer: BikeV2Serializer do params[:stolen] = true - { 'declared_params' => declared(params, include_missing: false) } + { "declared_params" => declared(params, include_missing: false) } set_proximity paginate find_bikes end @@ -75,15 +74,14 @@ def set_proximity params do use :search_bikes end - get '/non_stolen', root: 'bikes', each_serializer: BikeV2Serializer do + get "/non_stolen", root: "bikes", each_serializer: BikeV2Serializer do params[:non_stolen] = true - { 'declared_params' => declared(params, include_missing: false) } + { "declared_params" => declared(params, include_missing: false) } paginate find_bikes end - - desc 'Count of bikes matching search', { - notes: <<-NOTE + desc "Count of bikes matching search", { + notes: <<-NOTE, Include all the options you would pass in your search. This will respond with a hash of the number of bikes matching your search for each type: ```javascript @@ -103,32 +101,31 @@ def set_proximity use :search_bikes use :stolen_search end - get '/count', root: 'bikes', each_serializer: BikeV2Serializer do - { 'declared_params' => declared(params, include_missing: false) } + get "/count", root: "bikes", each_serializer: BikeV2Serializer do + { "declared_params" => declared(params, include_missing: false) } params[:proximity] = params[:proximity] || "ip" set_proximity BikeSearcher.new(params).find_bike_counts end - - desc 'Close serials', { - notes: <<-NOTE + desc "Close serials", { + notes: <<-NOTE, We can find bikes with serials close to the serial you search you input. Close serials are serials that are off by one or two characters Note: [Homoglyph](https://en.wikipedia.org/wiki/Homoglyph) matching happens for all endpoints (e.g. 1GGGGO will find IGGG0), you don't need to use `close_serials` to get it. NOTE } paginate - params do + params do requires :serial, type: String, desc: "Serial to search for" end - get '/close_serials', root: 'bikes', each_serializer: BikeV2Serializer do + get "/close_serials", root: "bikes", each_serializer: BikeV2Serializer do bikes = BikeSearcher.new(params.merge(api_search: true)).close_serials paginate bikes end - desc 'All stolen bikes', { - notes: <<-NOTE + desc "All stolen bikes", { + notes: <<-NOTE, Returns all the stolen bikes. Not paginated, the response is over > 10mb This is a cached response, updated a few times a day. The most recent update time is in the `Last-Modified` header. @@ -136,10 +133,10 @@ def set_proximity Note: this redirects to a static, cached JSON file. It doesn't work in the documentation. NOTE } - get '/all_stolen' do + get "/all_stolen" do all_stolen = FileCacheMaintainer.cached_all_stolen - header 'Last-Modified', Time.at(all_stolen['updated_at'].to_i).httpdate - Rails.env.production? ? redirect(all_stolen['path']) : JSON.parse(File.read(all_stolen['path'])) + header "Last-Modified", Time.at(all_stolen["updated_at"].to_i).httpdate + Rails.env.production? ? redirect(all_stolen["path"]) : JSON.parse(File.read(all_stolen["path"])) end end end diff --git a/app/controllers/api/v2/manufacturers.rb b/app/controllers/api/v2/manufacturers.rb index d5f3b27f52..29c7572679 100644 --- a/app/controllers/api/v2/manufacturers.rb +++ b/app/controllers/api/v2/manufacturers.rb @@ -6,19 +6,19 @@ class Manufacturers < API::Base resource :manufacturers, desc: "Accepted manufacturers" do desc "All the manufacturers with pagination" paginate - get '/' do + get "/" do paginate Manufacturer.reorder(:name) end - + desc "Manufacturer matching ID or name", { - notes: <<-NOTE + notes: <<-NOTE, You can request a manufacturer by either their name or their ID NOTE } params do - requires :id, type: String, desc: 'Manufacturer id or slug' + requires :id, type: String, desc: "Manufacturer id or slug" end - get ':id', serializer: ManufacturerV2ShowSerializer do + get ":id", serializer: ManufacturerV2ShowSerializer do manufacturer = Manufacturer.friendly_find(params[:id]) unless manufacturer.present? msg = "Unable to find manufacturer with name or id: #{params[:id]}" @@ -27,7 +27,6 @@ class Manufacturers < API::Base manufacturer end end - end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v2/me.rb b/app/controllers/api/v2/me.rb index 41fd1257c2..aa42804a05 100644 --- a/app/controllers/api/v2/me.rb +++ b/app/controllers/api/v2/me.rb @@ -3,9 +3,9 @@ module V2 class Me < API::Base include API::V2::Defaults resource :me, desc: "Operations about the current user" do - helpers do + helpers do def user_info - return {} unless current_scopes.include?('read_user') + return {} unless current_scopes.include?("read_user") { user: { username: current_user.username, @@ -13,33 +13,33 @@ def user_info email: current_user.email, secondary_emails: current_user.secondary_emails, twitter: (current_user.twitter if current_user.show_twitter), - image: (current_user.avatar_url if current_user.show_bikes) - } + image: (current_user.avatar_url if current_user.show_bikes), + }, } end - + def bike_ids - current_scopes.include?('read_bikes') ? { bike_ids: current_user.bike_ids } : {} + current_scopes.include?("read_bikes") ? { bike_ids: current_user.bike_ids } : {} end def serialized_membership(membership) { organization_name: membership.organization.name, - organization_slug: membership.organization.slug, + organization_slug: membership.organization.slug, organization_access_token: membership.organization.access_token, - user_is_organization_admin: (true ? membership.role == 'admin' : false) + user_is_organization_admin: (true ? membership.role == "admin" : false), } end def organization_memberships - return {} unless current_scopes.include?('read_organization_membership') + return {} unless current_scopes.include?("read_organization_membership") { memberships: current_user.memberships.map { |m| serialized_membership(m) } } end end desc "Current user's information in access token's scope*", { authorizations: { oauth2: [] }, - notes: <<-NOTE + notes: <<-NOTE, Current user is the owner of the `access_token` you use in the request. Depending on your scopes you will get different things back. You will always get the user's `id` For an array of the user's bike ids, you need `read_bikes` access @@ -48,23 +48,23 @@ def organization_memberships NOTE } - get '/' do + get "/" do { id: current_user.id.to_s }.merge(user_info).merge(bike_ids).merge(organization_memberships) end desc "Current user's bikes*", { authorizations: { oauth2: [{ scope: :read_bikes }] }, - notes: <<-NOTE + notes: <<-NOTE, This returns the current user's bikes, so long as the access_token has the `read_bikes` scope. This uses the bike list bike objects, which only contains the most important information. To get all possible information about a bike use `/bikes/{id}` NOTE } - get '/bikes', each_serializer: BikeV2Serializer, root: 'bikes' do + get "/bikes", each_serializer: BikeV2Serializer, root: "bikes" do current_user.bikes end end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v2/root_v2.rb b/app/controllers/api/v2/root_v2.rb index 01cfb5d150..2577583720 100644 --- a/app/controllers/api/v2/root_v2.rb +++ b/app/controllers/api/v2/root_v2.rb @@ -4,7 +4,7 @@ class RootV2 < API::Base format :json version %w(v3 v2) default_error_formatter :json - content_type :json, 'application/json' + content_type :json, "application/json" use ::WineBouncer::OAuth2 rescue_from :all do |e| @@ -16,22 +16,22 @@ class RootV2 < API::Base mount API::V2::Users mount API::V2::Manufacturers mount API::V2::Selections - add_swagger_documentation base_path: '/api', - api_version: 'v2', + add_swagger_documentation base_path: "/api", + api_version: "v2", hide_format: true, # don't show .json hide_documentation_path: true, - mount_path: '/swagger_doc', + mount_path: "/swagger_doc", markdown: GrapeSwagger::Markdown::KramdownAdapter, cascade: false, info: { - title: 'BikeIndex API v2', + title: "BikeIndex API v2", description: "This is the API for Bike Index. It's authenticated with OAuth2 and is generally pretty awesome", - contact: 'support@bikeindex.org', - license_url: 'https://github.com/bikeindex/bike_index/blob/master/LICENSE', - terms_of_service_url: 'https://bikeindex.org/terms' + contact: "support@bikeindex.org", + license_url: "https://github.com/bikeindex/bike_index/blob/master/LICENSE", + terms_of_service_url: "https://bikeindex.org/terms", } - route :any, '*path' do - raise StandardError, 'Unable to find endpoint' + route :any, "*path" do + raise StandardError, "Unable to find endpoint" end end end diff --git a/app/controllers/api/v2/selections.rb b/app/controllers/api/v2/selections.rb index aa9f2a50b5..334355aa95 100644 --- a/app/controllers/api/v2/selections.rb +++ b/app/controllers/api/v2/selections.rb @@ -4,64 +4,62 @@ class Selections < API::Base include API::V2::Defaults resource :selections, desc: "Selections (static options)" do - desc "Frame colors" - get '/colors', root: 'colors' do + get "/colors", root: "colors" do Color.all end desc "Types of components" - get '/component_types', each_serializer: CtypeSerializer, root: 'component_types' do + get "/component_types", each_serializer: CtypeSerializer, root: "component_types" do Ctype.all end desc "Types of cycles" - get '/cycle_types', root: 'cycle_types' do + get "/cycle_types", root: "cycle_types" do CycleType.legacy_selections end desc "Frame materials" - get '/frame_materials', root: 'frame_materials' do + get "/frame_materials", root: "frame_materials" do FrameMaterial.legacy_selections end desc "Front gear types" - get '/front_gear_types', root: 'front_gear_types' do + get "/front_gear_types", root: "front_gear_types" do FrontGearType.all end desc "Rear gear types" - get '/rear_gear_types', root: 'rear_gear_types' do + get "/rear_gear_types", root: "rear_gear_types" do RearGearType.all end desc "Handlebars" - get '/handlebar_types', root: 'handlebar_types' do + get "/handlebar_types", root: "handlebar_types" do HandlebarType.legacy_selections end desc "Propulsion types" - get '/propulsion_types', root: 'propulsion_types' do + get "/propulsion_types", root: "propulsion_types" do PropulsionType.legacy_selections end - + desc "Wheel sizes (paginated)", { - notes: <<-NOTE + notes: <<-NOTE, We identify wheel sizes by ISO - if you'd like to learn more about ISO, check out [Sheldon Brown's article on tire-sizing](http://sheldonbrown.com/tire-sizing.html#iso). We include all the ISO BSD sizes we're familiar with. You can choose get an abbreviated list by passing a `min_popularity`. Since wheel sizes frequently have similar names, we recommend only displaying standard and common sizes. NOTE } paginate - params do - optional :min_popularity, type: String, desc: 'Minimum commonness of wheel size to include', values: WheelSize.popularities + params do + optional :min_popularity, type: String, desc: "Minimum commonness of wheel size to include", values: WheelSize.popularities end - get '/wheel_sizes', root: 'wheel_sizes' do + get "/wheel_sizes", root: "wheel_sizes" do priority = WheelSize.popularities.index(params[:min_popularity]) || 0 wheel_sizes = WheelSize.where("priority > ?", priority) paginate wheel_sizes end - end end end diff --git a/app/controllers/api/v2/users.rb b/app/controllers/api/v2/users.rb index 134378436f..0d8a3f0386 100644 --- a/app/controllers/api/v2/users.rb +++ b/app/controllers/api/v2/users.rb @@ -4,29 +4,29 @@ class Users < API::Base include API::V2::Defaults resource :users do - helpers do + helpers do def user_info { username: current_user.username, name: current_user.name, - email: current_user.email, + email: current_user.email, twitter: (current_user.twitter if current_user.show_twitter), - image: (current_user.avatar_url if current_user.show_bikes) + image: (current_user.avatar_url if current_user.show_bikes), } end - + def bike_ids current_user.bike_ids end def organization_memberships return [] unless current_user.memberships.any? - current_user.memberships.map{ |membership| + current_user.memberships.map { |membership| { organization_name: membership.organization.name, - organization_slug: membership.organization.slug, + organization_slug: membership.organization.slug, organization_access_token: membership.organization.access_token, - user_is_organization_admin: (true ? membership.role == 'admin' : false) + user_is_organization_admin: (true ? membership.role == "admin" : false), } } end @@ -34,7 +34,7 @@ def organization_memberships desc "Current user's information in access token's scope", { authorizations: { oauth2: [] }, - notes: <<-NOTE + notes: <<-NOTE, Current user is the owner of the `access_token` you use in the request. Depending on your scopes you will get different things back. You will always get the user's `id` For an array of the user's bike ids, you need `read_bikes` access @@ -43,30 +43,29 @@ def organization_memberships NOTE } - get '/current', hidden: true do + get "/current", hidden: true do result = { - id: current_user.id.to_s + id: current_user.id.to_s, } - result[:user] = user_info if current_scopes.include?('read_user') - result[:bike_ids] = bike_ids if current_scopes.include?('read_bikes') - result[:memberships] = organization_memberships if current_scopes.include?('read_organization_membership') + result[:user] = user_info if current_scopes.include?("read_user") + result[:bike_ids] = bike_ids if current_scopes.include?("read_bikes") + result[:memberships] = organization_memberships if current_scopes.include?("read_organization_membership") result end desc "Current user's bikes", { authorizations: { oauth2: [{ scope: :read_bikes }] }, - notes: <<-NOTE + notes: <<-NOTE, This returns the current user's bikes, so long as the access_token has the `read_bikes` scope. This uses the bike list bike objects, which only contains the most important information. To get all possible information about a bike use `/bikes/{id}` NOTE } - get '/current/bikes', hidden: true, each_serializer: BikeV2Serializer, root: 'bikes' do + get "/current/bikes", hidden: true, each_serializer: BikeV2Serializer, root: "bikes" do current_user.bikes end - end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v3/me.rb b/app/controllers/api/v3/me.rb index c111f00eb3..b85cf7d910 100644 --- a/app/controllers/api/v3/me.rb +++ b/app/controllers/api/v3/me.rb @@ -24,11 +24,11 @@ def user_info secondary_emails: valid_current_user.secondary_emails, twitter: (valid_current_user.twitter if valid_current_user.show_twitter), created_at: valid_current_user.created_at.to_i, - image: (valid_current_user.avatar_url if valid_current_user.show_bikes) - }.merge(unconfirmed_scope? ? { confirmed: valid_current_user.confirmed? } : {}) + image: (valid_current_user.avatar_url if valid_current_user.show_bikes), + }.merge(unconfirmed_scope? ? { confirmed: valid_current_user.confirmed? } : {}), } end - + def bike_ids current_scopes.include?("read_bikes") ? { bike_ids: valid_current_user.bike_ids } : {} end @@ -38,19 +38,19 @@ def serialized_membership(membership) organization_name: membership.organization.name, organization_slug: membership.organization.slug, organization_access_token: membership.organization.access_token, - user_is_organization_admin: membership.role == "admin" + user_is_organization_admin: membership.role == "admin", } end def organization_memberships - return {} unless current_scopes.include?('read_organization_membership') + return {} unless current_scopes.include?("read_organization_membership") { memberships: valid_current_user.memberships.map { |m| serialized_membership(m) } } end end desc "Current user's information in access token's scope*", { authorizations: { oauth2: [] }, - notes: <<-NOTE + notes: <<-NOTE, Current user is the owner of the `access_token` you use in the request. Depending on your scopes you will get different things back. You will always get the user's `id` For an array of the user's bike ids, you need `read_bikes` access @@ -59,22 +59,22 @@ def organization_memberships NOTE } - get '/' do + get "/" do { id: valid_current_user.id.to_s }.merge(user_info) - .merge(bike_ids) - .merge(organization_memberships) + .merge(bike_ids) + .merge(organization_memberships) end desc "Current user's bikes*", { authorizations: { oauth2: [{ scope: :read_bikes }] }, - notes: <<-NOTE + notes: <<-NOTE, This returns the current user's bikes, so long as the access_token has the `read_bikes` scope. This uses the bike list bike objects, which only contains the most important information. To get all possible information about a bike use `/bikes/{id}` NOTE } - get '/bikes', each_serializer: BikeV2Serializer, root: 'bikes' do + get "/bikes", each_serializer: BikeV2Serializer, root: "bikes" do valid_current_user.bikes end end diff --git a/app/controllers/api/v3/organizations.rb b/app/controllers/api/v3/organizations.rb index c443e3f969..ee02763435 100644 --- a/app/controllers/api/v3/organizations.rb +++ b/app/controllers/api/v3/organizations.rb @@ -2,18 +2,18 @@ module API module V3 class Organizations < API::Base include API::V2::Defaults - + resource :organizations do helpers do def allowed_write_organizations application_uid = current_token&.application&.uid - ENV['ALLOWED_WRITE_ORGANIZATIONS'].split(',').any?(application_uid) + ENV["ALLOWED_WRITE_ORGANIZATIONS"].split(",").any?(application_uid) end end desc "Add an Organization to Bike Index*", { authorizations: { oauth2: [{ scope: :write_organizations }] }, - notes: <<-NOTES + notes: <<-NOTES, **Requires** `write_organizations` **in the access token** you use to create the organization.
    **Location:** You may optionally include `locations` for the organization. @@ -35,11 +35,11 @@ def allowed_write_organizations requires :country, type: String, desc: "The location's country", values: Country.valid_names optional :zipcode, type: String, desc: "The location's zipcode" optional :phone, type: String, desc: "The location's phone number" - end + end end # POST /api/v3/organizations - post serializer: OrganizationSerializer, root: 'organization' do + post serializer: OrganizationSerializer, root: "organization" do error!("Unauthorized. Cannot write organiztions", 401) if !allowed_write_organizations permitted = declared(params, include_missing: false) @@ -62,4 +62,4 @@ def allowed_write_organizations end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v3/root_v3.rb b/app/controllers/api/v3/root_v3.rb index 07ed5e3360..945f7b9ea2 100644 --- a/app/controllers/api/v3/root_v3.rb +++ b/app/controllers/api/v3/root_v3.rb @@ -28,7 +28,7 @@ class RootV3 < API::Base description: "This is the API for Bike Index. It's authenticated with OAuth2 and is generally pretty awesome", contact: "support@bikeindex.org", license_url: "https://github.com/bikeindex/bike_index/blob/master/LICENSE", - terms_of_service_url: "https://bikeindex.org/terms" + terms_of_service_url: "https://bikeindex.org/terms", } route :any, "*path" do raise StandardError, "Unable to find endpoint" diff --git a/app/controllers/api/v3/search.rb b/app/controllers/api/v3/search.rb index 0ce1efe69d..596d07be97 100644 --- a/app/controllers/api/v3/search.rb +++ b/app/controllers/api/v3/search.rb @@ -3,16 +3,16 @@ module V3 class Search < API::Base helpers do params :non_serial_search_params do - optional :query, type: String, desc: 'Full text search' + optional :query, type: String, desc: "Full text search" optional :manufacturer, type: String optional :colors, type: Array - optional :location, type: String, desc: 'Location for proximity search', default: 'IP' - optional :distance, type: String, desc: 'Distance in miles from `location` for proximity search', default: 10 - optional :stolenness, type: String, values: %w(non stolen proximity all) + [''], default: 'stolen' - optional :query_items, type: Array, desc: 'Our Fancy select query items, DO NOT USE, may change without notice', documentation: { hidden: true } + optional :location, type: String, desc: "Location for proximity search", default: "IP" + optional :distance, type: String, desc: "Distance in miles from `location` for proximity search", default: 10 + optional :stolenness, type: String, values: %w(non stolen proximity all) + [""], default: "stolen" + optional :query_items, type: Array, desc: "Our Fancy select query items, DO NOT USE, may change without notice", documentation: { hidden: true } end params :search do - optional :serial, type: String, desc: 'Serial, homoglyph matched' + optional :serial, type: String, desc: "Serial, homoglyph matched" use :non_serial_search_params end @@ -22,16 +22,16 @@ def interpreted_params def serialized_bikes_results(paginated_bikes) ActiveModel::ArraySerializer.new(paginated_bikes, - each_serializer: BikeV2Serializer, root: 'bikes') + each_serializer: BikeV2Serializer, root: "bikes") end def forwarded_ip_address - request.env['HTTP_X_FORWARDED_FOR'].split(',')[0] if request.env['HTTP_X_FORWARDED_FOR'] + request.env["HTTP_X_FORWARDED_FOR"].split(",")[0] if request.env["HTTP_X_FORWARDED_FOR"] end end - resource :search, desc: 'Searching for bikes' do - desc 'Search for bikes', { - notes: <<-NOTE + resource :search, desc: "Searching for bikes" do + desc "Search for bikes", { + notes: <<-NOTE, `stolenness` is the sort of bikes to match. "**all**": every bike, "**non**": only not-stolen, "**stolen**": all stolen, "**proximity**": only stolen within `distance` of included `location`. `location` is ignored unless `stolenness` is "**proximity**" @@ -44,14 +44,14 @@ def forwarded_ip_address paginate params do use :search - optional :per_page, type: Integer, default: 25, desc: 'Bikes per page (max 100)' + optional :per_page, type: Integer, default: 25, desc: "Bikes per page (max 100)" end - get '/' do + get "/" do serialized_bikes_results(paginate Bike.search(interpreted_params)) end - desc 'Count of bikes matching search', { - notes: <<-NOTE + desc "Count of bikes matching search", { + notes: <<-NOTE, Include all the options passed in your search. This endpoint accepts the same parameters as the root `/search` endpoint. Responds with a hash of the total number of bikes matching your search for each type. @@ -72,17 +72,17 @@ def forwarded_ip_address params do use :search end - get '/count' do - count_interpreted_params = Bike.searchable_interpreted_params(params.merge(stolenness: 'proximity'), ip: forwarded_ip_address) + get "/count" do + count_interpreted_params = Bike.searchable_interpreted_params(params.merge(stolenness: "proximity"), ip: forwarded_ip_address) { proximity: Bike.search(count_interpreted_params).count, - stolen: Bike.search(count_interpreted_params.merge(stolenness: 'stolen')).count, - non: Bike.search(count_interpreted_params.merge(stolenness: 'non')).count + stolen: Bike.search(count_interpreted_params.merge(stolenness: "stolen")).count, + non: Bike.search(count_interpreted_params.merge(stolenness: "non")).count, } end - desc 'Search close serials', { - notes: <<-NOTE + desc "Search close serials", { + notes: <<-NOTE, This endpoint accepts the same parameters as the root `/search` endpoint. It returns matches that are off of the submitted `serial` by less than 3 characters (postgres levenshtein, if you're curious). @@ -90,11 +90,11 @@ def forwarded_ip_address } paginate params do - requires :serial, type: String, desc: 'Serial, homoglyph matched' + requires :serial, type: String, desc: "Serial, homoglyph matched" use :non_serial_search_params - optional :per_page, type: Integer, default: 25, desc: 'Bikes per page (max 100)' + optional :per_page, type: Integer, default: 25, desc: "Bikes per page (max 100)" end - get '/close_serials' do + get "/close_serials" do serialized_bikes_results(paginate Bike.search_close_serials(interpreted_params)) end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e03836d39e..ab83bf809b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,20 +3,20 @@ class ApplicationController < ActionController::Base protect_from_forgery ensure_security_headers(csp: false, - hsts: "max-age=#{20.years.to_i}", - x_frame_options: 'SAMEORIGIN', - x_content_type_options: 'nosniff', - x_xss_protection: false, - x_download_options: false, - x_permitted_cross_domain_policies: false) + hsts: "max-age=#{20.years.to_i}", + x_frame_options: "SAMEORIGIN", + x_content_type_options: "nosniff", + x_xss_protection: false, + x_download_options: false, + x_permitted_cross_domain_policies: false) def forwarded_ip_address - @forwarded_ip_address ||= request.env['HTTP_X_FORWARDED_FOR'].split(',')[0] if request.env['HTTP_X_FORWARDED_FOR'] + @forwarded_ip_address ||= request.env["HTTP_X_FORWARDED_FOR"].split(",")[0] if request.env["HTTP_X_FORWARDED_FOR"] end def append_info_to_payload(payload) super - payload[:ip] = request.headers['CF-Connecting-IP'] + payload[:ip] = request.headers["CF-Connecting-IP"] end def handle_unverified_request @@ -25,11 +25,11 @@ def handle_unverified_request end def cors_set_access_control_headers - headers['Access-Control-Allow-Origin'] = '*' - headers['Access-Control-Allow-Methods'] = 'POST, PUT, GET, OPTIONS' - headers['Access-Control-Request-Method'] = '*' - headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization' - headers['Access-Control-Max-Age'] = "1728000" + headers["Access-Control-Allow-Origin"] = "*" + headers["Access-Control-Allow-Methods"] = "POST, PUT, GET, OPTIONS" + headers["Access-Control-Request-Method"] = "*" + headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept, Authorization" + headers["Access-Control-Max-Age"] = "1728000" end # If this is a preflight OPTIONS request, then short-circuit the @@ -37,11 +37,11 @@ def cors_set_access_control_headers # text/plain. def cors_preflight_check if request.method == :options - headers['Access-Control-Allow-Origin'] = '*' - headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS' - headers['Access-Control-Allow-Headers'] = '*' - headers['Access-Control-Max-Age'] = '1728000' - render text: '', content_type: 'text/plain' + headers["Access-Control-Allow-Origin"] = "*" + headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS" + headers["Access-Control-Allow-Headers"] = "*" + headers["Access-Control-Max-Age"] = "1728000" + render text: "", content_type: "text/plain" end end @@ -52,7 +52,7 @@ def force_html_response private def permitted_org_bike_search_params - @stolenness ||= params['stolenness'].present? ? params['stolenness'] : 'all' + @stolenness ||= params["stolenness"].present? ? params["stolenness"] : "all" params.permit(*Bike.permitted_search_params).merge(stolenness: @stolenness) end end diff --git a/app/controllers/bike_codes_controller.rb b/app/controllers/bike_codes_controller.rb index 52b8fcf906..144b990458 100644 --- a/app/controllers/bike_codes_controller.rb +++ b/app/controllers/bike_codes_controller.rb @@ -10,7 +10,7 @@ def update if @bike_code.errors.any? flash[:error] = @bike_code.errors.full_messages.to_sentence else - flash[:success] = "#{@bike_code.kind.titleize} #{@bike_code.code} - #{@bike_code.claimed? ? 'claimed' : 'unclaimed'}" + flash[:success] = "#{@bike_code.kind.titleize} #{@bike_code.code} - #{@bike_code.claimed? ? "claimed" : "unclaimed"}" if @bike_code.bike.present? redirect_to bike_path(@bike_code.bike_id) and return end diff --git a/app/controllers/bikes/recovery_controller.rb b/app/controllers/bikes/recovery_controller.rb index 0832531587..a792698574 100644 --- a/app/controllers/bikes/recovery_controller.rb +++ b/app/controllers/bikes/recovery_controller.rb @@ -2,7 +2,7 @@ module Bikes class RecoveryController < ApplicationController before_filter :find_bike before_filter :ensure_token_match! - layout 'application_revised' + layout "application_revised" def edit # redirect to bike show and set session - so the token isn't available to on page js @@ -14,7 +14,7 @@ def edit def update if @stolen_record.add_recovery_information(permitted_params) EmailRecoveredFromLinkWorker.perform_async(@stolen_record.id) - flash[:success] = 'Bike marked recovered! Thank you!' + flash[:success] = "Bike marked recovered! Thank you!" redirect_to bike_path(@bike) else render :edit, bike_id: @bike.id, token: params[:token] @@ -39,9 +39,9 @@ def ensure_token_match! recovery_link_token: params[:token]) if @stolen_record.present? return true if @bike.stolen - flash[:info] = 'Bike has already been marked recovered!' + flash[:info] = "Bike has already been marked recovered!" else - flash[:error] = 'Incorrect Token, check your email again' + flash[:error] = "Incorrect Token, check your email again" end redirect_to bike_path(@bike) and return end diff --git a/app/controllers/bikes_controller.rb b/app/controllers/bikes_controller.rb index 4a9313c9a0..06cde6b42b 100644 --- a/app/controllers/bikes_controller.rb +++ b/app/controllers/bikes_controller.rb @@ -10,11 +10,11 @@ class BikesController < ApplicationController before_filter :render_ad, only: [:index, :show] before_filter :store_return_to, only: [:edit] before_filter :remove_subdomain, only: [:index] - layout 'application_revised' + layout "application_revised" def index @interpreted_params = Bike.searchable_interpreted_params(permitted_search_params, ip: forwarded_ip_address) - if params[:stolenness] == 'proximity' && @interpreted_params[:stolenness] != 'proximity' + if params[:stolenness] == "proximity" && @interpreted_params[:stolenness] != "proximity" flash[:info] = "Sorry, we don't know the location \"#{params[:location]}\". Please try a different location to search nearby stolen bikes" end @bikes = Bike.search(@interpreted_params).page(params[:page] || 1).per(params[:per_page] || 10).decorate @@ -34,7 +34,7 @@ def show @bike = @bike.decorate respond_to do |format| format.html { render :show } - format.gif { render qrcode: bike_url(@bike), level: :h, unit: 50 } + format.gif { render qrcode: bike_url(@bike), level: :h, unit: 50 } end end @@ -45,9 +45,9 @@ def pdf @bike = @bike.decorate filename = "Registration_" + @bike.updated_at.strftime("%m%d_%H%M")[0..-1] unless @bike.pdf.present? && @bike.pdf.file.filename == "#{filename}.pdf" - pdf = render_to_string pdf: filename, template: 'bikes/pdf' + pdf = render_to_string pdf: filename, template: "bikes/pdf" save_path = "#{Rails.root}/tmp/#{filename}.pdf" - File.open(save_path, 'wb') do |file| + File.open(save_path, "wb") do |file| file << pdf end # @bike.pdf = File.open(pdf, 'wb') { |file| file << pdf } @@ -84,7 +84,7 @@ def spokecard def new unless current_user.present? store_return_to(new_bike_path(b_param_token: params[:b_param_token], stolen: params[:stolen])) - flash[:info] = 'You have to sign in to register a bike' + flash[:info] = "You have to sign in to register a bike" redirect_to new_user_path and return end find_or_new_b_param @@ -96,7 +96,7 @@ def new @bike.creation_organization ||= active_organization || current_organization @organization = @bike.creation_organization if @bike.stolen - @stolen_record = @bike.stolen_records.build(@b_param.params['stolen_record']) + @stolen_record = @bike.stolen_records.build(@b_param.params["stolen_record"]) @stolen_record.country_id ||= Country.united_states.id end @page_errors = @b_param.bike_errors @@ -115,7 +115,7 @@ def create params[:bike].delete(:image) end @b_param.update_attributes(params: permitted_bparams, - origin: (params[:bike][:embeded_extended] ? 'embed_extended' : 'embed')) + origin: (params[:bike][:embeded_extended] ? "embed_extended" : "embed")) @bike = BikeCreator.new(@b_param).create_bike if @bike.errors.any? @b_param.update_attributes(bike_errors: @bike.cleaned_error_messages) @@ -144,7 +144,7 @@ def create @b_param.update_attributes(bike_errors: @bike.cleaned_error_messages) redirect_to new_bike_url(b_param_token: @b_param.id_token) else - flash[:success] = 'Bike successfully added to the index!' + flash[:success] = "Bike successfully added to the index!" redirect_to edit_bike_url(@bike) end end @@ -153,13 +153,12 @@ def create def edit @page_errors = @bike.errors @edit_template = edit_templates[params[:page]].present? ? params[:page] : edit_templates.keys.first - if @edit_template == 'photos' - @private_images = PublicImage.unscoped.where(imageable_type: 'Bike').where(imageable_id: @bike.id).where(is_private: true) + if @edit_template == "photos" + @private_images = PublicImage.unscoped.where(imageable_type: "Bike").where(imageable_id: @bike.id).where(is_private: true) end render "edit_#{@edit_template}".to_sym end - def update begin @bike = BikeUpdator.new(user: current_user, bike: @bike, b_params: permitted_bike_params.as_json, current_ownership: @current_ownership).update_available_attributes @@ -170,22 +169,22 @@ def update if @bike.errors.any? || flash[:error].present? edit and return else - flash[:success] = 'Bike successfully updated!' + flash[:success] = "Bike successfully updated!" return if return_to_if_present redirect_to edit_bike_url(@bike, page: params[:edit_template]) and return end end def edit_templates_hash - stolen_type = @bike.recovered ? 'Recovery' : 'Theft' + stolen_type = @bike.recovered ? "Recovery" : "Theft" hash = { - root: 'Bike Details', - photos: 'Photos', - drivetrain: 'Wheels + Drivetrain', - accessories: 'Accessories + Components', - ownership: 'Groups + Ownership', - remove: 'Hide or Delete', - stolen: (@bike.stolen ? "#{stolen_type} details" : 'Report Stolen or Missing') + root: "Bike Details", + photos: "Photos", + drivetrain: "Wheels + Drivetrain", + accessories: "Accessories + Components", + ownership: "Groups + Ownership", + remove: "Hide or Delete", + stolen: (@bike.stolen ? "#{stolen_type} details" : "Report Stolen or Missing"), } # To make stolen the first key if bike is stolen. using as_json for string keys instead of sym (@bike.stolen ? hash.to_a.rotate(-1).to_h : hash).as_json @@ -209,7 +208,7 @@ def find_bike end if @bike.hidden unless current_user.present? && @bike.visible_by(current_user) - flash[:error] = 'Bike deleted' + flash[:error] = "Bike deleted" redirect_to root_url and return end end @@ -223,7 +222,7 @@ def find_or_new_b_param def ensure_user_allowed_to_edit @current_ownership = @bike.current_ownership - type = @bike && @bike.type || 'bike' + type = @bike && @bike.type || "bike" return true if @bike.authorize_for_user!(current_user) if current_user.present? error = "Oh no! It looks like you don't own that #{type}." @@ -238,7 +237,7 @@ def ensure_user_allowed_to_edit flash[:error] = error redirect_to bike_path(@bike) and return end - authenticate_user('Please create an account', flash_type: :info) + authenticate_user("Please create an account", flash_type: :info) end def render_ad diff --git a/app/controllers/blogs_controller.rb b/app/controllers/blogs_controller.rb index 432615f9fe..66a899767b 100644 --- a/app/controllers/blogs_controller.rb +++ b/app/controllers/blogs_controller.rb @@ -1,9 +1,8 @@ class BlogsController < ApplicationController - def index redirect_to news_index_url end - + def show redirect_to news_url end diff --git a/app/controllers/concerns/controller_helpers.rb b/app/controllers/concerns/controller_helpers.rb index 8ccfd61336..ee3ced55ab 100644 --- a/app/controllers/concerns/controller_helpers.rb +++ b/app/controllers/concerns/controller_helpers.rb @@ -63,12 +63,12 @@ def return_to_if_present session[:return_to] = nil cookies[:return_to] = nil case target.downcase - when 'password_reset' + when "password_reset" flash[:success] = "You've been logged in. Please reset your password" render action: :update_password and return true - when /\A#{ENV['BASE_URL']}/, %r{\A/} # Either starting with our URL or / + when /\A#{ENV["BASE_URL"]}/, %r{\A/} # Either starting with our URL or / redirect_to(target) and return true - when 'https://facebook.com/bikeindex' + when "https://facebook.com/bikeindex" redirect_to(target) and return true end elsif session[:discourse_redirect] @@ -81,7 +81,7 @@ def controller_namespace end def page_id - @page_id ||= [controller_namespace, controller_name, action_name].compact.join('_') + @page_id ||= [controller_namespace, controller_name, action_name].compact.join("_") end def recovered_bike_count @@ -120,7 +120,7 @@ def current_organization end # active_organization is the organization currently being used. - # If set, the user *is* interacting with the organization in said request + # If set, the user *is* interacting with the organization in said request def active_organization # We call this multiple times - make sure nil stays nil return @active_organization if defined?(@active_organization) diff --git a/app/controllers/concerns/sessionable.rb b/app/controllers/concerns/sessionable.rb index 488ba5df24..79096d2a29 100644 --- a/app/controllers/concerns/sessionable.rb +++ b/app/controllers/concerns/sessionable.rb @@ -1,5 +1,6 @@ module Sessionable extend ActiveSupport::Concern + def skip_if_signed_in store_return_to # Make absolutely sure we don't have an unconfirmed user @@ -42,7 +43,7 @@ def default_session_set(user) def cookie_options(user) c = { httponly: true, - value: [user.id, user.auth_token] + value: [user.id, user.auth_token], } # In development, secure: true breaks the cookie storage. Only add if production Rails.env.production? ? c.merge(secure: true) : c diff --git a/app/controllers/discourse_authentication_controller.rb b/app/controllers/discourse_authentication_controller.rb index e767a97c42..12e440fe16 100644 --- a/app/controllers/discourse_authentication_controller.rb +++ b/app/controllers/discourse_authentication_controller.rb @@ -13,11 +13,11 @@ def index private def discourse_secret - ENV['DISCOURSE_SECRET'] + ENV["DISCOURSE_SECRET"] end def discourse_redirect_url - "#{ENV['DISCOURSE_URL']}/session/sso_login" + "#{ENV["DISCOURSE_URL"]}/session/sso_login" end def authenticate_and_set_redirect diff --git a/app/controllers/documentation_controller.rb b/app/controllers/documentation_controller.rb index 3f8b2a2bbd..caabf13020 100644 --- a/app/controllers/documentation_controller.rb +++ b/app/controllers/documentation_controller.rb @@ -1,15 +1,16 @@ class DocumentationController < ApplicationController before_filter :render_swagger_for_page, only: [:api_v3, :api_v2] + def index redirect_to controller: :documentation, action: :api_v3 end def api_v1 unless current_user&.developer? - flash[:notice] = 'API V1 is deprecated, please use our current API version' + flash[:notice] = "API V1 is deprecated, please use our current API version" redirect_to documentation_index_path and return end - @root = ENV['BASE_URL'] + @root = ENV["BASE_URL"] render layout: false end diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb index c765b11689..7f7ef01d83 100644 --- a/app/controllers/errors_controller.rb +++ b/app/controllers/errors_controller.rb @@ -1,7 +1,7 @@ class ErrorsController < ApplicationController respond_to :html, :json before_filter :set_permitted_format - layout 'application_revised' + layout "application_revised" def bad_request render status: 400 @@ -26,6 +26,6 @@ def unauthorized private def set_permitted_format - request.format = 'html' unless request.format == 'json' + request.format = "html" unless request.format == "json" end end diff --git a/app/controllers/feedbacks_controller.rb b/app/controllers/feedbacks_controller.rb index 51d7cbeda0..ce8d69723a 100644 --- a/app/controllers/feedbacks_controller.rb +++ b/app/controllers/feedbacks_controller.rb @@ -1,5 +1,5 @@ class FeedbacksController < ApplicationController - layout 'application_revised' + layout "application_revised" before_filter :set_feedback_active_section before_filter :block_the_spam!, only: [:create] before_filter :set_permitted_format @@ -13,8 +13,8 @@ def create @feedback = Feedback.new(permitted_parameters) @feedback.user_id = current_user.id if current_user.present? if @feedback.save - flash[:success] = 'Thanks for your message!' - if request.env['HTTP_REFERER'].present? and request.env['HTTP_REFERER'] != request.env['REQUEST_URI'] + flash[:success] = "Thanks for your message!" + if request.env["HTTP_REFERER"].present? and request.env["HTTP_REFERER"] != request.env["REQUEST_URI"] redirect_to :back else redirect_to help_path @@ -30,7 +30,7 @@ def create end def set_feedback_active_section - @active_section = 'contact' + @active_section = "contact" end protected @@ -39,16 +39,15 @@ def block_the_spam! # Previously, we were authenticating users in a before_filter # But to make it possible for non-signed in users to generate leads, we're trying this out return false unless params[:feedback] && params[:feedback][:additional].present? - flash[:error] = 'Please sign in to send that message' - redirect_to feedbacks_path(anchor: 'contact_us_section') and return + flash[:error] = "Please sign in to send that message" + redirect_to feedbacks_path(anchor: "contact_us_section") and return end - def permitted_parameters params.require(:feedback).permit(%w(body email name title feedback_type feedback_hash).map(&:to_sym).freeze) end def set_permitted_format - request.format = 'html' + request.format = "html" end end diff --git a/app/controllers/info_controller.rb b/app/controllers/info_controller.rb index d18629c0fa..e41c186671 100644 --- a/app/controllers/info_controller.rb +++ b/app/controllers/info_controller.rb @@ -1,5 +1,5 @@ class InfoController < ApplicationController - layout 'application_revised' + layout "application_revised" def about end @@ -35,8 +35,8 @@ def image_resources end def support_bike_index - @page_title = 'Support Bike Index' - render layout: 'payments_layout' + @page_title = "Support Bike Index" + render layout: "payments_layout" end def support_the_index @@ -51,6 +51,6 @@ def dev_and_design end def how_not_to_buy_stolen - redirect_to 'https://files.bikeindex.org/stored/dont_buy_stolen.pdf' + redirect_to "https://files.bikeindex.org/stored/dont_buy_stolen.pdf" end end diff --git a/app/controllers/integrations_controller.rb b/app/controllers/integrations_controller.rb index 34b93744ee..7996ec99ed 100644 --- a/app/controllers/integrations_controller.rb +++ b/app/controllers/integrations_controller.rb @@ -3,9 +3,9 @@ class IntegrationsController < ApplicationController before_filter :skip_if_signed_in def create - @integration = Integration.new(information: request.env['omniauth.auth'], - access_token: request.env['omniauth.auth']['credentials']['token'], - provider_name: request.env['omniauth.auth']['provider']) + @integration = Integration.new(information: request.env["omniauth.auth"], + access_token: request.env["omniauth.auth"]["credentials"]["token"], + provider_name: request.env["omniauth.auth"]["provider"]) @integration.save if @integration.valid? && @integration.user.present? @user = @integration.user @@ -16,7 +16,7 @@ def create end def integrations_controller_creation_error - provider_name = request.env['omniauth.auth'] && request.env['omniauth.auth']['provider'] + provider_name = request.env["omniauth.auth"] && request.env["omniauth.auth"]["provider"] provider_name ||= params[:strategy] msg = "There was a problem authenticating you with #{provider_name}. Please sign in a different way or email us at contact@bikeindex.org" flash[:error] = msg diff --git a/app/controllers/landing_pages_controller.rb b/app/controllers/landing_pages_controller.rb index 8659a8f0ec..3098db4f7c 100644 --- a/app/controllers/landing_pages_controller.rb +++ b/app/controllers/landing_pages_controller.rb @@ -1,10 +1,10 @@ class LandingPagesController < ApplicationController - layout 'application_revised' + layout "application_revised" before_action :force_html_response before_filter :instantiate_feedback, except: [:show] def show - raise ActionController::RoutingError, 'Not found' unless active_organization.present? + raise ActionController::RoutingError, "Not found" unless active_organization.present? end def for_shops; end @@ -17,9 +17,9 @@ def for_schools; end def ascend; @page_title ||= "Ascend POS on Bike Index" end - def ambassadors_current; @page_title ||= 'Current Ambassadors' end + def ambassadors_current; @page_title ||= "Current Ambassadors" end - def ambassadors_how_to; @page_title ||= 'Ambassadors' end + def ambassadors_how_to; @page_title ||= "Ambassadors" end protected diff --git a/app/controllers/locks_controller.rb b/app/controllers/locks_controller.rb index 160ef145f2..66676ead7d 100644 --- a/app/controllers/locks_controller.rb +++ b/app/controllers/locks_controller.rb @@ -1,5 +1,5 @@ class LocksController < ApplicationController - layout 'application_revised' + layout "application_revised" before_filter :authenticate_user before_filter :find_lock, only: [:edit, :update, :destroy] @@ -22,8 +22,8 @@ def new def create @lock = current_user.locks.build(permitted_parameters) if @lock.save - flash[:success] = 'Lock created successfully!' - redirect_to user_home_path(active_tab: 'locks') + flash[:success] = "Lock created successfully!" + redirect_to user_home_path(active_tab: "locks") else @page_errors = @lock.errors render action: :new @@ -32,7 +32,7 @@ def create def destroy @lock.destroy - redirect_to user_home_path(active_tab: 'locks') + redirect_to user_home_path(active_tab: "locks") end private diff --git a/app/controllers/manufacturers_controller.rb b/app/controllers/manufacturers_controller.rb index f24c71ee41..e7d30f1b7e 100644 --- a/app/controllers/manufacturers_controller.rb +++ b/app/controllers/manufacturers_controller.rb @@ -1,5 +1,5 @@ class ManufacturersController < ApplicationController - layout 'application_revised' + layout "application_revised" def index @manufacturers = Manufacturer.all @@ -10,6 +10,6 @@ def index end def tsv - redirect_to 'https://files.bikeindex.org/uploads/tsvs/manufacturers.tsv' + redirect_to "https://files.bikeindex.org/uploads/tsvs/manufacturers.tsv" end end diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index c4c934bc73..635f45a660 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -1,15 +1,15 @@ class NewsController < ApplicationController - layout 'application_revised' + layout "application_revised" def show @blog = Blog.friendly_find(params[:id]) unless @blog - raise ActionController::RoutingError.new('Not Found') + raise ActionController::RoutingError.new("Not Found") end if @blog.is_listicle - @page = params[:page].to_i + @page = params[:page].to_i @page = 1 unless @page > 0 - @list_item = @blog.listicles[@page-1] + @list_item = @blog.listicles[@page - 1] @next_item = true unless @page >= @blog.listicles.count @prev_item = true unless @page == 1 end @@ -18,6 +18,6 @@ def show def index @blogs = Blog.published - redirect_to news_index_url(format: 'atom') if request.format == 'xml' + redirect_to news_index_url(format: "atom") if request.format == "xml" end end diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb index 216130a621..feccc551fd 100644 --- a/app/controllers/oauth/applications_controller.rb +++ b/app/controllers/oauth/applications_controller.rb @@ -14,9 +14,9 @@ def create @application.owner = current_user if @application.save flash[:notice] = I18n.t(:notice, :scope => [:doorkeeper, :flash, :applications, :create]) - # respond_with( :oauth, @application, location: oauth_application_url(@application) ) - Doorkeeper::AccessToken.create!(application_id: @application.id, resource_owner_id: ENV['V2_ACCESSOR_ID'], expires_in: nil, scopes: 'write_bikes') - redirect_to oauth_application_url(@application) + # respond_with( :oauth, @application, location: oauth_application_url(@application) ) + Doorkeeper::AccessToken.create!(application_id: @application.id, resource_owner_id: ENV["V2_ACCESSOR_ID"], expires_in: nil, scopes: "write_bikes") + redirect_to oauth_application_url(@application) else render :new end @@ -30,4 +30,4 @@ def ensure_app_owner! redirect_to oauth_applications_url and return end end -end \ No newline at end of file +end diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index c39d8053da..21f840a299 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -1,7 +1,7 @@ class OrganizationsController < ApplicationController before_filter :set_bparam, only: [:embed, :embed_extended] skip_before_filter :set_x_frame_options_header, only: [:embed, :embed_extended, :embed_create_success] - layout 'application_revised' + layout "application_revised" def new session[:return_to] ||= new_organization_url unless current_user.present? @@ -11,7 +11,7 @@ def new def connect_lightspeed if current_user && current_user.organizations.any? - redirect_to 'https://posintegration.bikeindex.org' and return + redirect_to "https://posintegration.bikeindex.org" and return end session[:return_to] = connect_lightspeed_path @@ -27,9 +27,9 @@ def connect_lightspeed def create @organization = Organization.new(permitted_create_params) if @organization.save - membership = Membership.create(user_id: current_user.id, role: 'admin', organization_id: @organization.id) - notify_admins('organization_created') - flash[:success] = 'Organization Created successfully!' + membership = Membership.create(user_id: current_user.id, role: "admin", organization_id: @organization.id) + notify_admins("organization_created") + flash[:success] = "Organization Created successfully!" if current_user.present? redirect_to organization_manage_index_path(organization_id: @organization.to_param) end @@ -37,7 +37,7 @@ def create render action: :new and return end end - + def embed @bike = BikeCreator.new(@b_param).new_bike @bike.owner_email = params[:email] if params[:email].present? @@ -62,7 +62,7 @@ def embed_extended def embed_create_success find_organization @bike = Bike.find(params[:bike_id]).decorate - render layout: 'embed_layout' + render layout: "embed_layout" end protected @@ -79,15 +79,15 @@ def set_bparam hash = { creation_organization_id: @organization.id, embeded: true, - bike: { stolen: params[:stolen] } + bike: { stolen: params[:stolen] }, } @b_param = BParam.create(creator_id: @organization.auto_user.id, params: hash) end end def built_stolen_record - if @b_param.params && @b_param.params['stolen_record'].present? - stolen_attrs = @b_param.params['stolen_record'].except('phone_no_show') + if @b_param.params && @b_param.params["stolen_record"].present? + stolen_attrs = @b_param.params["stolen_record"].except("phone_no_show") else stolen_attrs = { country_id: Country.united_states.id, date_stolen: Time.zone.now } end @@ -95,8 +95,8 @@ def built_stolen_record end def built_stolen_record_date(str) - DateTime.strptime("#{str} 06", '%m-%d-%Y %H') if str.present? - rescue ArgumentError + DateTime.strptime("#{str} 06", "%m-%d-%Y %H") if str.present? + rescue ArgumentError Time.zone.now end diff --git a/app/controllers/organized/admin_controller.rb b/app/controllers/organized/admin_controller.rb index 9ac280c3b0..3be01364f4 100644 --- a/app/controllers/organized/admin_controller.rb +++ b/app/controllers/organized/admin_controller.rb @@ -3,4 +3,4 @@ class AdminController < Organized::BaseController before_filter :ensure_admin! skip_before_filter :ensure_member! end -end \ No newline at end of file +end diff --git a/app/controllers/organized/base_controller.rb b/app/controllers/organized/base_controller.rb index fefa1a89f0..fd651ee03f 100644 --- a/app/controllers/organized/base_controller.rb +++ b/app/controllers/organized/base_controller.rb @@ -2,7 +2,7 @@ module Organized class BaseController < ApplicationController before_filter :ensure_active_organization! before_filter :ensure_member! - layout 'application_revised' + layout "application_revised" def ensure_member! return true if current_user && current_user.member_of?(active_organization) @@ -13,7 +13,7 @@ def ensure_member! def ensure_admin! return true if current_user && current_user.admin_of?(active_organization) - flash[:error] = 'You have to be an organization administrator to do that!' + flash[:error] = "You have to be an organization administrator to do that!" redirect_to organization_bikes_path(organization_id: active_organization.to_param) and return end diff --git a/app/controllers/organized/manage_controller.rb b/app/controllers/organized/manage_controller.rb index fdb6ac0c35..9f4459e347 100644 --- a/app/controllers/organized/manage_controller.rb +++ b/app/controllers/organized/manage_controller.rb @@ -1,6 +1,7 @@ module Organized class ManageController < Organized::AdminController before_filter :assign_organization, only: [:index, :update, :locations] + def index @organization.ensure_auto_user end @@ -26,14 +27,14 @@ def destroy flash[:info] = "Please contact support@bikeindex.org to delete #{organization_name}" redirect_to current_index_path and return end - notify_admins('organization_destroyed') + notify_admins("organization_destroyed") active_organization.destroy flash[:info] = "Deleted #{organization_name}" redirect_to user_root_url end def landing - render '/landing_pages/show' + render "/landing_pages/show" end private diff --git a/app/controllers/organized/stickers_controller.rb b/app/controllers/organized/stickers_controller.rb index 08b2a6ed09..c6c9a73f84 100644 --- a/app/controllers/organized/stickers_controller.rb +++ b/app/controllers/organized/stickers_controller.rb @@ -23,7 +23,7 @@ def update if @bike_code.errors.any? flash[:error] = @bike_code.errors.full_messages.to_sentence else - flash[:success] = "#{@bike_code.kind.titleize} #{@bike_code.code} - #{@bike_code.claimed? ? 'claimed' : 'unclaimed'}" + flash[:success] = "#{@bike_code.kind.titleize} #{@bike_code.code} - #{@bike_code.claimed? ? "claimed" : "unclaimed"}" if @bike_code.bike.present? redirect_to bike_path(@bike_code.bike_id) and return end diff --git a/app/controllers/organized/users_controller.rb b/app/controllers/organized/users_controller.rb index 92f31ea8c4..7296eec77f 100644 --- a/app/controllers/organized/users_controller.rb +++ b/app/controllers/organized/users_controller.rb @@ -5,7 +5,7 @@ class UsersController < Organized::AdminController def index @organization_invitations = active_organization.organization_invitations.unclaimed - @memberships = active_organization.memberships.order('created_at desc') + @memberships = active_organization.memberships.order("created_at desc") end def edit @@ -34,7 +34,7 @@ def destroy else @membership.destroy end - flash[:success] = 'Deleted user from your organization' + flash[:success] = "Deleted user from your organization" new_invites_count = active_organization.available_invitation_count + 1 active_organization.update_attribute :available_invitation_count, new_invites_count redirect_to current_index_path @@ -88,14 +88,14 @@ def create_organization_invitation_params invitee_name: params[:organization_invitation][:invitee_name], organization: active_organization, inviter: current_user, - membership_role: params[:organization_invitation][:membership_role] + membership_role: params[:organization_invitation][:membership_role], } end def update_organization_invitation_params { invitee_name: params[:organization_invitation][:name], - membership_role: params[:organization_invitation][:membership_role] + membership_role: params[:organization_invitation][:membership_role], } end diff --git a/app/controllers/ownerships_controller.rb b/app/controllers/ownerships_controller.rb index e5ea691923..2be4f0eb5a 100644 --- a/app/controllers/ownerships_controller.rb +++ b/app/controllers/ownerships_controller.rb @@ -37,5 +37,4 @@ def no_user_flash_msg def find_ownership @ownership = Ownership.find(params[:id]) end - end diff --git a/app/controllers/payments_controller.rb b/app/controllers/payments_controller.rb index 24609775ed..c21a7e7f57 100644 --- a/app/controllers/payments_controller.rb +++ b/app/controllers/payments_controller.rb @@ -1,5 +1,5 @@ class PaymentsController < ApplicationController - layout 'payments_layout' + layout "payments_layout" def new end @@ -16,7 +16,7 @@ def create elsif user.present? customer = Stripe::Customer.create( email: email, - card: params[:stripe_token] + card: params[:stripe_token], ) user.update_attribute :stripe_id, customer.id else @@ -27,7 +27,7 @@ def create else customer = Stripe::Customer.create( email: email, - card: params[:stripe_token] + card: params[:stripe_token], ) end end @@ -36,10 +36,10 @@ def create charge_time = charge.current_period_start else charge = Stripe::Charge.create( - customer: customer.id, - amount: amount_cents, - description: 'Bike Index customer', - currency: 'usd' + customer: customer.id, + amount: amount_cents, + description: "Bike Index customer", + currency: "usd", ) charge_time = charge.created end @@ -49,7 +49,7 @@ def create is_current: true, stripe_id: charge.id, first_payment_date: Time.at(charge_time).utc.to_datetime, - amount_cents: amount_cents + amount_cents: amount_cents, ) @payment.is_recurring = true if subscription @payment.is_payment = true if params[:is_payment] diff --git a/app/controllers/public_images_controller.rb b/app/controllers/public_images_controller.rb index 479ba51dc8..4e446da0ab 100644 --- a/app/controllers/public_images_controller.rb +++ b/app/controllers/public_images_controller.rb @@ -4,7 +4,7 @@ class PublicImagesController < ApplicationController def show @public_image = PublicImage.find(params[:id]) - if @public_image.present? && @public_image.imageable_type == 'Bike' + if @public_image.present? && @public_image.imageable_type == "Bike" @owner_viewing = true if @public_image.imageable.current_ownership.present? && @public_image.imageable.owner == current_user end end @@ -14,7 +14,7 @@ def create if params[:bike_id].present? @public_image.imageable = @bike @public_image.save - render 'create_revised' and return + render "create_revised" and return else if params[:blog_id].present? @blog = Blog.find(params[:blog_id]) @@ -25,7 +25,7 @@ def create @public_image.imageable = active_organization end @public_image.save - render 'create' and return + render "create" and return end flash[:error] = "Whoops! We can't let you create that image." redirect_to @public_image.present? ? @public_image.imageable : user_root_url @@ -41,7 +41,7 @@ def is_private def update if @public_image.update_attributes(permitted_parameters) - redirect_to edit_bike_url(@public_image.imageable), notice: 'Image was successfully updated.' + redirect_to edit_bike_url(@public_image.imageable), notice: "Image was successfully updated." else render :edit end @@ -52,10 +52,10 @@ def destroy imageable_id = @public_image.imageable_id imageable_type = @public_image.imageable_type @public_image.destroy - flash[:success] = 'Image was successfully deleted' + flash[:success] = "Image was successfully deleted" if params[:page].present? redirect_to edit_bike_url(imageable_id, page: params[:page]) and return - elsif imageable_type == 'Blog' + elsif imageable_type == "Blog" redirect_to edit_admin_news_url(@imageable.title_slug) and return else redirect_to edit_bike_url(imageable_id) @@ -82,13 +82,13 @@ def ensure_authorized_to_create! # Otherwise, it's a blog image or an organization image (or someone messing about), # so ensure the current user is admin authorized return true if current_user && current_user.superuser? - render json: { error: 'Access denied' }, status: 401 and return + render json: { error: "Access denied" }, status: 401 and return end def current_user_image_owner(public_image) - if public_image.imageable_type == 'Bike' + if public_image.imageable_type == "Bike" Bike.unscoped.find(public_image.imageable_id).owner == current_user - elsif public_image.imageable_type == 'Blog' + elsif public_image.imageable_type == "Blog" current_user && current_user.superuser? end end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index fe361bc854..594ead181a 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -1,11 +1,11 @@ class RegistrationsController < ApplicationController skip_before_filter :set_x_frame_options_header, except: [:new] before_filter :simple_header - layout 'reg_embed' + layout "reg_embed" def new @stolen = params[:stolen] # Passed into embed form - render layout: 'application_revised' + render layout: "application_revised" end def embed # Attributes assigned in the partial, but can be overridden so it can be used anywhere @@ -21,7 +21,7 @@ def embed # Attributes assigned in the partial, but can be overridden so it can def create @b_param = BParam.new(permitted_params) - @b_param.errors.add :owner_email, 'required' unless @b_param.owner_email.present? + @b_param.errors.add :owner_email, "required" unless @b_param.owner_email.present? if @b_param.errors.blank? && @b_param.save EmailPartialRegistrationWorker.perform_async(@b_param.id) else @@ -49,6 +49,6 @@ def permitted_params :primary_frame_color_id, :secondary_frame_color_id, :tertiary_frame_color_id) - .merge(origin: 'embed_partial') + .merge(origin: "embed_partial") end end diff --git a/app/controllers/stolen_controller.rb b/app/controllers/stolen_controller.rb index 610eae1660..8a4b2d4cfe 100644 --- a/app/controllers/stolen_controller.rb +++ b/app/controllers/stolen_controller.rb @@ -1,14 +1,14 @@ class StolenController < ApplicationController before_filter :set_permitted_format, only: [:index] before_filter :remove_subdomain - layout 'application_revised' + layout "application_revised" def index @feedback = Feedback.new end def current_tsv - redirect_to 'https://files.bikeindex.org/uploads/tsvs/current_stolen_bikes.tsv' + redirect_to "https://files.bikeindex.org/uploads/tsvs/current_stolen_bikes.tsv" end def show @@ -16,13 +16,13 @@ def show end def multi_serial_search - render layout: 'multi_serial' + render layout: "multi_serial" end private def set_permitted_format - request.format = 'html' + request.format = "html" end def remove_subdomain diff --git a/app/controllers/user_emails_controller.rb b/app/controllers/user_emails_controller.rb index 1ab9e2b457..0b051fbd44 100644 --- a/app/controllers/user_emails_controller.rb +++ b/app/controllers/user_emails_controller.rb @@ -2,7 +2,7 @@ class UserEmailsController < ApplicationController before_filter :ensure_user_email_ownership def resend_confirmation - flash[:success] = 'Email confirmation re-sent' + flash[:success] = "Email confirmation re-sent" @user_email.send_confirmation_email redirect_to my_account_path end diff --git a/app/controllers/user_embeds_controller.rb b/app/controllers/user_embeds_controller.rb index 7519c3efa0..d67f15caa2 100644 --- a/app/controllers/user_embeds_controller.rb +++ b/app/controllers/user_embeds_controller.rb @@ -1,14 +1,14 @@ class UserEmbedsController < ApplicationController skip_before_filter :set_x_frame_options_header - layout 'embed_user_layout' + layout "embed_user_layout" def show @text = params[:text] user = User.find_by_username(params[:id]) bikes = user.bikes if user.present? unless user && user.show_bikes? && bikes.present? - @text = 'Most Recent Indexed Bikes' - bikes = Bike.where('thumb_path IS NOT NULL').limit(5) + @text = "Most Recent Indexed Bikes" + bikes = Bike.where("thumb_path IS NOT NULL").limit(5) end @bikes = BikeDecorator.decorate_collection(bikes) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6feb1f6f33..dcff460baf 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -77,7 +77,7 @@ def password_reset def show user = User.find_by_username(params[:id]) unless user - raise ActionController::RoutingError.new('Not Found') + raise ActionController::RoutingError.new("Not Found") end @owner = user @user = user.decorate @@ -115,28 +115,28 @@ def update if !@user.errors.any? && @user.update_attributes(permitted_update_parameters) AfterUserChangeWorker.perform_async(@user.id) if params[:user][:terms_of_service].present? - if params[:user][:terms_of_service] == '1' + if params[:user][:terms_of_service] == "1" @user.terms_of_service = true @user.save - flash[:success] = 'Thanks! Now you can use Bike Index' + flash[:success] = "Thanks! Now you can use Bike Index" redirect_to user_home_url and return else - flash[:notice] = 'You have to accept the Terms of Service if you would like to use Bike Index' + flash[:notice] = "You have to accept the Terms of Service if you would like to use Bike Index" redirect_to accept_vendor_terms_url and return end elsif params[:user][:vendor_terms_of_service].present? - if params[:user][:vendor_terms_of_service] == '1' + if params[:user][:vendor_terms_of_service] == "1" @user.accept_vendor_terms_of_service if @user.memberships.any? flash[:success] = "Thanks! Now you can use Bike Index as #{@user.memberships.first.organization.name}" else - flash[:success] = 'Thanks for accepting the terms of service!' + flash[:success] = "Thanks for accepting the terms of service!" end redirect_to user_home_url and return # TODO: Redirect to the correct page, somehow this breaks things right now though. # redirect_to organization_home and return else - redirect_to accept_vendor_terms_url, notice: 'You have to accept the Terms of Service if you would like to use Bike Index as through the organization' and return + redirect_to accept_vendor_terms_url, notice: "You have to accept the Terms of Service if you would like to use Bike Index as through the organization" and return end end if params[:user][:password].present? @@ -145,7 +145,7 @@ def update @user.reload default_session_set(@user) end - flash[:success] = 'Your information was successfully updated.' + flash[:success] = "Your information was successfully updated." redirect_to my_account_url(page: params[:page]) and return end @page_errors = @user.errors.full_messages @@ -171,7 +171,7 @@ def accept_vendor_terms def unsubscribe user = User.find_by_username(params[:id]) user.update_attribute :notification_newsletters, false if user.present? - flash[:success] = 'You have been unsubscribed from Bike Index updates' + flash[:success] = "You have been unsubscribed from Bike Index updates" redirect_to user_root_url and return end @@ -188,17 +188,17 @@ def permitted_parameters def permitted_update_parameters pparams = permitted_parameters.except(:email, :password_reset_token) - if pparams.keys.include?('username') - pparams.delete('username') unless pparams['username'].present? + if pparams.keys.include?("username") + pparams.delete("username") unless pparams["username"].present? end pparams end def edit_templates @edit_templates ||= { - root: 'User Settings', - password: 'Password', - sharing: 'Sharing + Personal Page' + root: "User Settings", + password: "Password", + sharing: "Sharing + Personal Page", }.as_json end diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index bb5453234d..264604a546 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -1,5 +1,5 @@ class WelcomeController < ApplicationController - layout 'application_revised' + layout "application_revised" before_action :force_html_response before_filter :authenticate_user_for_welcome_controller, only: [:user_home, :choose_registration] # Allow iframes on the index URL because safari is an asshole, and doesn't honor our iframe options @@ -15,7 +15,7 @@ def bike_creation_graph end def update_browser - render action: 'update_browser', layout: false + render action: "update_browser", layout: false end def goodbye @@ -24,7 +24,7 @@ def goodbye def user_home page = params[:page] || 1 - @locks_active_tab = params[:active_tab] == 'locks' + @locks_active_tab = params[:active_tab] == "locks" @per_page = params[:per_page] || 20 # If there are over 100 bikes created by the user, we'll have problems loading and sorting them if current_user.creation_states.limit(101).count > 100 diff --git a/app/decorators/application_decorator.rb b/app/decorators/application_decorator.rb index e2c01bfdf0..ac3151106f 100644 --- a/app/decorators/application_decorator.rb +++ b/app/decorators/application_decorator.rb @@ -1,4 +1,4 @@ -class ApplicationDecorator < Draper::Decorator +class ApplicationDecorator < Draper::Decorator delegate_all include ActionView::Helpers::NumberHelper @@ -6,19 +6,18 @@ def self.collection_decorator_class PaginatingDecorator end - def ass_name(association, extra = '') + def ass_name(association, extra = "") ass = object.send(association, name) - [ass.name, extra].reject(&:blank?).join(' ') if ass.present? + [ass.name, extra].reject(&:blank?).join(" ") if ass.present? end def attr_list_item(desc = nil, title, with_colon: false) return nil unless desc.present? title = "#{title}:" if with_colon - html = h.content_tag(:span, title, class: 'attr-title') + html = h.content_tag(:span, title, class: "attr-title") h.content_tag(:li, html + desc) end - def dl_list_item(dd = nil, dt) return nil unless dd.present? html = h.content_tag(:dt, dt) @@ -53,13 +52,13 @@ def if_present(attribute, action = nil) def twitterable(user) if user.show_twitter and user.twitter - h.link_to 'Twitter', "https://twitter.com/#{user.twitter}" + h.link_to "Twitter", "https://twitter.com/#{user.twitter}" end end def websiteable(user) if user.show_website and user.website - h.link_to 'Website', user.website + h.link_to "Website", user.website end end @@ -89,9 +88,9 @@ def display_phone(str = nil) if str.blank? nil elsif str[/\+/] - number_to_phone(str.gsub(/\+\d*/,''), country_code: str[/\A.\d*/].gsub('+',''), delimiter: ' ' ) + number_to_phone(str.gsub(/\+\d*/, ""), country_code: str[/\A.\d*/].gsub("+", ""), delimiter: " ") else - number_to_phone(str, delimiter: ' ') + number_to_phone(str, delimiter: " ") end end end diff --git a/app/decorators/bike_decorator.rb b/app/decorators/bike_decorator.rb index a7db5f8a6a..bb9f0c7f04 100644 --- a/app/decorators/bike_decorator.rb +++ b/app/decorators/bike_decorator.rb @@ -49,7 +49,7 @@ def tire_width(position) end def list_link_url(target = nil) - if target == 'edit' + if target == "edit" "/bikes/#{object.id}/edit" else h.bike_path(object) @@ -60,17 +60,17 @@ def thumb_image if object.thumb_path h.image_tag(object.thumb_path, alt: title_string) elsif object.stock_photo_url.present? - small = object.stock_photo_url.split('/') + small = object.stock_photo_url.split("/") ext = "/small_" + small.pop - h.image_tag(small.join('/') + ext, alt: title_string) + h.image_tag(small.join("/") + ext, alt: title_string) else - h.image_tag('revised/bike_photo_placeholder.svg', alt: title_string, title: 'No image', class: 'no-image') + h.image_tag("revised/bike_photo_placeholder.svg", alt: title_string, title: "No image", class: "no-image") end end def list_image(target = nil) - h.content_tag :div, class: "blist-image-holder" do - h.link_to(list_link_url(target)) do + h.content_tag :div, class: "blist-image-holder" do + h.link_to(list_link_url(target)) do thumb_image end end @@ -78,8 +78,8 @@ def list_image(target = nil) def serial_display return "Hidden" if object.recovered - if object.serial.match('absent') - object.made_without_serial ? 'Has no serial' : 'Unknown' + if object.serial.match("absent") + object.made_without_serial ? "Has no serial" : "Unknown" else object.serial end diff --git a/app/decorators/component_decorator.rb b/app/decorators/component_decorator.rb index d9b7a2221b..bd06d04ab1 100644 --- a/app/decorators/component_decorator.rb +++ b/app/decorators/component_decorator.rb @@ -1,4 +1,3 @@ -class ComponentDecorator < ApplicationDecorator +class ComponentDecorator < ApplicationDecorator delegate_all - -end \ No newline at end of file +end diff --git a/app/decorators/location_decorator.rb b/app/decorators/location_decorator.rb index 20a52a69ba..215642f249 100644 --- a/app/decorators/location_decorator.rb +++ b/app/decorators/location_decorator.rb @@ -1,4 +1,3 @@ -class LocationDecorator < ApplicationDecorator +class LocationDecorator < ApplicationDecorator delegate_all - -end \ No newline at end of file +end diff --git a/app/decorators/manufacturer_decorator.rb b/app/decorators/manufacturer_decorator.rb index 1aec303613..758e3ea68e 100644 --- a/app/decorators/manufacturer_decorator.rb +++ b/app/decorators/manufacturer_decorator.rb @@ -1,4 +1,3 @@ class ManufacturerDecorator < ApplicationDecorator delegate_all - end diff --git a/app/decorators/organization_decorator.rb b/app/decorators/organization_decorator.rb index ceb0f887c1..36bea6828b 100644 --- a/app/decorators/organization_decorator.rb +++ b/app/decorators/organization_decorator.rb @@ -1,4 +1,3 @@ -class OrganizationDecorator < ApplicationDecorator +class OrganizationDecorator < ApplicationDecorator delegate_all - -end \ No newline at end of file +end diff --git a/app/decorators/paginating_decorator.rb b/app/decorators/paginating_decorator.rb index 7ef3573cb2..45b96b43e9 100644 --- a/app/decorators/paginating_decorator.rb +++ b/app/decorators/paginating_decorator.rb @@ -1,3 +1,3 @@ class PaginatingDecorator < Draper::CollectionDecorator delegate :current_page, :total_pages, :limit_value -end \ No newline at end of file +end diff --git a/app/decorators/stolen_record_decorator.rb b/app/decorators/stolen_record_decorator.rb index e40fd3bc8d..5f9c9487fe 100644 --- a/app/decorators/stolen_record_decorator.rb +++ b/app/decorators/stolen_record_decorator.rb @@ -1,3 +1,3 @@ -class StolenRecordDecorator < ApplicationDecorator +class StolenRecordDecorator < ApplicationDecorator delegate_all -end \ No newline at end of file +end diff --git a/app/decorators/user_decorator.rb b/app/decorators/user_decorator.rb index c7c1904f05..b666c4c924 100644 --- a/app/decorators/user_decorator.rb +++ b/app/decorators/user_decorator.rb @@ -1,4 +1,3 @@ class UserDecorator < ApplicationDecorator delegate_all - end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 128e7b7cc7..e4ee7bad38 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -24,38 +24,38 @@ def current_page_active?(link_path, match_controller = false) # - a valid partial file in views/shared # - nil - which just calls yield directly def current_page_skeleton - return 'organized_skeleton' if controller_namespace == 'organized' && action_name != 'landing' + return "organized_skeleton" if controller_namespace == "organized" && action_name != "landing" return nil if @force_landing_page_render case controller_name - when 'bikes' - 'edit_bike_skeleton' if %w(edit update).include?(action_name) - when 'info' - 'content_skeleton' unless %w(terms vendor_terms privacy support_the_index).include?(action_name) - when 'welcome' - 'content_skeleton' if %w(goodbye).include?(action_name) - when 'organizations' - 'content_skeleton' if %w(new lightspeed_integration).include?(action_name) - when 'users' - 'content_skeleton' if %w(request_password_reset).include?(action_name) + when "bikes" + "edit_bike_skeleton" if %w(edit update).include?(action_name) + when "info" + "content_skeleton" unless %w(terms vendor_terms privacy support_the_index).include?(action_name) + when "welcome" + "content_skeleton" if %w(goodbye).include?(action_name) + when "organizations" + "content_skeleton" if %w(new lightspeed_integration).include?(action_name) + when "users" + "content_skeleton" if %w(request_password_reset).include?(action_name) when *%w(news feedbacks manufacturers errors registrations) - 'content_skeleton' + "content_skeleton" end end # For determining menu items to display on content skeleton def content_page_type - if controller_name == 'info' + if controller_name == "info" action_name - elsif controller_name == 'news' - 'news' + elsif controller_name == "news" + "news" end end def body_class - if controller_name == 'landing_pages' || @force_landing_page_render - 'landing-page-body' - elsif current_page_skeleton == 'organized_skeleton' - 'organized-body' + if controller_name == "landing_pages" || @force_landing_page_render + "landing-page-body" + elsif current_page_skeleton == "organized_skeleton" + "organized-body" end end @@ -84,44 +84,44 @@ def link_to_add_fields(name, f, association) new_object = f.object.send(association).klass.new id = new_object.object_id fields = f.fields_for(association, new_object, child_index: id) do |builder| - render(association.to_s.singularize + '_fields', f: builder) + render(association.to_s.singularize + "_fields", f: builder) end - link_to(name, '#', class: 'add_fields button-blue', data: { id: id, fields: fields.gsub("\n", '') }) + link_to(name, "#", class: "add_fields button-blue", data: { id: id, fields: fields.gsub("\n", "") }) end def revised_link_to_add_fields(name, f, association, class_name: nil) new_object = f.object.send(association).klass.new id = new_object.object_id fields = f.fields_for(association, new_object, child_index: id) do |builder| - render(association.to_s.singularize + '_fields', f: builder) + render(association.to_s.singularize + "_fields", f: builder) end - link_to(name, '#', class: "add_fields #{class_name}", data: { id: id, fields: fields.gsub("\n", '') }) + link_to(name, "#", class: "add_fields #{class_name}", data: { id: id, fields: fields.gsub("\n", "") }) end def link_to_add_components(name, f, association, component_scope) new_object = f.object.send(association).klass.new id = new_object.object_id fields = f.fields_for(association, new_object, child_index: id) do |builder| - render('/bikes/bike_fields/component_fields', f: builder, component_group: component_scope) + render("/bikes/bike_fields/component_fields", f: builder, component_group: component_scope) end - link_to(name, '#', class: 'add_fields button-blue', data: { id: id, fields: fields.gsub("\n", '') }) + link_to(name, "#", class: "add_fields button-blue", data: { id: id, fields: fields.gsub("\n", "") }) end def revised_link_to_add_components(name, f, association) new_object = f.object.send(association).klass.new id = new_object.object_id fields = f.fields_for(association, new_object, child_index: id) do |builder| - render('/bikes/bike_fields/revised_component_fields', f: builder, ctype_id: Ctype.unknown.id) + render("/bikes/bike_fields/revised_component_fields", f: builder, ctype_id: Ctype.unknown.id) end text = "+#{name}" - link_to(text.html_safe, '#', class: 'add_fields', data: { id: id, fields: fields.gsub("\n", '') }) + link_to(text.html_safe, "#", class: "add_fields", data: { id: id, fields: fields.gsub("\n", "") }) end def listicle_html(list_item) - c = content_tag(:h2, list_item.title, class: 'list-item-title') + c = content_tag(:h2, list_item.title, class: "list-item-title") if list_item.image_credits.present? c = content_tag(:div, list_item.image_credits_html.html_safe, - class: 'listicle-image-credit') << c + class: "listicle-image-credit") << c end if list_item.image.present? c = image_tag(list_item.image_url(:large)) << c diff --git a/app/helpers/header_tag_helper.rb b/app/helpers/header_tag_helper.rb index b0c2e1d971..cd14502308 100644 --- a/app/helpers/header_tag_helper.rb +++ b/app/helpers/header_tag_helper.rb @@ -34,28 +34,28 @@ def page_description def auto_title return translation_title if translation_title.present? - [auto_namespace_title, auto_controller_and_action_title].compact.join(' ') + [auto_namespace_title, auto_controller_and_action_title].compact.join(" ") end def auto_description return translation_description if translation_description.present? - 'The best bike registry: Simple, secure and free.' + "The best bike registry: Simple, secure and free." end def default_meta_hash { - 'og:description' => page_description, - 'twitter:description' => page_description, - 'og:title' => page_title, - 'twitter:title' => page_title, - 'og:url' => request.url.to_s, - 'og:image' => page_image, - 'twitter:image' => page_image, - 'og:site_name' => 'Bike Index', - 'fb:app_id' => '223376277803071', - 'twitter:card' => (page_image == DEFAULT_IMAGE ? 'summary' : 'summary_large_image'), - 'twitter:creator' => '@bikeindex', - 'twitter:site' => '@bikeindex' + "og:description" => page_description, + "twitter:description" => page_description, + "og:title" => page_title, + "twitter:title" => page_title, + "og:url" => request.url.to_s, + "og:image" => page_image, + "twitter:image" => page_image, + "og:site_name" => "Bike Index", + "fb:app_id" => "223376277803071", + "twitter:card" => (page_image == DEFAULT_IMAGE ? "summary" : "summary_large_image"), + "twitter:creator" => "@bikeindex", + "twitter:site" => "@bikeindex", } end @@ -65,41 +65,41 @@ def social_meta_content_tags(meta_hash) def main_header_tags [ - tag(:meta, charset: 'utf-8'), - tag(:meta, 'http-equiv' => 'Content-Language', content: 'en'), - tag(:meta, 'http-equiv' => 'X-UA-Compatible', content: 'IE=edge'), - tag(:meta, name: 'viewport', content: 'width=device-width'), + tag(:meta, charset: "utf-8"), + tag(:meta, "http-equiv" => "Content-Language", content: "en"), + tag(:meta, "http-equiv" => "X-UA-Compatible", content: "IE=edge"), + tag(:meta, name: "viewport", content: "width=device-width"), content_tag(:title, page_title), - tag(:meta, name: 'description', content: page_description), - tag(:link, rel: 'shortcut icon', href: '/fav.ico'), - tag(:link, rel: 'apple-touch-icon-precomposed apple-touch-icon', href: '/apple_touch_icon.png'), - csrf_meta_tags + tag(:meta, name: "description", content: page_description), + tag(:link, rel: "shortcut icon", href: "/fav.ico"), + tag(:link, rel: "apple-touch-icon-precomposed apple-touch-icon", href: "/apple_touch_icon.png"), + csrf_meta_tags, ] end def welcome_header_tags - if action_name == 'user_home' - self.page_title = (current_user && current_user.name) ? "#{current_user.name} on Bike Index" : 'Your bikes' - elsif action_name == 'choose_registration' - self.page_title = translation_title(location: 'meta_titles.bikes_new') - self.page_description = translation_description(location: 'meta_descriptions.bikes_new') + if action_name == "user_home" + self.page_title = (current_user && current_user.name) ? "#{current_user.name} on Bike Index" : "Your bikes" + elsif action_name == "choose_registration" + self.page_title = translation_title(location: "meta_titles.bikes_new") + self.page_description = translation_description(location: "meta_descriptions.bikes_new") end default_header_tag_array end def bikes_header_tags meta_overrides = {} - if (action_name == 'new' || action_name == 'create') && @bike.stolen - self.page_title = translation_title(location: 'meta_titles.bikes_new_stolen') - self.page_description = translation_description(location: 'meta_descriptions.bikes_new_stolen') - elsif action_name == 'edit' || action_name == 'update' + if (action_name == "new" || action_name == "create") && @bike.stolen + self.page_title = translation_title(location: "meta_titles.bikes_new_stolen") + self.page_description = translation_description(location: "meta_descriptions.bikes_new_stolen") + elsif action_name == "edit" || action_name == "update" if @edit_templates.present? self.page_title = "#{@edit_templates[@edit_template]} - #{@bike.title_string}" else self.page_title = "Edit #{@bike.title_string}" end - elsif action_name == 'show' - self.page_title = "#{'Stolen ' if @bike.stolen}#{@bike.title_string}" + elsif action_name == "show" + self.page_title = "#{"Stolen " if @bike.stolen}#{@bike.title_string}" self.page_description = "#{@bike.frame_colors.to_sentence} #{@bike.title_string}, serial: #{@bike.serial_number}. #{@bike.stolen_string}#{@bike.description}" if @bike.thumb_path.present? && @bike.public_images.present? self.page_image = @bike.public_images.first.image_url @@ -107,7 +107,7 @@ def bikes_header_tags self.page_image = @bike.stock_photo_url end if @bike.owner && @bike.owner.show_twitter && @bike.owner.twitter.present? - meta_overrides['twitter:creator'] = "@#{@bike.owner.twitter}" + meta_overrides["twitter:creator"] = "@#{@bike.owner.twitter}" end end default_header_tag_array(meta_overrides) @@ -115,7 +115,7 @@ def bikes_header_tags def landing_pages_header_tags if active_organization - args = { default: '', organization: active_organization.short_name } + args = { default: "", organization: active_organization.short_name } self.page_title = translation_title(translation_args: args) self.page_description = translation_description(translation_args: args) end @@ -123,12 +123,12 @@ def landing_pages_header_tags end def users_header_tags - if action_name == 'show' + if action_name == "show" if @user.title.present? self.page_title = @user.title self.page_description = "#{@user.title} on Bike Index" end - if @user.avatar && @user.avatar.url != 'https://files.bikeindex.org/blank.png' + if @user.avatar && @user.avatar.url != "https://files.bikeindex.org/blank.png" self.page_image = @user.avatar.url end end @@ -136,36 +136,36 @@ def users_header_tags end def news_header_tags - return default_header_tag_array + [news_auto_discovery_link] unless action_name == 'show' + return default_header_tag_array + [news_auto_discovery_link] unless action_name == "show" self.page_title = @blog.title self.page_description = @blog.description meta_overrides = { - 'og:type' => 'article', - 'og:published_time' => @blog.published_at.utc, - 'og:modified_time' => @blog.updated_at.utc + "og:type" => "article", + "og:published_time" => @blog.published_at.utc, + "og:modified_time" => @blog.updated_at.utc, } - meta_overrides['twitter:creator'] = "@#{@blog.user.twitter}" if @blog.user.twitter + meta_overrides["twitter:creator"] = "@#{@blog.user.twitter}" if @blog.user.twitter if @blog.index_image.present? self.page_image = @blog.index_image_lg elsif @blog.public_images.any? self.page_image = @blog.public_images.last.image_url end default_header_tag_array(meta_overrides) + - [news_auto_discovery_link, tag(:link, rel: 'author', href: user_url(@blog.user))] + [news_auto_discovery_link, tag(:link, rel: "author", href: user_url(@blog.user))] end private SPECIAL_CONTROLLERS = %w(bikes welcome news users landing_pages).freeze - DEFAULT_IMAGE = '/bike_index.png'.freeze + DEFAULT_IMAGE = "/bike_index.png".freeze def default_header_tag_array(meta_overrides = {}) social_meta_content_tags(default_meta_hash.merge(meta_overrides)) + main_header_tags end def default_translation_args - return { default: '' } unless controller_namespace == 'organized' - { default: '', organization: active_organization.short_name } + return { default: "" } unless controller_namespace == "organized" + { default: "", organization: active_organization.short_name } end def translation_title(location: nil, translation_args: default_translation_args) @@ -180,9 +180,9 @@ def translation_description(location: nil, translation_args: default_translation def auto_controller_and_action_title case action_name - when 'index' + when "index" controller_name.humanize - when 'new', 'edit', 'show', 'create' + when "new", "edit", "show", "create" "#{auto_action_name_title} #{controller_name.humanize.singularize.downcase}" else action_name.humanize @@ -190,23 +190,23 @@ def auto_controller_and_action_title end def auto_namespace_title - if controller_namespace == 'admin' - 'Admin |' - elsif controller_namespace == 'organized' + if controller_namespace == "admin" + "Admin |" + elsif controller_namespace == "organized" active_organization.short_name end end def auto_action_name_title { - new: 'New', - edit: 'Edit', - show: 'View', - create: 'Created' + new: "New", + edit: "Edit", + show: "View", + create: "Created", }.as_json.freeze[action_name] end def news_auto_discovery_link - auto_discovery_link_tag(:atom, news_index_url(format: 'atom'), title: 'Bike Index news atom feed') + auto_discovery_link_tag(:atom, news_index_url(format: "atom"), title: "Bike Index news atom feed") end end diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb index 95ebc5cec5..11c733cd41 100644 --- a/app/mailers/admin_mailer.rb +++ b/app/mailers/admin_mailer.rb @@ -1,26 +1,26 @@ class AdminMailer < ActionMailer::Base - default from: 'contact@bikeindex.org', content_type: 'multipart/alternative', parts_order: ['text/calendar', 'text/plain', 'text/html', 'text/enriched'] - default to: 'contact@bikeindex.org' - layout 'email' + default from: "contact@bikeindex.org", content_type: "multipart/alternative", parts_order: ["text/calendar", "text/plain", "text/html", "text/enriched"] + default to: "contact@bikeindex.org" + layout "email" def feedback_notification_email(feedback) @feedback = feedback - send_to = 'contact@bikeindex.org' + send_to = "contact@bikeindex.org" if @feedback.feedback_type.present? - send_to += ', bryan@bikeindex.org, lily@bikeindex.org' if @feedback.feedback_type =~ /bike_recovery/ - send_to = 'bryan@bikeindex.org' if @feedback.feedback_type =~ /stolen_information/ + send_to += ", bryan@bikeindex.org, lily@bikeindex.org" if @feedback.feedback_type =~ /bike_recovery/ + send_to = "bryan@bikeindex.org" if @feedback.feedback_type =~ /stolen_information/ end - mail('Reply-To' => feedback.email, to: send_to, subject: feedback.title) + mail("Reply-To" => feedback.email, to: send_to, subject: feedback.title) end def no_admins_notification_email(organization) @organization = organization - mail(to: 'contact@bikeindex.org', subject: "#{@organization.name} doesn't have any admins!") + mail(to: "contact@bikeindex.org", subject: "#{@organization.name} doesn't have any admins!") end def blocked_stolen_notification_email(stolen_notification) @stolen_notification = stolen_notification - mail(to: 'bryan@bikeindex.org', bcc: 'contact@bikeindex.org', subject: 'Stolen notification blocked!') + mail(to: "bryan@bikeindex.org", bcc: "contact@bikeindex.org", subject: "Stolen notification blocked!") end def unknown_organization_for_ascend_import(bulk_import) @@ -31,6 +31,6 @@ def unknown_organization_for_ascend_import(bulk_import) def lightspeed_notification_email(organization, api_key) @organization = organization @api_key = api_key - mail(to: 'admin@bikeindex.org', subject: 'Api Notification sent!') + mail(to: "admin@bikeindex.org", subject: "Api Notification sent!") end end diff --git a/app/mailers/customer_mailer.rb b/app/mailers/customer_mailer.rb index 6e11d38ec3..d176c5b830 100644 --- a/app/mailers/customer_mailer.rb +++ b/app/mailers/customer_mailer.rb @@ -1,9 +1,9 @@ class CustomerMailer < ActionMailer::Base CONTACT_BIKEINDEX = '"Bike Index" '.freeze default from: CONTACT_BIKEINDEX, - content_type: 'multipart/alternative', - parts_order: ['text/calendar', 'text/plain', 'text/html', 'text/enriched'] - layout 'email' + content_type: "multipart/alternative", + parts_order: ["text/calendar", "text/plain", "text/html", "text/enriched"] + layout "email" def welcome_email(user) @user = user @@ -18,7 +18,7 @@ def confirmation_email(user) def password_reset_email(user) @user = user - @url = "#{ENV['BASE_URL']}/users/password_reset?token=#{@user.password_reset_token}" + @url = "#{ENV["BASE_URL"]}/users/password_reset?token=#{@user.password_reset_token}" mail(to: @user.email) end @@ -43,13 +43,13 @@ def stolen_bike_alert_email(customer_contact) def admin_contact_stolen_email(customer_contact) @customer_contact = customer_contact - mail(to: @customer_contact.user_email, 'Reply-To' => @customer_contact.creator_email, subject: @customer_contact.title) + mail(to: @customer_contact.user_email, "Reply-To" => @customer_contact.creator_email, subject: @customer_contact.title) end def stolen_notification_email(stolen_notification) @stolen_notification = stolen_notification - mail(to: [@stolen_notification.receiver_email, 'lily@bikeindex.org', 'bryan@bikeindex.org'], - from: 'bryan@bikeindex.org', subject: @stolen_notification.display_subject) + mail(to: [@stolen_notification.receiver_email, "lily@bikeindex.org", "bryan@bikeindex.org"], + from: "bryan@bikeindex.org", subject: @stolen_notification.display_subject) dates = stolen_notification.send_dates_parsed + [Time.now.to_i] stolen_notification.update_attribute :send_dates, dates end @@ -59,7 +59,7 @@ def recovered_from_link(stolen_record) @bike = stolen_record.bike @biketype = @bike.cycle_type_name&.downcase mail(to: [@bike.owner_email], - from: 'bryan@bikeindex.org', + from: "bryan@bikeindex.org", subject: "Your #{@biketype} has been marked recovered!") end @@ -68,6 +68,6 @@ def updated_terms_email(user) @_action_has_layout = false # layout is manually included here mail(to: @user.email, from: '"Lily Williams" ', - subject: 'Bike Index Terms and Privacy Policy Update') + subject: "Bike Index Terms and Privacy Policy Update") end end diff --git a/app/mailers/organized_mailer.rb b/app/mailers/organized_mailer.rb index aa47e74c44..a529794ac4 100644 --- a/app/mailers/organized_mailer.rb +++ b/app/mailers/organized_mailer.rb @@ -1,16 +1,16 @@ # Every email in here has the potential to be owned by an organization - # but they aren't necessarily class OrganizedMailer < ActionMailer::Base - CONTACT_BIKEINDEX = 'Bike Index '.freeze + CONTACT_BIKEINDEX = "Bike Index ".freeze default from: CONTACT_BIKEINDEX, - content_type: 'multipart/alternative', - parts_order: ['text/calendar', 'text/plain', 'text/html', 'text/enriched'] - layout 'email' + content_type: "multipart/alternative", + parts_order: ["text/calendar", "text/plain", "text/html", "text/enriched"] + layout "email" def partial_registration(b_param) @b_param = b_param @organization = @b_param.creation_organization - mail('Reply-To' => reply_to, to: @b_param.owner_email, subject: default_i18n_subject(default_subject_vars)) + mail("Reply-To" => reply_to, to: @b_param.owner_email, subject: default_i18n_subject(default_subject_vars)) end def finished_registration(ownership) @@ -25,7 +25,7 @@ def finished_registration(ownership) @organization = @bike.creation_organization if @bike.creation_organization.present? && @vars[:new_bike] @vars[:donation_message] = @bike.stolen? && !(@organization && !@organization.is_paid?) subject = t("organized_mailer.finished#{finished_registration_type}_registration.subject", default_subject_vars) - mail('Reply-To' => reply_to, to: @vars[:email], subject: subject) + mail("Reply-To" => reply_to, to: @vars[:email], subject: subject) end def organization_invitation(organization_invitation) @@ -34,7 +34,7 @@ def organization_invitation(organization_invitation) @inviter = @organization_invitation.inviter @vars = { email: @organization_invitation.invitee_email } @new_user = User.fuzzy_email_find(@vars[:email]).present? - mail('Reply-To' => reply_to, to: @vars[:email], subject: default_i18n_subject(default_subject_vars)) + mail("Reply-To" => reply_to, to: @vars[:email], subject: default_i18n_subject(default_subject_vars)) end def custom_message(organization_message) @@ -43,7 +43,7 @@ def custom_message(organization_message) @bike = @organization_message.bike @sender = @organization_message.sender - mail('Reply-To' => @organization_message.sender.email, to: @organization_message.email, subject: @organization_message.subject) do |format| + mail("Reply-To" => @organization_message.sender.email, to: @organization_message.email, subject: @organization_message.subject) do |format| format.html { render "geolocated_message" } format.text { render "geolocated_message_text" } end @@ -52,14 +52,14 @@ def custom_message(organization_message) private def finished_registration_type - return '_stolen' if @bike.stolen - @ownership.claimed ? '_owned' : '' + return "_stolen" if @bike.stolen + @ownership.claimed ? "_owned" : "" end def default_subject_vars { organization_name: @organization && "#{@organization.short_name} ", - bike_type: @bike && "#{@bike.type} " + bike_type: @bike && "#{@bike.type} ", } end diff --git a/app/models/ad.rb b/app/models/ad.rb index a608884794..77265e3dd2 100644 --- a/app/models/ad.rb +++ b/app/models/ad.rb @@ -1,5 +1,4 @@ class Ad < ActiveRecord::Base - belongs_to :organization validates_presence_of :title validates_uniqueness_of :title @@ -7,5 +6,4 @@ class Ad < ActiveRecord::Base mount_uploader :image, PartnerUploader scope :live, -> { where(live: true) } - end diff --git a/app/models/b_param.rb b/app/models/b_param.rb index 5d50b180cc..eb7d5dbed0 100644 --- a/app/models/b_param.rb +++ b/app/models/b_param.rb @@ -6,11 +6,11 @@ class BParam < ActiveRecord::Base # serialize :params serialize :bike_errors - belongs_to :created_bike, class_name: 'Bike' - belongs_to :creator, class_name: 'User' + belongs_to :created_bike, class_name: "Bike" + belongs_to :creator, class_name: "User" belongs_to :organization - scope :with_bike, -> { where('created_bike_id IS NOT NULL') } + scope :with_bike, -> { where("created_bike_id IS NOT NULL") } scope :without_bike, -> { where(created_bike_id: nil) } scope :without_creator, -> { where(creator_id: nil) } scope :partial_registrations, -> { where(origin: "embed_partial") } @@ -19,17 +19,17 @@ class BParam < ActiveRecord::Base before_save :clean_params def self.v2_params(hash) - h = hash['bike'].present? ? hash : { 'bike' => hash.with_indifferent_access } - h['bike']['serial_number'] = h['bike'].delete 'serial' - h['bike']['send_email'] = !(h['bike'].delete 'no_notify') - org = Organization.friendly_find(h['bike'].delete 'organization_slug') - h['bike']['creation_organization_id'] = org.id if org.present? + h = hash["bike"].present? ? hash : { "bike" => hash.with_indifferent_access } + h["bike"]["serial_number"] = h["bike"].delete "serial" + h["bike"]["send_email"] = !(h["bike"].delete "no_notify") + org = Organization.friendly_find(h["bike"].delete "organization_slug") + h["bike"]["creation_organization_id"] = org.id if org.present? # Move un-nested params outside of bike - %w(test id components).each { |k| h[k] = h['bike'].delete k } - stolen_attrs = h['bike'].delete 'stolen_record' - if stolen_attrs && stolen_attrs.delete_if { |k,v| v.blank? } && stolen_attrs.keys.any? - h['bike']['stolen'] = true - h['stolen_record'] = stolen_attrs + %w(test id components).each { |k| h[k] = h["bike"].delete k } + stolen_attrs = h["bike"].delete "stolen_record" + if stolen_attrs && stolen_attrs.delete_if { |k, v| v.blank? } && stolen_attrs.keys.any? + h["bike"]["stolen"] = true + h["stolen_record"] = stolen_attrs end h end @@ -54,8 +54,8 @@ def self.find_or_new_from_token(toke = nil, user_id: nil, organization_id: nil) end def self.with_organization_or_no_creator(toke) # Because organization embed bikes might not match the creator - without_bike.where('created_at >= ?', Time.now - 1.month).where(id_token: toke) - .detect { |b| b.creator_id.blank? || b.creation_organization_id.present? || b.params['creation_organization_id'].present? } + without_bike.where("created_at >= ?", Time.now - 1.month).where(id_token: toke) + .detect { |b| b.creator_id.blank? || b.creation_organization_id.present? || b.params["creation_organization_id"].present? } end def self.assignable_attrs @@ -76,54 +76,54 @@ def self.email_search(str) # Crazy new shit def manufacturer_id=(val) - params['bike']['manufacturer_id'] = val + params["bike"]["manufacturer_id"] = val end def creation_organization_id=(val) - params['bike']['creation_organization_id'] = val + params["bike"]["creation_organization_id"] = val end def owner_email=(val) - params['bike']['owner_email'] = val + params["bike"]["owner_email"] = val end def stolen=(val) - params['bike']['stolen'] = ActiveRecord::Type::Boolean.new.type_cast_from_database(val) + params["bike"]["stolen"] = ActiveRecord::Type::Boolean.new.type_cast_from_database(val) end def primary_frame_color_id=(val) - params['bike']['primary_frame_color_id'] = val + params["bike"]["primary_frame_color_id"] = val end def secondary_frame_color_id=(val) - params['bike']['secondary_frame_color_id'] = val + params["bike"]["secondary_frame_color_id"] = val end def tertiary_frame_color_id=(val) - params['bike']['tertiary_frame_color_id'] = val + params["bike"]["tertiary_frame_color_id"] = val end def with_bike?; created_bike_id.present? end - def bike; (params && params['bike'] || {}).with_indifferent_access end + def bike; (params && params["bike"] || {}).with_indifferent_access end - def primary_frame_color_id; bike['primary_frame_color_id'] end + def primary_frame_color_id; bike["primary_frame_color_id"] end - def secondary_frame_color_id; bike['secondary_frame_color_id'] end + def secondary_frame_color_id; bike["secondary_frame_color_id"] end - def tertiary_frame_color_id; bike['tertiary_frame_color_id'] end + def tertiary_frame_color_id; bike["tertiary_frame_color_id"] end - def manufacturer_id; bike['manufacturer_id'] end + def manufacturer_id; bike["manufacturer_id"] end - def stolen; bike['stolen'] end + def stolen; bike["stolen"] end - def is_pos; bike['is_pos'] || false end + def is_pos; bike["is_pos"] || false end - def is_new; bike['is_new'] || false end + def is_new; bike["is_new"] || false end - def is_bulk; bike['is_bulk'] || false end + def is_bulk; bike["is_bulk"] || false end - def no_duplicate; bike['no_duplicate'] || false end + def no_duplicate; bike["no_duplicate"] || false end def bike_code; bike["bike_code"] end @@ -133,17 +133,17 @@ def user_name; bike["user_name"] end def creation_organization; Organization.friendly_find(creation_organization_id) end - def manufacturer; bike['manufacturer_id'] && Manufacturer.friendly_find(bike['manufacturer_id']) end + def manufacturer; bike["manufacturer_id"] && Manufacturer.friendly_find(bike["manufacturer_id"]) end def partial_registration?; origin == "embed_partial" end def primary_frame_color; primary_frame_color_id.present? && Color.find(primary_frame_color_id)&.name end - def revised_new?; params && params['revised_new'] end + def revised_new?; params && params["revised_new"] end def creation_organization_id; bike && bike["creation_organization_id"] || params && params["creation_organization_id"] end - def owner_email; bike && bike['owner_email'] end + def owner_email; bike && bike["owner_email"] end def organization_affiliation; bike["organization_affiliation"] end @@ -168,51 +168,51 @@ def clean_params(updated_params = {}) # So we can pass in the params end def massage_if_v2 - self.params = self.class.v2_params(params) if origin == 'api_v2' + self.params = self.class.v2_params(params) if origin == "api_v2" true end def set_foreign_keys return true unless params.present? && bike.present? - bike['stolen'] = true if params['stolen_record'].present? + bike["stolen"] = true if params["stolen_record"].present? set_wheel_size_key set_manufacturer_key - set_color_key unless bike['primary_frame_color_id'].present? - set_cycle_type_key - set_rear_gear_type_slug if bike['rear_gear_type_slug'].present? - set_front_gear_type_slug if bike['front_gear_type_slug'].present? - set_handlebar_type_key + set_color_key unless bike["primary_frame_color_id"].present? + set_cycle_type_key + set_rear_gear_type_slug if bike["rear_gear_type_slug"].present? + set_front_gear_type_slug if bike["front_gear_type_slug"].present? + set_handlebar_type_key set_frame_material_key # Even if the value isn't present, since we need to remove the key end def set_handlebar_type_key - key = bike['handlebar_type'] || bike['handlebar_type_slug'] + key = bike["handlebar_type"] || bike["handlebar_type_slug"] ht = HandlebarType.friendly_find(key) - params['bike']['handlebar_type'] = ht&.slug - params['bike'].delete('handlebar_type_slug') + params["bike"]["handlebar_type"] = ht&.slug + params["bike"].delete("handlebar_type_slug") end def set_cycle_type_key - if key = (bike['cycle_type'] || bike['cycle_type_slug'] || bike['cycle_type_name']).presence + if key = (bike["cycle_type"] || bike["cycle_type_slug"] || bike["cycle_type_name"]).presence ct = CycleType.friendly_find(key) - params['bike']['cycle_type'] = ct&.slug - params['bike'].delete('cycle_type_slug') - params['bike'].delete('cycle_type_name') + params["bike"]["cycle_type"] = ct&.slug + params["bike"].delete("cycle_type_slug") + params["bike"].delete("cycle_type_name") end end def set_wheel_size_key - if bike.keys.include?('rear_wheel_bsd') - key = '_wheel_bsd' - elsif bike['rear_wheel_size'].present? - key = '_wheel_size' + if bike.keys.include?("rear_wheel_bsd") + key = "_wheel_bsd" + elsif bike["rear_wheel_size"].present? + key = "_wheel_size" else return nil end - rbsd = params['bike'].delete("rear#{key}") - fbsd = params['bike'].delete("front#{key}") - params['bike']['rear_wheel_size_id'] = WheelSize.id_for_bsd(rbsd) - params['bike']['front_wheel_size_id'] = WheelSize.id_for_bsd(fbsd) + rbsd = params["bike"].delete("rear#{key}") + fbsd = params["bike"].delete("front#{key}") + params["bike"]["rear_wheel_size_id"] = WheelSize.id_for_bsd(rbsd) + params["bike"]["front_wheel_size_id"] = WheelSize.id_for_bsd(fbsd) end def set_frame_material_key @@ -223,55 +223,55 @@ def set_frame_material_key def set_manufacturer_key return false unless bike.present? - m = params['bike'].delete('manufacturer') - m = params['bike'].delete('manufacturer_id') unless m.present? + m = params["bike"].delete("manufacturer") + m = params["bike"].delete("manufacturer_id") unless m.present? return nil unless m.present? b_manufacturer = Manufacturer.friendly_find(m) unless b_manufacturer.present? b_manufacturer = Manufacturer.other - params['bike']['manufacturer_other'] = m + params["bike"]["manufacturer_other"] = m end - params['bike']['manufacturer_id'] = b_manufacturer.id + params["bike"]["manufacturer_id"] = b_manufacturer.id end def set_rear_gear_type_slug - gear = RearGearType.where(slug: params['bike'].delete('rear_gear_type_slug')).first - params['bike']['rear_gear_type_id'] = gear && gear.id + gear = RearGearType.where(slug: params["bike"].delete("rear_gear_type_slug")).first + params["bike"]["rear_gear_type_id"] = gear && gear.id end def set_front_gear_type_slug - gear = FrontGearType.where(slug: params['bike'].delete('front_gear_type_slug')).first - params['bike']['front_gear_type_id'] = gear && gear.id + gear = FrontGearType.where(slug: params["bike"].delete("front_gear_type_slug")).first + params["bike"]["front_gear_type_id"] = gear && gear.id end def set_color_key - paint = params['bike']['color'] + paint = params["bike"]["color"] color = Color.friendly_find(paint.strip) if paint.present? if color.present? - params['bike']['primary_frame_color_id'] = color.id + params["bike"]["primary_frame_color_id"] = color.id else set_paint_key(paint) end - params['bike'].delete('color') + params["bike"].delete("color") end def set_paint_key(paint_entry) return nil unless paint_entry.present? paint = Paint.friendly_find(paint_entry) if paint.present? - params['bike']['paint_id'] = paint.id + params["bike"]["paint_id"] = paint.id else paint = Paint.new(name: paint_entry) - paint.manufacturer_id = bike['manufacturer_id'] if is_pos + paint.manufacturer_id = bike["manufacturer_id"] if is_pos paint.save - params['bike']['paint_id'] = paint.id - params['bike']['paint_name'] = paint.name + params["bike"]["paint_id"] = paint.id + params["bike"]["paint_name"] = paint.name end - unless bike['primary_frame_color_id'].present? + unless bike["primary_frame_color_id"].present? if paint.color_id.present? - params['bike']['primary_frame_color_id'] = paint.color.id + params["bike"]["primary_frame_color_id"] = paint.color.id else - params['bike']['primary_frame_color_id'] = Color.find_by_name('Black').id + params["bike"]["primary_frame_color_id"] = Color.find_by_name("Black").id end end end @@ -279,7 +279,7 @@ def set_paint_key(paint_entry) def find_duplicate_bike(bike) return nil unless no_duplicate dupe = Bike.where(serial_number: bike.serial_number, owner_email: bike.owner_email) - .where.not(id: bike.id).order(:created_at).first + .where.not(id: bike.id).order(:created_at).first return nil unless dupe.present? self.update_attribute :created_bike_id, dupe.id end @@ -303,14 +303,14 @@ def generate_id_token # Set the protected attrs separately from the params hash and merging over the passed params # Now that we're on rails 4, this is just a giant headache. def bike_from_attrs(is_stolen: nil, recovered: nil) - is_stolen = params['bike']['stolen'] if params['bike'] && params['bike'].keys.include?('stolen') - Bike.new(safe_bike_attrs({ 'stolen' => is_stolen, 'recovered' => recovered }).as_json) + is_stolen = params["bike"]["stolen"] if params["bike"] && params["bike"].keys.include?("stolen") + Bike.new(safe_bike_attrs({ "stolen" => is_stolen, "recovered" => recovered }).as_json) end def safe_bike_attrs(param_overrides) bike.merge(param_overrides).select { |k, v| self.class.assignable_attrs.include?(k.to_s) } - .merge('b_param_id' => id, - 'creator_id' => creator_id) + .merge("b_param_id" => id, + "creator_id" => creator_id) end def fetch_formatted_address diff --git a/app/models/bike.rb b/app/models/bike.rb index 30af474e9d..91d8d95b94 100644 --- a/app/models/bike.rb +++ b/app/models/bike.rb @@ -5,20 +5,20 @@ class Bike < ActiveRecord::Base process_in_background :pdf, CarrierWaveProcessWorker belongs_to :manufacturer - belongs_to :primary_frame_color, class_name: 'Color' - belongs_to :secondary_frame_color, class_name: 'Color' - belongs_to :tertiary_frame_color, class_name: 'Color' - belongs_to :rear_wheel_size, class_name: 'WheelSize' - belongs_to :front_wheel_size, class_name: 'WheelSize' + belongs_to :primary_frame_color, class_name: "Color" + belongs_to :secondary_frame_color, class_name: "Color" + belongs_to :tertiary_frame_color, class_name: "Color" + belongs_to :rear_wheel_size, class_name: "WheelSize" + belongs_to :front_wheel_size, class_name: "WheelSize" belongs_to :rear_gear_type belongs_to :front_gear_type belongs_to :paint, counter_cache: true - belongs_to :updator, class_name: 'User' + belongs_to :updator, class_name: "User" belongs_to :invoice belongs_to :location - belongs_to :current_stolen_record, class_name: 'StolenRecord' - belongs_to :creator, class_name: 'User' # to be deprecated and removed - belongs_to :creation_organization, class_name: 'Organization' # to be deprecated and removed + belongs_to :current_stolen_record, class_name: "StolenRecord" + belongs_to :creator, class_name: "User" # to be deprecated and removed + belongs_to :creation_organization, class_name: "Organization" # to be deprecated and removed has_many :bike_organizations, dependent: :destroy has_many :organizations, through: :bike_organizations @@ -36,7 +36,7 @@ class Bike < ActiveRecord::Base has_many :bike_codes has_many :b_params, foreign_key: :created_bike_id, dependent: :destroy has_many :duplicate_bike_groups, through: :normalized_serial_segments - has_many :recovered_records, -> { recovered }, class_name: 'StolenRecord' + has_many :recovered_records, -> { recovered }, class_name: "StolenRecord" accepts_nested_attributes_for :stolen_records accepts_nested_attributes_for :components, allow_destroy: true @@ -66,15 +66,15 @@ class Bike < ActiveRecord::Base enum cycle_type: CycleType::SLUGS enum propulsion_type: PropulsionType::SLUGS - default_scope { + default_scope { includes(:tertiary_frame_color, :secondary_frame_color, :primary_frame_color, :current_stolen_record) - .where(example: false, hidden: false) - .order('listing_order desc') + .where(example: false, hidden: false) + .order("listing_order desc") } scope :stolen, -> { where(stolen: true) } scope :non_stolen, -> { where(stolen: false) } scope :organized, -> { where.not(creation_organization_id: nil) } - scope :with_serial, -> { where('serial_number != ?', 'absent') } + scope :with_serial, -> { where("serial_number != ?", "absent") } # "Recovered" bikes are bikes that were found and are waiting to be claimed. This is confusing and should be fixed # so that it no longer is the same word as stolen recoveries scope :non_recovered, -> { where(recovered: false) } @@ -83,36 +83,36 @@ class Bike < ActiveRecord::Base include PgSearch pg_search_scope :pg_search, against: { - serial_number: 'A', - cached_data: 'B', - all_description: 'C' - } + serial_number: "A", + cached_data: "B", + all_description: "C", + } pg_search_scope :admin_search, - against: { owner_email: 'A' }, + against: { owner_email: "A" }, associated_against: { ownerships: :owner_email, creator: :email }, - using: { tsearch: { dictionary: 'english', prefix: true } } + using: { tsearch: { dictionary: "english", prefix: true } } class << self def old_attr_accessible # made_without_serial - GUARANTEE there was no serial - (%w(manufacturer_id manufacturer_other serial_number - serial_normalized has_no_serial made_without_serial additional_registration - creation_organization_id manufacturer year thumb_path name stolen - current_stolen_record_id recovered frame_material cycle_type frame_model number_of_seats - handlebar_type frame_size frame_size_number frame_size_unit - rear_tire_narrow front_wheel_size_id rear_wheel_size_id front_tire_narrow - primary_frame_color_id secondary_frame_color_id tertiary_frame_color_id paint_id paint_name - propulsion_type zipcode country_id belt_drive - coaster_brake rear_gear_type_slug rear_gear_type_id front_gear_type_slug front_gear_type_id description owner_email - timezone date_stolen receive_notifications phone creator creator_id image - components_attributes b_param_id embeded embeded_extended example hidden - card_id stock_photo_url pdf send_email other_listing_urls listing_order approved_stolen - marked_user_hidden marked_user_unhidden b_param_id_token is_for_sale bike_organization_ids - ).map(&:to_sym) + [stolen_records_attributes: StolenRecord.old_attr_accessible, - components_attributes: Component.old_attr_accessible]).freeze + (%w(manufacturer_id manufacturer_other serial_number + serial_normalized has_no_serial made_without_serial additional_registration + creation_organization_id manufacturer year thumb_path name stolen + current_stolen_record_id recovered frame_material cycle_type frame_model number_of_seats + handlebar_type frame_size frame_size_number frame_size_unit + rear_tire_narrow front_wheel_size_id rear_wheel_size_id front_tire_narrow + primary_frame_color_id secondary_frame_color_id tertiary_frame_color_id paint_id paint_name + propulsion_type zipcode country_id belt_drive + coaster_brake rear_gear_type_slug rear_gear_type_id front_gear_type_slug front_gear_type_id description owner_email + timezone date_stolen receive_notifications phone creator creator_id image + components_attributes b_param_id embeded embeded_extended example hidden + card_id stock_photo_url pdf send_email other_listing_urls listing_order approved_stolen + marked_user_hidden marked_user_unhidden b_param_id_token is_for_sale bike_organization_ids + ).map(&:to_sym) + [stolen_records_attributes: StolenRecord.old_attr_accessible, + components_attributes: Component.old_attr_accessible]).freeze end - + def text_search(query) query.present? ? pg_search(query) : all end @@ -145,8 +145,8 @@ def cleaned_error_messages # We don't actually want to show these messages to th def get_listing_order return current_stolen_record.date_stolen.to_time.to_i.abs if stolen && current_stolen_record.present? - t = (updated_at || Time.now).to_i/10000 - stock_photo_url.present? || public_images.present? ? t : t/100 + t = (updated_at || Time.now).to_i / 10000 + stock_photo_url.present? || public_images.present? ? t : t / 100 end def current_ownership; ownerships.reorder(:created_at).last end @@ -253,7 +253,7 @@ def phone @phone end - def visible_by(passed_user=nil) + def visible_by(passed_user = nil) return true unless hidden if passed_user.present? return true if passed_user.superuser @@ -267,24 +267,24 @@ def find_current_stolen_record end def title_string - t = [year, mnfg_name, frame_model].join(' ') + t = [year, mnfg_name, frame_model].join(" ") t += " #{type}" if type != "bike" - Rails::Html::FullSanitizer.new.sanitize(t.gsub(/\s+/,' ')).strip + Rails::Html::FullSanitizer.new.sanitize(t.gsub(/\s+/, " ")).strip end def stolen_string return nil unless stolen and current_stolen_record.present? [ - 'Stolen ', + "Stolen ", current_stolen_record.date_stolen && current_stolen_record.date_stolen.strftime("%Y-%m-%d"), - current_stolen_record.address && "from #{current_stolen_record.address}. " - ].compact.join(' ') + current_stolen_record.address && "from #{current_stolen_record.address}. ", + ].compact.join(" ") end def video_embed_src if video_embed.present? code = Nokogiri::HTML(video_embed) - src = code.xpath('//iframe/@src') + src = code.xpath("//iframe/@src") if src[0] src[0].value end @@ -296,8 +296,8 @@ def bike_organization_ids end def bike_organization_ids=(val) - org_ids = (val.is_a?(Array) ? val : val.split(',').map(&:strip)) - .map { |id| validated_organization_id(id) }.compact + org_ids = (val.is_a?(Array) ? val : val.split(",").map(&:strip)) + .map { |id| validated_organization_id(id) }.compact org_ids.each { |id| bike_organizations.where(organization_id: id).first_or_create } bike_organizations.each { |bo| bo.destroy unless org_ids.include?(bo.organization_id) } true @@ -307,7 +307,7 @@ def validated_organization_id(organization_id) return nil unless organization_id.present? organization = Organization.friendly_find(organization_id) return organization.id if organization && !organization.suspended? - msg = organization ? "suspended and can't be used" : 'not found' + msg = organization ? "suspended and can't be used" : "not found" errors.add(:organization, "#{organization_id} is #{msg}") nil end @@ -324,10 +324,10 @@ def set_mnfg_name end def set_user_hidden - if marked_user_hidden.present? && marked_user_hidden.to_s != '0' + if marked_user_hidden.present? && marked_user_hidden.to_s != "0" self.hidden = true current_ownership.update_attribute :user_hidden, true unless current_ownership.user_hidden - elsif marked_user_unhidden.present? && marked_user_unhidden.to_s != '0' + elsif marked_user_unhidden.present? && marked_user_unhidden.to_s != "0" self.hidden = false current_ownership.update_attribute :user_hidden, false if current_ownership.user_hidden end @@ -335,7 +335,7 @@ def set_user_hidden end def normalize_attributes - self.serial_number = 'absent' if serial_number.blank? || serial_number.strip.downcase == 'unknown' + self.serial_number = "absent" if serial_number.blank? || serial_number.strip.downcase == "unknown" self.serial_normalized = SerialNormalizer.new(serial: serial_number).normalized if User.fuzzy_email_find(owner_email) self.owner_email = User.fuzzy_email_find(owner_email).email @@ -358,32 +358,32 @@ def clean_frame_size unless frame_size_unit.present? if frame_size_number.present? if frame_size_number < 30 # Good guessing? - self.frame_size_unit = 'in' + self.frame_size_unit = "in" else - self.frame_size_unit = 'cm' + self.frame_size_unit = "cm" end else - self.frame_size_unit = 'ordinal' + self.frame_size_unit = "ordinal" end end if frame_size_number.present? - self.frame_size = frame_size_number.to_s.gsub('.0','') + frame_size_unit + self.frame_size = frame_size_number.to_s.gsub(".0", "") + frame_size_unit else self.frame_size = case frame_size.downcase - when /x*sma/, 'xs' - 'xs' - when /sma/, 's' - 's' - when /med/, 'm' - 'm' - when /(lg)|(large)/, 'l' - 'l' - when /x*l/, 'xl' - 'xl' - else - nil - end + when /x*sma/, "xs" + "xs" + when /sma/, "s" + "s" + when /med/, "m" + "m" + when /(lg)|(large)/, "l" + "l" + when /x*l/, "xl" + "xl" + else + nil + end end true end @@ -425,7 +425,7 @@ def frame_colors [ primary_frame_color && primary_frame_color.name, secondary_frame_color && secondary_frame_color.name, - tertiary_frame_color && tertiary_frame_color.name + tertiary_frame_color && tertiary_frame_color.name, ].compact end @@ -452,7 +452,7 @@ def components_cache_string [ c.year, (c.manufacturer && c.manufacturer.name), - c.component_type + c.component_type, ] if c.ctype.present? && c.ctype.name.present? end end @@ -461,9 +461,9 @@ def cache_stolen_attributes csr = find_current_stolen_record self.attributes = { current_stolen_record_id: csr && csr.id, - all_description: [description, csr && csr.theft_description].reject(&:blank?).join(' '), + all_description: [description, csr && csr.theft_description].reject(&:blank?).join(" "), stolen_lat: csr && csr.latitude, - stolen_long: csr && csr.longitude + stolen_long: csr && csr.longitude, } end @@ -472,7 +472,7 @@ def cache_bike cache_photo self.cached_data = [ mnfg_name, - (propulsion_type_name == 'Foot pedal' ? nil : propulsion_type_name), + (propulsion_type_name == "Foot pedal" ? nil : propulsion_type_name), year, (primary_frame_color && primary_frame_color.name), (secondary_frame_color && secondary_frame_color.name), @@ -483,9 +483,9 @@ def cache_bike (rear_wheel_size && "#{rear_wheel_size.name} wheel"), (front_wheel_size && front_wheel_size != rear_wheel_size ? "#{front_wheel_size.name} wheel" : nil), additional_registration, - (type == 'bike' ? nil : type), - components_cache_string - ].flatten.reject(&:blank?).join(' ') + (type == "bike" ? nil : type), + components_cache_string, + ].flatten.reject(&:blank?).join(" ") end def frame_material_name diff --git a/app/models/bike_code.rb b/app/models/bike_code.rb index b86ba99fc1..7301fcff3d 100644 --- a/app/models/bike_code.rb +++ b/app/models/bike_code.rb @@ -69,8 +69,8 @@ def unclaimed?; !claimed? end def url [ - "#{ENV['BASE_URL']}/scanned/bikes/#{code}", - organization.present? ? "?organization_id=#{organization.slug}" : nil + "#{ENV["BASE_URL"]}/scanned/bikes/#{code}", + organization.present? ? "?organization_id=#{organization.slug}" : nil, ].compact.join("") end diff --git a/app/models/blog.rb b/app/models/blog.rb index 1253d29f08..b95be97ad3 100644 --- a/app/models/blog.rb +++ b/app/models/blog.rb @@ -53,7 +53,7 @@ def set_published_at_and_published if self.post_date.present? self.published_at = TimeParser.parse(post_date, timezone) end - self.published_at = Time.now if self.post_now == '1' + self.published_at = Time.now if self.post_now == "1" if self.user_email.present? u = User.fuzzy_email_find(user_email) self.user_id = u.id if u.present? @@ -77,7 +77,7 @@ def feed_content def update_title_save return true unless update_title.present? - return true if update_title == false || update_title == '0' + return true if update_title == false || update_title == "0" self.old_title_slug = self.title_slug set_title_slug end @@ -87,7 +87,6 @@ def set_title_slug self.title_slug = self.class.slugify_title(title) end - def create_abbreviation if description_abbr.present? self.body_abbr = description_abbr @@ -101,7 +100,7 @@ def create_abbreviation end abbr = strip_tags(body_html) # strip tags, then remove extra spaces - abbr = abbr.gsub(/\n/,' ').gsub(/\s+/, ' ').strip if abbr.present? + abbr = abbr.gsub(/\n/, " ").gsub(/\s+/, " ").strip if abbr.present? self.body_abbr = truncate(abbr, length: 200) end true diff --git a/app/models/bulk_import.rb b/app/models/bulk_import.rb index ea73569910..cdaf0f9b1c 100644 --- a/app/models/bulk_import.rb +++ b/app/models/bulk_import.rb @@ -46,7 +46,7 @@ def add_file_error(error_msg, line_error = "", skip_save: false) self.progress = "finished" updated_file_error_data = { "file" => [file_import_errors, error_msg.to_s].compact.flatten, - "file_lines" => [file_import_error_lines, line_error].flatten + "file_lines" => [file_import_error_lines, line_error].flatten, } return true if skip_save # Don't get stuck in a loop during creation # Using update_attribute here to avoid validation checks that sometimes block updating postgres json in rails diff --git a/app/models/cgroup.rb b/app/models/cgroup.rb index 46d1f0de0a..67712de249 100644 --- a/app/models/cgroup.rb +++ b/app/models/cgroup.rb @@ -5,6 +5,6 @@ class Cgroup < ActiveRecord::Base has_many :ctypes def self.additional_parts - where(name: 'Additional parts').first_or_create + where(name: "Additional parts").first_or_create end end diff --git a/app/models/color.rb b/app/models/color.rb index 4b66431d1b..e78b899901 100644 --- a/app/models/color.rb +++ b/app/models/color.rb @@ -7,23 +7,23 @@ class Color < ActiveRecord::Base has_many :paints default_scope { order(:name) } - scope :commonness, -> { order('priority ASC, name ASC') } + scope :commonness, -> { order("priority ASC, name ASC") } def self.black - where(name: 'Black', priority: 1, display: '#000').first_or_create + where(name: "Black", priority: 1, display: "#000").first_or_create end def autocomplete_hash { id: id, text: name, - category: 'colors', + category: "colors", priority: 1000, data: { priority: 1000, display: display, - search_id: search_id - } + search_id: search_id, + }, }.as_json end diff --git a/app/models/component.rb b/app/models/component.rb index 9861d33c50..2a8e861a4a 100644 --- a/app/models/component.rb +++ b/app/models/component.rb @@ -1,12 +1,13 @@ class Component < ActiveRecord::Base include ActiveModel::Dirty - def self.old_attr_accessible + def self.old_attr_accessible %w(id cmodel_name year ctype ctype_id ctype_other manufacturer manufacturer_id mnfg_name manufacturer_other description bike_id bike serial_number front rear front_or_rear _destroy).map(&:to_sym).freeze - end + end attr_accessor :front_or_rear, :mnfg_name, :setting_is_stock + def model_name=(val) self.cmodel_name = val end @@ -16,15 +17,16 @@ def model_name=(val) belongs_to :bike before_save :set_front_or_rear + def set_front_or_rear return true unless self.front_or_rear.present? position = self.front_or_rear.downcase.strip - self.front_or_rear = '' + self.front_or_rear = "" if position == "both" f = self.dup f.front = true - f.save - self.rear = true + f.save + self.rear = true elsif position == "front" self.front = true elsif position == "rear" @@ -51,7 +53,7 @@ def component_group end def manufacturer_name - if manufacturer && manufacturer.name == 'Other' && manufacturer_other.present? + if manufacturer && manufacturer.name == "Other" && manufacturer_other.present? manufacturer_other else manufacturer && manufacturer.name @@ -59,6 +61,7 @@ def manufacturer_name end before_save :set_is_stock + def set_is_stock return true if setting_is_stock if id.present? && is_stock && description_changed? || cmodel_name_changed? @@ -68,6 +71,7 @@ def set_is_stock end before_validation :set_manufacturer + def set_manufacturer return true unless mnfg_name.present? self.manufacturer_id = Manufacturer.friendly_id_find(mnfg_name) diff --git a/app/models/concerns/autocomplete_hashable.rb b/app/models/concerns/autocomplete_hashable.rb index a4e5e546f1..eec6a4399e 100644 --- a/app/models/concerns/autocomplete_hashable.rb +++ b/app/models/concerns/autocomplete_hashable.rb @@ -3,6 +3,6 @@ module AutocompleteHashable def autocomplete_result_hash hash = autocomplete_hash.dup - hash.merge(hash.delete('data')) + hash.merge(hash.delete("data")) end end diff --git a/app/models/concerns/bike_searchable.rb b/app/models/concerns/bike_searchable.rb index 64055414a3..37aebfe4de 100644 --- a/app/models/concerns/bike_searchable.rb +++ b/app/models/concerns/bike_searchable.rb @@ -1,5 +1,6 @@ module BikeSearchable extend ActiveSupport::Concern + module ClassMethods # searchable_interpreted_params returns the args for by all other public methods in this class # query_params: @@ -40,9 +41,9 @@ def selected_query_items_options(interpreted_params) items = [] items += [interpreted_params[:query]] if interpreted_params[:query].present? items += [interpreted_params[:manufacturer]].flatten.map { |id| Manufacturer.friendly_find(id) } - .compact.map(&:autocomplete_result_hash) if interpreted_params[:manufacturer] + .compact.map(&:autocomplete_result_hash) if interpreted_params[:manufacturer] items += interpreted_params[:colors].map { |id| Color.friendly_find(id) } - .compact.map(&:autocomplete_result_hash) if interpreted_params[:colors] + .compact.map(&:autocomplete_result_hash) if interpreted_params[:colors] items.flatten.compact end @@ -60,10 +61,9 @@ def non_serial_matches(interpreted_params) .where(interpreted_params[:manufacturer] ? { manufacturer_id: interpreted_params[:manufacturer] } : {}) end - def searchable_query_items_query(query_params) return { query: query_params[:query] } if query_params[:query].present? - query = query_params[:query_items] && query_params[:query_items].select { |i| !(/\A[cm]_/ =~ i) }.join(' ') + query = query_params[:query_items] && query_params[:query_items].select { |i| !(/\A[cm]_/ =~ i) }.join(" ") query.present? ? { query: query } : {} end @@ -95,7 +95,7 @@ def searchable_query_stolenness(query_params, ip) if query_params[:stolenness] && %w(all non).include?(query_params[:stolenness]) { stolenness: query_params[:stolenness] } else - extracted_searchable_proximity_hash(query_params, ip) || { stolenness: 'stolen' } + extracted_searchable_proximity_hash(query_params, ip) || { stolenness: "stolen" } end end @@ -103,22 +103,22 @@ def extracted_query_items_manufacturer_id(query_params) return query_params[:manufacturer] if query_params[:manufacturer].present? manufacturer_id = query_params[:query_items] && query_params[:query_items].select { |i| /\Am_/ =~ i } return nil unless manufacturer_id && manufacturer_id.any? - manufacturer_id.map { |i| i.gsub(/m_/, '').to_i } + manufacturer_id.map { |i| i.gsub(/m_/, "").to_i } end def extracted_query_items_color_ids(query_params) return query_params[:colors] if query_params[:colors].present? color_ids = query_params[:query_items] && query_params[:query_items].select { |i| /\Ac_/ =~ i } return nil unless color_ids && color_ids.any? - color_ids.map { |i| i.gsub(/c_/, '').to_i } + color_ids.map { |i| i.gsub(/c_/, "").to_i } end def extracted_searchable_proximity_hash(query_params, ip) - return false unless query_params[:stolenness] == 'proximity' + return false unless query_params[:stolenness] == "proximity" location = query_params[:location] return false unless location && !(location =~ /anywhere/i) distance = query_params[:distance] && query_params[:distance].to_i - if ['', 'ip', 'you'].include?(location.strip.downcase) + if ["", "ip", "you"].include?(location.strip.downcase) return false unless ip.present? location = Geocoder.search(ip) if defined?(location.first.data) && location.first.data.is_a?(Array) @@ -129,9 +129,9 @@ def extracted_searchable_proximity_hash(query_params, ip) return false if bounding_box.detect(&:nan?) # If we can't create a bounding box, skip { bounding_box: bounding_box, - stolenness: 'proximity', - location: location, - distance: (distance && distance > 0) ? distance : 100 + stolenness: "proximity", + location: location, + distance: (distance && distance > 0) ? distance : 100, } end @@ -140,7 +140,7 @@ def extracted_searchable_proximity_hash(query_params, ip) def search_matching_color_ids(color_id) return all unless color_id # So we can chain this if we don't have any colors - where('primary_frame_color_id=? OR secondary_frame_color_id=? OR tertiary_frame_color_id =?', color_id, color_id, color_id) + where("primary_frame_color_id=? OR secondary_frame_color_id=? OR tertiary_frame_color_id =?", color_id, color_id, color_id) end def search_matching_query(query) @@ -150,16 +150,16 @@ def search_matching_query(query) def search_matching_serial(interpreted_params) return all unless interpreted_params[:serial] # Note: @@ is postgres fulltext search - where('serial_normalized @@ ?', interpreted_params[:serial]) + where("serial_normalized @@ ?", interpreted_params[:serial]) end def search_matching_stolenness(interpreted_params) case interpreted_params[:stolenness] - when 'all' + when "all" all - when 'non' + when "non" where(stolen: false) - when 'proximity' + when "proximity" where(stolen: true).within_bounding_box(interpreted_params[:bounding_box]) else where(stolen: true) @@ -167,7 +167,7 @@ def search_matching_stolenness(interpreted_params) end def search_matching_close_serials(serial) - where('LEVENSHTEIN(serial_normalized, ?) < 3', serial) + where("LEVENSHTEIN(serial_normalized, ?) < 3", serial) end end end diff --git a/app/models/concerns/enumable.rb b/app/models/concerns/enumable.rb index 6751af88ff..6d6de8bab8 100644 --- a/app/models/concerns/enumable.rb +++ b/app/models/concerns/enumable.rb @@ -28,4 +28,4 @@ def friendly_find(str) def name self.class::NAMES[slug] end -end \ No newline at end of file +end diff --git a/app/models/concerns/friendly_name_findable.rb b/app/models/concerns/friendly_name_findable.rb index 5c70d80311..8ee42e44fd 100644 --- a/app/models/concerns/friendly_name_findable.rb +++ b/app/models/concerns/friendly_name_findable.rb @@ -1,10 +1,11 @@ module FriendlyNameFindable extend ActiveSupport::Concern + module ClassMethods def friendly_find(n) return nil if n.blank? return where(id: n).first if n.is_a?(Integer) || n.match(/\A\d*\z/).present? - where('lower(name) = ?', n.downcase.strip).first + where("lower(name) = ?", n.downcase.strip).first end def friendly_id_find(n) diff --git a/app/models/concerns/friendly_slug_findable.rb b/app/models/concerns/friendly_slug_findable.rb index ce0eb8309c..54151bf7da 100644 --- a/app/models/concerns/friendly_slug_findable.rb +++ b/app/models/concerns/friendly_slug_findable.rb @@ -1,10 +1,11 @@ module FriendlySlugFindable extend ActiveSupport::Concern + module ClassMethods def friendly_find(n) return nil if n.blank? return where(id: n).first if n.is_a?(Integer) || n.strip.match(/\A\d*\z/).present? - find_by_slug(Slugifyer.slugify(n)) || where('lower(name) = ?', n.downcase.strip).first + find_by_slug(Slugifyer.slugify(n)) || where("lower(name) = ?", n.downcase.strip).first end end diff --git a/app/models/country.rb b/app/models/country.rb index 3a77d221c5..543d36810f 100644 --- a/app/models/country.rb +++ b/app/models/country.rb @@ -20,6 +20,6 @@ def self.united_states end def self.valid_names - StatesAndCountries.countries.map{ |c| c[:name] } + StatesAndCountries.countries.map { |c| c[:name] } end end diff --git a/app/models/creation_state.rb b/app/models/creation_state.rb index 710b319913..4e7c6ea845 100644 --- a/app/models/creation_state.rb +++ b/app/models/creation_state.rb @@ -1,7 +1,7 @@ class CreationState < ActiveRecord::Base belongs_to :bike belongs_to :organization - belongs_to :creator, class_name: 'User' + belongs_to :creator, class_name: "User" belongs_to :bulk_import def self.origins @@ -15,12 +15,14 @@ def creation_description end before_validation :ensure_permitted_origin + def ensure_permitted_origin self.origin = nil unless self.class.origins.include?(origin) true end after_create :create_bike_organization + def create_bike_organization return true unless organization.present? BikeOrganization.where(bike_id: bike_id, organization_id: organization_id).first_or_create @@ -31,6 +33,7 @@ def create_bike_organization end after_save :set_reflexive_association + def set_reflexive_association # Just for the time being, to make migration easier b = Bike.unscoped.find(bike_id) diff --git a/app/models/ctype.rb b/app/models/ctype.rb index f647fbe109..ce77138827 100644 --- a/app/models/ctype.rb +++ b/app/models/ctype.rb @@ -12,14 +12,15 @@ class Ctype < ActiveRecord::Base has_many :components def self.other - where(name: 'other', has_multiple: false, cgroup_id: Cgroup.additional_parts.id).first_or_create + where(name: "other", has_multiple: false, cgroup_id: Cgroup.additional_parts.id).first_or_create end def self.unknown - where(name: 'unknown', has_multiple: false, cgroup_id: Cgroup.additional_parts.id).first_or_create + where(name: "unknown", has_multiple: false, cgroup_id: Cgroup.additional_parts.id).first_or_create end before_create :set_calculated_attributes + def set_calculated_attributes return true unless self.cgroup_name.present? self.cgroup_id = Cgroup.friendly_find(cgroup_name)&.id diff --git a/app/models/customer_contact.rb b/app/models/customer_contact.rb index a83f6ed653..01ba462c42 100644 --- a/app/models/customer_contact.rb +++ b/app/models/customer_contact.rb @@ -8,16 +8,15 @@ class CustomerContact < ActiveRecord::Base validates_presence_of :user_email serialize :info_hash - belongs_to :bike belongs_to :user - belongs_to :creator, class_name: 'User' + belongs_to :creator, class_name: "User" before_save :normalize_email_and_find_user + def normalize_email_and_find_user self.user_email = EmailNormalizer.normalize(user_email) self.user ||= User.fuzzy_confirmed_or_unconfirmed_email_find(user_email) true end - end diff --git a/app/models/cycle_type.rb b/app/models/cycle_type.rb index 91869f9f29..7a67d3a621 100644 --- a/app/models/cycle_type.rb +++ b/app/models/cycle_type.rb @@ -17,12 +17,12 @@ class CycleType 'cargo-trike': 12, 'cargo-trike-rear': 13, 'trail-behind': 14, - 'pedi-cab': 15 + 'pedi-cab': 15, }.freeze NAMES = { bike: "Bike", - tandem: "Tandem", + tandem: "Tandem", unicycle: "Unicycle", tricycle: "Tricycle", stroller: "Stroller", @@ -33,10 +33,10 @@ class CycleType "tall-bike": "Tall Bike", "penny-farthing": "Penny Farthing", "cargo-rear": "Cargo Bike (rear storage)", - "cargo-trike": "Cargo Tricycle (front storage)", + "cargo-trike": "Cargo Tricycle (front storage)", "cargo-trike-rear": "Cargo Tricycle (rear storage)", "trail-behind": "Trail behind (half bike)", - "pedi-cab": "Pedi Cab (rickshaw)" + "pedi-cab": "Pedi Cab (rickshaw)", }.freeze def initialize(slug) diff --git a/app/models/duplicate_bike_group.rb b/app/models/duplicate_bike_group.rb index 5d46435337..adeaeb2da9 100644 --- a/app/models/duplicate_bike_group.rb +++ b/app/models/duplicate_bike_group.rb @@ -5,12 +5,13 @@ class DuplicateBikeGroup < ActiveRecord::Base scope :unignored, -> { where(ignore: false) } before_save :update_added_bike_at + def update_added_bike_at self.added_bike_at ||= Time.now end def segment normalized_serial_segments && normalized_serial_segments.first && - normalized_serial_segments.first.segment || '' + normalized_serial_segments.first.segment || "" end end diff --git a/app/models/export.rb b/app/models/export.rb index 65b17a608f..e93bfd6ac0 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -34,16 +34,16 @@ def self.default_kind_options { stolen: { with_blacklist: false, - only_serials_and_police_reports: false + only_serials_and_police_reports: false, }, organization: { partial_registrations: false, start_at: nil, - end_at: nil + end_at: nil, }, manufacturer: { - frame_only: false - } + frame_only: false, + }, }.as_json.freeze end @@ -140,11 +140,11 @@ def end_at end def tmp_file - @tmp_file ||= Tempfile.new(["#{kind == 'organization' ? organization.slug : kind}_#{id}", ".#{file_format}"]) + @tmp_file ||= Tempfile.new(["#{kind == "organization" ? organization.slug : kind}_#{id}", ".#{file_format}"]) end def tmp_file_rows - `wc -l "#{tmp_file.path}"`.strip.split(' ')[0].to_i - 1 # Because we don't count header + `wc -l "#{tmp_file.path}"`.strip.split(" ")[0].to_i - 1 # Because we don't count header end def description diff --git a/app/models/feedback.rb b/app/models/feedback.rb index da6be394aa..4c61d3d734 100644 --- a/app/models/feedback.rb +++ b/app/models/feedback.rb @@ -6,6 +6,7 @@ class Feedback < ActiveRecord::Base attr_accessor :additional # spam block attribute after_create :notify_admins + def notify_admins return true if no_notification_types.include?(feedback_type) EmailFeedbackNotificationWorker.perform_async(id) @@ -32,6 +33,6 @@ def set_user_attrs def lead_type return nil unless feedback_type && feedback_type =~ /lead_for_/ - feedback_type.gsub(/lead_for_/, '').humanize + feedback_type.gsub(/lead_for_/, "").humanize end end diff --git a/app/models/frame_material.rb b/app/models/frame_material.rb index 05a7182aa4..13fa4db610 100644 --- a/app/models/frame_material.rb +++ b/app/models/frame_material.rb @@ -1,12 +1,12 @@ class FrameMaterial - include Enumable - + include Enumable + SLUGS = { organic: 4, composite: 3, titanium: 2, aluminum: 1, - steel: 0 + steel: 0, }.freeze NAMES = { @@ -14,7 +14,7 @@ class FrameMaterial composite: "Carbon or composite", organic: "Wood or organic material", steel: "Steel", - titanium: "Titanium" + titanium: "Titanium", }.freeze def initialize(slug) diff --git a/app/models/handlebar_type.rb b/app/models/handlebar_type.rb index 9766f98d66..f1a610604c 100644 --- a/app/models/handlebar_type.rb +++ b/app/models/handlebar_type.rb @@ -7,7 +7,7 @@ class HandlebarType rearward: 3, other: 2, bmx: 1, - flat: 0 + flat: 0, }.freeze NAMES = { @@ -16,7 +16,7 @@ class HandlebarType rearward: "Rear facing", other: "Not handlebars", bmx: "BMX style", - flat: "Flat or riser" + flat: "Flat or riser", }.freeze def initialize(slug) diff --git a/app/models/integration.rb b/app/models/integration.rb index 2861045e58..f0448a7026 100644 --- a/app/models/integration.rb +++ b/app/models/integration.rb @@ -2,7 +2,6 @@ class IntegrationAssociationError < StandardError end class Integration < ActiveRecord::Base - validates_presence_of :access_token validates_presence_of :information @@ -11,10 +10,11 @@ class Integration < ActiveRecord::Base belongs_to :user before_create :associate_with_user + def associate_with_user - self.provider_name ||= information['provider'] - if provider_name == 'facebook' || provider_name == 'strava' - update_or_create_user(email: information['info']['email'], name: information['info']['name']) + self.provider_name ||= information["provider"] + if provider_name == "facebook" || provider_name == "strava" + update_or_create_user(email: information["info"]["email"], name: information["info"]["name"]) end end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index dd736977aa..1b2414218c 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -75,6 +75,7 @@ def paid_feature_ids=(val) # This isn't super efficient, but whateves # So that we can read and write def start_at; subscription_start_at end def end_at; subscription_end_at end + def start_at=(val) self.subscription_start_at = TimeParser.parse(val, timezone) end @@ -101,7 +102,7 @@ def amount_paid_formatted end def discount_formatted - money_formatted(- (discount_cents || 0)) + money_formatted(-(discount_cents || 0)) end def previous_invoice diff --git a/app/models/listicle.rb b/app/models/listicle.rb index fc04055136..cc90435551 100644 --- a/app/models/listicle.rb +++ b/app/models/listicle.rb @@ -1,10 +1,11 @@ class Listicle < ActiveRecord::Base - belongs_to :blog + belongs_to :blog mount_uploader :image, ListicleImageUploader - default_scope { order('list_order ASC') } + default_scope { order("list_order ASC") } before_save :htmlize_content + def htmlize_content self.body_html = Kramdown::Document.new(body).to_html if body.present? self.image_credits_html = Kramdown::Document.new(image_credits).to_html if image_credits.present? diff --git a/app/models/location.rb b/app/models/location.rb index b7aef11f36..a83e6248bd 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -31,8 +31,8 @@ def address street, city, state.present? ? state.abbreviation : nil, - zipcode, - country.name + zipcode, + country.name, ].compact.reject(&:blank?).join(", ") end diff --git a/app/models/lock.rb b/app/models/lock.rb index b8a061346c..25a3b2cd12 100644 --- a/app/models/lock.rb +++ b/app/models/lock.rb @@ -14,5 +14,4 @@ def manufacturer_name self.manufacturer.name end end - end diff --git a/app/models/lock_type.rb b/app/models/lock_type.rb index ab9292e326..e3ed3ab04e 100644 --- a/app/models/lock_type.rb +++ b/app/models/lock_type.rb @@ -1,4 +1,3 @@ class LockType < ActiveRecord::Base include FriendlySlugFindable - end diff --git a/app/models/mail_snippet.rb b/app/models/mail_snippet.rb index 4046f8c05c..fa1209af1e 100644 --- a/app/models/mail_snippet.rb +++ b/app/models/mail_snippet.rb @@ -26,7 +26,7 @@ def self.organization_snippets footer: "Above <3 <3 <3 <3 Bike Index Team", partial: "Below \"Finish it\" button, in email \"Partial registration\"", security: "How to keep your bike safe, in email \"Finished registration\"", - abandoned_bike: "Geocoded abandoned bike email" + abandoned_bike: "Geocoded abandoned bike email", }.as_json end diff --git a/app/models/manufacturer.rb b/app/models/manufacturer.rb index 21fdda6e5a..006002c27a 100644 --- a/app/models/manufacturer.rb +++ b/app/models/manufacturer.rb @@ -44,11 +44,11 @@ def friendly_id_find(n) end def other - where(name: 'Other', frame_maker: true).first_or_create + where(name: "Other", frame_maker: true).first_or_create end def fill_stripped(n) - n.gsub!(/accell/i, '') if n.match(/accell/i).present? + n.gsub!(/accell/i, "") if n.match(/accell/i).present? Slugifyer.manufacturer(n) end @@ -77,22 +77,23 @@ def to_csv # Also, probably just a good idea in general def ensure_non_blocking_name return true unless name - errors.add(:name, 'Cannot be the same as a color name') if Color.pluck(:name).map(&:downcase).include?(name.strip.downcase) + errors.add(:name, "Cannot be the same as a color name") if Color.pluck(:name).map(&:downcase).include?(name.strip.downcase) end before_save :set_slug, :set_website_and_logo_source + def set_slug self.slug = Slugifyer.manufacturer(name) end def set_website_and_logo_source self.website = website.present? ? Urlifyer.urlify(website) : nil - self.logo_source = logo.present? ? (logo_source || 'manual') : nil + self.logo_source = logo.present? ? (logo_source || "manual") : nil true end def autocomplete_hash_category - frame_maker ? 'frame_mnfg' : 'mnfg' + frame_maker ? "frame_mnfg" : "mnfg" end def autocomplete_hash_priority @@ -110,8 +111,8 @@ def autocomplete_hash data: { slug: slug, priority: autocomplete_hash_priority, - search_id: search_id - } + search_id: search_id, + }, }.as_json end diff --git a/app/models/membership.rb b/app/models/membership.rb index c9f360b42f..f5fa53eda1 100644 --- a/app/models/membership.rb +++ b/app/models/membership.rb @@ -6,7 +6,7 @@ class Membership < ActiveRecord::Base belongs_to :user belongs_to :organization - validates_presence_of :role, message: 'How the hell did you manage to not choose a role? You have to choose one.' + validates_presence_of :role, message: "How the hell did you manage to not choose a role? You have to choose one." validates_presence_of :organization, message: "Sorry, organization doesn't exist" validates_presence_of :user, message: "We're sorry, that user hasn't yet signed up for Bike Index. Please ask them to before adding them to your organization" @@ -17,7 +17,7 @@ def self.membership_types end def admin? - role == 'admin' + role == "admin" end def update_relationships diff --git a/app/models/normalized_serial_segment.rb b/app/models/normalized_serial_segment.rb index c0e1da9a9a..7835f68a87 100644 --- a/app/models/normalized_serial_segment.rb +++ b/app/models/normalized_serial_segment.rb @@ -1,5 +1,4 @@ class NormalizedSerialSegment < ActiveRecord::Base - belongs_to :bike validates_presence_of :bike_id validates_presence_of :segment diff --git a/app/models/organization.rb b/app/models/organization.rb index 8bd7196001..fd62a4afab 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -8,14 +8,14 @@ class Organization < ActiveRecord::Base bike_manufacturer: 4, software: 5, property_management: 6, - other: 7 + other: 7, }.freeze acts_as_paranoid mount_uploader :avatar, AvatarUploader belongs_to :parent_organization, class_name: "Organization" - belongs_to :auto_user, class_name: 'User' + belongs_to :auto_user, class_name: "User" has_many :recovered_records, through: :bikes has_many :locations, inverse_of: :organization, dependent: :destroy @@ -75,7 +75,7 @@ def self.admin_text_search(n) match_cols = %w(organizations.name organizations.short_name locations.name locations.city) joins("LEFT OUTER JOIN locations AS locations ON organizations.id = locations.organization_id") .distinct - .where(match_cols.map { |col| "#{col} ILIKE :str" }.join(' OR '), { str: str }) + .where(match_cols.map { |col| "#{col} ILIKE :str" }.join(" OR "), { str: str }) end def self.with_paid_feature_slugs(slugs) @@ -99,7 +99,7 @@ def mail_snippet_body(type) def message_kinds # Matches organization_message kinds [ paid_for?("geolocated_messages") ? "geolocated_messages" : nil, - paid_for?("abandoned_bike_messages") ? "abandoned_bike_messages" : nil + paid_for?("abandoned_bike_messages") ? "abandoned_bike_messages" : nil, ].compact end @@ -154,10 +154,10 @@ def set_calculated_attributes self.kind ||= "other" # We need to always have a kind specified - generally we catch this, but just in case... # For now, just use them. However - nesting organizations probably need slightly modified paid_feature slugs self.paid_feature_slugs = current_invoices.map(&:feature_slugs).flatten - new_slug = Slugifyer.slugify(self.short_name).gsub(/\Aadmin/, '') + new_slug = Slugifyer.slugify(self.short_name).gsub(/\Aadmin/, "") if new_slug != slug # If the organization exists, don't invalidate because of it's own slug - orgs = id.present? ? Organization.where('id != ?', id) : Organization.all + orgs = id.present? ? Organization.where("id != ?", id) : Organization.all while orgs.where(slug: new_slug).exists? i = i.present? ? i + 1 : 2 new_slug = "#{new_slug}-#{i}" @@ -172,11 +172,12 @@ def set_calculated_attributes def ensure_auto_user return true if auto_user.present? - self.embedable_user_email = users.first && users.first.email || ENV['AUTO_ORG_MEMBER'] + self.embedable_user_email = users.first && users.first.email || ENV["AUTO_ORG_MEMBER"] save end def child_ids; child_organizations.pluck(:id) end + # Parent invoice serves as invoice def current_invoices; parent_organization.present? ? parent_organization.current_invoices : invoices.active end @@ -194,7 +195,7 @@ def map_focus_coordinates location = locations&.first { latitude: location&.latitude || 37.7870322, - longitude: location&.longitude || -122.4061122 + longitude: location&.longitude || -122.4061122, } end @@ -202,8 +203,8 @@ def set_auto_user if embedable_user_email.present? u = User.fuzzy_email_find(embedable_user_email) self.auto_user_id = u.id if u && u.member_of?(self) - if auto_user_id.blank? && embedable_user_email == ENV['AUTO_ORG_MEMBER'] - Membership.create(user_id: u.id, organization_id: id, role: 'member') + if auto_user_id.blank? && embedable_user_email == ENV["AUTO_ORG_MEMBER"] + Membership.create(user_id: u.id, organization_id: id, role: "member") self.auto_user_id = u.id end elsif auto_user_id.blank? diff --git a/app/models/organization_invitation.rb b/app/models/organization_invitation.rb index 35b040c381..87129ec0fa 100644 --- a/app/models/organization_invitation.rb +++ b/app/models/organization_invitation.rb @@ -1,6 +1,4 @@ class OrganizationInvitation < ActiveRecord::Base - - attr_accessor :admin_org_id # We are making people fill in names. That way, everyone who is at an @@ -11,18 +9,20 @@ class OrganizationInvitation < ActiveRecord::Base validates_presence_of :inviter, :organization_id, :invitee_email, :membership_role belongs_to :organization - belongs_to :inviter, class_name: 'User', foreign_key: :inviter_id - belongs_to :invitee, class_name: 'User', foreign_key: :invitee_id + belongs_to :inviter, class_name: "User", foreign_key: :inviter_id + belongs_to :invitee, class_name: "User", foreign_key: :invitee_id default_scope { order(:created_at) } scope :unclaimed, -> { where(redeemed: nil) } after_create :enqueue_notification_job + def enqueue_notification_job EmailOrganizationInvitationWorker.perform_async(id) end after_create :if_user_exists_assign + def if_user_exists_assign user = User.fuzzy_email_find(self.invitee_email) if user @@ -31,11 +31,13 @@ def if_user_exists_assign end before_save :normalize_email + def normalize_email self.invitee_email = EmailNormalizer.normalize(invitee_email) end after_create :update_organization_invitation_counts + def update_organization_invitation_counts org = organization if org.available_invitation_count < 1 @@ -67,5 +69,4 @@ def assign_to(user) end create_membership end - end diff --git a/app/models/other_listing.rb b/app/models/other_listing.rb index d1cd1a2723..c323ef1324 100644 --- a/app/models/other_listing.rb +++ b/app/models/other_listing.rb @@ -1,8 +1,5 @@ class OtherListing < ActiveRecord::Base - - belongs_to :bike validates_presence_of :bike_id validates_presence_of :url - end diff --git a/app/models/ownership.rb b/app/models/ownership.rb index 743e0b3f15..5af9a74a9a 100644 --- a/app/models/ownership.rb +++ b/app/models/ownership.rb @@ -1,6 +1,4 @@ class Ownership < ActiveRecord::Base - - attr_accessor :creator_email, :user_email validates_presence_of :owner_email @@ -9,12 +7,13 @@ class Ownership < ActiveRecord::Base belongs_to :bike, touch: true belongs_to :user, touch: true - belongs_to :creator, class_name: 'User' + belongs_to :creator, class_name: "User" default_scope { order(:created_at) } scope :current, -> { where(current: true) } before_save :normalize_email + def normalize_email self.owner_email = EmailNormalizer.normalize(owner_email) end diff --git a/app/models/paint.rb b/app/models/paint.rb index 20ece7e36d..91bcc5d4b3 100644 --- a/app/models/paint.rb +++ b/app/models/paint.rb @@ -7,14 +7,15 @@ class Paint < ActiveRecord::Base belongs_to :manufacturer has_many :bikes - belongs_to :secondary_color, class_name: 'Color' - belongs_to :tertiary_color, class_name: 'Color' + belongs_to :secondary_color, class_name: "Color" + belongs_to :tertiary_color, class_name: "Color" - scope :official, -> { where('manufacturer_id IS NOT NULL') } + scope :official, -> { where("manufacturer_id IS NOT NULL") } before_save { |p| p.name = p.name.downcase.strip } before_create :associate_colors + def associate_colors color_ids = {} Color.all.each do |color| @@ -33,67 +34,67 @@ def associate_colors end def paint_name_parser(paint_str) - paint_str.gsub!(/[\\\/\"\-\()\?,\&\+\;\.]/, ' ') + paint_str.gsub!(/[\\\/\"\-\()\?,\&\+\;\.]/, " ") # RAL colors. See wikipedia table for rough groupings. Many of the reds are pink, greys are brown, etc. by whatever paint_str.gsub!(/ral\s?([1-8])\d{3}/) { case Regexp.last_match[1].to_i - when 1 then 'yellow' - when 2 then 'orange' - when 3 then 'red' - when 4 then 'purple' - when 5 then 'blue' - when 6 then 'green' - when 7 then 'silver' - when 8 then 'brown' + when 1 then "yellow" + when 2 then "orange" + when 3 then "red" + when 4 then "purple" + when 5 then "blue" + when 6 then "green" + when 7 then "silver" + when 8 then "brown" end } - paint_str.gsub!(/bluish/, 'blue') - paint_str.gsub!(/reddish/, 'red') - paint_str.gsub!(/ish( |\Z)/, ' ') + paint_str.gsub!(/bluish/, "blue") + paint_str.gsub!(/reddish/, "red") + paint_str.gsub!(/ish( |\Z)/, " ") paint_str.gsub!(/steel (blue|grey|gray|black)/, '\1') - paint_str.gsub!(/steel/, 'silver') - paint_str.gsub!(/maroon/, 'red') - paint_str.gsub!(/(\A|\s)rd(\s|\Z)/, ' red ') - paint_str.gsub!(/pearl/, 'white') - paint_str.gsub!(/ivory/, 'white') - paint_str.gsub!(/(cream|creme)/, 'white') - paint_str.gsub!(/champagne/, 'white') - paint_str.gsub!(/(\A|\s)wht?(\s|\Z)/, ' white ') - paint_str.gsub!(/beige/, 'white') - paint_str.gsub!(/(\A|\s)bl?k(\s|\Z)/, ' black ') - paint_str.gsub!(/carbon/, 'black') - paint_str.gsub!(/composite/, 'black') - paint_str.gsub!(/celeste/, 'blue') - paint_str.gsub!(/(\A|\s)blu(\s|\Z)/, ' blue ') - paint_str.gsub!(/navy/, 'blue') - paint_str.gsub!(/turquoise/, 'teal') - paint_str.gsub!(/emerald/, 'green') - paint_str.gsub!(/titanium/, 'silver') - paint_str.gsub!(/aluminum/, 'silver') - paint_str.gsub!(/brushed/, 'silver') - paint_str.gsub!(/clear\s?coat/, 'silver') - paint_str.gsub!(/(\A|\s)ti(\s|\Z)/, ' silver ') - paint_str.gsub!(/(\A|\s)tan(\s|\Z)/, ' brown ') - paint_str.gsub!(/(\A|\s)taupe(\s|\Z)/, ' brown ') - paint_str.gsub!(/wood/, 'brown') - paint_str.gsub!(/copper/, 'brown') - paint_str.gsub!(/brass/, 'yellow') - paint_str.gsub!(/bronze/, 'yellow') - paint_str.gsub!(/mustard/, 'yellow') - paint_str.gsub!(/golde?n?/, 'yellow') - paint_str.gsub!(/(\A|\s)crcl(\s|\Z)/, ' silver ') # bad abbreviation of charcoal - paint_str.gsub!(/gunmetal/, 'silver') - paint_str.gsub!(/char(coa?l)?/, 'silver') - paint_str.gsub!(/graphite/, 'silver') - paint_str.gsub!(/platinum/, 'silver') - paint_str.gsub!(/nickel/, 'silver') - paint_str.gsub!(/chrome/, 'silver') - paint_str.gsub!(/sli?ve?r?/, 'silver') - paint_str.gsub!(/quicksilver/, 'silver') - paint_str.gsub!(/gr(a|e)y/, ' silver ') - paint_str.gsub!(/burgu?a?ndy/, 'red') + paint_str.gsub!(/steel/, "silver") + paint_str.gsub!(/maroon/, "red") + paint_str.gsub!(/(\A|\s)rd(\s|\Z)/, " red ") + paint_str.gsub!(/pearl/, "white") + paint_str.gsub!(/ivory/, "white") + paint_str.gsub!(/(cream|creme)/, "white") + paint_str.gsub!(/champagne/, "white") + paint_str.gsub!(/(\A|\s)wht?(\s|\Z)/, " white ") + paint_str.gsub!(/beige/, "white") + paint_str.gsub!(/(\A|\s)bl?k(\s|\Z)/, " black ") + paint_str.gsub!(/carbon/, "black") + paint_str.gsub!(/composite/, "black") + paint_str.gsub!(/celeste/, "blue") + paint_str.gsub!(/(\A|\s)blu(\s|\Z)/, " blue ") + paint_str.gsub!(/navy/, "blue") + paint_str.gsub!(/turquoise/, "teal") + paint_str.gsub!(/emerald/, "green") + paint_str.gsub!(/titanium/, "silver") + paint_str.gsub!(/aluminum/, "silver") + paint_str.gsub!(/brushed/, "silver") + paint_str.gsub!(/clear\s?coat/, "silver") + paint_str.gsub!(/(\A|\s)ti(\s|\Z)/, " silver ") + paint_str.gsub!(/(\A|\s)tan(\s|\Z)/, " brown ") + paint_str.gsub!(/(\A|\s)taupe(\s|\Z)/, " brown ") + paint_str.gsub!(/wood/, "brown") + paint_str.gsub!(/copper/, "brown") + paint_str.gsub!(/brass/, "yellow") + paint_str.gsub!(/bronze/, "yellow") + paint_str.gsub!(/mustard/, "yellow") + paint_str.gsub!(/golde?n?/, "yellow") + paint_str.gsub!(/(\A|\s)crcl(\s|\Z)/, " silver ") # bad abbreviation of charcoal + paint_str.gsub!(/gunmetal/, "silver") + paint_str.gsub!(/char(coa?l)?/, "silver") + paint_str.gsub!(/graphite/, "silver") + paint_str.gsub!(/platinum/, "silver") + paint_str.gsub!(/nickel/, "silver") + paint_str.gsub!(/chrome/, "silver") + paint_str.gsub!(/sli?ve?r?/, "silver") + paint_str.gsub!(/quicksilver/, "silver") + paint_str.gsub!(/gr(a|e)y/, " silver ") + paint_str.gsub!(/burgu?a?ndy/, "red") paint_str end end diff --git a/app/models/propulsion_type.rb b/app/models/propulsion_type.rb index 9ca3eac431..398d2a0125 100644 --- a/app/models/propulsion_type.rb +++ b/app/models/propulsion_type.rb @@ -9,7 +9,7 @@ class PropulsionType "electric-assist": 4, "electric-throttle": 5, gas: 6, - "other-style": 7 + "other-style": 7, }.freeze NAMES = { @@ -20,7 +20,7 @@ class PropulsionType "electric-assist": "Electric Assist", "electric-throttle": "Electric throttle", gas: "Gas", - "other-style": "Other style" + "other-style": "Other style", }.freeze def initialize(slug) diff --git a/app/models/public_image.rb b/app/models/public_image.rb index 031601fb41..a65cf858f1 100644 --- a/app/models/public_image.rb +++ b/app/models/public_image.rb @@ -19,7 +19,7 @@ def default_name def set_calculated_attributes self.name = (name || default_name).truncate(100) return true if listing_order && listing_order > 0 - self.listing_order = imageable&.public_images&.length || 0 + self.listing_order = imageable&.public_images&.length || 0 end def enqueue_after_commit_jobs diff --git a/app/models/recovery_display.rb b/app/models/recovery_display.rb index 1627c5c5b0..c6734abfa5 100644 --- a/app/models/recovery_display.rb +++ b/app/models/recovery_display.rb @@ -4,22 +4,24 @@ class RecoveryDisplay < ActiveRecord::Base process_in_background :image, CarrierWaveProcessWorker belongs_to :stolen_record - default_scope { order('date_recovered desc') } + default_scope { order("date_recovered desc") } attr_accessor :date_input before_validation :set_time + def set_time if date_input.present? - self.date_recovered = DateTime.strptime("#{date_input} 06", '%m-%d-%Y %H') + self.date_recovered = DateTime.strptime("#{date_input} 06", "%m-%d-%Y %H") end self.date_recovered = Time.now unless date_recovered.present? end validate :quote_not_too_long + def quote_not_too_long return true if quote.blank? || quote.length < 301 - errors.add :base, 'That quote is too long. Please shorten it to be less than 300 characters' + errors.add :base, "That quote is too long. Please shorten it to be less than 300 characters" end def from_stolen_record(sr_id) diff --git a/app/models/state.rb b/app/models/state.rb index 4ad9867ff1..5e4c8736d0 100644 --- a/app/models/state.rb +++ b/app/models/state.rb @@ -18,6 +18,6 @@ def self.fuzzy_abbr_find(str) end def self.valid_names - StatesAndCountries.states.map{ |s| s[:name] } + StatesAndCountries.states.map { |s| s[:name] } end end diff --git a/app/models/stolen_notification.rb b/app/models/stolen_notification.rb index c9b077dea7..ead14be860 100644 --- a/app/models/stolen_notification.rb +++ b/app/models/stolen_notification.rb @@ -1,13 +1,14 @@ class StolenNotification < ActiveRecord::Base belongs_to :bike - belongs_to :sender, class_name: 'User', foreign_key: :sender_id - belongs_to :receiver, class_name: 'User', foreign_key: :receiver_id + belongs_to :sender, class_name: "User", foreign_key: :sender_id + belongs_to :receiver, class_name: "User", foreign_key: :receiver_id validates_presence_of :sender, :bike, :message before_validation :set_calculated_attributes after_create :notify_receiver + def notify_receiver EmailStolenNotificationWorker.perform_async(id) end diff --git a/app/models/stolen_record.rb b/app/models/stolen_record.rb index b655aedd92..7438260d11 100644 --- a/app/models/stolen_record.rb +++ b/app/models/stolen_record.rb @@ -4,7 +4,7 @@ class StolenRecord < ActiveRecord::Base attr_accessor :timezone # Just to provide a backup and permit assignment - def self.old_attr_accessible + def self.old_attr_accessible # recovery_tweet, recovery_share # We edit this in the admin panel %w(police_report_number police_report_department locking_description lock_defeat_description timezone date_stolen bike creation_organization_id country_id state_id street zipcode city latitude @@ -15,22 +15,22 @@ def self.old_attr_accessible end belongs_to :bike - has_one :current_bike, class_name: 'Bike', foreign_key: :current_stolen_record_id + has_one :current_bike, class_name: "Bike", foreign_key: :current_stolen_record_id has_one :recovery_display belongs_to :country belongs_to :state - belongs_to :creation_organization, class_name: 'Organization' + belongs_to :creation_organization, class_name: "Organization" validates_presence_of :bike validates_presence_of :date_stolen default_scope { where(current: true) } scope :approveds, -> { where(approved: true) } - scope :approveds_with_reports, -> { approveds.where('police_report_number IS NOT NULL').where('police_report_department IS NOT NULL') } - scope :not_tsved, -> { where('tsved_at IS NULL') } + scope :approveds_with_reports, -> { approveds.where("police_report_number IS NOT NULL").where("police_report_department IS NOT NULL") } + scope :not_tsved, -> { where("tsved_at IS NULL") } scope :tsv_today, -> { where("tsved_at IS NULL OR tsved_at >= '#{Time.now.beginning_of_day}'") } - scope :recovered, -> { unscoped.where(current: false).order('date_recovered desc') } + scope :recovered, -> { unscoped.where(current: false).order("date_recovered desc") } scope :displayable, -> { recovered.where(can_share_recovery: true) } scope :recovery_unposted, -> { unscoped.where(current: false, recovery_posted: false) } @@ -58,19 +58,19 @@ def address(skip_default_country: false, override_show_address: false) city, state&.abbreviation, zipcode, - country_string - ].reject(&:blank?).join(', ') + country_string, + ].reject(&:blank?).join(", ") end def address_short # Doesn't include street [city, (state && state.abbreviation), - zipcode].reject(&:blank?).join(',') + zipcode].reject(&:blank?).join(",") end def self.locking_description - ['U-lock', 'Two U-locks', 'U-lock and cable', 'Chain with padlock', - 'Cable lock', 'Heavy duty bicycle security chain', 'Not locked', 'Other'].freeze + ["U-lock", "Two U-locks", "U-lock and cable", "Chain with padlock", + "Cable lock", "Heavy duty bicycle security chain", "Not locked", "Other"].freeze end def self.locking_description_select @@ -79,12 +79,12 @@ def self.locking_description_select def self.locking_defeat_description [ - 'Lock was cut, and left at the scene.', - 'Lock was opened, and left unharmed at the scene.', - 'Lock is missing, along with the bike.', - 'Object that bike was locked to was broken, removed, or otherwise compromised.', - 'Other situation, please describe below.', - 'Bike was not locked' + "Lock was cut, and left at the scene.", + "Lock was opened, and left unharmed at the scene.", + "Lock is missing, along with the bike.", + "Object that bike was locked to was broken, removed, or otherwise compromised.", + "Other situation, please describe below.", + "Bike was not locked", ] end @@ -93,6 +93,7 @@ def self.locking_defeat_description_select end before_save :set_phone, :fix_date, :titleize_city, :update_tsved_at + def set_phone self.phone = Phonifyer.phonify(phone) if phone self.secondary_phone = Phonifyer.phonify(secondary_phone) if secondary_phone @@ -101,7 +102,7 @@ def set_phone def fix_date year = date_stolen.year if date_stolen.year < (Time.now - 100.years).year - decade = year.to_s.chars.last(2).join('') + decade = year.to_s.chars.last(2).join("") corrected = date_stolen.change(year: "20#{decade}".to_i) self.date_stolen = corrected end @@ -113,7 +114,7 @@ def fix_date def titleize_city if city.present? - self.city = city.gsub('USA', '').gsub(/,?(,|\s)[A-Z]+\s?++\z/, '') + self.city = city.gsub("USA", "").gsub(/,?(,|\s)[A-Z]+\s?++\z/, "") self.city = city.strip.titleize end true @@ -125,15 +126,15 @@ def update_tsved_at end def tsv_col(i) - return '' unless i.present? - i.gsub(/\\?(\t|\\t)+/i, ' ').gsub(/\\?(\r|\\r)+/i, ' ') - .gsub(/\\?(\n|\\n)+/i, ' ').gsub(/\\?\\?('|")+/, ' ') + return "" unless i.present? + i.gsub(/\\?(\t|\\t)+/i, " ").gsub(/\\?(\r|\\r)+/i, " ") + .gsub(/\\?(\n|\\n)+/i, " ").gsub(/\\?\\?('|")+/, " ") end def tsv_row(with_article = true, with_stolen_locations: false) b = bike - return '' unless b.present? - row = '' + return "" unless b.present? + row = "" if with_stolen_locations row << "#{tsv_col(city)}\t#{tsv_col(state && state.abbreviation)}\t" end @@ -141,7 +142,7 @@ def tsv_row(with_article = true, with_stolen_locations: false) row << "\t" row << tsv_col(b.frame_model) row << "\t" - row << tsv_col(b.serial) unless b.serial == 'absent' + row << tsv_col(b.serial) unless b.serial == "absent" row << "\t" row << tsv_col(b.frame_colors.to_sentence) row << tsv_col(b.description) @@ -149,13 +150,13 @@ def tsv_row(with_article = true, with_stolen_locations: false) row << " Stolen from: #{tsv_col(address)}" row << "\t" row << "Article\t" if with_article - row << date_stolen.strftime('%Y-%m-%d') + row << date_stolen.strftime("%Y-%m-%d") row << "\t" row << tsv_col(police_report_number) row << "\t" row << tsv_col(police_report_department) row << "\t\t" - row << "#{ENV['BASE_URL']}/bikes/#{b.id}\n" + row << "#{ENV["BASE_URL"]}/bikes/#{b.id}\n" row end diff --git a/app/models/tweet.rb b/app/models/tweet.rb index b7b5a93263..3c6fe1c41f 100644 --- a/app/models/tweet.rb +++ b/app/models/tweet.rb @@ -18,10 +18,10 @@ def self.friendly_find(id) def self.auto_link_text(text) text.gsub /@([^\s])*/ do username = Regexp.last_match[0] - "#{username}" + "#{username}" end.gsub /#([^\s])*/ do hashtag = Regexp.last_match[0] - "#{hashtag}" + "#{hashtag}" end end @@ -37,8 +37,8 @@ def ensure_valid_alignment end def set_body_from_response - return true unless body_html.blank? && twitter_response && twitter_response['text'].present? - self.body_html = self.class.auto_link_text(twitter_response['text']) + return true unless body_html.blank? && twitter_response && twitter_response["text"].present? + self.body_html = self.class.auto_link_text(twitter_response["text"]) end def trh @@ -46,19 +46,19 @@ def trh end def tweeted_at - Time.parse(trh['created_at']) + Time.parse(trh["created_at"]) end def tweetor - trh['user'] && trh['user']['screen_name'] + trh["user"] && trh["user"]["screen_name"] end def tweetor_avatar - trh['user'] && trh['user']['profile_image_url_https'] + trh["user"] && trh["user"]["profile_image_url_https"] end def tweetor_name - trh['user'] && trh['user']['name'] + trh["user"] && trh["user"]["name"] end def tweetor_link diff --git a/app/models/user.rb b/app/models/user.rb index f96ad14b41..25a1d5f966 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,28 +10,28 @@ class User < ActiveRecord::Base mount_uploader :avatar, AvatarUploader has_many :payments - has_many :subscriptions, -> { subscription }, class_name: 'Payment' + has_many :subscriptions, -> { subscription }, class_name: "Payment" has_many :memberships, dependent: :destroy - has_many :organization_embeds, class_name: 'Organization', foreign_key: :auto_user_id + has_many :organization_embeds, class_name: "Organization", foreign_key: :auto_user_id has_many :organizations, through: :memberships has_many :ownerships, dependent: :destroy - has_many :current_ownerships, -> { current }, class_name: 'Ownership' + has_many :current_ownerships, -> { current }, class_name: "Ownership" has_many :owned_bikes, through: :ownerships, source: :bike has_many :currently_owned_bikes, through: :current_ownerships, source: :bike - has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner + has_many :oauth_applications, class_name: "Doorkeeper::Application", as: :owner has_many :integrations, dependent: :destroy has_many :creation_states, inverse_of: :creator, foreign_key: :creator_id - has_many :created_ownerships, class_name: 'Ownership', inverse_of: :creator, foreign_key: :creator_id - has_many :created_bikes, class_name: 'Bike', inverse_of: :creator, foreign_key: :creator_id + has_many :created_ownerships, class_name: "Ownership", inverse_of: :creator, foreign_key: :creator_id + has_many :created_bikes, class_name: "Bike", inverse_of: :creator, foreign_key: :creator_id has_many :locks, dependent: :destroy has_many :user_emails, dependent: :destroy - has_many :sent_stolen_notifications, class_name: 'StolenNotification', foreign_key: :sender_id - has_many :received_stolen_notifications, class_name: 'StolenNotification', foreign_key: :receiver_id + has_many :sent_stolen_notifications, class_name: "StolenNotification", foreign_key: :sender_id + has_many :received_stolen_notifications, class_name: "StolenNotification", foreign_key: :receiver_id - has_many :organization_invitations, class_name: 'OrganizationInvitation', inverse_of: :inviter - has_many :organization_invitations, class_name: 'OrganizationInvitation', inverse_of: :invitee + has_many :organization_invitations, class_name: "OrganizationInvitation", inverse_of: :inviter + has_many :organization_invitations, class_name: "OrganizationInvitation", inverse_of: :invitee belongs_to :state belongs_to :country @@ -44,14 +44,14 @@ class User < ActiveRecord::Base presence: true, length: { within: 6..100 }, on: :create - validates_format_of :password, with: /\A.*(?=.*[a-z]).*\Z/i, message: 'must contain at least one letter', on: :create + validates_format_of :password, with: /\A.*(?=.*[a-z]).*\Z/i, message: "must contain at least one letter", on: :create - validates :password, + validates :password, confirmation: true, length: { within: 6..100 }, allow_blank: true, on: :update - validates_format_of :password, with: /\A.*(?=.*[a-z]).*\Z/i, message: 'must contain at least one letter', on: :update, allow_blank: true + validates_format_of :password, with: /\A.*(?=.*[a-z]).*\Z/i, message: "must contain at least one letter", on: :update, allow_blank: true validates_presence_of :email validates_uniqueness_of :email, case_sensitive: false @@ -65,10 +65,10 @@ class User < ActiveRecord::Base geocoded_by :address after_validation :geocode, if: ->(obj) do - !skip_geocode && - (obj.city.present? || obj.zipcode.present? || obj.street.present?) && - (obj.city_changed? || obj.zipcode_changed? || obj.street_changed?) - end + !skip_geocode && + (obj.city.present? || obj.zipcode.present? || obj.street.present?) && + (obj.city_changed? || obj.zipcode_changed? || obj.street_changed?) + end class << self def fuzzy_email_find(email) @@ -91,7 +91,7 @@ def friendly_id_find(n) def admin_text_search(n) search_str = "%#{n.strip}%" (where("name ILIKE ? OR email ILIKE ?", search_str, search_str) + - joins(:user_emails).where("user_emails.email ILIKE ?", search_str)).uniq + joins(:user_emails).where("user_emails.email ILIKE ?", search_str)).uniq end end @@ -104,10 +104,11 @@ def secondary_emails end validate :ensure_unique_email + def ensure_unique_email return true unless self.class.fuzzy_confirmed_or_unconfirmed_email_find(email) return true if id.present? # Because existing users shouldn't see this error - errors.add(:email, 'That email is already signed up on Bike Index.') + errors.add(:email, "That email is already signed up on Bike Index.") end def confirmed?; confirmed end @@ -142,16 +143,16 @@ def send_unstolen_notifications? end def reset_token_time - t = password_reset_token && password_reset_token.split('-')[0] + t = password_reset_token && password_reset_token.split("-")[0] t = (t.present? && t.to_i > 1427848192) ? t.to_i : 1364777722 Time.at(t) end def reset_token_expired? - reset_token_time < (Time.now - 1.hours) + reset_token_time < (Time.now - 1.hours) end - def set_password_reset_token(t=Time.now.to_i) + def set_password_reset_token(t = Time.now.to_i) self.password_reset_token = "#{t}-" + Digest::MD5.hexdigest("#{SecureRandom.hex(10)}-#{DateTime.now}") self.save end @@ -178,7 +179,7 @@ def confirm(token) true end end - + def role(organization) m = Membership.where(user_id: id, organization_id: organization.id).first m && m.role @@ -191,9 +192,9 @@ def member_of?(organization) def admin_of?(organization) return false unless organization.present? - Membership.where(user_id: id, organization_id: organization.id, role: 'admin').present? || superuser? + Membership.where(user_id: id, organization_id: organization.id, role: "admin").present? || superuser? end - + def has_membership? memberships.any? end @@ -215,22 +216,22 @@ def partner_sign_up partner_data && partner_data["sign_up"].present? ? partner_data["sign_up"] : nil end - def bikes(user_hidden=true) + def bikes(user_hidden = true) Bike.unscoped - .includes(:tertiary_frame_color, :secondary_frame_color, :primary_frame_color, :current_stolen_record) - .where(id: bike_ids(user_hidden)).reorder(:created_at) + .includes(:tertiary_frame_color, :secondary_frame_color, :primary_frame_color, :current_stolen_record) + .where(id: bike_ids(user_hidden)).reorder(:created_at) end def rough_approx_bikes # Rough fix for users with large numbers of bikes Bike.includes(:ownerships).where(ownerships: { current: true, user_id: id }).reorder(:created_at) end - def bike_ids(user_hidden=true) + def bike_ids(user_hidden = true) ows = ownerships.includes(:bike).where(example: false, current: true) if user_hidden - ows = ows.map{ |o| o.bike_id if o.user_hidden || o.bike } + ows = ows.map { |o| o.bike_id if o.user_hidden || o.bike } else - ows = ows.map{ |o| o.bike_id if o.bike } + ows = ows.map { |o| o.bike_id if o.bike } end ows.reject(&:blank?) end @@ -270,7 +271,7 @@ def mb_link_title end def normalize_attributes - self.phone = Phonifyer.phonify(phone) if phone + self.phone = Phonifyer.phonify(phone) if phone self.username = Slugifyer.slugify(username) if username self.email = EmailNormalizer.normalize(email) end @@ -293,11 +294,10 @@ def address(skip_default_country: false) city, (state&.abbreviation), zipcode, - country_string - ].reject(&:blank?).join(', ') + country_string, + ].reject(&:blank?).join(", ") end - def generate_auth_token begin self.auth_token = SecureRandom.urlsafe_base64 + "t#{Time.now.to_i}" diff --git a/app/models/user_email.rb b/app/models/user_email.rb index 717a08a044..7324b9aa00 100644 --- a/app/models/user_email.rb +++ b/app/models/user_email.rb @@ -1,12 +1,13 @@ class UserEmail < ActiveRecord::Base belongs_to :user, touch: true - belongs_to :old_user, class_name: 'User', touch: true + belongs_to :old_user, class_name: "User", touch: true validates_presence_of :user_id, :email - scope :confirmed, -> { where('confirmation_token IS NULL') } - scope :unconfirmed, -> { where('confirmation_token IS NOT NULL') } + scope :confirmed, -> { where("confirmation_token IS NULL") } + scope :unconfirmed, -> { where("confirmation_token IS NOT NULL") } before_validation :normalize_email + def normalize_email self.email = EmailNormalizer.normalize(email) end @@ -17,7 +18,7 @@ def self.create_confirmed_primary_email(user) end def self.add_emails_for_user_id(user_id, email_list) - email_list.to_s.split(',').reject(&:blank?).each do |str| + email_list.to_s.split(",").reject(&:blank?).each do |str| email = EmailNormalizer.normalize(str) next if where(user_id: user_id, email: email).present? ue = self.new(user_id: user_id, email: email) diff --git a/app/models/wheel_size.rb b/app/models/wheel_size.rb index a6e964e20d..91f41ae4c0 100644 --- a/app/models/wheel_size.rb +++ b/app/models/wheel_size.rb @@ -20,6 +20,6 @@ def self.popularities end def popularity - WheelSize.popularities[priority-1] + WheelSize.popularities[priority - 1] end end diff --git a/app/serializers/bike_serializer.rb b/app/serializers/bike_serializer.rb index ed39a5afed..eb18991b44 100644 --- a/app/serializers/bike_serializer.rb +++ b/app/serializers/bike_serializer.rb @@ -1,5 +1,4 @@ class BikeSerializer < ActiveModel::Serializer - attributes :id, :serial, :registration_created_at, @@ -39,23 +38,23 @@ def type_of_cycle def manufacturer_name object.mnfg_name end - + def url - "#{ENV['BASE_URL']}/bikes/#{object.id}" + "#{ENV["BASE_URL"]}/bikes/#{object.id}" end def api_url - "#{ENV['BASE_URL']}/api/v1/bikes/#{object.id}" + "#{ENV["BASE_URL"]}/api/v1/bikes/#{object.id}" end def title object.title_string + "(#{object.frame_colors.to_sentence.downcase})" end - + def registration_created_at object.created_at end - + def registration_updated_at object.updated_at end @@ -71,19 +70,19 @@ def photo object.stock_photo_url else nil - end + end end def thumb if object.public_images.present? object.public_images.first.image_url(:small) elsif object.stock_photo_url.present? - small = object.stock_photo_url.split('/') + small = object.stock_photo_url.split("/") ext = "/small_" + small.pop - small.join('/') + ext + small.join("/") + ext else nil - end + end end def frame_material diff --git a/app/serializers/bike_v2_serializer.rb b/app/serializers/bike_v2_serializer.rb index e4f73bc87f..bb53ef40c9 100644 --- a/app/serializers/bike_v2_serializer.rb +++ b/app/serializers/bike_v2_serializer.rb @@ -5,7 +5,7 @@ class BikeV2Serializer < ActiveModel::Serializer :manufacturer_name, :frame_model, :year, - :frame_colors, + :frame_colors, :thumb, :large_img, :is_stock_img, @@ -18,7 +18,7 @@ class BikeV2Serializer < ActiveModel::Serializer def manufacturer_name object.mnfg_name end - + def title object.title_string end @@ -31,9 +31,9 @@ def thumb if object.public_images.present? object.public_images.first.image_url(:small) elsif object.stock_photo_url.present? - small = object.stock_photo_url.split('/') + small = object.stock_photo_url.split("/") ext = "/small_" + small.pop - small.join('/') + ext + small.join("/") + ext end end diff --git a/app/serializers/bike_v2_show_serializer.rb b/app/serializers/bike_v2_show_serializer.rb index f8f0fa2afe..cdd65dde23 100644 --- a/app/serializers/bike_v2_show_serializer.rb +++ b/app/serializers/bike_v2_show_serializer.rb @@ -24,27 +24,27 @@ class BikeV2ShowSerializer < BikeV2Serializer has_many :public_images has_many :components - + def type_of_cycle object.cycle_type_name - end - + end + def url - "#{ENV['BASE_URL']}/bikes/#{object.id}" + "#{ENV["BASE_URL"]}/bikes/#{object.id}" end def api_url - "#{ENV['BASE_URL']}/api/v1/bikes/#{object.id}" + "#{ENV["BASE_URL"]}/api/v1/bikes/#{object.id}" end def test_bike object.example end - + def registration_created_at object.created_at.to_i end - + def registration_updated_at object.updated_at.to_i end diff --git a/app/serializers/ctype_serializer.rb b/app/serializers/ctype_serializer.rb index cf41aea780..042a0be28d 100644 --- a/app/serializers/ctype_serializer.rb +++ b/app/serializers/ctype_serializer.rb @@ -4,5 +4,4 @@ class CtypeSerializer < ActiveModel::Serializer :has_multiple self.root = "component_types" - end diff --git a/app/serializers/frame_material_serializer.rb b/app/serializers/frame_material_serializer.rb index a784a90863..a991ee1e97 100644 --- a/app/serializers/frame_material_serializer.rb +++ b/app/serializers/frame_material_serializer.rb @@ -1,3 +1,3 @@ class FrameMaterialSerializer < ActiveModel::Serializer attributes :name, :slug -end \ No newline at end of file +end diff --git a/app/serializers/location_serializer.rb b/app/serializers/location_serializer.rb index 194aad129c..ed40b9addf 100644 --- a/app/serializers/location_serializer.rb +++ b/app/serializers/location_serializer.rb @@ -8,4 +8,4 @@ def country def state object.state&.name end -end \ No newline at end of file +end diff --git a/app/serializers/manufacturer_serializer.rb b/app/serializers/manufacturer_serializer.rb index 9636c45763..5776b6d8aa 100644 --- a/app/serializers/manufacturer_serializer.rb +++ b/app/serializers/manufacturer_serializer.rb @@ -7,4 +7,4 @@ def company_url return "" unless object.website object.website end -end \ No newline at end of file +end diff --git a/app/serializers/manufacturer_v2_show_serializer.rb b/app/serializers/manufacturer_v2_show_serializer.rb index 83a7cb6ebc..fe031be947 100644 --- a/app/serializers/manufacturer_v2_show_serializer.rb +++ b/app/serializers/manufacturer_v2_show_serializer.rb @@ -15,7 +15,7 @@ def company_url end def image - return "" unless object.logo_url.present? && object.logo_url.match('/blank.png').blank? + return "" unless object.logo_url.present? && object.logo_url.match("/blank.png").blank? object.logo_url end -end \ No newline at end of file +end diff --git a/app/serializers/membership_serializer.rb b/app/serializers/membership_serializer.rb index d7f42a79b4..699cc0fda5 100644 --- a/app/serializers/membership_serializer.rb +++ b/app/serializers/membership_serializer.rb @@ -19,8 +19,8 @@ def organization_id object.organization.id end - def slug - object.organization.slug + def slug + object.organization.slug end def is_admin @@ -30,17 +30,16 @@ def is_admin def base_url "/organizations/#{object.organization.slug}" end - + def locations l = [] if object.organization.locations && object.organization.locations.length > 1 - object.organization.locations.each do |location| - l.push({ name: location.name, id: location.id}) + object.organization.locations.each do |location| + l.push({ name: location.name, id: location.id }) end else l.push({ name: organization_name, id: nil }) end return l end - end diff --git a/app/serializers/organized_message_serializer.rb b/app/serializers/organized_message_serializer.rb index 2b8e247b06..d0bfe8422b 100644 --- a/app/serializers/organized_message_serializer.rb +++ b/app/serializers/organized_message_serializer.rb @@ -17,7 +17,7 @@ def bike bike_obj = object.bike { id: bike_obj&.id, - title: bike_obj&.title_string + title: bike_obj&.title_string, } end end diff --git a/app/serializers/public_image_serializer.rb b/app/serializers/public_image_serializer.rb index 5797c687dc..c74be01c08 100644 --- a/app/serializers/public_image_serializer.rb +++ b/app/serializers/public_image_serializer.rb @@ -1,5 +1,5 @@ class PublicImageSerializer < ActiveModel::Serializer - self.root = 'images' + self.root = "images" attributes :name, :full, :large, @@ -17,9 +17,8 @@ def large def medium object.image_url(:medium) end - + def thumb object.image_url(:small) end - end diff --git a/app/serializers/single_bike_serializer.rb b/app/serializers/single_bike_serializer.rb index cad9e08256..a9f2dbc581 100644 --- a/app/serializers/single_bike_serializer.rb +++ b/app/serializers/single_bike_serializer.rb @@ -1,10 +1,9 @@ class SingleBikeSerializer < BikeSerializer - self.root = 'bikes' - attributes :images + self.root = "bikes" + attributes :images has_many :components def images object.public_images end - end diff --git a/app/serializers/stolen_notification_serializer.rb b/app/serializers/stolen_notification_serializer.rb index 33d9203871..eadfe8e659 100644 --- a/app/serializers/stolen_notification_serializer.rb +++ b/app/serializers/stolen_notification_serializer.rb @@ -1,3 +1,3 @@ class StolenNotificationSerializer < ActiveModel::Serializer attributes :message -end \ No newline at end of file +end diff --git a/app/serializers/stolen_record_serializer.rb b/app/serializers/stolen_record_serializer.rb index 38145e7502..d6aa96f0c7 100644 --- a/app/serializers/stolen_record_serializer.rb +++ b/app/serializers/stolen_record_serializer.rb @@ -12,12 +12,11 @@ class StolenRecordSerializer < ActiveModel::Serializer :create_open311, :id - def location a = [object.city] a << object.state.abbreviation if object.state.present? a << object.zipcode if object.zipcode.present? - a << object.country.iso if object.country.present? && object.country.iso != 'US' - a.compact.join(', ') + a << object.country.iso if object.country.present? && object.country.iso != "US" + a.compact.join(", ") end -end \ No newline at end of file +end diff --git a/app/serializers/stolen_record_v2_serializer.rb b/app/serializers/stolen_record_v2_serializer.rb index a1a4cb2dc2..308938060f 100644 --- a/app/serializers/stolen_record_v2_serializer.rb +++ b/app/serializers/stolen_record_v2_serializer.rb @@ -1,20 +1,19 @@ class StolenRecordV2Serializer < ActiveModel::Serializer attributes :date_stolen, - :location, - :latitude, - :longitude, - :theft_description, - :locking_description, - :lock_defeat_description, - :police_report_number, - :police_report_department, - :created_at, - :create_open311, - :id, - - def date_stolen - object.date_stolen.to_i - end + :location, + :latitude, + :longitude, + :theft_description, + :locking_description, + :lock_defeat_description, + :police_report_number, + :police_report_department, + :created_at, + :create_open311, + :id, + def date_stolen + object.date_stolen.to_i + end def created_at object.created_at.to_i diff --git a/app/services/admin_notifier.rb b/app/services/admin_notifier.rb index a74bed6825..2cd5f598b4 100644 --- a/app/services/admin_notifier.rb +++ b/app/services/admin_notifier.rb @@ -1,18 +1,18 @@ class AdminNotifier def for_organization(organization:, user:, type:) feedback = Feedback.new(email: user.email, - feedback_hash: { organization_id: organization.id }) - if type == 'organization_created' + feedback_hash: { organization_id: organization.id }) + if type == "organization_created" feedback.body = "#{organization.name} created an account" feedback.title = "New Organization created" - feedback.feedback_type = 'organization_created' - elsif type == 'organization_destroyed' + feedback.feedback_type = "organization_created" + elsif type == "organization_destroyed" feedback.body = "#{organization.name} deleted their account" feedback.title = "Organization deleted themselves" - feedback.feedback_type = 'organization_destroyed' + feedback.feedback_type = "organization_destroyed" else - feedback.feedback_type = 'organization_map' - if type == 'wants_shown' + feedback.feedback_type = "organization_map" + if type == "wants_shown" feedback.body = "#{organization.name} wants to be shown" feedback.title = "Organization wants to be shown" else @@ -22,4 +22,4 @@ def for_organization(organization:, user:, type:) end raise StandardError, "Couldn't notify admins" unless feedback.save end -end \ No newline at end of file +end diff --git a/app/services/autocomplete_loader.rb b/app/services/autocomplete_loader.rb index 7c2397c854..5c57c8c6f9 100644 --- a/app/services/autocomplete_loader.rb +++ b/app/services/autocomplete_loader.rb @@ -16,7 +16,7 @@ def reset end def load_colors - Soulheart::Loader.new.load(Color.all.map{ |c| c.autocomplete_hash }) + Soulheart::Loader.new.load(Color.all.map { |c| c.autocomplete_hash }) end def load_manufacturers @@ -24,4 +24,4 @@ def load_manufacturers Manufacturer.find_each { |m| mnfgs_list << m.autocomplete_hash } Soulheart::Loader.new.load(mnfgs_list) end -end \ No newline at end of file +end diff --git a/app/services/bike_creator.rb b/app/services/bike_creator.rb index eeaab5bd96..0cf8e8d21a 100644 --- a/app/services/bike_creator.rb +++ b/app/services/bike_creator.rb @@ -6,30 +6,30 @@ def initialize(b_param = nil) def add_bike_book_data return nil unless @b_param && @b_param.bike.present? && @b_param.manufacturer_id.present? - return nil unless @b_param.bike['frame_model'].present? && @b_param.bike['year'].present? + return nil unless @b_param.bike["frame_model"].present? && @b_param.bike["year"].present? bb_data = BikeBookIntegration.new.get_model({ - manufacturer: Manufacturer.find(@b_param.bike['manufacturer_id']).name, - year: @b_param.bike['year'], - frame_model: @b_param.bike['frame_model'] + manufacturer: Manufacturer.find(@b_param.bike["manufacturer_id"]).name, + year: @b_param.bike["year"], + frame_model: @b_param.bike["frame_model"], }) - return true unless bb_data && bb_data['bike'].present? - @b_param.params['bike']['cycle_type'] = bb_data['bike']['cycle_type'] if bb_data['bike'] && bb_data['bike']['cycle_type'].present? - if bb_data['bike']['paint_description'].present? - @b_param.params['bike']['paint_name'] = bb_data['bike']['paint_description'] unless @b_param.params['bike']['paint_name'].present? + return true unless bb_data && bb_data["bike"].present? + @b_param.params["bike"]["cycle_type"] = bb_data["bike"]["cycle_type"] if bb_data["bike"] && bb_data["bike"]["cycle_type"].present? + if bb_data["bike"]["paint_description"].present? + @b_param.params["bike"]["paint_name"] = bb_data["bike"]["paint_description"] unless @b_param.params["bike"]["paint_name"].present? end - if bb_data['bike']['description'].present? - if @b_param.params['bike']['description'].present? - @b_param.params['bike']['description'] += " #{bb_data['bike']['description']}" + if bb_data["bike"]["description"].present? + if @b_param.params["bike"]["description"].present? + @b_param.params["bike"]["description"] += " #{bb_data["bike"]["description"]}" else - @b_param.params['bike']['description'] = bb_data['bike']['description'] + @b_param.params["bike"]["description"] = bb_data["bike"]["description"] end end - @b_param.params['bike']['rear_wheel_bsd'] = bb_data['bike']['rear_wheel_bsd'] if bb_data['bike']['rear_wheel_bsd'].present? - @b_param.params['bike']['rear_tire_narrow'] = bb_data['bike']['rear_tire_narrow'] if bb_data['bike']['rear_tire_narrow'].present? - @b_param.params['bike']['stock_photo_url'] = bb_data['bike']['stock_photo_url'] if bb_data['bike']['stock_photo_url'].present? - @b_param.params['components'] = bb_data['components'] && bb_data['components'].map { |c| c.merge('is_stock' => true) } + @b_param.params["bike"]["rear_wheel_bsd"] = bb_data["bike"]["rear_wheel_bsd"] if bb_data["bike"]["rear_wheel_bsd"].present? + @b_param.params["bike"]["rear_tire_narrow"] = bb_data["bike"]["rear_tire_narrow"] if bb_data["bike"]["rear_tire_narrow"].present? + @b_param.params["bike"]["stock_photo_url"] = bb_data["bike"]["stock_photo_url"] if bb_data["bike"]["stock_photo_url"].present? + @b_param.params["components"] = bb_data["components"] && bb_data["components"].map { |c| c.merge("is_stock" => true) } @b_param.clean_params # if we just rely on the before_save filter, @b_param needs to be reloaded - @b_param.save if @b_param.id.present? + @b_param.save if @b_param.id.present? @b_param end @@ -38,7 +38,7 @@ def build_new_bike end def build_bike - @bike = BikeCreatorBuilder.new(@b_param).build + @bike = BikeCreatorBuilder.new(@b_param).build end def create_associations(bike) @@ -63,7 +63,7 @@ def validate_record(bike) elsif @b_param.id.present? # Only update b_param if it exists @b_param.update_attributes(created_bike_id: bike.id, bike_errors: nil) end - @bike + @bike end def save_bike(bike) @@ -103,7 +103,7 @@ def creation_state_attributes origin: @b_param.origin, bulk_import_id: @b_param.params["bulk_import_id"], creator_id: @b_param.creator_id, - organization_id: @bike.creation_organization_id + organization_id: @bike.creation_organization_id, } end end diff --git a/app/services/bike_creator_associator.rb b/app/services/bike_creator_associator.rb index bb347b4d5f..4e987eeab3 100644 --- a/app/services/bike_creator_associator.rb +++ b/app/services/bike_creator_associator.rb @@ -44,21 +44,21 @@ def attach_photo(bike) @b_param.update_attributes(image_processed: true) bike.reload end - + def attach_photos(bike) - return nil unless @b_param.params['photos'].present? - photos = @b_param.params['photos'].uniq.take(7) + return nil unless @b_param.params["photos"].present? + photos = @b_param.params["photos"].uniq.take(7) photos.each { |p| PublicImage.create(imageable: bike, remote_image_url: p) } end def add_other_listings(bike) - return nil unless @b_param.params['bike']['other_listing_urls'].present? - urls = @b_param.params['bike']['other_listing_urls'] + return nil unless @b_param.params["bike"]["other_listing_urls"].present? + urls = @b_param.params["bike"]["other_listing_urls"] urls.each { |url| OtherListing.create(url: url, bike_id: bike.id) } end def associate(bike) - begin + begin ownership = create_ownership(bike) create_components(bike) create_normalized_serial_segments(bike) diff --git a/app/services/bike_creator_builder.rb b/app/services/bike_creator_builder.rb index d80d4cf33a..0db4336700 100644 --- a/app/services/bike_creator_builder.rb +++ b/app/services/bike_creator_builder.rb @@ -16,7 +16,7 @@ def add_front_wheel_size(bike) def add_required_attributes(bike) bike.propulsion_type ||= "foot-pedal" - bike + bike end def new_bike diff --git a/app/services/bike_creator_organizer.rb b/app/services/bike_creator_organizer.rb index a692e5f33d..3458a8dbee 100644 --- a/app/services/bike_creator_organizer.rb +++ b/app/services/bike_creator_organizer.rb @@ -35,10 +35,10 @@ def organize(organization_id) end def check_organization - if @b_param.params['creation_organization_id'] - organize(@b_param.params['creation_organization_id']) - elsif @b_param.params['bike'].present? and @b_param.params['bike']['creation_organization_id'] - organize(@b_param.params['bike']['creation_organization_id']) + if @b_param.params["creation_organization_id"] + organize(@b_param.params["creation_organization_id"]) + elsif @b_param.params["bike"].present? and @b_param.params["bike"]["creation_organization_id"] + organize(@b_param.params["bike"]["creation_organization_id"]) else unorganize end diff --git a/app/services/bike_creator_verifier.rb b/app/services/bike_creator_verifier.rb index 3fa03df956..91b00ab0e8 100644 --- a/app/services/bike_creator_verifier.rb +++ b/app/services/bike_creator_verifier.rb @@ -9,8 +9,8 @@ def check_organization end def check_example - example_org = Organization.find_by_name('Example organization') - @bike.creation_organization_id = example_org.id if @b_param.params && @b_param.params['test'] + example_org = Organization.find_by_name("Example organization") + @bike.creation_organization_id = example_org.id if @b_param.params && @b_param.params["test"] if @bike.creation_organization_id.present? && example_org.present? @bike.example = true if @bike.creation_organization_id == example_org.id else @@ -20,7 +20,7 @@ def check_example end def add_phone - @bike.phone ||= @b_param.params['stolen_record']['phone'] if @b_param.params && @b_param.params['stolen_record'].present? + @bike.phone ||= @b_param.params["stolen_record"]["phone"] if @b_param.params && @b_param.params["stolen_record"].present? if @bike.creation_organization.present? && @bike.creation_organization.locations.any? @bike.phone ||= @bike.creation_organization.locations.first.phone elsif @bike.creator && @bike.creator.phone.present? @@ -39,13 +39,13 @@ def recoverize end def check_stolen_and_recovered - if @b_param.params['stolen'] + if @b_param.params["stolen"] stolenize - elsif @b_param.params['bike'].present? and @b_param.params['bike']['stolen'] + elsif @b_param.params["bike"].present? and @b_param.params["bike"]["stolen"] stolenize - elsif @b_param.params['recovered'] + elsif @b_param.params["recovered"] recoverize - elsif @b_param.params['bike'].present? and @b_param.params['bike']['recovered'] + elsif @b_param.params["bike"].present? and @b_param.params["bike"]["recovered"] recoverize end end diff --git a/app/services/bike_searcher.rb b/app/services/bike_searcher.rb index c348edcc37..e991dac7b5 100644 --- a/app/services/bike_searcher.rb +++ b/app/services/bike_searcher.rb @@ -4,7 +4,7 @@ def initialize(creation_params = {}, reverse_geocode = nil) @params = creation_params.merge(reverse_geocode: reverse_geocode) @bikes = params[:api_search] ? Bike.non_recovered : Bike.all if @params[:search_type].present? - if @params[:search_type] == 'serial' + if @params[:search_type] == "serial" @params[:serial] = @params[:query_typed] else @params[:query] = @params[:query_typed] @@ -13,7 +13,7 @@ def initialize(creation_params = {}, reverse_geocode = nil) @params = interpreted_params(@params) if @params[:serial].present? if @params[:query].present? - @params[:query] = @params[:query].gsub(/,?#,?/,'') + @params[:query] = @params[:query].gsub(/,?#,?/, "") end @normer = SerialNormalizer.new(serial: @params[:serial]) end @@ -22,14 +22,14 @@ def initialize(creation_params = {}, reverse_geocode = nil) attr_accessor :params, :location def interpreted_params(i_params) - query = (i_params[:query] || '').gsub('%23', '#') # ... ensure string so we can gsub it + query = (i_params[:query] || "").gsub("%23", "#") # ... ensure string so we can gsub it return i_params unless query.present? # serial segment looks like s#SERIAL# serial_matcher = /s#[^#]*#/i query.gsub!(serial_matcher) do |match| # Set the serial to the match, with the first part chopped and the last part chopped - i_params[:serial] = match.gsub(/\As#/, '').gsub(/#\z/, '') - '' # remove it from query + i_params[:serial] = match.gsub(/\As#/, "").gsub(/#\z/, "") + "" # remove it from query end i_params.merge(query: query) end @@ -37,9 +37,9 @@ def interpreted_params(i_params) # Remove the encoding tricks we use with selectize def stripped_query @params[:query] - .gsub(/m_\d+/, '') # manufacturers - .gsub(/c_\d+/, '') # colors - .gsub(/%2C/i, ',') # unencode commas + .gsub(/m_\d+/, "") # manufacturers + .gsub(/c_\d+/, "") # colors + .gsub(/%2C/i, ",") # unencode commas end def selectize_items @@ -51,10 +51,10 @@ def selectize_items @color_ids.each { |c_id| items << Color.find(c_id).autocomplete_result_hash } end if @params[:serial].present? - items << { id: 'serial', search_id: "s##{@params[:serial]}#", text: @params[:serial] }.as_json + items << { id: "serial", search_id: "s##{@params[:serial]}#", text: @params[:serial] }.as_json end if @params[:query] - stripped_query.split(',').reject(&:blank?) + stripped_query.split(",").reject(&:blank?) .each { |q| items << { search_id: q, text: q }.as_json } end items @@ -62,8 +62,8 @@ def selectize_items def stolenness return nil unless @params[:non_stolen].present? || @params[:stolen].present? - return 'stolen' if @params[:stolen].present? && @params[:stolen] - return 'non_stolen' if @params[:non_stolen].present? && @params[:non_stolen] + return "stolen" if @params[:stolen].present? && @params[:stolen] + return "non_stolen" if @params[:non_stolen].present? && @params[:non_stolen] end def is_proximity @@ -72,27 +72,27 @@ def is_proximity end def stolenness_type - return 'all' unless stolenness.present? - return 'stolen_proximity' if stolenness == 'stolen' && is_proximity + return "all" unless stolenness.present? + return "stolen_proximity" if stolenness == "stolen" && is_proximity stolenness end def matching_stolenness(bikes) return @bikes unless stolenness.present? - @bikes = (stolenness == 'stolen') ? bikes.stolen : bikes.non_stolen + @bikes = (stolenness == "stolen") ? bikes.stolen : bikes.non_stolen end def parsed_attributes if @params[:find_bike_attributes] attr_ids = @params[:find_bike_attributes][:ids].reject(&:empty?) - return attr_ids if attr_ids.any? + return attr_ids if attr_ids.any? nil end end def matching_query(bikes) return nil unless @params[:query].present? - @bikes = bikes.text_search(stripped_query.gsub(',', ' ')) + @bikes = bikes.text_search(stripped_query.gsub(",", " ")) @bikes end @@ -107,13 +107,13 @@ def matching_manufacturer(bikes) if @params[:manufacturer].present? manufacturer = Manufacturer.friendly_find(@params[:manufacturer]) if manufacturer.present? - @params[:manufacturer_id] = manufacturer.id + @params[:manufacturer_id] = manufacturer.id else @params[:manufacturer_id] = 0 end end if @params[:query] && @params[:query].match(/(,?m_\d+)/) - @params[:manufacturer_id] = @params[:query].match(/(,?m_\d+)/)[0].gsub(/,?m_/,'') + @params[:manufacturer_id] = @params[:query].match(/(,?m_\d+)/)[0].gsub(/,?m_/, "") end @bikes = bikes.where(manufacturer_id: @params[:manufacturer_id]) if @params[:manufacturer_id].present? @bikes @@ -121,24 +121,24 @@ def matching_manufacturer(bikes) def matching_colors(bikes) if @params[:colors].present? - @color_ids = @params[:colors].split(',') - .collect{ |c| Color.friendly_find(c).id if Color.friendly_find(c) } + @color_ids = @params[:colors].split(",") + .collect { |c| Color.friendly_find(c).id if Color.friendly_find(c) } elsif @params[:query] && @params[:query].match(/(,?c_\d+)/) @color_ids = @params[:query].scan(/(,?c_\d+)/).flatten - .map{ |c| c.gsub(/(,?c_)/,'') } + .map { |c| c.gsub(/(,?c_)/, "") } end if @color_ids.present? @color_ids.compact.each do |c_id| - @bikes = bikes.where('primary_frame_color_id = ? OR secondary_frame_color_id = ? OR tertiary_frame_color_id = ?', c_id, c_id, c_id) + @bikes = bikes.where("primary_frame_color_id = ? OR secondary_frame_color_id = ? OR tertiary_frame_color_id = ?", c_id, c_id, c_id) end end @bikes end - def fuzzy_find_serial_ids(bike_ids=[]) + def fuzzy_find_serial_ids(bike_ids = []) @normer.normalized_segments.each do |seg| next unless seg.length > 3 - bike_ids += NormalizedSerialSegment.where('LEVENSHTEIN(segment, ?) < 3', seg).map(&:bike_id) + bike_ids += NormalizedSerialSegment.where("LEVENSHTEIN(segment, ?) < 3", seg).map(&:bike_id) end bike_ids end @@ -148,8 +148,8 @@ def fuzzy_find_serial bike_ids = fuzzy_find_serial_ids # Don't return exact matches bike_ids = bike_ids.uniq - matching_serial.map(&:id) - Bike.where('id in (?)', bike_ids) - end + Bike.where("id in (?)", bike_ids) + end def by_proximity return unless is_proximity @@ -162,16 +162,16 @@ def by_proximity @location = Geocoder.search(@params[:proximity]) if @params[:reverse_geocode] box = Geocoder::Calculations.bounding_box((@location || @params[:proximity]), radius) unless box[0].nan? - bike_ids = StolenRecord.where('id in (?)', stolen_ids).within_bounding_box(box).pluck(:bike_id) - @bikes = @bikes.where('id in (?)', bike_ids) + bike_ids = StolenRecord.where("id in (?)", stolen_ids).within_bounding_box(box).pluck(:bike_id) + @bikes = @bikes.where("id in (?)", bike_ids) end @bikes end def by_date - return unless stolenness == 'stolen' + return unless stolenness == "stolen" return @bikes unless @params[:stolen_before].present? || @params[:stolen_after].present? - stolen_records = StolenRecord.where('id in (?)', @bikes.pluck(:current_stolen_record_id)) + stolen_records = StolenRecord.where("id in (?)", @bikes.pluck(:current_stolen_record_id)) if @params[:stolen_before].present? before = Time.at(@params[:stolen_before]).utc.to_datetime stolen_records = stolen_records.where("date_stolen <= ?", before) @@ -180,19 +180,19 @@ def by_date after = Time.at(@params[:stolen_after]).utc.to_datetime stolen_records = stolen_records.where("date_stolen >= ?", after) end - @bikes = @bikes.where('id in (?)', stolen_records.pluck(:bike_id)) + @bikes = @bikes.where("id in (?)", stolen_records.pluck(:bike_id)) end def find_bikes - @bikes = matching_serial + @bikes = matching_serial matching_stolenness(@bikes) matching_manufacturer(@bikes) matching_colors(@bikes) matching_query(@bikes) - if stolenness == 'stolen' + if stolenness == "stolen" by_proximity by_date - end + end @bikes end @@ -210,9 +210,9 @@ def find_bike_counts @params[:stolen] = true matching_stolenness(@bikes) by_date - + result[:stolen] = @bikes.count - + by_proximity result.merge(proximity: @bikes.count) end diff --git a/app/services/bike_updator.rb b/app/services/bike_updator.rb index b55c247992..3732caf2eb 100644 --- a/app/services/bike_updator.rb +++ b/app/services/bike_updator.rb @@ -6,7 +6,7 @@ class BikeUpdatorError < StandardError class BikeUpdator def initialize(creation_params = {}) - @user = creation_params[:user] + @user = creation_params[:user] @bike_params = creation_params[:b_params] @bike = creation_params[:bike] || find_bike @current_ownership = creation_params[:current_ownership] @@ -15,7 +15,7 @@ def initialize(creation_params = {}) def find_bike begin - return Bike.unscoped.find(@bike_params['id']) + return Bike.unscoped.find(@bike_params["id"]) rescue raise BikeUpdatorError, "Oh no! We couldn't find that bike" end @@ -23,19 +23,19 @@ def find_bike def update_ownership @bike.update_attribute :updator_id, @user.id if @user.present? && @bike.updator_id != @user.id - if @bike_params['bike'] && @bike_params['bike']['owner_email'] && - @bike.owner_email != @bike_params['bike']['owner_email'] - if @bike_params['bike']['owner_email'].blank? - @bike_params['bike'].delete('owner_email') + if @bike_params["bike"] && @bike_params["bike"]["owner_email"] && + @bike.owner_email != @bike_params["bike"]["owner_email"] + if @bike_params["bike"]["owner_email"].blank? + @bike_params["bike"].delete("owner_email") else opts = { - owner_email: @bike_params['bike']['owner_email'], + owner_email: @bike_params["bike"]["owner_email"], bike: @bike, creator: @user, - send_email: true + send_email: true, } OwnershipCreator.new(opts).create_ownership - @bike_params['bike']['is_for_sale'] = false + @bike_params["bike"]["is_for_sale"] = false end end end @@ -52,10 +52,10 @@ def update_api_components def update_stolen_record @bike.reload - if @bike_params['bike'] && @bike_params['bike']['date_stolen'] - StolenRecordUpdator.new(bike: @bike, date_stolen: @bike_params['bike']['date_stolen']).update_records + if @bike_params["bike"] && @bike_params["bike"]["date_stolen"] + StolenRecordUpdator.new(bike: @bike, date_stolen: @bike_params["bike"]["date_stolen"]).update_records else - if @bike_params['stolen_record'] || @bike_params['bike']['stolen_records_attributes'] + if @bike_params["stolen_record"] || @bike_params["bike"]["stolen_records_attributes"] StolenRecordUpdator.new(bike: @bike, b_param: @bike_params).update_records @bike.reload elsif @currently_stolen != @bike.stolen @@ -65,19 +65,19 @@ def update_stolen_record end def set_protected_attributes - @bike_params['bike']['serial_number'] = @bike.serial_number - @bike_params['bike']['manufacturer_id'] = @bike.manufacturer_id - @bike_params['bike']['manufacturer_other'] = @bike.manufacturer_other - @bike_params['bike']['creation_organization_id'] = @bike.creation_organization_id - @bike_params['bike']['creator'] = @bike.creator - @bike_params['bike']['example'] = @bike.example - @bike_params['bike']['hidden'] = @bike.hidden + @bike_params["bike"]["serial_number"] = @bike.serial_number + @bike_params["bike"]["manufacturer_id"] = @bike.manufacturer_id + @bike_params["bike"]["manufacturer_other"] = @bike.manufacturer_other + @bike_params["bike"]["creation_organization_id"] = @bike.creation_organization_id + @bike_params["bike"]["creator"] = @bike.creator + @bike_params["bike"]["example"] = @bike.example + @bike_params["bike"]["hidden"] = @bike.hidden end def remove_blank_components return false unless @bike.components.any? @bike.components.each do |c| - c.destroy unless c.ctype_id.present? || c.description.present? + c.destroy unless c.ctype_id.present? || c.description.present? end end @@ -85,11 +85,10 @@ def update_available_attributes ensure_ownership! set_protected_attributes update_ownership - update_api_components if @bike_params['components'].present? - update_stolen_record if @bike.update_attributes(@bike_params['bike'].except('stolen_records_attributes')) + update_api_components if @bike_params["components"].present? + update_stolen_record if @bike.update_attributes(@bike_params["bike"].except("stolen_records_attributes")) AfterBikeSaveWorker.perform_async(@bike.id) if @bike.present? # run immediately remove_blank_components @bike end - -end \ No newline at end of file +end diff --git a/app/services/component_creator.rb b/app/services/component_creator.rb index 94b9f067f4..bb9dbbb7a6 100644 --- a/app/services/component_creator.rb +++ b/app/services/component_creator.rb @@ -31,7 +31,7 @@ def set_component_type(component) component[:ctype_id] = ctype.id else component[:ctype_id] = Ctype.unknown.id - component[:ctype_other] = name + component[:ctype_other] = name end component.delete :component_type component @@ -50,7 +50,7 @@ def whitelist_attributes(component) ctype_other: component[:ctype_other], manufacturer_id: component[:manufacturer_id], manufacturer_other: component[:manufacturer_other], - mnfg_name: component[:manufacturer_name] || component[:manufacturer_name] || component[:mnfg_name] + mnfg_name: component[:manufacturer_name] || component[:manufacturer_name] || component[:mnfg_name], } comp_attributes.select { |k, v| v.present? } end @@ -62,10 +62,10 @@ def create_component(component) end def update_components_from_params - @b_param['components'].each_with_index do |comp, index| - if comp['id'].present? - component = @bike.components.find(comp['id']) - (component.destroy && next) if comp['destroy'] || comp['_destroy'] == '1' + @b_param["components"].each_with_index do |comp, index| + if comp["id"].present? + component = @bike.components.find(comp["id"]) + (component.destroy && next) if comp["destroy"] || comp["_destroy"] == "1" else component = @bike.components.new end @@ -76,12 +76,12 @@ def update_components_from_params end def create_components_from_params - if @b_param.present? && @b_param.params.present? && @b_param.params['components'].present? - (0...@b_param.params['components'].count).to_a.each do |c_number| - if @b_param.params['components'].kind_of?(Array) - component = @b_param.params['components'][c_number].with_indifferent_access + if @b_param.present? && @b_param.params.present? && @b_param.params["components"].present? + (0...@b_param.params["components"].count).to_a.each do |c_number| + if @b_param.params["components"].kind_of?(Array) + component = @b_param.params["components"][c_number].with_indifferent_access else - component = @b_param.params['components'][c_number.to_s].with_indifferent_access + component = @b_param.params["components"][c_number.to_s].with_indifferent_access end component = set_manufacturer_key(component) component = set_component_type(component) @@ -89,5 +89,4 @@ def create_components_from_params end end end - -end \ No newline at end of file +end diff --git a/app/services/geohelper.rb b/app/services/geohelper.rb index 7c4fb1f423..ffd96a6daa 100644 --- a/app/services/geohelper.rb +++ b/app/services/geohelper.rb @@ -51,7 +51,7 @@ def address_hash_from_geocoder_result(addy) city: city, state: state, zipcode: code, - country: country + country: country, }.with_indifferent_access end end diff --git a/app/services/ownership_creator.rb b/app/services/ownership_creator.rb index 78a562a247..8df6618d9a 100644 --- a/app/services/ownership_creator.rb +++ b/app/services/ownership_creator.rb @@ -38,7 +38,7 @@ def new_ownership_params example: @bike.example, current: true, send_email: @send_email, - user_hidden: @user_hidden + user_hidden: @user_hidden, } end diff --git a/app/services/serial_normalizer.rb b/app/services/serial_normalizer.rb index 7d27047a04..2963d8b9bd 100644 --- a/app/services/serial_normalizer.rb +++ b/app/services/serial_normalizer.rb @@ -5,18 +5,18 @@ def initialize(serial: nil, bike_id: nil) end def normalized - return 'absent' if @serial.blank? || @serial == 'ABSENT' + return "absent" if @serial.blank? || @serial == "ABSENT" normed = @serial.dup serial_substitutions.each do |key, value| normed.gsub!(/[#{key}]/, value) - normed.gsub!(/[^\w]|[_]/, ' ') # turn all non letter/numbers into spaces + normed.gsub!(/[^\w]|[_]/, " ") # turn all non letter/numbers into spaces end - normed.gsub(/^0+/, '').gsub(/\s+/, ' ').strip # remove leading zeros and multiple spaces + normed.gsub(/^0+/, "").gsub(/\s+/, " ").strip # remove leading zeros and multiple spaces end def normalized_segments - return [] if normalized == 'absent' - normalized.split(' ').reject(&:empty?).uniq + return [] if normalized == "absent" + normalized.split(" ").reject(&:empty?).uniq end def save_segments(bike_id) @@ -32,11 +32,11 @@ def save_segments(bike_id) def serial_substitutions { - '|IL' => '1', - 'O' => '0', - 'S' => '5', - 'Z' => '2', - 'B' => '8' + "|IL" => "1", + "O" => "0", + "S" => "5", + "Z" => "2", + "B" => "8", } end end diff --git a/app/services/stolen_record_updator.rb b/app/services/stolen_record_updator.rb index 463aaa0fed..0180e7e74b 100644 --- a/app/services/stolen_record_updator.rb +++ b/app/services/stolen_record_updator.rb @@ -28,7 +28,7 @@ def update_records elsif @date_stolen stolen_record = @bike.find_current_stolen_record stolen_record.update_attributes(date_stolen: @date_stolen) - elsif @b_param && (@b_param['stolen_record'] || @b_param['bike']['stolen_records_attributes']) + elsif @b_param && (@b_param["stolen_record"] || @b_param["bike"]["stolen_records_attributes"]) stolen_record = @bike.find_current_stolen_record update_with_params(stolen_record).save end @@ -60,7 +60,7 @@ def update_with_params(stolen_record) phone_for_everyone: false, phone_for_users: false, phone_for_shops: false, - phone_for_police: false + phone_for_police: false, } end stolen_record diff --git a/app/services/webhook_runner.rb b/app/services/webhook_runner.rb index e5c4dc6ae8..12d9c772ba 100644 --- a/app/services/webhook_runner.rb +++ b/app/services/webhook_runner.rb @@ -1,13 +1,12 @@ # This is deprecated and should be removed or refactored eventually. Check AfterBikeSaveWorker class WebhookRunner + require "httparty" - require 'httparty' - def make_request(url) begin response = HTTParty.get(url, - :headers => { 'Content-Type' => 'application/json' } ) + :headers => { "Content-Type" => "application/json" }) JSON.parse(response.body) rescue => e e.message @@ -39,5 +38,4 @@ def redis_id(method) def redis Redis.current end - -end \ No newline at end of file +end diff --git a/app/uploaders/avatar_uploader.rb b/app/uploaders/avatar_uploader.rb index 597b8c09ed..afe61e4f6c 100644 --- a/app/uploaders/avatar_uploader.rb +++ b/app/uploaders/avatar_uploader.rb @@ -12,12 +12,13 @@ class AvatarUploader < CarrierWave::Uploader::Base else storage :fog end - - after :remove, :delete_empty_upstream_dirs + + after :remove, :delete_empty_upstream_dirs + def delete_empty_upstream_dirs path = ::File.expand_path(store_dir, root) Dir.delete(path) # fails if path not empty dir - + path = ::File.expand_path(base_store_dir, root) Dir.delete(path) # fails if path not empty dir rescue SystemCallError @@ -26,7 +27,7 @@ def delete_empty_upstream_dirs # Fallback so the page doesn't break if the image isn't there def default_url - 'https://files.bikeindex.org/blank.png' + "https://files.bikeindex.org/blank.png" end def cache_dir @@ -36,7 +37,7 @@ def cache_dir def store_dir "#{base_store_dir}/#{model.id}" end - + def base_store_dir "uploads/#{model.class.to_s[0, 2]}" end @@ -53,7 +54,6 @@ def auto_orient end end - version :thumb do process :auto_orient process resize_to_fill: [100, 100] diff --git a/app/uploaders/circular_image_uploader.rb b/app/uploaders/circular_image_uploader.rb index cef5b9c8f7..d130bc7573 100644 --- a/app/uploaders/circular_image_uploader.rb +++ b/app/uploaders/circular_image_uploader.rb @@ -9,12 +9,13 @@ class CircularImageUploader < CarrierWave::Uploader::Base else storage :file end - - after :remove, :delete_empty_upstream_dirs + + after :remove, :delete_empty_upstream_dirs + def delete_empty_upstream_dirs path = ::File.expand_path(store_dir, root) Dir.delete(path) # fails if path not empty dir - + path = ::File.expand_path(base_store_dir, root) Dir.delete(path) # fails if path not empty dir rescue SystemCallError @@ -28,7 +29,7 @@ def store_dir def cache_dir Rails.root.join("tmp", "cache") end - + def base_store_dir "uploads/#{model.class.to_s[0, 2]}" end @@ -40,7 +41,7 @@ def filename process :fix_exif_rotation process :strip # Remove EXIF data, because we don't need it process convert: "jpg" - + version :large do process :round_image end @@ -50,7 +51,7 @@ def filename end version :thumb, :from_version => :medium do - process resize_to_fill: [100,100] + process resize_to_fill: [100, 100] end def extension_white_list @@ -64,11 +65,11 @@ def round_image width, height = img[:dimensions] radius_point = ((width > height) ? [width / 2, height] : [width, height / 2]).join(",") imagemagick_command = ["convert", - "-size #{ width }x#{ height }", - 'xc:transparent', - "-fill #{ path }", - "-draw 'circle #{ width / 2 },#{ height / 2 } #{ radius_point }'", - "+repage #{new_tmp_path}"].join(" ") + "-size #{width}x#{height}", + "xc:transparent", + "-fill #{path}", + "-draw 'circle #{width / 2},#{height / 2} #{radius_point}'", + "+repage #{new_tmp_path}"].join(" ") system(imagemagick_command) MiniMagick::Image.open(new_tmp_path) diff --git a/app/uploaders/image_uploader.rb b/app/uploaders/image_uploader.rb index a209f749a2..0a85ecd6a7 100644 --- a/app/uploaders/image_uploader.rb +++ b/app/uploaders/image_uploader.rb @@ -1,17 +1,18 @@ class ImageUploader < CarrierWave::Uploader::Base include CarrierWave::MiniMagick - + if Rails.env.production? storage :fog else storage :file end - - after :remove, :delete_empty_upstream_dirs + + after :remove, :delete_empty_upstream_dirs + def delete_empty_upstream_dirs path = ::File.expand_path(store_dir, root) Dir.delete(path) # fails if path not empty dir - + path = ::File.expand_path(base_store_dir, root) Dir.delete(path) # fails if path not empty dir rescue SystemCallError @@ -25,7 +26,7 @@ def cache_dir def store_dir "#{base_store_dir}/#{model.id}" end - + def base_store_dir "uploads/#{model.class.to_s[0, 2]}" end @@ -43,10 +44,10 @@ def extension_white_list end version :medium, from_version: :large do - process resize_to_fit: [700,525] + process resize_to_fit: [700, 525] end version :small, from_version: :medium do - process resize_to_fill: [300,300] + process resize_to_fill: [300, 300] end end diff --git a/app/uploaders/json_uploader.rb b/app/uploaders/json_uploader.rb index 09c1e7cdcf..c6b675c862 100644 --- a/app/uploaders/json_uploader.rb +++ b/app/uploaders/json_uploader.rb @@ -20,6 +20,6 @@ def store_dir end def base_store_dir - 'uploads/' + "uploads/" end end diff --git a/app/uploaders/listicle_image_uploader.rb b/app/uploaders/listicle_image_uploader.rb index 3663930e2d..fa3ea85b15 100644 --- a/app/uploaders/listicle_image_uploader.rb +++ b/app/uploaders/listicle_image_uploader.rb @@ -9,11 +9,12 @@ class ListicleImageUploader < CarrierWave::Uploader::Base storage :file end - after :remove, :delete_empty_upstream_dirs + after :remove, :delete_empty_upstream_dirs + def delete_empty_upstream_dirs path = ::File.expand_path(store_dir, root) Dir.delete(path) # fails if path not empty dir - + path = ::File.expand_path(base_store_dir, root) Dir.delete(path) # fails if path not empty dir rescue SystemCallError @@ -27,7 +28,7 @@ def cache_dir def store_dir "#{base_store_dir}/#{model.id}" end - + def base_store_dir "uploads/#{model.class.to_s[0, 2]}" end @@ -48,7 +49,7 @@ def base_store_dir end version :thumb, :from_version => :medium do - process resize_to_fill: [100,100] + process resize_to_fill: [100, 100] end def extension_white_list @@ -66,5 +67,4 @@ def crop img end end - -end \ No newline at end of file +end diff --git a/app/uploaders/partner_uploader.rb b/app/uploaders/partner_uploader.rb index 8a00304a0a..4298584c49 100644 --- a/app/uploaders/partner_uploader.rb +++ b/app/uploaders/partner_uploader.rb @@ -9,11 +9,12 @@ class PartnerUploader < CarrierWave::Uploader::Base storage :file end - after :remove, :delete_empty_upstream_dirs + after :remove, :delete_empty_upstream_dirs + def delete_empty_upstream_dirs path = ::File.expand_path(store_dir, root) Dir.delete(path) # fails if path not empty dir - + path = ::File.expand_path(base_store_dir, root) Dir.delete(path) # fails if path not empty dir rescue SystemCallError @@ -27,7 +28,7 @@ def cache_dir def store_dir "#{base_store_dir}/#{model.id}" end - + def base_store_dir "partner/" end @@ -44,11 +45,10 @@ def extension_white_list end version :medium, from_version: :large do - process resize_to_fit: [300,100] + process resize_to_fit: [300, 100] end version :small, from_version: :medium do - process resize_to_fill: [100,100] + process resize_to_fill: [100, 100] end - end diff --git a/app/uploaders/pdf_uploader.rb b/app/uploaders/pdf_uploader.rb index 318629388f..98f71bff12 100644 --- a/app/uploaders/pdf_uploader.rb +++ b/app/uploaders/pdf_uploader.rb @@ -15,12 +15,13 @@ class PdfUploader < CarrierWave::Uploader::Base else storage :fog end - - after :remove, :delete_empty_upstream_dirs + + after :remove, :delete_empty_upstream_dirs + def delete_empty_upstream_dirs path = ::File.expand_path(store_dir, root) Dir.delete(path) # fails if path not empty dir - + path = ::File.expand_path(base_store_dir, root) Dir.delete(path) # fails if path not empty dir rescue SystemCallError @@ -34,9 +35,8 @@ def cache_dir def store_dir "#{base_store_dir}/#{model.id}" end - + def base_store_dir "uploads/#{model.class.to_s[0, 2]}" end - end diff --git a/app/uploaders/tsv_uploader.rb b/app/uploaders/tsv_uploader.rb index c2555af89a..3389710b4b 100644 --- a/app/uploaders/tsv_uploader.rb +++ b/app/uploaders/tsv_uploader.rb @@ -2,7 +2,7 @@ class TsvUploader < CarrierWave::Uploader::Base # include Sprockets::Helpers::RailsHelper # Deprecated. Should be removed # include Sprockets::Helpers::IsolatedHelper # Deprecated. Should be removed - + if Rails.env.test? storage :file elsif Rails.env.development? @@ -18,7 +18,7 @@ def cache_dir def store_dir "#{base_store_dir}tsvs" end - + def base_store_dir "uploads/" end diff --git a/app/workers/additional_email_confirmation_worker.rb b/app/workers/additional_email_confirmation_worker.rb index e5a304887b..26323fed1f 100644 --- a/app/workers/additional_email_confirmation_worker.rb +++ b/app/workers/additional_email_confirmation_worker.rb @@ -1,6 +1,6 @@ class AdditionalEmailConfirmationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(user_email_id) diff --git a/app/workers/after_bike_save_worker.rb b/app/workers/after_bike_save_worker.rb index cb4292967c..ceb2208c68 100644 --- a/app/workers/after_bike_save_worker.rb +++ b/app/workers/after_bike_save_worker.rb @@ -31,7 +31,7 @@ def serialized(bike) { auth_token: AUTH_TOKEN, bike: BikeV2ShowSerializer.new(bike, root: false).as_json, - update: bike.created_at > Time.now - 30.seconds + update: bike.created_at > Time.now - 30.seconds, } end diff --git a/app/workers/after_user_create_worker.rb b/app/workers/after_user_create_worker.rb index 826f994f13..676b1b6310 100644 --- a/app/workers/after_user_create_worker.rb +++ b/app/workers/after_user_create_worker.rb @@ -65,13 +65,13 @@ def import_user_attributes(user) address = user_bikes_for_attrs(user.id).map { |b| b.registration_address }.reject(&:blank?).last if address.present? user.attributes = { skip_geocode: true, - street: address["address"], - zipcode: address["zipcode"], - city: address["city"], - state: State.fuzzy_find(address["state"]), - country: Country.fuzzy_find(address["country"]), - latitude: address["latitude"], - longitude: address["longitude"] } + street: address["address"], + zipcode: address["zipcode"], + city: address["city"], + state: State.fuzzy_find(address["state"]), + country: Country.fuzzy_find(address["country"]), + latitude: address["latitude"], + longitude: address["longitude"] } end end user.save if user.changed? diff --git a/app/workers/approve_stolen_listing_worker.rb b/app/workers/approve_stolen_listing_worker.rb index c29cf9f2bf..29562314c1 100644 --- a/app/workers/approve_stolen_listing_worker.rb +++ b/app/workers/approve_stolen_listing_worker.rb @@ -1,10 +1,9 @@ class ApproveStolenListingWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true - + def perform(bike_id) StolenTwitterbotIntegration.new.send_tweet(bike_id) end - -end \ No newline at end of file +end diff --git a/app/workers/bike_book_update_worker.rb b/app/workers/bike_book_update_worker.rb index 5a4d471bff..abfdd59132 100644 --- a/app/workers/bike_book_update_worker.rb +++ b/app/workers/bike_book_update_worker.rb @@ -1,18 +1,18 @@ class BikeBookUpdateWorker include Sidekiq::Worker sidekiq_options queue: "high_priority", backtrace: true - + def perform(bike_id) bike = Bike.unscoped.where(id: bike_id).first if bike.present? bb_data = BikeBookIntegration.new.get_model(bike) if bb_data.present? - bb_data['components'].each do |bb_comp| - ctype = Ctype.friendly_find(bb_comp.delete 'component_type') + bb_data["components"].each do |bb_comp| + ctype = Ctype.friendly_find(bb_comp.delete "component_type") component = bike.components.where(ctype_id: ctype.id).first - if component.present? - next unless component.description == bb_comp['description'] + if component.present? + next unless component.description == bb_comp["description"] else component = Component.new(bike_id: bike.id, ctype_id: ctype.id) end @@ -21,8 +21,6 @@ def perform(bike_id) component.update_attributes(ComponentCreator.new.whitelist_attributes(bb_comp)) end end - end end - -end \ No newline at end of file +end diff --git a/app/workers/bulk_import_worker.rb b/app/workers/bulk_import_worker.rb index 0b353661c2..c3fd30ff1d 100644 --- a/app/workers/bulk_import_worker.rb +++ b/app/workers/bulk_import_worker.rb @@ -1,4 +1,4 @@ -require 'csv' +require "csv" class BulkImportWorker include Sidekiq::Worker @@ -81,10 +81,10 @@ def row_to_b_param_hash(row_with_whitespaces) user_name: row[:owner_name], additional_registration: row[:secondary_serial], send_email: @bulk_import.send_email, - creation_organization_id: @bulk_import.organization_id + creation_organization_id: @bulk_import.organization_id, }, # Photo need to be an array - only include if photo has a value - photos: row[:photo].present? ? [row[:photo]] : nil + photos: row[:photo].present? ? [row[:photo]] : nil, } end @@ -140,7 +140,7 @@ def header_name_map photo: %i[photo_url], owner_email: %i[email customer_email], frame_size: %i[size], - description: %i[product_description] + description: %i[product_description], } end end diff --git a/app/workers/cache_all_stolen_worker.rb b/app/workers/cache_all_stolen_worker.rb index 560b586afb..2d913338c6 100644 --- a/app/workers/cache_all_stolen_worker.rb +++ b/app/workers/cache_all_stolen_worker.rb @@ -1,6 +1,6 @@ class CacheAllStolenWorker include Sidekiq::Worker - sidekiq_options queue: 'carrierwave', backtrace: true, retry: false + sidekiq_options queue: "carrierwave", backtrace: true, retry: false attr_reader :filename def perform @@ -18,7 +18,7 @@ def output_url(uploader) end def file_prefix - Rails.env.test? ? '/spec/fixtures/tsv_creation/' : '' + Rails.env.test? ? "/spec/fixtures/tsv_creation/" : "" end def filename @@ -30,12 +30,12 @@ def tmp_path end def write_stolen - File.open(tmp_path, 'w') {} - File.open(tmp_path, 'a+') do |file| + File.open(tmp_path, "w") { } + File.open(tmp_path, "a+") do |file| file << '{"bikes": [' - Bike.stolen.find_each { |bike| file << BikeV2Serializer.new(bike, root: false).to_json + ',' } + Bike.stolen.find_each { |bike| file << BikeV2Serializer.new(bike, root: false).to_json + "," } end File.truncate(tmp_path, File.size(tmp_path) - 1) # remove final comma - File.open(tmp_path, 'a+') { |file| file << ']}' } + File.open(tmp_path, "a+") { |file| file << "]}" } end end diff --git a/app/workers/carrier_wave_process_worker.rb b/app/workers/carrier_wave_process_worker.rb index 16aa37b94c..118bf1c703 100644 --- a/app/workers/carrier_wave_process_worker.rb +++ b/app/workers/carrier_wave_process_worker.rb @@ -1,3 +1,3 @@ class CarrierWaveProcessWorker < ::CarrierWave::Workers::ProcessAsset - sidekiq_options queue: 'carrierwave', backtrace: true, retry: 1 + sidekiq_options queue: "carrierwave", backtrace: true, retry: 1 end diff --git a/app/workers/carrier_wave_store_worker.rb b/app/workers/carrier_wave_store_worker.rb index 6757ab4177..30e176fdf2 100644 --- a/app/workers/carrier_wave_store_worker.rb +++ b/app/workers/carrier_wave_store_worker.rb @@ -1,4 +1,3 @@ class CarrierWaveStoreWorker < ::CarrierWave::Workers::StoreAsset - sidekiq_options queue: 'carrierwave', backtrace: true, :retry => 3, :dead => false - -end \ No newline at end of file + sidekiq_options queue: "carrierwave", backtrace: true, :retry => 3, :dead => false +end diff --git a/app/workers/create_creation_states_worker.rb b/app/workers/create_creation_states_worker.rb index e69de29bb2..8b13789179 100644 --- a/app/workers/create_creation_states_worker.rb +++ b/app/workers/create_creation_states_worker.rb @@ -0,0 +1 @@ + diff --git a/app/workers/duplicate_bike_finder_worker.rb b/app/workers/duplicate_bike_finder_worker.rb index 81edf69657..4ca9a83ac8 100644 --- a/app/workers/duplicate_bike_finder_worker.rb +++ b/app/workers/duplicate_bike_finder_worker.rb @@ -9,7 +9,7 @@ def perform(bike_id) existing_duplicate = DuplicateBikeGroup.includes(:normalized_serial_segments). where(normalized_serial_segments: { segment: serial_segment.segment }).first if existing_duplicate.present? - serial_segment.update_attribute :duplicate_bike_group_id, existing_duplicate.id + serial_segment.update_attribute :duplicate_bike_group_id, existing_duplicate.id existing_duplicate.update_attribute :added_bike_at, Time.now else duplicate_segments = NormalizedSerialSegment.where(segment: serial_segment.segment) diff --git a/app/workers/email_admin_contact_stolen_worker.rb b/app/workers/email_admin_contact_stolen_worker.rb index f13f381523..417865ce81 100644 --- a/app/workers/email_admin_contact_stolen_worker.rb +++ b/app/workers/email_admin_contact_stolen_worker.rb @@ -1,6 +1,6 @@ class EmailAdminContactStolenWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(customer_contact_id) diff --git a/app/workers/email_confirmation_worker.rb b/app/workers/email_confirmation_worker.rb index 9ec022ef5d..6f1087f578 100644 --- a/app/workers/email_confirmation_worker.rb +++ b/app/workers/email_confirmation_worker.rb @@ -1,6 +1,6 @@ class EmailConfirmationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(user_id) diff --git a/app/workers/email_feedback_notification_worker.rb b/app/workers/email_feedback_notification_worker.rb index cfe68584ce..86f4d6d1d2 100644 --- a/app/workers/email_feedback_notification_worker.rb +++ b/app/workers/email_feedback_notification_worker.rb @@ -1,6 +1,6 @@ class EmailFeedbackNotificationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(feedback_id) diff --git a/app/workers/email_invoice_worker.rb b/app/workers/email_invoice_worker.rb index c0e9eaa9aa..e90001b93d 100644 --- a/app/workers/email_invoice_worker.rb +++ b/app/workers/email_invoice_worker.rb @@ -1,11 +1,10 @@ class EmailInvoiceWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(id) @payment = Payment.find(id) CustomerMailer.invoice_email(@payment).deliver_now end - -end \ No newline at end of file +end diff --git a/app/workers/email_lightspeed_notification_worker.rb b/app/workers/email_lightspeed_notification_worker.rb index 3b3ffde2d1..25e85c321f 100644 --- a/app/workers/email_lightspeed_notification_worker.rb +++ b/app/workers/email_lightspeed_notification_worker.rb @@ -1,6 +1,6 @@ class EmailLightspeedNotificationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(organization_id, api_key) @@ -8,5 +8,4 @@ def perform(organization_id, api_key) @organization = Organization.find(organization_id) AdminMailer.lightspeed_notification_email(@organization, @api_key).deliver_now end - -end \ No newline at end of file +end diff --git a/app/workers/email_no_admins_notification_worker.rb b/app/workers/email_no_admins_notification_worker.rb index b761c6f8a6..1b82bc3d7d 100644 --- a/app/workers/email_no_admins_notification_worker.rb +++ b/app/workers/email_no_admins_notification_worker.rb @@ -1,6 +1,6 @@ class EmailNoAdminsNotificationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(organization_id) diff --git a/app/workers/email_organization_invitation_worker.rb b/app/workers/email_organization_invitation_worker.rb index 7570b28aaf..c32bafe317 100644 --- a/app/workers/email_organization_invitation_worker.rb +++ b/app/workers/email_organization_invitation_worker.rb @@ -1,6 +1,6 @@ class EmailOrganizationInvitationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(org_invite_id) diff --git a/app/workers/email_ownership_invitation_worker.rb b/app/workers/email_ownership_invitation_worker.rb index 642f6e8d3c..68ceaecf5d 100644 --- a/app/workers/email_ownership_invitation_worker.rb +++ b/app/workers/email_ownership_invitation_worker.rb @@ -1,6 +1,6 @@ class EmailOwnershipInvitationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(ownership_id) diff --git a/app/workers/email_partial_registration_worker.rb b/app/workers/email_partial_registration_worker.rb index f642b3a3c9..6dafbf867a 100644 --- a/app/workers/email_partial_registration_worker.rb +++ b/app/workers/email_partial_registration_worker.rb @@ -1,6 +1,6 @@ class EmailPartialRegistrationWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(b_param_id) diff --git a/app/workers/email_recovered_from_link_worker.rb b/app/workers/email_recovered_from_link_worker.rb index 8032666840..ff7ee7ae78 100644 --- a/app/workers/email_recovered_from_link_worker.rb +++ b/app/workers/email_recovered_from_link_worker.rb @@ -1,6 +1,6 @@ class EmailRecoveredFromLinkWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(stolen_record_id) diff --git a/app/workers/email_reset_password_worker.rb b/app/workers/email_reset_password_worker.rb index aafc88b8aa..c08a66be0d 100644 --- a/app/workers/email_reset_password_worker.rb +++ b/app/workers/email_reset_password_worker.rb @@ -1,6 +1,6 @@ class EmailResetPasswordWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(user_id) diff --git a/app/workers/email_stolen_bike_alert_worker.rb b/app/workers/email_stolen_bike_alert_worker.rb index ac706bfdf0..b3c7a92e36 100644 --- a/app/workers/email_stolen_bike_alert_worker.rb +++ b/app/workers/email_stolen_bike_alert_worker.rb @@ -1,6 +1,6 @@ class EmailStolenBikeAlertWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(customer_contact_id) diff --git a/app/workers/email_welcome_worker.rb b/app/workers/email_welcome_worker.rb index c57589deb9..08e602f4a1 100644 --- a/app/workers/email_welcome_worker.rb +++ b/app/workers/email_welcome_worker.rb @@ -1,6 +1,6 @@ class EmailWelcomeWorker include Sidekiq::Worker - sidekiq_options queue: 'notify' + sidekiq_options queue: "notify" sidekiq_options backtrace: true def perform(user_id) diff --git a/app/workers/get_manufacturer_logo_worker.rb b/app/workers/get_manufacturer_logo_worker.rb index 415d026ede..e24268582e 100644 --- a/app/workers/get_manufacturer_logo_worker.rb +++ b/app/workers/get_manufacturer_logo_worker.rb @@ -1,18 +1,18 @@ class GetManufacturerLogoWorker include Sidekiq::Worker sidekiq_options queue: "low_priority", backtrace: true, :retry => false - + def perform(id) manufacturer = Manufacturer.find(id) return true if manufacturer.website.blank? || manufacturer.logo.present? - clearbit_url = "http://logo.clearbit.com/#{manufacturer.website.gsub(/\Ahttps?:\/\//i,'')}?size=400" + clearbit_url = "http://logo.clearbit.com/#{manufacturer.website.gsub(/\Ahttps?:\/\//i, "")}?size=400" status_response = Net::HTTP.get_response(URI(clearbit_url)) return true unless status_response.kind_of? Net::HTTPSuccess manufacturer.remote_logo_url = clearbit_url - manufacturer.logo_source = 'Clearbit' + manufacturer.logo_source = "Clearbit" manufacturer.save end end diff --git a/app/workers/image_associator_worker.rb b/app/workers/image_associator_worker.rb index 65b763e1e8..7afef06318 100644 --- a/app/workers/image_associator_worker.rb +++ b/app/workers/image_associator_worker.rb @@ -1,12 +1,11 @@ class ImageAssociatorWorker include Sidekiq::Worker sidekiq_options queue: "high_priority", backtrace: true - + def perform - BParam.where(image_processed: false).where('image IS NOT NULL').each do |b_param| + BParam.where(image_processed: false).where("image IS NOT NULL").each do |b_param| next unless b_param.created_bike.present? BikeCreatorAssociator.new(b_param).attach_photo(b_param.created_bike) end end - -end \ No newline at end of file +end diff --git a/app/workers/listicle_image_size_worker.rb b/app/workers/listicle_image_size_worker.rb index 903eb500a1..e98fcb7c67 100644 --- a/app/workers/listicle_image_size_worker.rb +++ b/app/workers/listicle_image_size_worker.rb @@ -1,22 +1,21 @@ class ListicleImageSizeWorker include Sidekiq::Worker - sidekiq_options queue: 'carrierwave' + sidekiq_options queue: "carrierwave" sidekiq_options backtrace: true - + def perform(id) listicle = Listicle.find(id) return true unless listicle.image.present? unless listicle.image_width.present? width, height = `identify -format "%wx%h" #{listicle.image_url}`.split(/x/) - listicle.image_width = width.gsub(/\D/,'').to_i - listicle.image_height = height.gsub(/\D/,'').to_i + listicle.image_width = width.gsub(/\D/, "").to_i + listicle.image_height = height.gsub(/\D/, "").to_i end if listicle.crop_top_offset.present? listicle.process_image_upload = true - listicle.image.recreate_versions! + listicle.image.recreate_versions! end listicle.save listicle.blog.save if listicle.blog.present? end - end diff --git a/app/workers/merge_additional_email_worker.rb b/app/workers/merge_additional_email_worker.rb index ce1407c49c..5550ba91c4 100644 --- a/app/workers/merge_additional_email_worker.rb +++ b/app/workers/merge_additional_email_worker.rb @@ -45,7 +45,7 @@ def merge_user_memberships(user_email, old_user) def find_old_user(email, user_id) user = User.fuzzy_unconfirmed_primary_email_find(email) return user if user.present? - user_email = UserEmail.where('user_id != ?', user_id).where(email: email).first + user_email = UserEmail.where("user_id != ?", user_id).where(email: email).first user_email && user_email.user end end diff --git a/app/workers/organization_export_worker.rb b/app/workers/organization_export_worker.rb index d2cb512f48..958324cbd4 100644 --- a/app/workers/organization_export_worker.rb +++ b/app/workers/organization_export_worker.rb @@ -1,7 +1,7 @@ class OrganizationExportWorker include Sidekiq::Worker sidekiq_options queue: "low_priority", backtrace: true, retry: false - LINK_BASE = "#{ENV['BASE_URL']}/bikes/".freeze + LINK_BASE = "#{ENV["BASE_URL"]}/bikes/".freeze attr_accessor :export # Only necessary for testing @@ -111,7 +111,7 @@ def value_for_header(header, bike) when "manufacturer" then bike.mnfg_name when "model" then bike.frame_model when "year" then bike.year - when "color" then bike.frame_colors.join(', ') + when "color" then bike.frame_colors.join(", ") when "serial" then bike.serial_number when "additional_registration_number" then bike.additional_registration when "phone" then bike.phone @@ -133,7 +133,7 @@ def assign_bike_code_and_increment(bike) code end - # This is difficult to test in an automated fashion, it's been tested by running it - so be careful about modifying + # This is difficult to test in an automated fashion, it's been tested by running it - so be careful about modifying def check_export_ebrake(row) return true if @export_ebraked # If it's already braked, don't check again # only check every so often, so we can halt processing via an external trip switch diff --git a/app/workers/remove_expired_file_cache_worker.rb b/app/workers/remove_expired_file_cache_worker.rb index 2b05483dc4..7895f39f87 100644 --- a/app/workers/remove_expired_file_cache_worker.rb +++ b/app/workers/remove_expired_file_cache_worker.rb @@ -1,6 +1,6 @@ class RemoveExpiredFileCacheWorker include Sidekiq::Worker - sidekiq_options queue: 'carrierwave', backtrace: true, retry: false + sidekiq_options queue: "carrierwave", backtrace: true, retry: false def perform expired_file_hashes.each { |fh| FileCacheMaintainer.remove_file(fh) } @@ -9,7 +9,7 @@ def perform def expired_file_hashes expiration = (Time.now - 2.days).to_i FileCacheMaintainer.files.select do |file| - file['updated_at'].to_i < expiration + file["updated_at"].to_i < expiration end end end diff --git a/app/workers/scheduled_worker.rb b/app/workers/scheduled_worker.rb index cb9194c772..86c0c46331 100644 --- a/app/workers/scheduled_worker.rb +++ b/app/workers/scheduled_worker.rb @@ -23,7 +23,7 @@ def self.write_history(record) end def self.redis_queue - "queue:#{sidekiq_options['queue']}".freeze + "queue:#{sidekiq_options["queue"]}".freeze end def self.enqueued? diff --git a/app/workers/send_newsletter_worker.rb b/app/workers/send_newsletter_worker.rb index da22d7200f..0ebdb2d42b 100644 --- a/app/workers/send_newsletter_worker.rb +++ b/app/workers/send_newsletter_worker.rb @@ -1,7 +1,7 @@ class SendNewsletterWorker include Sidekiq::Worker - sidekiq_options queue: 'notify', backtrace: true, retry: false - API_KEY = ENV['SPARKPOST_API_KEY'] + sidekiq_options queue: "notify", backtrace: true, retry: false + API_KEY = ENV["SPARKPOST_API_KEY"] def client; @client ||= SimpleSpark::Client.new(api_key: API_KEY) end @@ -22,16 +22,16 @@ def mailing_properties(template, user) { options: { open_tracking: true, click_tracking: true }, campaign_id: "#{template}_campaign", - return_path: 'support@bikeindex.org', + return_path: "support@bikeindex.org", content: { template_id: template, - use_draft_template: true + use_draft_template: true, }, - recipients: [{ + recipients: [{ address: { email: user.email, name: user.display_name }, metadata: {}, - substitution_data: { name: user.name || '', user_id: user.username } - }] + substitution_data: { name: user.name || "", user_id: user.username }, + }], } end end diff --git a/app/workers/tsv_creator_worker.rb b/app/workers/tsv_creator_worker.rb index 4e58e5cb26..19546271c8 100644 --- a/app/workers/tsv_creator_worker.rb +++ b/app/workers/tsv_creator_worker.rb @@ -1,18 +1,17 @@ class TsvCreatorWorker include Sidekiq::Worker - require 'tsv_creator' - require 'file_cache_maintainer' - sidekiq_options queue: 'carrierwave' + require "tsv_creator" + require "file_cache_maintainer" + sidekiq_options queue: "carrierwave" sidekiq_options backtrace: true - - def perform(tsv_method, true_and_false=false) + + def perform(tsv_method, true_and_false = false) creator = TsvCreator.new if true_and_false - creator.send(tsv_method, true) - creator.send(tsv_method, false) + creator.send(tsv_method, true) + creator.send(tsv_method, false) else creator.send(tsv_method) end end - -end \ No newline at end of file +end diff --git a/app/workers/unused_ownership_removal_worker.rb b/app/workers/unused_ownership_removal_worker.rb index 84dad51385..63397147b7 100644 --- a/app/workers/unused_ownership_removal_worker.rb +++ b/app/workers/unused_ownership_removal_worker.rb @@ -1,11 +1,11 @@ class UnusedOwnershipRemovalWorker include Sidekiq::Worker sidekiq_options queue: "low_priority", backtrace: true - + def perform(id) ownership = Ownership.find(id) unless Bike.unscoped.where(id: ownership.bike_id).present? - ownership.update_attribute :current, false + ownership.update_attribute :current, false end end end diff --git a/app/workers/update_auth_token_worker.rb b/app/workers/update_auth_token_worker.rb index 686913e4d5..250ad6c24e 100644 --- a/app/workers/update_auth_token_worker.rb +++ b/app/workers/update_auth_token_worker.rb @@ -2,11 +2,10 @@ class UpdateAuthTokenWorker include Sidekiq::Worker sidekiq_options queue: "high_priority", backtrace: true - + def perform(id) user = User.find(id) user.generate_auth_token user.save end - -end \ No newline at end of file +end diff --git a/config/application.rb b/config/application.rb index d006c60622..ec0bd62d68 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,7 +1,7 @@ -require File.expand_path('../boot', __FILE__) +require File.expand_path("../boot", __FILE__) -require 'rails/all' -require 'rack/throttle' +require "rails/all" +require "rack/throttle" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. @@ -11,13 +11,13 @@ module Bikeindex class Application < Rails::Application # Use our custom error pages config.exceptions_app = self.routes - require 'draper' - Draper::Railtie.initializers.delete_if {|initializer| initializer.name == 'draper.setup_active_model_serializers' } + require "draper" + Draper::Railtie.initializers.delete_if { |initializer| initializer.name == "draper.setup_active_model_serializers" } # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. - config.autoload_paths << Rails.root.join('lib/') - config.autoload_paths << Rails.root.join('lib/integrations') + config.autoload_paths << Rails.root.join("lib/") + config.autoload_paths << Rails.root.join("lib/integrations") # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] @@ -28,7 +28,7 @@ class Application < Rails::Application config.active_record.schema_format = :sql # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] + config.i18n.load_path += Dir[Rails.root.join("config", "locales", "**", "*.{rb,yml}").to_s] config.i18n.default_locale = :en config.i18n.enforce_available_locales = false @@ -36,12 +36,12 @@ class Application < Rails::Application config.active_record.raise_in_transactional_callbacks = true # Throttle stuff - config.middleware.use Rack::Throttle::Minute, :max => ENV['MIN_MAX_RATE'].to_i, :cache => Redis.new, :key_prefix => :throttle + config.middleware.use Rack::Throttle::Minute, :max => ENV["MIN_MAX_RATE"].to_i, :cache => Redis.new, :key_prefix => :throttle config.to_prepare do - Doorkeeper::ApplicationsController.layout 'doorkeeper' - Doorkeeper::AuthorizationsController.layout 'doorkeeper' - Doorkeeper::AuthorizedApplicationsController.layout 'doorkeeper' + Doorkeeper::ApplicationsController.layout "doorkeeper" + Doorkeeper::AuthorizationsController.layout "doorkeeper" + Doorkeeper::AuthorizedApplicationsController.layout "doorkeeper" end config.generators do |g| diff --git a/config/boot.rb b/config/boot.rb index 6b750f00b1..fb24cf2ed5 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,3 +1,3 @@ -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) -require 'bundler/setup' # Set up gems listed in the Gemfile. +require "bundler/setup" # Set up gems listed in the Gemfile. diff --git a/config/environment.rb b/config/environment.rb index b2dee958f2..cd22a44f3c 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,8 +1,8 @@ # Load the landing_pages organizations -require File.expand_path('../landing_pages', __FILE__) +require File.expand_path("../landing_pages", __FILE__) # Load the Rails application. -require File.expand_path('../application', __FILE__) +require File.expand_path("../application", __FILE__) # Initialize the Rails application. Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb index bb725c00f2..ee7566a52d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -11,18 +11,18 @@ config.eager_load = false # Show full error reports and disable caching. - config.consider_all_requests_local = true + config.consider_all_requests_local = true config.action_controller.perform_caching = false config.cache_store = :dalli_store, - { namespace: Bikeindex, expires_in: 0, compress: true } + { namespace: Bikeindex, expires_in: 0, compress: true } config.action_mailer.raise_delivery_errors = true - config.action_mailer.default_url_options = { host: 'localhost', port: 3001 } + config.action_mailer.default_url_options = { host: "localhost", port: 3001 } config.action_mailer.delivery_method = :smtp config.action_mailer.perform_deliveries = true config.action_mailer.smtp_settings = { - address: 'localhost', - port: 1025 + address: "localhost", + port: 1025, } # Print deprecation notices to the Rails logger. @@ -51,7 +51,7 @@ config.lograge.custom_options = lambda do |event| { remote_ip: event.payload[:ip], - params: event.payload[:params].except('controller', 'action', 'format', 'id') + params: event.payload[:params].except("controller", "action", "format", "id"), } end @@ -69,14 +69,14 @@ # Make sure we reload the API after every request! @last_api_change = Time.now api_reloader = ActiveSupport::FileUpdateChecker.new(Dir["#{Rails.root}/app/controllers/api/v2/**/*.rb"]) do |reloader| - times = Dir["#{Rails.root}/app/api/**/*.rb"].map{|f| File.mtime(f) } - files = Dir["#{Rails.root}/app/api/**/*.rb"].map{|f| f } + times = Dir["#{Rails.root}/app/api/**/*.rb"].map { |f| File.mtime(f) } + files = Dir["#{Rails.root}/app/api/**/*.rb"].map { |f| f } - Rails.logger.debug '! Change detected: reloading following files:' - files.each_with_index do |s,i| + Rails.logger.debug "! Change detected: reloading following files:" + files.each_with_index do |s, i| if times[i] > @last_api_change Rails.logger.debug " - #{s}" - load s + load s end end diff --git a/config/environments/production.rb b/config/environments/production.rb index 9cfb276870..f572d1f49f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,6 +1,6 @@ Rails.application.configure do # Verifies that versions and hashed value of the package contents in the project's package.json -config.webpacker.check_yarn_integrity = false + config.webpacker.check_yarn_integrity = false # Settings specified here will take precedence over those in config/application.rb. # Use lograge for logging to production @@ -10,7 +10,7 @@ config.lograge.custom_options = lambda do |event| { remote_ip: event.payload[:ip], - params: event.payload[:params].except('controller', 'action', 'format', 'id') + params: event.payload[:params].except("controller", "action", "format", "id"), } end @@ -27,7 +27,7 @@ config.eager_load = true # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false + config.consider_all_requests_local = false config.action_controller.perform_caching = true config.cache_store = :dalli_store, { namespace: Bikeindex, expires_in: 0, compress: true } @@ -39,7 +39,7 @@ # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. - config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + config.serve_static_files = ENV["RAILS_SERVE_STATIC_FILES"].present? # Compress JavaScripts and CSS. config.assets.js_compressor = :uglifier @@ -81,6 +81,6 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false - config.action_mailer.default_url_options = { protocol: 'https', host: 'bikeindex.org' } + config.action_mailer.default_url_options = { protocol: "https", host: "bikeindex.org" } config.action_mailer.delivery_method = :smtp end diff --git a/config/environments/test.rb b/config/environments/test.rb index 155240ed48..b154cfadcd 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -13,11 +13,11 @@ config.eager_load = false # Configure static file server for tests with Cache-Control for performance. - config.serve_static_files = true - config.static_cache_control = 'public, max-age=3600' + config.serve_static_files = true + config.static_cache_control = "public, max-age=3600" # Show full error reports and disable caching. - config.consider_all_requests_local = true + config.consider_all_requests_local = true config.action_controller.perform_caching = false # Raise exceptions instead of rendering exception templates. @@ -39,5 +39,5 @@ # Raises error for missing translations # config.action_view.raise_on_missing_translations = true - config.action_mailer.default_url_options = { host: ENV['BASE_URL'] } + config.action_mailer.default_url_options = { host: ENV["BASE_URL"] } end diff --git a/config/initializers/admin_restriction.rb b/config/initializers/admin_restriction.rb index 089fdaf6cf..a985836faa 100644 --- a/config/initializers/admin_restriction.rb +++ b/config/initializers/admin_restriction.rb @@ -1,7 +1,7 @@ class AdminRestriction def self.matches?(req) - auth = Rack::Session::Cookie::Base64::Marshal.new.decode(req.cookies["auth"]) + auth = Rack::Session::Cookie::Base64::Marshal.new.decode(req.cookies["auth"]) user = User.from_auth(auth) return user && user.superuser? end -end \ No newline at end of file +end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index ddc08557a9..f4c2c4b0a9 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -1,7 +1,7 @@ # Be sure to restart your server when you modify this file. # Version of your assets, change this if you want to expire all your assets. -Rails.application.config.assets.version = '1.2' +Rails.application.config.assets.version = "1.2" Rails.application.config.assets.precompile += %w( graphs.js embed.js embed_user.js documentation_v2_and_v3.js diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index c6cabdd445..7319d79087 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -8,7 +8,7 @@ provider: "AWS", aws_access_key_id: ENV["S3_ACCESS_KEY"], aws_secret_access_key: ENV["S3_SECRET_KEY"], - region: "us-east-1" + region: "us-east-1", } config.fog_directory = ENV["S3_BUCKET"] @@ -21,12 +21,13 @@ module MiniMagick # check for images that are too large def validate_dimensions manipulate! do |img| - if img.dimensions.any?{|i| i > 8000 } - raise CarrierWave::ProcessingError, "dimensions too large" + if img.dimensions.any? { |i| i > 8000 } + raise CarrierWave::ProcessingError, "dimensions too large" end img end end + # Rotates the image based on the EXIF Orientation def fix_exif_rotation manipulate! do |img| @@ -34,7 +35,8 @@ def fix_exif_rotation img = yield(img) if block_given? img end - end + end + # Strips out all embedded information from the image def strip manipulate! do |img| diff --git a/config/initializers/cookie_verification_secret.rb b/config/initializers/cookie_verification_secret.rb index 77e468b271..b647a9fdec 100644 --- a/config/initializers/cookie_verification_secret.rb +++ b/config/initializers/cookie_verification_secret.rb @@ -1 +1 @@ -Rails.application.config.cookie_secret = ENV['VERIFICATION_SECRET'] \ No newline at end of file +Rails.application.config.cookie_secret = ENV["VERIFICATION_SECRET"] diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index aab3f72442..caa9167c35 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -1,14 +1,14 @@ OAUTH_SCOPES = %i[ - public - read_user - write_user - read_bikes - write_bikes - read_bikewise - write_bikewise - read_organization_membership + public + read_user + write_user + read_bikes + write_bikes + read_bikewise + write_bikewise + read_organization_membership write_organizations - unconfirmed + unconfirmed ].freeze if Rails.env.development? && defined?(User) && defined?(User.first) diff --git a/config/initializers/email_normalizer.rb b/config/initializers/email_normalizer.rb index f04b26720d..505c7428c5 100644 --- a/config/initializers/email_normalizer.rb +++ b/config/initializers/email_normalizer.rb @@ -1,5 +1,5 @@ class EmailNormalizer def self.normalize(email = nil) - (email || '').strip.downcase + (email || "").strip.downcase end -end \ No newline at end of file +end diff --git a/config/initializers/feature_flag_config.rb b/config/initializers/feature_flag_config.rb index 2ba82b17d6..e1428c6b0f 100644 --- a/config/initializers/feature_flag_config.rb +++ b/config/initializers/feature_flag_config.rb @@ -1,4 +1,4 @@ -require 'redis' +require "redis" $redis = Redis.new $rollout = Rollout.new($redis) @@ -8,4 +8,4 @@ $rollout.define_group(:superuser) { |user| user.superuser } $rollout.define_group(:developer_or_superuser) { |user| user.superuser || user.developer } -$rollout.activate_group(:preview, :developer_or_superuser) \ No newline at end of file +$rollout.activate_group(:preview, :developer_or_superuser) diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb index 0956a0136d..d31a9cfb32 100644 --- a/config/initializers/geocoder.rb +++ b/config/initializers/geocoder.rb @@ -5,6 +5,6 @@ use_https: true, api_key: ENV["GOOGLE_GEOCODER"], ip_lookup: :maxmind, - maxmind: { service: :city, api_key: ENV["MAXMIND_KEY"] } + maxmind: { service: :city, api_key: ENV["MAXMIND_KEY"] }, ) end diff --git a/config/initializers/grape_values.rb b/config/initializers/grape_values.rb index 1e6874658b..080cfa8b9b 100644 --- a/config/initializers/grape_values.rb +++ b/config/initializers/grape_values.rb @@ -1,11 +1,11 @@ -CYCLE_TYPE_NAMES = CycleType::NAMES.values.map(&:downcase) rescue ['bike'] +CYCLE_TYPE_NAMES = CycleType::NAMES.values.map(&:downcase) rescue ["bike"] if Rails.env.test? - CTYPE_NAMES = ['wheel', 'headset'] - COLOR_NAMES = ['black'] - COUNTRY_ISOS = ['US'] + CTYPE_NAMES = ["wheel", "headset"] + COLOR_NAMES = ["black"] + COUNTRY_ISOS = ["US"] else CTYPE_NAMES = !!Ctype && Ctype.pluck(:name).map(&:downcase) rescue [] COLOR_NAMES = !!Color && Color.pluck(:name).map(&:downcase) rescue [] COUNTRY_ISOS = !!Color && Country.pluck(:iso) rescue [] -end \ No newline at end of file +end diff --git a/config/initializers/instrumentation.rb b/config/initializers/instrumentation.rb index da985372bf..cdf85c269b 100644 --- a/config/initializers/instrumentation.rb +++ b/config/initializers/instrumentation.rb @@ -1,8 +1,8 @@ unless Rails.env.test? - ActiveSupport::Notifications.subscribe('grape_key') do |name, starts, ends, notification_id, payload| + ActiveSupport::Notifications.subscribe("grape_key") do |name, starts, ends, notification_id, payload| time = payload.delete(:time) Rails.logger.info payload.except(:response) .merge(time.merge(duration: time.delete(:total))) .to_json end -end \ No newline at end of file +end diff --git a/config/initializers/localeapp.rb b/config/initializers/localeapp.rb index cb2135dc74..9099ff84ea 100644 --- a/config/initializers/localeapp.rb +++ b/config/initializers/localeapp.rb @@ -15,4 +15,4 @@ # # If you prefer to turn off so potentially insecure yaml is not raised. # # config.raise_on_insecure_yaml = false # end -# end \ No newline at end of file +# end diff --git a/config/initializers/mailer_configuration.rb b/config/initializers/mailer_configuration.rb index f5ddfcb15a..d42a46ffbc 100644 --- a/config/initializers/mailer_configuration.rb +++ b/config/initializers/mailer_configuration.rb @@ -1,9 +1,9 @@ unless Rails.env.test? ActionMailer::Base.smtp_settings = { - port: ENV['SPARKPOST_PORT'], - address: 'smtp.sparkpostmail.com', - user_name: ENV['SPARKPOST_USERNAME'], - password: ENV['SPARKPOST_PASSWORD'], - authentication: :plain + port: ENV["SPARKPOST_PORT"], + address: "smtp.sparkpostmail.com", + user_name: ENV["SPARKPOST_USERNAME"], + password: ENV["SPARKPOST_PASSWORD"], + authentication: :plain, } -end \ No newline at end of file +end diff --git a/config/initializers/markdown_handler.rb b/config/initializers/markdown_handler.rb index c2ca841570..a08295c9dc 100644 --- a/config/initializers/markdown_handler.rb +++ b/config/initializers/markdown_handler.rb @@ -10,4 +10,4 @@ def self.call(template) end ActionView::Template.register_template_handler :md, MarkdownHandler -ActionView::Template.register_template_handler :markdown, MarkdownHandler \ No newline at end of file +ActionView::Template.register_template_handler :markdown, MarkdownHandler diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index f6fdceb30e..51eb68b403 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -1,4 +1,4 @@ Rails.application.config.middleware.use OmniAuth::Builder do - provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], scope: 'email' - provider :strava, ENV['STRAVA_KEY'], ENV['STRAVA_SECRET'], scope: 'public' -end \ No newline at end of file + provider :facebook, ENV["FACEBOOK_KEY"], ENV["FACEBOOK_SECRET"], scope: "email" + provider :strava, ENV["STRAVA_KEY"], ENV["STRAVA_SECRET"], scope: "public" +end diff --git a/config/initializers/phonifyer.rb b/config/initializers/phonifyer.rb index 74209c1350..15d87bcf42 100644 --- a/config/initializers/phonifyer.rb +++ b/config/initializers/phonifyer.rb @@ -3,9 +3,9 @@ def self.phonify(string) return nil unless string.present? if string.strip[/\A\+/] cc = string.strip[/\A\+\d*/] - "#{cc} #{string.strip.gsub(cc, '').gsub(/\D/, '')}" + "#{cc} #{string.strip.gsub(cc, "").gsub(/\D/, "")}" else - string.strip.gsub(/\D/, '') + string.strip.gsub(/\D/, "") end end @@ -16,7 +16,7 @@ def self.display(string) # Split at 3rd character, again 3 characters later, again with all the chars formatted = [3, 3, 10].each_with_index.collect do |amount, index| end_num[(index * 3), amount] - end.join('.') - [str[/\A\+\d*/], formatted].reject(&:blank?).join(' ') + end.join(".") + [str[/\A\+\d*/], formatted].reject(&:blank?).join(" ") end end diff --git a/config/initializers/rack_profiler.rb b/config/initializers/rack_profiler.rb index d536ce37f1..f78237b99b 100644 --- a/config/initializers/rack_profiler.rb +++ b/config/initializers/rack_profiler.rb @@ -1,12 +1,12 @@ -if Rails.env != 'test' - require 'rack-mini-profiler' - require 'flamegraph' +if Rails.env != "test" + require "rack-mini-profiler" + require "flamegraph" # initialization is skipped so trigger it Rack::MiniProfilerRails.initialize!(Rails.application) # Store in redis because production usage. Fails without configuring storage options :( - Rack::MiniProfiler.config.storage_options = { } + Rack::MiniProfiler.config.storage_options = {} Rack::MiniProfiler.config.storage = Rack::MiniProfiler::RedisStore - Rack::MiniProfiler.config.position = 'left' + Rack::MiniProfiler.config.position = "left" end diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb index 17034b642c..d7c54efdb3 100644 --- a/config/initializers/redis.rb +++ b/config/initializers/redis.rb @@ -1 +1 @@ -Redis.current = Redis.new \ No newline at end of file +Redis.current = Redis.new diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb index 93236512cd..64d48be413 100644 --- a/config/initializers/secret_token.rb +++ b/config/initializers/secret_token.rb @@ -1,2 +1,2 @@ -Bikeindex::Application.config.secret_token = ENV['SESSION_SECRET'] -Bikeindex::Application.config.secret_key_base = ENV['SECRET_KEY_BASE'] +Bikeindex::Application.config.secret_token = ENV["SESSION_SECRET"] +Bikeindex::Application.config.secret_key_base = ENV["SECRET_KEY_BASE"] diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 10c76364ae..71e2f23319 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,3 +1,3 @@ -domain = Rails.env.production? ? 'bikeindex.org' : 'localhost' +domain = Rails.env.production? ? "bikeindex.org" : "localhost" -Bikeindex::Application.config.session_store :cookie_store, key: '_bikeindex_session', domain: domain +Bikeindex::Application.config.session_store :cookie_store, key: "_bikeindex_session", domain: domain diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index b2b8742e17..b8d1b100f4 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,3 +1,3 @@ Sidekiq.configure_server do |config| - config.redis = { driver: 'hiredis' } -end \ No newline at end of file + config.redis = { driver: "hiredis" } +end diff --git a/config/initializers/slugifyer.rb b/config/initializers/slugifyer.rb index e315b04560..a924499dd3 100644 --- a/config/initializers/slugifyer.rb +++ b/config/initializers/slugifyer.rb @@ -1,24 +1,24 @@ class Slugifyer def self.slugify(string) - string.to_s.strip.gsub(/\s/, '-').gsub(/([^A-Za-z0-9_\-]+)/, '').downcase + string.to_s.strip.gsub(/\s/, "-").gsub(/([^A-Za-z0-9_\-]+)/, "").downcase end def self.book_slug(string) slug = I18n.transliterate(string.to_s.downcase) key_hash = { - '\s((bi)?cycles?|bikes?)' => ' ', - '\+' => 'plus', - '([^A-Za-z0-9])' => ' ' + '\s((bi)?cycles?|bikes?)' => " ", + '\+' => "plus", + "([^A-Za-z0-9])" => " ", } key_hash.keys.each do |k| slug.gsub!(/#{k}/i, key_hash[k]) end - slug.strip.gsub(/\s+/, '_') # strip and then turn any length of spaces into underscores + slug.strip.gsub(/\s+/, "_") # strip and then turn any length of spaces into underscores end def self.manufacturer(string) return nil unless string - book_slug(string.gsub(/\sco(\.|mpany)/i, ' ') - .gsub(/\s(frame)?works/i, ' ').gsub(/\([^\)]*\)/i, '')) + book_slug(string.gsub(/\sco(\.|mpany)/i, " ") + .gsub(/\s(frame)?works/i, " ").gsub(/\([^\)]*\)/i, "")) end end diff --git a/config/initializers/stripe.rb b/config/initializers/stripe.rb index 124eab4f48..463af6c05e 100644 --- a/config/initializers/stripe.rb +++ b/config/initializers/stripe.rb @@ -1,6 +1,6 @@ Rails.configuration.stripe = { publishable_key: ENV["STRIPE_PUBLISHABLE_KEY"], - secret_key: ENV["STRIPE_SECRET_KEY"] + secret_key: ENV["STRIPE_SECRET_KEY"], } Stripe.api_key = ENV["STRIPE_SECRET_KEY"] diff --git a/config/initializers/twitter.rb b/config/initializers/twitter.rb index e2c66e87a6..2c54e10cca 100644 --- a/config/initializers/twitter.rb +++ b/config/initializers/twitter.rb @@ -1,6 +1,6 @@ Twitter.configure do |config| - config.consumer_key = ENV['TWITTER_CONSUMER_KEY'] - config.consumer_secret = ENV['TWITTER_CONSUMER_SECRET'] - config.oauth_token = ENV['TWITTER_OAUTH_TOKEN'] - config.oauth_token_secret = ENV['TWITTER_OAUTH_TOKEN_SECRET'] + config.consumer_key = ENV["TWITTER_CONSUMER_KEY"] + config.consumer_secret = ENV["TWITTER_CONSUMER_SECRET"] + config.oauth_token = ENV["TWITTER_OAUTH_TOKEN"] + config.oauth_token_secret = ENV["TWITTER_OAUTH_TOKEN_SECRET"] end diff --git a/config/initializers/urlify.rb b/config/initializers/urlify.rb index e1d72713de..21e5b6ea98 100644 --- a/config/initializers/urlify.rb +++ b/config/initializers/urlify.rb @@ -11,7 +11,7 @@ def self.urlify(string) end def self.is_url(string) - true if uri?('http://' + string) + true if uri?("http://" + string) end def self.uri?(string) @@ -22,5 +22,4 @@ def self.uri?(string) rescue URI::InvalidURIError false end - end diff --git a/config/routes.rb b/config/routes.rb index b97baff6f5..7abcc439d5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,17 +1,17 @@ -require 'soulheart/server' -require 'sidekiq/web' +require "soulheart/server" +require "sidekiq/web" Sidekiq::Web.set :session_secret, Rails.application.secrets[:secret_key_base] Bikeindex::Application.routes.draw do use_doorkeeper do - controllers applications: 'oauth/applications' - controllers authorizations: 'oauth/authorizations' - controllers authorized_applications: 'oauth/authorized_applications' + controllers applications: "oauth/applications" + controllers authorizations: "oauth/authorizations" + controllers authorized_applications: "oauth/authorized_applications" end - get '/shop', to: redirect('https://bikeindex.myshopify.com'), as: :shop - get '/store', to: redirect('https://bikeindex.myshopify.com'), as: :store - get '/discuss', to: redirect('https://discuss.bikeindex.org'), as: :discuss - get 'discourse_authentication', to: 'discourse_authentication#index' + get "/shop", to: redirect("https://bikeindex.myshopify.com"), as: :shop + get "/store", to: redirect("https://bikeindex.myshopify.com"), as: :store + get "/discuss", to: redirect("https://discuss.bikeindex.org"), as: :discuss + get "discourse_authentication", to: "discourse_authentication#index" resources :organizations do member do @@ -21,32 +21,32 @@ end end - get '/', to: redirect(:root_url, subdomain: false), constraints: { subdomain: 'stolen' } - root to: 'welcome#index' + get "/", to: redirect(:root_url, subdomain: false), constraints: { subdomain: "stolen" } + root to: "welcome#index" LandingPages::ORGANIZATIONS.each do |slug| - get slug, to: 'landing_pages#show', organization_id: slug + get slug, to: "landing_pages#show", organization_id: slug end %w(for_shops for_advocacy for_law_enforcement for_schools ambassadors_how_to ambassadors_current ascend).freeze.each do |page| - get page, controller: 'landing_pages', action: page + get page, controller: "landing_pages", action: page end - get 'ambassadors', to: redirect('/ambassadors_how_to') # Because convenience + get "ambassadors", to: redirect("/ambassadors_how_to") # Because convenience %w(update_browser user_home choose_registration goodbye bike_creation_graph).freeze.each do |page| - get page, controller: 'welcome', action: page + get page, controller: "welcome", action: page end - get 'update_browser', to: 'welcome#update_browser' - get 'user_home', to: 'welcome#user_home' - get 'choose_registration', to: 'welcome#choose_registration' - get 'goodbye', to: 'welcome#goodbye' - get 'bike_creation_graph', to: 'welcome#bike_creation_graph' + get "update_browser", to: "welcome#update_browser" + get "user_home", to: "welcome#user_home" + get "choose_registration", to: "welcome#choose_registration" + get "goodbye", to: "welcome#goodbye" + get "bike_creation_graph", to: "welcome#bike_creation_graph" get "recovery_stories", to: "welcome#recovery_stories", as: :recovery_stories resource :session, only: [:new, :create, :destroy] - get 'logout', to: 'sessions#destroy' + get "logout", to: "sessions#destroy" resources :payments resources :documentation, only: [:index] do @@ -65,11 +65,11 @@ resources :stolen_notifications, only: [:create, :new] resources :feedbacks, only: [:index, :create] - get 'vendor_signup', to: redirect('/organizations/new') - get 'connect_lightspeed', to: 'organizations#connect_lightspeed' - get 'help', to: 'feedbacks#index' - get 'feedbacks/new', to: redirect('/help') - %w(support contact contact_us).each { |p| get p, to: redirect('/help') } + get "vendor_signup", to: redirect("/organizations/new") + get "connect_lightspeed", to: "organizations#connect_lightspeed" + get "help", to: "feedbacks#index" + get "feedbacks/new", to: redirect("/help") + %w(support contact contact_us).each { |p| get p, to: redirect("/help") } resources :users, only: %i[new create show edit update] do collection do @@ -82,20 +82,20 @@ end member { get "unsubscribe" } end - get :my_account, to: 'users#edit', as: :my_account - get :accept_vendor_terms, to: 'users#accept_vendor_terms' - get :accept_terms, to: 'users#accept_terms' + get :my_account, to: "users#edit", as: :my_account + get :accept_vendor_terms, to: "users#accept_vendor_terms" + get :accept_terms, to: "users#accept_terms" resources :user_embeds, only: [:show] resources :user_emails, only: [:destroy] do member do - post 'resend_confirmation' - get 'confirm' - post 'make_primary' + post "resend_confirmation" + get "confirm" + post "make_primary" end end resources :news, only: [:show, :index] resources :blogs, only: [:show, :index] - get 'blog', to: redirect('/news') + get "blog", to: redirect("/news") resources :public_images, only: [:create, :show, :edit, :update, :destroy] do collection do @@ -115,7 +115,7 @@ get :scanned get :pdf end - resource :recovery, only: [:edit, :update], controller: 'bikes/recovery' + resource :recovery, only: [:edit, :update], controller: "bikes/recovery" end get "bikes/scanned/:scanned_id", to: "bikes#scanned" @@ -123,7 +123,7 @@ resources :locks, except: [:show, :index] namespace :admin do - root to: 'dashboard#index' + root to: "dashboard#index" resources :bikes do collection do get :duplicates @@ -134,21 +134,21 @@ end member { get :get_destroy } end - get 'invitations', to: 'dashboard#invitations' - get 'maintenance', to: 'dashboard#maintenance' - put 'update_tsv_blacklist', to: 'dashboard#update_tsv_blacklist' - get 'tsvs', to: 'dashboard#tsvs' - get 'bust_z_cache', to: 'dashboard#bust_z_cache' - get 'destroy_example_bikes', to: 'dashboard#destroy_example_bikes' - get "invoices", to: 'payments#invoices', as: :invoices + get "invitations", to: "dashboard#invitations" + get "maintenance", to: "dashboard#maintenance" + put "update_tsv_blacklist", to: "dashboard#update_tsv_blacklist" + get "tsvs", to: "dashboard#tsvs" + get "bust_z_cache", to: "dashboard#bust_z_cache" + get "destroy_example_bikes", to: "dashboard#destroy_example_bikes" + get "invoices", to: "payments#invoices", as: :invoices resources :memberships, :organization_invitations, :bulk_imports, :exports, :paints, :ads, :recovery_displays, :mail_snippets, :paid_features, :payments resources :organizations do resources :custom_layouts, only: [:index, :edit, :update], controller: "organizations/custom_layouts" resources :invoices, controller: "organizations/invoices" end - get 'recover_organization', to: 'organizations#recover' - get 'show_deleted_organizations', to: 'organizations#show_deleted' + get "recover_organization", to: "organizations#recover" + get "show_deleted_organizations", to: "organizations#show_deleted" resources :flavor_texts, only: [:destroy, :create] resources :stolen_bikes do @@ -176,7 +176,7 @@ end resources :ownerships, only: [:edit, :update] resources :tweets - get 'blog', to: redirect('/news') + get "blog", to: redirect("/news") resources :news do collection do get :listicle_image_edit @@ -191,8 +191,8 @@ resources :users, only: [:index, :show, :edit, :update, :destroy] end - namespace :api, defaults: { format: 'json' } do - get '/', to: redirect('/documentation') + namespace :api, defaults: { format: "json" } do + get "/", to: redirect("/documentation") namespace :v1 do resources :bikes, only: [:index, :show, :create] do collection do @@ -218,55 +218,55 @@ post :send_request end end - get 'not_found', to: 'api_v1#not_found' - get '*a', to: 'api_v1#not_found' + get "not_found", to: "api_v1#not_found" + get "*a", to: "api_v1#not_found" end - mount Soulheart::Server, at: '/autocomplete' + mount Soulheart::Server, at: "/autocomplete" end - mount API::Base => '/api' + mount API::Base => "/api" resources :stolen, only: [:index, :show] do collection do - get 'current_tsv' + get "current_tsv" end end resources :manufacturers, only: [:index] do - collection { get 'tsv' } + collection { get "tsv" } end - get 'manufacturers_tsv', to: 'manufacturers#tsv' + get "manufacturers_tsv", to: "manufacturers#tsv" resource :integrations, only: [:create] - get '/auth/:provider/callback', to: 'integrations#create' - get '/auth/failure', to: 'integrations#integrations_controller_creation_error' + get "/auth/:provider/callback", to: "integrations#create" + get "/auth/failure", to: "integrations#integrations_controller_creation_error" %w(support_bike_index support_the_index support_the_bike_index protect_your_bike serials about where vendor_terms resources image_resources privacy terms how_not_to_buy_stolen dev_and_design lightspeed).freeze.each do |page| - get page, controller: 'info', action: page + get page, controller: "info", action: page end - get 'lightspeed_integration', to: redirect('/lightspeed') + get "lightspeed_integration", to: redirect("/lightspeed") - %w(stolen_bikes roadmap security spokecard how_it_works).freeze.each { |p| get p, to: redirect('/resources') } + %w(stolen_bikes roadmap security spokecard how_it_works).freeze.each { |p| get p, to: redirect("/resources") } # get 'sitemap.xml.gz' => redirect('https://files.bikeindex.org/sitemaps/sitemap_index.xml.gz') # Somehow the redirect drops the .gz extension, which ruins it so this redirect is handled by Cloudflare # get 'sitemaps/(*all)' => redirect('https://files.bikeindex.org/sitemaps/%{all}') - get '/400', to: 'errors#bad_request', via: :all - get '/401', to: 'errors#unauthorized', via: :all - get '/404', to: 'errors#not_found', via: :all - get '/422', to: 'errors#unprocessable_entity', via: :all - get '/500', to: 'errors#server_error', via: :all + get "/400", to: "errors#bad_request", via: :all + get "/401", to: "errors#unauthorized", via: :all + get "/404", to: "errors#not_found", via: :all + get "/422", to: "errors#unprocessable_entity", via: :all + get "/500", to: "errors#server_error", via: :all - mount Sidekiq::Web => '/sidekiq', constraints: AdminRestriction + mount Sidekiq::Web => "/sidekiq", constraints: AdminRestriction # No actions are defined here, this `resources` declaration # prepends a :organization_id/ to every nested URL. # Down here so that it doesn't override any other routes - resources :organizations, only: [], path: 'o', module: 'organized' do + resources :organizations, only: [], path: "o", module: "organized" do get "/", to: "bikes#index", as: :root - get 'landing', to: 'manage#landing', as: :landing + get "landing", to: "manage#landing", as: :landing resources :bikes, only: %i[index new show] do collection do get :recoveries @@ -288,5 +288,5 @@ resources :users, except: [:show] end - get '*unmatched_route', to: 'errors#not_found' if Rails.env.production? # Handle 404s with lograge + get "*unmatched_route", to: "errors#not_found" if Rails.env.production? # Handle 404s with lograge end diff --git a/config/sitemap.rb b/config/sitemap.rb index 69d8031e83..80e211e872 100644 --- a/config/sitemap.rb +++ b/config/sitemap.rb @@ -1,13 +1,13 @@ # Set the host name for URL creation -SitemapGenerator::Sitemap.default_host = 'https://bikeindex.org' -SitemapGenerator::Sitemap.sitemaps_host = 'https://bikeindex.org' +SitemapGenerator::Sitemap.default_host = "https://bikeindex.org" +SitemapGenerator::Sitemap.sitemaps_host = "https://bikeindex.org" SitemapGenerator::Sitemap.public_path = "#{Rails.root}/tmp/uploads" -SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/' +SitemapGenerator::Sitemap.sitemaps_path = "sitemaps/" SitemapGenerator::Sitemap.adapter = SitemapGenerator::WaveAdapter.new SitemapGenerator::Sitemap.create do group(filename: :about) do - paths = ['about'] + paths = ["about"] paths.each { |i| add "/#{i}", priority: 0.9 } end group(filename: :organizations) do @@ -15,29 +15,29 @@ end group(filename: :news) do - add '/blogs', priority: 0.9, changefreq: 'daily' + add "/blogs", priority: 0.9, changefreq: "daily" Blog.published.each do |b| add("/news/#{b.title_slug}", priority: 0.9, news: { - publication_name: 'Bike Index Blog', - publication_language: 'en', + publication_name: "Bike Index Blog", + publication_language: "en", title: b.title, - publication_date: b.published_at.strftime('%Y-%m-%dT%H:%M:%S+00:00') + publication_date: b.published_at.strftime("%Y-%m-%dT%H:%M:%S+00:00"), }) end end group(filename: :partners) do - paths = ['where', 'organizations/new'] + paths = ["where", "organizations/new"] paths.each { |i| add "/#{i}", priority: 0.9 } end group(filename: :documentation) do - add '/documentation/api_v2' + add "/documentation/api_v2" end group(filename: :bikes) do - Bike.all.each { |b| add bike_path(b), changefreq: 'daily', priority: 0.9 } + Bike.all.each { |b| add bike_path(b), changefreq: "daily", priority: 0.9 } end group(filename: :images) do diff --git a/config/unicorn.rb b/config/unicorn.rb index 70ca87af92..6eefd94426 100644 --- a/config/unicorn.rb +++ b/config/unicorn.rb @@ -1,15 +1,15 @@ worker_processes 5 -working_directory "#{ENV['STACK_PATH']}" +working_directory "#{ENV["STACK_PATH"]}" listen "/tmp/web_server.sock", backlog: 64 timeout 30 -pid '/tmp/web_server.pid' +pid "/tmp/web_server.pid" -stderr_path "#{ENV['STACK_PATH']}/log/unicorn.stderr.log" -stdout_path "#{ENV['STACK_PATH']}/log/unicorn.stdout.log" +stderr_path "#{ENV["STACK_PATH"]}/log/unicorn.stderr.log" +stdout_path "#{ENV["STACK_PATH"]}/log/unicorn.stdout.log" preload_app true GC.respond_to?(:copy_on_write_friendly=) and @@ -21,7 +21,7 @@ if defined? ActiveRecord::Base ActiveRecord::Base.connection.disconnect! end - old_pid = '/tmp/web_server.pid.oldbin' + old_pid = "/tmp/web_server.pid.oldbin" if File.exists?(old_pid) && server.pid != old_pid begin Process.kill("QUIT", File.read(old_pid).to_i) @@ -34,6 +34,6 @@ end after_fork do |server, worker| - defined?(ActiveRecord::Base) and - ActiveRecord::Base.establish_connection -end \ No newline at end of file + defined?(ActiveRecord::Base) and + ActiveRecord::Base.establish_connection +end diff --git a/db/migrate/20180804170624_add_organization_with_bike_actions_id.rb b/db/migrate/20180804170624_add_organization_with_bike_actions_id.rb index ad7951c972..4289b98bc5 100644 --- a/db/migrate/20180804170624_add_organization_with_bike_actions_id.rb +++ b/db/migrate/20180804170624_add_organization_with_bike_actions_id.rb @@ -1,5 +1,5 @@ class AddOrganizationWithBikeActionsId < ActiveRecord::Migration def change - add_reference :users, :bike_actions_organization, index: true + add_reference :users, :bike_actions_organization, index: true end end diff --git a/db/migrate/20181204215943_add_feature_slugs_to_paid_features.rb b/db/migrate/20181204215943_add_feature_slugs_to_paid_features.rb index d78c3b63f9..86145f457e 100644 --- a/db/migrate/20181204215943_add_feature_slugs_to_paid_features.rb +++ b/db/migrate/20181204215943_add_feature_slugs_to_paid_features.rb @@ -1,6 +1,6 @@ - class AddFeatureSlugsToPaidFeatures < ActiveRecord::Migration - def change - remove_column :paid_features, :is_locked, :boolean - add_column :paid_features, :feature_slugs, :text, array: true, default: [] - end +class AddFeatureSlugsToPaidFeatures < ActiveRecord::Migration + def change + remove_column :paid_features, :is_locked, :boolean + add_column :paid_features, :feature_slugs, :text, array: true, default: [] end +end diff --git a/db/migrate/20190214192448_adds_frame_material_to_bikes.rb b/db/migrate/20190214192448_adds_frame_material_to_bikes.rb index 2830d55987..64f542366d 100644 --- a/db/migrate/20190214192448_adds_frame_material_to_bikes.rb +++ b/db/migrate/20190214192448_adds_frame_material_to_bikes.rb @@ -1,5 +1,4 @@ class AddsFrameMaterialToBikes < ActiveRecord::Migration - def up add_column :bikes, :frame_material, :integer diff --git a/db/migrate/20190306232544_add_handlebar_type_to_bikes.rb b/db/migrate/20190306232544_add_handlebar_type_to_bikes.rb index 18cd399b50..837f87bf01 100644 --- a/db/migrate/20190306232544_add_handlebar_type_to_bikes.rb +++ b/db/migrate/20190306232544_add_handlebar_type_to_bikes.rb @@ -10,4 +10,4 @@ def up def down remove_column :bikes, :handlebar_type end -end \ No newline at end of file +end diff --git a/db/migrate/20190312185621_add_cycle_type_to_bikes.rb b/db/migrate/20190312185621_add_cycle_type_to_bikes.rb index 67096d4c0b..3411137a79 100644 --- a/db/migrate/20190312185621_add_cycle_type_to_bikes.rb +++ b/db/migrate/20190312185621_add_cycle_type_to_bikes.rb @@ -1,7 +1,7 @@ class AddCycleTypeToBikes < ActiveRecord::Migration def up add_column :bikes, :cycle_type, :integer, default: 0 - + defined?(Deprecated::CycleType) && Deprecated::CycleType.find_each do |ct| Bike.where(cycle_type_id: ct.id).update_all(cycle_type: Bike.cycle_types[ct.slug]) end diff --git a/db/migrate/20190314182139_add_propulsion_type_to_bikes.rb b/db/migrate/20190314182139_add_propulsion_type_to_bikes.rb index 357ce09b0a..3054646de2 100644 --- a/db/migrate/20190314182139_add_propulsion_type_to_bikes.rb +++ b/db/migrate/20190314182139_add_propulsion_type_to_bikes.rb @@ -1,13 +1,13 @@ class AddPropulsionTypeToBikes < ActiveRecord::Migration def up add_column :bikes, :propulsion_type, :integer, default: 0 - + defined?(Deprecated::PropulsionType) && Deprecated::PropulsionType.find_each do |pt| slug = pt.slug == "other" ? "other-style" : pt.slug Bike.where(propulsion_type_id: pt.id).update_all(propulsion_type: Bike.propulsion_types[slug]) end end - + def down remove_column :bikes, :propulsion_type end diff --git a/db/seeds.rb b/db/seeds.rb index 05d70565dd..ceb4e76a7f 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,13 +1,13 @@ # This file should contain all the record creation needed to seed the database with its default values. # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). -require File.expand_path('db/seeds/seed_manufacturers', Rails.root) -require File.expand_path('db/seeds/seed_wheel_sizes', Rails.root) -require File.expand_path('db/seeds/seed_bike_associations', Rails.root) -require File.expand_path('db/seeds/seed_components', Rails.root) -require File.expand_path('db/seeds/seed_countries_and_states', Rails.root) +require File.expand_path("db/seeds/seed_manufacturers", Rails.root) +require File.expand_path("db/seeds/seed_wheel_sizes", Rails.root) +require File.expand_path("db/seeds/seed_bike_associations", Rails.root) +require File.expand_path("db/seeds/seed_components", Rails.root) +require File.expand_path("db/seeds/seed_countries_and_states", Rails.root) # We have a silly random string at the top of a few pages. # They will break unless there is a value there... So here one is flavor = FlavorText.create(message: "Bike like the wind") -flavor.save \ No newline at end of file +flavor.save diff --git a/db/seeds/seed_bike_associations.rb b/db/seeds/seed_bike_associations.rb index 4bdeda8b4e..f6cac51259 100644 --- a/db/seeds/seed_bike_associations.rb +++ b/db/seeds/seed_bike_associations.rb @@ -1,6 +1,6 @@ # Seed the lock types -lock_types = ['U-lock', 'Chain with lock', 'Cable', 'Locking skewer', 'Other style'] +lock_types = ["U-lock", "Chain with lock", "Cable", "Locking skewer", "Other style"] lock_types.each do |type_name| lock_type = LockType.create(name: type_name) lock_type.save @@ -8,19 +8,19 @@ # Seed the colors colors = [ - { name: 'Black', priority: 1, display: '#000' }, - { name: 'Blue', priority: 1, display: '#386ed2' }, - { name: 'Brown', priority: 1, display: '#734a22' }, - { name: 'Green', priority: 1, display: '#1ba100' }, - { name: 'Orange', priority: 1, display: '#ff8d1d' }, - { name: 'Pink', priority: 1, display: '#ff7dfd' }, - { name: 'Purple', priority: 1, display: '#a745c0' }, - { name: 'Red', priority: 1, display: '#ec1313' }, - { name: 'Silver, Gray or Bare Metal', priority: 1, display: '#b0b0b0' }, - { name: 'Stickers tape or other cover-up', priority: 3, display: '#fff' }, - { name: 'Teal', priority: 1, display: '#3bede7' }, - { name: 'White', priority: 1, display: '#fff' }, - { name: 'Yellow or Gold', priority: 1, display: '#fff44b' } + { name: "Black", priority: 1, display: "#000" }, + { name: "Blue", priority: 1, display: "#386ed2" }, + { name: "Brown", priority: 1, display: "#734a22" }, + { name: "Green", priority: 1, display: "#1ba100" }, + { name: "Orange", priority: 1, display: "#ff8d1d" }, + { name: "Pink", priority: 1, display: "#ff7dfd" }, + { name: "Purple", priority: 1, display: "#a745c0" }, + { name: "Red", priority: 1, display: "#ec1313" }, + { name: "Silver, Gray or Bare Metal", priority: 1, display: "#b0b0b0" }, + { name: "Stickers tape or other cover-up", priority: 3, display: "#fff" }, + { name: "Teal", priority: 1, display: "#3bede7" }, + { name: "White", priority: 1, display: "#fff" }, + { name: "Yellow or Gold", priority: 1, display: "#fff44b" }, ] colors.each do |c| color = Color.create(name: c[:name], priority: c[:priority], display: c[:display]) @@ -30,47 +30,47 @@ # Seed the gear types f_gear_types = [ - { name: '1', count: 1, internal: false, standard: true }, - { name: '2', count: 2, internal: false, standard: true }, - { name: '3', count: 3, internal: false, standard: true }, - { name: '2 internal', count: 2, internal: true }, - { name: '3 internal', count: 3, internal: true } + { name: "1", count: 1, internal: false, standard: true }, + { name: "2", count: 2, internal: false, standard: true }, + { name: "3", count: 3, internal: false, standard: true }, + { name: "2 internal", count: 2, internal: true }, + { name: "3 internal", count: 3, internal: true }, ] f_gear_types.each do |gear| f_gear_type = FrontGearType.create(name: gear[:name], count: gear[:count], internal: gear[:internal], standard: gear[:standard]) f_gear_type.save end r_gear_types = [ - { name: '1', count: 1, internal: false, standard: true }, - { name: '2', count: 2, internal: false, standard: true }, - { name: '3', count: 3, internal: false, standard: true }, - { name: '4', count: 4, internal: false, standard: true }, - { name: '5', count: 5, internal: false, standard: true }, - { name: '6', count: 6, internal: false, standard: true }, - { name: '7', count: 7, internal: false, standard: true }, - { name: '8', count: 8, internal: false, standard: true }, - { name: '9', count: 9, internal: false, standard: true }, - { name: '10', count: 10, internal: false, standard: true }, - { name: '11', count: 11, internal: false, standard: true }, - { name: '12', count: 12, internal: false, standard: true }, - { name: '13', count: 13, internal: false, standard: true }, - { name: '14', count: 14, internal: false, standard: true }, - { name: '1 internal', count: 1, internal: true, standard: false }, - { name: '2 internal', count: 2, internal: true, standard: false }, - { name: '3 internal', count: 3, internal: true, standard: false }, - { name: '4 internal', count: 4, internal: true, standard: false }, - { name: '5 internal', count: 5, internal: true, standard: false }, - { name: '6 internal', count: 6, internal: true, standard: false }, - { name: '7 internal', count: 7, internal: true, standard: false }, - { name: '8 internal', count: 8, internal: true, standard: false }, - { name: '9 internal', count: 9, internal: true, standard: false }, - { name: '10 internal', count: 10, internal: true, standard: false }, - { name: '11 internal', count: 11, internal: true, standard: false }, - { name: '12 internal', count: 12, internal: true, standard: false }, - { name: '13 internal', count: 13, internal: true, standard: false }, - { name: '14 internal', count: 14, internal: true, standard: false }, - { name: 'Continuously variable', count: 0, internal: true, standard: true }, - { name: 'Fixed', count: 1, internal: false } + { name: "1", count: 1, internal: false, standard: true }, + { name: "2", count: 2, internal: false, standard: true }, + { name: "3", count: 3, internal: false, standard: true }, + { name: "4", count: 4, internal: false, standard: true }, + { name: "5", count: 5, internal: false, standard: true }, + { name: "6", count: 6, internal: false, standard: true }, + { name: "7", count: 7, internal: false, standard: true }, + { name: "8", count: 8, internal: false, standard: true }, + { name: "9", count: 9, internal: false, standard: true }, + { name: "10", count: 10, internal: false, standard: true }, + { name: "11", count: 11, internal: false, standard: true }, + { name: "12", count: 12, internal: false, standard: true }, + { name: "13", count: 13, internal: false, standard: true }, + { name: "14", count: 14, internal: false, standard: true }, + { name: "1 internal", count: 1, internal: true, standard: false }, + { name: "2 internal", count: 2, internal: true, standard: false }, + { name: "3 internal", count: 3, internal: true, standard: false }, + { name: "4 internal", count: 4, internal: true, standard: false }, + { name: "5 internal", count: 5, internal: true, standard: false }, + { name: "6 internal", count: 6, internal: true, standard: false }, + { name: "7 internal", count: 7, internal: true, standard: false }, + { name: "8 internal", count: 8, internal: true, standard: false }, + { name: "9 internal", count: 9, internal: true, standard: false }, + { name: "10 internal", count: 10, internal: true, standard: false }, + { name: "11 internal", count: 11, internal: true, standard: false }, + { name: "12 internal", count: 12, internal: true, standard: false }, + { name: "13 internal", count: 13, internal: true, standard: false }, + { name: "14 internal", count: 14, internal: true, standard: false }, + { name: "Continuously variable", count: 0, internal: true, standard: true }, + { name: "Fixed", count: 1, internal: false }, ] r_gear_types.each do |gear| r_gear_type = RearGearType.create(name: gear[:name], count: gear[:count], internal: gear[:internal], standard: gear[:standard]) diff --git a/db/seeds/seed_components.rb b/db/seeds/seed_components.rb index 4aa859aea1..065a412bea 100644 --- a/db/seeds/seed_components.rb +++ b/db/seeds/seed_components.rb @@ -1,8 +1,8 @@ # Seed the component groups -cgroups = [ {name: "Frame and fork", description: "Frame and fork. Also headset." }, - {name: "Wheels", description: "wheels and everything to do with them (including freehub bodies, not including cassettes)." }, - {name: "Drivetrain and brakes", description: "Shifters, cranks, chain, brake levers brake calipers." }, - {name: "Additional parts", description: "Seat, handlebars, accessories (computer, rack, lights, etc)." }] +cgroups = [{ name: "Frame and fork", description: "Frame and fork. Also headset." }, + { name: "Wheels", description: "wheels and everything to do with them (including freehub bodies, not including cassettes)." }, + { name: "Drivetrain and brakes", description: "Shifters, cranks, chain, brake levers brake calipers." }, + { name: "Additional parts", description: "Seat, handlebars, accessories (computer, rack, lights, etc)." }] cgroups.each do |component_group| cg = Cgroup.create(name: component_group[:name], description: component_group[:description]) cg.save @@ -13,17 +13,17 @@ { name: "other", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "unknown", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "water bottle cage", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, - { name: "stem", secondary_name: "Gooseneck", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, - { name: "bashguard/chain guide", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "fairing", has_multiple: false, cgroup_id: Cgroup.find_by_name('Frame and fork').id }, + { name: "stem", secondary_name: "Gooseneck", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, + { name: "bashguard/chain guide", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "fairing", has_multiple: false, cgroup_id: Cgroup.find_by_name("Frame and fork").id }, { name: "lights", has_multiple: true, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "bell/noisemaker", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "basket", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, - { name: "chain tensioners", secondary_name: "Chain tugs", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "derailleur", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "training wheels", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "bottom bracket", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "brake", has_multiple: true, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, + { name: "chain tensioners", secondary_name: "Chain tugs", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "derailleur", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "training wheels", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "bottom bracket", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "brake", has_multiple: true, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, { name: "hub guard", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "generator/dynamo", has_multiple: true, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "handlebar", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, @@ -35,21 +35,21 @@ { name: "spokes", has_multiple: true, cgroup_id: Cgroup.find_by_name("Wheels").id }, { name: "tube", has_multiple: true, cgroup_id: Cgroup.find_by_name("Wheels").id }, { name: "tire", has_multiple: true, cgroup_id: Cgroup.find_by_name("Wheels").id }, - { name: "brake lever", has_multiple: true, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "shift and brake lever", has_multiple: true, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "brake rotor", has_multiple: true, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "brake pad", has_multiple: true, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "shifter", has_multiple: true, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "fork", has_multiple: false, cgroup_id: Cgroup.find_by_name('Frame and fork').id }, - { name: "rear suspension", has_multiple: false, cgroup_id: Cgroup.find_by_name('Frame and fork').id }, - { name: "headset", has_multiple: false, cgroup_id: Cgroup.find_by_name('Frame and fork').id }, - { name: "brake cable", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "shift cable", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "chain", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "chainrings", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "cog/cassette/freewheel", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "crankset", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, - { name: "pedals", has_multiple: false, cgroup_id: Cgroup.find_by_name('Drivetrain and brakes').id }, + { name: "brake lever", has_multiple: true, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "shift and brake lever", has_multiple: true, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "brake rotor", has_multiple: true, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "brake pad", has_multiple: true, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "shifter", has_multiple: true, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "fork", has_multiple: false, cgroup_id: Cgroup.find_by_name("Frame and fork").id }, + { name: "rear suspension", has_multiple: false, cgroup_id: Cgroup.find_by_name("Frame and fork").id }, + { name: "headset", has_multiple: false, cgroup_id: Cgroup.find_by_name("Frame and fork").id }, + { name: "brake cable", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "shift cable", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "chain", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "chainrings", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "cog/cassette/freewheel", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "crankset", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, + { name: "pedals", has_multiple: false, cgroup_id: Cgroup.find_by_name("Drivetrain and brakes").id }, { name: "computer", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "pegs", has_multiple: true, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "toe clips", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, @@ -60,12 +60,12 @@ { name: "rack", has_multiple: true, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "seatpost", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, { name: "fender", has_multiple: true, cgroup_id: Cgroup.find_by_name("Additional parts").id }, - { name: "aero bars/extensions/bar ends", secondary_name: "Aero bars", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id} + { name: "aero bars/extensions/bar ends", secondary_name: "Aero bars", has_multiple: false, cgroup_id: Cgroup.find_by_name("Additional parts").id }, ] ctypes.each do |component_type| ct = Ctype.create(name: component_type[:name], cgroup_id: component_type[:cgroup_id]) if component_type[:has_multiple] - ct.has_multiple = true + ct.has_multiple = true end ct.save -end \ No newline at end of file +end diff --git a/db/seeds/seed_countries_and_states.rb b/db/seeds/seed_countries_and_states.rb index 14e1187c9b..0f081ab9f0 100644 --- a/db/seeds/seed_countries_and_states.rb +++ b/db/seeds/seed_countries_and_states.rb @@ -5,8 +5,8 @@ end # US States and territories -us_id = Country.find_by_iso('US').id +us_id = Country.find_by_iso("US").id StatesAndCountries.states.each do |s| state = State.create(country_id: us_id, name: s[:name], abbreviation: s[:abbr]) state.save -end \ No newline at end of file +end diff --git a/db/seeds/seed_manufacturers.rb b/db/seeds/seed_manufacturers.rb index 3bd28f8447..3e4fb1f4c6 100644 --- a/db/seeds/seed_manufacturers.rb +++ b/db/seeds/seed_manufacturers.rb @@ -1,10 +1,10 @@ # A Small sampling of manufacturers to seed! # To get the full list download https://github.com/bikeindex/resources/blob/master/manufacturers.csv # You can upload the csv in admin section :) -# -# +# +# # OG Test Manufacturers are commented out to get the whole list for now -# +# # Manufacturer.create(name: "Unknown", frame_maker: true) # Manufacturer.create(name: "Other", frame_maker: true) # Manufacturer.create(name: "Giant", frame_maker: true, website: "http://www.giant-bicycles.com/") @@ -24,7 +24,6 @@ # Manufacturer.create(name: "Shimano", frame_maker: false, website: "http://bike.shimano.com") # Manufacturer.create(name: "Campagnolo", frame_maker: false, website: "http://www.campagnolo.com/") - Manufacturer.create!(name: "24seven", frame_maker: true) Manufacturer.create!(name: "3M", frame_maker: true) Manufacturer.create!(name: "3T", frame_maker: true) diff --git a/db/seeds/seed_wheel_sizes.rb b/db/seeds/seed_wheel_sizes.rb index 8f5e558154..fcbbea7643 100644 --- a/db/seeds/seed_wheel_sizes.rb +++ b/db/seeds/seed_wheel_sizes.rb @@ -1,39 +1,39 @@ # Seed the database with the wheel sizes wheel_sizes = [ - { name: '8 x 1 1/4', iso_bsd: 137, priority: 4, description: '8 x 1 1/4 (Rare)' }, - { name: '10 x 2', iso_bsd: 152, priority: 4, description: '10 x 2 (Rare)' }, - { name: '12in', iso_bsd: 203, priority: 1, description: '12in (Standard size)' }, - { name: '16in', iso_bsd: 305, priority: 1, description: '16in (Standard size)' }, - { name: '16 x 1 3/4', iso_bsd: 317, priority: 4, description: '16 x 1 3/4 (Rare)' }, - { name: '16 x 1 3/8', iso_bsd: 335, priority: 4, description: '16 x 1 3/8 Polish juvenile (Rare)' }, - { name: '16 x 1 3/8', iso_bsd: 337, priority: 4, description: '16 x 1 3/8 Folders and recumbents (Rare)' }, - { name: '400 A', iso_bsd: 340, priority: 4, description: '400 A (Rare)' }, - { name: '16 x 1 3/8', iso_bsd: 349, priority: 4, description: '16 x 1 3/8, mysterious (Rare)' }, - { name: '18in', iso_bsd: 355, priority: 1, description: '18in (Standard size)' }, - { name: '17 x 1 1/4', iso_bsd: 369, priority: 4, description: '17 x 1 1/4 (Rare)' }, - { name: '450 A', iso_bsd: 390, priority: 4, description: '450 A (Rare)' }, - { name: '20in', iso_bsd: 406, priority: 1, description: '20in (Standard size)' }, - { name: '20 x 1 3/4', iso_bsd: 419, priority: 4, description: '20 x 1 3/4 (Rare)' }, - { name: '500 A', iso_bsd: 440, priority: 4, description: '500 A (Rare)' }, - { name: '20 x 1 1/8; x 1 1/4; x 1 3/8', iso_bsd: 451, priority: 3, description: '20 x 1 1/8; x 1 1/4; x 1 3/8 (Uncommon)' }, - { name: '22 x 1.75; x 2.125', iso_bsd: 457, priority: 4, description: '22 x 1.75; x 2.125 (Rare)' }, - { name: '550 A', iso_bsd: 490, priority: 4, description: '550 A (Rare)' }, - { name: '24in', iso_bsd: 507, priority: 1, description: '24in (Standard size)' }, - { name: '24 x 1', iso_bsd: 520, priority: 3, description: '24 x 1 performance wheels for smaller riders (Uncommon)' }, - { name: '24 x 1 1/8, 24 x 1 3/8 (E.5), 600 A', iso_bsd: 540, priority: 4, description: '24 x 1 1/8, 24 x 1 3/8 (E.5), 600 A (Rare)' }, - { name: '24 x 1 1/4, 24 x 1 3/8 (S-5)', iso_bsd: 547, priority: 4, description: '24 x 1 1/4, 24 x 1 3/8, Schwinn Juvenile (Rare)' }, - { name: '26in', iso_bsd: 559, priority: 1, description: '26in (Standard size)' }, - { name: '650 C', iso_bsd: 571, priority: 3, description: '650 C, Schwinn Cruisers, Tri- and Time-trial bikes (uncommon)' }, - { name: '650 B', iso_bsd: 584, priority: 1, description: '650 B, 27.5 mountain bikes, smaller road bikes (Standard size)' }, - { name: '700 D', iso_bsd: 587, priority: 4, description: '700 D GT size (Rare)' }, - { name: '26 x 1 3/8', iso_bsd: 590, priority: 3, description: '26 x 1 3/8 English 3-speeds, older department-store 10 speeds (Uncommon)' }, - { name: '26 x 1 3/8', iso_bsd: 597, priority: 2, description: '26 x 1 3/8 (Older Schwinns, S-6) (Common)' }, - { name: '26 x 1.25, x 1.375', iso_bsd: 599, priority: 4, description: '26 x 1.25, x 1.375 (Rare)' }, - { name: '700 C', iso_bsd: 622, priority: 1, description: '700 C, 29in mountain bikes (Standard size)' }, - { name: '27in', iso_bsd: 630, priority: 1, description: '27in (Standard size)' }, - { name: '28 x 1 1/2, 700 B', iso_bsd: 635, priority: 4, description: '28 x 1 1/2, 700 B (Rare)' }, - { name: '32in', iso_bsd: 686, priority: 4, description: '32in, Unicycle size (Rare)' }, - { name: '36in', iso_bsd: 787, priority: 4, description: '36in, Unicycle size (Rare)' } + { name: "8 x 1 1/4", iso_bsd: 137, priority: 4, description: "8 x 1 1/4 (Rare)" }, + { name: "10 x 2", iso_bsd: 152, priority: 4, description: "10 x 2 (Rare)" }, + { name: "12in", iso_bsd: 203, priority: 1, description: "12in (Standard size)" }, + { name: "16in", iso_bsd: 305, priority: 1, description: "16in (Standard size)" }, + { name: "16 x 1 3/4", iso_bsd: 317, priority: 4, description: "16 x 1 3/4 (Rare)" }, + { name: "16 x 1 3/8", iso_bsd: 335, priority: 4, description: "16 x 1 3/8 Polish juvenile (Rare)" }, + { name: "16 x 1 3/8", iso_bsd: 337, priority: 4, description: "16 x 1 3/8 Folders and recumbents (Rare)" }, + { name: "400 A", iso_bsd: 340, priority: 4, description: "400 A (Rare)" }, + { name: "16 x 1 3/8", iso_bsd: 349, priority: 4, description: "16 x 1 3/8, mysterious (Rare)" }, + { name: "18in", iso_bsd: 355, priority: 1, description: "18in (Standard size)" }, + { name: "17 x 1 1/4", iso_bsd: 369, priority: 4, description: "17 x 1 1/4 (Rare)" }, + { name: "450 A", iso_bsd: 390, priority: 4, description: "450 A (Rare)" }, + { name: "20in", iso_bsd: 406, priority: 1, description: "20in (Standard size)" }, + { name: "20 x 1 3/4", iso_bsd: 419, priority: 4, description: "20 x 1 3/4 (Rare)" }, + { name: "500 A", iso_bsd: 440, priority: 4, description: "500 A (Rare)" }, + { name: "20 x 1 1/8; x 1 1/4; x 1 3/8", iso_bsd: 451, priority: 3, description: "20 x 1 1/8; x 1 1/4; x 1 3/8 (Uncommon)" }, + { name: "22 x 1.75; x 2.125", iso_bsd: 457, priority: 4, description: "22 x 1.75; x 2.125 (Rare)" }, + { name: "550 A", iso_bsd: 490, priority: 4, description: "550 A (Rare)" }, + { name: "24in", iso_bsd: 507, priority: 1, description: "24in (Standard size)" }, + { name: "24 x 1", iso_bsd: 520, priority: 3, description: "24 x 1 performance wheels for smaller riders (Uncommon)" }, + { name: "24 x 1 1/8, 24 x 1 3/8 (E.5), 600 A", iso_bsd: 540, priority: 4, description: "24 x 1 1/8, 24 x 1 3/8 (E.5), 600 A (Rare)" }, + { name: "24 x 1 1/4, 24 x 1 3/8 (S-5)", iso_bsd: 547, priority: 4, description: "24 x 1 1/4, 24 x 1 3/8, Schwinn Juvenile (Rare)" }, + { name: "26in", iso_bsd: 559, priority: 1, description: "26in (Standard size)" }, + { name: "650 C", iso_bsd: 571, priority: 3, description: "650 C, Schwinn Cruisers, Tri- and Time-trial bikes (uncommon)" }, + { name: "650 B", iso_bsd: 584, priority: 1, description: "650 B, 27.5 mountain bikes, smaller road bikes (Standard size)" }, + { name: "700 D", iso_bsd: 587, priority: 4, description: "700 D GT size (Rare)" }, + { name: "26 x 1 3/8", iso_bsd: 590, priority: 3, description: "26 x 1 3/8 English 3-speeds, older department-store 10 speeds (Uncommon)" }, + { name: "26 x 1 3/8", iso_bsd: 597, priority: 2, description: "26 x 1 3/8 (Older Schwinns, S-6) (Common)" }, + { name: "26 x 1.25, x 1.375", iso_bsd: 599, priority: 4, description: "26 x 1.25, x 1.375 (Rare)" }, + { name: "700 C", iso_bsd: 622, priority: 1, description: "700 C, 29in mountain bikes (Standard size)" }, + { name: "27in", iso_bsd: 630, priority: 1, description: "27in (Standard size)" }, + { name: "28 x 1 1/2, 700 B", iso_bsd: 635, priority: 4, description: "28 x 1 1/2, 700 B (Rare)" }, + { name: "32in", iso_bsd: 686, priority: 4, description: "32in, Unicycle size (Rare)" }, + { name: "36in", iso_bsd: 787, priority: 4, description: "36in, Unicycle size (Rare)" }, ] wheel_sizes.each do |wheel_size| wheel_size = WheelSize.create!(name: wheel_size[:name], priority: wheel_size[:priority], description: wheel_size[:description], iso_bsd: wheel_size[:iso_bsd]) diff --git a/lib/integrations/bike_book_integration.rb b/lib/integrations/bike_book_integration.rb index 22e456ecb3..f3ad61d6b3 100644 --- a/lib/integrations/bike_book_integration.rb +++ b/lib/integrations/bike_book_integration.rb @@ -1,6 +1,6 @@ class BikeBookIntegration - require 'net/http' - + require "net/http" + def make_request(query, method = nil) begin uri = URI("http://bikebook.io#{method}") @@ -13,7 +13,7 @@ def make_request(query, method = nil) response = JSON.parse(res.body) return response if response.kind_of?(Array) - response.with_indifferent_access + response.with_indifferent_access end def get_model(options = {}) @@ -21,15 +21,14 @@ def get_model(options = {}) options = { year: options.year, manufacturer: options.manufacturer.name, - frame_model: options.frame_model + frame_model: options.frame_model, } end return nil unless options[:year].present? && options[:manufacturer].present? && options[:frame_model].present? # We're book sluging everything because, url safe (It's the same method bikebook uses) query = { manufacturer: Slugifyer.manufacturer(options[:manufacturer]), - year: options[:year], - frame_model: Slugifyer.book_slug(options[:frame_model]) - } + year: options[:year], + frame_model: Slugifyer.book_slug(options[:frame_model]) } make_request(query) end @@ -38,8 +37,7 @@ def get_model_list(options = {}) return nil unless options[:manufacturer].present? query = { manufacturer: Slugifyer.manufacturer(options[:manufacturer]) } query[:year] = options[:year] if options[:year].present? - + make_request(query, "/model_list/") end - -end \ No newline at end of file +end diff --git a/lib/integrations/file_cache_maintainer.rb b/lib/integrations/file_cache_maintainer.rb index a8a44d8f9d..7ee942f402 100644 --- a/lib/integrations/file_cache_maintainer.rb +++ b/lib/integrations/file_cache_maintainer.rb @@ -7,7 +7,7 @@ def assign_blacklist_ids(ids) end def blacklist - return [] unless redis.type(info_id) == 'set' + return [] unless redis.type(info_id) == "set" redis.smembers blacklist_id end @@ -22,12 +22,12 @@ def blacklist_include?(id) def descriptions { - 'manufacturers.tsv' => 'Manufacturers list', - 'current_stolen_bikes.tsv' => 'Stolen', - 'approved_current_stolen_bikes.tsv' => 'Stolen (without blacklisted bikes)', - 'current_stolen_with_reports.tsv' => 'Stolen with serials & police reports', - 'approved_current_stolen_with_reports.tsv' => 'Stolen with serials & police reports (without blacklisted bikes)', - 'all_stolen_cache.json' => 'Cached API response of all stolen bikes' + "manufacturers.tsv" => "Manufacturers list", + "current_stolen_bikes.tsv" => "Stolen", + "approved_current_stolen_bikes.tsv" => "Stolen (without blacklisted bikes)", + "current_stolen_with_reports.tsv" => "Stolen with serials & police reports", + "approved_current_stolen_with_reports.tsv" => "Stolen with serials & police reports (without blacklisted bikes)", + "all_stolen_cache.json" => "Cached API response of all stolen bikes", } end @@ -55,20 +55,20 @@ def file_info_hash(k) filename: path.basename.to_s, daily: daily_export, updated_at: @result[k], - description: descriptions[path.basename.to_s] + description: descriptions[path.basename.to_s], } end def files - return [] unless redis.type(info_id) == 'hash' + return [] unless redis.type(info_id) == "hash" @result = redis.hgetall(info_id) @result.keys.map { |k| file_info_hash(k).with_indifferent_access } .sort_by { |t| t[:filename] }.sort_by { |t| t[:daily] ? 1 : 0 } end def cached_all_stolen - files.select { |t| t['filename'] =~ /all_stolen_cache\.json/ } - .sort { |x, y| x['filename'] <=> y['filename'] }.last + files.select { |t| t["filename"] =~ /all_stolen_cache\.json/ } + .sort { |x, y| x["filename"] <=> y["filename"] }.last end def normalized(id) @@ -96,10 +96,10 @@ def uploader_from_filename(filename) end def remove_file(file_info_hash) - uploader = uploader_from_filename(file_info_hash['filename']) - uploader.retrieve_from_store!(file_info_hash['filename']) + uploader = uploader_from_filename(file_info_hash["filename"]) + uploader.retrieve_from_store!(file_info_hash["filename"]) uploader.remove! - redis.hdel(info_id, file_info_hash['path']) + redis.hdel(info_id, file_info_hash["path"]) end end end diff --git a/lib/integrations/stolen_twitterbot_integration.rb b/lib/integrations/stolen_twitterbot_integration.rb index d687f3c331..3959c7a821 100644 --- a/lib/integrations/stolen_twitterbot_integration.rb +++ b/lib/integrations/stolen_twitterbot_integration.rb @@ -1,11 +1,10 @@ class StolenTwitterbotIntegration - require 'httparty' - + require "httparty" + def send_tweet(bike_id) - options = {api_url: "#{ENV['BASE_URL']}/api/v1/bikes/#{bike_id}", key: ENV['STOLEN_TWITTERBOT_KEY']} - HTTParty.post(ENV['STOLEN_TWITTERBOT_URL'], - body: options.to_json, - headers: { 'Content-Type' => 'application/json' } ) + options = { api_url: "#{ENV["BASE_URL"]}/api/v1/bikes/#{bike_id}", key: ENV["STOLEN_TWITTERBOT_KEY"] } + HTTParty.post(ENV["STOLEN_TWITTERBOT_URL"], + body: options.to_json, + headers: { "Content-Type" => "application/json" }) end - -end \ No newline at end of file +end diff --git a/lib/integrations/tsv_creator.rb b/lib/integrations/tsv_creator.rb index 7d97cf6276..859e19dccb 100644 --- a/lib/integrations/tsv_creator.rb +++ b/lib/integrations/tsv_creator.rb @@ -1,9 +1,9 @@ class TsvCreator def self.enqueue_creation - TsvCreatorWorker.perform_async('create_manufacturer') - TsvCreatorWorker.perform_async('create_daily_tsvs') - TsvCreatorWorker.perform_in(20.minutes, 'create_stolen_with_reports', true) - TsvCreatorWorker.perform_in(1.hour, 'create_stolen', true) + TsvCreatorWorker.perform_async("create_manufacturer") + TsvCreatorWorker.perform_async("create_daily_tsvs") + TsvCreatorWorker.perform_in(20.minutes, "create_stolen_with_reports", true) + TsvCreatorWorker.perform_in(1.hour, "create_stolen", true) end attr_reader :file_prefix @@ -31,11 +31,11 @@ def org_counts_header def org_count_row(bike) row = bike.created_at.strftime("%m.%d.%Y") row << "\t" - row << "true" if bike.stolen + row << "true" if bike.stolen row << "\t" row << bike.first_ownership.user&.name if bike.first_ownership.user row << "\t#{bike.first_owner_email}" - row << "\t#{ENV['BASE_URL']}/bikes/#{bike.id}\n" + row << "\t#{ENV["BASE_URL"]}/bikes/#{bike.id}\n" "#{row}" end @@ -44,9 +44,9 @@ def manufacturer_row(mnfg) popularity = 500 if popularity > 500 popularity = 250 if popularity.between?(250, 499) popularity = 100 if popularity.between?(100, 249) - popularity = 10 if popularity.between?(2, 99) + popularity = 10 if popularity.between?(2, 99) row = "#{mnfg.id}\t#{mnfg.name}\t" - row << (mnfg.frame_maker ? 'Frame manufacturer' : 'Manufacturer') + row << (mnfg.frame_maker ? "Frame manufacturer" : "Manufacturer") row << "\t" row << "#{mnfg.bikes.count}" row << "\t" @@ -56,11 +56,11 @@ def manufacturer_row(mnfg) "#{row}" end - def create_org_count(organization, start_date=nil) + def create_org_count(organization, start_date = nil) start_date ||= Time.now.beginning_of_year - obikes = organization.bikes.where('bikes.created_at >= ?', start_date) + obikes = organization.bikes.where("bikes.created_at >= ?", start_date) out_file = File.join(Rails.root, "#{@file_prefix}org_count_bikes.tsv") - output = File.open(out_file, 'w') + output = File.open(out_file, "w") output.puts org_counts_header obikes.each { |b| output.puts org_count_row(b) } send_to_uploader(output) @@ -78,14 +78,14 @@ def create_org_count(organization, start_date=nil) # end def create_manufacturer - out_file = File.join(Rails.root,"#{@file_prefix}manufacturers.tsv") + out_file = File.join(Rails.root, "#{@file_prefix}manufacturers.tsv") output = File.open(out_file, "w") output.puts manufacturers_header Manufacturer.all.each { |m| output.puts manufacturer_row(m) } send_to_uploader(output) end - def create_stolen(blacklist=false, stolen_records: nil) + def create_stolen(blacklist = false, stolen_records: nil) stolen_records ||= StolenRecord.approveds filename = "#{@file_prefix}#{"approved_" if blacklist}current_stolen_bikes.tsv" out_file = File.join(Rails.root, filename) @@ -97,14 +97,14 @@ def create_stolen(blacklist=false, stolen_records: nil) send_to_uploader(output) end - def create_stolen_with_reports(blacklist=false, stolen_records: nil) + def create_stolen_with_reports(blacklist = false, stolen_records: nil) stolen_records ||= StolenRecord.approveds_with_reports filename = "#{@file_prefix}#{"approved_" if blacklist}current_stolen_with_reports.tsv" out_file = File.join(Rails.root, filename) output = File.open(out_file, "w") output.puts stolen_with_reports_header stolen_records.joins(:bike, :state).merge(Bike.with_serial).each do |sr| - next unless sr.police_report_number.present? + next unless sr.police_report_number.present? row = sr.tsv_row(false, with_stolen_locations: true) output.puts row if row.present? end @@ -125,11 +125,10 @@ def send_to_uploader(output) end def create_daily_tsvs - @file_prefix = "#{@file_prefix}#{Time.now.strftime('%Y_%-m_%-d')}_" + @file_prefix = "#{@file_prefix}#{Time.now.strftime("%Y_%-m_%-d")}_" create_stolen(true, stolen_records: StolenRecord.approveds.tsv_today) create_stolen_with_reports(true, stolen_records: StolenRecord.approveds_with_reports.tsv_today) t = Time.now - StolenRecord.tsv_today.map{ |sr| sr.update_attribute :tsved_at, t } + StolenRecord.tsv_today.map { |sr| sr.update_attribute :tsved_at, t } end - -end \ No newline at end of file +end diff --git a/lib/single_sign_on.rb b/lib/single_sign_on.rb index b8d17fadf6..67c2b10890 100644 --- a/lib/single_sign_on.rb +++ b/lib/single_sign_on.rb @@ -42,7 +42,7 @@ def self.parse(payload, sso_secret = nil) sso.send("#{k}=", val) end - decoded_hash.each do |k,v| + decoded_hash.each do |k, v| # 1234567 # custom. # @@ -67,15 +67,13 @@ def custom_fields @custom_fields ||= {} end - def sign(payload) OpenSSL::HMAC.hexdigest("sha256", sso_secret, payload) end - - def to_url(base_url=nil) + def to_url(base_url = nil) base = "#{base_url || sso_url}" - "#{base}#{base.include?('?') ? '&' : '?'}#{payload}" + "#{base}#{base.include?("?") ? "&" : "?"}#{payload}" end def payload @@ -86,13 +84,13 @@ def payload def unsigned_payload payload = {} ACCESSORS.each do |k| - next if (val = send k) == nil + next if (val = send k) == nil - payload[k] = val + payload[k] = val end if @custom_fields - @custom_fields.each do |k,v| + @custom_fields.each do |k, v| payload["custom.#{k}"] = v.to_s end end diff --git a/lib/states_and_countries.rb b/lib/states_and_countries.rb index ad2fcd7c0b..d9e8a7cc36 100644 --- a/lib/states_and_countries.rb +++ b/lib/states_and_countries.rb @@ -3,58 +3,58 @@ module StatesAndCountries def states [ - { name: 'Alabama', abbr: 'AL' }, - { name: 'Alaska', abbr: 'AK' }, - { name: 'Arizona', abbr: 'AZ' }, - { name: 'Arkansas', abbr: 'AR' }, - { name: 'California', abbr: 'CA' }, - { name: 'Colorado', abbr: 'CO' }, - { name: 'Connecticut', abbr: 'CT' }, - { name: 'Delaware', abbr: 'DE' }, - { name: 'District of Columbia', abbr: 'DC' }, - { name: 'Florida', abbr: 'FL' }, - { name: 'Georgia', abbr: 'GA' }, - { name: 'Hawaii', abbr: 'HI' }, - { name: 'Idaho', abbr: 'ID' }, - { name: 'Illinois', abbr: 'IL' }, - { name: 'Indiana', abbr: 'IN' }, - { name: 'Iowa', abbr: 'IA' }, - { name: 'Kansas', abbr: 'KS' }, - { name: 'Kentucky', abbr: 'KY' }, - { name: 'Louisiana', abbr: 'LA' }, - { name: 'Maine', abbr: 'ME' }, - { name: 'Maryland', abbr: 'MD' }, - { name: 'Massachusetts', abbr: 'MA' }, - { name: 'Michigan', abbr: 'MI' }, - { name: 'Minnesota', abbr: 'MN' }, - { name: 'Mississippi', abbr: 'MS' }, - { name: 'Missouri', abbr: 'MO' }, - { name: 'Montana', abbr: 'MT' }, - { name: 'Nebraska', abbr: 'NE' }, - { name: 'Nevada', abbr: 'NV' }, - { name: 'New Hampshire', abbr: 'NH' }, - { name: 'New Jersey', abbr: 'NJ' }, - { name: 'New Mexico', abbr: 'NM' }, - { name: 'New York', abbr: 'NY' }, - { name: 'North Carolina', abbr: 'NC' }, - { name: 'North Dakota', abbr: 'ND' }, - { name: 'Ohio', abbr: 'OH' }, - { name: 'Oklahoma', abbr: 'OK' }, - { name: 'Oregon', abbr: 'OR' }, - { name: 'Pennsylvania', abbr: 'PA' }, - { name: 'Puerto Rico', abbr: 'PR' }, - { name: 'Rhode Island', abbr: 'RI' }, - { name: 'South Carolina', abbr: 'SC' }, - { name: 'South Dakota', abbr: 'SD' }, - { name: 'Tennessee', abbr: 'TN' }, - { name: 'Texas', abbr: 'TX' }, - { name: 'Utah', abbr: 'UT' }, - { name: 'Vermont', abbr: 'VT' }, - { name: 'Virginia', abbr: 'VA' }, - { name: 'Washington', abbr: 'WA' }, - { name: 'West Virginia', abbr: 'WV' }, - { name: 'Wisconsin', abbr: 'WI' }, - { name: 'Wyoming', abbr: 'WY' } + { name: "Alabama", abbr: "AL" }, + { name: "Alaska", abbr: "AK" }, + { name: "Arizona", abbr: "AZ" }, + { name: "Arkansas", abbr: "AR" }, + { name: "California", abbr: "CA" }, + { name: "Colorado", abbr: "CO" }, + { name: "Connecticut", abbr: "CT" }, + { name: "Delaware", abbr: "DE" }, + { name: "District of Columbia", abbr: "DC" }, + { name: "Florida", abbr: "FL" }, + { name: "Georgia", abbr: "GA" }, + { name: "Hawaii", abbr: "HI" }, + { name: "Idaho", abbr: "ID" }, + { name: "Illinois", abbr: "IL" }, + { name: "Indiana", abbr: "IN" }, + { name: "Iowa", abbr: "IA" }, + { name: "Kansas", abbr: "KS" }, + { name: "Kentucky", abbr: "KY" }, + { name: "Louisiana", abbr: "LA" }, + { name: "Maine", abbr: "ME" }, + { name: "Maryland", abbr: "MD" }, + { name: "Massachusetts", abbr: "MA" }, + { name: "Michigan", abbr: "MI" }, + { name: "Minnesota", abbr: "MN" }, + { name: "Mississippi", abbr: "MS" }, + { name: "Missouri", abbr: "MO" }, + { name: "Montana", abbr: "MT" }, + { name: "Nebraska", abbr: "NE" }, + { name: "Nevada", abbr: "NV" }, + { name: "New Hampshire", abbr: "NH" }, + { name: "New Jersey", abbr: "NJ" }, + { name: "New Mexico", abbr: "NM" }, + { name: "New York", abbr: "NY" }, + { name: "North Carolina", abbr: "NC" }, + { name: "North Dakota", abbr: "ND" }, + { name: "Ohio", abbr: "OH" }, + { name: "Oklahoma", abbr: "OK" }, + { name: "Oregon", abbr: "OR" }, + { name: "Pennsylvania", abbr: "PA" }, + { name: "Puerto Rico", abbr: "PR" }, + { name: "Rhode Island", abbr: "RI" }, + { name: "South Carolina", abbr: "SC" }, + { name: "South Dakota", abbr: "SD" }, + { name: "Tennessee", abbr: "TN" }, + { name: "Texas", abbr: "TX" }, + { name: "Utah", abbr: "UT" }, + { name: "Vermont", abbr: "VT" }, + { name: "Virginia", abbr: "VA" }, + { name: "Washington", abbr: "WA" }, + { name: "West Virginia", abbr: "WV" }, + { name: "Wisconsin", abbr: "WI" }, + { name: "Wyoming", abbr: "WY" }, ] end @@ -302,7 +302,7 @@ def countries { name: "Western Sahara", iso: "EH" }, { name: "Yemen", iso: "YE" }, { name: "Zambia", iso: "ZM" }, - { name: "Zimbabwe", iso: "ZW" } + { name: "Zimbabwe", iso: "ZW" }, ] end -end \ No newline at end of file +end diff --git a/lib/tasks/rake_tasks.rake b/lib/tasks/rake_tasks.rake index 46ccc0c62b..0ca2076a20 100644 --- a/lib/tasks/rake_tasks.rake +++ b/lib/tasks/rake_tasks.rake @@ -14,12 +14,12 @@ task :slow_save => :environment do # end end -desc 'Create frame_makers and push to redis' +desc "Create frame_makers and push to redis" task :sm_import_manufacturers => :environment do - AutocompleteLoaderWorker.perform_async('load_manufacturers') + AutocompleteLoaderWorker.perform_async("load_manufacturers") end -desc 'cache all stolen response' +desc "cache all stolen response" task :cache_all_stolen => :environment do CacheAllStolenWorker.perform_async end @@ -30,14 +30,14 @@ task :daily_maintenance_tasks => :environment do Ownership.pluck(:id).each { |id| UnusedOwnershipRemovalWorker.perform_async(id) } end -desc 'Create stolen tsv' +desc "Create stolen tsv" task :create_tsvs => :environment do TsvCreator.enqueue_creation end -desc 'download manufacturer logos' +desc "download manufacturer logos" task :download_manufacturer_logos => :environment do Manufacturer.with_websites.pluck(:id).each_with_index do |id, index| - GetManufacturerLogoWorker.perform_in((5*index).seconds, id) + GetManufacturerLogoWorker.perform_in((5 * index).seconds, id) end end diff --git a/lib/tasks/seed_tasks.rake b/lib/tasks/seed_tasks.rake index dff9b6d457..34f425b9ce 100644 --- a/lib/tasks/seed_tasks.rake +++ b/lib/tasks/seed_tasks.rake @@ -1,14 +1,14 @@ # Seed the database with test things! # Note: you have to seed the users first, or else the bikes don't have anywhere to go. -desc 'Seed test users & 50 text bikes for user@example on first organization' +desc "Seed test users & 50 text bikes for user@example on first organization" task seed_test_users_and_bikes: :environment do user_attrs = { - admin: { name: 'admin', email: 'admin@example.com', password: 'please12', password_confirmation: 'please12', terms_of_service: true, superuser: true }, - member: { name: 'member', email: 'member@example.com', password: 'please12', password_confirmation: 'please12', terms_of_service: true }, - user: { name: 'user', email: 'user@example.com', password: 'please12', password_confirmation: 'please12', terms_of_service: true }, - api_accessor: { name: 'Api Accessor', email: 'api@example.com', password: 'please12', password_confirmation: 'please12', terms_of_service: true }, - example_user: { name: 'Example user', email: 'example_user@bikeindex.org', password: 'please12', password_confirmation: 'please12', terms_of_service: true } + admin: { name: "admin", email: "admin@example.com", password: "please12", password_confirmation: "please12", terms_of_service: true, superuser: true }, + member: { name: "member", email: "member@example.com", password: "please12", password_confirmation: "please12", terms_of_service: true }, + user: { name: "user", email: "user@example.com", password: "please12", password_confirmation: "please12", terms_of_service: true }, + api_accessor: { name: "Api Accessor", email: "api@example.com", password: "please12", password_confirmation: "please12", terms_of_service: true }, + example_user: { name: "Example user", email: "example_user@bikeindex.org", password: "please12", password_confirmation: "please12", terms_of_service: true }, } user_attrs.values.each do |attributes| @@ -17,23 +17,23 @@ task seed_test_users_and_bikes: :environment do new_user.save end - org = Organization.create(name: "Ikes Bike's", website: '', short_name: 'Ikes', show_on_map: true) + org = Organization.create(name: "Ikes Bike's", website: "", short_name: "Ikes", show_on_map: true) org.save - membership = Membership.create(organization_id: org.id, user_id: User.find_by_email('member@example.com').id, role: 'admin') + membership = Membership.create(organization_id: org.id, user_id: User.find_by_email("member@example.com").id, role: "admin") membership.save - org = Organization.create(name: 'Example organization', website: '', short_name: 'Example org', show_on_map: false, access_token: '7fb1c38526e57a98ec57760aa7f84992') + org = Organization.create(name: "Example organization", website: "", short_name: "Example org", show_on_map: false, access_token: "7fb1c38526e57a98ec57760aa7f84992") org.save - membership = Membership.create(organization_id: org.id, user_id: User.find_by_email('example_user@bikeindex.org').id, role: 'member') + membership = Membership.create(organization_id: org.id, user_id: User.find_by_email("example_user@bikeindex.org").id, role: "member") membership.save org.save puts "Users added successfully\n" - @user = User.find_by_email('user@example.com') - @member = User.find_by_email('member@example.com') + @user = User.find_by_email("user@example.com") + @member = User.find_by_email("member@example.com") @org = Organization.first 50.times do bike = Bike.new( cycle_type: :bike, - propulsion_type: 'foot-pedal', + propulsion_type: "foot-pedal", manufacturer_id: (rand(Manufacturer.frames.count) - 1), rear_tire_narrow: true, handlebar_type: HandlebarType.slugs.first, @@ -41,7 +41,7 @@ task seed_test_users_and_bikes: :environment do front_wheel_size_id: (rand(WheelSize.count) - 1), primary_frame_color_id: (rand(Color.count) - 1), creator: @user, - owner_email: @user.email + owner_email: @user.email, ) bike.serial_number = (0...10).map { (65 + rand(26)).chr }.join bike.creation_organization_id = @org.id @@ -61,8 +61,8 @@ task seed_test_users_and_bikes: :environment do end task seed_dup_bikes: :environment do - @user = User.find_by_email('user@example.com') - @member = User.find_by_email('member@example.com') + @user = User.find_by_email("user@example.com") + @member = User.find_by_email("member@example.com") @org = Organization.first @cycle_type = CycleType.new(:bike) @serial_number = (0...10).map { (65 + rand(26)).chr }.join @@ -70,7 +70,7 @@ task seed_dup_bikes: :environment do 500.times do bike = Bike.new( cycle_type: :bike, - propulsion_type: 'foot-pedal', + propulsion_type: "foot-pedal", manufacturer_id: @manufacturer_id, rear_tire_narrow: true, rear_wheel_size_id: WheelSize.first.id, @@ -79,7 +79,7 @@ task seed_dup_bikes: :environment do creator: @user, owner_email: @user.email, serial_number: @serial_number, - creation_organization_id: @org.id + creation_organization_id: @org.id, ) if bike.save ownership = Ownership.new(bike_id: bike.id, creator_id: @member.id, user_id: @user.id, owner_email: @user.email, current: true) diff --git a/spec/controllers/admin/ads_controller_spec.rb b/spec/controllers/admin/ads_controller_spec.rb index e3822b14cc..9b73895414 100644 --- a/spec/controllers/admin/ads_controller_spec.rb +++ b/spec/controllers/admin/ads_controller_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Admin::AdsController, type: :controller do - describe 'index' do + describe "index" do before do user = FactoryBot.create(:admin) set_current_user(user) diff --git a/spec/controllers/admin/bikes_controller_spec.rb b/spec/controllers/admin/bikes_controller_spec.rb index 64f6aff044..2e65a11851 100644 --- a/spec/controllers/admin/bikes_controller_spec.rb +++ b/spec/controllers/admin/bikes_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe Admin::BikesController do let(:user) { FactoryBot.create(:admin) } @@ -6,42 +6,42 @@ set_current_user(user) end - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index - expect(response.code).to eq('200') - expect(response).to render_template('index') + expect(response.code).to eq("200") + expect(response).to render_template("index") expect(flash).to_not be_present - expect(assigns(:page_id)).to eq 'admin_bikes_index' + expect(assigns(:page_id)).to eq "admin_bikes_index" end end - describe 'duplicates' do - it 'renders' do + describe "duplicates" do + it "renders" do get :duplicates - expect(response.code).to eq('200') - expect(response).to render_template('duplicates') + expect(response.code).to eq("200") + expect(response).to render_template("duplicates") expect(flash).to_not be_present end end - describe 'edit' do + describe "edit" do let(:bike) { FactoryBot.create(:stolen_bike) } let(:stolen_record) { bike.current_stolen_record } - context 'standard' do - it 'renders' do + context "standard" do + it "renders" do get :edit, id: FactoryBot.create(:bike).id - expect(response.code).to eq('200') - expect(response).to render_template('edit') + expect(response.code).to eq("200") + expect(response).to render_template("edit") expect(flash).to_not be_present end end - context 'with recovery' do + context "with recovery" do before { stolen_record.add_recovery_information } - it 'includes recovery' do + it "includes recovery" do get :edit, id: bike.id - expect(response.code).to eq('200') - expect(response).to render_template('edit') + expect(response.code).to eq("200") + expect(response).to render_template("edit") expect(flash).to_not be_present expect(assigns(:recoveries)).to eq bike.recovered_records expect(assigns(:recoveries).pluck(:id)).to eq([stolen_record.id]) @@ -49,8 +49,8 @@ end end - describe 'destroy' do - it 'destroys the bike' do + describe "destroy" do + it "destroys the bike" do bike = FactoryBot.create(:bike) expect do delete :destroy, id: bike.id @@ -61,10 +61,10 @@ end end - describe 'update' do - context 'success' do + describe "update" do + context "success" do let(:organization) { FactoryBot.create(:organization) } - it 'updates the bike and calls update_ownership and serial_normalizer' do + it "updates the bike and calls update_ownership and serial_normalizer" do expect_any_instance_of(BikeUpdator).to receive(:update_ownership) expect_any_instance_of(SerialNormalizer).to receive(:save_segments) bike = FactoryBot.create(:stolen_bike) @@ -72,14 +72,14 @@ expect(stolen_record).to be_present expect(stolen_record.is_a?(StolenRecord)).to be_truthy bike_attributes = { - serial_number: 'new thing and stuff', - bike_organization_ids: ['', organization.id.to_s], + serial_number: "new thing and stuff", + bike_organization_ids: ["", organization.id.to_s], stolen_records_attributes: { - "0"=> { - street: 'Cortland and Ashland', - city: 'Chicago' - } - } + "0" => { + street: "Cortland and Ashland", + city: "Chicago", + }, + }, } put :update, id: bike.id, bike: bike_attributes expect(flash[:success]).to be_present @@ -88,25 +88,25 @@ expect(bike.serial_number).to eq bike_attributes[:serial_number] expect(bike.find_current_stolen_record.id).to eq stolen_record.id stolen_record.reload - expect(stolen_record.street).to eq 'Cortland and Ashland' - expect(stolen_record.city).to eq 'Chicago' + expect(stolen_record.street).to eq "Cortland and Ashland" + expect(stolen_record.city).to eq "Chicago" expect(bike.bike_organization_ids).to eq([organization.id]) end end - context 'fast_attr_update' do - it 'marks a stolen bike recovered and passes attr update through' do + context "fast_attr_update" do + it "marks a stolen bike recovered and passes attr update through" do bike = FactoryBot.create(:stolen_bike) stolen_record = bike.current_stolen_record bike.reload expect(bike.stolen).to be_truthy opts = { id: bike.id, - mark_recovered_reason: 'I recovered it', + mark_recovered_reason: "I recovered it", mark_recovered_we_helped: true, can_share_recovery: 1, fast_attr_update: true, - bike: { stolen: 0 } + bike: { stolen: 0 }, } put :update, opts bike.reload @@ -122,64 +122,64 @@ end end - context 'valid return_to url' do - it 'redirects' do - bike = FactoryBot.create(:bike, serial_number: 'og serial') - session[:return_to] = '/about' + context "valid return_to url" do + it "redirects" do + bike = FactoryBot.create(:bike, serial_number: "og serial") + session[:return_to] = "/about" opts = { id: bike.id, - bike: { serial_number: 'ssssssssss' } + bike: { serial_number: "ssssssssss" }, } put :update, opts bike.reload - expect(bike.serial_number).to eq('ssssssssss') - expect(response).to redirect_to '/about' + expect(bike.serial_number).to eq("ssssssssss") + expect(response).to redirect_to "/about" expect(session[:return_to]).to be_nil end end end - describe 'ignore_duplicate' do + describe "ignore_duplicate" do before do - request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/bikes/missing_manufacturers' + request.env["HTTP_REFERER"] = "http://localhost:3000/admin/bikes/missing_manufacturers" end - context 'marked ignore' do - it 'duplicates are ignore' do + context "marked ignore" do + it "duplicates are ignore" do duplicate_bike_group = DuplicateBikeGroup.create expect(duplicate_bike_group.ignore).to be_falsey put :ignore_duplicate_toggle, id: duplicate_bike_group.id duplicate_bike_group.reload expect(duplicate_bike_group.ignore).to be_truthy - expect(response).to redirect_to 'http://localhost:3000/admin/bikes/missing_manufacturers' + expect(response).to redirect_to "http://localhost:3000/admin/bikes/missing_manufacturers" end end - context 'duplicate group unignore' do - it 'marks a duplicate group unignore' do + context "duplicate group unignore" do + it "marks a duplicate group unignore" do duplicate_bike_group = DuplicateBikeGroup.create(ignore: true) expect(duplicate_bike_group.ignore).to be_truthy put :ignore_duplicate_toggle, id: duplicate_bike_group.id duplicate_bike_group.reload expect(duplicate_bike_group.ignore).to be_falsey - expect(response).to redirect_to 'http://localhost:3000/admin/bikes/missing_manufacturers' + expect(response).to redirect_to "http://localhost:3000/admin/bikes/missing_manufacturers" end end end - describe 'update_manufacturers' do + describe "update_manufacturers" do before do - request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/bikes/missing_manufacturers' + request.env["HTTP_REFERER"] = "http://localhost:3000/admin/bikes/missing_manufacturers" end - it 'updates the products' do - bike1 = FactoryBot.create(:bike, manufacturer_other: 'hahaha') - bike2 = FactoryBot.create(:bike, manufacturer_other: '69') - bike3 = FactoryBot.create(:bike, manufacturer_other: '69') + it "updates the products" do + bike1 = FactoryBot.create(:bike, manufacturer_other: "hahaha") + bike2 = FactoryBot.create(:bike, manufacturer_other: "69") + bike3 = FactoryBot.create(:bike, manufacturer_other: "69") manufacturer = FactoryBot.create(:manufacturer) update_params = { manufacturer_id: manufacturer.id, - bikes_selected: { bike1.id => bike1.id, bike2.id => bike2.id } + bikes_selected: { bike1.id => bike1.id, bike2.id => bike2.id }, } post :update_manufacturers, update_params [bike1, bike2].each do |bike| @@ -188,22 +188,22 @@ expect(bike.manufacturer_other).to be_nil end bike3.reload - expect(bike3.manufacturer_other).to eq '69' # Sanity check + expect(bike3.manufacturer_other).to eq "69" # Sanity check end end - describe 'unrecover' do + describe "unrecover" do let(:bike) { FactoryBot.create(:stolen_bike) } let(:stolen_record) { bike.current_stolen_record } let(:recovery_link_token) { stolen_record.find_or_create_recovery_link_token } - let(:recovered_description) { 'something cool and party and things and stuff and it came back!!! XOXO' } + let(:recovered_description) { "something cool and party and things and stuff and it came back!!! XOXO" } before do stolen_record.add_recovery_information(recovered_description: recovered_description) bike.reload expect(bike.stolen).to be_falsey end - it 'marks unrecovered, without deleting the information about the recovery' do + it "marks unrecovered, without deleting the information about the recovery" do og_recover_link_token = recovery_link_token put :unrecover, bike_id: bike.id, stolen_record_id: stolen_record.id expect(flash[:success]).to match(/unrecovered/i) @@ -215,8 +215,8 @@ expect(stolen_record.recovered_description).to eq recovered_description expect(stolen_record.recovery_link_token).to_not eq og_recover_link_token end - context 'not matching stolen_record' do - it 'returns to bike page and renders flash' do + context "not matching stolen_record" do + it "returns to bike page and renders flash" do put :unrecover, bike_id: bike.id + 10, stolen_record_id: stolen_record.id expect(flash[:error]).to match(/contact/i) expect(response).to redirect_to admin_bike_path(bike.id + 10) diff --git a/spec/controllers/admin/customer_contacts_controller_spec.rb b/spec/controllers/admin/customer_contacts_controller_spec.rb index ffe329377d..22a9542451 100644 --- a/spec/controllers/admin/customer_contacts_controller_spec.rb +++ b/spec/controllers/admin/customer_contacts_controller_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe Admin::CustomerContactsController do - describe 'create' do - it 'creates the contact, send the email and redirect to the bike' do + describe "create" do + it "creates the contact, send the email and redirect to the bike" do stolen_record = FactoryBot.create(:stolen_record) # pp stolen_record.bike.id user = FactoryBot.create(:admin) @@ -10,9 +10,10 @@ user_email: stolen_record.bike.owner_email, creator_email: user.email, bike_id: stolen_record.bike.id, - title: 'some title', - body: 'some message', - contact_type: 'stolen_contact' } + title: "some title", + body: "some message", + contact_type: "stolen_contact", + } set_current_user(user) expect do post :create, customer_contact: customer_contact diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb index 65167e59f2..03cb48d21b 100644 --- a/spec/controllers/admin/dashboard_controller_spec.rb +++ b/spec/controllers/admin/dashboard_controller_spec.rb @@ -1,76 +1,76 @@ -require 'spec_helper' +require "spec_helper" describe Admin::DashboardController do - describe 'index' do - context 'logged in as admin' do + describe "index" do + context "logged in as admin" do include_context :logged_in_as_super_admin - it 'renders' do + it "renders" do get :index - expect(response.code).to eq '200' + expect(response.code).to eq "200" expect(response).to render_template(:index) end end - context 'not logged in' do - it 'redirects' do + context "not logged in" do + it "redirects" do get :index - expect(response.code).to eq('302') + expect(response.code).to eq("302") expect(response).to redirect_to(root_url) end end - context 'non-admin' do + context "non-admin" do include_context :logged_in_as_organization_admin - it 'redirects' do + it "redirects" do get :index - expect(response.code).to eq('302') + expect(response.code).to eq("302") expect(response).to redirect_to organization_bikes_path(organization_id: user.default_organization.to_param) end end end - context 'logged in as admin' do + context "logged in as admin" do include_context :logged_in_as_super_admin - describe 'invitations' do - it 'renders' do + describe "invitations" do + it "renders" do user = FactoryBot.create(:admin) set_current_user(user) BParam.create(creator_id: user.id) get :invitations - expect(response.code).to eq '200' + expect(response.code).to eq "200" expect(response).to render_template(:invitations) end end - describe 'maintenance' do - it 'renders' do - FactoryBot.create(:manufacturer, name: 'other') - FactoryBot.create(:ctype, name: 'other') + describe "maintenance" do + it "renders" do + FactoryBot.create(:manufacturer, name: "other") + FactoryBot.create(:ctype, name: "other") user = FactoryBot.create(:admin) set_current_user(user) BParam.create(creator_id: user.id) get :maintenance - expect(response.code).to eq '200' + expect(response.code).to eq "200" expect(response).to render_template(:maintenance) end end - describe 'tsvs' do - it 'renders and assigns tsvs' do + describe "tsvs" do + it "renders and assigns tsvs" do user = FactoryBot.create(:admin) set_current_user(user) t = Time.now - FileCacheMaintainer.reset_file_info('current_stolen_bikes.tsv', t) + FileCacheMaintainer.reset_file_info("current_stolen_bikes.tsv", t) # tsvs = [{ filename: 'current_stolen_bikes.tsv', updated_at: t.to_i.to_s, description: 'Approved Stolen bikes' }] blacklist = %w(1010101 2 4 6) FileCacheMaintainer.reset_blacklist_ids(blacklist) get :tsvs - expect(response.code).to eq('200') + expect(response.code).to eq("200") # assigns(:tsvs).should eq(tsvs) - expect(assigns(:blacklist).include?('2')).to be_truthy + expect(assigns(:blacklist).include?("2")).to be_truthy end end - describe 'update_tsv_blacklist' do - it 'renders and updates' do + describe "update_tsv_blacklist" do + it "renders and updates" do user = FactoryBot.create(:admin) set_current_user(user) ids = "\n1\n2\n69\n200\n22222\n\n\n" diff --git a/spec/controllers/admin/failed_bikes_controller_spec.rb b/spec/controllers/admin/failed_bikes_controller_spec.rb index ac5b0d421b..baff49d2b4 100644 --- a/spec/controllers/admin/failed_bikes_controller_spec.rb +++ b/spec/controllers/admin/failed_bikes_controller_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Admin::FailedBikesController do - describe 'index' do + describe "index" do before do user = FactoryBot.create(:admin) set_current_user(user) @@ -11,7 +11,7 @@ it { is_expected.to render_template(:index) } end - describe 'show' do + describe "show" do before do user = FactoryBot.create(:admin) set_current_user(user) diff --git a/spec/controllers/admin/feedbacks_controller_spec.rb b/spec/controllers/admin/feedbacks_controller_spec.rb index 715634000b..2a5019015f 100644 --- a/spec/controllers/admin/feedbacks_controller_spec.rb +++ b/spec/controllers/admin/feedbacks_controller_spec.rb @@ -1,27 +1,27 @@ -require 'spec_helper' +require "spec_helper" describe Admin::FeedbacksController, type: :controller do let(:subject) { FactoryBot.create(:feedback) } include_context :logged_in_as_super_admin - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) end end - describe 'show' do - it 'renders' do + describe "show" do + it "renders" do get :show, id: subject.to_param expect(response.status).to eq(200) expect(response).to render_template(:show) end end - describe 'graphs' do - it 'returns json' do + describe "graphs" do + it "returns json" do expect(subject).to be_present get :graphs expect(response.status).to eq(200) diff --git a/spec/controllers/admin/flavor_text_controller_spec.rb b/spec/controllers/admin/flavor_text_controller_spec.rb index 726642f2b0..2716f11c28 100644 --- a/spec/controllers/admin/flavor_text_controller_spec.rb +++ b/spec/controllers/admin/flavor_text_controller_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe Admin::FlavorTextsController do - describe 'destroy' do - it 'destroys' do - text = FlavorText.create(message: 'lulz') + describe "destroy" do + it "destroys" do + text = FlavorText.create(message: "lulz") user = FactoryBot.create(:admin) set_current_user(user) expect do @@ -12,15 +12,15 @@ end end - describe 'update' do - describe 'success' do - it 'updates' do + describe "update" do + describe "success" do + it "updates" do user = FactoryBot.create(:admin) set_current_user(user) - post :create, flavor_text: { message: 'lulz' } + post :create, flavor_text: { message: "lulz" } expect(response).to redirect_to(:admin_root) expect(flash).to be_present - expect(FlavorText.last.message).to eq 'lulz' + expect(FlavorText.last.message).to eq "lulz" end end end diff --git a/spec/controllers/admin/graphs_controller_spec.rb b/spec/controllers/admin/graphs_controller_spec.rb index cc3e40de02..42ea95b0f8 100644 --- a/spec/controllers/admin/graphs_controller_spec.rb +++ b/spec/controllers/admin/graphs_controller_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe Admin::GraphsController, type: :controller do include_context :logged_in_as_super_admin - describe 'index' do - context 'graphs' do - it 'renders' do + describe "index" do + context "graphs" do + it "renders" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) @@ -24,8 +24,8 @@ end end - describe 'tables' do - it 'renders' do + describe "tables" do + it "renders" do get :tables expect(response.status).to eq(200) expect(response).to render_template(:tables) @@ -68,12 +68,12 @@ end end context "payments" do - let!(:payment) { FactoryBot.create(:payment)} + let!(:payment) { FactoryBot.create(:payment) } it "returns json" do get :variable, kind: "payments", timezone: "America/Los_Angeles" expect(response.status).to eq(200) json_result = JSON.parse(response.body) - json_result.each do |data_group| + json_result.each do |data_group| expect(data_group.keys.count).to be > 0 expect(data_group.keys.first.class).to eq(String) expect(data_group.values.first.class).to eq(String) @@ -102,8 +102,8 @@ end end - describe 'users' do - it 'returns json' do + describe "users" do + it "returns json" do get :users expect(response.status).to eq(200) result = JSON.parse(response.body) @@ -111,27 +111,27 @@ end end - describe 'bikes' do - context 'no params' do - it 'returns JSON array' do + describe "bikes" do + context "no params" do + it "returns JSON array" do get :bikes expect(response.status).to eq(200) result = JSON.parse(response.body) expect(result.is_a?(Array)).to be_truthy - names = result.map { |r| r['name'] } - expect(names.include?('Registrations')).to be_truthy - expect(names.include?('Stolen')).to be_truthy + names = result.map { |r| r["name"] } + expect(names.include?("Registrations")).to be_truthy + expect(names.include?("Stolen")).to be_truthy end end - context 'start_at passed' do - it 'returns JSON array' do - get :bikes, start_at: 'past_year' + context "start_at passed" do + it "returns JSON array" do + get :bikes, start_at: "past_year" expect(response.status).to eq(200) result = JSON.parse(response.body) expect(result.is_a?(Array)).to be_truthy - names = result.map { |r| r['name'] } - expect(names.include?('Registrations')).to be_truthy - expect(names.include?('Stolen')).to be_truthy + names = result.map { |r| r["name"] } + expect(names.include?("Registrations")).to be_truthy + expect(names.include?("Stolen")).to be_truthy end end end diff --git a/spec/controllers/admin/mail_snippets_controller_spec.rb b/spec/controllers/admin/mail_snippets_controller_spec.rb index def84a7195..9e14285c0a 100644 --- a/spec/controllers/admin/mail_snippets_controller_spec.rb +++ b/spec/controllers/admin/mail_snippets_controller_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe Admin::MailSnippetsController do include_context :logged_in_as_super_admin - describe 'index' do - it 'renders without_organizations mail_snippets' do + describe "index" do + it "renders without_organizations mail_snippets" do FactoryBot.create(:organization_mail_snippet) mail_snippet = FactoryBot.create(:mail_snippet) get :index @@ -14,18 +14,18 @@ end end - describe 'edit' do - context 'organization_mail_snippet' do + describe "edit" do + context "organization_mail_snippet" do let(:mail_snippet) { FactoryBot.create(:organization_mail_snippet) } - it 'redirects' do + it "redirects" do expect do get :edit, id: mail_snippet.id end.to raise_error(ActiveRecord::RecordNotFound) end end - context 'non organized' do + context "non organized" do let(:mail_snippet) { FactoryBot.create(:mail_snippet) } - it 'renders' do + it "renders" do get :edit, id: mail_snippet.id expect(response.status).to eq(200) expect(response).to render_template(:edit) diff --git a/spec/controllers/admin/manufacturer_controller_spec.rb b/spec/controllers/admin/manufacturer_controller_spec.rb index 88662cc40b..30f49646c2 100644 --- a/spec/controllers/admin/manufacturer_controller_spec.rb +++ b/spec/controllers/admin/manufacturer_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe Admin::ManufacturersController, type: :controller do let(:subject) { FactoryBot.create(:manufacturer) } @@ -6,42 +6,42 @@ let(:permitted_attributes) do { - name: 'new name and things', - slug: 'new_name_and_things', - website: 'http://stuff.com', + name: "new name and things", + slug: "new_name_and_things", + website: "http://stuff.com", frame_maker: true, open_year: 1992, close_year: 89898, - description: 'new description' + description: "new description", } end - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) end end - describe 'show' do - it 'renders' do + describe "show" do + it "renders" do get :show, id: subject.slug expect(response.status).to eq(200) expect(response).to render_template(:show) end end - describe 'edit' do - context 'slug' do - it 'renders' do + describe "edit" do + context "slug" do + it "renders" do get :edit, id: subject.slug expect(response.status).to eq(200) expect(response).to render_template(:edit) end end - context 'id' do - it 'renders' do + context "id" do + it "renders" do get :edit, id: subject.id expect(response.status).to eq(200) expect(response).to render_template(:edit) @@ -49,8 +49,8 @@ end end - describe 'update' do - it 'updates available attributes' do + describe "update" do + it "updates available attributes" do put :update, id: subject.to_param, manufacturer: permitted_attributes subject.reload permitted_attributes.each do |attribute, val| @@ -60,13 +60,13 @@ end end - describe 'create' do - it 'creates with available attributes' do - expect(Manufacturer.where(name: 'new name and things').count).to eq 0 + describe "create" do + it "creates with available attributes" do + expect(Manufacturer.where(name: "new name and things").count).to eq 0 expect do post :create, manufacturer: permitted_attributes end.to change(Manufacturer, :count).by 1 - target = Manufacturer.where(name: 'new name and things').first + target = Manufacturer.where(name: "new name and things").first permitted_attributes.each { |attribute, val| expect(target.send(attribute)).to eq val } end end diff --git a/spec/controllers/admin/news_controller_spec.rb b/spec/controllers/admin/news_controller_spec.rb index 88ad27ace1..ef3799ec25 100644 --- a/spec/controllers/admin/news_controller_spec.rb +++ b/spec/controllers/admin/news_controller_spec.rb @@ -1,20 +1,20 @@ -require 'spec_helper' +require "spec_helper" describe Admin::NewsController, type: :controller do let(:subject) { FactoryBot.create(:blog) } include_context :logged_in_as_super_admin - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) end end - describe 'edit' do - context 'standard' do - it 'renders' do + describe "edit" do + context "standard" do + it "renders" do get :edit, id: subject.to_param expect(response.status).to eq(200) expect(response).to render_template(:edit) @@ -22,9 +22,9 @@ end end - describe 'update' do - it 'updates available attributes' do - blog_attrs = { title: 'new title thing stuff', body: '

    html

    ' } + describe "update" do + it "updates available attributes" do + blog_attrs = { title: "new title thing stuff", body: "

    html

    " } put :update, id: subject.to_param, blog: blog_attrs subject.reload expect(subject.title).to eq blog_attrs[:title] diff --git a/spec/controllers/admin/organizations/custom_layouts_controller_spec.rb b/spec/controllers/admin/organizations/custom_layouts_controller_spec.rb index e6195d5af7..ef5071c0d1 100644 --- a/spec/controllers/admin/organizations/custom_layouts_controller_spec.rb +++ b/spec/controllers/admin/organizations/custom_layouts_controller_spec.rb @@ -1,12 +1,12 @@ -require 'spec_helper' +require "spec_helper" describe Admin::Organizations::CustomLayoutsController, type: :controller do let(:organization) { FactoryBot.create(:organization) } - context 'super admin' do + context "super admin" do include_context :logged_in_as_super_admin - describe 'index' do - it 'redirects' do + describe "index" do + it "redirects" do get :index, organization_id: organization.to_param expect(response).to redirect_to(admin_organization_url(organization)) expect(flash).to be_present @@ -14,32 +14,32 @@ end end - context 'super admin and developer' do + context "super admin and developer" do let(:user) { FactoryBot.create(:admin_developer) } before do set_current_user(user) end - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template(:index) end end - describe 'edit' do - context 'landing_page' do - it 'renders' do - get :edit, organization_id: organization.to_param, id: 'landing_page' + describe "edit" do + context "landing_page" do + it "renders" do + get :edit, organization_id: organization.to_param, id: "landing_page" expect(response.status).to eq(200) expect(response).to render_template(:edit) end end - describe 'mail_snippets' do + describe "mail_snippets" do MailSnippet.organization_snippet_types.each do |snippet_name| context snippet_name do - it 'renders' do + it "renders" do expect(organization.mail_snippets.count).to eq 0 get :edit, organization_id: organization.to_param, id: snippet_name expect(response.status).to eq(200) @@ -53,50 +53,50 @@ end end - describe 'organization update' do - context 'landing_page' do - let(:update_attributes) { { landing_html: '

    html for the landing page

    ' } } - it 'updates and redirects to the landing_page edit' do + describe "organization update" do + context "landing_page" do + let(:update_attributes) { { landing_html: "

    html for the landing page

    " } } + it "updates and redirects to the landing_page edit" do put :update, organization_id: organization.to_param, - organization: update_attributes, id: 'landing_page' - target = edit_admin_organization_custom_layout_path(organization_id: organization.to_param, id: 'landing_page') + organization: update_attributes, id: "landing_page" + target = edit_admin_organization_custom_layout_path(organization_id: organization.to_param, id: "landing_page") expect(response).to redirect_to target organization.reload expect(organization.landing_html).to eq update_attributes[:landing_html] end end - context 'mail_snippet' do + context "mail_snippet" do let(:snippet_type) { MailSnippet.organization_snippet_types.last } let(:mail_snippet) do FactoryBot.create(:organization_mail_snippet, - organization: organization, - name: snippet_type, - is_enabled: false) + organization: organization, + name: snippet_type, + is_enabled: false) end let(:update_attributes) do { mail_snippets_attributes: { - '0' => { + "0" => { id: mail_snippet.id, - name: 'CRAZZY new name', # ignore - body: '

    html for snippet 1

    ', + name: "CRAZZY new name", # ignore + body: "

    html for snippet 1

    ", organization_id: 844, # Ignore - is_enabled: true - } - } + is_enabled: true, + }, + }, } end - it 'updates the mail snippets' do + it "updates the mail snippets" do expect(mail_snippet.is_enabled).to be_falsey expect do put :update, organization_id: organization.to_param, - organization: update_attributes, id: snippet_type + organization: update_attributes, id: snippet_type end.to change(MailSnippet, :count).by 0 target = edit_admin_organization_custom_layout_path(organization_id: organization.to_param, id: mail_snippet.name) expect(response).to redirect_to target mail_snippet.reload expect(mail_snippet.name).to eq snippet_type - expect(mail_snippet.body).to eq '

    html for snippet 1

    ' + expect(mail_snippet.body).to eq "

    html for snippet 1

    " expect(mail_snippet.organization).to eq organization expect(mail_snippet.is_enabled).to be_truthy end diff --git a/spec/controllers/admin/organizations/invoices_controller_spec.rb b/spec/controllers/admin/organizations/invoices_controller_spec.rb index fed14238c1..32c9ff43c6 100644 --- a/spec/controllers/admin/organizations/invoices_controller_spec.rb +++ b/spec/controllers/admin/organizations/invoices_controller_spec.rb @@ -11,7 +11,7 @@ amount_due: "1220", timezone: "EST", start_at: "2018-09-05T23:00:00", - notes: "some cool note about when something was paid" + notes: "some cool note about when something was paid", } end context "super admin" do diff --git a/spec/controllers/admin/organizations_controller_spec.rb b/spec/controllers/admin/organizations_controller_spec.rb index 302d9312fc..97860e0435 100644 --- a/spec/controllers/admin/organizations_controller_spec.rb +++ b/spec/controllers/admin/organizations_controller_spec.rb @@ -1,73 +1,73 @@ -require 'spec_helper' +require "spec_helper" describe Admin::OrganizationsController, type: :controller do let(:organization) { FactoryBot.create(:organization, approved: false) } include_context :logged_in_as_super_admin - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) end end - describe 'edit' do - it 'renders' do + describe "edit" do + it "renders" do get :edit, id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template(:edit) end end - describe 'organization update' do + describe "organization update" do let(:state) { FactoryBot.create(:state) } let(:country) { state.country } let(:parent_organization) { FactoryBot.create(:organization) } - let(:location_1) { FactoryBot.create(:location, organization: organization, street: 'old street', name: 'cool name') } + let(:location_1) { FactoryBot.create(:location, organization: organization, street: "old street", name: "cool name") } let(:update_attributes) do { - name: 'new name thing stuff', + name: "new name thing stuff", show_on_map: true, - kind: 'shop', + kind: "shop", parent_organization_id: parent_organization.id, ascend_name: "party on", locations_attributes: { - '0' => { + "0" => { id: location_1.id, - name: 'First shop', - zipcode: '2222222', - city: 'First city', + name: "First shop", + zipcode: "2222222", + city: "First city", state_id: state.id, country_id: country.id, - street: 'some street 2', - phone: '7272772727272', - email: 'stuff@goooo.com', + street: "some street 2", + phone: "7272772727272", + email: "stuff@goooo.com", latitude: 22_222, longitude: 11_111, organization_id: 844, shown: false, - _destroy: 0 + _destroy: 0, }, Time.zone.now.to_i.to_s => { created_at: Time.zone.now.to_f.to_s, - name: 'Second shop', - zipcode: '12243444', - city: 'cool city', + name: "Second shop", + zipcode: "12243444", + city: "cool city", state_id: state.id, country_id: country.id, - street: 'some street 2', - phone: '7272772727272', - email: 'stuff@goooo.com', + street: "some street 2", + phone: "7272772727272", + email: "stuff@goooo.com", latitude: 22_222, longitude: 11_111, organization_id: 844, - shown: false - } - } + shown: false, + }, + }, } end - it 'updates the organization' do + it "updates the organization" do expect(location_1).to be_present expect do put :update, organization_id: organization.to_param, id: organization.to_param, organization: update_attributes @@ -79,7 +79,7 @@ # Existing location is updated location_1.reload expect(location_1.organization).to eq organization - update_attributes[:locations_attributes]['0'].except(:latitude, :longitude, :organization_id, :created_at, :_destroy).each do |k, v| + update_attributes[:locations_attributes]["0"].except(:latitude, :longitude, :organization_id, :created_at, :_destroy).each do |k, v| expect(location_1.send(k)).to eq v end # still existing location diff --git a/spec/controllers/admin/ownerships_controller_spec.rb b/spec/controllers/admin/ownerships_controller_spec.rb index e362444797..4182a625c4 100644 --- a/spec/controllers/admin/ownerships_controller_spec.rb +++ b/spec/controllers/admin/ownerships_controller_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe Admin::OwnershipsController do - describe 'edit' do - it 'renders' do + describe "edit" do + it "renders" do ownership = FactoryBot.create(:ownership) user = FactoryBot.create(:admin) set_current_user(user) @@ -12,8 +12,8 @@ end end - describe 'update' do - it 'updates ownership' do + describe "update" do + it "updates ownership" do ownership = FactoryBot.create(:ownership) og_creator = ownership.creator user = FactoryBot.create(:admin) @@ -21,7 +21,7 @@ update_params = { user_email: ownership.creator.email, creator_email: user.email, - user_hidden: true + user_hidden: true, } put :update, id: ownership.id, ownership: update_params ownership.reload diff --git a/spec/controllers/admin/paints_controller_spec.rb b/spec/controllers/admin/paints_controller_spec.rb index c96398ad1a..2657b38ca0 100644 --- a/spec/controllers/admin/paints_controller_spec.rb +++ b/spec/controllers/admin/paints_controller_spec.rb @@ -1,17 +1,17 @@ -require 'spec_helper' +require "spec_helper" describe Admin::PaintsController do include_context :logged_in_as_super_admin - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) end end - describe 'edit' do - it 'renders' do + describe "edit" do + it "renders" do paint = FactoryBot.create(:paint) get :edit, id: paint.id expect(response.status).to eq(200) diff --git a/spec/controllers/admin/recoveries_controller_spec.rb b/spec/controllers/admin/recoveries_controller_spec.rb index 7295727995..4828739a62 100644 --- a/spec/controllers/admin/recoveries_controller_spec.rb +++ b/spec/controllers/admin/recoveries_controller_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe Admin::RecoveriesController do - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do user = FactoryBot.create(:admin) set_current_user(user) get :index diff --git a/spec/controllers/admin/recovery_displays_controller_spec.rb b/spec/controllers/admin/recovery_displays_controller_spec.rb index 8d2755ca1a..f1d2e85998 100644 --- a/spec/controllers/admin/recovery_displays_controller_spec.rb +++ b/spec/controllers/admin/recovery_displays_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe Admin::RecoveryDisplaysController do before do @@ -6,8 +6,8 @@ set_current_user(user) end - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index expect(response).to be_success expect(response).to render_template(:index) @@ -35,23 +35,23 @@ end end - describe 'create' do - context 'valid create' do - let(:valid_attrs) { { quote: 'something that is nice and short and stuff' } } - it 'creates the recovery_display' do + describe "create" do + context "valid create" do + let(:valid_attrs) { { quote: "something that is nice and short and stuff" } } + it "creates the recovery_display" do post :create, recovery_display: valid_attrs recovery_display = RecoveryDisplay.last expect(recovery_display.quote).to eq valid_attrs[:quote] end end - context 'valid create' do + context "valid create" do let(:invalid_attrs) do { - quote: 'La croix scenester pug glossier, yuccie salvia humblebrag chia. Meditation health goth readymade flannel hot chicken austin tofu salvia cornhole tumeric hashtag plaid. Umami vegan hell of before they sold out copper mug chillwave authentic poke mumblecore godard la croix 8-bit. Venmo raw denim synth wolf. Food truck hot chicken waistcoat activated charcoal' + quote: "La croix scenester pug glossier, yuccie salvia humblebrag chia. Meditation health goth readymade flannel hot chicken austin tofu salvia cornhole tumeric hashtag plaid. Umami vegan hell of before they sold out copper mug chillwave authentic poke mumblecore godard la croix 8-bit. Venmo raw denim synth wolf. Food truck hot chicken waistcoat activated charcoal", } end - it 'does not create a recovery display that is too long' do + it "does not create a recovery display that is too long" do expect do post :create, recovery_display: invalid_attrs end.to change(RecoveryDisplay, :count).by 0 diff --git a/spec/controllers/admin/stolen_bikes_controller_spec.rb b/spec/controllers/admin/stolen_bikes_controller_spec.rb index 3c758e7ce1..5ef53a5745 100644 --- a/spec/controllers/admin/stolen_bikes_controller_spec.rb +++ b/spec/controllers/admin/stolen_bikes_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe Admin::StolenBikesController do let(:user) { FactoryBot.create(:admin) } @@ -6,38 +6,38 @@ set_current_user(user) end - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index - expect(response.code).to eq('200') - expect(response).to render_template('index') + expect(response.code).to eq("200") + expect(response).to render_template("index") expect(flash).to_not be_present end end - describe 'edit' do + describe "edit" do let(:bike) { FactoryBot.create(:stolen_bike) } let(:stolen_record) { bike.current_stolen_record } - it 'renders' do + it "renders" do expect(stolen_record.recovery_link_token).to_not be_present get :edit, id: bike.id stolen_record.reload expect(stolen_record.recovery_link_token).to be_present - expect(response.code).to eq('200') - expect(response).to render_template('edit') + expect(response.code).to eq("200") + expect(response).to render_template("edit") expect(flash).to_not be_present end end - describe 'update' do - context 'success' do - it 'updates the bike and calls update_ownership and serial_normalizer' do + describe "update" do + context "success" do + it "updates the bike and calls update_ownership and serial_normalizer" do expect_any_instance_of(BikeUpdator).to receive(:update_ownership) expect_any_instance_of(SerialNormalizer).to receive(:save_segments) ownership = FactoryBot.create(:ownership) bike = ownership.bike - put :update, id: bike.id, bike: { serial_number: 'stuff' } + put :update, id: bike.id, bike: { serial_number: "stuff" } expect(response).to redirect_to(:edit_admin_stolen_bike) expect(flash).to be_present end diff --git a/spec/controllers/admin/stolen_notifications_controller_spec.rb b/spec/controllers/admin/stolen_notifications_controller_spec.rb index 9f5ba0f8b0..de1fd0c79d 100644 --- a/spec/controllers/admin/stolen_notifications_controller_spec.rb +++ b/spec/controllers/admin/stolen_notifications_controller_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Admin::StolenNotificationsController do - describe 'index' do + describe "index" do before do user = FactoryBot.create(:admin) set_current_user(user) @@ -12,7 +12,7 @@ it { is_expected.not_to set_flash } end - describe 'show' do + describe "show" do before do stolen_notification = FactoryBot.create(:stolen_notification) user = FactoryBot.create(:admin) @@ -24,8 +24,8 @@ it { is_expected.not_to set_flash } end - describe 'resend' do - it 'resends the stolen notification' do + describe "resend" do + it "resends the stolen notification" do Sidekiq::Worker.clear_all sender = FactoryBot.create(:user) admin = FactoryBot.create(:admin) @@ -37,7 +37,7 @@ end.to change(EmailStolenNotificationWorker.jobs, :size).by(1) end - it 'redirects if the stolen notification has already been sent' do + it "redirects if the stolen notification has already been sent" do Sidekiq::Worker.clear_all sender = FactoryBot.create(:user) admin = FactoryBot.create(:admin) @@ -50,7 +50,7 @@ expect(response).to redirect_to(:admin_stolen_notification) end - it 'resends if the stolen notification has already been sent if we say pretty please' do + it "resends if the stolen notification has already been sent if we say pretty please" do Sidekiq::Worker.clear_all sender = FactoryBot.create(:user) admin = FactoryBot.create(:admin) diff --git a/spec/controllers/admin/tweets_controller_spec.rb b/spec/controllers/admin/tweets_controller_spec.rb index b8b705c587..b1a3931987 100644 --- a/spec/controllers/admin/tweets_controller_spec.rb +++ b/spec/controllers/admin/tweets_controller_spec.rb @@ -1,38 +1,38 @@ -require 'spec_helper' +require "spec_helper" describe Admin::TweetsController do let(:subject) { FactoryBot.create(:tweet) } let(:user) { FactoryBot.create(:admin) } before { set_current_user(user) } - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index expect(response).to be_success expect(response).to render_template(:index) end end - describe 'edit' do - it 'renders' do + describe "edit" do + it "renders" do get :edit, id: subject.twitter_id expect(response).to be_success expect(response).to render_template(:edit) end end - describe 'new' do - it 'renders' do + describe "new" do + it "renders" do get :new expect(response).to be_success expect(response).to render_template(:new) end end - describe 'create' do - xit 'gets the tweet from twitter' do + describe "create" do + xit "gets the tweet from twitter" do # expect do - post :create, tweet: { twitter_id: '839247587521679360' } + post :create, tweet: { twitter_id: "839247587521679360" } # end.to change(Tweet, :count).by(1) expect(response).to redirect_to edit_admin_tweet_url expect(flash[:success]).to be_present diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index 9876d393a3..0feb8cafce 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -1,14 +1,14 @@ -require 'spec_helper' +require "spec_helper" describe Admin::UsersController do - describe 'edit' do + describe "edit" do xit "404s if the user doesn't exist" do # I have no idea why this fails. It works really, but not in tests! expect do - get :edit, id: 'STUFFFFFF' + get :edit, id: "STUFFFFFF" end.to raise_error(ActionController::RoutingError) end - it 'shows the edit page if the user exists' do + it "shows the edit page if the user exists" do admin = FactoryBot.create(:admin) user = FactoryBot.create(:user) set_current_user(admin) @@ -17,23 +17,23 @@ end end - describe 'update' do - context 'non developer' do + describe "update" do + context "non developer" do it "updates all the things that can be edited (finding via user id)" do admin = FactoryBot.create(:admin) user = FactoryBot.create(:user, confirmed: false) set_current_user(admin) post :update, id: user.id, user: { - name: 'New Name', - email: 'newemailexample.com', - confirmed: true, - superuser: true, - developer: true, - can_send_many_stolen_notifications: true, - banned: true - } - expect(user.reload.name).to eq('New Name') - expect(user.email).to eq('newemailexample.com') + name: "New Name", + email: "newemailexample.com", + confirmed: true, + superuser: true, + developer: true, + can_send_many_stolen_notifications: true, + banned: true, + } + expect(user.reload.name).to eq("New Name") + expect(user.email).to eq("newemailexample.com") expect(user.confirmed).to be_truthy expect(user.superuser).to be_truthy expect(user.developer).to be_falsey @@ -41,19 +41,19 @@ expect(user.banned).to be_truthy end end - context 'developer' do - it 'updates developer' do + context "developer" do + it "updates developer" do admin = FactoryBot.create(:admin_developer) set_current_user(admin) user = FactoryBot.create(:user) post :update, id: user.username, user: { - developer: true, - email: user.email, - superuser: false, - can_send_many_stolen_notifications: true, - banned: true - } + developer: true, + email: user.email, + superuser: false, + can_send_many_stolen_notifications: true, + banned: true, + } user.reload expect(user.developer).to be_truthy end diff --git a/spec/controllers/api/v1/bikes_controller_spec.rb b/spec/controllers/api/v1/bikes_controller_spec.rb index 87555cf7b3..f0e75b1a2f 100644 --- a/spec/controllers/api/v1/bikes_controller_spec.rb +++ b/spec/controllers/api/v1/bikes_controller_spec.rb @@ -1,22 +1,22 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::BikesController do - describe 'index' do - it 'loads the page and have the correct headers' do + describe "index" do + it "loads the page and have the correct headers" do FactoryBot.create(:bike) get :index, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end - describe 'stolen_ids' do - it 'returns correct code if no org' do + describe "stolen_ids" do + it "returns correct code if no org" do c = FactoryBot.create(:color) get :stolen_ids, format: :json - expect(response.code).to eq('401') + expect(response.code).to eq("401") end - it 'should return an array of ids' do + it "should return an array of ids" do bike = FactoryBot.create(:bike) stole1 = FactoryBot.create(:stolen_record) stole2 = FactoryBot.create(:stolen_record, approved: true) @@ -25,86 +25,86 @@ FactoryBot.create(:membership, user: user, organization: organization) options = { stolen: true, organization_slug: organization.slug, access_token: organization.access_token } get :stolen_ids, options.as_json - expect(response.code).to eq('200') - bikes = JSON.parse(response.body)['bikes'] + expect(response.code).to eq("200") + bikes = JSON.parse(response.body)["bikes"] expect(bikes.count).to eq(1) expect(bikes.first).to eq(stole2.bike.id) end end - describe 'show' do - it 'loads the page' do + describe "show" do + it "loads the page" do bike = FactoryBot.create(:bike) get :show, id: bike.id, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end - describe 'create' do + describe "create" do before do FactoryBot.create(:wheel_size, iso_bsd: 559) - FactoryBot.create(:ctype, name: 'wheel') - FactoryBot.create(:ctype, name: 'headset') + FactoryBot.create(:ctype, name: "wheel") + FactoryBot.create(:ctype, name: "headset") end - context 'pos_integrator rear_gear_type_slug error' do + context "pos_integrator rear_gear_type_slug error" do let(:auto_user) { FactoryBot.create(:organization_auto_user) } let(:organization) { auto_user.organizations.first } - let(:manufacturer) { FactoryBot.create(:manufacturer, name: 'Specialized') } - let(:black) { FactoryBot.create(:color, name: 'Black') } - let(:red) { FactoryBot.create(:color, name: 'Red') } + let(:manufacturer) { FactoryBot.create(:manufacturer, name: "Specialized") } + let(:black) { FactoryBot.create(:color, name: "Black") } + let(:red) { FactoryBot.create(:color, name: "Red") } let(:bike_hash) do { organization_slug: organization.slug, access_token: organization.access_token, bike: { - owner_email: 'example@gmail.com', - serial_number: 'SSOMESERIAL', - manufacturer: 'Specialized', - frame_model: 'Diverge Elite DSW (58)', - cycle_type: 'trail-behind', - color: 'Black/Red', + owner_email: "example@gmail.com", + serial_number: "SSOMESERIAL", + manufacturer: "Specialized", + frame_model: "Diverge Elite DSW (58)", + cycle_type: "trail-behind", + color: "Black/Red", send_email: true, - frame_size: '58', - frame_size_unit: 'cm', + frame_size: "58", + frame_size_unit: "cm", year: 2016, rear_wheel_size: nil, rear_gear_type_slug: nil, handlebar_type_slug: nil, frame_material_slug: "", - description: 'Diverge Elite DSW (58)', + description: "Diverge Elite DSW (58)", is_pos: true, is_new: true, - is_bulk: true - } + is_bulk: true, + }, } end before do expect([black, red, manufacturer].size).to eq 3 end - it 'creates a bike and does not duplicate' do + it "creates a bike and does not duplicate" do expect do - post :create, bike_hash.as_json, headers: { 'Content-Type' => 'application/json' } + post :create, bike_hash.as_json, headers: { "Content-Type" => "application/json" } end.to change(Ownership, :count).by(1) - expect(response.code).to eq('200') - bike = Bike.where(serial_number: 'SSOMESERIAL').first + expect(response.code).to eq("200") + bike = Bike.where(serial_number: "SSOMESERIAL").first expect(bike.manufacturer).to eq manufacturer - expect(bike.frame_model).to eq 'Diverge Elite DSW (58)' - expect(bike.frame_size).to eq '58cm' - expect(bike.frame_size_unit).to eq 'cm' + expect(bike.frame_model).to eq "Diverge Elite DSW (58)" + expect(bike.frame_size).to eq "58cm" + expect(bike.frame_size_unit).to eq "cm" expect(bike.primary_frame_color).to eq black - expect(bike.paint_description).to eq 'Black/Red' + expect(bike.paint_description).to eq "Black/Red" creation_state = bike.creation_state expect([creation_state.is_pos, creation_state.is_new, creation_state.is_bulk]).to eq([true, true, true]) expect(creation_state.organization).to eq organization expect(creation_state.creator).to eq bike.creator - expect(creation_state.origin).to eq 'api_v1' + expect(creation_state.origin).to eq "api_v1" expect do updated_hash = bike_hash.merge(bike: bike_hash[:bike].merge(no_duplicate: true)) - post :create, updated_hash.as_json, headers: { 'Content-Type' => 'application/json' } + post :create, updated_hash.as_json, headers: { "Content-Type" => "application/json" } end.to change(Ownership, :count).by 0 end end - context 'legacy tests' do + context "legacy tests" do before :each do @organization = FactoryBot.create(:organization) user = FactoryBot.create(:user) @@ -112,88 +112,88 @@ @organization.save end - it 'returns correct code if not logged in' do + it "returns correct code if not logged in" do c = FactoryBot.create(:color) - post :create, { bike: { serial_number: '69', color: c.name } } - expect(response.code).to eq('401') + post :create, { bike: { serial_number: "69", color: c.name } } + expect(response.code).to eq("401") end - it 'returns correct code if bike has errors' do + it "returns correct code if bike has errors" do c = FactoryBot.create(:color) - post :create, { bike: { serial_number: '69', color: c.name }, organization_slug: @organization.slug, access_token: @organization.access_token } - expect(response.code).to eq('422') + post :create, { bike: { serial_number: "69", color: c.name }, organization_slug: @organization.slug, access_token: @organization.access_token } + expect(response.code).to eq("422") end it "emails us if it can't create a record" do c = FactoryBot.create(:color) expect do - post :create, { bike: { serial_number: '69', color: c.name }, organization_slug: @organization.slug, access_token: @organization.access_token } + post :create, { bike: { serial_number: "69", color: c.name }, organization_slug: @organization.slug, access_token: @organization.access_token } end.to change(Feedback, :count).by(1) end - it 'creates a record and reset example' do + it "creates a record and reset example" do manufacturer = FactoryBot.create(:manufacturer) rear_gear_type = FactoryBot.create(:rear_gear_type) front_gear_type = FactoryBot.create(:front_gear_type) f_count = Feedback.count bike_attrs = { - serial_number: '69 non-example', + serial_number: "69 non-example", manufacturer_id: manufacturer.id, - rear_tire_narrow: 'true', + rear_tire_narrow: "true", rear_wheel_bsd: 559, color: FactoryBot.create(:color).name, example: true, - year: '1969', - owner_email: 'fun_times@examples.com', + year: "1969", + owner_email: "fun_times@examples.com", frame_model: "Tricruiser Tricycle", - cycle_type: 'trail-behind', + cycle_type: "trail-behind", send_email: true, - frame_size: '56cm', + frame_size: "56cm", frame_size_unit: nil, rear_gear_type_slug: rear_gear_type.slug, front_gear_type_slug: front_gear_type.slug, handlebar_type_slug: "forward", - registered_new: true + registered_new: true, } components = [ { manufacturer: manufacturer.name, - year: '1999', - component_type: 'Headset', - cgroup: 'Frame and fork', - description: 'yeah yay!', - serial_number: '69', - model_name: 'Richie rich' + year: "1999", + component_type: "Headset", + cgroup: "Frame and fork", + description: "yeah yay!", + serial_number: "69", + model_name: "Richie rich", }, { - manufacturer: 'BLUE TEETH', - front_or_rear: 'Both', - cgroup: 'Wheels', - component_type: 'wheel' - } + manufacturer: "BLUE TEETH", + front_or_rear: "Both", + cgroup: "Wheels", + component_type: "wheel", + }, ] photos = [ - 'http://i.imgur.com/lybYl1l.jpg', - 'http://i.imgur.com/3BGQeJh.jpg' + "http://i.imgur.com/lybYl1l.jpg", + "http://i.imgur.com/3BGQeJh.jpg", ] expect_any_instance_of(OwnershipCreator).to receive(:send_notification_email) expect do post :create, bike: bike_attrs, organization_slug: @organization.slug, - access_token: @organization.access_token, components: components, photos: photos + access_token: @organization.access_token, components: components, photos: photos end.to change(Ownership, :count).by(1) - expect(response.code).to eq('200') - bike = Bike.where(serial_number: '69 non-example').first + expect(response.code).to eq("200") + bike = Bike.where(serial_number: "69 non-example").first expect(bike.example).to be_falsey expect(bike.creation_organization_id).to eq(@organization.id) expect(bike.year).to eq(1969) expect(bike.components.count).to eq(3) expect(bike.creation_state.organization).to eq @organization - component = bike.components.where(serial_number: '69').first - expect(component.description).to eq('yeah yay!') - expect(component.ctype.slug).to eq('headset') + component = bike.components.where(serial_number: "69").first + expect(component.description).to eq("yeah yay!") + expect(component.ctype.slug).to eq("headset") expect(component.year).to eq(1999) expect(component.manufacturer_id).to eq(manufacturer.id) - expect(component.cmodel_name).to eq('Richie rich') + expect(component.cmodel_name).to eq("Richie rich") expect(bike.public_images.count).to eq(2) expect(f_count).to eq(Feedback.count) skipped = %w(send_email frame_size_unit rear_wheel_bsd color example rear_gear_type_slug front_gear_type_slug handlebar_type_slug) @@ -201,7 +201,7 @@ pp attr_name unless bike.send(attr_name).to_s == value.to_s expect(bike.send(attr_name).to_s).to eq value.to_s end - expect(bike.frame_size_unit).to eq 'cm' + expect(bike.frame_size_unit).to eq "cm" expect(bike.rear_wheel_size.iso_bsd).to eq bike_attrs[:rear_wheel_bsd] expect(bike.primary_frame_color.name).to eq bike_attrs[:color] expect(bike.rear_gear_type.slug).to eq bike_attrs[:rear_gear_type_slug] @@ -211,31 +211,31 @@ expect([creation_state.is_pos, creation_state.is_new, creation_state.is_bulk]).to eq([false, false, false]) expect(creation_state.organization).to eq @organization expect(creation_state.creator).to eq bike.creator - expect(creation_state.origin).to eq 'api_v1' + expect(creation_state.origin).to eq "api_v1" end - it 'creates a photos even if one fails' do + it "creates a photos even if one fails" do manufacturer = FactoryBot.create(:manufacturer) f_count = Feedback.count bike_attrs = { - serial_number: '69 photo-test', + serial_number: "69 photo-test", manufacturer_id: manufacturer.id, - rear_tire_narrow: 'true', - rear_wheel_bsd: '559', + rear_tire_narrow: "true", + rear_wheel_bsd: "559", color: FactoryBot.create(:color).name, example: true, - year: '1969', - owner_email: 'fun_times@examples.com', - cycle_type: 'wheelchair' + year: "1969", + owner_email: "fun_times@examples.com", + cycle_type: "wheelchair", } photos = [ - 'http://i.imgur.com/lybYl1l.jpg', - 'http://bikeindex.org/not_actually_a_thing_404_and_shit' + "http://i.imgur.com/lybYl1l.jpg", + "http://bikeindex.org/not_actually_a_thing_404_and_shit", ] post :create, bike: bike_attrs, organization_slug: @organization.slug, access_token: @organization.access_token, photos: photos - bike = Bike.where(serial_number: '69 photo-test').first + bike = Bike.where(serial_number: "69 photo-test").first expect(bike.public_images.count).to eq(1) - expect(bike.creation_state.origin).to eq 'api_v1' + expect(bike.creation_state.origin).to eq "api_v1" expect(bike.creation_state.creator).to eq bike.creator expect(bike.creation_state.organization).to eq @organization expect(bike.rear_wheel_size.iso_bsd).to eq 559 @@ -257,7 +257,7 @@ owner_email: "fun_times@examples.com", stolen: "true", phone: "9999999", - cycle_type_slug: "bike" + cycle_type_slug: "bike", } stolen_record = { date_stolen: "03-01-2013", @@ -269,7 +269,7 @@ police_report_number: "99999999", police_report_department: "Chicago", locking_description: "some locking description", - lock_defeat_description: "broken in some crazy way" + lock_defeat_description: "broken in some crazy way", } expect_any_instance_of(OwnershipCreator).to receive(:send_notification_email) @@ -292,79 +292,79 @@ end end - it 'creates an example bike if the bike is from example, and include all the options' do - FactoryBot.create(:color, name: 'Black') - org = FactoryBot.create(:organization, name: 'Example organization') + it "creates an example bike if the bike is from example, and include all the options" do + FactoryBot.create(:color, name: "Black") + org = FactoryBot.create(:organization, name: "Example organization") user = FactoryBot.create(:user) FactoryBot.create(:membership, user: user, organization: org) manufacturer = FactoryBot.create(:manufacturer) org.save bike_attrs = { - serial_number: '69 example bikez', - cycle_type_slug: 'unicycle', + serial_number: "69 example bikez", + cycle_type_slug: "unicycle", manufacturer_id: manufacturer.id, - rear_tire_narrow: 'true', + rear_tire_narrow: "true", rear_wheel_size: 559, - color: 'grazeen', + color: "grazeen", frame_material_slug: "Steel", handlebar_type_slug: "Other", - description: 'something else', - owner_email: 'fun_times@examples.com' + description: "something else", + owner_email: "fun_times@examples.com", } expect do expect do post :create, bike: bike_attrs, organization_slug: org.slug, access_token: org.access_token end.to change(Ownership, :count).by(1) end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(0) - expect(response.code).to eq('200') - bike = Bike.unscoped.where(serial_number: '69 example bikez').first - expect(bike.creation_state.origin).to eq 'api_v1' + expect(response.code).to eq("200") + bike = Bike.unscoped.where(serial_number: "69 example bikez").first + expect(bike.creation_state.origin).to eq "api_v1" expect(bike.creation_state.organization).to eq org expect(bike.example).to be_truthy expect(bike.rear_wheel_size.iso_bsd).to eq 559 - expect(bike.paint.name).to eq('grazeen') - expect(bike.description).to eq('something else') - expect(bike.frame_material_name).to eq('Steel') - expect(bike.frame_material).to eq('steel') - expect(bike.handlebar_type).to eq('other') - expect(bike.cycle_type).to eq('unicycle') - expect(bike.cycle_type_name).to eq('Unicycle') + expect(bike.paint.name).to eq("grazeen") + expect(bike.description).to eq("something else") + expect(bike.frame_material_name).to eq("Steel") + expect(bike.frame_material).to eq("steel") + expect(bike.handlebar_type).to eq("other") + expect(bike.cycle_type).to eq("unicycle") + expect(bike.cycle_type_name).to eq("Unicycle") end - it 'creates a record even if the post is a string' do + it "creates a record even if the post is a string" do manufacturer = FactoryBot.create(:manufacturer) f_count = Feedback.count bike_attrs = { - serial_number: '69 string', + serial_number: "69 string", manufacturer_id: manufacturer.id, - rear_tire_narrow: 'true', - rear_wheel_bsd: '559', + rear_tire_narrow: "true", + rear_wheel_bsd: "559", color: FactoryBot.create(:color).name, - owner_email: 'jsoned@examples.com', - cycle_type: 'tandem' + owner_email: "jsoned@examples.com", + cycle_type: "tandem", } options = { bike: bike_attrs.to_json, organization_slug: @organization.slug, access_token: @organization.access_token } expect do post :create, options end.to change(Ownership, :count).by(1) - expect(response.code).to eq('200') - bike = Bike.unscoped.where(serial_number: '69 string').first - expect(bike.creation_state.origin).to eq 'api_v1' + expect(response.code).to eq("200") + bike = Bike.unscoped.where(serial_number: "69 string").first + expect(bike.creation_state.origin).to eq "api_v1" expect(bike.creation_state.organization).to eq @organization end - it 'does not send an ownership email if it has no_email set' do + it "does not send an ownership email if it has no_email set" do manufacturer = FactoryBot.create(:manufacturer) f_count = Feedback.count bike = { - serial_number: '69 string', + serial_number: "69 string", manufacturer_id: manufacturer.id, - rear_tire_narrow: 'true', - rear_wheel_bsd: '559', + rear_tire_narrow: "true", + rear_wheel_bsd: "559", color: FactoryBot.create(:color).name, - owner_email: 'jsoned@examples.com', - send_email: 'false', - cycle_type_name: ' trailer ' + owner_email: "jsoned@examples.com", + send_email: "false", + cycle_type_name: " trailer ", } options = { bike: bike.to_json, organization_slug: @organization.slug, access_token: @organization.access_token } expect do @@ -372,9 +372,9 @@ post :create, options end.to change(Ownership, :count).by(1) end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(0) - expect(response.code).to eq('200') - bike = Bike.unscoped.where(serial_number: '69 string').first - expect(bike.creation_state.origin).to eq 'api_v1' + expect(response.code).to eq("200") + bike = Bike.unscoped.where(serial_number: "69 string").first + expect(bike.creation_state.origin).to eq "api_v1" expect(bike.creation_state.organization).to eq @organization end end diff --git a/spec/controllers/api/v1/colors_controller_spec.rb b/spec/controllers/api/v1/colors_controller_spec.rb index 6f360f58a0..5806d15fd5 100644 --- a/spec/controllers/api/v1/colors_controller_spec.rb +++ b/spec/controllers/api/v1/colors_controller_spec.rb @@ -1,11 +1,11 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::ColorsController do - describe 'index' do - it 'loads the page' do + describe "index" do + it "loads the page" do FactoryBot.create(:color) get :index, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end end diff --git a/spec/controllers/api/v1/component_types_controller_spec.rb b/spec/controllers/api/v1/component_types_controller_spec.rb index 67f92803f0..685ac37ac1 100644 --- a/spec/controllers/api/v1/component_types_controller_spec.rb +++ b/spec/controllers/api/v1/component_types_controller_spec.rb @@ -1,11 +1,11 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::ComponentTypesController do - describe 'index' do - it 'loads the request' do + describe "index" do + it "loads the request" do FactoryBot.create(:ctype) get :index, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end end diff --git a/spec/controllers/api/v1/cycle_types_controller_spec.rb b/spec/controllers/api/v1/cycle_types_controller_spec.rb index ca06660809..808cdb65a6 100644 --- a/spec/controllers/api/v1/cycle_types_controller_spec.rb +++ b/spec/controllers/api/v1/cycle_types_controller_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::CycleTypesController do - describe 'index' do - it 'loads the request' do + describe "index" do + it "loads the request" do get :index, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end end diff --git a/spec/controllers/api/v1/frame_materials_controller_spec.rb b/spec/controllers/api/v1/frame_materials_controller_spec.rb index c7dbec7cb8..3db90a059a 100644 --- a/spec/controllers/api/v1/frame_materials_controller_spec.rb +++ b/spec/controllers/api/v1/frame_materials_controller_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::FrameMaterialsController do - describe 'index' do - it 'loads the page' do + describe "index" do + it "loads the page" do get :index, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end end diff --git a/spec/controllers/api/v1/handlebar_types_controller_spec.rb b/spec/controllers/api/v1/handlebar_types_controller_spec.rb index 950e5142ca..3e0415c750 100644 --- a/spec/controllers/api/v1/handlebar_types_controller_spec.rb +++ b/spec/controllers/api/v1/handlebar_types_controller_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::HandlebarTypesController do - describe 'index' do - it 'loads the page' do + describe "index" do + it "loads the page" do get :index, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end end diff --git a/spec/controllers/api/v1/notifications_controller_spec.rb b/spec/controllers/api/v1/notifications_controller_spec.rb index f9b58bfd29..908139a466 100644 --- a/spec/controllers/api/v1/notifications_controller_spec.rb +++ b/spec/controllers/api/v1/notifications_controller_spec.rb @@ -1,72 +1,71 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::NotificationsController do - describe 'send_notification_email' do - it 'returns correct code if authentication fails' do + describe "send_notification_email" do + it "returns correct code if authentication fails" do bike = FactoryBot.create(:bike) - options = { some_stuff: 'things', - other_stuff: 'Things', - bike_id: bike.id - } + options = { some_stuff: "things", + other_stuff: "Things", + bike_id: bike.id } post :create, options - expect(response.code).to eq('401') + expect(response.code).to eq("401") end - it 'sends an email if the authorization works' do + it "sends an email if the authorization works" do expect(CustomerContact.count).to eq(0) stolen_record = FactoryBot.create(:stolen_record) options = { - access_token: ENV['NOTIFICATIONS_API_KEY'], + access_token: ENV["NOTIFICATIONS_API_KEY"], notification_hash: { - notification_type: 'stolen_twitter_alerter', + notification_type: "stolen_twitter_alerter", bike_id: stolen_record.bike.id, tweet_id: 69, - tweet_string: 'STOLEN - something special', - tweet_account_screen_name: 'bikeindex', - tweet_account_name: 'Bike Index', - tweet_account_image: 'https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png', - retweet_screen_names: [] - } + tweet_string: "STOLEN - something special", + tweet_account_screen_name: "bikeindex", + tweet_account_name: "Bike Index", + tweet_account_image: "https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png", + retweet_screen_names: [], + }, } expect do post :create, options, format: :json end.to change(EmailStolenBikeAlertWorker.jobs, :size).by(1) - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(CustomerContact.count).to eq(1) customer_contact = CustomerContact.first expect(customer_contact.info_hash[:bike_id].to_i).to eq(stolen_record.bike.id) - expect(customer_contact.info_hash[:tweet_string]).to eq('STOLEN - something special') - expect(customer_contact.info_hash[:notification_type]).to eq('stolen_twitter_alerter') + expect(customer_contact.info_hash[:tweet_string]).to eq("STOLEN - something special") + expect(customer_contact.info_hash[:notification_type]).to eq("stolen_twitter_alerter") end - it 'sends a recovered email if the authorization works' do + it "sends a recovered email if the authorization works" do expect(CustomerContact.count).to eq(0) stolen_record = FactoryBot.create(:stolen_record) bike = stolen_record.bike bike.update_attribute :recovered, true options = { - access_token: ENV['NOTIFICATIONS_API_KEY'], + access_token: ENV["NOTIFICATIONS_API_KEY"], notification_hash: { - notification_type: 'stolen_twitter_alerter', + notification_type: "stolen_twitter_alerter", bike_id: stolen_record.bike.id, tweet_id: 69, - tweet_string: 'FOUND - something special', - tweet_account_screen_name: 'bikeindex', - tweet_account_name: 'Bike Index', - tweet_account_image: 'https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png', - retweet_screen_names: [] - } + tweet_string: "FOUND - something special", + tweet_account_screen_name: "bikeindex", + tweet_account_name: "Bike Index", + tweet_account_image: "https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png", + retweet_screen_names: [], + }, } expect do post :create, options, format: :json end.to change(EmailStolenBikeAlertWorker.jobs, :size).by(1) - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(CustomerContact.count).to eq(1) customer_contact = CustomerContact.first expect(customer_contact.info_hash[:bike_id].to_i).to eq(stolen_record.bike.id) - expect(customer_contact.info_hash[:tweet_string]).to eq('FOUND - something special') - expect(customer_contact.title).to eq('We tweeted about the bike you recovered!') - expect(customer_contact.info_hash[:notification_type]).to eq('stolen_twitter_alerter') + expect(customer_contact.info_hash[:tweet_string]).to eq("FOUND - something special") + expect(customer_contact.title).to eq("We tweeted about the bike you recovered!") + expect(customer_contact.info_hash[:notification_type]).to eq("stolen_twitter_alerter") end end end diff --git a/spec/controllers/api/v1/organizations_controller_spec.rb b/spec/controllers/api/v1/organizations_controller_spec.rb index 352a7054c2..32abd27164 100644 --- a/spec/controllers/api/v1/organizations_controller_spec.rb +++ b/spec/controllers/api/v1/organizations_controller_spec.rb @@ -1,35 +1,35 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::OrganizationsController do - describe 'show' do - it 'returns unauthorized unless organizations api token present' do + describe "show" do + it "returns unauthorized unless organizations api token present" do organization = FactoryBot.create(:organization) get :show, id: organization.slug, format: :json - expect(response.code).to eq('401') + expect(response.code).to eq("401") end - it 'returns the organization info if the token is present' do + it "returns the organization info if the token is present" do organization = FactoryBot.create(:organization) - options = { id: organization.slug, access_token: ENV['ORGANIZATIONS_API_ACCESS_TOKEN'] } + options = { id: organization.slug, access_token: ENV["ORGANIZATIONS_API_ACCESS_TOKEN"] } get :show, options, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") result = JSON.parse(response.body) - expect(result['name']).to eq(organization.name) - expect(result['can_add_bikes']).to be_falsey + expect(result["name"]).to eq(organization.name) + expect(result["can_add_bikes"]).to be_falsey end - it 'returns the organization info if the org token is present' do + it "returns the organization info if the org token is present" do organization = FactoryBot.create(:organization) options = { id: organization.slug, access_token: organization.access_token } get :show, options, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") result = JSON.parse(response.body) - expect(result['name']).to eq(organization.name) - expect(result['can_add_bikes']).to be_falsey + expect(result["name"]).to eq(organization.name) + expect(result["can_add_bikes"]).to be_falsey end it "404s if the organization doesn't exist" do - body = { id: 'fake_organization_slug', access_token: ENV['ORGANIZATIONS_API_ACCESS_TOKEN'] } + body = { id: "fake_organization_slug", access_token: ENV["ORGANIZATIONS_API_ACCESS_TOKEN"] } get :show, body, format: :json expect(response).to redirect_to(api_v1_not_found_url) end diff --git a/spec/controllers/api/v1/stolen_locking_response_suggestions_controller_spec.rb b/spec/controllers/api/v1/stolen_locking_response_suggestions_controller_spec.rb index e82fca3b45..24ff81804f 100644 --- a/spec/controllers/api/v1/stolen_locking_response_suggestions_controller_spec.rb +++ b/spec/controllers/api/v1/stolen_locking_response_suggestions_controller_spec.rb @@ -1,14 +1,14 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::StolenLockingResponseSuggestionsController do - describe 'index' do - it 'loads the page' do + describe "index" do + it "loads the page" do get :index, format: :json # pp response.body - expect(response.code).to eq('200') + expect(response.code).to eq("200") result = JSON.parse(response.body) - expect(result['locking_defeat_descriptions'].count).to eq(6) - expect(result['locking_descriptions'].count).to eq(8) + expect(result["locking_defeat_descriptions"].count).to eq(6) + expect(result["locking_descriptions"].count).to eq(8) end end end diff --git a/spec/controllers/api/v1/users_controller_spec.rb b/spec/controllers/api/v1/users_controller_spec.rb index 52efa3f9c5..0c01d18170 100644 --- a/spec/controllers/api/v1/users_controller_spec.rb +++ b/spec/controllers/api/v1/users_controller_spec.rb @@ -1,30 +1,30 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::UsersController do - describe 'current' do - it 'returns user_present = false if there is no user present' do + describe "current" do + it "returns user_present = false if there is no user present" do get :current, format: :json - expect(response.code).to eq('200') - expect(response.headers['Access-Control-Allow-Origin']).not_to be_present - expect(response.headers['Access-Control-Request-Method']).not_to be_present + expect(response.code).to eq("200") + expect(response.headers["Access-Control-Allow-Origin"]).not_to be_present + expect(response.headers["Access-Control-Request-Method"]).not_to be_present end - it 'returns user_present if a user is present' do + it "returns user_present if a user is present" do # We need to test that cors isn't present u = FactoryBot.create(:user_confirmed) set_current_user(u) get :current, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") result = JSON.parse(response.body) - expect(result).to include('user_present' => true) - expect(result['email']).to_not be_present - expect(response.headers['Access-Control-Allow-Origin']).not_to be_present - expect(response.headers['Access-Control-Request-Method']).not_to be_present + expect(result).to include("user_present" => true) + expect(result["email"]).to_not be_present + expect(response.headers["Access-Control-Allow-Origin"]).not_to be_present + expect(response.headers["Access-Control-Request-Method"]).not_to be_present end end - describe 'send_request' do - it 'actuallies send the mail' do + describe "send_request" do + it "actuallies send the mail" do Sidekiq::Testing.inline! do # We don't test that this is being added to Sidekiq # Because we're testing that sidekiq does what it @@ -33,82 +33,82 @@ user = o.creator bike = o.bike delete_request = { - request_type: 'bike_delete_request', + request_type: "bike_delete_request", user_id: user.id, request_bike_id: bike.id, - request_reason: 'Some reason' + request_reason: "Some reason", } set_current_user(user) ActionMailer::Base.deliveries = [] post :send_request, delete_request - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(ActionMailer::Base.deliveries).not_to be_empty end end - context 'manufacturer_update_manufacturer present' do - it 'updates the manufacturer' do + context "manufacturer_update_manufacturer present" do + it "updates the manufacturer" do o = FactoryBot.create(:ownership) manufacturer = FactoryBot.create(:manufacturer) user = o.creator bike = o.bike update_manufacturer_request = { - request_type: 'manufacturer_update_manufacturer', + request_type: "manufacturer_update_manufacturer", user_id: user.id, request_bike_id: bike.id, - request_reason: 'Need to update manufacturer', - manufacturer_update_manufacturer: manufacturer.slug + request_reason: "Need to update manufacturer", + manufacturer_update_manufacturer: manufacturer.slug, } set_current_user(user) post :send_request, update_manufacturer_request - expect(response.code).to eq('200') + expect(response.code).to eq("200") bike.reload expect(bike.manufacturer).to eq manufacturer end end - context 'manufacturer_update_manufacturer present' do - it 'does not make nil manufacturer' do + context "manufacturer_update_manufacturer present" do + it "does not make nil manufacturer" do o = FactoryBot.create(:ownership) user = o.creator bike = o.bike update_manufacturer_request = { - request_type: 'manufacturer_update_manufacturer', + request_type: "manufacturer_update_manufacturer", user_id: user.id, request_bike_id: bike.id, - request_reason: 'Need to update manufacturer', - manufacturer_update_manufacturer: 'doadsfizxcv' + request_reason: "Need to update manufacturer", + manufacturer_update_manufacturer: "doadsfizxcv", } set_current_user(user) post :send_request, update_manufacturer_request - expect(response.code).to eq('200') + expect(response.code).to eq("200") bike.reload expect(bike.manufacturer).to be_present end end - context 'serial request mail' do + context "serial request mail" do it "doesn't create a new serial request mail" do o = FactoryBot.create(:ownership) user = o.creator bike = o.bike serial_request = { - request_type: 'serial_update_request', + request_type: "serial_update_request", user_id: user.id, request_bike_id: bike.id, - request_reason: 'Some reason', - serial_update_serial: 'some new serial' + request_reason: "Some reason", + serial_update_serial: "some new serial", } set_current_user(user) expect_any_instance_of(SerialNormalizer).to receive(:save_segments) expect do post :send_request, serial_request end.to change(EmailFeedbackNotificationWorker.jobs, :size).by(0) - expect(response.code).to eq('200') - expect(bike.reload.serial_number).to eq('some new serial') + expect(response.code).to eq("200") + expect(bike.reload.serial_number).to eq("some new serial") end end - it 'it untsvs a bike' do + it "it untsvs a bike" do t = Time.now - 1.minute stolen_record = FactoryBot.create(:stolen_record, tsved_at: t) o = FactoryBot.create(:ownership, bike: stolen_record.bike) @@ -116,36 +116,36 @@ bike = o.bike bike.update_attribute :current_stolen_record_id, bike.find_current_stolen_record.id serial_request = { - request_type: 'serial_update_request', + request_type: "serial_update_request", user_id: user.id, request_bike_id: bike.id, - request_reason: 'Some reason', - serial_update_serial: 'some new serial' + request_reason: "Some reason", + serial_update_serial: "some new serial", } set_current_user(user) expect_any_instance_of(SerialNormalizer).to receive(:save_segments) post :send_request, serial_request - expect(response.code).to eq('200') + expect(response.code).to eq("200") bike.reload - expect(bike.serial_number).to eq('some new serial') + expect(bike.serial_number).to eq("some new serial") stolen_record.reload expect(stolen_record.tsved_at).to be_nil end - describe 'recovery' do + describe "recovery" do let(:bike) { FactoryBot.create(:stolen_bike) } let(:stolen_record) { bike.current_stolen_record } let(:ownership) { FactoryBot.create(:ownership, bike: bike) } let(:user) { ownership.creator } let(:recovery_request) do { - request_type: 'bike_recovery', + request_type: "bike_recovery", user_id: user.id, request_bike_id: bike.id, - request_reason: 'Some reason', - index_helped_recovery: 'true', - can_share_recovery: 'true', - mark_recovered_stolen_record_id: stolen_record.id + request_reason: "Some reason", + index_helped_recovery: "true", + can_share_recovery: "true", + mark_recovered_stolen_record_id: stolen_record.id, } end @@ -154,9 +154,9 @@ set_current_user(user) end - it 'recovers the bike' do + it "recovers the bike" do post :send_request, recovery_request.as_json - expect(response.code).to eq('200') + expect(response.code).to eq("200") bike.reload stolen_record.reload feedback = Feedback.last @@ -164,7 +164,7 @@ expect(bike.stolen).to be_falsey expect(feedback.body).to eq recovery_request[:request_reason] expect(feedback.feedback_hash).to eq recovery_request - .slice(:index_helped_recovery, :can_share_recovery).merge(bike_id: bike.id.to_s) + .slice(:index_helped_recovery, :can_share_recovery).merge(bike_id: bike.id.to_s) expect(stolen_record.current).to be_falsey expect(stolen_record.bike).to eq(bike) expect(stolen_record.recovered?).to be_truthy @@ -178,21 +178,21 @@ it "does not create a new serial request mailer if a user isn't present" do bike = FactoryBot.create(:bike) - message = { request_bike_id: bike.id, serial_update_serial: 'some update', request_reason: 'Some reason' } + message = { request_bike_id: bike.id, serial_update_serial: "some update", request_reason: "Some reason" } # pp message post :send_request, message, format: :json - expect(response.code).to eq('403') + expect(response.code).to eq("403") end - it 'does not create a new serial request mailer if wrong user user is present' do + it "does not create a new serial request mailer if wrong user user is present" do o = FactoryBot.create(:ownership) bike = o.bike user = FactoryBot.create(:user_confirmed) set_current_user(user) - params = { request_bike_id: bike.id, serial_update_serial: 'some update', request_reason: 'Some reason' } + params = { request_bike_id: bike.id, serial_update_serial: "some update", request_reason: "Some reason" } post :send_request, params # pp response - expect(response.code).to eq('403') + expect(response.code).to eq("403") end end end diff --git a/spec/controllers/api/v1/wheel_sizes_controller_spec.rb b/spec/controllers/api/v1/wheel_sizes_controller_spec.rb index 1833b0362a..46b0d04d65 100644 --- a/spec/controllers/api/v1/wheel_sizes_controller_spec.rb +++ b/spec/controllers/api/v1/wheel_sizes_controller_spec.rb @@ -1,11 +1,11 @@ -require 'spec_helper' +require "spec_helper" describe Api::V1::WheelSizesController do - describe 'index' do - it 'loads the request' do + describe "index" do + it "loads the request" do FactoryBot.create(:wheel_size) get :index, format: :json - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end end diff --git a/spec/controllers/bikes/recovery_controller_spec.rb b/spec/controllers/bikes/recovery_controller_spec.rb index 6c1c7684c3..1a936d5416 100644 --- a/spec/controllers/bikes/recovery_controller_spec.rb +++ b/spec/controllers/bikes/recovery_controller_spec.rb @@ -1,29 +1,29 @@ -require 'spec_helper' +require "spec_helper" describe Bikes::RecoveryController, type: :controller do let(:bike) { FactoryBot.create(:stolen_bike) } let(:stolen_record) { bike.current_stolen_record } let(:recovery_link_token) { stolen_record.find_or_create_recovery_link_token } - describe 'edit' do - context 'nonmatching recovery token' do - it 'renders' do - get :edit, bike_id: bike.id, token: 'XXXXXXXX' + describe "edit" do + context "nonmatching recovery token" do + it "renders" do + get :edit, bike_id: bike.id, token: "XXXXXXXX" expect(response).to redirect_to bike_url(bike) expect(flash[:error]).to be_present expect(session[:recovery_link_token]).to be_blank end end - context 'matching recovery token' do - it 'renders' do + context "matching recovery token" do + it "renders" do get :edit, bike_id: bike.id, token: recovery_link_token expect(response).to redirect_to bike_path(bike) expect(session[:recovery_link_token]).to eq recovery_link_token end end - context 'already recovered bike' do + context "already recovered bike" do before { stolen_record.add_recovery_information } - it 'redirects' do + it "redirects" do bike.reload expect(bike.stolen).to be_falsey get :edit, bike_id: bike.id, token: recovery_link_token @@ -34,18 +34,18 @@ end end - describe 'update' do + describe "update" do let(:recovery_info) do { date_recovered: "2018-07-28T18:57:13.277", timezone: "America/Monterrey", - recovered_description: 'Some sweet description', - index_helped_recovery: '0', - can_share_recovery: '1' + recovered_description: "Some sweet description", + index_helped_recovery: "0", + can_share_recovery: "1", } end - context 'matching recovery token' do - it 'updates' do + context "matching recovery token" do + it "updates" do expect do put :update, bike_id: bike.id, token: recovery_link_token, stolen_record: recovery_info @@ -63,10 +63,10 @@ expect(stolen_record.reload.date_recovered.to_i).to be_within(1).of 1532822233 end end - context 'non-matching recovery token' do - it 'does not update' do + context "non-matching recovery token" do + it "does not update" do expect do - put :update, bike_id: bike.id, token: 'XDSFCVVVVVVVVVSD888', + put :update, bike_id: bike.id, token: "XDSFCVVVVVVVVVSD888", stolen_record: recovery_info end.to change(EmailRecoveredFromLinkWorker.jobs, :size).by(0) stolen_record.reload diff --git a/spec/controllers/bikes_controller_spec.rb b/spec/controllers/bikes_controller_spec.rb index 2510461017..1cef1d7362 100644 --- a/spec/controllers/bikes_controller_spec.rb +++ b/spec/controllers/bikes_controller_spec.rb @@ -1,42 +1,42 @@ -require 'spec_helper' +require "spec_helper" describe BikesController do - describe 'index' do + describe "index" do include_context :geocoder_default_location - let!(:non_stolen_bike) { FactoryBot.create(:bike, serial_number: '1234567890') } + let!(:non_stolen_bike) { FactoryBot.create(:bike, serial_number: "1234567890") } let!(:stolen_bike) { FactoryBot.create(:stolen_bike, latitude: default_location[:latitude], longitude: default_location[:longitude]) } - let(:serial) { '1234567890' } + let(:serial) { "1234567890" } let!(:stolen_bike_2) { FactoryBot.create(:stolen_bike, latitude: 41.8961603, longitude: -87.677215) } - let(:ip_address) { '127.0.0.1' } - let(:target_location) { ['New York', 'NY', 'US'] } + let(:ip_address) { "127.0.0.1" } + let(:target_location) { ["New York", "NY", "US"] } let(:target_interpreted_params) { Bike.searchable_interpreted_params(query_params, ip: ip_address) } - context 'with subdomain' do - it 'redirects to no subdomain' do - @request.host = 'stolen.example.com' + context "with subdomain" do + it "redirects to no subdomain" do + @request.host = "stolen.example.com" get :index expect(response).to redirect_to bikes_url(subdomain: false) end end - describe 'assignment' do - context 'no params' do - it 'assigns defaults, stolenness: stolen' do + describe "assignment" do + context "no params" do + it "assigns defaults, stolenness: stolen" do get :index expect(response.status).to eq 200 expect(response).to render_template(:index) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(flash).to_not be_present - expect(assigns(:interpreted_params)).to eq(stolenness: 'stolen') + expect(assigns(:interpreted_params)).to eq(stolenness: "stolen") expect(assigns(:selected_query_items_options)).to eq([]) expect(assigns(:bikes).map(&:id)).to match_array([stolen_bike.id, stolen_bike_2.id]) - expect(assigns(:page_id)).to eq 'bikes_index' + expect(assigns(:page_id)).to eq "bikes_index" end end - context 'query_items and serial search' do + context "query_items and serial search" do let(:manufacturer) { non_stolen_bike.manufacturer } let(:color) { non_stolen_bike.primary_frame_color } - let(:query_params) { { serial: "#{serial}0d", query_items: [color.search_id, manufacturer.search_id], stolenness: 'non' } } + let(:query_params) { { serial: "#{serial}0d", query_items: [color.search_id, manufacturer.search_id], stolenness: "non" } } let(:target_selected_query_items_options) { Bike.selected_query_items_options(target_interpreted_params) } - it 'assigns passed parameters, assigns close_serials' do + it "assigns passed parameters, assigns close_serials" do get :index, query_params expect(response.status).to eq 200 expect(assigns(:interpreted_params)).to eq target_interpreted_params @@ -45,10 +45,10 @@ expect(assigns(:close_serials).map(&:id)).to eq([non_stolen_bike.id]) end end - context 'ip proximity' do - let(:query_params) { { location: 'yoU', distance: 1, stolenness: 'proximity' } } - context 'found location' do - it 'assigns passed parameters and close_serials' do + context "ip proximity" do + let(:query_params) { { location: "yoU", distance: 1, stolenness: "proximity" } } + context "found location" do + it "assigns passed parameters and close_serials" do expect_any_instance_of(BikesController).to receive(:forwarded_ip_address) { ip_address } allow(Geocoder).to receive(:search) { legacy_production_ip_search_result } get :index, query_params @@ -57,9 +57,9 @@ expect(assigns(:bikes).map(&:id)).to eq([stolen_bike.id]) end end - context 'ip passed as parameter' do - let(:ip_query_params) { query_params.merge(location: 'IP') } - it 'assigns passed parameters and close_serials' do + context "ip passed as parameter" do + let(:ip_query_params) { query_params.merge(location: "IP") } + it "assigns passed parameters and close_serials" do expect_any_instance_of(BikesController).to receive(:forwarded_ip_address) { ip_address } allow(Geocoder).to receive(:search) { production_ip_search_result } get :index, ip_query_params @@ -68,9 +68,9 @@ expect(assigns(:bikes).map(&:id)).to eq([stolen_bike.id]) end end - context 'no location' do - let(:ip_query_params) { query_params.merge(location: ' ') } - it 'assigns passed parameters and close_serials' do + context "no location" do + let(:ip_query_params) { query_params.merge(location: " ") } + it "assigns passed parameters and close_serials" do expect_any_instance_of(BikesController).to receive(:forwarded_ip_address) { ip_address } allow(Geocoder).to receive(:search) { production_ip_search_result } get :index, ip_query_params @@ -79,33 +79,33 @@ expect(assigns(:bikes).map(&:id)).to eq([stolen_bike.id]) end end - context 'unknown location' do + context "unknown location" do let(:bounding_box) { [66.00, -84.22, 67.000, (0.0 / 0)] } # Override bounding box stub in geocoder_default_location - it 'includes a flash[:info] for unknown location, renders non-proximity' do + it "includes a flash[:info] for unknown location, renders non-proximity" do get :index, query_params expect(response.status).to eq 200 expect(flash[:info]).to match(/location/) - expect(query_params[:stolenness]).to eq 'proximity' - expect(assigns(:interpreted_params)[:stolenness]).to eq 'stolen' + expect(query_params[:stolenness]).to eq "proximity" + expect(assigns(:interpreted_params)[:stolenness]).to eq "stolen" end end end - context 'passed all permitted params' do + context "passed all permitted params" do let(:query_params) do { - query: '1', - manufacturer: '2', + query: "1", + manufacturer: "2", colors: %w[3 4], - location: '5', - distance: '6', - serial: '9', + location: "5", + distance: "6", + serial: "9", query_items: %w[7 8], - stolenness: 'all' + stolenness: "all", }.as_json end - it 'sends all the params we want to searchable_interpreted_params' do - expect_any_instance_of(BikesController).to receive(:forwarded_ip_address) { 'special' } - expect(Bike).to receive(:searchable_interpreted_params).with(query_params, ip: 'special') { {} } + it "sends all the params we want to searchable_interpreted_params" do + expect_any_instance_of(BikesController).to receive(:forwarded_ip_address) { "special" } + expect(Bike).to receive(:searchable_interpreted_params).with(query_params, ip: "special") { {} } get :index, query_params expect(response.status).to eq 200 end @@ -113,7 +113,7 @@ end end - describe 'show' do + describe "show" do let(:ownership) { FactoryBot.create(:ownership) } let(:user) { ownership.creator } let(:bike) { ownership.bike } @@ -148,9 +148,9 @@ expect(assigns(:bike)).to be_decorated end end - context 'hidden bikes' do - context 'admin hidden (fake delete)' do - it 'redirects and sets the flash' do + context "hidden bikes" do + context "admin hidden (fake delete)" do + it "redirects and sets the flash" do ownership.bike.update_attributes(hidden: true) get :show, id: bike.id expect(response).to redirect_to(:root) @@ -226,26 +226,26 @@ end end end - context 'too large of integer bike_id' do - it 'responds with not found' do + context "too large of integer bike_id" do + it "responds with not found" do expect do get :show, id: 57549641769762268311552 end.to raise_error(ActiveRecord::RecordNotFound) end end - context 'qr code gif' do - it 'renders' do + context "qr code gif" do + it "renders" do get :show, id: bike.id, format: :gif expect(response.status).to eq(200) end end end - describe 'spokecard' do - it 'renders the page from bike id' do + describe "spokecard" do + it "renders the page from bike id" do bike = FactoryBot.create(:bike) get :spokecard, id: bike.id - expect(response.code).to eq('200') + expect(response.code).to eq("200") end end @@ -307,40 +307,40 @@ end end - describe 'new' do - context 'not signed in' do - it 'sets redirect_to' do - get :new, stolen: true, b_param_token: 'cool-token-thing' + describe "new" do + context "not signed in" do + it "sets redirect_to" do + get :new, stolen: true, b_param_token: "cool-token-thing" expect(response).to redirect_to new_user_url # expect(Rack::Utils.parse_query(session[:discourse_redirect])).to eq(discourse_params) expect(flash[:info]).to be_present - expect(session[:return_to]).to eq new_bike_path(stolen: true, b_param_token: 'cool-token-thing') + expect(session[:return_to]).to eq new_bike_path(stolen: true, b_param_token: "cool-token-thing") end end - context 'signed in' do + context "signed in" do include_context :logged_in_as_user let(:manufacturer) { FactoryBot.create(:manufacturer) } let(:color) { FactoryBot.create(:color) } let(:organization) { FactoryBot.create(:organization) } - context 'passed stolen param' do - it 'renders a new stolen bike' do + context "passed stolen param" do + it "renders a new stolen bike" do get :new, stolen: true - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(assigns(:bike).stolen).to be_truthy end end - context 'passed recovered param' do - it 'renders a new recovered bike' do + context "passed recovered param" do + it "renders a new recovered bike" do get :new, recovered: true - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(assigns(:bike).recovered).to be_truthy end end context "with organization id" do it "renders and assigns creation organization" do get :new, organization_id: organization.to_param - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(assigns(:bike).creation_organization).to eq organization expect(assigns[:current_organization]).to be_nil # Because the user isn't necessarily a member of an org end @@ -349,47 +349,47 @@ let(:user) { FactoryBot.create(:organization_member, organization: organization) } it "renders and assigns creation_organization" do get :new - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(assigns(:bike).creation_organization).to eq organization expect(assigns[:current_organization]).to eq organization end end - context 'stolen from params' do - it 'renders a new stolen bike' do + context "stolen from params" do + it "renders a new stolen bike" do get :new, stolen: true - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(assigns(:bike).stolen).to be_truthy b_param = assigns(:b_param) expect(b_param.revised_new?).to be_truthy expect(response).to render_template(:new) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - context 'bike through b_param' do + context "bike through b_param" do let(:bike_attrs) do { manufacturer_id: manufacturer.id, primary_frame_color_id: color.id, - owner_email: 'something@stuff.com' + owner_email: "something@stuff.com", } end - context 'valid b_param' do - it 'renders the bike from b_param' do - b_param = BParam.create(params: { bike: bike_attrs.merge('revised_new' => true) }) + context "valid b_param" do + it "renders the bike from b_param" do + b_param = BParam.create(params: { bike: bike_attrs.merge("revised_new" => true) }) expect(b_param.id_token).to be_present get :new, b_param_token: b_param.id_token bike = assigns(:bike) expect(assigns(:b_param)).to eq b_param expect(bike.is_a?(Bike)).to be_truthy bike_attrs.each { |k, v| expect(bike.send(k)).to eq(v) } - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - context 'partial registration by organization' do + context "partial registration by organization" do let(:organization) { FactoryBot.create(:organization_with_auto_user) } let(:organized_bike_attrs) { bike_attrs.merge(creation_organization_id: organization.id) } - it 'renders for the user (even though a different creator)' do - b_param = BParam.create(params: { bike: organized_bike_attrs.merge('revised_new' => true) }) + it "renders for the user (even though a different creator)" do + b_param = BParam.create(params: { bike: organized_bike_attrs.merge("revised_new" => true) }) expect(b_param.id_token).to be_present get :new, b_param_token: b_param.id_token bike = assigns(:bike) @@ -399,19 +399,19 @@ pp k unless bike.send(k) == v expect(bike.send(k)).to eq(v) end - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:organization)).to eq organization end end - context 'invalid b_param' do - it 'renders a new bike, has a flash message' do + context "invalid b_param" do + it "renders a new bike, has a flash message" do b_param = BParam.create(creator_id: FactoryBot.create(:user).id) expect(b_param.id_token).to be_present get :new, b_param_token: b_param.id_token bike = assigns(:bike) expect(bike.is_a?(Bike)).to be_truthy expect(assigns(:b_param)).to_not eq b_param - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(flash[:info]).to match(/couldn.t find/i) end end @@ -428,7 +428,7 @@ end end - describe 'create' do + describe "create" do # This is the create action for bikes controller let(:manufacturer) { FactoryBot.create(:manufacturer) } let(:color) { FactoryBot.create(:color) } @@ -442,32 +442,32 @@ street: "2459 W Division St", city: "Chicago", zipcode: "60622", - state_id: state.id + state_id: state.id, } end - describe 'embeded' do + describe "embeded" do let(:organization) { FactoryBot.create(:organization_with_auto_user) } let(:user) { organization.auto_user } let(:b_param) { BParam.create(creator_id: organization.auto_user.id, params: { creation_organization_id: organization.id, embeded: true }) } let(:bike_params) do { - serial_number: '69', + serial_number: "69", b_param_id_token: b_param.id_token, creation_organization_id: organization.id, embeded: true, - additional_registration: 'Testly secondary', + additional_registration: "Testly secondary", cycle_type_slug: " Tricycle ", manufacturer_id: manufacturer.id, - manufacturer_other: '', + manufacturer_other: "", primary_frame_color_id: color.id, handlebar_type: handlebar_type, - owner_email: 'flow@goodtimes.com' + owner_email: "flow@goodtimes.com", } end let(:testable_bike_params) { bike_params.except(:b_param_id_token, :embeded, :cycle_type_slug) } - context 'non-stolen' do - it 'creates a new ownership and bike from an organization' do + context "non-stolen" do + it "creates a new ownership and bike from an organization" do expect(user).to be_present expect do post :create, bike: bike_params @@ -483,13 +483,13 @@ end end end - context 'stolen' do + context "stolen" do let(:target_time) { Time.now.to_i } let(:stolen_params) { chicago_stolen_params.merge(date_stolen: (Time.now - 1.day).utc, timezone: "UTC") } - context 'valid' do + context "valid" do include_context :geocoder_real - context 'with old style date input' do - it 'creates a new ownership and bike from an organization' do + context "with old style date input" do + it "creates a new ownership and bike from an organization" do VCR.use_cassette("bikes_controller-create-stolen-chicago", match_requests_on: [:path]) do expect do post :create, bike: bike_params.merge(stolen: true), stolen_record: stolen_params @@ -497,7 +497,7 @@ end.to change(Ownership, :count).by 1 bike = Bike.last expect(bike).to be_present - expect(bike.creation_state.origin).to eq 'embed' + expect(bike.creation_state.origin).to eq "embed" expect(bike.creation_state.organization).to eq organization expect(bike.creation_state.creator).to eq bike.creator testable_bike_params.each { |k, v| expect(bike.send(k).to_s).to eq v.to_s } @@ -508,17 +508,17 @@ end end end - context 'new date input' do + context "new date input" do let(:alt_stolen_params) { stolen_params.merge(date_stolen: "2018-07-28T23:34:00", timezone: "America/New_York") } let(:target_time) { 1532835240 } - it 'creates a new ownership and bike from an organization' do + it "creates a new ownership and bike from an organization" do VCR.use_cassette("bikes_controller-create-stolen-chicago", match_requests_on: [:path]) do expect do post :create, bike: bike_params.merge(stolen: true), stolen_record: alt_stolen_params end.to change(Ownership, :count).by 1 bike = Bike.last expect(bike).to be_present - expect(bike.creation_state.origin).to eq 'embed' + expect(bike.creation_state.origin).to eq "embed" expect(bike.creation_state.organization).to eq organization expect(bike.creation_state.creator).to eq bike.creator testable_bike_params.each { |k, v| expect(bike.send(k).to_s).to eq v.to_s } @@ -529,11 +529,11 @@ end end end - context 'invalid' do - it 'renders the stolen form with all the attributes' do + context "invalid" do + it "renders the stolen form with all the attributes" do target_path = embed_organization_path(id: organization.slug, b_param_id_token: b_param.id_token) expect do - post :create, bike: bike_params.merge(stolen: '1', primary_frame_color: nil), + post :create, bike: bike_params.merge(stolen: "1", primary_frame_color: nil), stolen_record: stolen_params expect(assigns(:bike).errors&.full_messages).to be_present end.to change(Ownership, :count).by 0 @@ -549,39 +549,39 @@ end end - describe 'extended embeded submission' do + describe "extended embeded submission" do let(:organization) { FactoryBot.create(:organization_with_auto_user) } let(:bike_params) do { - serial_number: '69', + serial_number: "69", b_param_id_token: b_param.id_token, creation_organization_id: organization.id, embeded: true, embeded_extended: true, - cycle_type: 'pedi-cab', + cycle_type: "pedi-cab", manufacturer_id: manufacturer.slug, primary_frame_color_id: color.id, handlebar_type: handlebar_type, - owner_email: 'Flow@goodtimes.com' + owner_email: "Flow@goodtimes.com", } end let(:b_param) { BParam.create(creator_id: organization.auto_user.id, params: { creation_organization_id: organization.id, embeded: true }) } before do expect(b_param).to be_present end - context 'with an image' do - it 'registers a bike and uploads an image' do + context "with an image" do + it "registers a bike and uploads an image" do Sidekiq::Testing.inline! do - test_photo = Rack::Test::UploadedFile.new(File.open(File.join(Rails.root, 'spec', 'fixtures', 'bike.jpg'))) + test_photo = Rack::Test::UploadedFile.new(File.open(File.join(Rails.root, "spec", "fixtures", "bike.jpg"))) expect_any_instance_of(ImageAssociatorWorker).to receive(:perform).and_return(true) post :create, bike: bike_params.merge(image: test_photo) expect(response).to redirect_to(embed_extended_organization_url(organization)) bike = Bike.last expect(bike.owner_email).to eq bike_params[:owner_email].downcase - expect(bike.creation_state.origin).to eq 'embed_extended' + expect(bike.creation_state.origin).to eq "embed_extended" expect(bike.creation_state.organization).to eq organization expect(bike.creation_state.creator).to eq bike.creator - expect(bike.cycle_type_name).to eq 'Pedi Cab (rickshaw)' + expect(bike.cycle_type_name).to eq "Pedi Cab (rickshaw)" expect(bike.manufacturer).to eq manufacturer end end @@ -629,25 +629,25 @@ end end - context 'standard web form submission' do + context "standard web form submission" do include_context :logged_in_as_user - context 'legacy b_param' do + context "legacy b_param" do let(:bike_params) do { - serial_number: '1234567890', + serial_number: "1234567890", b_param_id_token: b_param.id_token, - cycle_type: 'stroller', + cycle_type: "stroller", manufacturer_id: manufacturer.name, - rear_tire_narrow: 'true', + rear_tire_narrow: "true", rear_wheel_size_id: FactoryBot.create(:wheel_size).id, primary_frame_color_id: color.id, handlebar_type: handlebar_type, - owner_email: user.email + owner_email: user.email, } end - context 'b_param not owned by user' do + context "b_param not owned by user" do let(:other_user) { FactoryBot.create(:user) } let(:b_param) { FactoryBot.create(:b_param, creator: other_user) } it "does not use the b_param if isn't owned by user" do @@ -657,22 +657,22 @@ end end - context 'stolen b_param from user' do + context "stolen b_param from user" do let(:b_param) { FactoryBot.create(:b_param, creator: user) } - it 'creates a new stolen bike and assigns the user phone' do - FactoryBot.create(:country, iso: 'US') + it "creates a new stolen bike and assigns the user phone" do + FactoryBot.create(:country, iso: "US") expect do - post :create, stolen: 'true', bike: bike_params.merge(phone: '312.379.9513') + post :create, stolen: "true", bike: bike_params.merge(phone: "312.379.9513") end.to change(StolenRecord, :count).by(1) expect(b_param.reload.created_bike_id).not_to be_nil expect(b_param.reload.bike_errors).to be_nil - expect(user.reload.phone).to eq('3123799513') + expect(user.reload.phone).to eq("3123799513") end end - context 'organization b_param' do + context "organization b_param" do let(:organization) { FactoryBot.create(:organization_with_auto_user) } let(:b_param) { FactoryBot.create(:b_param, creator: organization.auto_user) } - it 'creates a new ownership and bike from an organization' do + it "creates a new ownership and bike from an organization" do expect do post :create, bike: bike_params.merge(creation_organization_id: organization.id) end.to change(Ownership, :count).by(1) @@ -698,7 +698,7 @@ tertiary_frame_color_id: "", owner_email: "something@stuff.com", phone: "312.379.9513", - stolen: true + stolen: true, } end before { expect(BParam.all.count).to eq 0 } @@ -731,8 +731,8 @@ end end end - context 'failure' do - it 'assigns a bike and a stolen record with the attrs passed' do + context "failure" do + it "assigns a bike and a stolen record with the attrs passed" do expect do post :create, stolen: true, bike: bike_params.as_json, stolen_record: chicago_stolen_params end.to change(Bike, :count).by(0) @@ -750,24 +750,24 @@ end end end - context 'existing b_param' do - context 'no bike' do + context "existing b_param" do + context "no bike" do let(:bike_params) do { - cycle_type: 'cargo-rear', - serial_number: 'example serial', - manufacturer_other: '', - year: '2016', - frame_model: 'Cool frame model', + cycle_type: "cargo-rear", + serial_number: "example serial", + manufacturer_other: "", + year: "2016", + frame_model: "Cool frame model", primary_frame_color_id: color.id.to_s, - secondary_frame_color_id: '', - tertiary_frame_color_id: '', - owner_email: 'something@stuff.com' + secondary_frame_color_id: "", + tertiary_frame_color_id: "", + owner_email: "something@stuff.com", } end include_context :geocoder_default_location let(:target_address) { { address: "278 Broadway", city: "New York", state: "NY", zipcode: "10007", country: "USA" } } - let(:b_param) { BParam.create(params: { 'bike' => bike_params.as_json }, origin: 'embed_partial') } + let(:b_param) { BParam.create(params: { "bike" => bike_params.as_json }, origin: "embed_partial") } before do expect(b_param.partial_registration?).to be_truthy bb_data = { bike: {} } @@ -776,16 +776,16 @@ # This is also where we're testing bikebook assignment expect_any_instance_of(BikeBookIntegration).to receive(:get_model) { bb_data } end - it 'creates a bike' do + it "creates a bike" do expect do post :create, bike: { - manufacturer_id: manufacturer.slug, - b_param_id_token: b_param.id_token, - address: default_location[:address], - additional_registration: "XXXZZZ", - organization_affiliation: "employee", - phone: "888.777.6666" - } + manufacturer_id: manufacturer.slug, + b_param_id_token: b_param.id_token, + address: default_location[:address], + additional_registration: "XXXZZZ", + organization_affiliation: "employee", + phone: "888.777.6666", + } end.to change(Bike, :count).by(1) expect(flash[:success]).to be_present bike = Bike.last @@ -796,7 +796,7 @@ bike_params.delete(:manufacturer_id) bike_params.each { |k, v| expect(bike.send(k).to_s).to eq v } expect(bike.manufacturer).to eq manufacturer - expect(bike.creation_state.origin).to eq 'embed_partial' + expect(bike.creation_state.origin).to eq "embed_partial" expect(bike.creation_state.creator).to eq bike.creator expect(bike.registration_address).to eq target_address.as_json expect(bike.additional_registration).to eq "XXXZZZ" @@ -812,16 +812,16 @@ it "creates the bike and does the updated address thing" do expect do post :create, bike: { - manufacturer_id: manufacturer.slug, - b_param_id_token: b_param.id_token, - address: "212 Main St", - address_city: "Chicago", - address_state: "IL", - address_zipcode: "60647", - additional_registration: " ", - organization_affiliation: "student", - phone: "8887776666" - } + manufacturer_id: manufacturer.slug, + b_param_id_token: b_param.id_token, + address: "212 Main St", + address_city: "Chicago", + address_state: "IL", + address_zipcode: "60647", + additional_registration: " ", + organization_affiliation: "student", + phone: "8887776666", + } end.to change(Bike, :count).by(1) expect(flash[:success]).to be_present bike = Bike.last @@ -830,7 +830,7 @@ bike_params.delete(:manufacturer_id) bike_params.each { |k, v| expect(bike.send(k).to_s).to eq v } expect(bike.manufacturer).to eq manufacturer - expect(bike.creation_state.origin).to eq 'embed_partial' + expect(bike.creation_state.origin).to eq "embed_partial" expect(bike.creation_state.creator).to eq bike.creator expect(bike.registration_address).to eq target_address.as_json expect(bike.additional_registration).to be_blank @@ -842,8 +842,8 @@ end end end - context 'created bike' do - it 'redirects to the bike' do + context "created bike" do + it "redirects to the bike" do bike = FactoryBot.create(:bike) b_param = BParam.create(params: { bike: {} }, created_bike_id: bike.id, creator_id: user.id) expect(b_param.created_bike).to be_present @@ -855,35 +855,35 @@ end end - describe 'edit' do + describe "edit" do let(:ownership) { FactoryBot.create(:ownership) } let(:bike) { ownership.bike } let(:edit_templates) do { - root: 'Bike Details', - photos: 'Photos', - drivetrain: 'Wheels + Drivetrain', - accessories: 'Accessories + Components', - ownership: 'Groups + Ownership', - remove: 'Hide or Delete' + root: "Bike Details", + photos: "Photos", + drivetrain: "Wheels + Drivetrain", + accessories: "Accessories + Components", + ownership: "Groups + Ownership", + remove: "Hide or Delete", } end - let(:non_stolen_edit_templates) { edit_templates.merge(stolen: 'Report Stolen or Missing') } - let(:stolen_edit_templates) { { stolen: 'Theft details' }.merge(edit_templates) } - let(:recovery_edit_templates) { { stolen: 'Recovery details' }.merge(edit_templates) } + let(:non_stolen_edit_templates) { edit_templates.merge(stolen: "Report Stolen or Missing") } + let(:stolen_edit_templates) { { stolen: "Theft details" }.merge(edit_templates) } + let(:recovery_edit_templates) { { stolen: "Recovery details" }.merge(edit_templates) } - context 'no user' do - it 'redirects and sets the flash' do + context "no user" do + it "redirects and sets the flash" do get :edit, id: bike.id expect(response).to redirect_to bike_path(bike) expect(flash[:error]).to be_present end end - context 'user present' do + context "user present" do let(:user) { FactoryBot.create(:user_confirmed) } before { set_current_user(user) } context "user present but isn't allowed to edit the bike" do - it 'redirects and sets the flash' do + it "redirects and sets the flash" do FactoryBot.create(:user) get :edit, id: bike.id expect(response).to redirect_to bike_path(bike) @@ -891,68 +891,68 @@ end end context "user present but hasn't claimed the bike" do - it 'claims and renders' do + it "claims and renders" do ownership.update_attribute :user_id, user.id expect(bike.owner).to_not eq user get :edit, id: bike.id bike.reload expect(bike.owner).to eq user expect(response).to be_success - expect(assigns(:edit_template)).to eq 'root' + expect(assigns(:edit_template)).to eq "root" end end - context 'not-creator but member of creation_organization' do + context "not-creator but member of creation_organization" do let(:ownership) { FactoryBot.create(:ownership_organization_bike) } let(:organization) { bike.creation_organization } let(:user) { FactoryBot.create(:organization_member, organization: organization) } - it 'renders' do + it "renders" do expect(bike.owner).to_not eq user expect(bike.creation_organization).to eq user.organizations.first get :edit, id: bike.id expect(response).to be_success - expect(assigns(:edit_template)).to eq 'root' + expect(assigns(:edit_template)).to eq "root" end end end - context 'user allowed to edit the bike' do + context "user allowed to edit the bike" do let(:user) { ownership.creator } - context 'revised' do + context "revised" do before { set_current_user(user) } - context 'root' do - context 'non-stolen bike' do - it 'renders the bike_details template' do + context "root" do + context "non-stolen bike" do + it "renders the bike_details template" do get :edit, id: bike.id - expect(response).to render_with_layout 'application_revised' + expect(response).to render_with_layout "application_revised" expect(response).to be_success - expect(assigns(:edit_template)).to eq 'root' + expect(assigns(:edit_template)).to eq "root" expect(assigns(:edit_templates)).to eq non_stolen_edit_templates.as_json - expect(response).to render_template 'edit_root' + expect(response).to render_template "edit_root" end end - context 'stolen bike' do - it 'renders with stolen as first template, different description' do + context "stolen bike" do + it "renders with stolen as first template, different description" do bike.update_attribute :stolen, true bike.reload expect(bike.stolen).to be_truthy get :edit, id: bike.id - expect(response).to render_with_layout 'application_revised' + expect(response).to render_with_layout "application_revised" expect(response).to be_success - expect(assigns(:edit_template)).to eq 'stolen' + expect(assigns(:edit_template)).to eq "stolen" expect(assigns(:edit_templates)).to eq stolen_edit_templates.as_json - expect(response).to render_template 'edit_stolen' + expect(response).to render_template "edit_stolen" end end - context 'recovered bike' do - it 'renders with recovered as first template, different description' do + context "recovered bike" do + it "renders with recovered as first template, different description" do bike.update_attributes(stolen: true, recovered: true) bike.reload expect(bike.recovered).to be_truthy get :edit, id: bike.id - expect(response).to render_with_layout 'application_revised' + expect(response).to render_with_layout "application_revised" expect(response).to be_success - expect(assigns(:edit_template)).to eq 'stolen' + expect(assigns(:edit_template)).to eq "stolen" expect(assigns(:edit_templates)).to eq recovery_edit_templates.as_json - expect(response).to render_template 'edit_stolen' + expect(response).to render_template "edit_stolen" end end end @@ -962,13 +962,13 @@ bc.instance_variable_set(:@bike, Bike.new) bc.edit_templates_hash.keys.map(&:to_s).each do |template| context template do - it 'renders the template' do + it "renders the template" do get :edit, id: bike.id, page: template - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(response).to be_success expect(response).to render_template("edit_#{template}") expect(assigns(:edit_template)).to eq(template) - expect(assigns(:private_images)).to eq([]) if template == 'photos' + expect(assigns(:private_images)).to eq([]) if template == "photos" end end end @@ -976,69 +976,69 @@ end end - describe 'update' do - context 'user is present but is not allowed to edit' do - it 'does not update and redirects' do + describe "update" do + context "user is present but is not allowed to edit" do + it "does not update and redirects" do ownership = FactoryBot.create(:ownership) user = FactoryBot.create(:user_confirmed) set_current_user(user) - put :update, id: ownership.bike.id, bike: { serial_number: '69' } + put :update, id: ownership.bike.id, bike: { serial_number: "69" } expect(response).to redirect_to bike_url(ownership.bike) expect(flash[:error]).to be_present end end - context 'creator present (who is allowed to edit)' do + context "creator present (who is allowed to edit)" do let(:ownership) { FactoryBot.create(:ownership) } let(:user) { ownership.creator } let(:bike) { ownership.bike } before do set_current_user(user) end - context 'legacy' do - it 'allows you to edit an example bike' do + context "legacy" do + it "allows you to edit an example bike" do # Also test that we don't don't blank bike_organizations # if bike_organization_ids aren't passed organization = FactoryBot.create(:organization) ownership.bike.update_attributes(example: true, bike_organization_ids: [organization.id]) bike.reload expect(bike.bike_organization_ids).to eq([organization.id]) - put :update, id: bike.id, bike: { description: '69' } + put :update, id: bike.id, bike: { description: "69" } expect(response).to redirect_to edit_bike_url(bike) bike.reload - expect(bike.description).to eq('69') + expect(bike.description).to eq("69") expect(bike.bike_organization_ids).to eq([organization.id]) end - it 'updates the bike and components' do + it "updates the bike and components" do component1 = FactoryBot.create(:component, bike: bike) another_handlebar_type = "drop" ctype_id = component1.ctype_id bike.reload component2_attrs = { - _destroy: '0', + _destroy: "0", ctype_id: ctype_id, - description: 'sdfsdfsdf', + description: "sdfsdfsdf", manufacturer_id: bike.manufacturer_id.to_s, - manufacturer_other: 'stuffffffff', - cmodel_name: 'asdfasdf', - year: '1995', - serial_number: 'simple_serial' + manufacturer_other: "stuffffffff", + cmodel_name: "asdfasdf", + year: "1995", + serial_number: "simple_serial", } bike_attrs = { - description: '69', + description: "69", handlebar_type: another_handlebar_type, components_attributes: { - '0' => { - '_destroy' => '1', - id: component1.id.to_s + "0" => { + "_destroy" => "1", + id: component1.id.to_s, }, - Time.zone.now.to_i.to_s => component2_attrs - } + Time.zone.now.to_i.to_s => component2_attrs, + }, } put :update, id: bike.id, bike: bike_attrs bike.reload - expect(bike.description).to eq('69') + expect(bike.description).to eq("69") expect(response).to redirect_to edit_bike_url(bike) expect(bike.handlebar_type).to eq another_handlebar_type expect(assigns(:bike)).to be_decorated @@ -1052,38 +1052,38 @@ end end - it 'marks the bike unhidden' do - bike.update_attribute :marked_user_hidden, '1' + it "marks the bike unhidden" do + bike.update_attribute :marked_user_hidden, "1" bike.reload expect(bike.hidden).to be_truthy - put :update, id: bike.id, bike: { marked_user_unhidden: 'true' } + put :update, id: bike.id, bike: { marked_user_unhidden: "true" } expect(bike.reload.hidden).to be_falsey end - it 'creates a new ownership if the email changes' do + it "creates a new ownership if the email changes" do expect do - put :update, id: bike.id, bike: { owner_email: 'new@email.com' } + put :update, id: bike.id, bike: { owner_email: "new@email.com" } end.to change(Ownership, :count).by(1) end it "redirects to return_to if it's a valid url" do - session[:return_to] = '/about' - put :update, id: bike.id, bike: { description: '69', marked_user_hidden: '0' } - expect(bike.reload.description).to eq('69') - expect(response).to redirect_to '/about' + session[:return_to] = "/about" + put :update, id: bike.id, bike: { description: "69", marked_user_hidden: "0" } + expect(bike.reload.description).to eq("69") + expect(response).to redirect_to "/about" expect(session[:return_to]).to be_nil end it "doesn't redirect and clears the session if not a valid url" do - session[:return_to] = 'http://testhost.com/bad_place' - put :update, id: bike.id, bike: { description: '69', marked_user_hidden: '0' } + session[:return_to] = "http://testhost.com/bad_place" + put :update, id: bike.id, bike: { description: "69", marked_user_hidden: "0" } bike.reload - expect(bike.description).to eq('69') + expect(bike.description).to eq("69") expect(session[:return_to]).to be_nil expect(response).to redirect_to edit_bike_url end end - context 'revised' do + context "revised" do # We're testing a few things in here: # Firstly, new stolen update code paths # Also, that we can apply stolen changes to hidden bikes @@ -1111,15 +1111,15 @@ secondary_phone: "8888888888", proof_of_ownership: 1, receive_notifications: 0, - estimated_value: "1200" + estimated_value: "1200", } end let(:bike_attrs) do { stolen: true, stolen_records_attributes: { - "0" => stolen_attrs - } + "0" => stolen_attrs, + }, } end let(:skipped_attrs) { %w[proof_of_ownership receive_notifications timezone date_stolen estimated_value].map(&:to_sym) } @@ -1160,13 +1160,13 @@ end end end - context 'recovered bike' do - it 'marks the bike recovered' + context "recovered bike" do + it "marks the bike recovered" end end end end - context 'owner present (who is allowed to edit)' do + context "owner present (who is allowed to edit)" do let(:color) { FactoryBot.create(:color) } let(:user) { FactoryBot.create(:user_confirmed) } let(:ownership) { FactoryBot.create(:ownership_organization_bike, owner_email: user.email) } @@ -1175,8 +1175,8 @@ let(:organization_2) { FactoryBot.create(:organization) } let(:allowed_attributes) do { - description: '69 description', - marked_user_hidden: '0', + description: "69 description", + marked_user_hidden: "0", primary_frame_color_id: color.id, secondary_frame_color_id: color.id, tertiary_frame_color_id: Color.black.id, @@ -1185,13 +1185,13 @@ belt_drive: true, front_gear_type_id: FactoryBot.create(:front_gear_type).id, rear_gear_type_id: FactoryBot.create(:rear_gear_type).id, - owner_email: 'new_email@stuff.com', + owner_email: "new_email@stuff.com", year: 1993, - frame_model: 'A sweet model named things', - frame_size: '56cm', - name: 'a sweet name for a bike', - additional_registration: 'some weird other number', - bike_organization_ids: "#{organization_2.id}, #{organization.id}" + frame_model: "A sweet model named things", + frame_size: "56cm", + name: "a sweet name for a bike", + additional_registration: "some weird other number", + bike_organization_ids: "#{organization_2.id}, #{organization.id}", } end let(:skipped_attrs) { %w[marked_user_hidden bike_organization_ids].map(&:to_sym) } @@ -1200,7 +1200,7 @@ set_current_user(user) expect(ownership.owner).to eq user end - it 'updates the bike with the allowed_attributes' do + it "updates the bike with the allowed_attributes" do put :update, id: bike.id, bike: allowed_attributes expect(response).to redirect_to edit_bike_url(bike) expect(assigns(:bike)).to be_decorated @@ -1234,11 +1234,11 @@ end end - describe 'show with recovery token present' do + describe "show with recovery token present" do let(:bike) { FactoryBot.create(:stolen_bike) } let(:stolen_record) { bike.current_stolen_record } let(:recovery_link_token) { stolen_record.find_or_create_recovery_link_token } - it 'renders a mark recovered modal, and deletes the session recovery_link_token' do + it "renders a mark recovered modal, and deletes the session recovery_link_token" do session[:recovery_link_token] = recovery_link_token get :show, id: bike.id expect(response.body).to match(recovery_link_token) diff --git a/spec/controllers/blogs_controller_spec.rb b/spec/controllers/blogs_controller_spec.rb index 789eb04aa9..bb18fa2e91 100644 --- a/spec/controllers/blogs_controller_spec.rb +++ b/spec/controllers/blogs_controller_spec.rb @@ -1,17 +1,17 @@ -require 'spec_helper' +require "spec_helper" describe BlogsController do - describe 'index' do - it 'redirects' do + describe "index" do + it "redirects" do get :index expect(response).to redirect_to(news_index_url) end end - describe 'show' do - it 'redirects' do + describe "show" do + it "redirects" do user = FactoryBot.create(:user) - blog = Blog.create(title: 'foo title', body: 'ummmmm good', user_id: user.id) + blog = Blog.create(title: "foo title", body: "ummmmm good", user_id: user.id) get :show, id: blog.title_slug expect(response).to redirect_to(news_url(blog.title_slug)) end diff --git a/spec/controllers/discourse_authentication_controller_spec.rb b/spec/controllers/discourse_authentication_controller_spec.rb index 95bf390937..a8034edc37 100644 --- a/spec/controllers/discourse_authentication_controller_spec.rb +++ b/spec/controllers/discourse_authentication_controller_spec.rb @@ -1,35 +1,35 @@ -require 'spec_helper' +require "spec_helper" describe DiscourseAuthenticationController do - describe 'index' do - let(:discourse_query_string) { 'sso=bm9uY2U9MGViZDBjMWU2YmZjMDk2MmIxODQ2YzBiYWY4NjNmNDcmcmV0dXJu%0AX3Nzb191cmw9aHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTMwMDAlMkZzZXNz%0AaW9uJTJGc3NvX2xvZ2lu%0A&sig=b1cffd09e878825b0bcdbf2eedf7e7e6133e3ca5acac6854f096bee71786f125' } - let(:discourse_params) { { 'sso' => 'bm9uY2U9MGViZDBjMWU2YmZjMDk2MmIxODQ2YzBiYWY4NjNmNDcmcmV0dXJu%0AX3Nzb191cmw9aHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTMwMDAlMkZzZXNz%0AaW9uJTJGc3NvX2xvZ2lu%0A', 'sig' => '5b49e8c57feef6f8ca0ae0720388dcf6d46c183be8017413344c388580daaca3' } } + describe "index" do + let(:discourse_query_string) { "sso=bm9uY2U9MGViZDBjMWU2YmZjMDk2MmIxODQ2YzBiYWY4NjNmNDcmcmV0dXJu%0AX3Nzb191cmw9aHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTMwMDAlMkZzZXNz%0AaW9uJTJGc3NvX2xvZ2lu%0A&sig=b1cffd09e878825b0bcdbf2eedf7e7e6133e3ca5acac6854f096bee71786f125" } + let(:discourse_params) { { "sso" => "bm9uY2U9MGViZDBjMWU2YmZjMDk2MmIxODQ2YzBiYWY4NjNmNDcmcmV0dXJu%0AX3Nzb191cmw9aHR0cCUzQSUyRiUyRmxvY2FsaG9zdCUzQTMwMDAlMkZzZXNz%0AaW9uJTJGc3NvX2xvZ2lu%0A", "sig" => "5b49e8c57feef6f8ca0ae0720388dcf6d46c183be8017413344c388580daaca3" } } - context 'not signed in' do - it 'redirects to sign in and sets discourse_redirect' do + context "not signed in" do + it "redirects to sign in and sets discourse_redirect" do get :index, discourse_params expect(Rack::Utils.parse_query(session[:discourse_redirect])).to eq(discourse_params) expect(response).to redirect_to(new_session_path) end end - context 'signed in' do + context "signed in" do before do user = FactoryBot.create(:user_confirmed) set_current_user(user) - sso = SingleSignOn.parse(discourse_query_string, ENV['DISCOURSE_SECRET']) + sso = SingleSignOn.parse(discourse_query_string, ENV["DISCOURSE_SECRET"]) sso.email = user.email sso.name = user.name sso.external_id = user.id - @target_url = sso.to_url("#{ENV['DISCOURSE_URL']}/session/sso_login") + @target_url = sso.to_url("#{ENV["DISCOURSE_URL"]}/session/sso_login") end - it 'redirects signed in user from query string' do + it "redirects signed in user from query string" do get :index, Rack::Utils.parse_query(discourse_query_string) expect(response).to redirect_to(@target_url) expect(session[:discourse_redirect]).to be_nil end - it 'redirects user from discourse_redirect in session' do + it "redirects user from discourse_redirect in session" do session[:discourse_redirect] = discourse_query_string get :index expect(response).to redirect_to(@target_url) diff --git a/spec/controllers/documentation_controller_spec.rb b/spec/controllers/documentation_controller_spec.rb index eed81615da..418ce0d9d0 100644 --- a/spec/controllers/documentation_controller_spec.rb +++ b/spec/controllers/documentation_controller_spec.rb @@ -1,51 +1,51 @@ -require 'spec_helper' +require "spec_helper" describe DocumentationController do - describe 'index' do - it 'redirects to current api documentation' do + describe "index" do + it "redirects to current api documentation" do get :index - expect(response).to redirect_to('/documentation/api_v3') + expect(response).to redirect_to("/documentation/api_v3") expect(flash).to_not be_present end end - describe 'api_v1' do - context 'developer user' do - it 'renders' do + describe "api_v1" do + context "developer user" do + it "renders" do user = FactoryBot.create(:developer) set_current_user(user) - FactoryBot.create(:organization, name: 'Example organization') # Required because I'm an idiot + FactoryBot.create(:organization, name: "Example organization") # Required because I'm an idiot get :api_v1 - expect(response.code).to eq('200') - expect(response).to render_template('api_v1') + expect(response.code).to eq("200") + expect(response).to render_template("api_v1") expect(flash).to_not be_present end end - context 'user' do - it 'redirects to home, message API deprecated' do + context "user" do + it "redirects to home, message API deprecated" do user = FactoryBot.create(:user_confirmed) set_current_user(user) get :api_v1 expect(response).to redirect_to documentation_index_path - expect(flash[:notice]).to match 'deprecated' + expect(flash[:notice]).to match "deprecated" end end end - describe 'api_v2' do - it 'renders' do + describe "api_v2" do + it "renders" do get :api_v2 - expect(response.code).to eq('200') - expect(response).to render_template('api_v2') + expect(response.code).to eq("200") + expect(response).to render_template("api_v2") expect(flash).to_not be_present end end - describe 'api_v3' do - it 'renders' do + describe "api_v3" do + it "renders" do get :api_v3 - expect(response.code).to eq('200') - expect(response).to render_template('api_v3') + expect(response.code).to eq("200") + expect(response).to render_template("api_v3") expect(flash).to_not be_present end end diff --git a/spec/controllers/errors_controller_spec.rb b/spec/controllers/errors_controller_spec.rb index 5b544f38f4..fe5d680272 100644 --- a/spec/controllers/errors_controller_spec.rb +++ b/spec/controllers/errors_controller_spec.rb @@ -1,32 +1,32 @@ -require 'spec_helper' +require "spec_helper" describe ErrorsController do - describe 'bad_request' do - it 'renders' do + describe "bad_request" do + it "renders" do get :bad_request expect(response.status).to eq(400) expect(response).to render_template(:bad_request) end end - describe 'unauthorized' do - it 'renders' do + describe "unauthorized" do + it "renders" do get :unauthorized, format: :json expect(response.status).to eq(401) expect(response).to render_template(:unauthorized) end end - describe 'not_found' do - it 'renders' do + describe "not_found" do + it "renders" do get :not_found expect(response.status).to eq(404) expect(response).to render_template(:not_found) end end - describe 'unprocessable_entity' do - it 'renders' do + describe "unprocessable_entity" do + it "renders" do get :unprocessable_entity, format: :json expect(response.status).to eq(422) expect(response).to render_template(:unprocessable_entity) diff --git a/spec/controllers/feedbacks_controller_spec.rb b/spec/controllers/feedbacks_controller_spec.rb index 0dba1efe96..c145e860c5 100644 --- a/spec/controllers/feedbacks_controller_spec.rb +++ b/spec/controllers/feedbacks_controller_spec.rb @@ -1,33 +1,33 @@ -require 'spec_helper' +require "spec_helper" describe FeedbacksController do - describe 'index' do - it 'renders with revised_layout' do + describe "index" do + it "renders with revised_layout" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - describe 'create' do + describe "create" do let(:feedback_attrs) do { - name: 'something cool', - email: 'example@stuff.com', - title: 'a title and things', - body: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + name: "something cool", + email: "example@stuff.com", + title: "a title and things", + body: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non - proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' + proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", } end let!(:user) { FactoryBot.create(:user_confirmed) } - context 'valid feedback' do - it 'creates a feedback message' do + context "valid feedback" do + it "creates a feedback message" do expect(user.name).to be_present set_current_user(user) expect do @@ -55,41 +55,41 @@ end end - context 'feedback with generated title' do - it 'creates a feedback' do - request.env['HTTP_REFERER'] = 'http://localhost:3000/partyyyyy' + context "feedback with generated title" do + it "creates a feedback" do + request.env["HTTP_REFERER"] = "http://localhost:3000/partyyyyy" expect do post :create, feedback: { - name: 'Cool School', - feedback_type: 'lead_for_school', - email: 'example@example.com', - body: 'ffff' - } + name: "Cool School", + feedback_type: "lead_for_school", + email: "example@example.com", + body: "ffff", + } end.to change(EmailFeedbackNotificationWorker.jobs, :count).by(1) - expect(response).to redirect_to 'http://localhost:3000/partyyyyy' + expect(response).to redirect_to "http://localhost:3000/partyyyyy" expect(flash[:success]).to be_present feedback = Feedback.last - expect(feedback.title).to eq 'New School lead: Cool School' - expect(feedback.email).to eq 'example@example.com' - expect(feedback.body).to eq 'ffff' + expect(feedback.title).to eq "New School lead: Cool School" + expect(feedback.email).to eq "example@example.com" + expect(feedback.body).to eq "ffff" end end - context 'feedback with additional' do - it 'creates a feedback message' do + context "feedback with additional" do + it "creates a feedback message" do expect do - post :create, feedback: feedback_attrs.merge(additional: 'stuff') + post :create, feedback: feedback_attrs.merge(additional: "stuff") end.to change(EmailFeedbackNotificationWorker.jobs, :count).by(0) expect(flash[:error]).to match(/sign in/i) - expect(response).to redirect_to feedbacks_path(anchor: 'contact_us_section') + expect(response).to redirect_to feedbacks_path(anchor: "contact_us_section") end end - context 'invalid feedback' do - context 'no referrer' do - it 'does not create a feedback message' do + context "invalid feedback" do + context "no referrer" do + it "does not create a feedback message" do expect do - post :create, feedback: feedback_attrs.merge(email: '') + post :create, feedback: feedback_attrs.merge(email: "") end.to change(EmailFeedbackNotificationWorker.jobs, :count).by(0) expect(response).to render_template(:index) feedback = assigns(:feedback) @@ -97,14 +97,14 @@ expect(assigns(:page_errors).full_messages.to_s).to match "Email can't be blank" end end - context 'referrer set' do - it 'does not create a feedback message' do + context "referrer set" do + it "does not create a feedback message" do set_current_user(user) - request.env['HTTP_REFERER'] = for_schools_url + request.env["HTTP_REFERER"] = for_schools_url expect do - post :create, feedback: feedback_attrs.merge(body: '') + post :create, feedback: feedback_attrs.merge(body: "") end.to change(EmailFeedbackNotificationWorker.jobs, :count).by(0) - expect(response).to render_template('landing_pages/for_schools') + expect(response).to render_template("landing_pages/for_schools") feedback = assigns(:feedback) feedback_attrs.except(:body).each { |k, v| expect(feedback.send(k)).to eq(v) } expect(assigns(:page_errors).full_messages.to_s).to match "Body can't be blank" diff --git a/spec/controllers/info_controller_spec.rb b/spec/controllers/info_controller_spec.rb index 7dc91fcf42..dbd9dc55fb 100644 --- a/spec/controllers/info_controller_spec.rb +++ b/spec/controllers/info_controller_spec.rb @@ -1,26 +1,26 @@ -require 'spec_helper' +require "spec_helper" describe InfoController do - describe 'revised views' do + describe "revised views" do pages = %w(about protect_your_bike where serials image_resources resources dev_and_design support_bike_index terms vendor_terms privacy lightspeed) - context 'no user' do + context "no user" do pages.each do |page| context "#{page} with revised_layout enabled" do - it 'renders with revised_layout' do + it "renders with revised_layout" do get page.to_sym expect(response.status).to eq(200) expect(response).to render_template(page.to_sym) - if page == 'support_bike_index' - expect(response).to render_with_layout('payments_layout') + if page == "support_bike_index" + expect(response).to render_with_layout("payments_layout") else - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end end end end - context 'signed in user' do + context "signed in user" do let(:user) { FactoryBot.create(:user_confirmed) } # Since we're rendering things, and these are important pages, # let's test with users as well @@ -29,14 +29,14 @@ end pages.each do |page| context "#{page} with revised_layout enabled" do - it 'renders with revised_layout' do + it "renders with revised_layout" do get page.to_sym expect(response.status).to eq(200) expect(response).to render_template(page.to_sym) - if page == 'support_bike_index' - expect(response).to render_with_layout('payments_layout') + if page == "support_bike_index" + expect(response).to render_with_layout("payments_layout") else - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end end diff --git a/spec/controllers/integrations_controller_spec.rb b/spec/controllers/integrations_controller_spec.rb index 4a7c3f0c72..ef2428b38f 100644 --- a/spec/controllers/integrations_controller_spec.rb +++ b/spec/controllers/integrations_controller_spec.rb @@ -2,42 +2,41 @@ describe IntegrationsController do let!(:omniauth_facebook_mock) do - OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new('provider' => 'facebook', - 'uid' => '64901670', - 'info' => { - 'nickname' => 'foo.user.5', - 'email' => 'foo.user@gmail.com', - 'name' => 'foo user', - 'first_name' => 'foo', - 'last_name' => 'user', - 'image' => 'http://graph.facebook.com/64901670/picture?type=square', - 'urls' => { - 'Facebook' => 'http://www.facebook.com/foo.user.5' - }, - 'verified' => true - }, - 'credentials' => { - 'token' => 'CAAGW44SIv5sBACqokzRSPaAhh3xiQntB8GD6oRKHToSLWFzz4kv32tJUpK2aZCg3pdzyUNODKjtvXdJyMqCnyZCqPgJvluOK08sbDgRXgQ5oIggVl2pxnokDD09kF1xkQIyUhTI55sUyxOkjKo', - 'expires_at' => 1373982961, - 'expires' => true - }, - 'extra' => { - 'raw_info' => { - 'id' => '64901670', - 'name' => 'foo user', - 'first_name' => 'foo', - 'last_name' => 'user', - 'link' => 'http://www.facebook.com/foo.user.5', - 'username' => 'foo.user.5', - 'gender' => 'male', - 'email' => 'foo.user@gmail.com', - 'timezone' => -5, - 'locale' => 'en_US', - 'verified' => true, - 'updated_time' => '2012-08-06T23:32:31+0000' - } - }) - + OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new("provider" => "facebook", + "uid" => "64901670", + "info" => { + "nickname" => "foo.user.5", + "email" => "foo.user@gmail.com", + "name" => "foo user", + "first_name" => "foo", + "last_name" => "user", + "image" => "http://graph.facebook.com/64901670/picture?type=square", + "urls" => { + "Facebook" => "http://www.facebook.com/foo.user.5", + }, + "verified" => true, + }, + "credentials" => { + "token" => "CAAGW44SIv5sBACqokzRSPaAhh3xiQntB8GD6oRKHToSLWFzz4kv32tJUpK2aZCg3pdzyUNODKjtvXdJyMqCnyZCqPgJvluOK08sbDgRXgQ5oIggVl2pxnokDD09kF1xkQIyUhTI55sUyxOkjKo", + "expires_at" => 1373982961, + "expires" => true, + }, + "extra" => { + "raw_info" => { + "id" => "64901670", + "name" => "foo user", + "first_name" => "foo", + "last_name" => "user", + "link" => "http://www.facebook.com/foo.user.5", + "username" => "foo.user.5", + "gender" => "male", + "email" => "foo.user@gmail.com", + "timezone" => -5, + "locale" => "en_US", + "verified" => true, + "updated_time" => "2012-08-06T23:32:31+0000", + }, + }) end describe "create" do context "when there is no user" do @@ -60,7 +59,7 @@ expect do get :create, access_token: "123456", expires_in: "3920", token_type: "Bearer", refresh_token: "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" - expect(flash[:success]).to be_present + expect(flash[:success]).to be_present expect(response).to redirect_to(user_home_url) end.to change(Integration, :count).by 1 end diff --git a/spec/controllers/landing_pages_controller_spec.rb b/spec/controllers/landing_pages_controller_spec.rb index 82dbcb8d2b..56a9252361 100644 --- a/spec/controllers/landing_pages_controller_spec.rb +++ b/spec/controllers/landing_pages_controller_spec.rb @@ -34,7 +34,7 @@ elsif landing_type == "ascend" expect(title).to eq "Ascend POS on Bike Index" else - expect(title).to eq "Bike Index #{landing_type.titleize.gsub(/\AF/, 'f')}" + expect(title).to eq "Bike Index #{landing_type.titleize.gsub(/\AF/, "f")}" end end end diff --git a/spec/controllers/locks_controller_spec.rb b/spec/controllers/locks_controller_spec.rb index c15ddba9d8..529bd8e442 100644 --- a/spec/controllers/locks_controller_spec.rb +++ b/spec/controllers/locks_controller_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe LocksController do include_context :logged_in_as_user before do # We have to create all the lock types.... Could be improved ;) - ['U-lock', 'Chain with lock', 'Cable', 'Locking skewer', 'Other style'].each do |name| + ["U-lock", "Chain with lock", "Cable", "Locking skewer", "Other style"].each do |name| LockType.create(name: name) end end @@ -16,54 +16,54 @@ { lock_type_id: lock_type.id, manufacturer_id: manufacturer.id, - manufacturer_other: '', + manufacturer_other: "", has_key: true, has_combination: false, - key_serial: '321', - combination: '' + key_serial: "321", + combination: "", } end - describe 'new' do - it 'renders' do + describe "new" do + it "renders" do get :new - expect(response.code).to eq('200') - expect(response).to render_template('new') + expect(response.code).to eq("200") + expect(response).to render_template("new") end end - describe 'edit' do - context 'not lock owner' do - it 'redirects to user_home' do + describe "edit" do + context "not lock owner" do + it "redirects to user_home" do get :edit, id: lock.id expect(flash[:error]).to be_present expect(response).to redirect_to(:user_home) end end - context 'lock owner' do - it 'renders' do + context "lock owner" do + it "renders" do get :edit, id: owner_lock.id - expect(response.code).to eq('200') - expect(response).to render_template('edit') + expect(response.code).to eq("200") + expect(response).to render_template("edit") end end end - describe 'update' do - context 'not lock owner' do - it 'redirects to user_home' do - put :update, id: lock.id, combination: '123' + describe "update" do + context "not lock owner" do + it "redirects to user_home" do + put :update, id: lock.id, combination: "123" expect(flash[:error]).to be_present expect(response).to redirect_to(:user_home) - expect(lock.combination).to_not eq('123') + expect(lock.combination).to_not eq("123") end end - context 'lock owner' do - it 'renders' do + context "lock owner" do + it "renders" do put :update, id: owner_lock.id, lock: valid_attributes owner_lock.reload - expect(response.code).to eq('200') - expect(response).to render_template('edit') + expect(response.code).to eq("200") + expect(response).to render_template("edit") valid_attributes.each do |key, value| pp key unless owner_lock.send(key) == value expect(owner_lock.send(key)).to eq value @@ -72,13 +72,13 @@ end end - describe 'create' do - context 'success' do - it 'redirects you to user_home locks table' do + describe "create" do + context "success" do + it "redirects you to user_home locks table" do post :create, lock: valid_attributes user.reload lock = user.locks.first - expect(response).to redirect_to user_home_path(active_tab: 'locks') + expect(response).to redirect_to user_home_path(active_tab: "locks") valid_attributes.each do |key, value| pp key unless lock.send(key) == value expect(lock.send(key)).to eq value @@ -87,9 +87,9 @@ end end - describe 'destroy' do - context 'not lock owner' do - it 'redirects to user_home' do + describe "destroy" do + context "not lock owner" do + it "redirects to user_home" do expect(lock).to be_present delete :destroy, id: lock.id expect(flash[:error]).to be_present @@ -97,13 +97,13 @@ expect(lock.reload).to be_truthy end end - context 'lock owner' do - it 'renders' do + context "lock owner" do + it "renders" do expect(owner_lock).to be_present expect do delete :destroy, id: owner_lock.id end.to change(Lock, :count).by(-1) - expect(response).to redirect_to user_home_path(active_tab: 'locks') + expect(response).to redirect_to user_home_path(active_tab: "locks") end end end diff --git a/spec/controllers/manufacturers_controller_spec.rb b/spec/controllers/manufacturers_controller_spec.rb index a440924171..d7696fed78 100644 --- a/spec/controllers/manufacturers_controller_spec.rb +++ b/spec/controllers/manufacturers_controller_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require "spec_helper" describe ManufacturersController do - describe 'index' do - it 'renders with revised_layout' do + describe "index" do + it "renders with revised_layout" do get :index expect(response.status).to eq(200) expect(response).to render_template(:index) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - describe 'tsv' do + describe "tsv" do before do get :tsv end diff --git a/spec/controllers/news_controller_spec.rb b/spec/controllers/news_controller_spec.rb index 4e57692761..8364835ff7 100644 --- a/spec/controllers/news_controller_spec.rb +++ b/spec/controllers/news_controller_spec.rb @@ -1,74 +1,74 @@ -require 'spec_helper' +require "spec_helper" describe NewsController do - context 'legacy' do - describe 'index' do - it 'renders' do + context "legacy" do + describe "index" do + it "renders" do get :index expect(response.status).to eq(200) - expect(response).to render_template('index') + expect(response).to render_template("index") end end - describe 'show' do + describe "show" do let(:user) { FactoryBot.create(:user) } - let(:blog) { Blog.create(title: 'foo title', body: 'ummmmm good', user_id: user.id, old_title_slug: 'an-older-title') } - context 'title slug' do - it 'renders' do + let(:blog) { Blog.create(title: "foo title", body: "ummmmm good", user_id: user.id, old_title_slug: "an-older-title") } + context "title slug" do + it "renders" do get :show, id: blog.title_slug expect(response.status).to eq(200) - expect(response).to render_template('show') + expect(response).to render_template("show") end end - context 'old title slug' do - it 'renders' do + context "old title slug" do + it "renders" do get :show, id: blog.old_title_slug expect(response.status).to eq(200) - expect(response).to render_template('show') + expect(response).to render_template("show") end end - context 'id' do - it 'renders' do + context "id" do + it "renders" do get :show, id: blog.id expect(response.status).to eq(200) - expect(response).to render_template('show') + expect(response).to render_template("show") end end end end - context 'revised' do - describe 'index' do - context 'html' do - it 'renders' do + context "revised" do + describe "index" do + context "html" do + it "renders" do get :index expect(response.status).to eq(200) - expect(response).to render_template('index') - expect(response).to render_with_layout('application_revised') + expect(response).to render_template("index") + expect(response).to render_with_layout("application_revised") end end - context 'xml' do - it 'redirects to atom' do + context "xml" do + it "redirects to atom" do get :index, format: :xml - expect(response).to redirect_to(news_index_path(format: 'atom')) + expect(response).to redirect_to(news_index_path(format: "atom")) end end - context 'atom' do - it 'renders' do + context "atom" do + it "renders" do get :index, format: :atom expect(response.status).to eq(200) end end end - describe 'show' do + describe "show" do let(:user) { FactoryBot.create(:user) } - let(:blog) { Blog.create(title: 'foo title', body: 'ummmmm good', user_id: user.id, old_title_slug: 'an-older-title') } - it 'renders' do + let(:blog) { Blog.create(title: "foo title", body: "ummmmm good", user_id: user.id, old_title_slug: "an-older-title") } + it "renders" do get :show, id: blog.title_slug expect(response.status).to eq(200) - expect(response).to render_template('show') - expect(response).to render_with_layout('application_revised') + expect(response).to render_template("show") + expect(response).to render_with_layout("application_revised") end end end diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb index 8c345a4f4f..0ebfd02634 100644 --- a/spec/controllers/oauth/applications_controller_spec.rb +++ b/spec/controllers/oauth/applications_controller_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe Oauth::ApplicationsController do include_context :existing_doorkeeper_app describe "index" do - it 'redirects' do + it "redirects" do get :index expect(response).to redirect_to new_session_url expect(flash[:error]).to be_present @@ -26,13 +26,13 @@ end end - describe 'create' do + describe "create" do include_context :logged_in_as_user it "creates an application and adds the v2 accessor to it" do v2_access_id app_attrs = { name: "Some app", - redirect_uri: "urn:ietf:wg:oauth:2.0:oob" + redirect_uri: "urn:ietf:wg:oauth:2.0:oob", } post :create, doorkeeper_application: app_attrs app = user.oauth_applications.first @@ -59,7 +59,7 @@ it "renders if owned by user" do expect(doorkeeper_app.owner_id).to eq user.id get :edit, id: doorkeeper_app.id - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(flash).not_to be_present end @@ -75,10 +75,10 @@ context "admin" do let(:user) { FactoryBot.create(:admin) } - it 'renders if superuser' do + it "renders if superuser" do expect(doorkeeper_app.owner_id).to_not eq user.id get :edit, id: doorkeeper_app.id - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(flash).not_to be_present end end @@ -87,7 +87,7 @@ describe "update" do before { set_current_user(user) } # Do separately from logged_in_as, pulling doorkeeper user - it 'renders if owned by user' do + it "renders if owned by user" do expect(doorkeeper_app.owner_id).to eq user.id put :update, id: doorkeeper_app.id, doorkeeper_application: { name: "new thing" } doorkeeper_app.reload diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index dbf65bf754..22e8f4e024 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -1,34 +1,34 @@ -require 'spec_helper' +require "spec_helper" describe OrganizationsController do - describe 'new' do - context 'with out user' do - it 'renders' do + describe "new" do + context "with out user" do + it "renders" do get :new expect(response.status).to eq(200) expect(response).to render_template(:new) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - context 'with user' do - it 'renders with revised_layout' do + context "with user" do + it "renders with revised_layout" do set_current_user(FactoryBot.create(:user_confirmed)) get :new expect(response.status).to eq(200) expect(response).to render_template(:new) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end end - describe 'create' do + describe "create" do let(:org_attrs) do { name: "a new org", kind: "bike_shop", } end - it 'creates org, membership, filters approved attrs & redirect to org with current_user' do + it "creates org, membership, filters approved attrs & redirect to org with current_user" do expect(Organization.count).to eq(0) user = FactoryBot.create(:user_confirmed) set_current_user(user) @@ -44,7 +44,7 @@ expect(organization.kind).to eq "bike_shop" end - it 'creates org, membership, filters approved attrs & redirect to org with current_user and mails' do + it "creates org, membership, filters approved attrs & redirect to org with current_user and mails" do Sidekiq::Testing.inline! do expect(Organization.count).to eq(0) user = FactoryBot.create(:user_confirmed) @@ -79,63 +79,63 @@ end end - describe 'legacy embeds' do + describe "legacy embeds" do let(:organization) { FactoryBot.create(:organization_with_auto_user) } - - context 'non-stolen' do - it 'renders embed without xframe block' do + + context "non-stolen" do + it "renders embed without xframe block" do get :embed, id: organization.slug - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(response).to render_template(:embed) - expect(response.headers['X-Frame-Options']).not_to be_present + expect(response.headers["X-Frame-Options"]).not_to be_present expect(assigns(:stolen)).to be_falsey bike = assigns(:bike) expect(bike.stolen).to be_falsey end end - context 'stolen' do - it 'renders embed without xframe block' do + context "stolen" do + it "renders embed without xframe block" do get :embed, id: organization.slug, stolen: 1 - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(response).to render_template(:embed) - expect(response.headers['X-Frame-Options']).not_to be_present + expect(response.headers["X-Frame-Options"]).not_to be_present expect(assigns(:stolen)).to be_truthy bike = assigns(:bike) expect(bike.stolen).to be_truthy end end - context 'embed_extended' do - it 'renders embed without xframe block, not stolen' do - get :embed_extended, id: organization.slug, email: 'something@example.com' - expect(response.code).to eq('200') + context "embed_extended" do + it "renders embed without xframe block, not stolen" do + get :embed_extended, id: organization.slug, email: "something@example.com" + expect(response.code).to eq("200") expect(response).to render_template(:embed_extended) - expect(response.headers['X-Frame-Options']).not_to be_present + expect(response.headers["X-Frame-Options"]).not_to be_present expect(assigns(:persist_email)).to be_truthy bike = assigns(:bike) expect(bike.stolen).to be_falsey end end - context 'crazy b_param data' do + context "crazy b_param data" do let(:b_param_attrs) do { bike: { - stolen: 'true', - owner_email: 'someemail@stuff.com', - creation_organization_id: organization.id.to_s + stolen: "true", + owner_email: "someemail@stuff.com", + creation_organization_id: organization.id.to_s, }, stolen_record: { - phone_no_show: 'true', - phone: '7183839292' - } + phone_no_show: "true", + phone: "7183839292", + }, } end let(:b_param) { FactoryBot.create(:b_param, params: b_param_attrs) } - it 'renders' do + it "renders" do expect(b_param).to be_present get :embed, id: organization.slug, b_param_id_token: b_param.id_token - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(response).to render_template(:embed) - expect(response.headers['X-Frame-Options']).not_to be_present + expect(response.headers["X-Frame-Options"]).not_to be_present expect(assigns(:stolen)).to be_truthy bike = assigns(:bike) expect(bike.stolen).to be_truthy @@ -144,24 +144,24 @@ end end - describe 'connect_lightspeed' do - context 'with user with organization' do + describe "connect_lightspeed" do + context "with user with organization" do include_context :logged_in_as_organization_admin - it 'redirects to posintegration' do + it "redirects to posintegration" do get :connect_lightspeed - expect(response).to redirect_to 'https://posintegration.bikeindex.org' + expect(response).to redirect_to "https://posintegration.bikeindex.org" end end - context 'with user without organization' do + context "with user without organization" do include_context :logged_in_as_user - it 'redirects to posintegration' do + it "redirects to posintegration" do get :connect_lightspeed expect(flash[:info]).to match(/organization/) expect(response).to redirect_to new_organization_path end end - context 'without user' do - it 'redirects to posintegration' do + context "without user" do + it "redirects to posintegration" do get :connect_lightspeed expect(response).to redirect_to new_user_path expect(flash[:info]).to match(/sign up/) diff --git a/spec/controllers/organized/bikes_controller_spec.rb b/spec/controllers/organized/bikes_controller_spec.rb index 1645d6fa58..904592900a 100644 --- a/spec/controllers/organized/bikes_controller_spec.rb +++ b/spec/controllers/organized/bikes_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe Organized::BikesController, type: :controller do let(:non_organization_bike) { FactoryBot.create(:bike) } @@ -23,59 +23,59 @@ get :index, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template :index - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization - expect(assigns(:page_id)).to eq 'organized_bikes_index' + expect(assigns(:page_id)).to eq "organized_bikes_index" expect(assigns(:current_organization)).to eq organization expect(session[:current_organization_id]).to eq organization.id end end end - context 'logged_in_as_organization_admin' do + context "logged_in_as_organization_admin" do include_context :logged_in_as_organization_admin - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template :index - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization - expect(assigns(:page_id)).to eq 'organized_bikes_index' + expect(assigns(:page_id)).to eq "organized_bikes_index" end end - describe 'new' do - it 'renders' do + describe "new" do + it "renders" do get :new, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template :new - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization end end end - context 'logged_in_as_organization_member' do + context "logged_in_as_organization_member" do include_context :logged_in_as_organization_member context "paid organization" do before { organization.update_columns(is_paid: true, paid_feature_slugs: %w[bike_search show_recoveries show_partial_registrations]) } # Stub organization having paid feature - describe 'index' do - context 'with params' do + describe "index" do + context "with params" do let(:query_params) do { - query: '1', - manufacturer: '2', + query: "1", + manufacturer: "2", colors: %w(3 4), - location: '5', - distance: '6', - serial: '9', + location: "5", + distance: "6", + serial: "9", query_items: %w(7 8), - stolenness: 'stolen' + stolenness: "stolen", }.as_json end let(:organization_bikes) { organization.bikes } - it 'sends all the params and renders search template to organization_bikes' do + it "sends all the params and renders search template to organization_bikes" do session[:current_organization_id] = "0" # Because, who knows! Maybe they don't have org access at some point. get :index, query_params.merge(organization_id: organization.to_param) expect(response.status).to eq(200) @@ -85,18 +85,18 @@ expect(session[:current_organization_id]).to eq organization.id end end - context 'without params' do - it 'renders, assigns search_query_present and stolenness all' do + context "without params" do + it "renders, assigns search_query_present and stolenness all" do get :index, organization_id: organization.to_param expect(response.status).to eq(200) - expect(assigns(:interpreted_params)[:stolenness]).to eq 'all' + expect(assigns(:interpreted_params)[:stolenness]).to eq "all" expect(assigns(:active_organization)).to eq organization expect(assigns(:search_query_present)).to be_falsey expect(assigns(:bikes).pluck(:id).include?(non_organization_bike.id)).to be_falsey end end end - describe 'recoveries' do + describe "recoveries" do let(:bike) { FactoryBot.create(:stolen_bike) } let(:bike2) { FactoryBot.create(:stolen_bike) } let(:recovered_record) { bike.find_current_stolen_record } @@ -106,17 +106,17 @@ let(:date) { "2016-01-10 13:59:59" } let(:recovery_information) do { - recovered_description: 'recovered it on a special corner', + recovered_description: "recovered it on a special corner", index_helped_recovery: true, can_share_recovery: true, - date_recovered: "2016-01-10 13:59:59" + date_recovered: "2016-01-10 13:59:59", } end before do recovered_record.add_recovery_information recovered_record2.add_recovery_information(recovery_information) end - it 'renders, assigns search_query_present and stolenness all' do + it "renders, assigns search_query_present and stolenness all" do expect(recovered_record2.date_recovered.to_date).to eq Date.parse("2016-01-10") get :recoveries, organization_id: organization.to_param expect(response.status).to eq(200) @@ -130,7 +130,7 @@ manufacturer_id: Manufacturer.other.id, primary_frame_color_id: Color.black.id, owner_email: "something@stuff.com", - creation_organization_id: organization.id + creation_organization_id: organization.id, } end let!(:partial_registration) { BParam.create(params: { bike: partial_reg_attrs }, origin: "embed_partial") } @@ -161,7 +161,7 @@ end end end - context 'unpaid organization' do + context "unpaid organization" do before do expect(organization.is_paid).to be_falsey end @@ -190,12 +190,12 @@ end end - describe 'new' do - it 'renders' do + describe "new" do + it "renders" do get :new, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template :new - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization end end diff --git a/spec/controllers/organized/exports_controller_spec.rb b/spec/controllers/organized/exports_controller_spec.rb index 9b3ad1d696..77e35ad41b 100644 --- a/spec/controllers/organized/exports_controller_spec.rb +++ b/spec/controllers/organized/exports_controller_spec.rb @@ -147,7 +147,7 @@ end_at: nil, file_format: "xlsx", timezone: "America/Los Angeles", - headers: %w[link registered_at manufacturer model registered_by] + headers: %w[link registered_at manufacturer model registered_by], } end let(:avery_params) { valid_attrs.merge(end_at: "2016-03-08 02:00:00", avery_export: true, bike_code_start: "a221C ") } @@ -204,7 +204,7 @@ timezone: "", file_format: "csv", bike_code_start: "01", # Avery export organizations always submit a number here - headers: %w[link registered_at] + Export.additional_registration_fields.values + headers: %w[link registered_at] + Export.additional_registration_fields.values, } end it "creates the expected export" do @@ -251,7 +251,7 @@ expect(flash[:error]).to match(/sticker/) end end - end + end end end diff --git a/spec/controllers/organized/manage_controller_spec.rb b/spec/controllers/organized/manage_controller_spec.rb index f85c093522..22931fe29a 100644 --- a/spec/controllers/organized/manage_controller_spec.rb +++ b/spec/controllers/organized/manage_controller_spec.rb @@ -1,26 +1,26 @@ -require 'spec_helper' +require "spec_helper" describe Organized::ManageController, type: :controller do - context 'logged_in_as_organization_member' do + context "logged_in_as_organization_member" do include_context :logged_in_as_organization_member - describe 'index' do - it 'redirects' do + describe "index" do + it "redirects" do get :index, organization_id: organization.to_param expect(response.location).to match(organization_bikes_path(organization_id: organization.to_param)) expect(flash[:error]).to be_present end end - describe 'locations' do - it 'redirects' do + describe "locations" do + it "redirects" do get :locations, organization_id: organization.to_param expect(response.location).to match(organization_bikes_path(organization_id: organization.to_param)) expect(flash[:error]).to be_present end end - describe 'standard organization' do - it 'does not destroy' do + describe "standard organization" do + it "does not destroy" do expect do delete :destroy, id: organization.id, organization_id: organization.to_param end.to change(Organization, :count).by(0) @@ -29,45 +29,45 @@ end end end - context 'logged_in_as_organization_admin' do + context "logged_in_as_organization_admin" do include_context :logged_in_as_organization_admin - describe 'index' do - it 'renders, sets active organization' do + describe "index" do + it "renders, sets active organization" do session[:current_organization_id] = "XXXYYY" get :index, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template :index - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization expect(assigns(:current_organization)).to eq organization expect(session[:current_organization_id]).to eq organization.id end end - describe 'landing' do - it 'renders' do + describe "landing" do + it "renders" do session[:current_organization_id] = "XXXYYY" get :landing, organization_id: organization.to_param expect(response.status).to eq(200) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization expect(assigns(:current_organization)).to eq organization expect(session[:current_organization_id]).to eq organization.id end end - describe 'locations' do - it 'renders' do + describe "locations" do + it "renders" do get :locations, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template :locations - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization end end - describe 'update' do - context 'dissallowed attributes' do + describe "update" do + context "dissallowed attributes" do let(:org_attributes) do { available_invitation_count: 10, @@ -77,32 +77,32 @@ auto_user_id: user.id, show_on_map: false, api_access_approved: false, - access_token: 'stuff7', - new_bike_notification: 'stuff8', + access_token: "stuff7", + new_bike_notification: "stuff8", lock_show_on_map: true, - is_paid: false + is_paid: false, } end let(:user_2) { FactoryBot.create(:organization_member, organization: organization) } let(:update_attributes) do { # slug: 'short_name', - slug: 'cool name and stuffffff', - available_invitation_count: '20', - sent_invitation_count: '0', + slug: "cool name and stuffffff", + available_invitation_count: "20", + sent_invitation_count: "0", is_suspended: true, auto_user_id: user.id, embedable_user_email: user_2.email, api_access_approved: true, - access_token: 'things7', - new_bike_notification: 'things8', - website: ' www.drseuss.org', - name: 'some new name', - kind: 'bike_shop', + access_token: "things7", + new_bike_notification: "things8", + website: " www.drseuss.org", + name: "some new name", + kind: "bike_shop", is_paid: true, lock_show_on_map: false, show_on_map: true, - locations_attributes: [] + locations_attributes: [], } end # Website is also permitted, but we're manually setting it @@ -111,7 +111,7 @@ expect(user_2).to be_present organization.update_attributes(org_attributes) end - it 'updates, sends message about maps' do + it "updates, sends message about maps" do put :update, organization_id: organization.to_param, id: organization.to_param, organization: update_attributes expect(response).to redirect_to organization_manage_index_path(organization_id: organization.to_param) expect(flash[:success]).to be_present @@ -122,55 +122,55 @@ end # Test that the website and auto_user_id are set correctly expect(organization.auto_user_id).to eq user_2.id - expect(organization.website).to eq('http://www.drseuss.org') + expect(organization.website).to eq("http://www.drseuss.org") # Ensure we're protecting the correct attributes org_attributes.except(*permitted_update_keys).each do |key, value| expect(organization.send(key)).to eq value end end end - context 'with locations and normal show_on_map' do + context "with locations and normal show_on_map" do let(:state) { FactoryBot.create(:state) } let(:country) { state.country } - let(:location_1) { FactoryBot.create(:location, organization: organization, street: 'old street', name: 'cool name') } + let(:location_1) { FactoryBot.create(:location, organization: organization, street: "old street", name: "cool name") } let(:update_attributes) do { name: organization.name, show_on_map: true, - kind: 'bike_shop', + kind: "bike_shop", locations_attributes: { - '0' => { + "0" => { id: location_1.id, - name: 'First shop', - zipcode: '2222222', - city: 'First city', + name: "First shop", + zipcode: "2222222", + city: "First city", state_id: state.id, country_id: country.id, - street: 'some street 2', - phone: '7272772727272', - email: 'stuff@goooo.com', + street: "some street 2", + phone: "7272772727272", + email: "stuff@goooo.com", latitude: 22_222, longitude: 11_111, organization_id: 844, shown: false, - _destroy: 0 + _destroy: 0, }, Time.zone.now.to_i.to_s => { created_at: Time.zone.now.to_f.to_s, - name: 'Second shop', - zipcode: '12243444', - city: 'cool city', + name: "Second shop", + zipcode: "12243444", + city: "cool city", state_id: state.id, country_id: country.id, - street: 'some street 2', - phone: '7272772727272', - email: 'stuff@goooo.com', + street: "some street 2", + phone: "7272772727272", + email: "stuff@goooo.com", latitude: 22_222, longitude: 11_111, organization_id: 844, - shown: false - } - } + shown: false, + }, + }, } end before do @@ -178,8 +178,8 @@ expect(organization.show_on_map).to be_falsey expect(organization.lock_show_on_map).to be_falsey end - context 'update' do - it 'updates and adds the locations and shows on map' do + context "update" do + it "updates and adds the locations and shows on map" do expect do put :update, organization_id: organization.to_param, id: organization.to_param, organization: update_attributes end.to change(Location, :count).by 1 @@ -188,11 +188,11 @@ # Existing location is updated location_1.reload expect(location_1.organization).to eq organization - update_attributes[:locations_attributes]['0'].except(:latitude, :longitude, :organization_id, :shown, :created_at, :_destroy).each do |k, v| + update_attributes[:locations_attributes]["0"].except(:latitude, :longitude, :organization_id, :shown, :created_at, :_destroy).each do |k, v| expect(location_1.send(k)).to eq v end # ensure we are not permitting crazy assignment for first location - update_attributes[:locations_attributes]['0'].slice(:latitude, :longitude, :organization_id, :shown).each do |k, v| + update_attributes[:locations_attributes]["0"].slice(:latitude, :longitude, :organization_id, :shown).each do |k, v| expect(location_1.send(k)).to_not eq v end @@ -208,10 +208,10 @@ end end end - context 'remove' do - it 'removes the location' do + context "remove" do + it "removes the location" do # update_attributes = update_attributes.dup - update_attributes[:locations_attributes]['0'][:_destroy] = 1 + update_attributes[:locations_attributes]["0"][:_destroy] = 1 expect do put :update, organization_id: organization.to_param, id: organization.to_param, organization: update_attributes end.to change(Location, :count).by 0 @@ -221,10 +221,10 @@ end end - describe 'destroy' do - context 'standard organization' do - it 'destroys' do - expect_any_instance_of(AdminNotifier).to receive(:for_organization).with(organization: organization, user: user, type: 'organization_destroyed') + describe "destroy" do + context "standard organization" do + it "destroys" do + expect_any_instance_of(AdminNotifier).to receive(:for_organization).with(organization: organization, user: user, type: "organization_destroyed") expect do delete :destroy, id: organization.id, organization_id: organization.to_param end.to change(Organization, :count).by(-1) @@ -232,8 +232,8 @@ expect(flash[:info]).to be_present end end - context 'paid organization' do - it 'does not destroy' do + context "paid organization" do + it "does not destroy" do organization.update_attribute :is_paid, true expect do delete :destroy, id: organization.id, organization_id: organization.to_param diff --git a/spec/controllers/organized/messages_controller_spec.rb b/spec/controllers/organized/messages_controller_spec.rb index 469408bd9d..38740e83f5 100644 --- a/spec/controllers/organized/messages_controller_spec.rb +++ b/spec/controllers/organized/messages_controller_spec.rb @@ -19,7 +19,7 @@ bike_id: bike.to_param, latitude: default_location[:latitude], longitude: default_location[:longitude], - accuracy: 12 + accuracy: 12, } end diff --git a/spec/controllers/organized/users_controller_spec.rb b/spec/controllers/organized/users_controller_spec.rb index d17b21f940..a0969c718a 100644 --- a/spec/controllers/organized/users_controller_spec.rb +++ b/spec/controllers/organized/users_controller_spec.rb @@ -1,36 +1,36 @@ -require 'spec_helper' +require "spec_helper" describe Organized::UsersController, type: :controller do - context 'logged_in_as_organization_member' do + context "logged_in_as_organization_member" do include_context :logged_in_as_organization_member - describe 'index' do - it 'redirects' do + describe "index" do + it "redirects" do get :index, organization_id: organization.to_param expect(response.location).to match(organization_bikes_path(organization_id: organization.to_param)) expect(flash[:error]).to be_present end end - describe 'new' do - it 'redirects' do + describe "new" do + it "redirects" do get :new, organization_id: organization.to_param expect(response.location).to match(organization_bikes_path(organization_id: organization.to_param)) expect(flash[:error]).to be_present end end - describe 'update' do - context 'organization_invitation' do + describe "update" do + context "organization_invitation" do let(:organization_invitation) { FactoryBot.create(:organization_invitation, organization: organization, inviter: user) } let(:organization_invitation_params) do { - membership_role: 'admin', - name: 'something', + membership_role: "admin", + name: "something", inviter_id: 333, - invitee_email: 'new_bike_email@bike_shop.com' + invitee_email: "new_bike_email@bike_shop.com", } end - it 'does not update' do + it "does not update" do organization_invitation.invitee_email expect do put :update, organization_id: organization.to_param, @@ -40,67 +40,67 @@ expect(response.location).to match(organization_bikes_path(organization_id: organization.to_param)) expect(flash[:error]).to be_present organization_invitation.reload - expect(organization_invitation.membership_role).to eq 'member' + expect(organization_invitation.membership_role).to eq "member" end end end end - context 'logged_in_as_organization_admin' do + context "logged_in_as_organization_admin" do include_context :logged_in_as_organization_admin - describe 'index' do - it 'renders' do + describe "index" do + it "renders" do get :index, organization_id: organization.to_param expect(response.status).to eq(200) expect(response).to render_template :index - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:active_organization)).to eq organization end end - describe 'new' do - it 'renders the page' do + describe "new" do + it "renders the page" do get :new, organization_id: organization.to_param - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(response).to render_template :new - expect(response).to render_with_layout 'application_revised' + expect(response).to render_with_layout "application_revised" end end - describe 'edit' do - context 'membership' do + describe "edit" do + context "membership" do let(:membership) { FactoryBot.create(:existing_membership, organization: organization) } - it 'renders the page' do + it "renders the page" do get :edit, organization_id: organization.to_param, id: membership.id expect(assigns(:membership)).to eq membership - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(response).to render_template :edit - expect(response).to render_with_layout 'application_revised' + expect(response).to render_with_layout "application_revised" end end - context 'organization_invitation' do + context "organization_invitation" do let(:invitation) { FactoryBot.create(:organization_invitation, organization: organization) } - it 'renders the page' do + it "renders the page" do get :edit, organization_id: organization.to_param, id: invitation.id, is_invitation: true expect(assigns(:organization_invitation)).to eq invitation - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(response).to render_template :edit - expect(response).to render_with_layout 'application_revised' + expect(response).to render_with_layout "application_revised" end end end - describe 'update' do - context 'organization_invitation' do + describe "update" do + context "organization_invitation" do let(:organization_invitation) { FactoryBot.create(:organization_invitation, organization: organization, inviter: user) } let(:organization_invitation_params) do { - membership_role: 'admin', - name: 'something', + membership_role: "admin", + name: "something", inviter_id: 333, - invitee_email: 'new_bike_email@bike_shop.com' + invitee_email: "new_bike_email@bike_shop.com", } end - it 'updates name and role, ignores email' do + it "updates name and role, ignores email" do og_email = organization_invitation.invitee_email expect do put :update, organization_id: organization.to_param, @@ -110,46 +110,46 @@ expect(response).to redirect_to organization_users_path(organization_id: organization.to_param) expect(flash[:success]).to be_present organization_invitation.reload - expect(organization_invitation.membership_role).to eq 'admin' - expect(organization_invitation.invitee_name).to eq 'something' + expect(organization_invitation.membership_role).to eq "admin" + expect(organization_invitation.invitee_name).to eq "something" expect(organization_invitation.inviter).to eq user expect(organization_invitation.invitee_email).to eq og_email end end - context 'membership' do - context 'other valid membership' do - let(:membership) { FactoryBot.create(:existing_membership, organization: organization, role: 'member') } - let(:membership_params) { { role: 'admin', user_id: 333 } } - it 'updates the role' do + context "membership" do + context "other valid membership" do + let(:membership) { FactoryBot.create(:existing_membership, organization: organization, role: "member") } + let(:membership_params) { { role: "admin", user_id: 333 } } + it "updates the role" do og_user = membership.user put :update, organization_id: organization.to_param, id: membership.id, membership: membership_params expect(response).to redirect_to organization_users_path(organization_id: organization.to_param) expect(flash[:success]).to be_present membership.reload - expect(membership.role).to eq 'admin' + expect(membership.role).to eq "admin" expect(membership.user).to eq og_user end end - context 'marking self member' do + context "marking self member" do let(:membership) { user.memberships.first } - it 'does not update the membership' do + it "does not update the membership" do put :update, organization_id: organization.to_param, id: membership.id, - membership: { role: 'member' } + membership: { role: "member" } expect(response).to redirect_to organization_users_path(organization_id: organization.to_param) expect(flash[:error]).to be_present membership.reload - expect(membership.role).to eq 'admin' + expect(membership.role).to eq "admin" expect(membership.user).to eq user end end end end - describe 'destroy' do - context 'organization_invitation' do + describe "destroy" do + context "organization_invitation" do let(:organization_invitation) { FactoryBot.create(:organization_invitation, organization: organization, inviter: user) } - it 'destroys' do + it "destroys" do expect(organization_invitation).to be_present count = organization.available_invitation_count expect do @@ -162,10 +162,10 @@ expect(organization.available_invitation_count).to eq(count + 1) end end - context 'membership' do - context 'other valid membership' do - let(:membership) { FactoryBot.create(:existing_membership, organization: organization, role: 'member') } - it 'destroys the membership' do + context "membership" do + context "other valid membership" do + let(:membership) { FactoryBot.create(:existing_membership, organization: organization, role: "member") } + it "destroys the membership" do expect(membership).to be_present count = organization.available_invitation_count expect do @@ -177,9 +177,9 @@ expect(organization.available_invitation_count).to eq(count + 1) end end - context 'marking self member' do + context "marking self member" do let(:membership) { user.memberships.first } - it 'does not destroy' do + it "does not destroy" do count = organization.available_invitation_count expect do delete :destroy, organization_id: organization.to_param, id: membership.id @@ -193,16 +193,16 @@ end end - describe 'create' do + describe "create" do let(:organization_invitation_params) do { - membership_role: 'member', - invitee_name: 'cool', - invitee_email: 'bike_email@bike_shop.com' + membership_role: "member", + invitee_name: "cool", + invitee_email: "bike_email@bike_shop.com", } end - context 'available invitations' do - it 'creates organization_invitation, reduces invitation tokens by 1' do + context "available invitations" do + it "creates organization_invitation, reduces invitation tokens by 1" do expect(organization.available_invitation_count).to eq 5 expect do put :create, organization_id: organization.to_param, @@ -213,15 +213,15 @@ organization.reload expect(organization.available_invitation_count).to eq 4 organization_invitation = OrganizationInvitation.last - expect(organization_invitation.membership_role).to eq 'member' + expect(organization_invitation.membership_role).to eq "member" expect(organization_invitation.inviter).to eq user - expect(organization_invitation.invitee_email).to eq 'bike_email@bike_shop.com' - expect(organization_invitation.invitee_name).to eq 'cool' + expect(organization_invitation.invitee_email).to eq "bike_email@bike_shop.com" + expect(organization_invitation.invitee_name).to eq "cool" expect(organization.sent_invitation_count).to eq 1 end end - context 'no available invitations' do - it 'does not create a new organization_invitation' do + context "no available invitations" do + it "does not create a new organization_invitation" do organization.update_attributes(available_invitation_count: 0) expect do put :create, organization_id: organization.to_param, organization_invitation: organization_invitation_params diff --git a/spec/controllers/ownerships_controller_spec.rb b/spec/controllers/ownerships_controller_spec.rb index bafa9a474c..b5a8a41e64 100644 --- a/spec/controllers/ownerships_controller_spec.rb +++ b/spec/controllers/ownerships_controller_spec.rb @@ -1,34 +1,34 @@ -require 'spec_helper' +require "spec_helper" describe OwnershipsController do - describe 'show' do - it 'sets the flash with absent user for create account' do + describe "show" do + it "sets the flash with absent user for create account" do ownership = FactoryBot.create(:ownership) put :show, id: ownership.id expect(response).to redirect_to(:new_user) - expect(flash[:error].match('to claim')).to be_present + expect(flash[:error].match("to claim")).to be_present expect(flash[:error].match(/create an account/i)).to be_present end - it 'sets the flash with sign in for owner exists' do + it "sets the flash with sign in for owner exists" do user = FactoryBot.create(:user) ownership = FactoryBot.create(:ownership, user: user) put :show, id: ownership.id expect(response).to redirect_to(:new_session) - expect(flash[:error].match('to claim')).to be_present + expect(flash[:error].match("to claim")).to be_present expect(flash[:error].match(/sign in/i)).to be_present end - describe 'user present' do + describe "user present" do before :each do @user = FactoryBot.create(:user_confirmed) @ownership = FactoryBot.create(:ownership) set_current_user(@user) end - it 'redirects and not change the ownership' do + it "redirects and not change the ownership" do put :show, id: @ownership.id - expect(response.code).to eq('302') + expect(response.code).to eq("302") expect(flash).to be_present expect(@ownership.reload.claimed).to be_falsey end @@ -36,15 +36,15 @@ it "redirects and not change the ownership if it isn't current" do @ownership.update_attributes(owner_email: @user.email, current: false) put :show, id: @ownership.id - expect(response.code).to eq('302') + expect(response.code).to eq("302") expect(flash).to be_present expect(@ownership.reload.claimed).to be_falsey end - it 'redirects and mark current based on fuzzy find' do + it "redirects and mark current based on fuzzy find" do @ownership.update_attributes(owner_email: @user.email.upcase) put :show, id: @ownership.id - expect(response.code).to eq('302') + expect(response.code).to eq("302") expect(response).to redirect_to edit_bike_url(@ownership.bike) expect(flash).to be_present expect(@ownership.reload.claimed).to be_truthy diff --git a/spec/controllers/payments_controller_spec.rb b/spec/controllers/payments_controller_spec.rb index 5c109b96bb..5a8fc3dc5e 100644 --- a/spec/controllers/payments_controller_spec.rb +++ b/spec/controllers/payments_controller_spec.rb @@ -34,8 +34,8 @@ number: "4242424242424242", exp_month: 12, exp_year: 2025, - cvc: "314" - } + cvc: "314", + }, ) end diff --git a/spec/controllers/public_images_controller_spec.rb b/spec/controllers/public_images_controller_spec.rb index 4d38259707..51c98813a4 100644 --- a/spec/controllers/public_images_controller_spec.rb +++ b/spec/controllers/public_images_controller_spec.rb @@ -1,94 +1,94 @@ -require 'spec_helper' +require "spec_helper" describe PublicImagesController do - describe 'create' do - context 'bike' do + describe "create" do + context "bike" do let(:ownership) { FactoryBot.create(:ownership) } let(:bike) { ownership.bike } let(:user) { ownership.creator } - context 'valid owner' do - it 'creates an image' do + context "valid owner" do + it "creates an image" do set_current_user(user) - post :create, bike_id: bike.id, public_image: { name: 'cool name' }, format: :js + post :create, bike_id: bike.id, public_image: { name: "cool name" }, format: :js bike.reload - expect(bike.public_images.first.name).to eq 'cool name' + expect(bike.public_images.first.name).to eq "cool name" # TODO: Rails 5 update - after commit doesn't run :(, commented out until that change happens # expect(AfterBikeSaveWorker).to have_enqueued_sidekiq_job(bike.id) end end - context 'no user' do - it 'does not create an image' do + context "no user" do + it "does not create an image" do expect do - post :create, bike_id: bike.id, public_image: { name: 'cool name' }, format: :js - expect(response.code).to eq('401') + post :create, bike_id: bike.id, public_image: { name: "cool name" }, format: :js + expect(response.code).to eq("401") end.to change(PublicImage, :count).by 0 end end end - context 'blog' do + context "blog" do let(:blog) { FactoryBot.create(:blog) } - context 'admin authorized' do - it 'creates an image' do + context "admin authorized" do + it "creates an image" do user = FactoryBot.create(:admin) set_current_user(user) - post :create, blog_id: blog.id, public_image: { name: 'cool name' }, format: :js + post :create, blog_id: blog.id, public_image: { name: "cool name" }, format: :js blog.reload - expect(blog.public_images.first.name).to eq 'cool name' + expect(blog.public_images.first.name).to eq "cool name" end end - context 'not admin' do - it 'does not create an image' do + context "not admin" do + it "does not create an image" do set_current_user(FactoryBot.create(:user_confirmed)) expect do - post :create, blog_id: blog.id, public_image: { name: 'cool name' }, format: :js - expect(response.code).to eq('401') + post :create, blog_id: blog.id, public_image: { name: "cool name" }, format: :js + expect(response.code).to eq("401") end.to change(PublicImage, :count).by 0 end end end - context 'organization' do + context "organization" do let(:organization) { FactoryBot.create(:organization) } - context 'admin authorized' do + context "admin authorized" do include_context :logged_in_as_super_admin - it 'creates an image' do - post :create, organization_id: organization.to_param, public_image: { name: 'cool name' }, format: :js + it "creates an image" do + post :create, organization_id: organization.to_param, public_image: { name: "cool name" }, format: :js organization.reload - expect(organization.public_images.first.name).to eq 'cool name' + expect(organization.public_images.first.name).to eq "cool name" end end - context 'not admin' do + context "not admin" do include_context :logged_in_as_user - it 'does not create an image' do + it "does not create an image" do expect do - post :create, organization_id: organization.to_param, public_image: { name: 'cool name' }, format: :js - expect(response.code).to eq('401') + post :create, organization_id: organization.to_param, public_image: { name: "cool name" }, format: :js + expect(response.code).to eq("401") end.to change(PublicImage, :count).by 0 end end end - context 'mail_snippet' do + context "mail_snippet" do let(:mail_snippet) { FactoryBot.create(:mail_snippet) } - context 'admin authorized' do + context "admin authorized" do include_context :logged_in_as_super_admin - it 'creates an image' do - post :create, mail_snippet_id: mail_snippet.to_param, public_image: { name: 'cool name' }, format: :js + it "creates an image" do + post :create, mail_snippet_id: mail_snippet.to_param, public_image: { name: "cool name" }, format: :js mail_snippet.reload - expect(mail_snippet.public_images.first.name).to eq 'cool name' + expect(mail_snippet.public_images.first.name).to eq "cool name" end end - context 'not signed in' do - it 'does not create an image' do + context "not signed in" do + it "does not create an image" do expect do - post :create, organization_id: mail_snippet.to_param, public_image: { name: 'cool name' }, format: :js - expect(response.code).to eq('401') + post :create, organization_id: mail_snippet.to_param, public_image: { name: "cool name" }, format: :js + expect(response.code).to eq("401") end.to change(PublicImage, :count).by 0 end end end end - describe 'destroy' do - context 'with owner' do - it 'allows the destroy of public_image' do + describe "destroy" do + context "with owner" do + it "allows the destroy of public_image" do user = FactoryBot.create(:user_confirmed) bike = FactoryBot.create(:bike) FactoryBot.create(:ownership, bike: bike, creator: user, owner_email: user.email) @@ -99,11 +99,11 @@ delete :destroy, id: public_image.id end.to change(PublicImage, :count).by(-1) end - context 'non owner' do - it 'rejects the destroy' do + context "non owner" do + it "rejects the destroy" do ownership = FactoryBot.create(:ownership) bike = ownership.bike - non_owner = FactoryBot.create(:user_confirmed, name: 'Non Owner') + non_owner = FactoryBot.create(:user_confirmed, name: "Non Owner") public_image = FactoryBot.create(:public_image, imageable: bike) set_current_user(non_owner) expect do @@ -111,8 +111,8 @@ end.not_to change(PublicImage, :count) end end - context 'owner and hidden bike' do - it 'allows the destroy' do + context "owner and hidden bike" do + it "allows the destroy" do user = FactoryBot.create(:user_confirmed) bike = FactoryBot.create(:bike, hidden: true) FactoryBot.create(:ownership, bike: bike, creator: user, owner_email: user.email) @@ -120,14 +120,14 @@ expect(bike.reload.owner).to eq(user) set_current_user(user) expect do - delete :destroy, id: public_image.id, page: 'redirect_page' + delete :destroy, id: public_image.id, page: "redirect_page" end.to change(PublicImage, :count).by(-1) - expect(response).to redirect_to(edit_bike_path(bike, page: 'redirect_page')) + expect(response).to redirect_to(edit_bike_path(bike, page: "redirect_page")) end end end - context 'with owner' do - it 'allows a the owner of a public_image to destroy the public_image' do + context "with owner" do + it "allows a the owner of a public_image to destroy the public_image" do user = FactoryBot.create(:user_confirmed) bike = FactoryBot.create(:bike) FactoryBot.create(:ownership, bike: bike, creator: user, owner_email: user.email) @@ -135,85 +135,85 @@ expect(bike.reload.owner).to eq(user) set_current_user(user) expect do - delete :destroy, id: public_image.id, page: 'redirect_page' + delete :destroy, id: public_image.id, page: "redirect_page" end.to change(PublicImage, :count).by(-1) - expect(response).to redirect_to(edit_bike_path(bike, page: 'redirect_page')) + expect(response).to redirect_to(edit_bike_path(bike, page: "redirect_page")) end end end - describe 'show' do - it 'renders' do + describe "show" do + it "renders" do image = FactoryBot.create(:public_image) get :show, id: image.id - expect(response.code).to eq('200') - expect(response).to render_template('show') + expect(response.code).to eq("200") + expect(response).to render_template("show") expect(flash).to_not be_present end end - describe 'edit' do - it 'renders' do + describe "edit" do + it "renders" do ownership = FactoryBot.create(:ownership) user = ownership.owner set_current_user(user) image = FactoryBot.create(:public_image, imageable: ownership.bike) get :edit, id: image.id - expect(response.code).to eq('200') - expect(response).to render_template('edit') + expect(response.code).to eq("200") + expect(response).to render_template("edit") expect(flash).to_not be_present end end - describe 'update' do - context 'normal update' do - context 'with owner' do - it 'updates things and go back to editing the bike' do + describe "update" do + context "normal update" do + context "with owner" do + it "updates things and go back to editing the bike" do user = FactoryBot.create(:user_confirmed) bike = FactoryBot.create(:bike) FactoryBot.create(:ownership, bike: bike, creator: user, owner_email: user.email) public_image = FactoryBot.create(:public_image, imageable: bike) expect(bike.reload.owner).to eq(user) set_current_user(user) - put :update, id: public_image.id, public_image: { name: 'Food' } + put :update, id: public_image.id, public_image: { name: "Food" } expect(response).to redirect_to(edit_bike_url(bike)) - expect(public_image.reload.name).to eq('Food') + expect(public_image.reload.name).to eq("Food") # ensure enqueueing after this end end - context 'not owner' do - it 'does not update' do + context "not owner" do + it "does not update" do user = FactoryBot.create(:user_confirmed) bike = FactoryBot.create(:bike) FactoryBot.create(:ownership, bike: bike) - public_image = FactoryBot.create(:public_image, imageable: bike, name: 'party') + public_image = FactoryBot.create(:public_image, imageable: bike, name: "party") set_current_user(user) - put :update, id: public_image.id, public_image: { name: 'Food' } - expect(public_image.reload.name).to eq('party') + put :update, id: public_image.id, public_image: { name: "Food" } + expect(public_image.reload.name).to eq("party") end end end end - describe 'is_private' do + describe "is_private" do let(:user) { FactoryBot.create(:user_confirmed) } let(:bike) { FactoryBot.create(:bike) } - context 'with owner' do - context 'is_private true' do - it 'marks image private' do + context "with owner" do + context "is_private true" do + it "marks image private" do FactoryBot.create(:ownership, bike: bike, creator: user, owner_email: user.email) public_image = FactoryBot.create(:public_image, imageable: bike) expect(bike.reload.owner).to eq(user) set_current_user(user) - post :is_private, id: public_image.id, is_private: 'true' + post :is_private, id: public_image.id, is_private: "true" public_image.reload expect(public_image.is_private).to be_truthy # TODO: Rails 5 update - after commit doesn't run :(, commented out until that is enabled # expect(AfterBikeSaveWorker).to have_enqueued_sidekiq_job(bike.id) end end - context 'is_private false' do - it 'marks bike not private' do + context "is_private false" do + it "marks bike not private" do FactoryBot.create(:ownership, bike: bike, creator: user, owner_email: user.email) public_image = FactoryBot.create(:public_image, imageable: bike, is_private: true) expect(bike.reload.owner).to eq(user) @@ -226,18 +226,18 @@ end end end - context 'non owner' do - it 'does not update' do + context "non owner" do + it "does not update" do FactoryBot.create(:ownership, bike: bike) - public_image = FactoryBot.create(:public_image, imageable: bike, name: 'party') + public_image = FactoryBot.create(:public_image, imageable: bike, name: "party") set_current_user(user) - post :is_private, id: public_image.id, is_private: 'true' + post :is_private, id: public_image.id, is_private: "true" expect(public_image.is_private).to be_falsey end end end - describe 'order' do + describe "order" do let(:bike) { FactoryBot.create(:bike) } let(:ownership) { FactoryBot.create(:ownership, bike: bike) } let(:user) { ownership.creator } @@ -247,7 +247,7 @@ let(:public_image_3) { FactoryBot.create(:public_image, imageable: bike, listing_order: 3) } let(:public_image_other) { FactoryBot.create(:public_image, imageable: other_ownership.bike, listing_order: 0) } - it 'updates the listing order' do + it "updates the listing order" do expect([public_image_1, public_image_2, public_image_3, public_image_other]).to be_present public_image_other.reload expect(public_image_other.listing_order).to eq 0 diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 51881c85c9..be413784a4 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe RegistrationsController do let(:user) { FactoryBot.create(:user_confirmed) } @@ -6,29 +6,29 @@ let(:organization) { auto_user.organizations.first } let(:renders_embed_without_xframe) do expect(response.status).to eq(200) - expect(response).to render_with_layout('reg_embed') - expect(response.headers['X-Frame-Options']).not_to be_present + expect(response).to render_with_layout("reg_embed") + expect(response.headers["X-Frame-Options"]).not_to be_present expect(flash).to_not be_present end - describe 'new' do - it 'renders with the embeded form, no xframing' do + describe "new" do + it "renders with the embeded form, no xframing" do set_current_user(user) get :new, organization_id: organization.id, stolen: true expect(response).to render_template(:new) expect(response.status).to eq(200) - expect(response).to render_with_layout('application_revised') - expect(response.headers['X-Frame-Options']).to be_present + expect(response).to render_with_layout("application_revised") + expect(response.headers["X-Frame-Options"]).to be_present expect(flash).to_not be_present end end - describe 'embed' do + describe "embed" do let(:expect_it_to_render_correctly) do renders_embed_without_xframe expect(response).to render_template(:embed) end - context 'no organization' do - context 'no user' do - it 'renders' do + context "no organization" do + context "no user" do + it "renders" do get :embed, stolen: true expect_it_to_render_correctly expect(assigns(:stolen)).to be_truthy @@ -36,8 +36,8 @@ expect(assigns(:owner_email)).to be_nil end end - context 'with user' do - it 'renders does not set creator' do + context "with user" do + it "renders does not set creator" do set_current_user(user) get :embed expect_it_to_render_correctly @@ -47,9 +47,9 @@ end end end - context 'with organization' do - context 'no user' do - it 'renders' do + context "with organization" do + context "no user" do + it "renders" do get :embed, organization_id: organization.to_param, simple_header: true, select_child_organization: true expect_it_to_render_correctly expect(assigns(:stolen)).to eq 0 @@ -61,13 +61,13 @@ body = response.body # creation_organization creator_organization_input = body[/value=.*id..b_param_creation_organization_id/i] - creator_organization_value = creator_organization_input.gsub(/value=./, '').match(/\A[^\"]*/)[0] + creator_organization_value = creator_organization_input.gsub(/value=./, "").match(/\A[^\"]*/)[0] expect(creator_organization_value).to eq organization.id.to_s end end - context 'with user' do + context "with user" do let!(:organization_child) { FactoryBot.create(:organization, parent_organization_id: organization.id) } - it 'renders, testing variables' do + it "renders, testing variables" do set_current_user(user) get :embed, organization_id: organization.id, stolen: true, select_child_organization: true expect_it_to_render_correctly @@ -75,7 +75,7 @@ body = response.body # Owner email owner_email_input = body[/value=.*id..b_param_owner_email*/i] - email_value = owner_email_input.gsub(/value=./, '').match(/\A[^\"]*/)[0] + email_value = owner_email_input.gsub(/value=./, "").match(/\A[^\"]*/)[0] expect(email_value).to eq user.email expect(assigns(:simple_header)).to be_falsey @@ -89,12 +89,12 @@ end end end - describe 'create' do + describe "create" do let(:manufacturer) { FactoryBot.create(:manufacturer) } let(:color) { FactoryBot.create(:color) } - context 'invalid creation' do - context 'email not set, sets simple_header' do - it 'does not create a bparam, rerenders new with all assigned values' do + context "invalid creation" do + context "email not set, sets simple_header" do + it "does not create a bparam, rerenders new with all assigned values" do attrs = { manufacturer_id: manufacturer.id, stolen: true, @@ -102,7 +102,7 @@ primary_frame_color_id: color.id, secondary_frame_color_id: 12, tertiary_frame_color_id: 222, - creation_organization_id: 9292 + creation_organization_id: 9292, } expect do post :create, simple_header: true, b_param: attrs @@ -115,36 +115,36 @@ expect(b_param.send(key).to_s).to eq value.to_s end expect(b_param.creator_id).to be_nil - expect(b_param.origin).to eq 'embed_partial' + expect(b_param.origin).to eq "embed_partial" end end end - context 'valid creation' do + context "valid creation" do let(:expect_it_to_render_correctly) do renders_embed_without_xframe expect(response).to render_template(:create) end - context 'nothing except email set' do - it 'creates a new bparam and renders' do - post :create, b_param: { owner_email: 'something@stuff.com' }, simple_header: true + context "nothing except email set" do + it "creates a new bparam and renders" do + post :create, b_param: { owner_email: "something@stuff.com" }, simple_header: true expect_it_to_render_correctly b_param = BParam.last - expect(b_param.owner_email).to eq 'something@stuff.com' - expect(b_param.origin).to eq 'embed_partial' + expect(b_param.owner_email).to eq "something@stuff.com" + expect(b_param.origin).to eq "embed_partial" expect(b_param.partial_registration?).to be_truthy expect(EmailPartialRegistrationWorker).to have_enqueued_sidekiq_job(b_param.id) expect(assigns(:simple_header)).to be_truthy end end - context 'all values set' do - it 'creates a new bparam and renders' do + context "all values set" do + it "creates a new bparam and renders" do attrs = { manufacturer_id: manufacturer.id, primary_frame_color_id: color.id, secondary_frame_color_id: color.id, tertiary_frame_color_id: 222, - owner_email: 'ks78xxxxxx@stuff.com', - creation_organization_id: 21 + owner_email: "ks78xxxxxx@stuff.com", + creation_organization_id: 21, } post :create, b_param: attrs expect_it_to_render_correctly @@ -152,7 +152,7 @@ attrs.each do |key, value| expect(b_param.send(key).to_s).to eq value.to_s end - expect(b_param.origin).to eq 'embed_partial' + expect(b_param.origin).to eq "embed_partial" expect(EmailPartialRegistrationWorker).to have_enqueued_sidekiq_job(b_param.id) expect(b_param.partial_registration?).to be_truthy end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 2a293271cc..4cd6e21b20 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -78,9 +78,9 @@ end end - describe 'create' do + describe "create" do let(:user) { FactoryBot.create(:user_confirmed) } - describe 'when user is found' do + describe "when user is found" do before do expect(User).to receive(:fuzzy_email_find).and_return(user) end @@ -98,10 +98,10 @@ context "admin" do let(:user) { FactoryBot.create(:admin) } - it 'authenticates and redirects to admin' do + it "authenticates and redirects to admin" do expect(user).to receive(:authenticate).and_return(true) - request.env['HTTP_REFERER'] = user_home_url - post :create, session: { password: 'would be correct' } + request.env["HTTP_REFERER"] = user_home_url + post :create, session: { password: "would be correct" } expect(cookies.signed[:auth][1]).to eq(user.auth_token) expect(response).to redirect_to admin_root_url end @@ -109,8 +109,8 @@ it "redirects to discourse_authentication url if it's a valid oauth url" do expect(user).to receive(:authenticate).and_return(true) - session[:discourse_redirect] = 'sso=foo&sig=bar' - post :create, session: { hmmm: 'yeah' } + session[:discourse_redirect] = "sso=foo&sig=bar" + post :create, session: { hmmm: "yeah" } expect(User.from_auth(cookies.signed[:auth])).to eq(user) expect(response).to redirect_to discourse_authentication_url end @@ -118,25 +118,25 @@ it "redirects to return_to if it's a valid oauth url" do expect(user).to receive(:authenticate).and_return(true) session[:return_to] = oauth_authorization_url(cool_thing: true) - post :create, session: { stuff: 'lololol' } + post :create, session: { stuff: "lololol" } expect(User.from_auth(cookies.signed[:auth])).to eq(user) expect(session[:return_to]).to be_nil expect(response).to redirect_to oauth_authorization_url(cool_thing: true) end - it 'redirects to facebook.com/bikeindex' do + it "redirects to facebook.com/bikeindex" do expect(user).to receive(:authenticate).and_return(true) - session[:return_to] = 'https://facebook.com/bikeindex' - post :create, session: { thing: 'asdfasdf' } + session[:return_to] = "https://facebook.com/bikeindex" + post :create, session: { thing: "asdfasdf" } expect(User.from_auth(cookies.signed[:auth])).to eq(user) expect(session[:return_to]).to be_nil - expect(response).to redirect_to 'https://facebook.com/bikeindex' + expect(response).to redirect_to "https://facebook.com/bikeindex" end - it 'does not redirect to a random facebook page' do + it "does not redirect to a random facebook page" do expect(user).to receive(:authenticate).and_return(true) - session[:return_to] = 'https://facebook.com/bikeindex-mean-place' - post :create, session: { thing: 'asdfasdf' } + session[:return_to] = "https://facebook.com/bikeindex-mean-place" + post :create, session: { thing: "asdfasdf" } expect(User.from_auth(cookies.signed[:auth])).to eq(user) expect(session[:return_to]).to be_nil expect(response).to redirect_to user_home_url @@ -145,19 +145,19 @@ it "doesn't redirect and clears the session if not a valid oauth url" do expect(user).to receive(:authenticate).and_return(true) session[:return_to] = "http://testhost.com/bad_place?f=#{oauth_authorization_url(cool_thing: true)}" - post :create, session: { thing: 'asdfasdf' } + post :create, session: { thing: "asdfasdf" } expect(User.from_auth(cookies.signed[:auth])).to eq(user) expect(session[:return_to]).to be_nil expect(response).to redirect_to user_home_url end end - it 'does not authenticate the user when user authentication fails' do + it "does not authenticate the user when user authentication fails" do expect(user).to receive(:authenticate).and_return(false) - post :create, session: { password: 'something incorrect' } + post :create, session: { password: "something incorrect" } expect(session[:user_id]).to be_nil - expect(response).to render_template('new') - expect(response).to render_with_layout('application_revised') + expect(response).to render_template("new") + expect(response).to render_with_layout("application_revised") end context "user is organization admin" do let(:organization) { FactoryBot.create(:organization, kind: organization_kind) } @@ -204,11 +204,11 @@ end end - it 'does not log in the user when the user is not found' do - post :create, session: { email: 'notThere@example.com' } + it "does not log in the user when the user is not found" do + post :create, session: { email: "notThere@example.com" } expect(cookies.signed[:auth]).to be_nil expect(response).to render_template(:new) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end end diff --git a/spec/controllers/stolen_controller_spec.rb b/spec/controllers/stolen_controller_spec.rb index 80b138adfa..dc216bf4ad 100644 --- a/spec/controllers/stolen_controller_spec.rb +++ b/spec/controllers/stolen_controller_spec.rb @@ -1,25 +1,25 @@ -require 'spec_helper' +require "spec_helper" describe StolenController do - describe 'index' do - context 'with subdomain' do - it 'redirects to no subdomain' do - @request.host = 'stolen.example.com' + describe "index" do + context "with subdomain" do + it "redirects to no subdomain" do + @request.host = "stolen.example.com" get :index expect(response).to redirect_to stolen_index_url(subdomain: false) end end - it 'renders with layout even if text' do + it "renders with layout even if text" do get :index, format: :text expect(response.status).to eq(200) expect(response).to render_template(:index) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - describe 'faq' do - it 'redirects other pages to index' do - get :show, id: 'faq' + describe "faq" do + it "redirects other pages to index" do + get :show, id: "faq" expect(response).to redirect_to stolen_index_url end end diff --git a/spec/controllers/stolen_notifications_controller_spec.rb b/spec/controllers/stolen_notifications_controller_spec.rb index 517c06a9c4..af85a70dc6 100644 --- a/spec/controllers/stolen_notifications_controller_spec.rb +++ b/spec/controllers/stolen_notifications_controller_spec.rb @@ -9,7 +9,7 @@ { bike_id: bike.id, message: "I saw this bike on the street!", - reference_url: "https://party.com" + reference_url: "https://party.com", } end diff --git a/spec/controllers/user_emails_controller_spec.rb b/spec/controllers/user_emails_controller_spec.rb index 6611ed9569..7069afefbc 100644 --- a/spec/controllers/user_emails_controller_spec.rb +++ b/spec/controllers/user_emails_controller_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require "spec_helper" describe UserEmailsController do - let(:user_email) { FactoryBot.create(:user_email, confirmation_token: 'sometoken-or-something') } + let(:user_email) { FactoryBot.create(:user_email, confirmation_token: "sometoken-or-something") } let(:user) { user_email.user } before do expect(user_email.confirmed).to be_falsey end - describe 'resend_confirmation' do - context 'user who has user_email' do - it 'enqueues a job to send an additional email confirmation' do + describe "resend_confirmation" do + context "user who has user_email" do + it "enqueues a job to send an additional email confirmation" do set_current_user(user) expect do post :resend_confirmation, id: user_email.id @@ -19,7 +19,7 @@ end context "not user's user_email" do - it 'does not enqueue a job and sets the flash' do + it "does not enqueue a job and sets the flash" do set_current_user(FactoryBot.create(:user_confirmed)) expect do post :resend_confirmation, id: user_email.id @@ -28,8 +28,8 @@ end end - context 'no user, no email_id' do - it 'does not enqueue a job and sets the flash (and does not break)' do + context "no user, no email_id" do + it "does not enqueue a job and sets the flash (and does not break)" do expect do post :resend_confirmation, id: 33333 end.to change(AdditionalEmailConfirmationWorker.jobs, :size).by 0 @@ -38,13 +38,13 @@ end end - describe 'confirm' do + describe "confirm" do context "user's user email" do before do set_current_user(user) end - context 'unconfirmed' do - it 'confirms and enqueues merge job' do + context "unconfirmed" do + it "confirms and enqueues merge job" do expect do get :confirm, id: user_email.id, confirmation_token: user_email.confirmation_token end.to change(MergeAdditionalEmailWorker.jobs, :size).by 1 @@ -53,19 +53,19 @@ expect(flash[:success]).to be_present end end - context 'confirmed' do - it 'sets flash info and does not add job' do + context "confirmed" do + it "sets flash info and does not add job" do user_email.confirm(user_email.confirmation_token) expect do - get :confirm, id: user_email.id, confirmation_token: 'sometoken-or-something' + get :confirm, id: user_email.id, confirmation_token: "sometoken-or-something" end.to change(MergeAdditionalEmailWorker.jobs, :size).by 0 expect(flash[:info]).to be_present end end - context 'incorrect token' do - it 'sets flash error and does not add job' do + context "incorrect token" do + it "sets flash error and does not add job" do expect do - get :confirm, id: user_email.id, confirmation_token: 'somethingelse-' + get :confirm, id: user_email.id, confirmation_token: "somethingelse-" end.to change(MergeAdditionalEmailWorker.jobs, :size).by 0 expect(flash[:error]).to be_present end @@ -73,7 +73,7 @@ end context "not user's user_email" do - it 'does not enqueue a job and sets the flash' do + it "does not enqueue a job and sets the flash" do set_current_user(FactoryBot.create(:user_confirmed)) expect do get :confirm, id: user_email.id, confirmation_token: user_email.confirmation_token @@ -82,8 +82,8 @@ end end - context 'no user, no email_id' do - it 'does not enqueue a job and sets the flash (and does not break)' do + context "no user, no email_id" do + it "does not enqueue a job and sets the flash (and does not break)" do expect do get :confirm, id: user_email.id, confirmation_token: user_email.confirmation_token end.to change(AdditionalEmailConfirmationWorker.jobs, :size).by 0 @@ -92,22 +92,22 @@ end end - describe 'destroy' do + describe "destroy" do context "user's user email" do before do set_current_user(user) end - context 'unconfirmed' do - it 'deletes the email' do + context "unconfirmed" do + it "deletes the email" do delete :destroy, id: user_email.id expect(UserEmail.where(id: user_email.id)).to_not be_present expect(flash[:success]).to be_present end end - context 'only has email' do - it 'sets flash info and does not delete the email' do + context "only has email" do + it "sets flash info and does not delete the email" do user_email.destroy - user.user_emails.each { |ue| ue.update_attribute :confirmation_token, 'stuff' } + user.user_emails.each { |ue| ue.update_attribute :confirmation_token, "stuff" } expect(user.user_emails.count).to eq 1 expect(user.user_emails.confirmed.count).to eq 0 delete :destroy, id: user.user_emails.first.id @@ -117,8 +117,8 @@ expect(flash[:info]).to be_present end end - context 'confirmed' do - it 'sets flash info and does not delete the email' do + context "confirmed" do + it "sets flash info and does not delete the email" do user_email.confirm(user_email.confirmation_token) delete :destroy, id: user_email.id user_email.reload @@ -129,7 +129,7 @@ end context "not user's user_email" do - it 'does not delete the email and sets an error flash' do + it "does not delete the email and sets an error flash" do set_current_user(FactoryBot.create(:user_confirmed)) expect do delete :destroy, id: user_email.id @@ -138,8 +138,8 @@ end end - context 'no user, no email_id' do - it 'does not delete the email and sets an error flash' do + context "no user, no email_id" do + it "does not delete the email and sets an error flash" do expect do delete :destroy, id: user_email.id end.to change(AdditionalEmailConfirmationWorker.jobs, :size).by 0 @@ -148,13 +148,13 @@ end end - describe 'make_primary' do + describe "make_primary" do context "user's user email" do before do set_current_user(user) end - context 'unconfirmed' do - it 'does not make primary' do + context "unconfirmed" do + it "does not make primary" do post :make_primary, id: user_email.id user_email.reload expect(user_email.primary).to be_falsey @@ -162,8 +162,8 @@ expect(flash[:info]).to be_present end end - context 'confirmed' do - it 'sets flash success and makes primary' do + context "confirmed" do + it "sets flash success and makes primary" do user_email.confirm(user_email.confirmation_token) expect(user.user_emails.confirmed.count).to eq 2 post :make_primary, id: user_email.id @@ -175,8 +175,8 @@ expect(flash[:success]).to be_present end end - context 'confirmed and primary' do - it 'user_email remains primary' do + context "confirmed and primary" do + it "user_email remains primary" do user_email.confirm(user_email.confirmation_token) user_email.make_primary post :make_primary, id: user_email.id @@ -187,7 +187,7 @@ end context "not user's user_email" do - it 'does not enqueue a job and sets the flash' do + it "does not enqueue a job and sets the flash" do set_current_user(FactoryBot.create(:user_confirmed)) post :make_primary, id: user_email.id user_email.reload @@ -196,8 +196,8 @@ end end - context 'no user, no email_id' do - it 'does not enqueue a job and sets the flash (and does not break)' do + context "no user, no email_id" do + it "does not enqueue a job and sets the flash (and does not break)" do post :make_primary, id: user_email.id user_email.reload expect(user_email.primary).to be_falsey diff --git a/spec/controllers/user_embeds_controller_spec.rb b/spec/controllers/user_embeds_controller_spec.rb index 8e1deb9bf9..8b3a72497c 100644 --- a/spec/controllers/user_embeds_controller_spec.rb +++ b/spec/controllers/user_embeds_controller_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require "spec_helper" describe UserEmbedsController do - describe 'show' do - it 'renders the page if username is found' do + describe "show" do + it "renders the page if username is found" do user = FactoryBot.create(:user, show_bikes: true) ownership = FactoryBot.create(:ownership, user_id: user.id, current: true) get :show, id: user.username - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(assigns(:bikes).first).to eq(ownership.bike) expect(assigns(:bikes).count).to eq(1) - expect(response.headers['X-Frame-Options']).not_to be_present + expect(response.headers["X-Frame-Options"]).not_to be_present end it "renders the most recent bikes with images if it doesn't find the user" do @@ -18,10 +18,10 @@ allow_any_instance_of(Bike).to receive(:public_images) { [public_image] } bike.save && bike.reload expect(bike.thumb_path).to be_present - get :show, id: 'NOT A USER' - expect(response.code).to eq('200') + get :show, id: "NOT A USER" + expect(response.code).to eq("200") expect(assigns(:bikes).count).to eq(1) - expect(response.headers['X-Frame-Options']).not_to be_present + expect(response.headers["X-Frame-Options"]).not_to be_present end end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 64555a2d23..825b3568c6 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -149,14 +149,14 @@ end end - describe 'confirm' do - describe 'user exists' do - it 'tells the user to log in when already confirmed' do - get :confirm, id: user.id, code: 'wtfmate' + describe "confirm" do + describe "user exists" do + it "tells the user to log in when already confirmed" do + get :confirm, id: user.id, code: "wtfmate" expect(response).to redirect_to new_session_url end - describe 'user not yet confirmed' do + describe "user not yet confirmed" do let(:user) { FactoryBot.create(:user) } before :each do @@ -188,32 +188,32 @@ end end - it 'shows a view when confirmation fails' do + it "shows a view when confirmation fails" do expect(user).to receive(:confirm).and_return(false) - get :confirm, id: user.id, code: 'Wtfmate' + get :confirm, id: user.id, code: "Wtfmate" expect(response).to render_template :confirm_error_bad_token end end end - it 'shows an appropriate message when the user is nil' do - get :confirm, id: 1234, code: 'Wtfmate' + it "shows an appropriate message when the user is nil" do + get :confirm, id: 1234, code: "Wtfmate" expect(response).to render_template :confirm_error_404 end end - context 'revised' do + context "revised" do let(:user_attrs) do { - name: 'foo', - email: 'foo1@bar.com', - password: 'coolpasswprd$$$$$', - terms_of_service: '0', - notification_newsletters: '0' + name: "foo", + email: "foo1@bar.com", + password: "coolpasswprd$$$$$", + terms_of_service: "0", + notification_newsletters: "0", } end - context 'create attrs' do - it 'renders' do + context "create attrs" do + it "renders" do expect do post :create, user: user_attrs end.to change(User, :count).by(1) @@ -293,11 +293,11 @@ end end - describe 'show' do + describe "show" do before { expect(user.confirmed).to be_truthy } it "404s if the user doesn't exist" do expect do - get :show, id: 'fake_user extra stuff' + get :show, id: "fake_user extra stuff" end.to raise_error(ActionController::RoutingError) end @@ -308,53 +308,53 @@ expect(response).to redirect_to user_home_url end - it 'shows the page if the user exists and wants to show their page' do + it "shows the page if the user exists and wants to show their page" do user.show_bikes = true user.save get :show, id: user.username, page: 1, per_page: 1 expect(response).to render_template :show - expect(assigns(:per_page)).to eq '1' - expect(assigns(:page)).to eq '1' + expect(assigns(:per_page)).to eq "1" + expect(assigns(:page)).to eq "1" end end - describe 'accept_vendor_terms' do - it 'renders' do + describe "accept_vendor_terms" do + it "renders" do set_current_user(user) get :accept_vendor_terms expect(response.status).to eq(200) expect(response).to render_template(:accept_vendor_terms) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - describe 'accept_terms' do - it 'renders' do + describe "accept_terms" do + it "renders" do set_current_user(user) get :accept_terms expect(response).to render_template(:accept_terms) - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") end end - describe 'edit' do + describe "edit" do include_context :logged_in_as_user - context 'no page given' do - it 'renders root' do + context "no page given" do + it "renders root" do get :edit expect(response).to be_success - expect(response).to render_with_layout('application_revised') - expect(assigns(:edit_template)).to eq('root') - expect(response).to render_template('edit') + expect(response).to render_with_layout("application_revised") + expect(assigns(:edit_template)).to eq("root") + expect(response).to render_template("edit") end end - context 'application_revised layout' do + context "application_revised layout" do %w[root password sharing].each do |template| context template do - it 'renders the template' do + it "renders the template" do get :edit, page: template expect(response).to be_success - expect(response).to render_with_layout('application_revised') + expect(response).to render_with_layout("application_revised") expect(assigns(:edit_template)).to eq(template) expect(response).to render_template(partial: "_edit_#{template}") end @@ -363,7 +363,7 @@ end end - describe 'update' do + describe "update" do let!(:user) { FactoryBot.create(:user_confirmed, terms_of_service: false, password: "old_pass", password_confirmation: "old_pass", username: "something") } context "nil username" do it "doesn't update username" do @@ -381,26 +381,26 @@ set_current_user(user) post :update, id: user.username, user: { - password: 'new_pass', - password_confirmation: 'new_pass' + password: "new_pass", + password_confirmation: "new_pass", } - expect(user.reload.authenticate('new_pass')).to be_falsey + expect(user.reload.authenticate("new_pass")).to be_falsey end it "doesn't update user if password doesn't match" do set_current_user(user) post :update, id: user.username, user: { - current_password: 'old_pass', - password: 'new_pass', - name: 'Mr. Slick', - password_confirmation: 'new_passd' + current_password: "old_pass", + password: "new_pass", + name: "Mr. Slick", + password_confirmation: "new_passd", } - expect(user.reload.authenticate('new_pass')).to be_falsey - expect(user.name).not_to eq('Mr. Slick') + expect(user.reload.authenticate("new_pass")).to be_falsey + expect(user.name).not_to eq("Mr. Slick") end - it 'Updates user if there is a reset_pass token' do + it "Updates user if there is a reset_pass token" do user.set_password_reset_token((Time.now - 30.minutes).to_i) user.reload auth = user.auth_token @@ -408,14 +408,14 @@ set_current_user(user) post :update, id: user.username, user: { - email: 'cool_new_email@something.com', + email: "cool_new_email@something.com", password_reset_token: user.password_reset_token, - password: 'new_pass', - password_confirmation: 'new_pass' + password: "new_pass", + password_confirmation: "new_pass", } - expect(user.reload.authenticate('new_pass')).to be_truthy + expect(user.reload.authenticate("new_pass")).to be_truthy expect(user.email).to eq(email) - expect(user.password_reset_token).not_to eq('stuff') + expect(user.password_reset_token).not_to eq("stuff") expect(user.auth_token).not_to eq(auth) expect(cookies.signed[:auth][1]).to eq(user.auth_token) expect(response).to redirect_to(my_account_url) @@ -430,13 +430,13 @@ set_current_user(user) post :update, id: user.username, user: { - password_reset_token: 'something_else', - password: 'new_pass', - password_confirmation: 'new_pass' + password_reset_token: "something_else", + password: "new_pass", + password_confirmation: "new_pass", } expect(response).to_not redirect_to(my_account_url) expect(flash[:error]).to be_present - expect(user.reload.authenticate('new_pass')).to be_falsey + expect(user.reload.authenticate("new_pass")).to be_falsey expect(user.password_reset_token).to eq(reset) end @@ -449,7 +449,7 @@ user: { password_reset_token: user.password_reset_token, password: "new_pass", - password_confirmation: "new_pass" + password_confirmation: "new_pass", } expect(response).to_not redirect_to(my_account_url) expect(flash[:error]).to be_present @@ -460,26 +460,26 @@ expect(cookies.signed[:auth]).to_not be_present end - it 'resets users auth if password changed, updates current session' do - user = FactoryBot.create(:user_confirmed, terms_of_service: false, password: 'old_pass', password_confirmation: 'old_pass', password_reset_token: 'stuff') + it "resets users auth if password changed, updates current session" do + user = FactoryBot.create(:user_confirmed, terms_of_service: false, password: "old_pass", password_confirmation: "old_pass", password_reset_token: "stuff") auth = user.auth_token email = user.email set_current_user(user) post :update, id: user.username, user: { - email: 'cool_new_email@something.com', - current_password: 'old_pass', - password: 'new_pass', - name: 'Mr. Slick', - password_confirmation: 'new_pass' + email: "cool_new_email@something.com", + current_password: "old_pass", + password: "new_pass", + name: "Mr. Slick", + password_confirmation: "new_pass", } expect(response).to redirect_to(my_account_url) expect(flash[:error]).to_not be_present - expect(user.reload.authenticate('new_pass')).to be_truthy + expect(user.reload.authenticate("new_pass")).to be_truthy expect(user.auth_token).not_to eq(auth) expect(user.email).to eq(email) - expect(user.password_reset_token).not_to eq('stuff') - expect(user.name).to eq('Mr. Slick') + expect(user.password_reset_token).not_to eq("stuff") + expect(user.name).to eq("Mr. Slick") expect(cookies.signed[:auth][1]).to eq(user.auth_token) end @@ -499,7 +499,7 @@ street: "278 Broadway", zipcode: "10007", notification_newsletters: "1", - phone: "3223232" + phone: "3223232", } expect(response).to redirect_to(my_account_url) expect(flash[:error]).to_not be_present @@ -516,9 +516,9 @@ end end - it 'updates the terms of service' do + it "updates the terms of service" do set_current_user(user) - post :update, id: user.username, user: { terms_of_service: '1' } + post :update, id: user.username, user: { terms_of_service: "1" } expect(response).to redirect_to(user_home_url) expect(user.reload.terms_of_service).to be_truthy end @@ -533,27 +533,27 @@ expect(user.notification_unstolen).to be_falsey end - it 'updates the vendor terms of service and emailable' do + it "updates the vendor terms of service and emailable" do user = FactoryBot.create(:user_confirmed, terms_of_service: false, notification_newsletters: false) expect(user.notification_newsletters).to be_falsey org = FactoryBot.create(:organization) FactoryBot.create(:membership, organization: org, user: user) set_current_user(user) - post :update, id: user.username, user: { vendor_terms_of_service: '1', notification_newsletters: true } - expect(response.code).to eq('302') + post :update, id: user.username, user: { vendor_terms_of_service: "1", notification_newsletters: true } + expect(response.code).to eq("302") expect(user.reload.vendor_terms_of_service).to be_truthy expect(user.notification_newsletters).to be_truthy end - it 'enqueues job (it enqueues job whenever update is successful)' do + it "enqueues job (it enqueues job whenever update is successful)" do set_current_user(user) expect do - post :update, id: user.username, user: { name: 'Cool stuff' } + post :update, id: user.username, user: { name: "Cool stuff" } end.to change(AfterUserChangeWorker.jobs, :size).by(1) - expect(user.reload.name).to eq('Cool stuff') + expect(user.reload.name).to eq("Cool stuff") end end - describe 'unsubscribe' do + describe "unsubscribe" do context "subscribed unconfirmed user" do let(:user) { FactoryBot.create(:user, notification_newsletters: true) } it "updates notification_newsletters" do @@ -567,19 +567,19 @@ expect(user.confirmed).to be_falsey end end - context 'user not present' do - it 'does not error, shows same flash success (to prevent email enumeration)' do - get :unsubscribe, id: 'cvxvxxxxx' - expect(response.code).to eq('302') + context "user not present" do + it "does not error, shows same flash success (to prevent email enumeration)" do + get :unsubscribe, id: "cvxvxxxxx" + expect(response.code).to eq("302") expect(flash[:success]).to be_present end end - context 'user already unsubscribed' do + context "user already unsubscribed" do let(:user) { FactoryBot.create(:user_confirmed, notification_newsletters: false) } - it 'does nothing' do + it "does nothing" do expect(user.notification_newsletters).to be_falsey get :unsubscribe, id: user.username - expect(response.code).to eq('302') + expect(response.code).to eq("302") expect(flash[:success]).to be_present user.reload expect(user.notification_newsletters).to be_falsey diff --git a/spec/decorators/application_decorator_spec.rb b/spec/decorators/application_decorator_spec.rb index db6a4bb770..985645dd73 100644 --- a/spec/decorators/application_decorator_spec.rb +++ b/spec/decorators/application_decorator_spec.rb @@ -1,94 +1,94 @@ -require 'spec_helper' +require "spec_helper" describe ApplicationDecorator do - describe 'dl_list_item' do + describe "dl_list_item" do it "returns a dt and dd from what's passed attribute" do bike = Bike.new - dl_list = ApplicationDecorator.new(bike).dl_list_item('description', 'title') - expect(dl_list).to eq('
    title
    description
    ') + dl_list = ApplicationDecorator.new(bike).dl_list_item("description", "title") + expect(dl_list).to eq("
    title
    description
    ") end end - describe 'dl_from_attribute' do + describe "dl_from_attribute" do it "returns nil if the attribute isn't present" do bike = Bike.new decorator = ApplicationDecorator.new(bike) allow(decorator).to receive(:if_present).and_return(nil) - expect(decorator.dl_from_attribute('serial_number')).to be_nil + expect(decorator.dl_from_attribute("serial_number")).to be_nil end - it 'returns a dt and dd from the attribute' do + it "returns a dt and dd from the attribute" do bike = Bike.new decorator = ApplicationDecorator.new(bike) - allow(decorator).to receive(:if_present).and_return('cereal') - expect(decorator).to receive(:dl_list_item).with('cereal', 'Serial Number') - decorator.dl_from_attribute('serial_number') + allow(decorator).to receive(:if_present).and_return("cereal") + expect(decorator).to receive(:dl_list_item).with("cereal", "Serial Number") + decorator.dl_from_attribute("serial_number") end end - describe 'if_present' do + describe "if_present" do it "returns the attribute if it's present" do lock = Lock.new - allow(lock).to receive(:manufacturer_other).and_return('thingsy') - expect(ApplicationDecorator.new(lock).if_present('manufacturer_other')).to eq('thingsy') + allow(lock).to receive(:manufacturer_other).and_return("thingsy") + expect(ApplicationDecorator.new(lock).if_present("manufacturer_other")).to eq("thingsy") end end - describe 'websiteable' do - it 'creates a link if bike owner wants one shown' do + describe "websiteable" do + it "creates a link if bike owner wants one shown" do user = User.new allow(user).to receive(:show_website).and_return(true) - allow(user).to receive(:website).and_return('website') + allow(user).to receive(:website).and_return("website") decorator = ApplicationDecorator.new(user).websiteable(user) expect(decorator).to eq('Website') end end - describe 'twitterable' do - it 'creates a link if bike owner wants one shown' do + describe "twitterable" do + it "creates a link if bike owner wants one shown" do user = User.new allow(user).to receive(:show_twitter).and_return(true) - allow(user).to receive(:twitter).and_return('twitter') + allow(user).to receive(:twitter).and_return("twitter") decorator = ApplicationDecorator.new(user).twitterable(user) expect(decorator).to eq('Twitter') end end - describe 'show_twitter_and_website' do - it 'combines twitter and website' do + describe "show_twitter_and_website" do + it "combines twitter and website" do user = User.new decorator = ApplicationDecorator.new(user) - allow(decorator).to receive(:twitterable).and_return('twitter') - allow(decorator).to receive(:websiteable).and_return('website') - expect(decorator.show_twitter_and_website(user)).to eq('twitter and website') + allow(decorator).to receive(:twitterable).and_return("twitter") + allow(decorator).to receive(:websiteable).and_return("website") + expect(decorator.show_twitter_and_website(user)).to eq("twitter and website") end - it 'justs return website if no twitter' do + it "justs return website if no twitter" do user = User.new decorator = ApplicationDecorator.new(user) allow(decorator).to receive(:user?).and_return(true) allow(decorator).to receive(:twitterable).and_return(nil) - allow(decorator).to receive(:websiteable).and_return('website') - expect(decorator.show_twitter_and_website(user)).to eq('website') + allow(decorator).to receive(:websiteable).and_return("website") + expect(decorator.show_twitter_and_website(user)).to eq("website") end end - describe 'ass_name' do - it 'grabs the association name' do - wheel_size = FactoryBot.create(:wheel_size, name: 'foobar', iso_bsd: 559) + describe "ass_name" do + it "grabs the association name" do + wheel_size = FactoryBot.create(:wheel_size, name: "foobar", iso_bsd: 559) bike = Bike.new(front_wheel_size: wheel_size) - expect(ApplicationDecorator.new(bike).ass_name('front_wheel_size')).to eq('foobar') + expect(ApplicationDecorator.new(bike).ass_name("front_wheel_size")).to eq("foobar") end end - describe 'display_phone' do - it 'displays the phone with an area code' do + describe "display_phone" do + it "displays the phone with an area code" do location = Location.new - allow(location).to receive(:phone).and_return('999 999 9999') - expect(ApplicationDecorator.new(location).display_phone).to eq('999 999 9999') + allow(location).to receive(:phone).and_return("999 999 9999") + expect(ApplicationDecorator.new(location).display_phone).to eq("999 999 9999") end - it 'displays the phone with a country code' do + it "displays the phone with a country code" do location = Location.new - allow(location).to receive(:phone).and_return('+91 8041505583') - expect(ApplicationDecorator.new(location).display_phone).to eq('+91 804 150 5583') + allow(location).to receive(:phone).and_return("+91 8041505583") + expect(ApplicationDecorator.new(location).display_phone).to eq("+91 804 150 5583") end end end diff --git a/spec/decorators/bike_decorator_spec.rb b/spec/decorators/bike_decorator_spec.rb index 000e14ba54..554f73a38b 100644 --- a/spec/decorators/bike_decorator_spec.rb +++ b/spec/decorators/bike_decorator_spec.rb @@ -1,21 +1,21 @@ -require 'spec_helper' +require "spec_helper" describe BikeDecorator do - describe 'show_other_bikes' do - it 'links to bikes if the user is the current owner and wants to share' do + describe "show_other_bikes" do + it "links to bikes if the user is the current owner and wants to share" do bike = Bike.new user = User.new allow(bike).to receive(:user).and_return(user) allow(user).to receive(:show_bikes).and_return(true) - allow(user).to receive(:username).and_return('i') + allow(user).to receive(:username).and_return("i") decorator = BikeDecorator.new(bike) allow(bike).to receive(:user?).and_return(true) expect(decorator.show_other_bikes.match("href='/users/i")).to be_present end end - describe 'bike_show_twitter_and_website' do - it 'calls the method from application decorator' do + describe "bike_show_twitter_and_website" do + it "calls the method from application decorator" do user = User.new bike = Bike.new allow(bike).to receive(:user).and_return(user) @@ -26,23 +26,23 @@ end end - describe 'title' do - it 'returns the major bike attribs formatted' do + describe "title" do + it "returns the major bike attribs formatted" do bike = Bike.new - allow(bike).to receive(:year).and_return('1999') - allow(bike).to receive(:frame_model).and_return('model') - allow(bike).to receive(:mnfg_name).and_return('foo') + allow(bike).to receive(:year).and_return("1999") + allow(bike).to receive(:frame_model).and_return("model") + allow(bike).to receive(:mnfg_name).and_return("foo") decorator = BikeDecorator.new(bike) - expect(decorator.title).to eq('1999 model by foo') + expect(decorator.title).to eq("1999 model by foo") end end - describe 'phoneable_by?' do + describe "phoneable_by?" do it "does not return anything if there isn't a stolen record" do bike = Bike.new expect(BikeDecorator.new(bike).phoneable_by?).to be_nil end - it 'returns true if users can see it' do + it "returns true if users can see it" do bike = Bike.new stolen_record = StolenRecord.new allow(bike).to receive(:stolen).and_return(true) @@ -51,7 +51,7 @@ expect(BikeDecorator.new(bike).phoneable_by?).to be_truthy end - it 'returns true if users can see it and user is there' do + it "returns true if users can see it and user is there" do user = User.new bike = Bike.new stolen_record = StolenRecord.new @@ -61,7 +61,7 @@ expect(BikeDecorator.new(bike).phoneable_by?(user)).to be_truthy end - it 'returns true if shops can see it and user has shop membership' do + it "returns true if shops can see it and user has shop membership" do user = User.new bike = Bike.new stolen_record = StolenRecord.new @@ -73,7 +73,7 @@ expect(BikeDecorator.new(bike).phoneable_by?(user)).to be_truthy end - it 'returns true if police can see it and user is police' do + it "returns true if police can see it and user is police" do user = User.new bike = Bike.new stolen_record = StolenRecord.new @@ -86,7 +86,7 @@ expect(BikeDecorator.new(bike).phoneable_by?(user)).to be_truthy end - it 'returns true for superusers' do + it "returns true for superusers" do user = User.new bike = Bike.new stolen_record = StolenRecord.new @@ -100,121 +100,121 @@ end end - describe 'tire_width' do - it 'returns wide if false' do + describe "tire_width" do + it "returns wide if false" do bike = Bike.new allow(bike).to receive(:front_tire_narrow).and_return(nil) - decorator = BikeDecorator.new(bike).tire_width('front') - expect(decorator).to eq('wide') + decorator = BikeDecorator.new(bike).tire_width("front") + expect(decorator).to eq("wide") end - it 'returns narrow if narrow' do + it "returns narrow if narrow" do bike = Bike.new allow(bike).to receive(:rear_tire_narrow).and_return(true) - decorator = BikeDecorator.new(bike).tire_width('rear') - expect(decorator).to eq('narrow') + decorator = BikeDecorator.new(bike).tire_width("rear") + expect(decorator).to eq("narrow") end end - describe 'list_link_url' do - it 'returns the bike edit path if edit' do + describe "list_link_url" do + it "returns the bike edit path if edit" do bike = Bike.new allow(bike).to receive(:id).and_return(69) - decorator = BikeDecorator.new(bike).list_link_url('edit') - expect(decorator).to eq('/bikes/69/edit') + decorator = BikeDecorator.new(bike).list_link_url("edit") + expect(decorator).to eq("/bikes/69/edit") end - it 'returns the normal path if passed' do + it "returns the normal path if passed" do bike = Bike.new allow(bike).to receive(:id).and_return(69) decorator = BikeDecorator.new(bike).list_link_url - expect(decorator).to eq('/bikes/69') + expect(decorator).to eq("/bikes/69") end end - describe 'thumb_image' do - context 'bike photo exists' do - it 'returns the thumb path if one exists' do + describe "thumb_image" do + context "bike photo exists" do + it "returns the thumb path if one exists" do bike = Bike.new - allow(bike).to receive(:thumb_path).and_return('pathy') + allow(bike).to receive(:thumb_path).and_return("pathy") decorator = BikeDecorator.new(bike) - allow(decorator).to receive(:title_string).and_return('Title') + allow(decorator).to receive(:title_string).and_return("Title") expect(decorator.thumb_image).to eq('Title') end end - context 'bike photo does not exist' do - it 'returns the bike placeholder path' do + context "bike photo does not exist" do + it "returns the bike placeholder path" do bike = Bike.new decorator = BikeDecorator.new(bike) - allow(decorator).to receive(:title_string).and_return('Title') + allow(decorator).to receive(:title_string).and_return("Title") html = decorator.thumb_image expect(html).to match("alt=\"Title\"") expect(html).to match('title=\"No image\"') expect(html).to match(/revised.bike_photo_placeholder.*\.svg/) end - end + end end - describe 'list_image' do - it 'returns the link with thumb path if nothing is passed' do + describe "list_image" do + it "returns the link with thumb path if nothing is passed" do bike = Bike.new allow(bike).to receive(:id).and_return(69) decorator = BikeDecorator.new(bike) - allow(decorator).to receive(:thumb_image).and_return('imagey') + allow(decorator).to receive(:thumb_image).and_return("imagey") expect(decorator.list_image).not_to be_nil end - it 'returns the images thumb path' do + it "returns the images thumb path" do bike = Bike.new allow(bike).to receive(:id).and_return(69) - allow(bike).to receive(:thumb_path).and_return('something') + allow(bike).to receive(:thumb_path).and_return("something") decorator = BikeDecorator.new(bike) - allow(decorator).to receive(:thumb_image).and_return('imagey') + allow(decorator).to receive(:thumb_image).and_return("imagey") expect(decorator.list_image).not_to be_nil end end - describe 'serial_display' do - context 'absent' do - context 'stolen' do - it 'unknown' do - bike = Bike.new(serial_number: 'absent') + describe "serial_display" do + context "absent" do + context "stolen" do + it "unknown" do + bike = Bike.new(serial_number: "absent") allow(bike).to receive(:stolen).and_return(true) decorator = BikeDecorator.new(bike) - expect(decorator.serial_display).to eq('Unknown') + expect(decorator.serial_display).to eq("Unknown") end end - context 'not stolen' do - it 'unknown' do - bike = Bike.new(serial_number: 'absent') + context "not stolen" do + it "unknown" do + bike = Bike.new(serial_number: "absent") allow(bike).to receive(:stolen).and_return(false) decorator = BikeDecorator.new(bike) - expect(decorator.serial_display).to eq('Unknown') + expect(decorator.serial_display).to eq("Unknown") end end - context 'made_without_serial' do - it 'Has no serial' do - bike = Bike.new(serial_number: 'absent', made_without_serial: true) + context "made_without_serial" do + it "Has no serial" do + bike = Bike.new(serial_number: "absent", made_without_serial: true) allow(bike).to receive(:stolen).and_return(false) decorator = BikeDecorator.new(bike) - expect(decorator.serial_display).to eq('Has no serial') + expect(decorator.serial_display).to eq("Has no serial") end end end - context 'recovered' do - it 'returns hidden' do - bike = Bike.new(serial_number: 'asdf') + context "recovered" do + it "returns hidden" do + bike = Bike.new(serial_number: "asdf") allow(bike).to receive(:stolen).and_return(false) allow(bike).to receive(:recovered).and_return(true) decorator = BikeDecorator.new(bike) - expect(decorator.serial_display).to eq('Hidden') + expect(decorator.serial_display).to eq("Hidden") end end - it 'returns serial number' do - bike = Bike.new(serial_number: 'test_serial') + it "returns serial number" do + bike = Bike.new(serial_number: "test_serial") allow(bike).to receive(:stolen).and_return(false) allow(bike).to receive(:recovered).and_return(false) decorator = BikeDecorator.new(bike) - expect(decorator.serial_display).to eq('test_serial') + expect(decorator.serial_display).to eq("test_serial") end end end diff --git a/spec/decorators/lock_decorator_spec.rb b/spec/decorators/lock_decorator_spec.rb index 85f2d2928b..ecbb585080 100644 --- a/spec/decorators/lock_decorator_spec.rb +++ b/spec/decorators/lock_decorator_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require "spec_helper" describe LockDecorator do - describe 'lock_type_name' do - it 'returns the lock type name other name if present' do + describe "lock_type_name" do + it "returns the lock type name other name if present" do lock = Lock.new lock_type = LockType.new allow(lock).to receive(:lock_type).and_return(lock_type) - allow(lock_type).to receive(:name).and_return('lockity lock') - expect(LockDecorator.new(lock).lock_type_name).to eq('lockity lock') + allow(lock_type).to receive(:name).and_return("lockity lock") + expect(LockDecorator.new(lock).lock_type_name).to eq("lockity lock") end end end diff --git a/spec/factories.rb b/spec/factories.rb index 6d8a8f6528..2cf8f75351 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -95,36 +95,36 @@ end factory :integration do - access_token { '12345teststststs' } + access_token { "12345teststststs" } end factory :blog do user - body { 'Some sweet blog content that everyone loves' } + body { "Some sweet blog content that everyone loves" } sequence(:title) { |n| "Blog title #{n}" } end factory :feedback do - email { 'foo@boy.com' } - body { 'This is a test email.' } - title { 'New Feedback Submitted' } - name { 'Bobby Joe' } + email { "foo@boy.com" } + body { "This is a test email." } + title { "New Feedback Submitted" } + name { "Bobby Joe" } end factory :stolen_notification do sender { FactoryBot.create(:user) } receiver { FactoryBot.create(:user) } bike { FactoryBot.create(:bike) } - message { 'This is a test email.' } + message { "This is a test email." } end factory :customer_contact do creator { FactoryBot.create(:user) } bike { FactoryBot.create(:bike) } - title { 'Some title' } - body { 'some message' } - creator_email { 'something@example.com' } - user_email { 'something_else@example.com' } - contact_type { 'stolen_message' } + title { "Some title" } + body { "some message" } + creator_email { "something@example.com" } + user_email { "something_else@example.com" } + contact_type { "stolen_message" } end end diff --git a/spec/factories/b_params.rb b/spec/factories/b_params.rb index b4700b7fe1..f3f815cd3a 100644 --- a/spec/factories/b_params.rb +++ b/spec/factories/b_params.rb @@ -26,8 +26,8 @@ revised_new: true, manufacturer_id: manufacturer.id, owner_email: owner_email, - creation_organization_id: organization.id - } + creation_organization_id: organization.id, + }, } end end @@ -36,8 +36,8 @@ { bike: { owner_email: owner_email, - creation_organization_id: organization.id - } + creation_organization_id: organization.id, + }, } end end @@ -47,8 +47,8 @@ bike: { owner_email: owner_email, creation_organization_id: organization.id, - stolen: true - } + stolen: true, + }, } end end diff --git a/spec/factories/mail_snippets.rb b/spec/factories/mail_snippets.rb index 816a6ed336..dce8027123 100644 --- a/spec/factories/mail_snippets.rb +++ b/spec/factories/mail_snippets.rb @@ -2,14 +2,14 @@ factory :mail_snippet do name is_enabled { true } - body { '

    Foo

    ' } + body { "

    Foo

    " } factory :mail_snippet_location_triggered do is_location_triggered { true } proximity_radius { 100 } - address { 'New York, NY' } + address { "New York, NY" } end factory :organization_mail_snippet do - sequence(:name) { |n| MailSnippet.organization_snippet_types[MailSnippet.organization_snippet_types.count%n] } + sequence(:name) { |n| MailSnippet.organization_snippet_types[MailSnippet.organization_snippet_types.count % n] } organization { FactoryBot.create(:organization) } end end diff --git a/spec/factories/tweets.rb b/spec/factories/tweets.rb index d0055cd593..9525b9625c 100644 --- a/spec/factories/tweets.rb +++ b/spec/factories/tweets.rb @@ -1,6 +1,6 @@ FactoryBot.define do factory :tweet do - twitter_id { '874644243737751553' } - twitter_response { File.read(Rails.root.join('spec', 'fixtures', 'integration_data_tweet.json')) } + twitter_id { "874644243737751553" } + twitter_response { File.read(Rails.root.join("spec", "fixtures", "integration_data_tweet.json")) } end end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index c39c38ac86..e893cebe8c 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -2,8 +2,8 @@ factory :user do name email { generate(:unique_email) } - password { 'testthisthing7$' } - password_confirmation { 'testthisthing7$' } + password { "testthisthing7$" } + password_confirmation { "testthisthing7$" } terms_of_service { true } factory :user_confirmed do after(:create) { |u| u.confirm(u.confirmation_token) } @@ -38,7 +38,7 @@ end factory :organization_admin do after(:create) do |user, evaluator| - FactoryBot.create(:membership, user: user, organization: evaluator.organization, role: 'admin') + FactoryBot.create(:membership, user: user, organization: evaluator.organization, role: "admin") end end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 82a800c2cb..3b14527eab 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -1,65 +1,65 @@ -require 'spec_helper' +require "spec_helper" describe ApplicationHelper do - describe 'active_link' do - context 'without a class' do - it 'returns the link active if it ought to be' do + describe "active_link" do + context "without a class" do + it "returns the link active if it ought to be" do allow(view).to receive(:current_page?).and_return(true) generated = 'Bike Index about' - expect(helper.active_link('Bike Index about', 'http://bikeindex.org')).to eq generated + expect(helper.active_link("Bike Index about", "http://bikeindex.org")).to eq generated end end - context 'match controller true' do - let(:request) { double('request', url: new_bike_url) } + context "match controller true" do + let(:request) { double("request", url: new_bike_url) } before { allow(helper).to receive(:request).and_return(request) } - it 'returns the link active if it is a bikes page' do + it "returns the link active if it is a bikes page" do generated = 'Bike Index bikes page' - result = helper.active_link('Bike Index bikes page', new_bike_url, match_controller: true, class: 'seeeeeeee', id: "") + result = helper.active_link("Bike Index bikes page", new_bike_url, match_controller: true, class: "seeeeeeee", id: "") expect(result).to eq generated end end - context 'current with a class' do - it 'returns the link active if it ought to be' do + context "current with a class" do + it "returns the link active if it ought to be" do allow(view).to receive(:current_page?).and_return(true) generated = 'Bike Index about' - result = helper.active_link('Bike Index about', 'http://bikeindex.org', class: 'nav-party-link', id: "XXX") + result = helper.active_link("Bike Index about", "http://bikeindex.org", class: "nav-party-link", id: "XXX") expect(result).to eq generated end end - context 'organization_invitation' do - it 'returns link, active if it ought to be' do - allow(view).to receive(:controller_name).and_return('organization_invitations') + context "organization_invitation" do + it "returns link, active if it ought to be" do + allow(view).to receive(:controller_name).and_return("organization_invitations") generated = 'Invitations' - expect(helper.active_link('Invitations', '/invitations')).to eq(generated) + expect(helper.active_link("Invitations", "/invitations")).to eq(generated) end end end - describe 'current_page_skeleton' do + describe "current_page_skeleton" do before { allow(view).to receive(:controller_namespace) { controller_namespace } } let(:controller_namespace) { nil } - describe 'landing_pages controller' do - before { allow(view).to receive(:controller_name) { 'landing_pages' } } - context 'show (organization landing page)' do - it 'returns nil' do - allow(view).to receive(:action_name) { 'show' } + describe "landing_pages controller" do + before { allow(view).to receive(:controller_name) { "landing_pages" } } + context "show (organization landing page)" do + it "returns nil" do + allow(view).to receive(:action_name) { "show" } expect(helper.current_page_skeleton).to be_nil end end %w(for_law_enfocement for_schools).each do |action| context action do - it 'returns nil' do + it "returns nil" do allow(view).to receive(:action_name) { action } expect(helper.current_page_skeleton).to be_nil end end end end - describe 'bikes controller' do - before { allow(view).to receive(:controller_name) { 'bikes' } } + describe "bikes controller" do + before { allow(view).to receive(:controller_name) { "bikes" } } %w(new create).each do |action| context action do - it 'returns nil' do + it "returns nil" do allow(view).to receive(:action_name) { action } expect(helper.current_page_skeleton).to be_nil end @@ -67,230 +67,230 @@ end %w(edit update).each do |action| context action do - it 'returns edit_bike_skeleton' do + it "returns edit_bike_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'edit_bike_skeleton' + expect(helper.current_page_skeleton).to eq "edit_bike_skeleton" end end end end - describe 'registrations controller' do - before { allow(view).to receive(:controller_name) { 'registrations' } } + describe "registrations controller" do + before { allow(view).to receive(:controller_name) { "registrations" } } %w(new).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end - describe 'info controller' do - before { allow(view).to receive(:controller_name) { 'info' } } + describe "info controller" do + before { allow(view).to receive(:controller_name) { "info" } } %w(about protect_your_bike where serials image_resources resources dev_and_design).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end - context 'support_the_index' do - it 'returns nil' do - allow(view).to receive(:action_name) { 'support_the_index' } + context "support_the_index" do + it "returns nil" do + allow(view).to receive(:action_name) { "support_the_index" } expect(helper.current_page_skeleton).to be_nil end end %w(terms vendor_terms privacy).each do |action| context action do - it 'returns nil' do + it "returns nil" do allow(view).to receive(:action_name) { action } expect(helper.current_page_skeleton).to be_nil end end end end - describe 'news controller' do - before { allow(view).to receive(:controller_name) { 'news' } } + describe "news controller" do + before { allow(view).to receive(:controller_name) { "news" } } %w(index show).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end - describe 'payments controller' do - before { allow(view).to receive(:controller_name) { 'payments' } } + describe "payments controller" do + before { allow(view).to receive(:controller_name) { "payments" } } %w(new create).each do |action| context action do - it 'returns nil' do + it "returns nil" do allow(view).to receive(:action_name) { action } expect(helper.current_page_skeleton).to be_nil end end end end - describe 'feedbacks controller' do - before { allow(view).to receive(:controller_name) { 'feedbacks' } } + describe "feedbacks controller" do + before { allow(view).to receive(:controller_name) { "feedbacks" } } %w(index).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end - describe 'manufacturers controller' do - before { allow(view).to receive(:controller_name) { 'manufacturers' } } + describe "manufacturers controller" do + before { allow(view).to receive(:controller_name) { "manufacturers" } } %w(index).each do |action| context action do - it 'returns nil' do + it "returns nil" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end - describe 'welcome controller' do - before { allow(view).to receive(:controller_name) { 'welcome' } } + describe "welcome controller" do + before { allow(view).to receive(:controller_name) { "welcome" } } %w(goodbye).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end - describe 'organizations controller' do - before { allow(view).to receive(:controller_name) { 'organizations' } } + describe "organizations controller" do + before { allow(view).to receive(:controller_name) { "organizations" } } %w(new lightspeed_integration).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end - describe 'organized subrouting' do - let(:controller_namespace) { 'organized' } - context 'manage' do - before { allow(view).to receive(:controller_name) { 'manage' } } - it 'returns organized for index' do - allow(view).to receive(:action_name) { 'index' } - expect(helper.current_page_skeleton).to eq 'organized_skeleton' + describe "organized subrouting" do + let(:controller_namespace) { "organized" } + context "manage" do + before { allow(view).to receive(:controller_name) { "manage" } } + it "returns organized for index" do + allow(view).to receive(:action_name) { "index" } + expect(helper.current_page_skeleton).to eq "organized_skeleton" end end - context 'bikes' do - before { allow(view).to receive(:controller_name) { 'bikes' } } - it 'returns organized for index' do - allow(view).to receive(:action_name) { 'index' } - expect(helper.current_page_skeleton).to eq 'organized_skeleton' + context "bikes" do + before { allow(view).to receive(:controller_name) { "bikes" } } + it "returns organized for index" do + allow(view).to receive(:action_name) { "index" } + expect(helper.current_page_skeleton).to eq "organized_skeleton" end end - context 'users' do - before { allow(view).to receive(:controller_name) { 'users' } } - it 'returns organized for index' do - allow(view).to receive(:action_name) { 'index' } - expect(helper.current_page_skeleton).to eq 'organized_skeleton' + context "users" do + before { allow(view).to receive(:controller_name) { "users" } } + it "returns organized for index" do + allow(view).to receive(:action_name) { "index" } + expect(helper.current_page_skeleton).to eq "organized_skeleton" end end end - describe 'stolen controller' do - before { allow(view).to receive(:controller_name) { 'stolen' } } + describe "stolen controller" do + before { allow(view).to receive(:controller_name) { "stolen" } } %w(index).each do |action| context action do - it 'returns nil' do + it "returns nil" do allow(view).to receive(:action_name) { action } expect(helper.current_page_skeleton).to be_nil end end end end - describe 'users controller' do - before { allow(view).to receive(:controller_name) { 'users' } } + describe "users controller" do + before { allow(view).to receive(:controller_name) { "users" } } %w(request_password_reset).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end - describe 'errors controller' do - before { allow(view).to receive(:controller_name) { 'errors' } } + describe "errors controller" do + before { allow(view).to receive(:controller_name) { "errors" } } %w(bad_request not_found unprocessable_entity server_error unauthorized).each do |action| context action do - it 'returns content_skeleton' do + it "returns content_skeleton" do allow(view).to receive(:action_name) { action } - expect(helper.current_page_skeleton).to eq 'content_skeleton' + expect(helper.current_page_skeleton).to eq "content_skeleton" end end end end end - describe 'body_class' do - context 'organized_skeleton' do - it 'returns organized-body' do - expect(helper).to receive(:current_page_skeleton) { 'organized_skeleton' } - expect(helper.body_class).to eq 'organized-body' + describe "body_class" do + context "organized_skeleton" do + it "returns organized-body" do + expect(helper).to receive(:current_page_skeleton) { "organized_skeleton" } + expect(helper.body_class).to eq "organized-body" end end - context 'landing_page controller' do - before { allow(view).to receive(:controller_name) { 'landing_pages' } } - it 'returns organized-body' do - expect(helper.body_class).to eq 'landing-page-body' + context "landing_page controller" do + before { allow(view).to receive(:controller_name) { "landing_pages" } } + it "returns organized-body" do + expect(helper.body_class).to eq "landing-page-body" end end - context 'bikes controller' do - before { allow(view).to receive(:controller_name) { 'bikes' } } + context "bikes controller" do + before { allow(view).to receive(:controller_name) { "bikes" } } before { allow(view).to receive(:controller_namespace) { nil } } - it 'returns nil' do + it "returns nil" do expect(helper.body_class).to be_nil end end end - describe 'content_page_type' do - context 'info controller' do - it 'returns info active_page' do - allow(view).to receive(:controller_name).and_return('info') - allow(view).to receive(:action_name).and_return('dev_and_design') - expect(helper.content_page_type).to eq 'dev_and_design' + describe "content_page_type" do + context "info controller" do + it "returns info active_page" do + allow(view).to receive(:controller_name).and_return("info") + allow(view).to receive(:action_name).and_return("dev_and_design") + expect(helper.content_page_type).to eq "dev_and_design" end end - context 'news controller' do - it 'returns news index' do - allow(view).to receive(:controller_name).and_return('news') - allow(view).to receive(:action_name).and_return('index') - expect(helper.content_page_type).to eq 'news' + context "news controller" do + it "returns news index" do + allow(view).to receive(:controller_name).and_return("news") + allow(view).to receive(:action_name).and_return("index") + expect(helper.content_page_type).to eq "news" end end - context 'bikes controller' do - let(:request) { double('request', url: new_bike_url) } + context "bikes controller" do + let(:request) { double("request", url: new_bike_url) } before { allow(helper).to receive(:request).and_return(request) } - it 'returns nil for non-info pages' do + it "returns nil for non-info pages" do expect(helper.content_page_type).to be_nil end end end - describe 'listicle_html' do - it 'returns the html formatted as we want' do - l = Listicle.new(body: 'body', title: 'title', image_credits: 'credit') + describe "listicle_html" do + it "returns the html formatted as we want" do + l = Listicle.new(body: "body", title: "title", image_credits: "credit") l.htmlize_content html = helper.listicle_html(l) target = '

    credit

    ' target << "\n" target << '

    title

    body

    ' target << "\n" - target << '
    ' + target << "" expect(html).to eq(target) end end diff --git a/spec/helpers/header_tag_helper_spec.rb b/spec/helpers/header_tag_helper_spec.rb index 9de0b6da9b..ea2f61774a 100644 --- a/spec/helpers/header_tag_helper_spec.rb +++ b/spec/helpers/header_tag_helper_spec.rb @@ -1,154 +1,154 @@ -require 'spec_helper' +require "spec_helper" describe HeaderTagHelper do before do allow(view).to receive(:controller_name) { controller_name } allow(view).to receive(:action_name) { action_name } - allow(view).to receive(:request_url) { '' } + allow(view).to receive(:request_url) { "" } # These two methods are defined in application controller allow(view).to receive(:controller_namespace) { controller_namespace } - allow(view).to receive(:page_id) { [controller_namespace, controller_name, action_name].compact.join('_') } + allow(view).to receive(:page_id) { [controller_namespace, controller_name, action_name].compact.join("_") } end let(:controller_namespace) { nil } - describe 'header_tags' do + describe "header_tags" do %w(bikes welcome news users landing_pages).each do |controller_name| context controller_name do let(:controller_name) { controller_name } - it 'calls special_controller name' do - expect(helper).to receive("#{controller_name}_header_tags".to_sym) { ['tags'] } - expect(helper.header_tags).to eq 'tags' + it "calls special_controller name" do + expect(helper).to receive("#{controller_name}_header_tags".to_sym) { ["tags"] } + expect(helper.header_tags).to eq "tags" end end end - context 'non-special controller' do - let(:controller_name) { 'standard_names' } - it 'returns default' do + context "non-special controller" do + let(:controller_name) { "standard_names" } + it "returns default" do expect(helper).to receive(:default_header_tag_array) { %w(title description) } expect(helper.header_tags).to eq "title\ndescription" end end end - describe 'page_title=' do - it 'sets page_title with strip_tags' do - helper.page_title = ' title stuff' - expect(helper.page_title).to eq 'title stuff' + describe "page_title=" do + it "sets page_title with strip_tags" do + helper.page_title = " title stuff" + expect(helper.page_title).to eq "title stuff" end end - describe 'page_description=' do - it 'sets page_description with strip_tags' do - helper.page_description = ' description stuff' - expect(helper.page_description).to eq 'description stuff' + describe "page_description=" do + it "sets page_description with strip_tags" do + helper.page_description = " description stuff" + expect(helper.page_description).to eq "description stuff" end end - describe 'auto_title' do - context 'Assigned title from translation (users new)' do - let(:controller_name) { 'users' } - let(:action_name) { 'new' } - it 'returns the translation title' do - expect(helper.auto_title).to eq 'Sign up - Bike Index' + describe "auto_title" do + context "Assigned title from translation (users new)" do + let(:controller_name) { "users" } + let(:action_name) { "new" } + it "returns the translation title" do + expect(helper.auto_title).to eq "Sign up - Bike Index" end end - context 'rendering from controller and action name' do - let(:controller_name) { 'cool_things' } - context 'index action' do - let(:action_name) { 'index' } - it 'returns the humanized, titleized controller_name' do - expect(helper.auto_title).to eq 'Cool things' + context "rendering from controller and action name" do + let(:controller_name) { "cool_things" } + context "index action" do + let(:action_name) { "index" } + it "returns the humanized, titleized controller_name" do + expect(helper.auto_title).to eq "Cool things" end end - context 'new' do - let(:action_name) { 'new' } - it 'returns compiled title' do - expect(helper.auto_title).to eq 'New cool thing' + context "new" do + let(:action_name) { "new" } + it "returns compiled title" do + expect(helper.auto_title).to eq "New cool thing" end end - context 'edit' do - let(:action_name) { 'edit' } - it 'returns compiled title' do - expect(helper.auto_title).to eq 'Edit cool thing' + context "edit" do + let(:action_name) { "edit" } + it "returns compiled title" do + expect(helper.auto_title).to eq "Edit cool thing" end end - context 'show' do - let(:action_name) { 'show' } - it 'returns compiled title' do - expect(helper.auto_title).to eq 'View cool thing' + context "show" do + let(:action_name) { "show" } + it "returns compiled title" do + expect(helper.auto_title).to eq "View cool thing" end end - context 'create' do - let(:action_name) { 'create' } - it 'returns compiled title' do - expect(helper.auto_title).to eq 'Created cool thing' + context "create" do + let(:action_name) { "create" } + it "returns compiled title" do + expect(helper.auto_title).to eq "Created cool thing" end end end - context 'unknown action_name' do - let(:controller_name) { 'organizations' } - let(:action_name) { 'lightspeed_integration' } - it 'returns the weird action name humanized' do - expect(helper.auto_title).to eq 'Lightspeed integration' + context "unknown action_name" do + let(:controller_name) { "organizations" } + let(:action_name) { "lightspeed_integration" } + it "returns the weird action name humanized" do + expect(helper.auto_title).to eq "Lightspeed integration" end end - context 'admin namespace' do - let(:controller_namespace) { 'admin' } - describe 'bikes' do - let(:controller_name) { 'bikes' } - let(:action_name) { 'index' } - it 'returns prepended title' do - expect(helper.auto_title).to eq 'Admin | Bikes' + context "admin namespace" do + let(:controller_namespace) { "admin" } + describe "bikes" do + let(:controller_name) { "bikes" } + let(:action_name) { "index" } + it "returns prepended title" do + expect(helper.auto_title).to eq "Admin | Bikes" end end end - context 'organized namespace' do - let(:controller_namespace) { 'organized' } - let(:organization) { FactoryBot.build(:organization, short_name: 'Sweet Bike Org') } + context "organized namespace" do + let(:controller_namespace) { "organized" } + let(:organization) { FactoryBot.build(:organization, short_name: "Sweet Bike Org") } before do allow(view).to receive(:active_organization) { organization } end - describe 'bikes' do - let(:controller_name) { 'bikes' } - let(:action_name) { 'index' } - it 'returns title prepended with org name' do - expect(helper.auto_title).to eq 'Sweet Bike Org Bikes' + describe "bikes" do + let(:controller_name) { "bikes" } + let(:action_name) { "index" } + it "returns title prepended with org name" do + expect(helper.auto_title).to eq "Sweet Bike Org Bikes" end end end end - describe 'auto_description' do - context 'existing meta description translation' do - let(:controller_name) { 'manufacturers' } - let(:action_name) { 'index' } - let(:target) { 'Bicycle related manufacturers listed on Bike Index - all the brands you know and then some.' } - it 'returns the translation' do + describe "auto_description" do + context "existing meta description translation" do + let(:controller_name) { "manufacturers" } + let(:action_name) { "index" } + let(:target) { "Bicycle related manufacturers listed on Bike Index - all the brands you know and then some." } + it "returns the translation" do expect(helper.auto_description).to eq target end end - context 'no translation present' do - let(:controller_name) { 'weird_things' } - let(:action_name) { 'index' } - let(:target) { 'The best bike registry: Simple, secure and free.' } - it 'returns the default title' do + context "no translation present" do + let(:controller_name) { "weird_things" } + let(:action_name) { "index" } + let(:target) { "The best bike registry: Simple, secure and free." } + it "returns the default title" do expect(helper.auto_description).to eq target end end end - describe 'social_meta_tags' do + describe "social_meta_tags" do let(:meta_keys) do - ['og:description', 'twitter:description', 'og:title', 'twitter:title', 'og:url', 'og:image', - 'og:site_name', 'twitter:card', 'fb:app_id', 'twitter:creator', 'twitter:site'] + ["og:description", "twitter:description", "og:title", "twitter:title", "og:url", "og:image", + "og:site_name", "twitter:card", "fb:app_id", "twitter:creator", "twitter:site"] end - describe 'default_social_meta_hash' do - let(:title_keys) { ['og:title', 'twitter:title'] } - let(:description_keys) { ['og:description', 'twitter:description'] } - let(:title) { 'SWeet TITLE bro' } - let(:description) { 'A description that is just the right thing for everyone' } - context 'passed description and title' do - it 'uses passed title and description' do + describe "default_social_meta_hash" do + let(:title_keys) { ["og:title", "twitter:title"] } + let(:description_keys) { ["og:description", "twitter:description"] } + let(:title) { "SWeet TITLE bro" } + let(:description) { "A description that is just the right thing for everyone" } + context "passed description and title" do + it "uses passed title and description" do helper.instance_variable_set(:@page_title, title) helper.instance_variable_set(:@page_description, description) result = helper.default_meta_hash @@ -157,8 +157,8 @@ description_keys.each { |key| expect(result[key]).to eq description } end end - context 'no description or title passed' do - it 'uses auto_title and auto_description' do + context "no description or title passed" do + it "uses auto_title and auto_description" do expect(helper).to receive(:auto_title) { title } expect(helper).to receive(:auto_description) { description } result = helper.default_meta_hash @@ -168,10 +168,10 @@ end end end - describe 'meta_hash_html_tags' do - it 'returns content_tags_for each one' do - helper.instance_variable_set(:@page_title, 'Stuff') - helper.instance_variable_set(:@page_description, 'Description') + describe "meta_hash_html_tags" do + it "returns content_tags_for each one" do + helper.instance_variable_set(:@page_title, "Stuff") + helper.instance_variable_set(:@page_description, "Description") result = helper.social_meta_content_tags(helper.default_meta_hash).join("\n") meta_keys.each do |k| expect(result.include?("property=\"#{k}\"")).to be_truthy @@ -180,9 +180,9 @@ end end - describe 'main_header_tags' do - let(:title) { 'A really, really sweet title' } - let(:description) { 'Some lame description' } + describe "main_header_tags" do + let(:title) { "A really, really sweet title" } + let(:description) { "Some lame description" } let(:target) do [ '', @@ -193,189 +193,189 @@ "", '', '', - nil # csrf_meta_tags is nil in test + nil, # csrf_meta_tags is nil in test ] end - it 'returns main tags' do + it "returns main tags" do helper.instance_variable_set(:@page_title, title) helper.instance_variable_set(:@page_description, description) expect(helper.main_header_tags).to eq target end end - describe 'landing_pages_header_tags' do - let(:controller_name) { 'landing_pages' } - context 'show (organization landing page)' do - let(:action_name) { 'show' } - let(:organization) { FactoryBot.build(:organization, name: 'Sweet University') } - it 'sets the page title' do + describe "landing_pages_header_tags" do + let(:controller_name) { "landing_pages" } + context "show (organization landing page)" do + let(:action_name) { "show" } + let(:organization) { FactoryBot.build(:organization, name: "Sweet University") } + it "sets the page title" do allow(view).to receive(:active_organization) { organization } helper.landing_pages_header_tags - expect(helper.page_title).to eq 'Sweet University Bike Registration' - expect(helper.page_description).to eq 'Register your bicycle with Sweet University - powered by Bike Index' + expect(helper.page_title).to eq "Sweet University Bike Registration" + expect(helper.page_description).to eq "Register your bicycle with Sweet University - powered by Bike Index" end end end - describe 'welcome_header_tags' do - context 'user_home' do - let(:action_name) { 'user_home' } - context 'nil current_user name' do - it 'sets the page title' do + describe "welcome_header_tags" do + context "user_home" do + let(:action_name) { "user_home" } + context "nil current_user name" do + it "sets the page title" do allow(view).to receive(:current_user) { nil } helper.welcome_header_tags - expect(helper.page_title).to eq 'Your bikes' + expect(helper.page_title).to eq "Your bikes" end end - context 'current_user name' do - let(:user) { FactoryBot.build(:user, name: 'John') } - it 'sets the page title' do + context "current_user name" do + let(:user) { FactoryBot.build(:user, name: "John") } + it "sets the page title" do allow(view).to receive(:current_user) { user } helper.welcome_header_tags - expect(helper.page_title).to eq 'John on Bike Index' + expect(helper.page_title).to eq "John on Bike Index" end end end - context 'choose_registration' do - let(:action_name) { 'choose_registration' } - it 'sets the page title' do + context "choose_registration" do + let(:action_name) { "choose_registration" } + it "sets the page title" do helper.welcome_header_tags - expect(helper.page_title).to eq 'Register a bike!' - expect(helper.page_description).to eq 'Register a bike on Bike Index quickly, easily and for free. Create a permanent verified record of your bike to protect it.' + expect(helper.page_title).to eq "Register a bike!" + expect(helper.page_description).to eq "Register a bike on Bike Index quickly, easily and for free. Create a permanent verified record of your bike to protect it." end end end - describe 'users_header_tags' do + describe "users_header_tags" do let(:avatar) { AvatarUploader.new } - let(:controller_name) { 'users' } - let(:action_name) { 'show' } - context 'with user title, and avatar' do - let(:user) { FactoryBot.build(:user, name: 'John', title: "John's bikes") } - it 'returns the user avatar, title and titled description' do - allow(avatar).to receive(:url) { 'http://something.com' } + let(:controller_name) { "users" } + let(:action_name) { "show" } + context "with user title, and avatar" do + let(:user) { FactoryBot.build(:user, name: "John", title: "John's bikes") } + it "returns the user avatar, title and titled description" do + allow(avatar).to receive(:url) { "http://something.com" } allow(user).to receive(:avatar) { avatar } @user = user helper.users_header_tags expect(helper.page_title).to eq "John's bikes" expect(helper.page_description).to eq "John's bikes on Bike Index" - expect(helper.page_image).to eq 'http://something.com' + expect(helper.page_image).to eq "http://something.com" end end - context 'with no user title and blank avatar' do - let(:user) { FactoryBot.build(:user, name: 'John') } - it 'has default image and a title' do - allow(avatar).to receive(:url) { 'https://files.bikeindex.org/blank.png' } + context "with no user title and blank avatar" do + let(:user) { FactoryBot.build(:user, name: "John") } + it "has default image and a title" do + allow(avatar).to receive(:url) { "https://files.bikeindex.org/blank.png" } allow(user).to receive(:avatar) { avatar } @user = user helper.users_header_tags - expect(helper.page_title).to eq 'View user' - expect(helper.page_image).to eq '/bike_index.png' + expect(helper.page_title).to eq "View user" + expect(helper.page_image).to eq "/bike_index.png" end end end - describe 'bikes_header_tags' do + describe "bikes_header_tags" do let(:bike) { Bike.new(stolen: true) } - context 'new stolen bike' do + context "new stolen bike" do let(:user) { FactoryBot.build(:user) } - it 'says new stolen on new stolen' do + it "says new stolen on new stolen" do allow(view).to receive(:current_user).and_return(user) - allow(view).to receive(:action_name).and_return('new') + allow(view).to receive(:action_name).and_return("new") @bike = bike # So that it's assigned in the helper helper.bikes_header_tags - expect(helper.page_title).to eq 'Register a stolen bike' - expect(helper.page_description).to_not eq 'Blank' + expect(helper.page_title).to eq "Register a stolen bike" + expect(helper.page_description).to_not eq "Blank" end end - describe 'show' do - let(:action_name) { 'show' } - before { allow(bike).to receive(:title_string) { 'Something special 1969' } } - context 'default' do - it 'returns the bike name on Show' do - allow(bike).to receive(:stock_photo_url) { 'http://something.com' } + describe "show" do + let(:action_name) { "show" } + before { allow(bike).to receive(:title_string) { "Something special 1969" } } + context "default" do + it "returns the bike name on Show" do + allow(bike).to receive(:stock_photo_url) { "http://something.com" } @bike = bike # So that it's assigned in the helper header_tags = helper.bikes_header_tags - expect(helper.page_title).to eq 'Stolen Something special 1969' - expect(helper.page_description).not_to eq 'Blank' + expect(helper.page_title).to eq "Stolen Something special 1969" + expect(helper.page_description).not_to eq "Blank" og_image = header_tags.select { |t| t && t[/og.image/] }.first - twitter_image = header_tags.select { |t| t && t.include?('twitter:image') }.first - expect(og_image.include?('http://something.com')).to be_truthy - expect(twitter_image.include?('http://something.com')).to be_truthy - expect(header_tags.select { |t| t && t.include?('twitter:card') }.first).to match 'summary_large_image' + twitter_image = header_tags.select { |t| t && t.include?("twitter:image") }.first + expect(og_image.include?("http://something.com")).to be_truthy + expect(twitter_image.include?("http://something.com")).to be_truthy + expect(header_tags.select { |t| t && t.include?("twitter:card") }.first).to match "summary_large_image" end end - context 'twitter present and shown' do - it 'has twitter creator if present and shown' do - user = User.new(twitter: 'coolio', show_twitter: true) + context "twitter present and shown" do + it "has twitter creator if present and shown" do + user = User.new(twitter: "coolio", show_twitter: true) allow(bike).to receive(:owner).and_return(user) @bike = bike # So that it's assigned in the helper header_tags = helper.bikes_header_tags - expect(header_tags.select { |t| t && t.include?('twitter:creator') }.first).to match '@coolio' + expect(header_tags.select { |t| t && t.include?("twitter:creator") }.first).to match "@coolio" end end - context 'twitter present and not shown' do + context "twitter present and not shown" do it "doesn't include twitter creator" do - user = User.new(twitter: 'coolio') + user = User.new(twitter: "coolio") allow(bike).to receive(:owner).and_return(user) @bike = bike # So that it's assigned in the helper header_tags = helper.bikes_header_tags - expect(header_tags.select { |t| t && t.include?('twitter:creator') }.first).to match '@bikeindex' + expect(header_tags.select { |t| t && t.include?("twitter:creator") }.first).to match "@bikeindex" end end end end - describe 'news_header_tags' do - let(:controller_name) { 'news' } + describe "news_header_tags" do + let(:controller_name) { "news" } let(:auto_discovery_tag) { '' } - describe 'index' do - let(:action_name) { 'index' } - it 'adds auto_discovery_link' do + describe "index" do + let(:action_name) { "index" } + it "adds auto_discovery_link" do expect(helper.news_header_tags.last).to eq auto_discovery_tag end end - describe 'show' do - let(:action_name) { 'show' } + describe "show" do + let(:action_name) { "show" } let(:target_time) { (Time.now - 1.hour).utc } # Have to create user so it creates a path for the user - let(:user) { FactoryBot.create(:user, name: 'John', twitter: 'stolenbikereg') } + let(:user) { FactoryBot.create(:user, name: "John", twitter: "stolenbikereg") } let(:blog) do FactoryBot.build(:blog, - title: 'Cool blog', - description_abbr: 'Bike Index did something cool', - published_at: target_time, - updated_at: target_time, - user: user) + title: "Cool blog", + description_abbr: "Bike Index did something cool", + published_at: target_time, + updated_at: target_time, + user: user) end - let(:target_url) { 'http://something.com' } - context 'index image present' do - it 'adds the index image and the tags we want' do + let(:target_url) { "http://something.com" } + context "index image present" do + it "adds the index image and the tags we want" do allow(blog).to receive(:index_image) { target_url } allow(blog).to receive(:index_image_lg) { target_url } @blog = blog header_tags = helper.news_header_tags - expect(helper.page_title).to eq 'Cool blog' - expect(helper.page_description).to eq 'Bike Index did something cool' - expect(helper.page_image).to eq 'http://something.com' - expect(header_tags.select { |t| t && t.include?('og:type') }.first).to match 'article' - expect(header_tags.select { |t| t && t.include?('twitter:creator') }.first).to match '@stolenbikereg' - expect(header_tags.select { |t| t && t.include?('og:published_time') }.first).to match target_time.to_s - expect(header_tags.select { |t| t && t.include?('og:modified_time') }.first).to match target_time.to_s + expect(helper.page_title).to eq "Cool blog" + expect(helper.page_description).to eq "Bike Index did something cool" + expect(helper.page_image).to eq "http://something.com" + expect(header_tags.select { |t| t && t.include?("og:type") }.first).to match "article" + expect(header_tags.select { |t| t && t.include?("twitter:creator") }.first).to match "@stolenbikereg" + expect(header_tags.select { |t| t && t.include?("og:published_time") }.first).to match target_time.to_s + expect(header_tags.select { |t| t && t.include?("og:modified_time") }.first).to match target_time.to_s expect(header_tags.include?(auto_discovery_tag)).to be_truthy expect(header_tags.include?("")).to be_truthy end end - context 'public_image present' do + context "public_image present" do let(:public_image) { PublicImage.new } - it 'adds the public image we want' do + it "adds the public image we want" do allow(public_image).to receive(:image_url) { target_url } allow(blog).to receive(:public_images) { [public_image] } allow(blog).to receive(:index_image_lg) { target_url } @blog = blog header_tags = helper.news_header_tags - expect(helper.page_title).to eq 'Cool blog' - expect(helper.page_image).to eq 'http://something.com' + expect(helper.page_title).to eq "Cool blog" + expect(helper.page_image).to eq "http://something.com" expect(header_tags.include?(auto_discovery_tag)).to be_truthy expect(header_tags.include?("")).to be_truthy end diff --git a/spec/initializers/email_normalizer_spec.rb b/spec/initializers/email_normalizer_spec.rb index fb0e38b896..f0250bb999 100644 --- a/spec/initializers/email_normalizer_spec.rb +++ b/spec/initializers/email_normalizer_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require "spec_helper" describe EmailNormalizer do - describe 'normalize' do - context 'spaces and capitals' do - it 'normalizes them' do - expect(EmailNormalizer.normalize(" awesome@stuff.COM \t")).to eq 'awesome@stuff.com' + describe "normalize" do + context "spaces and capitals" do + it "normalizes them" do + expect(EmailNormalizer.normalize(" awesome@stuff.COM \t")).to eq "awesome@stuff.com" end end - context 'nil' do + context "nil" do it "doesn't break on nil" do - expect(EmailNormalizer.normalize()).to eq('') + expect(EmailNormalizer.normalize()).to eq("") end end end diff --git a/spec/initializers/slugify_spec.rb b/spec/initializers/slugify_spec.rb index 36479104ea..c05c2c6543 100644 --- a/spec/initializers/slugify_spec.rb +++ b/spec/initializers/slugify_spec.rb @@ -1,57 +1,57 @@ # encoding: utf-8 -require 'spec_helper' +require "spec_helper" describe Slugifyer do - describe 'book_slug' do - it 'removes special characters and downcase' do + describe "book_slug" do + it "removes special characters and downcase" do slug = Slugifyer.book_slug("Surly's Cross-check bike (small wheel)") - expect(slug).to eq('surly_s_cross_check_small_wheel') + expect(slug).to eq("surly_s_cross_check_small_wheel") end - it 'removes bikes and bicycles, because people just put them in everything' do - slug = Slugifyer.book_slug('Cross-check Singlespeed BicyclE') - expect(slug).to eq('cross_check_singlespeed') + it "removes bikes and bicycles, because people just put them in everything" do + slug = Slugifyer.book_slug("Cross-check Singlespeed BicyclE") + expect(slug).to eq("cross_check_singlespeed") end - it 'removes diacritics and bicycles, because people just put them in everything' do - slug = Slugifyer.book_slug('paké rum runner') - expect(slug).to eq('pake_rum_runner') + it "removes diacritics and bicycles, because people just put them in everything" do + slug = Slugifyer.book_slug("paké rum runner") + expect(slug).to eq("pake_rum_runner") end - it 'changes + to plus for URL safety, and Trek uses + to differentiate' do - slug = Slugifyer.book_slug('L100+ Lowstep BLX') - expect(slug).to eq('l100plus_lowstep_blx') + it "changes + to plus for URL safety, and Trek uses + to differentiate" do + slug = Slugifyer.book_slug("L100+ Lowstep BLX") + expect(slug).to eq("l100plus_lowstep_blx") end end - describe 'manufacturer' do - it 'removes works rivendell' do - slug = Slugifyer.manufacturer('Rivendell Bicycle Works') - expect(slug).to eq('rivendell') - end - it 'removes frameworks for legacy' do - slug = Slugifyer.manufacturer('Legacy Frameworks') - expect(slug).to eq('legacy') - end - it 'removes bicycle company for Kona' do - slug = Slugifyer.manufacturer('Kona Bicycle Company') - expect(slug).to eq('kona') - end - it 'does not remove WorkCycles' do - slug = Slugifyer.manufacturer('WorkCycles') - expect(slug).to eq('workcycles') - end - it 'does not remove haibike' do - slug = Slugifyer.manufacturer('Haibike (Currietech)') - expect(slug).to eq('haibike') - end - it 'does not remove worksman' do - slug = Slugifyer.manufacturer('Worksman Cycles') - expect(slug).to eq('worksman') - end - it 'removes parens from EAI' do - slug = Slugifyer.manufacturer('EAI (Euro Asia Imports)') - expect(slug).to eq('eai') + describe "manufacturer" do + it "removes works rivendell" do + slug = Slugifyer.manufacturer("Rivendell Bicycle Works") + expect(slug).to eq("rivendell") + end + it "removes frameworks for legacy" do + slug = Slugifyer.manufacturer("Legacy Frameworks") + expect(slug).to eq("legacy") + end + it "removes bicycle company for Kona" do + slug = Slugifyer.manufacturer("Kona Bicycle Company") + expect(slug).to eq("kona") + end + it "does not remove WorkCycles" do + slug = Slugifyer.manufacturer("WorkCycles") + expect(slug).to eq("workcycles") + end + it "does not remove haibike" do + slug = Slugifyer.manufacturer("Haibike (Currietech)") + expect(slug).to eq("haibike") + end + it "does not remove worksman" do + slug = Slugifyer.manufacturer("Worksman Cycles") + expect(slug).to eq("worksman") + end + it "removes parens from EAI" do + slug = Slugifyer.manufacturer("EAI (Euro Asia Imports)") + expect(slug).to eq("eai") end end end diff --git a/spec/initializers/urlifyer_spec.rb b/spec/initializers/urlifyer_spec.rb index 37c3e466c8..cf3241be22 100644 --- a/spec/initializers/urlifyer_spec.rb +++ b/spec/initializers/urlifyer_spec.rb @@ -1,23 +1,23 @@ # encoding: utf-8 -require 'spec_helper' +require "spec_helper" describe Urlifyer do - describe 'urlify' do - it 'does nothing if no website is present' do + describe "urlify" do + it "does nothing if no website is present" do website = Urlifyer.urlify(nil) expect(website).to be_nil - website = Urlifyer.urlify('i') + website = Urlifyer.urlify("i") expect(website).to be_nil end it "adds http:// if the website doesn't have it" do - website = Urlifyer.urlify('www.somafab.com') - expect(website).to eq('http://www.somafab.com') + website = Urlifyer.urlify("www.somafab.com") + expect(website).to eq("http://www.somafab.com") end it "doesn't do anything if the site has https://" do - website = Urlifyer.urlify('http://www.somafab.com') - expect(website).to eq('http://www.somafab.com') + website = Urlifyer.urlify("http://www.somafab.com") + expect(website).to eq("http://www.somafab.com") end it "doesn't let you do sweet XSS because http is present in the string" do diff --git a/spec/lib/file_cache_maintainer_spec.rb b/spec/lib/file_cache_maintainer_spec.rb index c55a13e0da..ad2f862381 100644 --- a/spec/lib/file_cache_maintainer_spec.rb +++ b/spec/lib/file_cache_maintainer_spec.rb @@ -1,25 +1,25 @@ -require 'spec_helper' +require "spec_helper" describe FileCacheMaintainer do - describe 'cached_all_stolen' do - it 'returns the most recent all_stolen' do - FileCacheMaintainer.update_file_info('1456863086_all_stolen_cache.json', 1456863086) + describe "cached_all_stolen" do + it "returns the most recent all_stolen" do + FileCacheMaintainer.update_file_info("1456863086_all_stolen_cache.json", 1456863086) t = Time.now.to_i FileCacheMaintainer.update_file_info("#{t}_all_stolen_cache.json", t) target = { - 'path' => "#{t}_all_stolen_cache.json", - 'filename' => "#{t}_all_stolen_cache.json", - 'daily' => true, - 'updated_at' => t.to_s, - 'description' => nil + "path" => "#{t}_all_stolen_cache.json", + "filename" => "#{t}_all_stolen_cache.json", + "daily" => true, + "updated_at" => t.to_s, + "description" => nil, } expect(FileCacheMaintainer.cached_all_stolen).to eq(target) end end - describe 'blacklist_ids' do - it 'gets and sets the ids' do - FileCacheMaintainer.reset_blacklist_ids([1, 1, 2, 4, 'https://bikeindex.org/admin/bikes/6']) + describe "blacklist_ids" do + it "gets and sets the ids" do + FileCacheMaintainer.reset_blacklist_ids([1, 1, 2, 4, "https://bikeindex.org/admin/bikes/6"]) expect(FileCacheMaintainer.blacklist).to eq %w(1 2 4 6) end it "doesn't break if it's empty" do @@ -28,49 +28,49 @@ end end - describe 'blacklist_include' do - it 'checks if blacklist includes something' do + describe "blacklist_include" do + it "checks if blacklist includes something" do FileCacheMaintainer.reset_blacklist_ids([1010101, 2, 4, 6]) - expect(FileCacheMaintainer.blacklist_include?('http://bikeindex.org/bikes/1010101/edit')).to be_truthy + expect(FileCacheMaintainer.blacklist_include?("http://bikeindex.org/bikes/1010101/edit")).to be_truthy expect(FileCacheMaintainer.blacklist_include?(7)).to be_falsey end end - describe 'tsv info' do - it 'updates tsv info and returns with indifferent access' do + describe "tsv info" do + it "updates tsv info and returns with indifferent access" do t = Time.now - FileCacheMaintainer.reset_file_info('current_stolen_bikes.tsv', t) + FileCacheMaintainer.reset_file_info("current_stolen_bikes.tsv", t) tsv = FileCacheMaintainer.files[0] expect(tsv[:updated_at]).to eq(t.to_i.to_s) expect(tsv[:daily]).to be_falsey - expect(tsv['path']).to eq('current_stolen_bikes.tsv') - expect(tsv['description']).to eq('Stolen') + expect(tsv["path"]).to eq("current_stolen_bikes.tsv") + expect(tsv["description"]).to eq("Stolen") end - it 'returns the way we want - dailys after non daily' do + it "returns the way we want - dailys after non daily" do t = Time.now - FileCacheMaintainer.reset_file_info('https://files.bikeindex.org/uploads/tsvs/approved_current_stolen_bikes.tsv', t) - FileCacheMaintainer.update_file_info('https://files.bikeindex.org/uploads/tsvs/current_stolen_bikes.tsv') - FileCacheMaintainer.update_file_info("https://files.bikeindex.org/uploads/tsvs/#{Time.now.strftime('%Y_%-m_%-d')}_approved_current_stolen_bikes.tsv") - FileCacheMaintainer.update_file_info("https://files.bikeindex.org/uploads/tsvs/#{Time.now.strftime('%Y_%-m_%-d')}_current_stolen_bikes.tsv") + FileCacheMaintainer.reset_file_info("https://files.bikeindex.org/uploads/tsvs/approved_current_stolen_bikes.tsv", t) + FileCacheMaintainer.update_file_info("https://files.bikeindex.org/uploads/tsvs/current_stolen_bikes.tsv") + FileCacheMaintainer.update_file_info("https://files.bikeindex.org/uploads/tsvs/#{Time.now.strftime("%Y_%-m_%-d")}_approved_current_stolen_bikes.tsv") + FileCacheMaintainer.update_file_info("https://files.bikeindex.org/uploads/tsvs/#{Time.now.strftime("%Y_%-m_%-d")}_current_stolen_bikes.tsv") FileCacheMaintainer.files.each_with_index do |file, index| if index < 2 - expect(['approved_current_stolen_bikes.tsv', 'current_stolen_bikes.tsv'].include?(file[:filename])).to be_truthy + expect(["approved_current_stolen_bikes.tsv", "current_stolen_bikes.tsv"].include?(file[:filename])).to be_truthy else - expect(["#{Time.now.strftime('%Y_%-m_%-d')}_approved_current_stolen_bikes.tsv", "#{Time.now.strftime('%Y_%-m_%-d')}_current_stolen_bikes.tsv"].include?(file[:filename])).to be_truthy + expect(["#{Time.now.strftime("%Y_%-m_%-d")}_approved_current_stolen_bikes.tsv", "#{Time.now.strftime("%Y_%-m_%-d")}_current_stolen_bikes.tsv"].include?(file[:filename])).to be_truthy end end end end - describe 'remove_file' do - it 'deletes the file' do + describe "remove_file" do + it "deletes the file" do FactoryBot.create(:stolen_bike) - FileCacheMaintainer.reset_file_info('1456863086_all_stolen_cache.json', 1456863086) + FileCacheMaintainer.reset_file_info("1456863086_all_stolen_cache.json", 1456863086) CacheAllStolenWorker.new.perform files_count = FileCacheMaintainer.files.count cached_all_stolen = FileCacheMaintainer.cached_all_stolen - expect(Dir['spec/fixtures/tsv_creation/*'].join).to match(cached_all_stolen['filename']) + expect(Dir["spec/fixtures/tsv_creation/*"].join).to match(cached_all_stolen["filename"]) FileCacheMaintainer.remove_file(cached_all_stolen) expect(FileCacheMaintainer.files.count).to eq(files_count - 1) # For some reason, carrierwave doesn't deleting the file in tests, but it works diff --git a/spec/lib/integrations/bike_book_integration_spec.rb b/spec/lib/integrations/bike_book_integration_spec.rb index ec121f5c77..bdadc949d7 100644 --- a/spec/lib/integrations/bike_book_integration_spec.rb +++ b/spec/lib/integrations/bike_book_integration_spec.rb @@ -1,35 +1,35 @@ -require 'spec_helper' +require "spec_helper" describe BikeBookIntegration do - describe 'get_model' do - it 'returns a hash with the model for Co-motion' do - manufacturer = FactoryBot.create(:manufacturer, name: 'Co-Motion') - bike = { manufacturer: manufacturer.name, frame_model: 'Americano Rohloff', year: 2014 } + describe "get_model" do + it "returns a hash with the model for Co-motion" do + manufacturer = FactoryBot.create(:manufacturer, name: "Co-Motion") + bike = { manufacturer: manufacturer.name, frame_model: "Americano Rohloff", year: 2014 } response = BikeBookIntegration.new.get_model(bike) - expect(response[:bike][:frame_model]).to eq('Americano Rohloff') - fork = { ctype: 'fork', description: 'Easton EC 90X' } + expect(response[:bike][:frame_model]).to eq("Americano Rohloff") + fork = { ctype: "fork", description: "Easton EC 90X" } expect(response[:components].count).to eq(8) end - it 'returns a hash of the model for Surly' do - manufacturer = FactoryBot.create(:manufacturer, name: 'Surly') - bike = { manufacturer: manufacturer.name, frame_model: 'Pugsley', year: 2013 } + it "returns a hash of the model for Surly" do + manufacturer = FactoryBot.create(:manufacturer, name: "Surly") + bike = { manufacturer: manufacturer.name, frame_model: "Pugsley", year: 2013 } response = BikeBookIntegration.new.get_model(bike) - expect(response[:bike][:frame_model]).to eq('Pugsley') + expect(response[:bike][:frame_model]).to eq("Pugsley") expect(response[:components].count).to eq(22) end - it 'returns nothing if it fails' do - manufacturer = FactoryBot.create(:manufacturer, name: 'Some crazy manufacturer we have nothing on') - bike = { manufacturer: manufacturer.name, frame_model: 'Pugsley', year: 2014 } + it "returns nothing if it fails" do + manufacturer = FactoryBot.create(:manufacturer, name: "Some crazy manufacturer we have nothing on") + bike = { manufacturer: manufacturer.name, frame_model: "Pugsley", year: 2014 } response = BikeBookIntegration.new.get_model(bike) expect(response).to be_nil end end - describe 'get_model_list' do + describe "get_model_list" do it "doesn't fail if bikebook is down" do - manufacturer = FactoryBot.create(:manufacturer, name: 'Giant') + manufacturer = FactoryBot.create(:manufacturer, name: "Giant") all_giants = BikeBookIntegration.new.get_model_list(manufacturer: manufacturer.name) expect(all_giants.is_a?(Array)).to be_truthy giants_from_2014 = BikeBookIntegration.new.get_model_list({ manufacturer: manufacturer.name, year: 2014 }) @@ -37,8 +37,8 @@ expect(all_giants.count).to be > giants_from_2014.count end - it 'returns an array with the models for Giant, and a smaller array for a specific year of giant' do - manufacturer = FactoryBot.create(:manufacturer, name: 'Giant') + it "returns an array with the models for Giant, and a smaller array for a specific year of giant" do + manufacturer = FactoryBot.create(:manufacturer, name: "Giant") all_giants = BikeBookIntegration.new.get_model_list(manufacturer: manufacturer.name) expect(all_giants.is_a?(Array)).to be_truthy giants_from_2014 = BikeBookIntegration.new.get_model_list({ manufacturer: manufacturer.name, year: 2014 }) @@ -46,8 +46,8 @@ expect(all_giants.count).to be > giants_from_2014.count end - it 'returns nothing if it fails' do - manufacturer = FactoryBot.create(:manufacturer, name: 'Some weird manufacturer') + it "returns nothing if it fails" do + manufacturer = FactoryBot.create(:manufacturer, name: "Some weird manufacturer") response = BikeBookIntegration.new.get_model_list(manufacturer: manufacturer.name) expect(response).to be_nil end diff --git a/spec/lib/integrations/stolen_twitterbot_integration_spec.rb b/spec/lib/integrations/stolen_twitterbot_integration_spec.rb index bf7e2cc402..769587aa4f 100644 --- a/spec/lib/integrations/stolen_twitterbot_integration_spec.rb +++ b/spec/lib/integrations/stolen_twitterbot_integration_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe StolenTwitterbotIntegration do - describe 'send_tweet' do - it 'sends a post request' do - ENV['STOLEN_TWITTERBOT_URL'] = 'http://example.com' + describe "send_tweet" do + it "sends a post request" do + ENV["STOLEN_TWITTERBOT_URL"] = "http://example.com" expect(HTTParty).to receive(:post) StolenTwitterbotIntegration.new.send_tweet(101) end diff --git a/spec/lib/tsv_creator_spec.rb b/spec/lib/tsv_creator_spec.rb index 9bd58c2c80..8d346e5e1a 100644 --- a/spec/lib/tsv_creator_spec.rb +++ b/spec/lib/tsv_creator_spec.rb @@ -1,16 +1,16 @@ -require 'spec_helper' +require "spec_helper" describe TsvCreator do - describe 'create_manufacturer' do - it 'makes mnfgs' + describe "create_manufacturer" do + it "makes mnfgs" end - describe 'sent_to_uploader' do - it 'sends to uploader' + describe "sent_to_uploader" do + it "sends to uploader" end - describe 'create_organization_count' do - it 'creates tsv with output bikes' do + describe "create_organization_count" do + it "creates tsv with output bikes" do ownership = FactoryBot.create(:ownership_organization_bike) organization = ownership.bike.creation_organization creator = TsvCreator.new @@ -22,21 +22,21 @@ end end - describe 'enqueue_creation' do - it 'creates jobs for the TSV creation' do + describe "enqueue_creation" do + it "creates jobs for the TSV creation" do expect do TsvCreator.enqueue_creation end.to change(TsvCreatorWorker.jobs, :size).by(4) - expect(TsvCreatorWorker.jobs.select { |j| j['args'] == ['create_manufacturer'] }).to be_present - expect(TsvCreatorWorker.jobs.select { |j| j['args'] == ['create_stolen_with_reports', true] }).to be_present - expect(TsvCreatorWorker.jobs.select { |j| j['args'] == ['create_stolen', true] }).to be_present - expect(TsvCreatorWorker.jobs.select { |j| j['args'] == ['create_daily_tsvs'] }).to be_present + expect(TsvCreatorWorker.jobs.select { |j| j["args"] == ["create_manufacturer"] }).to be_present + expect(TsvCreatorWorker.jobs.select { |j| j["args"] == ["create_stolen_with_reports", true] }).to be_present + expect(TsvCreatorWorker.jobs.select { |j| j["args"] == ["create_stolen", true] }).to be_present + expect(TsvCreatorWorker.jobs.select { |j| j["args"] == ["create_daily_tsvs"] }).to be_present end end - describe 'create_daily_tsvs' do - it 'calls create_stolen and create_stolen_with_reports with scoped query' do + describe "create_daily_tsvs" do + it "calls create_stolen and create_stolen_with_reports with scoped query" do stolen_record = FactoryBot.create(:stolen_record, current: true, tsved_at: nil) tsv_creator = TsvCreator.new expect(tsv_creator).to receive(:create_stolen_with_reports).with(true, stolen_records: StolenRecord.approveds_with_reports.tsv_today) diff --git a/spec/mailers/admin_mailer_spec.rb b/spec/mailers/admin_mailer_spec.rb index dc8c64da92..3a5b145ff6 100644 --- a/spec/mailers/admin_mailer_spec.rb +++ b/spec/mailers/admin_mailer_spec.rb @@ -1,93 +1,93 @@ -require 'spec_helper' +require "spec_helper" describe AdminMailer do - describe 'feedback_notification_email' do + describe "feedback_notification_email" do before :each do @feedback = FactoryBot.create(:feedback) @mail = AdminMailer.feedback_notification_email(@feedback) end - it 'renders email' do - expect(@mail.subject).to eq('New Feedback Submitted') - expect(@mail.to).to eq(['contact@bikeindex.org']) + it "renders email" do + expect(@mail.subject).to eq("New Feedback Submitted") + expect(@mail.to).to eq(["contact@bikeindex.org"]) expect(@mail.reply_to).to eq([@feedback.email]) end end - describe 'special_feedback_notification_email' do + describe "special_feedback_notification_email" do before :each do @bike = FactoryBot.create(:bike) @feedback = FactoryBot.create(:feedback, feedback_hash: { bike_id: @bike.id }) end - it 'sends a delete request email' do - @feedback.update_attributes(feedback_type: 'bike_delete_request') + it "sends a delete request email" do + @feedback.update_attributes(feedback_type: "bike_delete_request") mail = AdminMailer.feedback_notification_email(@feedback) - expect(mail.subject).to eq('New Feedback Submitted') - expect(mail.to).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("New Feedback Submitted") + expect(mail.to).to eq(["contact@bikeindex.org"]) expect(mail.reply_to).to eq([@feedback.email]) end - it 'sends a recovery email' do - @feedback.update_attributes(feedback_type: 'bike_recovery') + it "sends a recovery email" do + @feedback.update_attributes(feedback_type: "bike_recovery") mail = AdminMailer.feedback_notification_email(@feedback) - expect(mail.subject).to eq('New Feedback Submitted') - expect(mail.to).to eq(['contact@bikeindex.org', 'bryan@bikeindex.org', 'lily@bikeindex.org']) + expect(mail.subject).to eq("New Feedback Submitted") + expect(mail.to).to eq(["contact@bikeindex.org", "bryan@bikeindex.org", "lily@bikeindex.org"]) expect(mail.reply_to).to eq([@feedback.email]) end - it 'sends a stolen_information email' do - @feedback.update_attributes(feedback_type: 'stolen_information') + it "sends a stolen_information email" do + @feedback.update_attributes(feedback_type: "stolen_information") mail = AdminMailer.feedback_notification_email(@feedback) - expect(mail.to).to eq(['bryan@bikeindex.org']) + expect(mail.to).to eq(["bryan@bikeindex.org"]) end - it 'sends a serial update email' do - @feedback.update_attributes(feedback_type: 'serial_update_request') + it "sends a serial update email" do + @feedback.update_attributes(feedback_type: "serial_update_request") mail = AdminMailer.feedback_notification_email(@feedback) - expect(mail.subject).to eq('New Feedback Submitted') - expect(mail.to).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("New Feedback Submitted") + expect(mail.to).to eq(["contact@bikeindex.org"]) expect(mail.reply_to).to eq([@feedback.email]) end - it 'sends a new org email' do + it "sends a new org email" do organization = FactoryBot.create(:organization) user = FactoryBot.create(:user) FactoryBot.create(:membership, user: user, organization: organization) - @feedback.update_attributes(feedback_hash: { organization_id: organization.id }, feedback_type: 'organization_created') + @feedback.update_attributes(feedback_hash: { organization_id: organization.id }, feedback_type: "organization_created") mail = AdminMailer.feedback_notification_email(@feedback) expect(mail.reply_to).to eq([@feedback.email]) end end - context 'user_hidden bike' do + context "user_hidden bike" do let(:ownership) { FactoryBot.create(:ownership, user_hidden: true) } let(:bike) { ownership.bike } - let(:feedback) { FactoryBot.create(:feedback, feedback_hash: { bike_id: bike.id }, feedback_type: 'bike_delete_request') } + let(:feedback) { FactoryBot.create(:feedback, feedback_hash: { bike_id: bike.id }, feedback_type: "bike_delete_request") } it "doesn't explode" do bike.update_attribute :hidden, true bike.reload expect(bike.user_hidden).to be_truthy mail = AdminMailer.feedback_notification_email(feedback) - expect(mail.subject).to eq('New Feedback Submitted') - expect(mail.to).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("New Feedback Submitted") + expect(mail.to).to eq(["contact@bikeindex.org"]) expect(mail.reply_to).to eq([feedback.email]) end end - describe 'no_admins_notification_email' do + describe "no_admins_notification_email" do before :each do @organization = FactoryBot.create(:organization) @mail = AdminMailer.no_admins_notification_email(@organization) end - it 'renders email' do - expect(@mail.to).to eq(['contact@bikeindex.org']) + it "renders email" do + expect(@mail.to).to eq(["contact@bikeindex.org"]) expect(@mail.subject).to match("doesn't have any admins") end end - describe 'blocked_stolen_notification_email' do + describe "blocked_stolen_notification_email" do before :each do - @stolen_notification = FactoryBot.create(:stolen_notification, message: 'Test Message', subject: 'Test subject') + @stolen_notification = FactoryBot.create(:stolen_notification, message: "Test Message", subject: "Test subject") @mail = AdminMailer.blocked_stolen_notification_email(@stolen_notification) end - it 'renders email' do + it "renders email" do expect(@mail.subject[/blocked/i].present?).to be_truthy expect(@mail.body.encoded).to match(@stolen_notification.message) end diff --git a/spec/mailers/customer_mailer_spec.rb b/spec/mailers/customer_mailer_spec.rb index ce01adf4f1..10a58bf385 100644 --- a/spec/mailers/customer_mailer_spec.rb +++ b/spec/mailers/customer_mailer_spec.rb @@ -1,19 +1,19 @@ -require 'spec_helper' +require "spec_helper" describe CustomerMailer do let(:user) { FactoryBot.create(:user) } - describe 'welcome_email' do - it 'renders an email' do + describe "welcome_email" do + it "renders an email" do mail = CustomerMailer.welcome_email(user) - expect(mail.subject).to eq('Welcome to Bike Index!') - expect(mail.from).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("Welcome to Bike Index!") + expect(mail.from).to eq(["contact@bikeindex.org"]) expect(mail.to).to eq([user.email]) end end - describe 'confirmation_email' do - it 'renders email' do + describe "confirmation_email" do + it "renders email" do mail = CustomerMailer.confirmation_email(user) expect(mail.subject).to eq("Please confirm your Bike Index email!") expect(mail.to).to eq([user.email]) @@ -31,118 +31,118 @@ end end - describe 'password_reset_email' do - it 'renders email' do + describe "password_reset_email" do + it "renders email" do user.set_password_reset_token mail = CustomerMailer.password_reset_email(user) - expect(mail.subject).to eq('Instructions to reset your password') - expect(mail.from).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("Instructions to reset your password") + expect(mail.from).to eq(["contact@bikeindex.org"]) expect(mail.body.encoded).to match(user.password_reset_token) end end - describe 'additional_email_confirmation' do + describe "additional_email_confirmation" do let(:user_email) { FactoryBot.create(:user_email) } - it 'renders email' do + it "renders email" do mail = CustomerMailer.additional_email_confirmation(user_email) expect(mail.subject).to match(/confirm/i) - expect(mail.from).to eq(['contact@bikeindex.org']) + expect(mail.from).to eq(["contact@bikeindex.org"]) end end - describe 'invoice_email' do - context 'donation' do + describe "invoice_email" do + context "donation" do let(:payment) { FactoryBot.create(:payment, user: user) } - it 'renders email' do + it "renders email" do mail = CustomerMailer.invoice_email(payment) - expect(mail.subject).to eq('Thank you for supporting Bike Index!') + expect(mail.subject).to eq("Thank you for supporting Bike Index!") expect(mail.to).to eq([user.email]) - expect(mail.from).to eq(['contact@bikeindex.org']) - expect(mail.body.encoded).to match 'donation of' + expect(mail.from).to eq(["contact@bikeindex.org"]) + expect(mail.body.encoded).to match "donation of" end end - context 'payment' do + context "payment" do let(:payment) { FactoryBot.create(:payment, user: user, is_payment: true) } - it 'renders email' do + it "renders email" do mail = CustomerMailer.invoice_email(payment) - expect(mail.subject).to eq('Thank you for supporting Bike Index!') + expect(mail.subject).to eq("Thank you for supporting Bike Index!") expect(mail.to).to eq([user.email]) - expect(mail.from).to eq(['contact@bikeindex.org']) - expect(mail.body.encoded).to_not match 'donation of' + expect(mail.from).to eq(["contact@bikeindex.org"]) + expect(mail.body.encoded).to_not match "donation of" end end end - describe 'stolen_bike_alert_email' do + describe "stolen_bike_alert_email" do let!(:ownership) { FactoryBot.create(:ownership, bike: stolen_record.bike) } let(:stolen_record) { FactoryBot.create(:stolen_record) } let(:notification_hash) do { - notification_type: 'stolen_twitter_alerter', + notification_type: "stolen_twitter_alerter", bike_id: stolen_record.bike.id, tweet_id: 69, - tweet_string: 'STOLEN - something special', - tweet_account_screen_name: 'bikeindex', - tweet_account_name: 'Bike Index', - tweet_account_image: 'https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png', - location: 'Everywhere', - retweet_screen_names: %w(someother_screename and_another) + tweet_string: "STOLEN - something special", + tweet_account_screen_name: "bikeindex", + tweet_account_name: "Bike Index", + tweet_account_image: "https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png", + location: "Everywhere", + retweet_screen_names: %w(someother_screename and_another), } end - let(:customer_contact) { FactoryBot.create(:customer_contact, info_hash: notification_hash, title: 'CUSTOM CUSTOMER contact Title', bike: stolen_record.bike) } - it 'renders email' do + let(:customer_contact) { FactoryBot.create(:customer_contact, info_hash: notification_hash, title: "CUSTOM CUSTOMER contact Title", bike: stolen_record.bike) } + it "renders email" do mail = CustomerMailer.stolen_bike_alert_email(customer_contact) expect(mail.to).to eq([customer_contact.user_email]) - expect(mail.subject).to eq 'CUSTOM CUSTOMER contact Title' - expect(mail.from).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq "CUSTOM CUSTOMER contact Title" + expect(mail.from).to eq(["contact@bikeindex.org"]) end end - describe 'recovered_from_link' do - let(:bike) { FactoryBot.create(:stolen_bike, cycle_type: 'tall-bike') } + describe "recovered_from_link" do + let(:bike) { FactoryBot.create(:stolen_bike, cycle_type: "tall-bike") } let(:stolen_record) { bike.current_stolen_record } let!(:ownership) { FactoryBot.create(:ownership, bike: stolen_record.bike) } - let(:recovered_description) { 'Bike Index helped me find my stolen bike and get it back!' } + let(:recovered_description) { "Bike Index helped me find my stolen bike and get it back!" } before { stolen_record.add_recovery_information(recovered_description: recovered_description) } - it 'renders email' do + it "renders email" do mail = CustomerMailer.recovered_from_link(stolen_record) expect(mail.to).to eq([bike.owner_email]) - expect(mail.subject).to eq 'Your tall bike has been marked recovered!' - expect(mail.from).to eq(['bryan@bikeindex.org']) + expect(mail.subject).to eq "Your tall bike has been marked recovered!" + expect(mail.from).to eq(["bryan@bikeindex.org"]) expect(mail.body.encoded).to match recovered_description end end - describe 'admin_contact_stolen_email' do + describe "admin_contact_stolen_email" do let!(:ownership) { FactoryBot.create(:ownership, bike: stolen_record.bike) } let(:stolen_record) { FactoryBot.create(:stolen_record) } - let(:user) { FactoryBot.create(:admin, email: 'something@stuff.com') } + let(:user) { FactoryBot.create(:admin, email: "something@stuff.com") } let(:customer_contact) do CustomerContact.create(user_email: stolen_record.bike.owner_email, creator_email: user.email, - body: 'some message', - contact_type: 'stolen_contact', + body: "some message", + contact_type: "stolen_contact", bike_id: stolen_record.bike.id, - title: 'some title') + title: "some title") end - it 'renders email' do + it "renders email" do mail = CustomerMailer.admin_contact_stolen_email(customer_contact) - expect(mail.subject).to eq('some title') - expect(mail.body.encoded).to match('some message') - expect(mail.reply_to).to eq(['something@stuff.com']) - expect(mail.from).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("some title") + expect(mail.body.encoded).to match("some message") + expect(mail.reply_to).to eq(["something@stuff.com"]) + expect(mail.from).to eq(["contact@bikeindex.org"]) end end - describe 'stolen_notification_email' do + describe "stolen_notification_email" do let(:stolen_record) { FactoryBot.create(:stolen_record) } let!(:ownership) { FactoryBot.create(:ownership, bike: stolen_record.bike) } - let(:stolen_notification) { FactoryBot.create(:stolen_notification, message: 'Test Message', reference_url: 'something.com', bike: stolen_record.bike) } - it 'renders email and update sent_dates' do + let(:stolen_notification) { FactoryBot.create(:stolen_notification, message: "Test Message", reference_url: "something.com", bike: stolen_record.bike) } + it "renders email and update sent_dates" do mail = CustomerMailer.stolen_notification_email(stolen_notification) expect(mail.subject).to eq(stolen_notification.default_subject) expect(mail.from.count).to eq(1) - expect(mail.from.first).to eq('bryan@bikeindex.org') + expect(mail.from.first).to eq("bryan@bikeindex.org") expect(mail.body.encoded).to match(stolen_notification.message) expect(mail.body.encoded).to match(stolen_notification.reference_url) stolen_notification.reload @@ -156,14 +156,14 @@ end end - describe 'updated_terms_email' do + describe "updated_terms_email" do let(:user) { FactoryBot.create(:user) } - it 'renders email' do + it "renders email" do mail = CustomerMailer.updated_terms_email(user) - expect(mail.subject).to eq 'Bike Index Terms and Privacy Policy Update' + expect(mail.subject).to eq "Bike Index Terms and Privacy Policy Update" expect(mail.from.count).to eq(1) - expect(mail.from.first).to eq('lily@bikeindex.org') - expect(mail.body.encoded).to_not match 'vendor terms' + expect(mail.from.first).to eq("lily@bikeindex.org") + expect(mail.body.encoded).to_not match "vendor terms" end end end diff --git a/spec/mailers/organized_mailer_spec.rb b/spec/mailers/organized_mailer_spec.rb index a97591dace..c4117e8a53 100644 --- a/spec/mailers/organized_mailer_spec.rb +++ b/spec/mailers/organized_mailer_spec.rb @@ -1,29 +1,29 @@ -require 'spec_helper' +require "spec_helper" describe OrganizedMailer do let(:organization) { FactoryBot.create(:organization_with_auto_user) } let(:header_mail_snippet) do FactoryBot.create(:organization_mail_snippet, - name: 'header', - organization: organization, - body: '

    HEADERXSNIPPET

    ') + name: "header", + organization: organization, + body: "

    HEADERXSNIPPET

    ") end - describe 'partial_registration' do - context 'without organization' do + describe "partial_registration" do + context "without organization" do let(:b_param) { FactoryBot.create(:b_param_stolen) } - it 'stolen renders, with reply to for the organization' do + it "stolen renders, with reply to for the organization" do expect(b_param.owner_email).to be_present mail = OrganizedMailer.partial_registration(b_param) - expect(mail.subject).to eq('Finish your Bike Index registration!') + expect(mail.subject).to eq("Finish your Bike Index registration!") expect(mail.to).to eq([b_param.owner_email]) - expect(mail.reply_to).to eq(['contact@bikeindex.org']) + expect(mail.reply_to).to eq(["contact@bikeindex.org"]) end end - context 'with organization' do + context "with organization" do let(:organization) { FactoryBot.create(:organization_with_auto_user) } - context 'non-stolen, organization has mail snippet' do + context "non-stolen, organization has mail snippet" do let(:b_param) { FactoryBot.create(:b_param_with_creation_organization, organization: organization) } - it 'renders, with reply to for the organization' do + it "renders, with reply to for the organization" do expect(b_param.owner_email).to be_present expect(header_mail_snippet).to be_present organization.reload @@ -36,9 +36,9 @@ context "with partial snippet" do let!(:partial_mail_snippet) do FactoryBot.create(:organization_mail_snippet, - name: "partial", - organization: organization, - body: '

    PARTIALYXSNIPPET

    ') + name: "partial", + organization: organization, + body: "

    PARTIALYXSNIPPET

    ") end it "includes mail snippet" do expect(b_param.owner_email).to be_present @@ -56,58 +56,58 @@ end end - describe 'finished_registration' do + describe "finished_registration" do let(:mail) { OrganizedMailer.finished_registration(ownership) } - context 'passed new ownership' do + context "passed new ownership" do let(:ownership) { FactoryBot.create(:ownership) } - it 'renders email' do - expect(mail.subject).to match 'Confirm your Bike Index registration' + it "renders email" do + expect(mail.subject).to match "Confirm your Bike Index registration" end end - context 'existing bike and ownership passed' do + context "existing bike and ownership passed" do let(:user) { FactoryBot.create(:user) } let(:ownership) { FactoryBot.create(:ownership, bike: bike) } - context 'non-stolen, multi-ownership' do + context "non-stolen, multi-ownership" do let(:ownership_1) { FactoryBot.create(:ownership, user: user, bike: bike) } - let(:bike) { FactoryBot.create(:bike, owner_email: 'someotheremail@stuff.com', creator_id: user.id) } - it 'renders email' do + let(:bike) { FactoryBot.create(:bike, owner_email: "someotheremail@stuff.com", creator_id: user.id) } + it "renders email" do expect(ownership_1).to be_present - expect(mail.subject).to eq('Confirm your Bike Index registration') - expect(mail.reply_to).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("Confirm your Bike Index registration") + expect(mail.reply_to).to eq(["contact@bikeindex.org"]) end end - context 'claimed registration (e.g. self_made)' do + context "claimed registration (e.g. self_made)" do let(:bike) { FactoryBot.create(:bike, creator_id: user.id) } - it 'renders email' do + it "renders email" do ownership.update_attribute :claimed, true ownership.reload expect(ownership.claimed).to be_truthy - expect(mail.subject).to eq('Bike Index registration successful') - expect(mail.reply_to).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("Bike Index registration successful") + expect(mail.reply_to).to eq(["contact@bikeindex.org"]) end end - context 'stolen' do + context "stolen" do let(:country) { FactoryBot.create(:country) } let(:bike) { FactoryBot.create(:stolen_bike) } - it 'renders email with the stolen title' do + it "renders email with the stolen title" do expect(mail.subject).to eq("Confirm your stolen #{bike.type} on Bike Index") - expect(mail.reply_to).to eq(['contact@bikeindex.org']) + expect(mail.reply_to).to eq(["contact@bikeindex.org"]) expect(mail.body.encoded).to match bike.current_stolen_record.find_or_create_recovery_link_token end end end - context 'organized snippets' do + context "organized snippets" do let(:welcome_mail_snippet) do FactoryBot.create(:organization_mail_snippet, - name: 'welcome', - organization: organization, - body: '

    WELCOMEXSNIPPET

    ') + name: "welcome", + organization: organization, + body: "

    WELCOMEXSNIPPET

    ") end let(:security_mail_snippet) do FactoryBot.create(:organization_mail_snippet, - name: 'security', - organization: organization, - body: '

    SECURITYXSNIPPET

    ') + name: "security", + organization: organization, + body: "

    SECURITYXSNIPPET

    ") end let(:ownership) { FactoryBot.create(:ownership, bike: bike) } @@ -116,9 +116,9 @@ expect(ownership.bike.ownerships.count).to eq 1 expect(organization.mail_snippets.count).to eq 3 end - context 'new non-stolen bike' do + context "new non-stolen bike" do let(:bike) { FactoryBot.create(:organization_bike, creation_organization: organization) } - it 'renders email and includes the snippets' do + it "renders email and includes the snippets" do expect(mail.subject).to eq("Confirm your #{organization.short_name} Bike Index registration") expect(mail.body.encoded).to match header_mail_snippet.body expect(mail.body.encoded).to match welcome_mail_snippet.body @@ -126,9 +126,9 @@ expect(mail.reply_to).to eq([organization.auto_user.email]) end end - context 'new stolen registration' do + context "new stolen registration" do let(:bike) { FactoryBot.create(:stolen_bike, creation_organization: organization) } - it 'renders and includes the org name in the title' do + it "renders and includes the org name in the title" do expect(mail.body.encoded).to match header_mail_snippet.body expect(mail.body.encoded).to match welcome_mail_snippet.body expect(mail.body.encoded).to match security_mail_snippet.body @@ -136,7 +136,7 @@ expect(mail.reply_to).to eq([organization.auto_user.email]) end end - context 'non-new (pre-existing ownership)' do + context "non-new (pre-existing ownership)" do let(:bike) { FactoryBot.create(:bike, creation_organization: organization) } let(:pre_existing_ownership) { FactoryBot.create(:ownership, bike: bike, created_at: Time.now - 1.minute) } before do @@ -149,20 +149,20 @@ expect(mail.body.encoded).to_not match header_mail_snippet.body expect(mail.body.encoded).to_not match welcome_mail_snippet.body expect(mail.body.encoded).to_not match security_mail_snippet.body - expect(mail.subject).to eq('Confirm your Bike Index registration') - expect(mail.reply_to).to eq(['contact@bikeindex.org']) + expect(mail.subject).to eq("Confirm your Bike Index registration") + expect(mail.reply_to).to eq(["contact@bikeindex.org"]) end end end end - describe 'organization_invitation' do + describe "organization_invitation" do let(:organization_invitation) { FactoryBot.create(:organization_invitation, organization: organization) } let(:mail) { OrganizedMailer.organization_invitation(organization_invitation) } before do expect(header_mail_snippet).to be_present end - it 'renders email' do + it "renders email" do expect(mail.body.encoded).to match header_mail_snippet.body expect(mail.subject).to eq("Join #{organization.short_name} on Bike Index") expect(mail.reply_to).to eq([organization.auto_user.email]) @@ -176,7 +176,7 @@ before do expect(header_mail_snippet).to be_present end - it 'renders email' do + it "renders email" do expect(mail.body.encoded).to match header_mail_snippet.body expect(mail.body.encoded).to match "278 Broadway, New York, NY 10007, USA" # includes location expect(mail.subject).to eq(organization_message.subject) diff --git a/spec/mailers/previews/admin_mailer_preview.rb b/spec/mailers/previews/admin_mailer_preview.rb index 8056a847b9..b9b585af6c 100644 --- a/spec/mailers/previews/admin_mailer_preview.rb +++ b/spec/mailers/previews/admin_mailer_preview.rb @@ -17,7 +17,7 @@ def blocked_stolen_notification_email def lightspeed_notification_email organization = Organization.last - AdminMailer.lightspeed_notification_email(organization, 'asdfasdf') + AdminMailer.lightspeed_notification_email(organization, "asdfasdf") end def unknown_organization_for_ascend_import diff --git a/spec/mailers/previews/customer_mailer_preview.rb b/spec/mailers/previews/customer_mailer_preview.rb index 61852af5a6..a015a00a77 100644 --- a/spec/mailers/previews/customer_mailer_preview.rb +++ b/spec/mailers/previews/customer_mailer_preview.rb @@ -28,7 +28,7 @@ def stolen_bike_alert_email end def admin_contact_stolen_email - customer_contact = CustomerContact.where(contact_type: 'stolen_contact').last + customer_contact = CustomerContact.where(contact_type: "stolen_contact").last CustomerMailer.admin_contact_stolen_email(customer_contact) end diff --git a/spec/models/ad_spec.rb b/spec/models/ad_spec.rb index fcaff1902e..47c6ef7c42 100644 --- a/spec/models/ad_spec.rb +++ b/spec/models/ad_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Ad do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :organization } it { is_expected.to validate_presence_of :title } it { is_expected.to validate_uniqueness_of :title } diff --git a/spec/models/b_param_spec.rb b/spec/models/b_param_spec.rb index 6330cccc6b..73df2f59d3 100644 --- a/spec/models/b_param_spec.rb +++ b/spec/models/b_param_spec.rb @@ -1,16 +1,16 @@ -require 'spec_helper' +require "spec_helper" describe BParam do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :created_bike } it { is_expected.to belong_to :creator } # it { should validate_presence_of :creator } end - describe 'bike' do - it 'returns the bike attribs' do - b_param = BParam.new(params: { bike: { serial_number: 'XXX' } }) - expect(b_param.bike['serial_number']).to eq('XXX') + describe "bike" do + it "returns the bike attribs" do + b_param = BParam.new(params: { bike: { serial_number: "XXX" } }) + expect(b_param.bike["serial_number"]).to eq("XXX") end it "does not fail if there isn't a bike" do user = FactoryBot.create(:user) @@ -18,71 +18,71 @@ expect(b_param.save).to be_truthy end end - describe 'clean_params' do - context 'passed params' do - it 'calls the things we want it to call' do + describe "clean_params" do + context "passed params" do + it "calls the things we want it to call" do b_param = BParam.new expect(b_param).to receive(:set_foreign_keys) expect(b_param).to receive(:massage_if_v2) - b_param.clean_params(bike: { cool: 'lol' }.as_json) - expect(b_param.params['bike']['cool']).to eq('lol') # indifferent access + b_param.clean_params(bike: { cool: "lol" }.as_json) + expect(b_param.params["bike"]["cool"]).to eq("lol") # indifferent access end end - context 'not passed params' do - it 'makes indifferent' do - b_param = BParam.new(params: { bike: { cool: 'lol' } }.as_json) + context "not passed params" do + it "makes indifferent" do + b_param = BParam.new(params: { bike: { cool: "lol" } }.as_json) b_param.clean_params - expect(b_param.params['bike']['cool']).to eq('lol') + expect(b_param.params["bike"]["cool"]).to eq("lol") end end - context 'existing and passed params' do - it 'makes indifferent' do - b_param = BParam.new(params: { bike: { cool: 'lol' }, stolen_record: { something: 42 } }.as_json) - merge_params = { bike: { owner_email: 'foo@example.com' }, stolen_record: { phone: '171-829-2625' } }.as_json + context "existing and passed params" do + it "makes indifferent" do + b_param = BParam.new(params: { bike: { cool: "lol" }, stolen_record: { something: 42 } }.as_json) + merge_params = { bike: { owner_email: "foo@example.com" }, stolen_record: { phone: "171-829-2625" } }.as_json b_param.clean_params(merge_params) - expect(b_param.params['bike']['cool']).to eq('lol') - expect(b_param.params['bike']['owner_email']).to eq('foo@example.com') - expect(b_param.params['stolen_record']['something']).to eq(42) - expect(b_param.params['stolen_record']['phone']).to eq('171-829-2625') + expect(b_param.params["bike"]["cool"]).to eq("lol") + expect(b_param.params["bike"]["owner_email"]).to eq("foo@example.com") + expect(b_param.params["stolen_record"]["something"]).to eq(42) + expect(b_param.params["stolen_record"]["phone"]).to eq("171-829-2625") end end - it 'has before_save_callback_method of clean_params' do + it "has before_save_callback_method of clean_params" do expect(BParam._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:clean_params)).to eq(true) end end - describe 'massage_if_v2' do - it 'renames v2 keys' do + describe "massage_if_v2" do + it "renames v2 keys" do p = { - serial: 'something', - manufacturer: 'something else', + serial: "something", + manufacturer: "something else", test: true, stolen_record: { - date_stolen: '', - phone: nil - } + date_stolen: "", + phone: nil, + }, }.as_json - b_param = BParam.new(params: p, origin: 'api_v2') + b_param = BParam.new(params: p, origin: "api_v2") b_param.massage_if_v2 new_params = b_param.bike - expect(new_params.keys.include?('serial_number')).to be_truthy - expect(new_params.keys.include?('manufacturer')).to be_truthy + expect(new_params.keys.include?("serial_number")).to be_truthy + expect(new_params.keys.include?("manufacturer")).to be_truthy expect(new_params.keys.length).to eq(3) - expect(b_param.params['test']).to be_truthy - expect(b_param.params['stolen']).to be_falsey - expect(b_param.params['stolen_record']).not_to be_present + expect(b_param.params["test"]).to be_truthy + expect(b_param.params["stolen"]).to be_falsey + expect(b_param.params["stolen_record"]).not_to be_present end - it 'gets the organization id' do - org = FactoryBot.create(:organization, name: 'Something') + it "gets the organization id" do + org = FactoryBot.create(:organization, name: "Something") p = { organization_slug: org.slug } - b_param = BParam.new(params: p, origin: 'api_v2') + b_param = BParam.new(params: p, origin: "api_v2") b_param.massage_if_v2 - expect(b_param.bike['creation_organization_id']).to eq(org.id) + expect(b_param.bike["creation_organization_id"]).to eq(org.id) end end - describe 'bike_from_attrs' do - it 'is stolen if it is stolen (ignore passed parameter)' do + describe "bike_from_attrs" do + it "is stolen if it is stolen (ignore passed parameter)" do b_param = BParam.new b_param.stolen = true bike = b_param.bike_from_attrs(is_stolen: false) @@ -90,13 +90,13 @@ end end - describe 'set_foreign_keys' do - it 'calls set_foreign_keys' do + describe "set_foreign_keys" do + it "calls set_foreign_keys" do bike = { - handlebar_type_slug: 'else', - cycle_type_slug: 'entirely', - rear_gear_type_slug: 'gears awesome', - front_gear_type_slug: 'cool gears' + handlebar_type_slug: "else", + cycle_type_slug: "entirely", + rear_gear_type_slug: "gears awesome", + front_gear_type_slug: "cool gears", }.as_json b_param = BParam.new(params: { bike: bike }) expect(b_param).to receive(:set_manufacturer_key).and_return(true) @@ -126,95 +126,95 @@ end end - describe 'set_wheel_size_key' do - it 'sets rear_wheel_size_id to the bsd submitted' do - ws = FactoryBot.create(:wheel_size, iso_bsd: 'Bike') + describe "set_wheel_size_key" do + it "sets rear_wheel_size_id to the bsd submitted" do + ws = FactoryBot.create(:wheel_size, iso_bsd: "Bike") bike = { rear_wheel_bsd: ws.iso_bsd } b_param = BParam.new(params: { bike: bike }) b_param.set_wheel_size_key - expect(b_param.bike['rear_wheel_size_id']).to eq(ws.id) + expect(b_param.bike["rear_wheel_size_id"]).to eq(ws.id) end end - describe 'set_cycle_type_key' do - it 'sets cycle_type to the cycle type from name submitted' do - bike = { serial_number: 'gobble gobble', cycle_type_slug: ' strolLeR ' } + describe "set_cycle_type_key" do + it "sets cycle_type to the cycle type from name submitted" do + bike = { serial_number: "gobble gobble", cycle_type_slug: " strolLeR " } b_param = BParam.new(params: { bike: bike }) b_param.set_cycle_type_key - expect(b_param.bike['cycle_type']).to eq(:stroller) - expect(b_param.bike['cycle_type_slug'].present?).to be_falsey + expect(b_param.bike["cycle_type"]).to eq(:stroller) + expect(b_param.bike["cycle_type_slug"].present?).to be_falsey end end - describe 'set_handlebar_type_key' do - it 'sets handlebar_type to the handlebar type from name submitted' do - bike = { serial_number: 'gobble gobble', handlebar_type_slug: ' bmx ' } + describe "set_handlebar_type_key" do + it "sets handlebar_type to the handlebar type from name submitted" do + bike = { serial_number: "gobble gobble", handlebar_type_slug: " bmx " } b_param = BParam.new(params: { bike: bike }) b_param.set_handlebar_type_key - expect(b_param.bike['handlebar_type_slug'].present?).to be_falsey - expect(b_param.bike['handlebar_type']).to eq(:bmx) + expect(b_param.bike["handlebar_type_slug"].present?).to be_falsey + expect(b_param.bike["handlebar_type"]).to eq(:bmx) end end - describe 'set_manufacturer_key' do - context 'attr set on manufacturer_id' do - context 'other' do - it 'adds other manufacturer name and set the set the foreign keys' do - bike = { manufacturer_id: 'lololol' } + describe "set_manufacturer_key" do + context "attr set on manufacturer_id" do + context "other" do + it "adds other manufacturer name and set the set the foreign keys" do + bike = { manufacturer_id: "lololol" } b_param = BParam.new(params: { bike: bike }) b_param.set_manufacturer_key - expect(b_param.bike['manufacturer']).not_to be_present - expect(b_param.bike['manufacturer_id']).to eq(Manufacturer.other.id) - expect(b_param.bike['manufacturer_other']).to eq('lololol') + expect(b_param.bike["manufacturer"]).not_to be_present + expect(b_param.bike["manufacturer_id"]).to eq(Manufacturer.other.id) + expect(b_param.bike["manufacturer_other"]).to eq("lololol") end end - context 'existing manufacturer' do + context "existing manufacturer" do let(:manufacturer) { FactoryBot.create(:manufacturer) } - context 'manufacturer name' do - it 'uses manufacturer' do + context "manufacturer name" do + it "uses manufacturer" do bike = { manufacturer_id: manufacturer.id } b_param = BParam.new(params: { bike: bike }) b_param.set_manufacturer_key - expect(b_param.bike['manufacturer_id']).to eq(manufacturer.id) + expect(b_param.bike["manufacturer_id"]).to eq(manufacturer.id) end end - context 'manufacturer id' do - it 'sets the manufacturer' do + context "manufacturer id" do + it "sets the manufacturer" do bike = { manufacturer_id: manufacturer.id } - b_param = BParam.new(params: { bike: bike }) + b_param = BParam.new(params: { bike: bike }) b_param.set_manufacturer_key - expect(b_param.bike['manufacturer_id']).to eq(manufacturer.id) + expect(b_param.bike["manufacturer_id"]).to eq(manufacturer.id) end end end - context 'no manufacturer or manufacturer_id' do - it 'does not set anything' do - bike = { manufacturer_id: ' ' } - b_param = BParam.new(params: { bike: bike }) + context "no manufacturer or manufacturer_id" do + it "does not set anything" do + bike = { manufacturer_id: " " } + b_param = BParam.new(params: { bike: bike }) b_param.set_manufacturer_key - expect(b_param.bike['manufacturer_id']).to be_nil + expect(b_param.bike["manufacturer_id"]).to be_nil end end end - context 'attr set on manufacturer' do - context 'other manufacturer' do - it 'adds other manufacturer name and set the set the foreign keys' do - bike = { manufacturer: 'gobble gobble' } + context "attr set on manufacturer" do + context "other manufacturer" do + it "adds other manufacturer name and set the set the foreign keys" do + bike = { manufacturer: "gobble gobble" } b_param = BParam.new(params: { bike: bike }) b_param.set_manufacturer_key - expect(b_param.bike['manufacturer']).not_to be_present - expect(b_param.bike['manufacturer_id']).to eq(Manufacturer.other.id) - expect(b_param.bike['manufacturer_other']).to eq('gobble gobble') + expect(b_param.bike["manufacturer"]).not_to be_present + expect(b_param.bike["manufacturer_id"]).to eq(Manufacturer.other.id) + expect(b_param.bike["manufacturer_other"]).to eq("gobble gobble") end end - context 'existing manufacturer' do - it 'looks through book slug' do - manufacturer = FactoryBot.create(:manufacturer, name: 'Something Cycles') - bike = { manufacturer: 'something' } + context "existing manufacturer" do + it "looks through book slug" do + manufacturer = FactoryBot.create(:manufacturer, name: "Something Cycles") + bike = { manufacturer: "something" } b_param = BParam.new(params: { bike: bike }) b_param.set_manufacturer_key - expect(b_param.bike['manufacturer']).not_to be_present - expect(b_param.bike['manufacturer_id']).to eq(manufacturer.id) + expect(b_param.bike["manufacturer"]).not_to be_present + expect(b_param.bike["manufacturer_id"]).to eq(manufacturer.id) end end end @@ -232,8 +232,8 @@ address: "123 Main St", address_city: "Nevernever Land", address_zipcode: "11111", - address_state: "CA" - } + address_state: "CA", + }, }.as_json end let(:b_param) { BParam.new(params: params_hash) } @@ -251,113 +251,113 @@ end end - describe 'gear_slugs' do - it 'sets the rear gear slug' do + describe "gear_slugs" do + it "sets the rear gear slug" do gear = FactoryBot.create(:rear_gear_type) bike = { rear_gear_type_slug: gear.slug } b_param = BParam.new(params: { bike: bike }) b_param.set_rear_gear_type_slug - expect(b_param.params['bike']['rear_gear_type_slug']).not_to be_present - expect(b_param.params['bike']['rear_gear_type_id']).to eq(gear.id) + expect(b_param.params["bike"]["rear_gear_type_slug"]).not_to be_present + expect(b_param.params["bike"]["rear_gear_type_id"]).to eq(gear.id) end - it 'sets the front gear slug' do + it "sets the front gear slug" do gear = FactoryBot.create(:front_gear_type) bike = { front_gear_type_slug: gear.slug } b_param = BParam.new(params: { bike: bike }) b_param.set_front_gear_type_slug - expect(b_param.params['bike']['front_gear_type_slug']).not_to be_present - expect(b_param.params['bike']['front_gear_type_id']).to eq(gear.id) + expect(b_param.params["bike"]["front_gear_type_slug"]).not_to be_present + expect(b_param.params["bike"]["front_gear_type_id"]).to eq(gear.id) end end - describe 'set_color_key' do + describe "set_color_key" do it "sets the color if it's a color and remove the color attr" do color = FactoryBot.create(:color) bike = { color: color.name } b_param = BParam.new(params: { bike: bike }) b_param.set_color_key - expect(b_param.params['bike']['color']).not_to be_present - expect(b_param.params['bike']['primary_frame_color_id']).to eq(color.id) + expect(b_param.params["bike"]["color"]).not_to be_present + expect(b_param.params["bike"]["primary_frame_color_id"]).to eq(color.id) end it "set_paint_keys if it isn't a color" do - bike = { color: 'Goop' } + bike = { color: "Goop" } b_param = BParam.new(params: { bike: bike }) expect(b_param).to receive(:set_paint_key).and_return(true) b_param.set_color_key end end - describe 'set_paint_key' do - it 'associates the paint and set the color if it can' do - FactoryBot.create(:color, name: 'Black') - color = FactoryBot.create(:color, name: 'Yellow') - paint = FactoryBot.create(:paint, name: 'pinkly butter', color_id: color.id) + describe "set_paint_key" do + it "associates the paint and set the color if it can" do + FactoryBot.create(:color, name: "Black") + color = FactoryBot.create(:color, name: "Yellow") + paint = FactoryBot.create(:paint, name: "pinkly butter", color_id: color.id) b_param = BParam.new(params: { bike: { color: paint.name } }) b_param.set_paint_key(paint.name) - expect(b_param.bike['paint_id']).to eq(paint.id) - expect(b_param.bike['primary_frame_color_id']).to eq(color.id) + expect(b_param.bike["paint_id"]).to eq(paint.id) + expect(b_param.bike["primary_frame_color_id"]).to eq(color.id) end it "creates a paint and set the color to black if we don't know the color" do - black = FactoryBot.create(:color, name: 'Black') + black = FactoryBot.create(:color, name: "Black") b_param = BParam.new(params: { bike: {} }) expect do - b_param.set_paint_key('Paint 69') + b_param.set_paint_key("Paint 69") end.to change(Paint, :count).by(1) - expect(b_param.bike['paint_id']).to eq(Paint.find_by_name('paint 69').id) - expect(b_param.bike['primary_frame_color_id']).to eq(black.id) + expect(b_param.bike["paint_id"]).to eq(Paint.find_by_name("paint 69").id) + expect(b_param.bike["primary_frame_color_id"]).to eq(black.id) end it "associates the manufacturer with the paint if it's a new bike" do - FactoryBot.create(:color, name: 'Black') + FactoryBot.create(:color, name: "Black") m = FactoryBot.create(:manufacturer) bike = { is_pos: true, manufacturer_id: m.id } b_param = BParam.new(params: { bike: bike }) - b_param.set_paint_key('paint 69') - p = Paint.find_by_name('paint 69') + b_param.set_paint_key("paint 69") + p = Paint.find_by_name("paint 69") expect(p.manufacturer_id).to eq(m.id) end end - describe 'generate_username_confirmation_and_auth' do - it 'generates the required tokens' do + describe "generate_username_confirmation_and_auth" do + it "generates the required tokens" do b_param = BParam.new b_param.generate_id_token expect(b_param.id_token.length).to be > 10 end - it 'haves before create callback' do + it "haves before create callback" do expect(BParam._create_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:generate_id_token)).to eq(true) end end # # Revised attrs - describe 'find_or_new_from_token' do + describe "find_or_new_from_token" do let(:user) { FactoryBot.create(:user) } # # Because for now we aren't updating the factory, use this let for b_params factory let(:b_param) { BParam.create } let(:expire_b_param) { b_param.update_attribute :created_at, Time.zone.now - 5.weeks } - context 'with user_id passed' do - context 'without token' do - it 'returns a new b_param, with creator of user_id' do + context "with user_id passed" do + context "without token" do + it "returns a new b_param, with creator of user_id" do result = BParam.find_or_new_from_token(nil, user_id: user.id) expect(result.is_a?(BParam)).to be_truthy expect(result.id).to be_nil expect(result.creator_id).to eq user.id end end - context 'existing token' do - context 'with creator of same user and expired b_param' do - it 'returns the b_param - also testing that we get the *correct* b_param' do + context "existing token" do + context "with creator of same user and expired b_param" do + it "returns the b_param - also testing that we get the *correct* b_param" do expire_b_param BParam.create(creator_id: user.id) b_param.update_attribute :creator_id, user.id expect(BParam.find_or_new_from_token(b_param.id_token, user_id: user.id)).to eq b_param end end - context 'with creator of different user' do - it 'fails' do + context "with creator of different user" do + it "fails" do other_user = FactoryBot.create(:user) b_param.update_attribute :creator_id, user.id result = BParam.find_or_new_from_token(b_param.id_token, user_id: other_user.id) @@ -365,13 +365,13 @@ expect(result.id).to be_nil end end - context 'with no creator' do - it 'returns the b_param' do + context "with no creator" do + it "returns the b_param" do result = BParam.find_or_new_from_token(b_param.id_token, user_id: user.id) expect(result.id).to eq b_param.id end - context 'with expired b_param' do - it 'fails' do + context "with expired b_param" do + it "fails" do expire_b_param result = BParam.find_or_new_from_token(b_param.id_token, user_id: user.id) expect(result.is_a?(BParam)).to be_truthy @@ -380,7 +380,7 @@ end end end - it 'updates with the organization' do + it "updates with the organization" do organization_id = 42 result = BParam.find_or_new_from_token(user_id: user.id, organization_id: organization_id) expect(result.is_a?(BParam)).to be_truthy @@ -388,8 +388,8 @@ expect(result.creator_id).to eq(user.id) expect(result.id).to be_nil end - context 'with existing bike' do - it 'fails and says expired' do + context "with existing bike" do + it "fails and says expired" do b_param.update_attribute :created_bike_id, 33 result = BParam.find_or_new_from_token(b_param.id_token) expect(result.is_a?(BParam)).to be_truthy @@ -397,17 +397,17 @@ end end end - context 'without user_id passed' do - context 'without token' do - it 'returns a new b_param' do + context "without user_id passed" do + context "without token" do + it "returns a new b_param" do result = BParam.find_or_new_from_token expect(result.is_a?(BParam)).to be_truthy expect(result.id).to be_nil end end - context 'with organization' do - context 'organization not set' do - it 'updates with the organization' do + context "with organization" do + context "organization not set" do + it "updates with the organization" do organization_id = 42 result = BParam.find_or_new_from_token(b_param.id_token, organization_id: organization_id) expect(result).to eq b_param @@ -415,22 +415,22 @@ end end end - context 'without user' do - it 'returns the b_param also testing that we get the *correct* b_param' do + context "without user" do + it "returns the b_param also testing that we get the *correct* b_param" do BParam.create expect(BParam.find_or_new_from_token(b_param.id_token)).to eq b_param expect(BParam.first).to_not eq b_param # Ensuring we aren't picking it accidentally end - context 'expired_b_param' do - it 'returns new b_param' do + context "expired_b_param" do + it "returns new b_param" do expire_b_param result = BParam.find_or_new_from_token(b_param.id_token) expect(result.is_a?(BParam)).to be_truthy expect(result.id).to be_nil end end - context 'with creator' do - it 'returns new b_param' do + context "with creator" do + it "returns new b_param" do b_param.update_attribute :creator_id, user.id result = BParam.find_or_new_from_token(b_param.id_token) expect(result.is_a?(BParam)).to be_truthy @@ -452,54 +452,54 @@ end end - describe 'safe_bike_hash' do - context 'with creator' do - it 'returns the hash we pass, ignoring ignored and overriding param_overrides' do + describe "safe_bike_hash" do + context "with creator" do + it "returns the hash we pass, ignoring ignored and overriding param_overrides" do bike_attrs = { manufacturer_id: 12, primary_frame_color_id: 8, - owner_email: 'something@stuff.com', + owner_email: "something@stuff.com", stolen: false, creator_id: 1, - cycle_type_slug: 'cargo', + cycle_type_slug: "cargo", b_param_id: 79999, creation_organization_id: 888, - something_else_cool: 'party' + something_else_cool: "party", } b_param = BParam.new(params: { bike: bike_attrs }, creator_id: 777) b_param.id = 122 target = { manufacturer_id: 12, primary_frame_color_id: 8, - owner_email: 'something@stuff.com', + owner_email: "something@stuff.com", stolen: true, creator_id: 777, b_param_id: 122, - creation_organization_id: 888 + creation_organization_id: 888, }.with_indifferent_access expect(b_param.safe_bike_attrs(stolen: true).with_indifferent_access).to eq(target) end end end - describe 'display_email?' do - context 'owner_email present' do - it 'is false' do - b_param = BParam.new(params: { bike: { owner_email: 'something@stuff.com' }.with_indifferent_access }) + describe "display_email?" do + context "owner_email present" do + it "is false" do + b_param = BParam.new(params: { bike: { owner_email: "something@stuff.com" }.with_indifferent_access }) expect(b_param.display_email?).to be_falsey end end - context 'owner_email not present' do - it 'is true' do - b_param = BParam.new(params: { bike: { owner_email: '' }.with_indifferent_access }) + context "owner_email not present" do + it "is true" do + b_param = BParam.new(params: { bike: { owner_email: "" }.with_indifferent_access }) expect(b_param.display_email?).to be_truthy end end - context 'Bike has errors' do - it 'is true' do + context "Bike has errors" do + it "is true" do b_param = BParam.new(params: { - bike: { owner_email: 'something@stuff.com' }.with_indifferent_access - }, bike_errors: ['Some error']) + bike: { owner_email: "something@stuff.com" }.with_indifferent_access, + }, bike_errors: ["Some error"]) expect(b_param.display_email?).to be_truthy end end diff --git a/spec/models/bike_organization_spec.rb b/spec/models/bike_organization_spec.rb index eaa0526087..f94fc4dce8 100644 --- a/spec/models/bike_organization_spec.rb +++ b/spec/models/bike_organization_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" RSpec.describe BikeOrganization, type: :model do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :bike } it { is_expected.to belong_to :organization } it { is_expected.to validate_presence_of :bike_id } @@ -9,4 +9,3 @@ it { is_expected.to validate_uniqueness_of(:organization_id).scoped_to(:bike_id) } end end - diff --git a/spec/models/bike_spec.rb b/spec/models/bike_spec.rb index a9c0617ed6..deda94510f 100644 --- a/spec/models/bike_spec.rb +++ b/spec/models/bike_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe Bike do - it_behaves_like 'bike_searchable' - describe 'validations' do + it_behaves_like "bike_searchable" + describe "validations" do it { is_expected.to belong_to :manufacturer } it { is_expected.to belong_to :primary_frame_color } it { is_expected.to belong_to :secondary_frame_color } @@ -39,29 +39,29 @@ it { is_expected.to validate_presence_of :primary_frame_color_id } end - describe 'scopes' do - it 'default scopes to created_at desc' do - expect(Bike.all.to_sql).to eq(Bike.unscoped.where(example: false, hidden: false).order('listing_order desc').to_sql) + describe "scopes" do + it "default scopes to created_at desc" do + expect(Bike.all.to_sql).to eq(Bike.unscoped.where(example: false, hidden: false).order("listing_order desc").to_sql) end - it 'scopes to only stolen bikes' do + it "scopes to only stolen bikes" do expect(Bike.stolen.to_sql).to eq(Bike.where(stolen: true).to_sql) end - it 'non_stolen scopes to only non_stolen bikes' do + it "non_stolen scopes to only non_stolen bikes" do expect(Bike.non_stolen.to_sql).to eq(Bike.where(stolen: false).to_sql) end - it 'non_recovered scopes to only non_recovered bikes' do + it "non_recovered scopes to only non_recovered bikes" do expect(Bike.non_recovered.to_sql).to eq(Bike.where(recovered: false).to_sql) end end - describe 'recovered_records' do - it 'default scopes to created_at desc' do + describe "recovered_records" do + it "default scopes to created_at desc" do bike = FactoryBot.create(:bike) - expect(bike.recovered_records.to_sql).to eq(StolenRecord.unscoped.where(bike_id: bike.id, current: false).order('date_recovered desc').to_sql) + expect(bike.recovered_records.to_sql).to eq(StolenRecord.unscoped.where(bike_id: bike.id, current: false).order("date_recovered desc").to_sql) end end - describe 'visible_by' do + describe "visible_by" do it "isn't be visible to owner unless user hidden" do bike = Bike.new(hidden: true) user = User.new @@ -69,26 +69,26 @@ allow(bike).to receive(:user_hidden).and_return(false) expect(bike.visible_by(user)).to be_falsey end - it 'is visible to owner' do + it "is visible to owner" do bike = Bike.new(hidden: true) user = User.new allow(bike).to receive(:owner).and_return(user) allow(bike).to receive(:user_hidden).and_return(true) expect(bike.visible_by(user)).to be_truthy end - it 'is visible to superuser' do + it "is visible to superuser" do bike = Bike.new(hidden: true) user = User.new user.superuser = true expect(bike.visible_by(user)).to be_truthy end - it 'is visible if not hidden' do + it "is visible if not hidden" do bike = Bike.new expect(bike.visible_by).to be_truthy end end - describe 'owner' do + describe "owner" do it "doesn't break if the owner is deleted" do delete_user = FactoryBot.create(:user) ownership = FactoryBot.create(:ownership, user_id: delete_user.id) @@ -157,7 +157,7 @@ end end - describe 'user?' do + describe "user?" do let(:bike) { Bike.new } let(:ownership) { Ownership.new } before { allow(bike).to receive(:current_ownership) { ownership } } @@ -167,23 +167,23 @@ context "claimed" do let(:user) { User.new } let(:ownership) { Ownership.new(claimed: true, user: user) } - it 'returns true if ownership is claimed' do + it "returns true if ownership is claimed" do expect(bike.user?).to be_truthy end end end - describe 'claimable_by?' do - context 'already claimed' do - it 'returns false' do + describe "claimable_by?" do + context "already claimed" do + it "returns false" do user = User.new bike = Bike.new allow(bike).to receive(:user?).and_return(true) expect(bike.claimable_by?(user)).to be_falsey end end - context 'can be claimed' do - it 'returns true' do + context "can be claimed" do + it "returns true" do user = User.new ownership = Ownership.new bike = Bike.new @@ -193,8 +193,8 @@ expect(bike.claimable_by?(user)).to be_truthy end end - context 'no current_ownership' do # AKA Something is broken. Bikes should always have ownerships - it 'does not explode' do + context "no current_ownership" do # AKA Something is broken. Bikes should always have ownerships + it "does not explode" do user = User.new bike = Bike.new expect(bike.claimable_by?(user)).to be_falsey @@ -202,7 +202,7 @@ end end - describe 'cleaned_error_messages' do + describe "cleaned_error_messages" do let(:errors) { ["Manufacturer can't be blank", "Bike can't be blank", "Association error Ownership wasn't saved. Are you sure the bike was created?"] } it "removes error messages we don't want to show users" do bike = Bike.new @@ -419,33 +419,33 @@ end end - describe 'user_hidden' do - it 'is true if bike is hidden and ownership is user hidden' do + describe "user_hidden" do + it "is true if bike is hidden and ownership is user hidden" do bike = Bike.new(hidden: true) ownership = Ownership.new(user_hidden: true) allow(bike).to receive(:current_ownership).and_return(ownership) expect(bike.user_hidden).to be_truthy end - it 'is false otherwise' do + it "is false otherwise" do bike = Bike.new(hidden: true) expect(bike.user_hidden).to be_falsey end end - describe 'fake_deleted' do - it 'is true if bike is hidden and ownership is user hidden' do + describe "fake_deleted" do + it "is true if bike is hidden and ownership is user hidden" do bike = Bike.new(hidden: true) ownership = Ownership.new(user_hidden: true) allow(bike).to receive(:current_ownership).and_return(ownership) expect(bike.fake_deleted).to be_falsey end - it 'is false otherwise' do + it "is false otherwise" do bike = Bike.new(hidden: true) expect(bike.fake_deleted).to be_truthy end end - describe 'set_user_hidden' do + describe "set_user_hidden" do let(:ownership) { FactoryBot.create(:ownership) } let(:bike) { ownership.bike } it "marks updates ownership user hidden, marks self hidden" do @@ -466,8 +466,8 @@ end end - describe 'find_current_stolen_record' do - it 'returns the last current stolen record if bike is stolen' do + describe "find_current_stolen_record" do + it "returns the last current stolen record if bike is stolen" do @bike = Bike.new first_stolen_record = StolenRecord.new second_stolen_record = StolenRecord.new @@ -511,41 +511,41 @@ context "manufacturer with parens" do let(:manufacturer) { FactoryBot.create(:manufacturer, name: "SE Racing (S E Bikes)") } let(:bike) { FactoryBot.build(:bike, manufacturer: manufacturer) } - it 'returns Just SE Bikes (and does it on save)' do + it "returns Just SE Bikes (and does it on save)" do bike.save expect(bike.mnfg_name).to eq("SE Racing") end end end - describe 'type' do - it 'returns the cycle type name' do + describe "type" do + it "returns the cycle type name" do bike = FactoryBot.create(:bike, cycle_type: "trailer") expect(bike.type).to eq("bike trailer") end end - describe 'video_embed_src' do - it 'returns false if there is no video_embed' do + describe "video_embed_src" do + it "returns false if there is no video_embed" do @bike = Bike.new allow(@bike).to receive(:video_embed).and_return(nil) expect(@bike.video_embed_src).to be_nil end - it 'returns just the url of the video from a youtube iframe' do + it "returns just the url of the video from a youtube iframe" do youtube_share = ' ' @bike = Bike.new allow(@bike).to receive(:video_embed).and_return(youtube_share) - expect(@bike.video_embed_src).to eq('//www.youtube.com/embed/Sv3xVOs7_No') + expect(@bike.video_embed_src).to eq("//www.youtube.com/embed/Sv3xVOs7_No") end - it 'returns just the url of the video from a vimeo iframe' do + it "returns just the url of the video from a vimeo iframe" do vimeo_share = '

    Fixed Gear Kuala Lumpur, RatsKL Putrajaya from irmanhilmi on Vimeo.

    ' @bike = Bike.new allow(@bike).to receive(:video_embed).and_return(vimeo_share) - expect(@bike.video_embed_src).to eq('http://player.vimeo.com/video/13094257') + expect(@bike.video_embed_src).to eq("http://player.vimeo.com/video/13094257") end end @@ -589,28 +589,28 @@ end end - describe 'serial' do - it 'only returns the serial if we should show people the serial' do + describe "serial" do + it "only returns the serial if we should show people the serial" do # We're hiding serial numbers for bikes that are recovered to provide a method of verifying # ownership bike = Bike.new - allow(bike).to receive(:serial_number).and_return('something') + allow(bike).to receive(:serial_number).and_return("something") allow(bike).to receive(:recovered).and_return(true) expect(bike.serial).to be_nil end end - describe 'pg search' do - it 'returns a bike which has a matching part of its description' do - @bike = FactoryBot.create(:bike, description: 'Phil wood hub') - @bikes = Bike.text_search('phil wood hub') + describe "pg search" do + it "returns a bike which has a matching part of its description" do + @bike = FactoryBot.create(:bike, description: "Phil wood hub") + @bikes = Bike.text_search("phil wood hub") expect(@bikes).to include(@bike) end - it 'returns the bikes in the default scope pattern if there is no query' do - bike = FactoryBot.create(:bike, description: 'Phil wood hub') + it "returns the bikes in the default scope pattern if there is no query" do + bike = FactoryBot.create(:bike, description: "Phil wood hub") FactoryBot.create(:bike) - bikes = Bike.text_search('') + bikes = Bike.text_search("") expect(bikes.first).to eq(bike) end end @@ -728,39 +728,39 @@ end end - describe 'set_paints' do - it 'returns true if paint is a color' do - FactoryBot.create(:color, name: 'Bluety') + describe "set_paints" do + it "returns true if paint is a color" do + FactoryBot.create(:color, name: "Bluety") bike = Bike.new - allow(bike).to receive(:paint_name).and_return(' blueTy') + allow(bike).to receive(:paint_name).and_return(" blueTy") expect { bike.set_paints }.not_to change(Paint, :count) expect(bike.paint).to be_nil end - it 'removes paint id if paint_name is nil' do + it "removes paint id if paint_name is nil" do paint = FactoryBot.create(:paint) bike = FactoryBot.build(:bike, paint_id: paint.id) - bike.paint_name = '' + bike.paint_name = "" bike.save expect(bike.paint).to be_nil end - it 'sets the paint if it exists' do - FactoryBot.create(:paint, name: 'poopy pile') + it "sets the paint if it exists" do + FactoryBot.create(:paint, name: "poopy pile") bike = Bike.new - allow(bike).to receive(:paint_name).and_return('Poopy PILE ') + allow(bike).to receive(:paint_name).and_return("Poopy PILE ") expect { bike.set_paints }.not_to change(Paint, :count) - expect(bike.paint.name).to eq('poopy pile') + expect(bike.paint.name).to eq("poopy pile") end - it 'creates a new paint and set it otherwise' do + it "creates a new paint and set it otherwise" do bike = Bike.new - bike.paint_name = ['Food Time SOOON'] + bike.paint_name = ["Food Time SOOON"] expect { bike.set_paints }.to change(Paint, :count).by(1) - expect(bike.paint.name).to eq('food time sooon') + expect(bike.paint.name).to eq("food time sooon") end end - describe 'cache_photo' do - context 'existing photo' do - it 'caches the photo' do + describe "cache_photo" do + context "existing photo" do + it "caches the photo" do bike = FactoryBot.create(:bike) FactoryBot.create(:public_image, imageable: bike) bike.reload @@ -768,17 +768,17 @@ expect(bike.thumb_path).not_to be_nil end end - context 'no photo' do - it 'removes existing cache if inaccurate' do - bike = Bike.new(thumb_path: 'some url') + context "no photo" do + it "removes existing cache if inaccurate" do + bike = Bike.new(thumb_path: "some url") bike.cache_photo expect(bike.thumb_path).to be_nil end end end - describe 'components_cache_string' do - it 'caches the components' do + describe "components_cache_string" do + it "caches the components" do bike = FactoryBot.create(:bike) c = FactoryBot.create(:component, bike: bike) bike.save @@ -786,36 +786,36 @@ end end - describe 'cache_stolen_attributes' do - context 'current_stolen_record with lat and long' do - it 'saves the stolen description to all description and set stolen_rec_id' do - stolen_record = FactoryBot.create(:stolen_record, theft_description: 'some theft description', latitude: 40.7143528, longitude: -74.0059731) + describe "cache_stolen_attributes" do + context "current_stolen_record with lat and long" do + it "saves the stolen description to all description and set stolen_rec_id" do + stolen_record = FactoryBot.create(:stolen_record, theft_description: "some theft description", latitude: 40.7143528, longitude: -74.0059731) bike = stolen_record.bike - bike.description = 'I love my bike' + bike.description = "I love my bike" bike.cache_stolen_attributes - expect(bike.all_description).to eq('I love my bike some theft description') + expect(bike.all_description).to eq("I love my bike some theft description") expect(bike.stolen_lat).to eq(40.7143528) expect(bike.stolen_long).to eq(-74.0059731) end end - context 'no current_stolen_record' do - it 'grabs the desc and erase current_stolen_id' do - bike = Bike.new(current_stolen_record_id: 69, description: 'lalalala', stolen_lat: 40.7143528, stolen_long: -74.0059731) + context "no current_stolen_record" do + it "grabs the desc and erase current_stolen_id" do + bike = Bike.new(current_stolen_record_id: 69, description: "lalalala", stolen_lat: 40.7143528, stolen_long: -74.0059731) bike.cache_stolen_attributes expect(bike.current_stolen_record_id).not_to be_present - expect(bike.all_description).to eq('lalalala') + expect(bike.all_description).to eq("lalalala") expect(bike.stolen_lat).to eq nil expect(bike.stolen_long).to eq nil end end end - describe 'cache_bike' do + describe "cache_bike" do let(:wheel_size) { FactoryBot.create(:wheel_size) } let(:bike) { FactoryBot.create(:bike, rear_wheel_size: wheel_size) } let!(:stolen_record) { FactoryBot.create(:stolen_record, bike: bike) } let(:target_cached_string) { "#{bike.mnfg_name} Sail 1999 #{bike.primary_frame_color.name} #{bike.secondary_frame_color.name} #{bike.tertiary_frame_color.name} #{bike.frame_material_name} 56foo #{bike.frame_model} #{wheel_size.name} wheel unicycle" } - it 'caches all the bike parts' do + it "caches all the bike parts" do bike.update_attributes(year: 1999, frame_material: "steel", secondary_frame_color_id: bike.primary_frame_color_id, tertiary_frame_color_id: bike.primary_frame_color_id, @@ -823,21 +823,21 @@ handlebar_type: "bmx", propulsion_type: "sail", cycle_type: "unicycle", - frame_size: '56', frame_size_unit: 'foo', - frame_model: 'Some model') + frame_size: "56", frame_size_unit: "foo", + frame_model: "Some model") bike.reload expect(bike.cached_data).to eq target_cached_string expect(bike.current_stolen_record_id).to eq(stolen_record.id) end end - describe 'frame_colors' do - it 'returns an array of the frame colors' do + describe "frame_colors" do + it "returns an array of the frame colors" do bike = Bike.new color = Color.new color2 = Color.new - allow(color).to receive(:name).and_return('Blue') - allow(color2).to receive(:name).and_return('Black') + allow(color).to receive(:name).and_return("Blue") + allow(color2).to receive(:name).and_return("Black") allow(bike).to receive(:primary_frame_color).and_return(color) allow(bike).to receive(:secondary_frame_color).and_return(color2) allow(bike).to receive(:tertiary_frame_color).and_return(color) @@ -845,8 +845,8 @@ end end - describe 'cgroup_array' do - it 'grabs a list of all the cgroups' do + describe "cgroup_array" do + it "grabs a list of all the cgroups" do bike = Bike.new component1 = Component.new component2 = Component.new @@ -900,56 +900,56 @@ end end - describe 'title_string' do - it 'escapes correctly' do - bike = Bike.new(frame_model: '') - allow(bike).to receive(:mnfg_name).and_return('baller') - allow(bike).to receive(:type).and_return('bike') - expect(bike.title_string).not_to match('') + describe "title_string" do + it "escapes correctly" do + bike = Bike.new(frame_model: "") + allow(bike).to receive(:mnfg_name).and_return("baller") + allow(bike).to receive(:type).and_return("bike") + expect(bike.title_string).not_to match("") expect(bike.title_string.length).to be > 5 end end - describe 'validated_organization_id' do + describe "validated_organization_id" do let(:bike) { Bike.new } - context 'valid organization' do + context "valid organization" do let(:organization) { FactoryBot.create(:organization) } - context 'slug' do - it 'returns true' do + context "slug" do + it "returns true" do expect(bike.validated_organization_id(organization.slug)).to eq organization.id end end - context 'id' do - it 'returns true' do + context "id" do + it "returns true" do expect(bike.validated_organization_id(organization.id)).to eq organization.id end end end - context 'suspended organization' do + context "suspended organization" do let(:organization) { FactoryBot.create(:organization, is_suspended: true) } - it 'adds an error to the bike' do + it "adds an error to the bike" do expect(bike.validated_organization_id(organization.id)).to be_nil end end - context 'unable to find organization' do - it 'adds an error to the bike' do - expect(bike.validated_organization_id('some org')).to be_nil + context "unable to find organization" do + it "adds an error to the bike" do + expect(bike.validated_organization_id("some org")).to be_nil expect(bike.errors[:organization].to_s).to match(/not found/) expect(bike.errors[:organization].to_s).to match(/some org/) end end end - describe 'assignment of bike_organization_ids' do + describe "assignment of bike_organization_ids" do let(:bike) { FactoryBot.create(:organization_bike) } let(:organization) { bike.organizations.first } let(:bike_organization) { bike.bike_organizations.first } let(:organization_2) { FactoryBot.create(:organization) } before { expect(bike.bike_organization_ids).to eq([organization.id]) } - context 'no organization_ids' do - it 'removes bike organizations' do + context "no organization_ids" do + it "removes bike organizations" do expect(bike.bike_organization_ids).to eq([organization.id]) - bike.bike_organization_ids = '' + bike.bike_organization_ids = "" # Acts as paranoid bike_organization.reload expect(bike_organization.deleted_at).to be_within(1.second).of Time.now @@ -959,22 +959,22 @@ expect(bike.bike_organization_ids).to eq([organization.id]) # despite uniqueness validation end end - context 'invalid organization_id' do + context "invalid organization_id" do let(:organization_invalid) { FactoryBot.create(:organization, is_suspended: true) } - it 'adds valid organization but not invalid one' do + it "adds valid organization but not invalid one" do bike.bike_organization_ids = [organization.id, organization_2.id, organization_invalid.id] expect(bike.bike_organization_ids).to eq([organization.id, organization_2.id]) end end - context 'different organization' do - it 'adds organization and removes existing' do + context "different organization" do + it "adds organization and removes existing" do bike.bike_organization_ids = "#{organization_2.id}, " expect(bike.bike_organization_ids).to eq([organization_2.id]) end end end - describe 'handlebar_type_name' do + describe "handlebar_type_name" do let(:bike) { FactoryBot.create(:bike, handlebar_type: "bmx") } it "returns the normalized name" do normalized_name = HandlebarType.new(bike.handlebar_type).name @@ -982,7 +982,7 @@ end end - describe 'cycle_type_name' do + describe "cycle_type_name" do let(:bike) { FactoryBot.create(:bike, cycle_type: "cargo") } it "returns the normalized name" do normalized_name = CycleType.new(bike.cycle_type).name @@ -990,7 +990,7 @@ end end - describe 'propulsion_type_name' do + describe "propulsion_type_name" do let(:bike) { FactoryBot.create(:bike, propulsion_type: "electric-assist") } it "returns the normalized name" do normalized_name = PropulsionType.new(bike.propulsion_type).name diff --git a/spec/models/blog_spec.rb b/spec/models/blog_spec.rb index 84a473eb7b..7eed4f1f31 100644 --- a/spec/models/blog_spec.rb +++ b/spec/models/blog_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe Blog do # describe 'validations' do @@ -11,7 +11,7 @@ describe "friendly_find" do let(:user) { FactoryBot.create(:user) } - let!(:blog) { Blog.create(title: 'foo title', body: 'ummmmm good', user_id: user.id, old_title_slug: 'an-elder-statesman-title') } + let!(:blog) { Blog.create(title: "foo title", body: "ummmmm good", user_id: user.id, old_title_slug: "an-elder-statesman-title") } it "finds by the things we expect it to" do expect(blog.title_slug).to eq "foo-title" expect(Blog.friendly_find("foo title").id).to eq blog.id @@ -26,33 +26,33 @@ end end - describe 'set_title_slug' do - it 'makes the title 70 char long and character safe for params' do + describe "set_title_slug" do + it "makes the title 70 char long and character safe for params" do @user = FactoryBot.create(:user) - blog = Blog.new(title: 'A really really really really loooooooooooooooooooooooooooooooooooong title that absolutely rocks so hard', body: 'some things', user_id: @user.id, published_at: Time.now) + blog = Blog.new(title: "A really really really really loooooooooooooooooooooooooooooooooooong title that absolutely rocks so hard", body: "some things", user_id: @user.id, published_at: Time.now) blog.save - expect(blog.title_slug).to eq('a-really-really-really-really-loooooooooooooooooooooooooooooooooooong') + expect(blog.title_slug).to eq("a-really-really-really-really-loooooooooooooooooooooooooooooooooooong") end end - describe 'update_title_save' do - it 'makes the title 70 char long and character safe for params' do + describe "update_title_save" do + it "makes the title 70 char long and character safe for params" do @user = FactoryBot.create(:user) - blog = Blog.new(title: 'A really really really really loooooooooooooooooooooooooooooooooooong title that absolutely rocks so hard', body: 'some things', user_id: @user.id, published_at: Time.now) + blog = Blog.new(title: "A really really really really loooooooooooooooooooooooooooooooooooong title that absolutely rocks so hard", body: "some things", user_id: @user.id, published_at: Time.now) blog.save - blog.title = 'New Title' - blog.update_title = '1' + blog.title = "New Title" + blog.update_title = "1" blog.save - expect(blog.title_slug).to eq('new-title') - expect(blog.old_title_slug).to eq('a-really-really-really-really-loooooooooooooooooooooooooooooooooooong') + expect(blog.title_slug).to eq("new-title") + expect(blog.old_title_slug).to eq("a-really-really-really-really-loooooooooooooooooooooooooooooooooooong") end end - describe 'create_abbreviation' do - it 'makes the text 200 char long or less and remove any new lines' do + describe "create_abbreviation" do + it "makes the text 200 char long or less and remove any new lines" do @user = FactoryBot.create(:user) - blog = Blog.new(title: 'Blog title', user_id: @user.id, published_at: Time.now) - blog.body = ''" + blog = Blog.new(title: "Blog title", user_id: @user.id, published_at: Time.now) + blog.body = "" " Lorem ipsum dolor sit amet! Consectetur adipisicing elit, sed do eiusmod @@ -65,32 +65,32 @@ proident, sunt in culpa qui officia deserunt mollit anim id est laborum. lorem - "'' + " "" blog.save - expect(blog.body_abbr).to eq('Lorem ipsum dolor sit amet! Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ...') + expect(blog.body_abbr).to eq("Lorem ipsum dolor sit amet! Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ...") end - it 'creates the body abbr from a listicle' do + it "creates the body abbr from a listicle" do @user = FactoryBot.create(:user) - blog = Blog.create(title: 'Blog title', user_id: @user.id, published_at: Time.now, body: 'stuff', is_listicle: true) + blog = Blog.create(title: "Blog title", user_id: @user.id, published_at: Time.now, body: "stuff", is_listicle: true) Listicle.create(blog_id: blog.id, body: "View the link\n[here](http://something)\n\nBike Index shirt and stickers\n![PBR, a bike bag and drawings](http://imgur.com/e4zzEjP.jpg) and also this") blog.reload.save - expect(blog.reload.body_abbr).to eq('View the link here and also this') + expect(blog.reload.body_abbr).to eq("View the link here and also this") end - it 'removes any link information and images' do + it "removes any link information and images" do # TODO: remove markdown images # Also, it would be cool if we could end on a word instead of in the middle of one... @user = FactoryBot.create(:user) - blog = Blog.new(title: 'Blog title', user_id: @user.id, published_at: Time.now) + blog = Blog.new(title: "Blog title", user_id: @user.id, published_at: Time.now) blog.body = "View the link\n[here](http://something)\n\nBike Index shirt and stickers\n![PBR, a bike bag and drawings](http://imgur.com/e4zzEjP.jpg) and also this" blog.save - expect(blog.body_abbr).to eq('View the link here and also this') + expect(blog.body_abbr).to eq("View the link here and also this") end end - describe 'set_index_image' do - it 'sets the public image for a blog' do + describe "set_index_image" do + it "sets the public image for a blog" do blog = FactoryBot.create(:blog) public_image = FactoryBot.create(:public_image, imageable: blog) blog.reload # Reload so it knows about association @@ -108,20 +108,20 @@ end end - describe 'feed_content' do - it 'returns html content for non-listicles' do - blog = Blog.new(body: 'something') + describe "feed_content" do + it "returns html content for non-listicles" do + blog = Blog.new(body: "something") expect(blog.feed_content).to eq("

    something

    \n") end - it 'returns listicles' do + it "returns listicles" do blog = Blog.new(is_listicle: true) - listicle = Listicle.new(body: 'body', title: 'title', image_credits: 'credit') + listicle = Listicle.new(body: "body", title: "title", image_credits: "credit") listicle.htmlize_content allow(blog).to receive(:listicles).and_return([listicle]) target = '

    credit

    ' \ "\n" + '

    title

    body

    ' \ - "\n" + '
    ' + "\n" + "" expect(blog.feed_content).to eq(target) end end diff --git a/spec/models/bulk_import_spec.rb b/spec/models/bulk_import_spec.rb index 4b539d109f..8de3d2e3e9 100644 --- a/spec/models/bulk_import_spec.rb +++ b/spec/models/bulk_import_spec.rb @@ -16,7 +16,7 @@ end end context "existing errors - unlikely, but worth just to make sure" do - let(:existing_errors) { { line: [2, "Nobody loves you"], file: "Wrong place wrong time", file_lines: [1] } } + let(:existing_errors) { { line: [2, "Nobody loves you"], file: "Wrong place wrong time", file_lines: [1] } } let!(:bulk_import) { FactoryBot.create(:bulk_import, progress: "ongoing", import_errors: existing_errors) } it "adds a new error" do expect(bulk_import.starting_line).to eq 2 diff --git a/spec/models/cgroup_spec.rb b/spec/models/cgroup_spec.rb index 814fd309ce..bcb066d90c 100644 --- a/spec/models/cgroup_spec.rb +++ b/spec/models/cgroup_spec.rb @@ -1,16 +1,16 @@ -require 'spec_helper' +require "spec_helper" describe Cgroup do - it_behaves_like 'friendly_slug_findable' - describe 'validations' do + it_behaves_like "friendly_slug_findable" + describe "validations" do it { is_expected.to have_many :ctypes } it { is_expected.to validate_presence_of :name } it { is_expected.to validate_uniqueness_of :name } end - describe 'additional_parts' do - it 'finds additional parts' do - expect(Cgroup.additional_parts.name).to eq 'Additional parts' + describe "additional_parts" do + it "finds additional parts" do + expect(Cgroup.additional_parts.name).to eq "Additional parts" end end end diff --git a/spec/models/color_spec.rb b/spec/models/color_spec.rb index 873b48e282..dc89f40f55 100644 --- a/spec/models/color_spec.rb +++ b/spec/models/color_spec.rb @@ -1,44 +1,44 @@ -require 'spec_helper' +require "spec_helper" describe Color do - it_behaves_like 'friendly_name_findable' - it_behaves_like 'autocomplete_hashable' - describe 'validations' do + it_behaves_like "friendly_name_findable" + it_behaves_like "autocomplete_hashable" + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_presence_of :priority } it { is_expected.to validate_uniqueness_of :name } it { is_expected.to have_many :paints } end - describe 'friendly_find' do + describe "friendly_find" do it "finds users by email address when the case doesn't match" do - color = FactoryBot.create(:color, name: 'Poopy PANTERS') - expect(Color.friendly_find('poopy panters')).to eq(color) + color = FactoryBot.create(:color, name: "Poopy PANTERS") + expect(Color.friendly_find("poopy panters")).to eq(color) end end - describe 'autocomplete_hash' do - it 'returns what we want' do - color = FactoryBot.create(:color, name: 'blue', display: '#386ed2') + describe "autocomplete_hash" do + it "returns what we want" do + color = FactoryBot.create(:color, name: "blue", display: "#386ed2") result = color.autocomplete_hash expect(result.keys).to eq(%w(id text category priority data)) - expect(result['data']['display']).to eq color.display - expect(result['data']['search_id']).to eq("c_#{color.id}") + expect(result["data"]["display"]).to eq color.display + expect(result["data"]["search_id"]).to eq("c_#{color.id}") end end - describe 'update_display_format' do - context 'with a background color' do - it 'removes the extra display information to just return a color' do - color = FactoryBot.create(:color, name: 'blue', display: "") + describe "update_display_format" do + context "with a background color" do + it "removes the extra display information to just return a color" do + color = FactoryBot.create(:color, name: "blue", display: "") color.reload color.update_display_format - expect(color.display).to eq('#386ed2') + expect(color.display).to eq("#386ed2") end end - context 'without a background color' do - it 'makes it white with full transparency' do - color = FactoryBot.create(:color, name: 'blue', display: "stckrs") + context "without a background color" do + it "makes it white with full transparency" do + color = FactoryBot.create(:color, name: "blue", display: "stckrs") color.reload color.update_display_format expect(color.display).to be_nil @@ -46,9 +46,9 @@ end end - describe 'black' do - context 'not-existing' do - it 'creates it on first pass' do + describe "black" do + context "not-existing" do + it "creates it on first pass" do expect { Color.black }.to change(Color, :count).by(1) end end diff --git a/spec/models/component_spec.rb b/spec/models/component_spec.rb index d7011a4af5..6703f14c26 100644 --- a/spec/models/component_spec.rb +++ b/spec/models/component_spec.rb @@ -1,60 +1,60 @@ -require 'spec_helper' +require "spec_helper" describe Component do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :bike } it { is_expected.to belong_to :manufacturer } it { is_expected.to belong_to :ctype } end - describe 'component_type' do - it 'returns the name of the ctype other if it should' do + describe "component_type" do + it "returns the name of the ctype other if it should" do ctype = Ctype.new component = Component.new allow(component).to receive(:ctype).and_return(ctype) - allow(ctype).to receive(:name).and_return('Other') - allow(component).to receive(:ctype_other).and_return('OOOP') - expect(component.component_type).to eq('OOOP') + allow(ctype).to receive(:name).and_return("Other") + allow(component).to receive(:ctype_other).and_return("OOOP") + expect(component.component_type).to eq("OOOP") end - it 'returns the name of the ctype' do + it "returns the name of the ctype" do ctype = Ctype.new component = Component.new allow(component).to receive(:ctype).and_return(ctype) - allow(ctype).to receive(:name).and_return('stuff') - expect(component.component_type).to eq('stuff') + allow(ctype).to receive(:name).and_return("stuff") + expect(component.component_type).to eq("stuff") end end - describe 'set_front_or_rear' do - it 'returns the name of the ctype other if it should' do + describe "set_front_or_rear" do + it "returns the name of the ctype other if it should" do bike = FactoryBot.create(:bike) - FactoryBot.create(:component, bike: bike, front_or_rear: 'both') + FactoryBot.create(:component, bike: bike, front_or_rear: "both") expect(bike.reload.components.count).to eq(2) end end - describe 'manufacturer_name' do - it 'returns the value of manufacturer_other if manufacturer is other' do + describe "manufacturer_name" do + it "returns the value of manufacturer_other if manufacturer is other" do mnfg = Ctype.new component = Component.new allow(component).to receive(:manufacturer).and_return(mnfg) - allow(mnfg).to receive(:name).and_return('stuff') - expect(component.manufacturer_name).to eq('stuff') + allow(mnfg).to receive(:name).and_return("stuff") + expect(component.manufacturer_name).to eq("stuff") end it "returns the name of the manufacturer if it isn't other" do mnfg = Ctype.new component = Component.new allow(component).to receive(:manufacturer).and_return(mnfg) - allow(component).to receive(:manufacturer_other).and_return('oooop') - allow(mnfg).to receive(:name).and_return('Other') - expect(component.manufacturer_name).to eq('oooop') + allow(component).to receive(:manufacturer_other).and_return("oooop") + allow(mnfg).to receive(:name).and_return("Other") + expect(component.manufacturer_name).to eq("oooop") end end - describe 'set_is_stock' do - it 'sets not stock if description changed' do + describe "set_is_stock" do + it "sets not stock if description changed" do component = FactoryBot.create(:component, is_stock: true) expect(component.is_stock).to be_truthy component.year = 1987 @@ -62,35 +62,35 @@ component.manufacturer_id = 69 component.set_is_stock expect(component.is_stock).to be_truthy - component.description = 'A new description' + component.description = "A new description" component.set_is_stock expect(component.is_stock).to be_falsey end - it 'sets not stock if cmodel_name changed' do + it "sets not stock if cmodel_name changed" do component = FactoryBot.create(:component, is_stock: true) expect(component.is_stock).to be_truthy - component.cmodel_name = 'New mode' + component.cmodel_name = "New mode" component.set_is_stock expect(component.is_stock).to be_falsey end - it 'skips if setting_is_stock' do + it "skips if setting_is_stock" do component = FactoryBot.create(:component, is_stock: true) expect(component.is_stock).to be_truthy component.setting_is_stock = true - component.cmodel_name = 'New mode' + component.cmodel_name = "New mode" component.set_is_stock expect(component.is_stock).to be_truthy end - it 'has before_save_callback_method defined for clean_frame_size' do + it "has before_save_callback_method defined for clean_frame_size" do expect(Component._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:set_is_stock)).to eq(true) end end - describe 'fuzzy_assign_mnfg' do - context 'manufacturer_id a manufacturer name' do - it 'sets manufacturer_id correctly' do - m = FactoryBot.create(:manufacturer, name: 'SRAM') - c = { manufacturer_id: 'sram' } + describe "fuzzy_assign_mnfg" do + context "manufacturer_id a manufacturer name" do + it "sets manufacturer_id correctly" do + m = FactoryBot.create(:manufacturer, name: "SRAM") + c = { manufacturer_id: "sram" } component = ComponentCreator.new.set_manufacturer_key(c) expect(component[:manufacturer_id]).to eq m.id expect(component[:manufacturer]).to_not be_present diff --git a/spec/models/country_spec.rb b/spec/models/country_spec.rb index 788f674cf6..fa28f053be 100644 --- a/spec/models/country_spec.rb +++ b/spec/models/country_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Country do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_uniqueness_of :iso } it { is_expected.to validate_uniqueness_of :iso } @@ -9,14 +9,14 @@ it { is_expected.to have_many :locations } end - describe 'fuzzy_iso_find' do + describe "fuzzy_iso_find" do it "finds the country by ISO address when the case doesn't match" do - country = Country.create(name: 'EEEEEEEh', iso: 'LULZ') - expect(Country.fuzzy_iso_find('lulz ')).to eq(country) + country = Country.create(name: "EEEEEEEh", iso: "LULZ") + expect(Country.fuzzy_iso_find("lulz ")).to eq(country) end - it 'finds USA' do - country = Country.create(name: 'United States', iso: 'US') - expect(Country.fuzzy_iso_find('USA')).to eq(country) + it "finds USA" do + country = Country.create(name: "United States", iso: "US") + expect(Country.fuzzy_iso_find("USA")).to eq(country) end end end diff --git a/spec/models/creation_state_spec.rb b/spec/models/creation_state_spec.rb index 6da65d2fb1..00b0a0b3a9 100644 --- a/spec/models/creation_state_spec.rb +++ b/spec/models/creation_state_spec.rb @@ -1,75 +1,75 @@ -require 'spec_helper' +require "spec_helper" RSpec.describe CreationState, type: :model do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :bike } it { is_expected.to belong_to :creator } it { is_expected.to belong_to :organization } end - describe 'origin' do - context 'unknown origin' do - it 'ignores an unknown origin' do - creation_state = CreationState.new(origin: 'SOMEwhere', bike_id: 2) + describe "origin" do + context "unknown origin" do + it "ignores an unknown origin" do + creation_state = CreationState.new(origin: "SOMEwhere", bike_id: 2) creation_state.ensure_permitted_origin expect(creation_state.origin).to be_nil end end - context 'known origin' do + context "known origin" do let(:origin) { CreationState.origins.last } - it 'uses the origin' do + it "uses the origin" do creation_state = CreationState.new(origin: origin) creation_state.ensure_permitted_origin expect(creation_state.origin).to eq origin end end - it 'has a before_save callback for ensure_permitted_origin' do + it "has a before_save callback for ensure_permitted_origin" do expect(CreationState._validation_callbacks.select { |cb| cb.kind.eql?(:before) } .map(&:raw_filter).include?(:ensure_permitted_origin)).to be_truthy end end - describe 'creation_description' do - context 'bulk' do - let(:creation_state) { CreationState.new(is_bulk: true, origin: 'api_v12') } - it 'returns bulk reg' do - expect(creation_state.creation_description).to eq 'bulk reg' + describe "creation_description" do + context "bulk" do + let(:creation_state) { CreationState.new(is_bulk: true, origin: "api_v12") } + it "returns bulk reg" do + expect(creation_state.creation_description).to eq "bulk reg" end end - context 'pos' do - let(:creation_state) { CreationState.new(is_pos: true, origin: 'embed_extended') } - it 'returns pos reg' do - expect(creation_state.creation_description).to eq 'pos' + context "pos" do + let(:creation_state) { CreationState.new(is_pos: true, origin: "embed_extended") } + it "returns pos reg" do + expect(creation_state.creation_description).to eq "pos" end end - context 'embed_extended' do - let(:creation_state) { CreationState.new(origin: 'embed_extended') } - it 'returns pos reg' do - expect(creation_state.creation_description).to eq 'embed extended' + context "embed_extended" do + let(:creation_state) { CreationState.new(origin: "embed_extended") } + it "returns pos reg" do + expect(creation_state.creation_description).to eq "embed extended" end end - context 'nil' do + context "nil" do let(:creation_state) { CreationState.new(organization_id: 1, creator_id: 1) } - it 'returns nil' do + it "returns nil" do expect(creation_state.creation_description).to be_nil end end end - describe 'create_bike_organization' do + describe "create_bike_organization" do let(:bike) { FactoryBot.create(:bike) } let(:organization) { FactoryBot.create(:organization) } - context 'no organization' do + context "no organization" do let(:creation_state) { FactoryBot.create(:creation_state, bike: bike) } - it 'returns true' do + it "returns true" do expect do creation_state.create_bike_organization end.to change(BikeOrganization, :count).by 0 end end - context 'with organization' do + context "with organization" do let(:creation_state) { FactoryBot.create(:creation_state, bike: bike) } - it 'creates the bike_organization' do + it "creates the bike_organization" do creation_state.organization = organization expect do creation_state.create_bike_organization @@ -79,12 +79,11 @@ end context "parent organization" do it "creates the bike_organization for both" do - end end - context 'already existing bike_organization' do + context "already existing bike_organization" do let(:creation_state) { FactoryBot.create(:creation_state, bike: bike) } - it 'does not error or duplicate' do + it "does not error or duplicate" do FactoryBot.create(:bike_organization, bike: bike, organization: organization) creation_state.organization = organization expect do @@ -92,20 +91,20 @@ end.to change(BikeOrganization, :count).by 0 end end - it 'has an after_create callback' do + it "has an after_create callback" do expect(CreationState._create_callbacks.select { |cb| cb.kind.eql?(:after) } .map(&:raw_filter).include?(:create_bike_organization)).to eq(true) end end - context 'set_reflexive_association' do - it 'sets the creation_state_id on bike' do + context "set_reflexive_association" do + it "sets the creation_state_id on bike" do creation_state = FactoryBot.create(:creation_state) bike = creation_state.bike bike.reload expect(bike.creation_state_id).to eq creation_state.id end - it 'has an after_save callback' do + it "has an after_save callback" do expect(CreationState._save_callbacks.select { |cb| cb.kind.eql?(:after) } .map(&:raw_filter).include?(:set_reflexive_association)).to eq(true) end diff --git a/spec/models/ctype_spec.rb b/spec/models/ctype_spec.rb index 1018f607fd..a08f3845a9 100644 --- a/spec/models/ctype_spec.rb +++ b/spec/models/ctype_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe Ctype do - it_behaves_like 'friendly_slug_findable' - describe 'validations' do + it_behaves_like "friendly_slug_findable" + describe "validations" do it { is_expected.to belong_to :cgroup } it { is_expected.to have_many :components } it { is_expected.to validate_presence_of :name } diff --git a/spec/models/customer_contact_spec.rb b/spec/models/customer_contact_spec.rb index d1303c613f..1c92024f8d 100644 --- a/spec/models/customer_contact_spec.rb +++ b/spec/models/customer_contact_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe CustomerContact do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :user_email } it { is_expected.to validate_presence_of :creator_email } # it { should validate_presence_of :creator_id } @@ -15,15 +15,15 @@ it { is_expected.to serialize :info_hash } end - describe 'normalize_email_and_find_user' do - it 'finds email and associate' do + describe "normalize_email_and_find_user" do + it "finds email and associate" do user = FactoryBot.create(:user) cc = CustomerContact.new allow(cc).to receive(:user_email).and_return(user.email) cc.normalize_email_and_find_user expect(cc.user_id).to eq(user.id) end - it 'has before_save_callback_method defined as a before_save callback' do + it "has before_save_callback_method defined as a before_save callback" do expect(CustomerContact._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:normalize_email_and_find_user)).to eq(true) end end diff --git a/spec/models/cycle_type_spec.rb b/spec/models/cycle_type_spec.rb index fcda73134e..c9462cd5a3 100644 --- a/spec/models/cycle_type_spec.rb +++ b/spec/models/cycle_type_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe CycleType do describe "normalized name" do diff --git a/spec/models/duplicate_bike_group_spec.rb b/spec/models/duplicate_bike_group_spec.rb index f632dc5fee..78702bed0f 100644 --- a/spec/models/duplicate_bike_group_spec.rb +++ b/spec/models/duplicate_bike_group_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require "spec_helper" describe DuplicateBikeGroup do it { is_expected.to have_many :normalized_serial_segments } it { is_expected.to have_many :bikes } - describe 'segment' do - it 'returns the first segment' do + describe "segment" do + it "returns the first segment" do duplicate_bike_group = DuplicateBikeGroup.new - normalized_serial_segment = NormalizedSerialSegment.new(segment: 'stuff') + normalized_serial_segment = NormalizedSerialSegment.new(segment: "stuff") allow(duplicate_bike_group).to receive(:normalized_serial_segments).and_return([normalized_serial_segment]) - expect(duplicate_bike_group.segment).to eq('stuff') + expect(duplicate_bike_group.segment).to eq("stuff") end end end diff --git a/spec/models/feedback_spec.rb b/spec/models/feedback_spec.rb index ff718958d6..4d30c032d7 100644 --- a/spec/models/feedback_spec.rb +++ b/spec/models/feedback_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Feedback do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :body } it { is_expected.to validate_presence_of :email } it { is_expected.to validate_presence_of :title } @@ -10,41 +10,41 @@ # it { should belong_to :application } # This is Doorkeeper::Application, not application end - describe 'create' do - it 'enqueues an email job' do + describe "create" do + it "enqueues an email job" do expect do FactoryBot.create(:feedback) end.to change(EmailFeedbackNotificationWorker.jobs, :size).by(1) end - it 'enqueues an email job for delete requests' do + it "enqueues an email job for delete requests" do expect do - FactoryBot.create(:feedback, feedback_type: 'bike_delete_request') + FactoryBot.create(:feedback, feedback_type: "bike_delete_request") end.to change(EmailFeedbackNotificationWorker.jobs, :size).by(1) end it "doesn't enqueue an email job for serial updates" do expect do - FactoryBot.create(:feedback, feedback_type: 'serial_update_request') + FactoryBot.create(:feedback, feedback_type: "serial_update_request") end.to change(EmailFeedbackNotificationWorker.jobs, :size).by(0) end it "doesn't enqueue an email job for manufacturer updates" do expect do - FactoryBot.create(:feedback, feedback_type: 'manufacturer_update_request') + FactoryBot.create(:feedback, feedback_type: "manufacturer_update_request") end.to change(EmailFeedbackNotificationWorker.jobs, :size).by(0) end end - describe 'lead_type' do - context 'non-lead feedback' do - it 'returns nil' do - expect(Feedback.new(feedback_type: 'manufacturer_update_request').lead_type).to be_nil + describe "lead_type" do + context "non-lead feedback" do + it "returns nil" do + expect(Feedback.new(feedback_type: "manufacturer_update_request").lead_type).to be_nil end end - context 'lead type feedback' do - it 'returns type' do - expect(Feedback.new(feedback_type: 'lead_for_school').lead_type).to eq 'School' + context "lead type feedback" do + it "returns type" do + expect(Feedback.new(feedback_type: "lead_for_school").lead_type).to eq "School" end end end diff --git a/spec/models/front_gear_type_spec.rb b/spec/models/front_gear_type_spec.rb index fc993e7dc7..f207198b16 100644 --- a/spec/models/front_gear_type_spec.rb +++ b/spec/models/front_gear_type_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe FrontGearType do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_presence_of :count } it { is_expected.to validate_uniqueness_of :name } diff --git a/spec/models/handlebar_type_spec.rb b/spec/models/handlebar_type_spec.rb index 4f76894708..3f6c3131f2 100644 --- a/spec/models/handlebar_type_spec.rb +++ b/spec/models/handlebar_type_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe HandlebarType do describe "normalized name" do diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb index 93673ddeb1..78bc7c58ea 100644 --- a/spec/models/integration_spec.rb +++ b/spec/models/integration_spec.rb @@ -1,39 +1,39 @@ -require 'spec_helper' +require "spec_helper" describe Integration do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :information } it { is_expected.to validate_presence_of :access_token } end - let(:facebook_file) { File.read(Rails.root.join('spec', 'fixtures', 'integration_data_facebook.json')) } - let(:strava_file) { File.read(Rails.root.join('spec', 'fixtures', 'integration_data_strava.json')) } + let(:facebook_file) { File.read(Rails.root.join("spec", "fixtures", "integration_data_facebook.json")) } + let(:strava_file) { File.read(Rails.root.join("spec", "fixtures", "integration_data_strava.json")) } - describe 'associate_with_user' do - context 'facebook integration' do + describe "associate_with_user" do + context "facebook integration" do let(:info) { JSON.parse(facebook_file) } - it 'associates with a user if the emails match' do - user = FactoryBot.create(:user, email: 'foo.user@gmail.com') + it "associates with a user if the emails match" do + user = FactoryBot.create(:user, email: "foo.user@gmail.com") integration = FactoryBot.create(:integration, information: info) expect(user.id).to eq(integration.user.id) end - it 'marks the user confirmed but not mark the terms of service agreed' do - user = FactoryBot.create(:user, email: 'foo.user@gmail.com', confirmed: false, terms_of_service: false) + it "marks the user confirmed but not mark the terms of service agreed" do + user = FactoryBot.create(:user, email: "foo.user@gmail.com", confirmed: false, terms_of_service: false) integration = FactoryBot.create(:integration, information: info) expect(integration.user).to eq(user) expect(integration.user.confirmed).to be_truthy expect(integration.user.terms_of_service).to be_falsey end - it 'creates a user, associate it if the emails match and run new user tasks' do + it "creates a user, associate it if the emails match and run new user tasks" do expect do expect_any_instance_of(AfterUserCreateWorker).to receive(:perform_confirmed_jobs) FactoryBot.create(:integration, information: info) end.to change(User, :count).by 1 end - it 'deletes previous integrations with the same service' do + it "deletes previous integrations with the same service" do integration = FactoryBot.create(:integration, information: info) expect(integration.user.confirmed).to be_truthy expect do @@ -42,30 +42,30 @@ end end - context 'strava integration' do + context "strava integration" do let(:info) { JSON.parse(strava_file) } - it 'associates with a user if the emails match' do - user = FactoryBot.create(:user, email: 'bar@example.com') + it "associates with a user if the emails match" do + user = FactoryBot.create(:user, email: "bar@example.com") integration = FactoryBot.create(:integration, information: info) expect(user.id).to eq(integration.user.id) end - it 'marks the user confirmed but not mark the terms of service agreed' do - user = FactoryBot.create(:user, email: 'bar@example.com', confirmed: false, terms_of_service: false) + it "marks the user confirmed but not mark the terms of service agreed" do + user = FactoryBot.create(:user, email: "bar@example.com", confirmed: false, terms_of_service: false) integration = FactoryBot.create(:integration, information: info) expect(integration.user).to eq(user) expect(integration.user.confirmed).to be_truthy expect(integration.user.terms_of_service).to be_falsey end - it 'creates a user, associate it if the emails match and run new user tasks' do + it "creates a user, associate it if the emails match and run new user tasks" do expect do expect_any_instance_of(AfterUserCreateWorker).to receive(:perform_confirmed_jobs) FactoryBot.create(:integration, information: info) end.to change(User, :count).by 1 end - it 'deletes previous integrations with the same service' do + it "deletes previous integrations with the same service" do integration = FactoryBot.create(:integration, information: info) expect(integration.user.confirmed).to be_truthy expect do diff --git a/spec/models/listicle_spec.rb b/spec/models/listicle_spec.rb index 2c31370351..d353411851 100644 --- a/spec/models/listicle_spec.rb +++ b/spec/models/listicle_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Listicle do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :blog } end end diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 480188ef38..e1ac30b858 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Location do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :organization } it { is_expected.to belong_to :country } it { is_expected.to belong_to :state } @@ -11,15 +11,15 @@ it { is_expected.to validate_presence_of :country } end - describe 'set_phone' do - it 'strips the non-digit numbers from the phone input' do - location = FactoryBot.create(:location, phone: '773.83ddp+83(887)') - expect(location.phone).to eq('7738383887') + describe "set_phone" do + it "strips the non-digit numbers from the phone input" do + location = FactoryBot.create(:location, phone: "773.83ddp+83(887)") + expect(location.phone).to eq("7738383887") end end - describe 'address' do - it 'strips the non-digit numbers from the phone input' do + describe "address" do + it "strips the non-digit numbers from the phone input" do location = FactoryBot.create(:location) expect(location.address).to be_a(String) end @@ -37,8 +37,8 @@ end end - describe 'org_location_id' do - it 'creates a unique id that references the organization' do + describe "org_location_id" do + it "creates a unique id that references the organization" do location = FactoryBot.create(:location) expect(location.org_location_id).to eq("#{location.organization_id}_#{location.id}") end diff --git a/spec/models/lock_type_spec.rb b/spec/models/lock_type_spec.rb index a92e449514..f12f64b3df 100644 --- a/spec/models/lock_type_spec.rb +++ b/spec/models/lock_type_spec.rb @@ -1,24 +1,24 @@ -require 'spec_helper' +require "spec_helper" describe LockType do - it_behaves_like 'friendly_slug_findable' + it_behaves_like "friendly_slug_findable" - describe 'manufacturer_name' do - it 'returns the value of manufacturer_other if manufacturer is other' do + describe "manufacturer_name" do + it "returns the value of manufacturer_other if manufacturer is other" do lock = Lock.new other_manufacturer = Manufacturer.new - allow(other_manufacturer).to receive(:name).and_return('Other') + allow(other_manufacturer).to receive(:name).and_return("Other") allow(lock).to receive(:manufacturer).and_return(other_manufacturer) - allow(lock).to receive(:manufacturer_other).and_return('Other manufacturer name') - expect(lock.manufacturer_name).to eq('Other manufacturer name') + allow(lock).to receive(:manufacturer_other).and_return("Other manufacturer name") + expect(lock.manufacturer_name).to eq("Other manufacturer name") end it "returns the name of the manufacturer if it isn't other" do lock = Lock.new manufacturer = Manufacturer.new - allow(manufacturer).to receive(:name).and_return('Mnfg name') + allow(manufacturer).to receive(:name).and_return("Mnfg name") allow(lock).to receive(:manufacturer).and_return(manufacturer) - expect(lock.manufacturer_name).to eq('Mnfg name') + expect(lock.manufacturer_name).to eq("Mnfg name") end end end diff --git a/spec/models/mail_snippet_spec.rb b/spec/models/mail_snippet_spec.rb index 12f0228fe6..d358a32db7 100644 --- a/spec/models/mail_snippet_spec.rb +++ b/spec/models/mail_snippet_spec.rb @@ -1,14 +1,14 @@ -require 'spec_helper' +require "spec_helper" describe MailSnippet do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to belong_to :organization } it { is_expected.to validate_uniqueness_of(:organization_id).scoped_to(:name) } end - describe 'disable_if_blank' do - it 'sets unenabled if body is blank' do + describe "disable_if_blank" do + it "sets unenabled if body is blank" do mail_snippet = MailSnippet.new(is_enabled: true, body: nil, name: "welcome") expect(mail_snippet.is_enabled).to be_truthy mail_snippet.save diff --git a/spec/models/manufacturer_spec.rb b/spec/models/manufacturer_spec.rb index 3a8aa65281..4aea164f34 100644 --- a/spec/models/manufacturer_spec.rb +++ b/spec/models/manufacturer_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe Manufacturer do - it_behaves_like 'autocomplete_hashable' - describe 'validations' do + it_behaves_like "autocomplete_hashable" + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_uniqueness_of :name } it { is_expected.to validate_uniqueness_of :slug } @@ -12,78 +12,78 @@ it { is_expected.to have_many :paints } end - describe 'default_scope is alphabetized' do - it 'default scopes to created_at desc' do + describe "default_scope is alphabetized" do + it "default scopes to created_at desc" do expect(Manufacturer.all.to_sql).to eq(Manufacturer.unscoped.order(:name).to_sql) end end - describe 'ensure_non_blocking_name' do - before { FactoryBot.create(:color, name: 'Purple') } - context 'name same as a color' do - it 'adds an error' do - manufacturer = FactoryBot.build(:manufacturer, name: ' pURple ') + describe "ensure_non_blocking_name" do + before { FactoryBot.create(:color, name: "Purple") } + context "name same as a color" do + it "adds an error" do + manufacturer = FactoryBot.build(:manufacturer, name: " pURple ") manufacturer.valid? - expect(manufacturer.errors.full_messages.to_s).to match 'same as a color' + expect(manufacturer.errors.full_messages.to_s).to match "same as a color" end end - context 'name includes a color' do - it 'adds no error' do - manufacturer = FactoryBot.build(:manufacturer, name: 'Purple bikes') + context "name includes a color" do + it "adds no error" do + manufacturer = FactoryBot.build(:manufacturer, name: "Purple bikes") manufacturer.valid? expect(manufacturer.errors.count).to eq 0 end end end - describe 'friendly_find' do - it 'finds manufacturers by their slug' do - mnfg = FactoryBot.create(:manufacturer, name: 'Poopy PANTERS') - expect(Manufacturer.friendly_find('poopy panters')).to eq(mnfg) + describe "friendly_find" do + it "finds manufacturers by their slug" do + mnfg = FactoryBot.create(:manufacturer, name: "Poopy PANTERS") + expect(Manufacturer.friendly_find("poopy panters")).to eq(mnfg) end it "removes Accell (because it's widespread mnfg)" do - mnfg = FactoryBot.create(:manufacturer, name: 'Poopy PANTERS') - expect(Manufacturer.friendly_find('poopy panters Accell')).to eq(mnfg) + mnfg = FactoryBot.create(:manufacturer, name: "Poopy PANTERS") + expect(Manufacturer.friendly_find("poopy panters Accell")).to eq(mnfg) end end - describe 'autocomplete_hash' do - it 'returns what we expect' do + describe "autocomplete_hash" do + it "returns what we expect" do manufacturer = FactoryBot.create(:manufacturer) result = manufacturer.autocomplete_hash expect(result.keys).to eq(%w(id text category priority data)) - expect(result['data']['slug']).to eq manufacturer.slug - expect(result['data']['search_id']).to eq("m_#{manufacturer.id}") + expect(result["data"]["slug"]).to eq manufacturer.slug + expect(result["data"]["search_id"]).to eq("m_#{manufacturer.id}") end end - describe 'autocomplete_hash_category' do - context '0 bikes or components' do - it 'returns 0' do + describe "autocomplete_hash_category" do + context "0 bikes or components" do + it "returns 0" do manufacturer = Manufacturer.new allow(manufacturer).to receive(:bikes) { [] } allow(manufacturer).to receive(:components) { [] } expect(manufacturer.autocomplete_hash_priority).to eq(0) end end - context '1 component' do - it 'returns 10' do + context "1 component" do + it "returns 10" do manufacturer = Manufacturer.new allow(manufacturer).to receive(:bikes) { [] } allow(manufacturer).to receive(:components) { [2] } expect(manufacturer.autocomplete_hash_priority).to eq(10) end end - context '25 bikes and 50 components' do - it 'returns 15' do + context "25 bikes and 50 components" do + it "returns 15" do manufacturer = Manufacturer.new allow(manufacturer).to receive(:bikes) { Array(0..24) } allow(manufacturer).to receive(:components) { Array(0..50) } expect(manufacturer.autocomplete_hash_priority).to eq(15) end end - context '1020 bikes' do - it 'returns 100' do + context "1020 bikes" do + it "returns 100" do manufacturer = Manufacturer.new allow(manufacturer).to receive(:bikes) { Array(1..1020) } allow(manufacturer).to receive(:components) { [2, 2, 2] } @@ -92,68 +92,68 @@ end end - describe 'import csv' do - it 'adds manufacturers to the list' do - import_file = File.open(Rails.root.to_s + '/spec/fixtures/manufacturer-test-import.csv') + describe "import csv" do + it "adds manufacturers to the list" do + import_file = File.open(Rails.root.to_s + "/spec/fixtures/manufacturer-test-import.csv") expect do Manufacturer.import(import_file) end.to change(Manufacturer, :count).by(2) end - it 'adds in all the attributes that are listed' do - import_file = File.open(Rails.root.to_s + '/spec/fixtures/manufacturer-test-import.csv') + it "adds in all the attributes that are listed" do + import_file = File.open(Rails.root.to_s + "/spec/fixtures/manufacturer-test-import.csv") Manufacturer.import(import_file) - manufacturer = Manufacturer.find_by_slug('surly') - expect(manufacturer.website).to eq('http://surlybikes.com') + manufacturer = Manufacturer.find_by_slug("surly") + expect(manufacturer.website).to eq("http://surlybikes.com") expect(manufacturer.frame_maker).to be_truthy expect(manufacturer.open_year).to eq(1900) expect(manufacturer.close_year).to eq(3000) - manufacturer2 = Manufacturer.find_by_slug('wethepeople') - expect(manufacturer2.website).to eq('http://wethepeople.com') + manufacturer2 = Manufacturer.find_by_slug("wethepeople") + expect(manufacturer2.website).to eq("http://wethepeople.com") end - it 'updates attributes on a second upload' do - import_file = File.open(Rails.root.to_s + '/spec/fixtures/manufacturer-test-import.csv') + it "updates attributes on a second upload" do + import_file = File.open(Rails.root.to_s + "/spec/fixtures/manufacturer-test-import.csv") Manufacturer.import(import_file) - second_import_file = File.open(Rails.root.to_s + '/spec/fixtures/manufacturer-test-import-second.csv') + second_import_file = File.open(Rails.root.to_s + "/spec/fixtures/manufacturer-test-import-second.csv") Manufacturer.import(second_import_file) - manufacturer = Manufacturer.find_by_slug('surly-bikes') + manufacturer = Manufacturer.find_by_slug("surly-bikes") end end - describe 'friendly_id_find' do - it 'gets id from name' do + describe "friendly_id_find" do + it "gets id from name" do manufacturer = FactoryBot.create(:manufacturer) result = Manufacturer.friendly_id_find(manufacturer.name) expect(result).to eq(manufacturer.id) end - it 'fails with nil' do - result = Manufacturer.friendly_id_find('some stuff') + it "fails with nil" do + result = Manufacturer.friendly_id_find("some stuff") expect(result).to be_nil end end - describe 'set_website_and_logo_source' do - it 'has before_save_callback_method defined for set_website' do + describe "set_website_and_logo_source" do + it "has before_save_callback_method defined for set_website" do expect(Manufacturer._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:set_website_and_logo_source)).to eq(true) end - it 'sets logo source' do + it "sets logo source" do manufacturer = Manufacturer.new - allow(manufacturer).to receive(:logo).and_return('http://example.com/logo.png') + allow(manufacturer).to receive(:logo).and_return("http://example.com/logo.png") manufacturer.set_website_and_logo_source - expect(manufacturer.logo_source).to eq('manual') + expect(manufacturer.logo_source).to eq("manual") end it "doesn't overwrite logo source" do - manufacturer = Manufacturer.new(logo_source: 'something cool') - allow(manufacturer).to receive(:logo).and_return('http://example.com/logo.png') + manufacturer = Manufacturer.new(logo_source: "something cool") + allow(manufacturer).to receive(:logo).and_return("http://example.com/logo.png") manufacturer.set_website_and_logo_source - expect(manufacturer.logo_source).to eq('something cool') + expect(manufacturer.logo_source).to eq("something cool") end - it 'empties if no logo' do - manufacturer = Manufacturer.new(logo_source: 'something cool') + it "empties if no logo" do + manufacturer = Manufacturer.new(logo_source: "something cool") manufacturer.set_website_and_logo_source expect(manufacturer.logo_source).to be_nil end diff --git a/spec/models/membership_spec.rb b/spec/models/membership_spec.rb index 7b52017d21..ffdb79a318 100644 --- a/spec/models/membership_spec.rb +++ b/spec/models/membership_spec.rb @@ -1,22 +1,22 @@ -require 'spec_helper' +require "spec_helper" describe Membership do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :organization } it { is_expected.to validate_presence_of(:role).with_message(/a role/i) } it { is_expected.to validate_presence_of(:organization).with_message(/organization/i) } it { is_expected.to validate_presence_of(:user).with_message(/user/) } end - describe 'admin?' do - context 'admin' do - it 'returns true' do - membership = Membership.new(role: 'admin') + describe "admin?" do + context "admin" do + it "returns true" do + membership = Membership.new(role: "admin") expect(membership.admin?).to be_truthy end end - context 'member' do - it 'returns true' do - membership = Membership.new(role: 'member') + context "member" do + it "returns true" do + membership = Membership.new(role: "member") expect(membership.admin?).to be_falsey end end diff --git a/spec/models/normalized_serial_segment_spec.rb b/spec/models/normalized_serial_segment_spec.rb index e48417b2d0..c5c87d486f 100644 --- a/spec/models/normalized_serial_segment_spec.rb +++ b/spec/models/normalized_serial_segment_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe NormalizedSerialSegment do it { is_expected.to belong_to :bike } diff --git a/spec/models/organization_invitation_spec.rb b/spec/models/organization_invitation_spec.rb index 89bb7aaa1c..7d192b8334 100644 --- a/spec/models/organization_invitation_spec.rb +++ b/spec/models/organization_invitation_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe OrganizationInvitation do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :inviter } it { is_expected.to belong_to :invitee } it { is_expected.to validate_presence_of :invitee_email } @@ -10,16 +10,16 @@ it { is_expected.to validate_presence_of :membership_role } end - describe 'create' do + describe "create" do before :each do @o = FactoryBot.create(:organization_invitation) end - it 'creates a valid organization_invitation' do + it "creates a valid organization_invitation" do expect(@o.valid?).to be_truthy end - it 'assigns to user if the user exists' do + it "assigns to user if the user exists" do @user = FactoryBot.create(:user_confirmed) @o1 = FactoryBot.create(:organization_invitation, invitee_email: @user.email) expect(@user.memberships.count).to eq(1) @@ -27,30 +27,30 @@ end end - it 'enqueues an email job' do + it "enqueues an email job" do expect do FactoryBot.create(:organization_invitation) end.to change(EmailOrganizationInvitationWorker.jobs, :size).by(1) end - describe 'normalize_email' do - it 'removes leading and trailing whitespace and downcase email' do + describe "normalize_email" do + it "removes leading and trailing whitespace and downcase email" do oi = OrganizationInvitation.new - allow(oi).to receive(:invitee_email).and_return(' SomE@dd.com ') - expect(oi.normalize_email).to eq('some@dd.com') + allow(oi).to receive(:invitee_email).and_return(" SomE@dd.com ") + expect(oi.normalize_email).to eq("some@dd.com") end end - describe 'assign_to(user)' do + describe "assign_to(user)" do before :each do @organization = FactoryBot.create(:organization) - @o = FactoryBot.create(:organization_invitation, organization: @organization, invitee_email: 'EMAIL@email.com') - @user = FactoryBot.create(:user_confirmed, email: 'EMAIL@email.com') + @o = FactoryBot.create(:organization_invitation, organization: @organization, invitee_email: "EMAIL@email.com") + @user = FactoryBot.create(:user_confirmed, email: "EMAIL@email.com") @o.reload @user.reload end # These are performed automatically as part of create_user_jobs, but we still want to test - it 'sets the user if the email matches and redeems' do + it "sets the user if the email matches and redeems" do @o.reload # @o.assign_to(@user) expect(@o.invitee.id).to eq(@user.id) @@ -59,17 +59,17 @@ it "sets the user's name if the name is blank" do @user2 = FactoryBot.create(:user_confirmed, name: nil) - @o2 = FactoryBot.create(:organization_invitation, organization: @organization, invitee_email: @user2.email, invitee_name: 'Biker Name') - expect(@user2.reload.name).to eq('Biker Name') + @o2 = FactoryBot.create(:organization_invitation, organization: @organization, invitee_email: @user2.email, invitee_name: "Biker Name") + expect(@user2.reload.name).to eq("Biker Name") end - it 'is not able to be used again once it has been redeemed' do + it "is not able to be used again once it has been redeemed" do @o.assign_to(@user) @o.assign_to(@user) expect(@user.memberships.count).to eq(1) end - it 'does not let users have more than one membership to a single organization' do + it "does not let users have more than one membership to a single organization" do @user.reload @o.reload expect(@user.memberships.count).to eq 1 @@ -77,7 +77,7 @@ expect(@user.memberships.count).to eq 1 end - it 'lets users have multiple memberships to different organizations' do + it "lets users have multiple memberships to different organizations" do @organization2 = FactoryBot.create(:organization) FactoryBot.create(:membership, organization: @organization2, user: @user) expect(@user.memberships.count).to eq(2) diff --git a/spec/models/organization_spec.rb b/spec/models/organization_spec.rb index b0ba9cebf2..f5f3689c8e 100644 --- a/spec/models/organization_spec.rb +++ b/spec/models/organization_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Organization do - describe 'validations' do + describe "validations" do # it { should validate_uniqueness_of :slug } it { is_expected.to validate_presence_of :name } it { is_expected.to have_many :memberships } @@ -17,38 +17,38 @@ it { is_expected.to belong_to :auto_user } end - describe 'scopes' do - it 'Shown on map is shown on map *and* validated' do + describe "scopes" do + it "Shown on map is shown on map *and* validated" do expect(Organization.shown_on_map.to_sql).to eq(Organization.where(show_on_map: true).where(approved: true).order(:name).to_sql) end end - describe 'admin text search' do - context 'by name' do - let!(:organization) { FactoryBot.create(:organization, name: 'University of Maryland') } - it 'finds the organization' do - expect(Organization.admin_text_search('maryl')).to eq([organization]) + describe "admin text search" do + context "by name" do + let!(:organization) { FactoryBot.create(:organization, name: "University of Maryland") } + it "finds the organization" do + expect(Organization.admin_text_search("maryl")).to eq([organization]) end end - context 'by slug' do - let!(:organization) { FactoryBot.create(:organization, short_name: 'UMD') } - it 'finds the organization' do - expect(Organization.admin_text_search('umd')).to eq([organization]) + context "by slug" do + let!(:organization) { FactoryBot.create(:organization, short_name: "UMD") } + it "finds the organization" do + expect(Organization.admin_text_search("umd")).to eq([organization]) end end - context 'through locations' do + context "through locations" do let!(:organization) { location.organization } - context 'by location name' do - let(:location) { FactoryBot.create(:location, name: 'Sweet spot') } - it 'finds the organization' do - expect(Organization.admin_text_search('sweet Spot')).to eq([organization]) + context "by location name" do + let(:location) { FactoryBot.create(:location, name: "Sweet spot") } + it "finds the organization" do + expect(Organization.admin_text_search("sweet Spot")).to eq([organization]) end end - context 'by location city' do - let(:location) { FactoryBot.create(:location, city: 'Chicago') } - let!(:location_2) { FactoryBot.create(:location, city: 'Chicago', organization: organization) } - it 'finds the organization' do - expect(Organization.admin_text_search('chi')).to eq([organization]) + context "by location city" do + let(:location) { FactoryBot.create(:location, city: "Chicago") } + let!(:location_2) { FactoryBot.create(:location, city: "Chicago", organization: organization) } + it "finds the organization" do + expect(Organization.admin_text_search("chi")).to eq([organization]) end end end @@ -155,19 +155,19 @@ end end - describe 'organization recoveries' do + describe "organization recoveries" do let(:organization) { FactoryBot.create(:organization) } let(:bike) { FactoryBot.create(:stolen_bike, creation_organization_id: organization.id) } let(:stolen_record) { bike.find_current_stolen_record } let!(:bike_organization) { FactoryBot.create(:bike_organization, bike: bike, organization: organization) } let(:recovery_information) do { - recovered_description: 'recovered it on a special corner', + recovered_description: "recovered it on a special corner", index_helped_recovery: true, - can_share_recovery: true + can_share_recovery: true, } end - it 'returns recovered bikes' do + it "returns recovered bikes" do organization.reload expect(organization.bikes).to eq([bike]) expect(organization.bikes.stolen).to eq([bike]) @@ -178,9 +178,9 @@ end end - describe 'set_calculated_attributes' do - it 'sets the short_name and the slug on save' do - organization = Organization.new(name: 'something') + describe "set_calculated_attributes" do + it "sets the short_name and the slug on save" do + organization = Organization.new(name: "something") organization.set_calculated_attributes expect(organization.short_name).to be_present expect(organization.slug).to be_present @@ -190,35 +190,35 @@ end it "doesn't xss" do - org = Organization.new(name: '', - website: '') + org = Organization.new(name: "", + website: "") org.set_calculated_attributes expect(org.name).to match(/stop messing about/i) - expect(org.website).to eq('http://') + expect(org.website).to eq("http://") expect(org.short_name).to match(/stop messing about/i) end it "protects from name collisions, without erroring because of it's own slug" do - org1 = Organization.create(name: 'Bicycle shop') + org1 = Organization.create(name: "Bicycle shop") org1.reload.save - expect(org1.reload.slug).to eq('bicycle-shop') - organization = Organization.new(name: 'Bicycle shop') + expect(org1.reload.slug).to eq("bicycle-shop") + organization = Organization.new(name: "Bicycle shop") organization.set_calculated_attributes - expect(organization.slug).to eq('bicycle-shop-2') + expect(organization.slug).to eq("bicycle-shop-2") end - describe 'set_locations_shown' do + describe "set_locations_shown" do let(:country) { FactoryBot.create(:country) } let(:organization) { FactoryBot.create(:organization, show_on_map: true, approved: true) } - let(:location) { Location.create(country_id: country.id, city: 'Chicago', name: 'stuff', organization_id: organization.id, shown: true) } - context 'organization approved' do - it 'sets the locations shown to be org shown on save' do + let(:location) { Location.create(country_id: country.id, city: "Chicago", name: "stuff", organization_id: organization.id, shown: true) } + context "organization approved" do + it "sets the locations shown to be org shown on save" do expect(organization.allowed_show).to be_truthy organization.set_calculated_attributes expect(location.reload.shown).to be_truthy end end - context 'not approved' do - it 'sets not shown' do + context "not approved" do + it "sets not shown" do organization.update_attribute :approved, false organization.reload expect(organization.allowed_show).to be_falsey @@ -228,26 +228,26 @@ end end - describe 'set_auto_user' do - it 'sets the embedable user' do + describe "set_auto_user" do + it "sets the embedable user" do organization = FactoryBot.create(:organization) - user = FactoryBot.create(:user_confirmed, email: 'embed@org.com') + user = FactoryBot.create(:user_confirmed, email: "embed@org.com") FactoryBot.create(:membership, organization: organization, user: user) - organization.embedable_user_email = 'embed@org.com' + organization.embedable_user_email = "embed@org.com" organization.save expect(organization.reload.auto_user_id).to eq(user.id) end - it 'does not set the embedable user if user is not a member' do + it "does not set the embedable user if user is not a member" do organization = FactoryBot.create(:organization) - FactoryBot.create(:user_confirmed, email: 'no_embed@org.com') - organization.embedable_user_email = 'no_embed@org.com' + FactoryBot.create(:user_confirmed, email: "no_embed@org.com") + organization.embedable_user_email = "no_embed@org.com" organization.save expect(organization.reload.auto_user_id).to be_nil end - it 'Makes a membership if the user is auto user' do + it "Makes a membership if the user is auto user" do organization = FactoryBot.create(:organization) - user = FactoryBot.create(:user_confirmed, email: ENV['AUTO_ORG_MEMBER']) - organization.embedable_user_email = ENV['AUTO_ORG_MEMBER'] + user = FactoryBot.create(:user_confirmed, email: ENV["AUTO_ORG_MEMBER"]) + organization.embedable_user_email = ENV["AUTO_ORG_MEMBER"] organization.save expect(organization.reload.auto_user_id).to eq(user.id) end @@ -261,26 +261,26 @@ end end - describe 'ensure_auto_user' do + describe "ensure_auto_user" do let(:organization) { FactoryBot.create(:organization) } - context 'existing members' do + context "existing members" do let(:member) { FactoryBot.create(:organization_member, organization: organization) } before do expect(member).to be_present end - it 'sets the first user' do + it "sets the first user" do organization.ensure_auto_user organization.reload expect(organization.auto_user).to eq member end end - context 'no members' do - let(:auto_user) { FactoryBot.create(:user_confirmed, email: ENV['AUTO_ORG_MEMBER']) } + context "no members" do + let(:auto_user) { FactoryBot.create(:user_confirmed, email: ENV["AUTO_ORG_MEMBER"]) } before do expect(organization).to be_present expect(auto_user).to be_present end - it 'sets the AUTO_ORG_MEMBER' do + it "sets the AUTO_ORG_MEMBER" do organization.ensure_auto_user organization.reload expect(organization.auto_user).to eq auto_user @@ -288,44 +288,44 @@ end end - describe 'display_avatar' do - context 'unpaid' do - it 'does not display' do + describe "display_avatar" do + context "unpaid" do + it "does not display" do organization = Organization.new(is_paid: false) - allow(organization).to receive(:avatar) { 'a pretty picture' } + allow(organization).to receive(:avatar) { "a pretty picture" } expect(organization.display_avatar).to be_falsey end end - context 'paid' do - it 'displays' do + context "paid" do + it "displays" do organization = Organization.new(is_paid: true) - allow(organization).to receive(:avatar) { 'a pretty picture' } + allow(organization).to receive(:avatar) { "a pretty picture" } expect(organization.display_avatar).to be_truthy end end end - describe 'mail_snippet_body' do + describe "mail_snippet_body" do let(:organization) { FactoryBot.create(:organization) } before do expect((organization && mail_snippet).present?).to be_truthy expect(organization.mail_snippets).to be_present end - context 'not included snippet type' do - let(:mail_snippet) { FactoryBot.create(:organization_mail_snippet, organization: organization, name: 'fool') } - it 'returns nil for not-allowed snippet type' do - expect(organization.mail_snippet_body('fool')).to be nil + context "not included snippet type" do + let(:mail_snippet) { FactoryBot.create(:organization_mail_snippet, organization: organization, name: "fool") } + it "returns nil for not-allowed snippet type" do + expect(organization.mail_snippet_body("fool")).to be nil end end - context 'non-enabled snippet type' do + context "non-enabled snippet type" do let(:mail_snippet) { FactoryBot.create(:organization_mail_snippet, organization: organization, is_enabled: false) } - it 'returns nil for not-enabled snippet' do + it "returns nil for not-enabled snippet" do expect(organization.mail_snippet_body(mail_snippet.name)).to be nil end end - context 'enabled snippet' do - let(:mail_snippet) { FactoryBot.create(:organization_mail_snippet, organization: organization, name: 'security') } - it 'returns nil for not-enabled snippet' do + context "enabled snippet" do + let(:mail_snippet) { FactoryBot.create(:organization_mail_snippet, organization: organization, name: "security") } + it "returns nil for not-enabled snippet" do expect(organization.mail_snippet_body(mail_snippet.name)).to eq mail_snippet.body end end diff --git a/spec/models/other_listing_spec.rb b/spec/models/other_listing_spec.rb index f61b8fe5fb..fbbcbf03d0 100644 --- a/spec/models/other_listing_spec.rb +++ b/spec/models/other_listing_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe OtherListing do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :bike_id } it { is_expected.to validate_presence_of :url } it { is_expected.to belong_to :bike } diff --git a/spec/models/ownership_spec.rb b/spec/models/ownership_spec.rb index 97781dbd87..ed4a0699f4 100644 --- a/spec/models/ownership_spec.rb +++ b/spec/models/ownership_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe Ownership do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to(:bike).touch true } it { is_expected.to belong_to(:user).touch true } it { is_expected.to belong_to :creator } @@ -10,14 +10,14 @@ it { is_expected.to validate_presence_of :owner_email } end - describe 'normalize_email' do - it 'removes leading and trailing whitespace and downcase email' do + describe "normalize_email" do + it "removes leading and trailing whitespace and downcase email" do ownership = Ownership.new - allow(ownership).to receive(:owner_email).and_return(' SomE@dd.com ') - expect(ownership.normalize_email).to eq('some@dd.com') + allow(ownership).to receive(:owner_email).and_return(" SomE@dd.com ") + expect(ownership.normalize_email).to eq("some@dd.com") end - it 'haves before save callback' do + it "haves before save callback" do expect(Ownership._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:normalize_email)).to eq(true) end end @@ -36,8 +36,8 @@ end end - describe 'owner' do - it 'returns the current owner if the ownership is claimed' do + describe "owner" do + it "returns the current owner if the ownership is claimed" do user = FactoryBot.create(:user_confirmed) ownership = Ownership.new allow(ownership).to receive(:claimed).and_return(true) @@ -53,20 +53,20 @@ expect(ownership.owner).to eq(user) end - it 'returns auto user if creator is deleted' do - user = FactoryBot.create(:user_confirmed, email: ENV['AUTO_ORG_MEMBER']) + it "returns auto user if creator is deleted" do + user = FactoryBot.create(:user_confirmed, email: ENV["AUTO_ORG_MEMBER"]) ownership = Ownership.new expect(ownership.owner).to eq(user) end end - describe 'claimable_by?' do + describe "claimable_by?" do let(:user) { FactoryBot.create(:user_confirmed) } - it 'true if user email matches' do + it "true if user email matches" do ownership = Ownership.new(owner_email: " #{user.email.upcase}") expect(ownership.claimable_by?(user)).to be_truthy end - it 'true if user matches' do + it "true if user matches" do ownership = Ownership.new(user_id: user.id) expect(ownership.claimable_by?(user)).to be_truthy end diff --git a/spec/models/paint_spec.rb b/spec/models/paint_spec.rb index 565d35114d..f65dff8144 100644 --- a/spec/models/paint_spec.rb +++ b/spec/models/paint_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe Paint do - it_behaves_like 'friendly_name_findable' - describe 'validations' do + it_behaves_like "friendly_name_findable" + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_uniqueness_of :name } it { is_expected.to belong_to :color } @@ -12,44 +12,44 @@ it { is_expected.to have_many :bikes } end - describe 'lowercase name' do - it 'makes the name lowercase on save' do - pd = Paint.create(name: 'Hazel or Something') - expect(pd.name).to eq('hazel or something') + describe "lowercase name" do + it "makes the name lowercase on save" do + pd = Paint.create(name: "Hazel or Something") + expect(pd.name).to eq("hazel or something") end end - describe 'friendly_find' do + describe "friendly_find" do it "finds color when the case doesn't match" do - paint = FactoryBot.create(:paint, name: 'Poopy PAiNTERS') - expect(Paint.friendly_find('poopy painters')).to eq(paint) + paint = FactoryBot.create(:paint, name: "Poopy PAiNTERS") + expect(Paint.friendly_find("poopy painters")).to eq(paint) end end - describe 'assign_colors' do + describe "assign_colors" do before(:each) do - bi_colors = ['Black', 'Blue', 'Brown', 'Green', 'Orange', 'Pink', 'Purple', 'Red', 'Silver, Gray or Bare Metal', 'Stickers tape or other cover-up', 'Teal', 'White', 'Yellow or Gold'] + bi_colors = ["Black", "Blue", "Brown", "Green", "Orange", "Pink", "Purple", "Red", "Silver, Gray or Bare Metal", "Stickers tape or other cover-up", "Teal", "White", "Yellow or Gold"] bi_colors.each do |col| FactoryBot.create(:color, name: col) end end - it 'associates paint with reasonable colors' do - paint = Paint.new(name: 'burgandy/ivory with black stripes') + it "associates paint with reasonable colors" do + paint = Paint.new(name: "burgandy/ivory with black stripes") paint.associate_colors - expect(paint.color.name.downcase).to eq('red') - expect(paint.secondary_color.name.downcase).to eq('white') - expect(paint.tertiary_color.name.downcase).to eq('black') + expect(paint.color.name.downcase).to eq("red") + expect(paint.secondary_color.name.downcase).to eq("white") + expect(paint.tertiary_color.name.downcase).to eq("black") end - it 'associates only as many colors as it finds' do - paint = Paint.new(name: 'wood with leaf details') + it "associates only as many colors as it finds" do + paint = Paint.new(name: "wood with leaf details") paint.associate_colors - expect(paint.color.name.downcase).to eq('brown') + expect(paint.color.name.downcase).to eq("brown") expect(paint.secondary_color).to be_nil expect(paint.tertiary_color).to be_nil end - it 'has before_create_callback_method' do + it "has before_create_callback_method" do expect(Paint._create_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:associate_colors)).to eq(true) end end diff --git a/spec/models/propulsion_type_spec.rb b/spec/models/propulsion_type_spec.rb index 0c1bd16539..6f44b5593b 100644 --- a/spec/models/propulsion_type_spec.rb +++ b/spec/models/propulsion_type_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe PropulsionType do describe "normalized name" do diff --git a/spec/models/public_image_spec.rb b/spec/models/public_image_spec.rb index 8d05061f15..b210cfcb03 100644 --- a/spec/models/public_image_spec.rb +++ b/spec/models/public_image_spec.rb @@ -1,23 +1,23 @@ -require 'spec_helper' +require "spec_helper" describe PublicImage do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to :imageable } end - describe 'default_name' do - it 'sets a default name from filename if not bike' do + describe "default_name" do + it "sets a default name from filename if not bike" do public_image = PublicImage.new - allow(public_image).to receive(:imageable_type).and_return('Nope') - allow(public_image).to receive(:name).and_return('Boop') + allow(public_image).to receive(:imageable_type).and_return("Nope") + allow(public_image).to receive(:name).and_return("Boop") public_image.default_name - expect(public_image.name).to eq('Boop') + expect(public_image.name).to eq("Boop") end it "returns the name of the manufacturer if it isn't other" do public_image = PublicImage.new - bike = FactoryBot.create(:bike, year: 1969, frame_model: 'Hobo') - allow(public_image).to receive(:imageable_type).and_return('Bike') + bike = FactoryBot.create(:bike, year: 1969, frame_model: "Hobo") + allow(public_image).to receive(:imageable_type).and_return("Bike") allow(public_image).to receive(:imageable).and_return(bike) public_image.default_name expect(public_image.name).to eq("#{bike.title_string} #{bike.frame_colors.to_sentence}") @@ -36,18 +36,18 @@ end end - describe 'enqueue_after_commit_jobs' do - context 'non-bike' do - let(:public_image) { PublicImage.new(imageable_type: 'Blog', imageable_id: 12) } - it 'does not enqueue after_bike_save_worker' do + describe "enqueue_after_commit_jobs" do + context "non-bike" do + let(:public_image) { PublicImage.new(imageable_type: "Blog", imageable_id: 12) } + it "does not enqueue after_bike_save_worker" do expect do public_image.enqueue_after_commit_jobs end.to change(AfterBikeSaveWorker.jobs, :size).by(0) end end - context 'bike' do - let(:public_image) { PublicImage.new(imageable_type: 'Bike', imageable_id: 12) } - it 'enqueues after_bike_save_worker' do + context "bike" do + let(:public_image) { PublicImage.new(imageable_type: "Bike", imageable_id: 12) } + it "enqueues after_bike_save_worker" do expect do expect do public_image.enqueue_after_commit_jobs diff --git a/spec/models/rear_gear_type_spec.rb b/spec/models/rear_gear_type_spec.rb index 473e8b88b5..f8e4ca07b7 100644 --- a/spec/models/rear_gear_type_spec.rb +++ b/spec/models/rear_gear_type_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe RearGearType do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_presence_of :count } it { is_expected.to validate_uniqueness_of :name } diff --git a/spec/models/recovery_display_spec.rb b/spec/models/recovery_display_spec.rb index 7d6f7417de..7bd197f360 100644 --- a/spec/models/recovery_display_spec.rb +++ b/spec/models/recovery_display_spec.rb @@ -1,51 +1,51 @@ -require 'spec_helper' +require "spec_helper" describe RecoveryDisplay do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :quote } it { is_expected.to belong_to :stolen_record } # Before validation sets it, so test fails # it { should validate_presence_of :recovered_at } end - describe 'set_time' do - it 'sets time from input' do - recovery_display = RecoveryDisplay.new(date_input: '04-27-1999') + describe "set_time" do + it "sets time from input" do + recovery_display = RecoveryDisplay.new(date_input: "04-27-1999") recovery_display.set_time - expect(recovery_display.date_recovered).to eq(DateTime.strptime('04-27-1999 06', '%m-%d-%Y %H')) + expect(recovery_display.date_recovered).to eq(DateTime.strptime("04-27-1999 06", "%m-%d-%Y %H")) end - it 'sets time if no time' do + it "sets time if no time" do recovery_display = RecoveryDisplay.new recovery_display.set_time expect(recovery_display.date_recovered).to be > Time.now - 5.seconds end - it 'has before_validation_callback_method defined' do + it "has before_validation_callback_method defined" do expect(RecoveryDisplay._validation_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:set_time)).to eq(true) end end - describe 'from_stolen_record' do + describe "from_stolen_record" do it "doesn't break if stolen record isn't present" do recovery_display = RecoveryDisplay.new recovery_display.from_stolen_record(69) expect(recovery_display.errors).not_to be_present end - it 'sets attrs from stolen record' do + it "sets attrs from stolen record" do t = Time.now - stolen_record = FactoryBot.create(:stolen_record, date_recovered: t, recovered_description: 'stuff', current: false) + stolen_record = FactoryBot.create(:stolen_record, date_recovered: t, recovered_description: "stuff", current: false) recovery_display = RecoveryDisplay.new recovery_display.from_stolen_record(stolen_record.id) - expect(recovery_display.quote).to eq('stuff') + expect(recovery_display.quote).to eq("stuff") expect(recovery_display.date_recovered).to be > Time.now - 5.seconds expect(recovery_display.stolen_record_id).to eq(stolen_record.id) end - it 'sets name from stolen record' do - user = FactoryBot.create(:user, name: 'somebody special') + it "sets name from stolen record" do + user = FactoryBot.create(:user, name: "somebody special") ownership = FactoryBot.create(:ownership, creator: user, user: user) stolen_record = FactoryBot.create(:stolen_record, bike: ownership.bike) recovery_display = RecoveryDisplay.new recovery_display.from_stolen_record(stolen_record.id) - expect(recovery_display.quote_by).to eq('somebody special') + expect(recovery_display.quote_by).to eq("somebody special") end end end diff --git a/spec/models/state_spec.rb b/spec/models/state_spec.rb index d0d718f982..18bec81e31 100644 --- a/spec/models/state_spec.rb +++ b/spec/models/state_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe State do - describe 'validations' do + describe "validations" do it { is_expected.to have_many :locations } it { is_expected.to have_many :stolen_records } it { is_expected.to belong_to :country } @@ -12,10 +12,10 @@ it { is_expected.to validate_uniqueness_of :abbreviation } end - describe 'fuzzy_abbr_find' do + describe "fuzzy_abbr_find" do it "finds users by email address when the case doesn't match" do - state = FactoryBot.create(:state, abbreviation: 'LULZ') - expect(State.fuzzy_abbr_find('lulz ')).to eq(state) + state = FactoryBot.create(:state, abbreviation: "LULZ") + expect(State.fuzzy_abbr_find("lulz ")).to eq(state) end end end diff --git a/spec/models/stolen_notification_spec.rb b/spec/models/stolen_notification_spec.rb index c1e44d383b..b70883cc57 100644 --- a/spec/models/stolen_notification_spec.rb +++ b/spec/models/stolen_notification_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe StolenNotification do describe "create" do diff --git a/spec/models/stolen_record_spec.rb b/spec/models/stolen_record_spec.rb index 960838d6c1..d8976e0c62 100644 --- a/spec/models/stolen_record_spec.rb +++ b/spec/models/stolen_record_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe StolenRecord do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :bike } it { is_expected.to belong_to :bike } it { is_expected.to have_one :recovery_display } @@ -10,20 +10,20 @@ it { is_expected.to belong_to :creation_organization } end - it 'marks current true by default' do + it "marks current true by default" do stolen_record = StolenRecord.new expect(stolen_record.current).to be_truthy end - describe 'find_or_create_recovery_link_token' do + describe "find_or_create_recovery_link_token" do let(:stolen_record) { StolenRecord.new } - it 'returns an existing recovery_link_token' do - stolen_record.recovery_link_token = 'blah' + it "returns an existing recovery_link_token" do + stolen_record.recovery_link_token = "blah" expect(stolen_record).to_not receive(:save) - expect(stolen_record.find_or_create_recovery_link_token).to eq 'blah' + expect(stolen_record.find_or_create_recovery_link_token).to eq "blah" end - it 'creates a recovery_link_token and saves' do + it "creates a recovery_link_token and saves" do stolen_record = StolenRecord.new expect(stolen_record).to receive(:save) result = stolen_record.find_or_create_recovery_link_token @@ -31,31 +31,31 @@ end end - describe 'scopes' do - it 'default scopes to current' do + describe "scopes" do + it "default scopes to current" do expect(StolenRecord.all.to_sql).to eq(StolenRecord.unscoped.where(current: true).to_sql) end - it 'scopes approveds' do + it "scopes approveds" do expect(StolenRecord.approveds.to_sql).to eq(StolenRecord.unscoped.where(current: true).where(approved: true).to_sql) end - it 'scopes approveds_with_reports' do + it "scopes approveds_with_reports" do expect(StolenRecord.approveds_with_reports.to_sql).to eq(StolenRecord.unscoped.where(current: true).where(approved: true) - .where('police_report_number IS NOT NULL').where('police_report_department IS NOT NULL').to_sql) + .where("police_report_number IS NOT NULL").where("police_report_department IS NOT NULL").to_sql) end - it 'scopes not_tsved' do - expect(StolenRecord.not_tsved.to_sql).to eq(StolenRecord.unscoped.where(current: true).where('tsved_at IS NULL').to_sql) + it "scopes not_tsved" do + expect(StolenRecord.not_tsved.to_sql).to eq(StolenRecord.unscoped.where(current: true).where("tsved_at IS NULL").to_sql) end - it 'scopes recovered' do - expect(StolenRecord.recovered.to_sql).to eq(StolenRecord.unscoped.where(current: false).order('date_recovered desc').to_sql) + it "scopes recovered" do + expect(StolenRecord.recovered.to_sql).to eq(StolenRecord.unscoped.where(current: false).order("date_recovered desc").to_sql) end - it 'scopes displayable' do - expect(StolenRecord.displayable.to_sql).to eq(StolenRecord.unscoped.where(current: false, can_share_recovery: true).order('date_recovered desc').to_sql) + it "scopes displayable" do + expect(StolenRecord.displayable.to_sql).to eq(StolenRecord.unscoped.where(current: false, can_share_recovery: true).order("date_recovered desc").to_sql) end - it 'scopes recovery_unposted' do + it "scopes recovery_unposted" do expect(StolenRecord.recovery_unposted.to_sql).to eq(StolenRecord.unscoped.where(current: false, recovery_posted: false).to_sql) end - it 'scopes tsv_today' do + it "scopes tsv_today" do stolen1 = FactoryBot.create(:stolen_record, current: true, tsved_at: Time.now) stolen2 = FactoryBot.create(:stolen_record, current: true, tsved_at: nil) @@ -63,11 +63,11 @@ end end - it 'only allows one current stolen record per bike' + it "only allows one current stolen record per bike" describe "address" do let(:country) { Country.create(name: "Neverland", iso: "NEVVVV") } - let(:state) { State.create(country_id: country.id, name: "BullShit", abbreviation: "XXX")} + let(:state) { State.create(country_id: country.id, name: "BullShit", abbreviation: "XXX") } it "creates an address" do stolen_record = StolenRecord.new(street: "2200 N Milwaukee Ave", city: "Chicago", @@ -93,22 +93,22 @@ end end - describe 'scopes' do - it 'only includes current records' do + describe "scopes" do + it "only includes current records" do expect(StolenRecord.all.to_sql).to eq(StolenRecord.unscoped.where(current: true).to_sql) end - it 'only includes non-current in recovered' do - expect(StolenRecord.recovered.to_sql).to eq(StolenRecord.unscoped.where(current: false).order('date_recovered desc').to_sql) + it "only includes non-current in recovered" do + expect(StolenRecord.recovered.to_sql).to eq(StolenRecord.unscoped.where(current: false).order("date_recovered desc").to_sql) end - it 'only includes sharable unapproved in recovery_waiting_share_approval' do + it "only includes sharable unapproved in recovery_waiting_share_approval" do expect(StolenRecord.recovery_unposted.to_sql).to eq(StolenRecord.unscoped.where(current: false, recovery_posted: false).to_sql) end end - describe 'tsv_row' do - it 'returns the tsv row' do + describe "tsv_row" do + it "returns the tsv row" do stolen_record = FactoryBot.create(:stolen_record) stolen_record.bike.update_attribute :description, "I like tabs because i'm an \\tass\T right\N" row = stolen_record.tsv_row @@ -118,63 +118,63 @@ it "doesn't show the serial for recovered bikes" do stolen_record = FactoryBot.create(:stolen_record) - stolen_record.bike.update_attributes(serial_number: 'SERIAL_SERIAL', recovered: true) + stolen_record.bike.update_attributes(serial_number: "SERIAL_SERIAL", recovered: true) row = stolen_record.tsv_row expect(row).not_to match(/serial_serial/i) end end - describe 'set_phone' do - it 'it should set_phone' do + describe "set_phone" do + it "it should set_phone" do stolen_record = FactoryBot.create(:stolen_record) - stolen_record.phone = '000/000/0000' - stolen_record.secondary_phone = '000/000/0000' + stolen_record.phone = "000/000/0000" + stolen_record.secondary_phone = "000/000/0000" stolen_record.set_phone - expect(stolen_record.phone).to eq('0000000000') - expect(stolen_record.secondary_phone).to eq('0000000000') + expect(stolen_record.phone).to eq("0000000000") + expect(stolen_record.secondary_phone).to eq("0000000000") end - it 'has before_save_callback_method defined as a before_save callback' do + it "has before_save_callback_method defined as a before_save callback" do expect(StolenRecord._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:set_phone)).to eq(true) end end - describe 'phone_display' do # from phoneifyerable - it 'has phone_display' do - stolen_record = StolenRecord.new(phone: '272 222-22222') - expect(stolen_record.phone_display).to eq '272.222.22222' + describe "phone_display" do # from phoneifyerable + it "has phone_display" do + stolen_record = StolenRecord.new(phone: "272 222-22222") + expect(stolen_record.phone_display).to eq "272.222.22222" end end - describe 'titleize_city' do - it 'it should titleize_city' do + describe "titleize_city" do + it "it should titleize_city" do stolen_record = FactoryBot.create(:stolen_record) - stolen_record.city = 'INDIANAPOLIS, IN USA' + stolen_record.city = "INDIANAPOLIS, IN USA" stolen_record.titleize_city - expect(stolen_record.city).to eq('Indianapolis') + expect(stolen_record.city).to eq("Indianapolis") end it "it shouldn't remove other things" do stolen_record = FactoryBot.create(:stolen_record) - stolen_record.city = 'Georgian la' + stolen_record.city = "Georgian la" stolen_record.titleize_city - expect(stolen_record.city).to eq('Georgian La') + expect(stolen_record.city).to eq("Georgian La") end - it 'has before_save_callback_method defined as a before_save callback' do + it "has before_save_callback_method defined as a before_save callback" do expect(StolenRecord._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:titleize_city)).to eq(true) end end - describe 'fix_date' do - it 'it should set the year to something not stupid' do + describe "fix_date" do + it "it should set the year to something not stupid" do stolen_record = StolenRecord.new - stupid_year = Date.strptime('07-22-0014', '%m-%d-%Y') + stupid_year = Date.strptime("07-22-0014", "%m-%d-%Y") stolen_record.date_stolen = stupid_year stolen_record.fix_date expect(stolen_record.date_stolen.year).to eq(2014) end - it 'it should set the year to not last century' do + it "it should set the year to not last century" do stolen_record = StolenRecord.new - wrong_century = Date.strptime('07-22-1913', '%m-%d-%Y') + wrong_century = Date.strptime("07-22-1913", "%m-%d-%Y") stolen_record.date_stolen = wrong_century stolen_record.fix_date expect(stolen_record.date_stolen.year).to eq(2013) @@ -187,46 +187,46 @@ expect(stolen_record.date_stolen.year).to eq(Time.now.year - 1) end - it 'has before_save_callback_method defined as a before_save callback' do + it "has before_save_callback_method defined as a before_save callback" do expect(StolenRecord._save_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:fix_date)).to eq(true) end end - describe 'update_tsved_at' do - it 'does not reset on save' do + describe "update_tsved_at" do + it "does not reset on save" do t = Time.now - 1.minute stolen_record = FactoryBot.create(:stolen_record, tsved_at: t) - stolen_record.update_attributes(theft_description: 'Something new description wise') + stolen_record.update_attributes(theft_description: "Something new description wise") stolen_record.reload expect(stolen_record.tsved_at.to_i).to eq(t.to_i) end - it 'resets from an update to police report' do + it "resets from an update to police report" do t = Time.now - 1.minute stolen_record = FactoryBot.create(:stolen_record, tsved_at: t) - stolen_record.update_attributes(police_report_number: '89dasf89dasf') + stolen_record.update_attributes(police_report_number: "89dasf89dasf") stolen_record.reload expect(stolen_record.tsved_at).to be_nil end - it 'resets from an update to police report department' do + it "resets from an update to police report department" do t = Time.now - 1.minute stolen_record = FactoryBot.create(:stolen_record, tsved_at: t) - stolen_record.update_attributes(police_report_department: 'CPD') + stolen_record.update_attributes(police_report_department: "CPD") stolen_record.reload expect(stolen_record.tsved_at).to be_nil end end - describe 'add_recovery_information' do + describe "add_recovery_information" do let(:bike) { FactoryBot.create(:stolen_bike) } let(:stolen_record) { bike.current_stolen_record } let(:recovery_info) do { - request_type: 'bike_recovery', + request_type: "bike_recovery", user_id: 69, request_bike_id: bike.id, - recovered_description: 'Some reason', - index_helped_recovery: 'true', - can_share_recovery: 'false' + recovered_description: "Some reason", + index_helped_recovery: "true", + can_share_recovery: "false", } end before do @@ -242,9 +242,9 @@ expect(stolen_record.index_helped_recovery).to be_truthy expect(stolen_record.can_share_recovery).to be_falsey end - context 'no date_recovered' do + context "no date_recovered" do let(:recovery_request) { recovery_info.except(:can_share_recovery) } - it 'updates recovered bike' do + it "updates recovered bike" do expect(stolen_record.reload.date_recovered).to be_within(1.second).of Time.now end end diff --git a/spec/models/tweet_spec.rb b/spec/models/tweet_spec.rb index f981bb4262..b2bcb4e564 100644 --- a/spec/models/tweet_spec.rb +++ b/spec/models/tweet_spec.rb @@ -1,58 +1,58 @@ -require 'spec_helper' +require "spec_helper" RSpec.describe Tweet, type: :model do - let(:twitter_response) { File.read(Rails.root.join('spec', 'fixtures', 'integration_data_tweet.json')) } + let(:twitter_response) { File.read(Rails.root.join("spec", "fixtures", "integration_data_tweet.json")) } - describe 'validations' do + describe "validations" do it { should validate_presence_of :twitter_id } end - describe 'friendly_find' do + describe "friendly_find" do let!(:tweet) { FactoryBot.create(:tweet) } let(:twitter_id) { tweet.twitter_id } - context 'twitter_id' do - it 'finds the tweet' do + context "twitter_id" do + it "finds the tweet" do expect(Tweet.friendly_find(twitter_id)).to eq tweet end end - context 'our id' do - it 'finds the tweet' do + context "our id" do + it "finds the tweet" do expect(Tweet.friendly_find(tweet.id)).to eq tweet end end - context 'not found' do - it 'does not error' do + context "not found" do + it "does not error" do expect(Tweet.friendly_find(1111111)).to be_nil end end end - describe 'ensure_valid_alignment' do - it 'adds an error if alignment invalid' do - expect(Tweet.new(twitter_id: 111, alignment: 'weird').valid?).to be_falsey + describe "ensure_valid_alignment" do + it "adds an error if alignment invalid" do + expect(Tweet.new(twitter_id: 111, alignment: "weird").valid?).to be_falsey end end - describe 'auto_link_mentions' do - it 'auto links mentioned folk' do - input = 'Portland Patrol officer Baxter assists in another #biketheft recovery today in Old Town! Great looking out and using @stolenbikereg 👍' + describe "auto_link_mentions" do + it "auto links mentioned folk" do + input = "Portland Patrol officer Baxter assists in another #biketheft recovery today in Old Town! Great looking out and using @stolenbikereg 👍" target = 'Portland Patrol officer Baxter assists in another #biketheft recovery today in Old Town! Great looking out and using @stolenbikereg 👍' expect(Tweet.auto_link_text(input)).to eq target end end - context 'twitter response present' do - let(:tweet) { Tweet.new(twitter_id: '874644243737751553', twitter_response: twitter_response) } - it 'sets the body on create' do + context "twitter response present" do + let(:tweet) { Tweet.new(twitter_id: "874644243737751553", twitter_response: twitter_response) } + it "sets the body on create" do tweet.save expect(tweet.body_html).to eq 'Remember this stolen Novara? The "Wedding gift" bike? It has now been recovered with an assist by @PPBBikeTheft :) https://t.co/hiZZYtCBC1' end - it 'gives us the responses we want' do - expect(tweet.tweetor).to eq 'stolenbikereg' + it "gives us the responses we want" do + expect(tweet.tweetor).to eq "stolenbikereg" expect(tweet.tweeted_at.to_i).to eq 1497366412 - expect(tweet.tweetor_avatar).to eq 'https://pbs.twimg.com/profile_images/505773652646711296/bTYbvFTy_normal.jpeg' - expect(tweet.tweetor_name).to eq 'BikeIndex Portland' + expect(tweet.tweetor_avatar).to eq "https://pbs.twimg.com/profile_images/505773652646711296/bTYbvFTy_normal.jpeg" + expect(tweet.tweetor_name).to eq "BikeIndex Portland" end end end diff --git a/spec/models/user_email_spec.rb b/spec/models/user_email_spec.rb index 0a02ba29ec..3a68d3afa7 100644 --- a/spec/models/user_email_spec.rb +++ b/spec/models/user_email_spec.rb @@ -1,37 +1,37 @@ -require 'spec_helper' +require "spec_helper" describe UserEmail do - describe 'validations' do + describe "validations" do it { is_expected.to belong_to(:user).touch(true) } it { is_expected.to belong_to :old_user } it { is_expected.to validate_presence_of :user_id } it { is_expected.to validate_presence_of :email } end - describe 'scopes' do - it 'confirmed only user_emails without tokens' do - expect(UserEmail.confirmed.to_sql).to eq(UserEmail.where('confirmation_token IS NULL').to_sql) + describe "scopes" do + it "confirmed only user_emails without tokens" do + expect(UserEmail.confirmed.to_sql).to eq(UserEmail.where("confirmation_token IS NULL").to_sql) end - it 'unconfirmed scopes to only unconfirmed UserEmails' do - expect(UserEmail.unconfirmed.to_sql).to eq(UserEmail.where('confirmation_token IS NOT NULL').to_sql) + it "unconfirmed scopes to only unconfirmed UserEmails" do + expect(UserEmail.unconfirmed.to_sql).to eq(UserEmail.where("confirmation_token IS NOT NULL").to_sql) end end - describe 'create_confirmed_primary_email' do - context 'confirmed user' do - let(:user) { User.new(email: 'cool@stuff.com') } - it 'creates a new user_email' do + describe "create_confirmed_primary_email" do + context "confirmed user" do + let(:user) { User.new(email: "cool@stuff.com") } + it "creates a new user_email" do user.confirmed = true user.id = 4444 user_email = UserEmail.create_confirmed_primary_email(user) expect(user_email.confirmed).to be_truthy - expect(user_email.email).to eq 'cool@stuff.com' + expect(user_email.email).to eq "cool@stuff.com" expect(user_email.valid?).to be_truthy end end - context 'already existing' do - let(:user) { FactoryBot.create(:user_confirmed, email: 'cool@stuff.com') } - it 'creates a new user_email' do + context "already existing" do + let(:user) { FactoryBot.create(:user_confirmed, email: "cool@stuff.com") } + it "creates a new user_email" do expect(user.confirmed).to be_truthy expect(user.user_emails.count).to eq 1 user_email = user.user_emails.first @@ -42,54 +42,54 @@ end end - describe 'fuzzy_user_id_find' do - let(:user) { FactoryBot.create(:user_confirmed, email: 'mommy@stuff.com') } + describe "fuzzy_user_id_find" do + let(:user) { FactoryBot.create(:user_confirmed, email: "mommy@stuff.com") } before do expect(user).to be_present end - context 'blank' do - it 'returns nil' do - expect(UserEmail.fuzzy_user_id_find(' ')).to be_nil + context "blank" do + it "returns nil" do + expect(UserEmail.fuzzy_user_id_find(" ")).to be_nil end end - context 'matching' do - it 'returns the user' do - expect(UserEmail.fuzzy_user_id_find('mommy@stUFF.com ')).to eq user.id + context "matching" do + it "returns the user" do + expect(UserEmail.fuzzy_user_id_find("mommy@stUFF.com ")).to eq user.id end end - context 'non-matching' do - it 'returns nil' do - expect(UserEmail.fuzzy_user_id_find('something@fooooOO.edu')).to be_nil + context "non-matching" do + it "returns nil" do + expect(UserEmail.fuzzy_user_id_find("something@fooooOO.edu")).to be_nil end end end - describe 'fuzzy_user_find' do - let(:user) { FactoryBot.create(:user_confirmed, email: 'mommy@stuff.com') } + describe "fuzzy_user_find" do + let(:user) { FactoryBot.create(:user_confirmed, email: "mommy@stuff.com") } before do expect(user).to be_present end - context 'blank' do - it 'returns nil' do - expect(UserEmail.fuzzy_user_find(' ')).to be_nil + context "blank" do + it "returns nil" do + expect(UserEmail.fuzzy_user_find(" ")).to be_nil end end - context 'matching' do - it 'returns the user' do - expect(UserEmail.fuzzy_user_find('mommy@stUFF.com ')).to eq user + context "matching" do + it "returns the user" do + expect(UserEmail.fuzzy_user_find("mommy@stUFF.com ")).to eq user end end - context 'non-matching' do - it 'returns nil' do - expect(UserEmail.fuzzy_user_find('something@fooooOO.edu')).to be_nil + context "non-matching" do + it "returns nil" do + expect(UserEmail.fuzzy_user_find("something@fooooOO.edu")).to be_nil end end - context 'secondary email' do - let(:secondary_email) { FactoryBot.create(:user_email, user: user, email: '2@dddd') } - it 'returns the user' do + context "secondary email" do + let(:secondary_email) { FactoryBot.create(:user_email, user: user, email: "2@dddd") } + it "returns the user" do expect(secondary_email.user).to eq user expect(secondary_email.confirmed).to be_truthy - expect(UserEmail.fuzzy_user_find('2@dddd')).to eq user + expect(UserEmail.fuzzy_user_find("2@dddd")).to eq user end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index a6336fecc5..d190a0d5a1 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe User do - describe 'validations' do + describe "validations" do it { is_expected.to have_many :user_emails } it { is_expected.to have_many :payments } it { is_expected.to have_many :subscriptions } @@ -23,46 +23,46 @@ # it { is_expected.to validate_uniqueness_of :email } end - describe 'create user_email' do - it 'creates a user_email on create' do + describe "create user_email" do + it "creates a user_email on create" do user = FactoryBot.create(:user_confirmed) expect(user.user_emails.count).to eq 1 expect(user.email).to eq user.user_emails.first.email end end - describe 'validate' do - describe 'create' do + describe "validate" do + describe "create" do before :each do @user = User.new(FactoryBot.attributes_for(:user)) expect(@user.valid?).to be_truthy end - it 'requires password on create' do + it "requires password on create" do @user.password = nil @user.password_confirmation = nil expect(@user.valid?).to be_falsey expect(@user.errors.messages[:password].include?("can't be blank")).to be_truthy end - it 'requires password and confirmation to match' do - @user.password_confirmation = 'wtf' + it "requires password and confirmation to match" do + @user.password_confirmation = "wtf" expect(@user.valid?).to be_falsey expect(@user.errors.messages[:password_confirmation].include?("doesn't match confirmation")).to be_truthy end - it 'requires at least 8 characters for the password' do - @user.password = 'hi' - @user.password_confirmation = 'hi' + it "requires at least 8 characters for the password" do + @user.password = "hi" + @user.password_confirmation = "hi" expect(@user.valid?).to be_falsey - expect(@user.errors.messages[:password].include?('is too short (minimum is 6 characters)')).to be_truthy + expect(@user.errors.messages[:password].include?("is too short (minimum is 6 characters)")).to be_truthy end - it 'makes sure there is at least one letter' do - @user.password = '1234567890' - @user.password_confirmation = '1234567890' + it "makes sure there is at least one letter" do + @user.password = "1234567890" + @user.password_confirmation = "1234567890" expect(@user.valid?).to be_falsey - expect(@user.errors.messages[:password].include?('must contain at least one letter')).to be_truthy + expect(@user.errors.messages[:password].include?("must contain at least one letter")).to be_truthy end it "doesn't let unconfirmed users have the same password" do @@ -78,58 +78,58 @@ end end - describe 'confirm' do + describe "confirm" do let(:user) { FactoryBot.create(:user) } - it 'requires confirmation' do + it "requires confirmation" do expect(user.confirmed).to be_falsey expect(user.confirmation_token).not_to be_nil end - it 'confirms users' do + it "confirms users" do expect(user.confirmed).to be_falsey expect(user.confirm(user.confirmation_token)).to be_truthy expect(user.confirmed).to be_truthy expect(user.confirmation_token).to be_nil end - it 'fails to confirm users' do - expect(user.confirm('wtfmate')).to be_falsey + it "fails to confirm users" do + expect(user.confirm("wtfmate")).to be_falsey expect(user.confirmed).to be_falsey expect(user.confirmation_token).not_to be_nil end - it 'is bannable' do + it "is bannable" do user.banned = true user.save - expect(user.authenticate('testme21')).to eq(false) + expect(user.authenticate("testme21")).to eq(false) end end - describe 'update' do + describe "update" do before :each do @user = FactoryBot.create(:user) expect(@user.valid?).to be_truthy end - it 'requires password and confirmation to match' do - @user.password_confirmation = 'wtf' + it "requires password and confirmation to match" do + @user.password_confirmation = "wtf" expect(@user.valid?).to be_falsey expect(@user.errors.messages[:password_confirmation].include?("doesn't match confirmation")).to be_truthy end - it 'requires at least 8 characters for the password' do - @user.password = 'hi' - @user.password_confirmation = 'hi' + it "requires at least 8 characters for the password" do + @user.password = "hi" + @user.password_confirmation = "hi" expect(@user.valid?).to be_falsey - expect(@user.errors.messages[:password].include?('is too short (minimum is 6 characters)')).to be_truthy + expect(@user.errors.messages[:password].include?("is too short (minimum is 6 characters)")).to be_truthy end - it 'makes sure there is at least one letter' do - @user.password = '1234567890' - @user.password_confirmation = '1234567890' + it "makes sure there is at least one letter" do + @user.password = "1234567890" + @user.password_confirmation = "1234567890" expect(@user.valid?).to be_falsey - expect(@user.errors.messages[:password].include?('must contain at least one letter')).to be_truthy + expect(@user.errors.messages[:password].include?("must contain at least one letter")).to be_truthy end end end @@ -152,22 +152,22 @@ end end - describe 'fuzzy finds' do + describe "fuzzy finds" do before do expect(user).to be_present end - context 'confirmed user' do - let(:user) { FactoryBot.create(:user_confirmed, email: 'ned@foo.com') } - context 'primary email' do + context "confirmed user" do + let(:user) { FactoryBot.create(:user_confirmed, email: "ned@foo.com") } + context "primary email" do it "finds users by email address when the case doesn't match" do - expect(User.fuzzy_email_find('NeD@fOO.cOM ')).to eq(user) - expect(User.fuzzy_confirmed_or_unconfirmed_email_find('NeD@fOO.cOM ')).to eq user + expect(User.fuzzy_email_find("NeD@fOO.cOM ")).to eq(user) + expect(User.fuzzy_confirmed_or_unconfirmed_email_find("NeD@fOO.cOM ")).to eq user end end - context 'secondary email' do - let(:email) { 'another@foo.com' } + context "secondary email" do + let(:email) { "another@foo.com" } let(:secondary_email) { FactoryBot.create(:user_email, user: user, email: email) } - it 'finds users by secondary email' do + it "finds users by secondary email" do expect(secondary_email.confirmed).to be_truthy expect(secondary_email.user).to eq user expect(user.secondary_emails.include?(email)).to be_truthy @@ -176,75 +176,75 @@ end end end - describe 'fuzzy_unconfirmed_primary_email_find' do - let(:user) { FactoryBot.create(:user, email: 'ned@foo.com') } - it 'finds user' do + describe "fuzzy_unconfirmed_primary_email_find" do + let(:user) { FactoryBot.create(:user, email: "ned@foo.com") } + it "finds user" do expect(user.confirmed).to be_falsey - expect(User.fuzzy_unconfirmed_primary_email_find(' NeD@fOO.com ')).to eq user - expect(User.fuzzy_confirmed_or_unconfirmed_email_find(' NeD@fOO.com ')).to eq user + expect(User.fuzzy_unconfirmed_primary_email_find(" NeD@fOO.com ")).to eq user + expect(User.fuzzy_confirmed_or_unconfirmed_email_find(" NeD@fOO.com ")).to eq user end end end - describe 'admin text search' do + describe "admin text search" do before do expect(user).to be_present end - context 'unconfirmed user partial match' do - let(:user) { FactoryBot.create(:user, email: 'sample-stuff@e.us') } - it 'finds users' do + context "unconfirmed user partial match" do + let(:user) { FactoryBot.create(:user, email: "sample-stuff@e.us") } + it "finds users" do expect(user.confirmed).to be_falsey - expect(User.admin_text_search('sample-stuff ')).to eq([user]) + expect(User.admin_text_search("sample-stuff ")).to eq([user]) end end - context 'secondary email partial match' do + context "secondary email partial match" do let(:user_email) do FactoryBot.create(:user_email, - email: 'urrg@second.org', - user: FactoryBot.create(:user, name: 'FeconDDD')) + email: "urrg@second.org", + user: FactoryBot.create(:user, name: "FeconDDD")) end let(:user) { user_email.user } - it 'finds users, deduping' do - expect(User.admin_text_search('econd')).to eq([user]) + it "finds users, deduping" do + expect(User.admin_text_search("econd")).to eq([user]) end end - context 'partial match for name' do - let(:user) { FactoryBot.create(:user, name: 'XYLoPHONE') } - it 'finds user' do - User.admin_text_search('ylop') - expect(User.admin_text_search('ylop')).to eq([user]) + context "partial match for name" do + let(:user) { FactoryBot.create(:user, name: "XYLoPHONE") } + it "finds user" do + User.admin_text_search("ylop") + expect(User.admin_text_search("ylop")).to eq([user]) end end end - describe 'secondary_emails' do - let(:user) { FactoryBot.create(:user_confirmed, email: 'cool@stuff.com') } + describe "secondary_emails" do + let(:user) { FactoryBot.create(:user_confirmed, email: "cool@stuff.com") } let(:user_email) { FactoryBot.create(:user_email, user: user) } - it 'lists the non-primary emails' do + it "lists the non-primary emails" do expect(user_email).to be_present expect(user.secondary_emails).to eq([user_email.email]) end end - describe 'set_calculated_attributes' do + describe "set_calculated_attributes" do describe "title, urls" do it "adds http:// to twitter and website if the url doesn't have it so that the link goes somewhere" do - user = User.new(show_twitter: true, twitter: 'http://somewhere.com', show_website: true, website: 'somewhere.org') + user = User.new(show_twitter: true, twitter: "http://somewhere.com", show_website: true, website: "somewhere.org") user.set_calculated_attributes - expect(user.website).to eq('http://somewhere.org') + expect(user.website).to eq("http://somewhere.org") end it "does not add http:// to twitter if it's already there" do - user = User.new(show_twitter: true, twitter: 'http://somewhere.com', show_website: true, website: 'somewhere', my_bikes_link_target: 'https://something.com') + user = User.new(show_twitter: true, twitter: "http://somewhere.com", show_website: true, website: "somewhere", my_bikes_link_target: "https://something.com") user.set_calculated_attributes - expect(user.my_bikes_hash["link_target"]).to eq('https://something.com') - expect(user.mb_link_target).to eq('https://something.com') - expect(user.twitter).to eq('http://somewhere.com') + expect(user.my_bikes_hash["link_target"]).to eq("https://something.com") + expect(user.mb_link_target).to eq("https://something.com") + expect(user.twitter).to eq("http://somewhere.com") end end end - describe 'bikes' do - it 'returns nil if the user has no bikes' do + describe "bikes" do + it "returns nil if the user has no bikes" do user = FactoryBot.create(:user) expect(user.bikes).to be_empty end @@ -271,8 +271,8 @@ end end - describe 'generate_username_confirmation_and_auth' do - it 'generates the required tokens' do + describe "generate_username_confirmation_and_auth" do + it "generates the required tokens" do user = FactoryBot.create(:user) expect(user.auth_token).to be_present expect(user.username).to be_present @@ -280,20 +280,20 @@ time = Time.at(user.auth_token.match(/\d*\z/)[0].to_i) expect(time).to be > Time.now - 1.minutes end - it 'haves before create callback' do + it "haves before create callback" do expect(User._create_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:generate_username_confirmation_and_auth)).to eq(true) end end - describe 'access_tokens_for_application' do - it 'returns [] if no application' do + describe "access_tokens_for_application" do + it "returns [] if no application" do user = User.new expect(user.access_tokens_for_application(nil)).to eq([]) end - it 'returns access tokens for the application' do + it "returns access tokens for the application" do user = FactoryBot.create(:user) - application = Doorkeeper::Application.new(name: 'test', redirect_uri: 'https://foo.bar') - application2 = Doorkeeper::Application.new(name: 'other_test', redirect_uri: 'https://foo.bar') + application = Doorkeeper::Application.new(name: "test", redirect_uri: "https://foo.bar") + application2 = Doorkeeper::Application.new(name: "other_test", redirect_uri: "https://foo.bar") application.owner = user application.save application2.owner = user @@ -307,26 +307,26 @@ end end - describe 'reset_token_time' do - it 'gets long time ago if not there' do + describe "reset_token_time" do + it "gets long time ago if not there" do user = User.new - allow(user).to receive(:password_reset_token).and_return('c7c3b99a319ac09e2b00-2015-03-31 19:29:52 -0500') + allow(user).to receive(:password_reset_token).and_return("c7c3b99a319ac09e2b00-2015-03-31 19:29:52 -0500") expect(user.reset_token_time).to eq(Time.at(1364777722)) end - it 'gets the time' do + it "gets the time" do user = User.new user.set_password_reset_token expect(user.reset_token_time).to be > Time.now - 2.seconds end - it 'uses input time' do + it "uses input time" do user = FactoryBot.create(:user) user.set_password_reset_token((Time.now - 61.minutes).to_i) expect(user.reload.reset_token_time).to be < (Time.now - 1.hours) end end - describe 'send_password_reset_email' do - it 'enqueues sending the password reset' do + describe "send_password_reset_email" do + it "enqueues sending the password reset" do user = FactoryBot.create(:user) expect(user.password_reset_token).to be_nil expect do @@ -346,9 +346,9 @@ end end - describe 'friendly_id_find' do - it 'fails with nil' do - result = User.friendly_id_find('some stuff') + describe "friendly_id_find" do + it "fails with nil" do + result = User.friendly_id_find("some stuff") expect(result).to be_nil end end @@ -410,41 +410,41 @@ end end - describe 'normalize_attributes' do + describe "normalize_attributes" do it "doesn't let you overwrite usernames" do - target = 'coolname' + target = "coolname" user1 = FactoryBot.create(:user) user1.update_attribute :username, target expect(user1.reload.username).to eq(target) user2 = FactoryBot.create(:user) user2.username = "#{target}'" expect(user2.save).to be_falsey - expect(user2.errors.full_messages.to_s).to match('Username has already been taken') + expect(user2.errors.full_messages.to_s).to match("Username has already been taken") expect(user2.reload.username).not_to eq(target) expect(user1.reload.username).to eq(target) end - it 'has before validation callback for normalizing' do + it "has before validation callback for normalizing" do expect(User._validation_callbacks.select { |cb| cb.kind.eql?(:before) }.map(&:raw_filter).include?(:normalize_attributes)).to eq(true) end end - describe 'normalize_attributes' do - let(:user) { FactoryBot.build(:user, phone: '773.83ddp+83(887)', email: "SOMethinG@example.com\n") } + describe "normalize_attributes" do + let(:user) { FactoryBot.build(:user, phone: "773.83ddp+83(887)", email: "SOMethinG@example.com\n") } before(:each) { user.normalize_attributes } - it 'strips the non-digit numbers from the phone input' do - expect(user.phone).to eq('7738383887') + it "strips the non-digit numbers from the phone input" do + expect(user.phone).to eq("7738383887") end - it 'normalizes the email' do - expect(user.email).to eq('something@example.com') + it "normalizes the email" do + expect(user.email).to eq("something@example.com") end end - describe 'donations' do + describe "donations" do let(:user) { FactoryBot.create(:user) } - it 'returns the payment amount' do + it "returns the payment amount" do Payment.create(user: user, amount_cents: 200) expect(user.donations).to eq 200 expect(user.donor?).to be_falsey @@ -453,150 +453,150 @@ end end - describe 'subscriptions' do - it 'returns the payment if payment is subscription' do + describe "subscriptions" do + it "returns the payment if payment is subscription" do user = FactoryBot.create(:user) Payment.create(is_recurring: true, user_id: user) expect(user.subscriptions).to eq(user.payments.where(is_recurring: true)) end end - describe 'userlink' do - it 'returns user path if user show' do - user = User.new(show_bikes: true, username: 'coolstuff') + describe "userlink" do + it "returns user path if user show" do + user = User.new(show_bikes: true, username: "coolstuff") # pp user - expect(user.userlink).to eq('/users/coolstuff') + expect(user.userlink).to eq("/users/coolstuff") end - it 'returns twitter if user twitter' do - user = User.new(show_bikes: false, username: 'coolstuff', twitter: 'bikeindex') + it "returns twitter if user twitter" do + user = User.new(show_bikes: false, username: "coolstuff", twitter: "bikeindex") # pp user - expect(user.userlink).to eq('https://twitter.com/bikeindex') + expect(user.userlink).to eq("https://twitter.com/bikeindex") end end - describe 'primary_user_email' do - it 'can not set a unconfirmed email to the primary email' + describe "primary_user_email" do + it "can not set a unconfirmed email to the primary email" end - describe 'additional_emails=' do + describe "additional_emails=" do let(:user) { FactoryBot.create(:user_confirmed) } before do expect(user.user_emails.count).to eq 1 end - context 'blank' do - it 'does nothing' do + context "blank" do + it "does nothing" do expect do - user.additional_emails = ' ' + user.additional_emails = " " user.save end.to change(UserEmail, :count).by 0 expect(UserEmail.where(user_id: user.id).count).to eq 1 end end - context 'a single email' do - it 'adds the email' do + context "a single email" do + it "adds the email" do expect do - user.additional_emails = 'stuffthings@oooooooooh.com' + user.additional_emails = "stuffthings@oooooooooh.com" user.save end.to change(UserEmail, :count).by 1 user.reload expect(user.user_emails.confirmed.count).to eq 1 expect(user.user_emails.unconfirmed.count).to eq 1 - expect(user.user_emails.unconfirmed.first.email).to eq 'stuffthings@oooooooooh.com' + expect(user.user_emails.unconfirmed.first.email).to eq "stuffthings@oooooooooh.com" end end - context 'list with repeats' do - it 'adds the non-duped emails' do - user.additional_emails = 'stuffthings@oooooooooh.com,another_email@cool.com' + context "list with repeats" do + it "adds the non-duped emails" do + user.additional_emails = "stuffthings@oooooooooh.com,another_email@cool.com" user.save user.reload # pp user.user_emails # pp UserEmail.all expect(UserEmail.unconfirmed.where(user_id: user.id).count).to eq 2 - second_confirmed = UserEmail.where(user_id: user.id, email: 'stuffthings@oooooooooh.com').first + second_confirmed = UserEmail.where(user_id: user.id, email: "stuffthings@oooooooooh.com").first second_confirmed.confirm(second_confirmed.confirmation_token) user.reload expect(user.user_emails.confirmed.count).to eq 2 expect(user.user_emails.unconfirmed.count).to eq 1 expect do - user.additional_emails = ' andAnother@cool.com,stuffthings@oooooooooh.com,another_email@cool.com,lols@stuff.com' + user.additional_emails = " andAnother@cool.com,stuffthings@oooooooooh.com,another_email@cool.com,lols@stuff.com" user.save end.to change(UserEmail, :count).by 2 user.reload expect(user.user_emails.confirmed.count).to eq 2 - expect(user.user_emails.where(email: 'andanother@cool.com').count).to eq 1 + expect(user.user_emails.where(email: "andanother@cool.com").count).to eq 1 end end end - describe 'member_of?' do + describe "member_of?" do let(:organization) { FactoryBot.create(:organization) } - context 'admin of organization' do + context "admin of organization" do let(:user) { FactoryBot.create(:organization_admin, organization: organization) } - it 'returns true' do + it "returns true" do expect(user.member_of?(organization)).to be_truthy end end - context 'member of organization' do + context "member of organization" do let(:user) { FactoryBot.create(:organization_member, organization: organization) } - it 'returns true' do + it "returns true" do expect(user.member_of?(organization)).to be_truthy end end - context 'superadmin' do + context "superadmin" do let(:user) { FactoryBot.create(:admin) } - it 'returns true' do + it "returns true" do expect(user.member_of?(organization)).to be_truthy end end - context 'incorrect searching' do + context "incorrect searching" do let(:user) { FactoryBot.create(:organization_admin, organization: organization) } - context 'non-member' do + context "non-member" do let(:other_organization) { FactoryBot.create(:organization) } - it 'returns false' do + it "returns false" do expect(other_organization).to be_present expect(user.member_of?(other_organization)).to be_falsey end end - context 'no organization' do - it 'returns false' do + context "no organization" do + it "returns false" do expect(user.member_of?(nil)).to be_falsey end end end end - describe 'admin_of?' do + describe "admin_of?" do let(:organization) { FactoryBot.create(:organization) } - context 'admin of organization' do + context "admin of organization" do let(:user) { FactoryBot.create(:organization_admin, organization: organization) } - it 'returns true' do + it "returns true" do expect(user.admin_of?(organization)).to be_truthy end end - context 'member of organization' do + context "member of organization" do let(:user) { FactoryBot.create(:organization_member, organization: organization) } - it 'returns true' do + it "returns true" do expect(user.admin_of?(organization)).to be_falsey end end - context 'superadmin' do + context "superadmin" do let(:user) { FactoryBot.create(:admin) } - it 'returns true' do + it "returns true" do expect(user.admin_of?(organization)).to be_truthy end end - context 'incorrect searching' do + context "incorrect searching" do let(:user) { FactoryBot.create(:organization_admin, organization: organization) } - context 'non-member' do + context "non-member" do let(:other_organization) { FactoryBot.create(:organization) } - it 'returns false' do + it "returns false" do expect(other_organization).to be_present expect(user.admin_of?(other_organization)).to be_falsey end end - context 'no organization' do - it 'returns false' do + context "no organization" do + it "returns false" do expect(user.admin_of?(nil)).to be_falsey end end diff --git a/spec/models/wheel_size_spec.rb b/spec/models/wheel_size_spec.rb index 212206a4fc..534324c060 100644 --- a/spec/models/wheel_size_spec.rb +++ b/spec/models/wheel_size_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe WheelSize do - describe 'validations' do + describe "validations" do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_presence_of :priority } it { is_expected.to validate_presence_of :description } @@ -10,25 +10,25 @@ it { is_expected.to validate_uniqueness_of :iso_bsd } end - describe 'popularity' do - it 'returns the popularities word of the wheel size' do + describe "popularity" do + it "returns the popularities word of the wheel size" do wheel_size = WheelSize.new(priority: 1) - expect(wheel_size.popularity).to eq('Standard') + expect(wheel_size.popularity).to eq("Standard") wheel_size.priority = 4 - expect(wheel_size.popularity).to eq('Rare') + expect(wheel_size.popularity).to eq("Rare") end end - describe 'find_id_by_iso_bsd' do - context 'string iso_bsd' do - it 'returns the id' do + describe "find_id_by_iso_bsd" do + context "string iso_bsd" do + it "returns the id" do wheel_size = FactoryBot.create(:wheel_size, iso_bsd: 622) expect(WheelSize.id_for_bsd("\n622 ")).to eq wheel_size.id end end - context 'unknown number' do - it 'returns nil' do - expect(WheelSize.id_for_bsd('6220')).to be_nil + context "unknown number" do + it "returns nil" do + expect(WheelSize.id_for_bsd("6220")).to be_nil end end end diff --git a/spec/noenv_helper.rb b/spec/noenv_helper.rb index 39e075fadc..2ffef0c007 100644 --- a/spec/noenv_helper.rb +++ b/spec/noenv_helper.rb @@ -1,2 +1,2 @@ -require 'simplecov' +require "simplecov" SimpleCov.start diff --git a/spec/requests/api/manufacturers_request_spec.rb b/spec/requests/api/manufacturers_request_spec.rb index 08ef8d8226..b2eba5ffab 100644 --- a/spec/requests/api/manufacturers_request_spec.rb +++ b/spec/requests/api/manufacturers_request_spec.rb @@ -1,60 +1,60 @@ -require 'spec_helper' +require "spec_helper" -describe 'Manufacturers API V3' do - describe 'root' do - it 'responds on index with pagination' do +describe "Manufacturers API V3" do + describe "root" do + it "responds on index with pagination" do FactoryBot.create(:manufacturer) FactoryBot.create(:manufacturer) unless Manufacturer.count == 2 - get '/api/v3/manufacturers?per_page=1' - expect(response.header['Total']).to eq('2') + get "/api/v3/manufacturers?per_page=1" + expect(response.header["Total"]).to eq("2") pagination_link = '; rel="last", ; rel="next"' - expect(response.header['Link']).to eq(pagination_link) - expect(response.code).to eq('200') - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') + expect(response.header["Link"]).to eq(pagination_link) + expect(response.code).to eq("200") + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") end end - describe 'find by id or name' do + describe "find by id or name" do before :all do @manufacturer = FactoryBot.create(:manufacturer) end - it 'returns one with from an id' do + it "returns one with from an id" do get "/api/v3/manufacturers/#{@manufacturer.id}" result = response.body - expect(response.code).to eq('200') - expect(JSON.parse(result)['manufacturer']['id']).to eq(@manufacturer.id) + expect(response.code).to eq("200") + expect(JSON.parse(result)["manufacturer"]["id"]).to eq(@manufacturer.id) end - it 'responds with missing and cors headers' do - get '/api/v3/manufacturers/10000' - expect(response.code).to eq('404') - expect(JSON(response.body)['error'].present?).to be_truthy - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') - expect(response.headers['Content-Type'].match('json')).to be_present + it "responds with missing and cors headers" do + get "/api/v3/manufacturers/10000" + expect(response.code).to eq("404") + expect(JSON(response.body)["error"].present?).to be_truthy + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") + expect(response.headers["Content-Type"].match("json")).to be_present end - it 'returns one from a name' do + it "returns one from a name" do # THIS FAILS when we don't create a manufacturer in this block, # I've got no idea why - manufacturer = FactoryBot.create(:manufacturer, name: 'awesome') - get '/api/v3/manufacturers/awesome' + manufacturer = FactoryBot.create(:manufacturer, name: "awesome") + get "/api/v3/manufacturers/awesome" result = response.body - expect(response.code).to eq('200') - expect(JSON.parse(result)['manufacturer']['id']).to eq(manufacturer.id) + expect(response.code).to eq("200") + expect(JSON.parse(result)["manufacturer"]["id"]).to eq(manufacturer.id) end end - describe 'JUST CRAZY 404' do - it 'responds with missing and cors headers' do - get '/api/v3/manufacturersdddd' + describe "JUST CRAZY 404" do + it "responds with missing and cors headers" do + get "/api/v3/manufacturersdddd" # pp JSON.parse(response.body) - expect(response.code).to eq('404') - expect(JSON(response.body)['error'].present?).to be_truthy - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("404") + expect(JSON(response.body)["error"].present?).to be_truthy + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") + expect(response.headers["Content-Type"].match("json")).to be_present end end -end \ No newline at end of file +end diff --git a/spec/requests/api/v2/bikes_request_spec.rb b/spec/requests/api/v2/bikes_request_spec.rb index 993edede59..4e223059fb 100644 --- a/spec/requests/api/v2/bikes_request_spec.rb +++ b/spec/requests/api/v2/bikes_request_spec.rb @@ -1,43 +1,43 @@ -require 'spec_helper' +require "spec_helper" -describe 'Bikes API V2' do +describe "Bikes API V2" do let(:manufacturer) { FactoryBot.create(:manufacturer) } let(:color) { FactoryBot.create(:color) } include_context :existing_doorkeeper_app - describe 'find by id' do - it 'returns one with from an id' do + describe "find by id" do + it "returns one with from an id" do bike = FactoryBot.create(:bike) get "/api/v2/bikes/#{bike.id}", format: :json result = JSON.parse(response.body) - expect(response.code).to eq('200') - expect(result['bike']['id']).to eq(bike.id) - expect(response.headers['Content-Type'].match('json')).to be_present - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') + expect(response.code).to eq("200") + expect(result["bike"]["id"]).to eq(bike.id) + expect(response.headers["Content-Type"].match("json")).to be_present + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") end - it 'responds with missing' do - get '/api/v2/bikes/10', format: :json + it "responds with missing" do + get "/api/v2/bikes/10", format: :json result = JSON(response.body) - expect(response.code).to eq('404') - expect(result['error'].present?).to be_truthy - expect(response.headers['Content-Type'].match('json')).to be_present - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') + expect(response.code).to eq("404") + expect(result["error"].present?).to be_truthy + expect(response.headers["Content-Type"].match("json")).to be_present + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") end end - describe 'create' do + describe "create" do let(:bike_attrs) do { - serial: '69 non-example', + serial: "69 non-example", manufacturer: manufacturer.name, - rear_tire_narrow: 'true', - rear_wheel_bsd: '559', + rear_tire_narrow: "true", + rear_wheel_bsd: "559", color: color.name, - year: '1969', - owner_email: 'fun_times@examples.com' + year: "1969", + owner_email: "fun_times@examples.com", } end let!(:token) { create_doorkeeper_token(scopes: "read_bikes write_bikes") } @@ -46,55 +46,55 @@ end include_context :geocoder_default_location - it 'responds with 401' do - post '/api/v2/bikes', bike_attrs.to_json - expect(response.code).to eq('401') + it "responds with 401" do + post "/api/v2/bikes", bike_attrs.to_json + expect(response.code).to eq("401") end it "fails if the token doesn't have write_bikes scope" do - token.update_attribute :scopes, 'read_bikes' + token.update_attribute :scopes, "read_bikes" post "/api/v2/bikes?access_token=#{token.token}", bike_attrs.to_json, json_headers - expect(response.code).to eq('403') + expect(response.code).to eq("403") end - it 'creates a non example bike, with components' do + it "creates a non example bike, with components" do manufacturer = FactoryBot.create(:manufacturer) - FactoryBot.create(:ctype, name: 'wheel') - FactoryBot.create(:ctype, name: 'Headset') + FactoryBot.create(:ctype, name: "wheel") + FactoryBot.create(:ctype, name: "Headset") front_gear_type = FactoryBot.create(:front_gear_type) handlebar_type_slug = "bmx" components = [ { manufacturer: manufacturer.name, - year: '1999', - component_type: 'headset', - description: 'yeah yay!', - serial_number: '69', - model_name: 'Richie rich' + year: "1999", + component_type: "headset", + description: "yeah yay!", + serial_number: "69", + model_name: "Richie rich", }, { - manufacturer: 'BLUE TEETH', - front_or_rear: 'Both', - component_type: 'wheel' - } + manufacturer: "BLUE TEETH", + front_or_rear: "Both", + component_type: "wheel", + }, ] bike_attrs.merge!(components: components, - front_gear_type_slug: front_gear_type.slug, - handlebar_type_slug: handlebar_type_slug, - is_for_sale: true, - is_bulk: true, - is_new: true, - is_pos: true) + front_gear_type_slug: front_gear_type.slug, + handlebar_type_slug: handlebar_type_slug, + is_for_sale: true, + is_bulk: true, + is_new: true, + is_pos: true) expect do post "/api/v2/bikes?access_token=#{token.token}", bike_attrs.to_json, json_headers end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(1) - expect(response.code).to eq('201') - result = JSON.parse(response.body)['bike'] - expect(result['serial']).to eq(bike_attrs[:serial]) - expect(result['manufacturer_name']).to eq(bike_attrs[:manufacturer]) - bike = Bike.find(result['id']) + expect(response.code).to eq("201") + result = JSON.parse(response.body)["bike"] + expect(result["serial"]).to eq(bike_attrs[:serial]) + expect(result["manufacturer_name"]).to eq(bike_attrs[:manufacturer]) + bike = Bike.find(result["id"]) expect(bike.example).to be_falsey expect(bike.is_for_sale).to be_truthy expect(bike.components.count).to eq(3) @@ -104,7 +104,7 @@ expect(bike.handlebar_type).to eq(handlebar_type_slug) creation_state = bike.creation_state expect([creation_state.is_pos, creation_state.is_new, creation_state.is_bulk]).to eq([true, true, true]) - expect(creation_state.origin).to eq 'api_v2' + expect(creation_state.origin).to eq "api_v2" expect(creation_state.creator).to eq bike.creator end @@ -114,22 +114,22 @@ bike_attrs.merge(no_notify: true).to_json, json_headers end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(0) - expect(response.code).to eq('201') + expect(response.code).to eq("201") end - it 'creates an example bike' do - FactoryBot.create(:organization, name: 'Example organization') + it "creates an example bike" do + FactoryBot.create(:organization, name: "Example organization") expect do post "/api/v2/bikes?access_token=#{token.token}", bike_attrs.merge(test: true).to_json, json_headers end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(0) - expect(response.code).to eq('201') - result = JSON.parse(response.body)['bike'] - expect(result['serial']).to eq(bike_attrs[:serial]) - expect(result['manufacturer_name']).to eq(bike_attrs[:manufacturer]) - bike = Bike.unscoped.find(result['id']) - expect(bike.creation_state.origin).to eq 'api_v2' + expect(response.code).to eq("201") + result = JSON.parse(response.body)["bike"] + expect(result["serial"]).to eq(bike_attrs[:serial]) + expect(result["manufacturer_name"]).to eq(bike_attrs[:manufacturer]) + bike = Bike.unscoped.find(result["id"]) + expect(bike.creation_state.origin).to eq "api_v2" expect(bike.creation_state.creator).to eq bike.creator expect(bike.example).to be_truthy expect(bike.is_for_sale).to be_falsey @@ -154,9 +154,9 @@ zipcode: "10007", state: "NY", police_report_number: "99999999", - police_report_department: "New York" - # locking_description: "some locking description", - # lock_defeat_description: "broken in some crazy way" + police_report_department: "New York", + # locking_description: "some locking description", + # lock_defeat_description: "broken in some crazy way" } expect do post "/api/v2/bikes?access_token=#{token.token}", @@ -179,11 +179,11 @@ expect(bike.current_stolen_record.phone).to eq("1234567890") end - it 'does not register a stolen bike unless attrs are present' do + it "does not register a stolen bike unless attrs are present" do bike_attrs[:stolen_record] = { - phone: '', + phone: "", theft_description: "This bike was stolen and that's no fair.", - city: 'Chicago' + city: "Chicago", } expect do post "/api/v2/bikes?access_token=#{token.token}", @@ -191,22 +191,22 @@ json_headers end.to change(Ownership, :count).by 0 result = JSON.parse(response.body) - expect(result['error']).to be_present + expect(result["error"]).to be_present end end - describe 'create v2_accessor' do + describe "create v2_accessor" do let(:organization) { FactoryBot.create(:organization) } let(:bike_attrs) do - { - serial: '69 non-example', + { + serial: "69 non-example", manufacturer: manufacturer.name, - rear_tire_narrow: 'true', - rear_wheel_bsd: '559', + rear_tire_narrow: "true", + rear_wheel_bsd: "559", color: color.name, - year: '1969', - owner_email: 'fun_times@examples.com', - organization_slug: organization.slug + year: "1969", + owner_email: "fun_times@examples.com", + organization_slug: organization.slug, } end let!(:tokenized_url) { "/api/v2/bikes?access_token=#{v2_access_token.token}" } @@ -214,18 +214,18 @@ FactoryBot.create(:wheel_size, iso_bsd: 559) end - it 'also sets front wheel bsd' do - FactoryBot.create(:membership, user: user, organization: organization, role: 'admin') + it "also sets front wheel bsd" do + FactoryBot.create(:membership, user: user, organization: organization, role: "admin") organization.save wheel_size_2 = FactoryBot.create(:wheel_size, iso_bsd: 622) additional_attrs = { front_wheel_bsd: 622, - front_tire_narrow: false + front_tire_narrow: false, } post tokenized_url, bike_attrs.merge(additional_attrs).to_json, json_headers - result = JSON.parse(response.body)['bike'] - expect(response.code).to eq('201') - bike = Bike.find(result['id']) + result = JSON.parse(response.body)["bike"] + expect(response.code).to eq("201") + bike = Bike.find(result["id"]) expect(bike.primary_frame_color).to eq color expect(bike.creator).to eq(user) expect(bike.rear_wheel_size.iso_bsd).to eq 559 @@ -234,13 +234,13 @@ expect(bike.front_tire_narrow).to be_falsey end - it 'creates a bike for organization with v2_accessor' do - FactoryBot.create(:membership, user: user, organization: organization, role: 'admin') + it "creates a bike for organization with v2_accessor" do + FactoryBot.create(:membership, user: user, organization: organization, role: "admin") organization.save post tokenized_url, bike_attrs.to_json, json_headers - result = JSON.parse(response.body)['bike'] - expect(response.code).to eq('201') - bike = Bike.find(result['id']) + result = JSON.parse(response.body)["bike"] + expect(response.code).to eq("201") + bike = Bike.find(result["id"]) expect(bike.creation_organization).to eq(organization) expect(bike.creator).to eq(user) expect(bike.secondary_frame_color).to be_nil @@ -248,93 +248,93 @@ expect(bike.front_wheel_size.iso_bsd).to eq 559 expect(bike.rear_tire_narrow).to be_truthy expect(bike.front_tire_narrow).to be_truthy - expect(bike.creation_state.origin).to eq 'api_v2' + expect(bike.creation_state.origin).to eq "api_v2" expect(bike.creation_state.organization).to eq organization expect(bike.creation_state.creator).to eq bike.creator end it "doesn't create a bike without an organization with v2_accessor" do - FactoryBot.create(:membership, user: user, organization: organization, role: 'admin') + FactoryBot.create(:membership, user: user, organization: organization, role: "admin") organization.save bike_attrs.delete(:organization_slug) post tokenized_url, bike_attrs.to_json, json_headers result = JSON.parse(response.body) - expect(response.code).to eq('403') + expect(response.code).to eq("403") result = JSON.parse(response.body) - expect(result['error'].is_a?(String)).to be_truthy + expect(result["error"].is_a?(String)).to be_truthy end it "fails to create a bike if the app owner isn't a member of the organization" do expect(user.has_membership?).to be_falsey post tokenized_url, bike_attrs.to_json, json_headers result = JSON.parse(response.body) - expect(response.code).to eq('403') + expect(response.code).to eq("403") result = JSON.parse(response.body) - expect(result['error'].is_a?(String)).to be_truthy + expect(result["error"].is_a?(String)).to be_truthy end end - describe 'update' do - let(:params) { { year: 1999, serial_number: 'XXX69XXX' } } + describe "update" do + let(:params) { { year: 1999, serial_number: "XXX69XXX" } } let(:url) { "/api/v2/bikes/#{bike.id}?access_token=#{token.token}" } let(:bike) { FactoryBot.create(:ownership, creator_id: user.id).bike } let!(:token) { create_doorkeeper_token(scopes: "read_user write_bikes") } it "doesn't update if user doesn't own the bike" do bike.current_ownership.update_attributes(user_id: FactoryBot.create(:user).id, claimed: true) - expect_any_instance_of(Bike).to receive(:type).and_return('unicorn') + expect_any_instance_of(Bike).to receive(:type).and_return("unicorn") put url, params.to_json, json_headers - expect(response.body.match('do not own that unicorn')).to be_present - expect(response.code).to eq('403') + expect(response.body.match("do not own that unicorn")).to be_present + expect(response.code).to eq("403") end it "doesn't update if not in scope" do - token.update_attribute :scopes, 'public' + token.update_attribute :scopes, "public" put url, params.to_json, json_headers - expect(response.code).to eq('403') + expect(response.code).to eq("403") expect(response.body).to match(/oauth/i) expect(response.body).to match(/permission/i) end it "fails to update bike if required stolen attrs aren't present" do - FactoryBot.create(:country, iso: 'US') + FactoryBot.create(:country, iso: "US") expect(bike.year).to be_nil serial = bike.serial_number params[:stolen_record] = { - phone: '', - city: 'Chicago' + phone: "", + city: "Chicago", } put url, params.to_json, json_headers - expect(response.code).to eq('401') - expect(response.body.match('missing phone')).to be_present + expect(response.code).to eq("401") + expect(response.body.match("missing phone")).to be_present end it "updates a bike, adds a stolen record, doesn't update locked attrs" do - FactoryBot.create(:country, iso: 'US') + FactoryBot.create(:country, iso: "US") expect(bike.year).to be_nil serial = bike.serial_number params[:stolen_record] = { - city: 'Chicago', - phone: '1234567890', - police_report_number: '999999' + city: "Chicago", + phone: "1234567890", + police_report_number: "999999", } - params[:owner_email] = 'foo@new_owner.com' + params[:owner_email] = "foo@new_owner.com" expect do put url, params.to_json, json_headers end.to change(Ownership, :count).by(1) - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(bike.reload.year).to eq(params[:year]) expect(bike.serial_number).to eq(serial) expect(bike.stolen).to be_truthy expect(bike.current_stolen_record.date_stolen.to_i).to be > Time.now.to_i - 10 - expect(bike.current_stolen_record.police_report_number).to eq('999999') + expect(bike.current_stolen_record.police_report_number).to eq("999999") end - it 'updates a bike, adds and removes components' do + it "updates a bike, adds and removes components" do # FactoryBot.create(:manufacturer, name: 'Other') - wheels = FactoryBot.create(:ctype, name: 'wheel') - headsets = FactoryBot.create(:ctype, name: 'Headset') + wheels = FactoryBot.create(:ctype, name: "wheel") + headsets = FactoryBot.create(:ctype, name: "Headset") comp = FactoryBot.create(:component, bike: bike, ctype: headsets) comp2 = FactoryBot.create(:component, bike: bike, ctype: wheels) FactoryBot.create(:component) @@ -344,30 +344,30 @@ components = [ { manufacturer: manufacturer.name, - year: '1999', - component_type: 'headset', - description: 'Second component', - serial_number: '69', - model_name: 'Richie rich' + year: "1999", + component_type: "headset", + description: "Second component", + serial_number: "69", + model_name: "Richie rich", }, { - manufacturer: 'BLUE TEETH', - front_or_rear: 'Rear', - description: 'third component' + manufacturer: "BLUE TEETH", + front_or_rear: "Rear", + description: "third component", }, { id: comp.id, - destroy: true + destroy: true, }, { id: comp2.id, - year: '1999', - description: 'First component' - } + year: "1999", + description: "First component", + }, ] params[:is_for_sale] = true params[:components] = components expect do put url, params.to_json, json_headers end.to change(Ownership, :count).by(0) - expect(response.code).to eq('200') + expect(response.code).to eq("200") bike.reload bike.components.reload expect(bike.is_for_sale).to be_truthy @@ -384,16 +384,16 @@ components = [ { id: comp.id, - year: 1999 + year: 1999, }, { id: not_urs.id, - destroy: true - } + destroy: true, + }, ] params[:components] = components put url, params.to_json, json_headers - expect(response.code).to eq('401') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("401") + expect(response.headers["Content-Type"].match("json")).to be_present # response.headers['Access-Control-Allow-Origin'].should eq('*') # response.headers['Access-Control-Request-Method'].should eq('*') expect(bike.reload.components.reload.count).to eq(1) @@ -401,90 +401,90 @@ expect(not_urs.reload.id).to be_present end - it 'claims a bike and updates if it should' do + it "claims a bike and updates if it should" do expect(bike.year).to be_nil bike.current_ownership.update_attributes(owner_email: user.email, creator_id: FactoryBot.create(:user).id, claimed: false) expect(bike.reload.owner).not_to eq(user) put url, params.to_json, json_headers - expect(response.code).to eq('200') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("200") + expect(response.headers["Content-Type"].match("json")).to be_present expect(bike.reload.current_ownership.claimed).to be_truthy expect(bike.owner).to eq(user) expect(bike.year).to eq(params[:year]) end end - describe 'image' do + describe "image" do let!(:token) { create_doorkeeper_token(scopes: "read_user write_bikes") } it "doesn't post an image to a bike if the bike isn't owned by the user" do bike = FactoryBot.create(:ownership).bike - file = File.open(File.join(Rails.root, 'spec', 'fixtures', 'bike.jpg')) + file = File.open(File.join(Rails.root, "spec", "fixtures", "bike.jpg")) url = "/api/v2/bikes/#{bike.id}/image?access_token=#{token.token}" expect(bike.public_images.count).to eq(0) post url, file: Rack::Test::UploadedFile.new(file) - expect(response.code).to eq('403') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("403") + expect(response.headers["Content-Type"].match("json")).to be_present expect(bike.reload.public_images.count).to eq(0) end - it 'errors on non whitelisted extensions' do + it "errors on non whitelisted extensions" do bike = FactoryBot.create(:ownership, creator_id: user.id).bike - file = File.open(File.join(Rails.root, 'spec', 'spec_helper.rb')) + file = File.open(File.join(Rails.root, "spec", "spec_helper.rb")) url = "/api/v2/bikes/#{bike.id}/image?access_token=#{token.token}" expect(bike.public_images.count).to eq(0) post url, file: Rack::Test::UploadedFile.new(file) expect(response.body.match(/not allowed to upload .?.rb/i)).to be_present - expect(response.code).to eq('401') + expect(response.code).to eq("401") expect(bike.reload.public_images.count).to eq(0) end - it 'posts an image' do + it "posts an image" do bike = FactoryBot.create(:ownership, creator_id: user.id).bike - file = File.open(File.join(Rails.root, 'spec', 'fixtures', 'bike.jpg')) + file = File.open(File.join(Rails.root, "spec", "fixtures", "bike.jpg")) url = "/api/v2/bikes/#{bike.id}/image?access_token=#{token.token}" expect(bike.public_images.count).to eq(0) post url, file: Rack::Test::UploadedFile.new(file) - expect(response.code).to eq('201') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("201") + expect(response.headers["Content-Type"].match("json")).to be_present expect(bike.reload.public_images.count).to eq(1) end end - describe 'send_stolen_notification' do + describe "send_stolen_notification" do let(:bike) { FactoryBot.create(:ownership, creator_id: user.id).bike } let(:params) { { message: "Something I'm sending you" } } let(:url) { "/api/v2/bikes/#{bike.id}/send_stolen_notification?access_token=#{token.token}" } let!(:token) { create_doorkeeper_token(scopes: "read_user") } before { bike.update_attribute :stolen, true } - it 'fails to send a stolen notification without read_user' do - token.update_attribute :scopes, 'public' + it "fails to send a stolen notification without read_user" do + token.update_attribute :scopes, "public" post url, params.to_json, json_headers - expect(response.code).to eq('403') - expect(response.body).to match('OAuth') + expect(response.code).to eq("403") + expect(response.body).to match("OAuth") expect(response.body).to match(/permission/i) - expect(response.body).to_not match('is not stolen') + expect(response.body).to_not match("is not stolen") end it "fails if the bike isn't stolen" do bike.update_attribute :stolen, false post url, params.to_json, json_headers - expect(response.code).to eq('400') - expect(response.body.match('is not stolen')).to be_present + expect(response.code).to eq("400") + expect(response.body.match("is not stolen")).to be_present end it "fails if the bike isn't owned by the access token user" do bike.current_ownership.update_attributes(user_id: FactoryBot.create(:user).id, claimed: true) post url, params.to_json, json_headers - expect(response.code).to eq('403') - expect(response.body.match('application is not approved')).to be_present + expect(response.code).to eq("403") + expect(response.body.match("application is not approved")).to be_present end - it 'sends a notification' do + it "sends a notification" do expect do post url, params.to_json, json_headers end.to change(EmailStolenNotificationWorker.jobs, :size).by(1) - expect(response.code).to eq('201') + expect(response.code).to eq("201") end end end diff --git a/spec/requests/api/v2/bikes_search_request_spec.rb b/spec/requests/api/v2/bikes_search_request_spec.rb index bc486def25..852f0d9530 100644 --- a/spec/requests/api/v2/bikes_search_request_spec.rb +++ b/spec/requests/api/v2/bikes_search_request_spec.rb @@ -1,92 +1,92 @@ -require 'spec_helper' +require "spec_helper" -describe 'Bikes API V2' do - describe 'bike search' do +describe "Bikes API V2" do + describe "bike search" do before :each do @bike = FactoryBot.create(:bike) FactoryBot.create(:bike) FactoryBot.create(:recovered_bike) end - it 'all bikes (root) search works' do - get '/api/v2/bikes_search?per_page=1', format: :json - expect(response.code).to eq('200') - expect(response.header['Total']).to eq('2') - expect(response.header['Link'].match('page=2&per_page=1>; rel=\"next\"')).to be_present + it "all bikes (root) search works" do + get "/api/v2/bikes_search?per_page=1", format: :json + expect(response.code).to eq("200") + expect(response.header["Total"]).to eq("2") + expect(response.header["Link"].match('page=2&per_page=1>; rel=\"next\"')).to be_present result = response.body - expect(JSON.parse(result)['bikes'][0]['id']).to be_present + expect(JSON.parse(result)["bikes"][0]["id"]).to be_present end - it 'non_stolen bikes search works' do - get '/api/v2/bikes_search/non_stolen?per_page=1', format: :json - expect(response.code).to eq('200') - expect(response.header['Total']).to eq('2') - expect(response.header['Link'].match('page=2&per_page=1>; rel=\"next\"')).to be_present + it "non_stolen bikes search works" do + get "/api/v2/bikes_search/non_stolen?per_page=1", format: :json + expect(response.code).to eq("200") + expect(response.header["Total"]).to eq("2") + expect(response.header["Link"].match('page=2&per_page=1>; rel=\"next\"')).to be_present result = response.body - expect(JSON.parse(result)['bikes'][0]['id']).to be_present + expect(JSON.parse(result)["bikes"][0]["id"]).to be_present end - it 'serial search works' do - bike = FactoryBot.create(:bike, serial_number: '0000HEYBB') - get '/api/v2/bikes_search/?serial=0HEYBB', format: :json + it "serial search works" do + bike = FactoryBot.create(:bike, serial_number: "0000HEYBB") + get "/api/v2/bikes_search/?serial=0HEYBB", format: :json result = JSON.parse(response.body) - expect(response.code).to eq('200') - expect(response.header['Total']).to eq('1') - expect(result['bikes'][0]['id']).to eq(bike.id) + expect(response.code).to eq("200") + expect(response.header["Total"]).to eq("1") + expect(result["bikes"][0]["id"]).to eq(bike.id) end - it 'stolen search works' do + it "stolen search works" do FactoryBot.create(:stolen_bike) - get '/api/v2/bikes_search/stolen?per_page=1', format: :json - expect(response.code).to eq('200') - expect(response.header['Total']).to eq('1') + get "/api/v2/bikes_search/stolen?per_page=1", format: :json + expect(response.code).to eq("200") + expect(response.header["Total"]).to eq("1") result = response.body - expect(JSON.parse(result)['bikes'][0]['id']).to be_present + expect(JSON.parse(result)["bikes"][0]["id"]).to be_present end end - describe 'fuzzy serial search' do - it 'finds a close one' do - bike = FactoryBot.create(:bike, serial_number: 'Something1') + describe "fuzzy serial search" do + it "finds a close one" do + bike = FactoryBot.create(:bike, serial_number: "Something1") bike.create_normalized_serial_segments - get '/api/v2/bikes_search/close_serials?serial=s0meth1nglvv', format: :json + get "/api/v2/bikes_search/close_serials?serial=s0meth1nglvv", format: :json result = JSON.parse(response.body) - expect(response.code).to eq('200') - expect(response.header['Total']).to eq('1') - expect(result['bikes'][0]['id']).to eq(bike.id) + expect(response.code).to eq("200") + expect(response.header["Total"]).to eq("1") + expect(result["bikes"][0]["id"]).to eq(bike.id) end end - describe 'count' do + describe "count" do it "returns the count hash for matching bikes, doesn't need access_token" do - FactoryBot.create(:bike, serial_number: 'awesome') + FactoryBot.create(:bike, serial_number: "awesome") FactoryBot.create(:bike) - get '/api/v2/bikes_search/count?query=awesome', format: :json + get "/api/v2/bikes_search/count?query=awesome", format: :json result = JSON.parse(response.body) - expect(result['non_stolen']).to eq(1) - expect(result['stolen']).to eq(0) - expect(result['proximity']).to eq(0) - expect(response.code).to eq('200') + expect(result["non_stolen"]).to eq(1) + expect(result["stolen"]).to eq(0) + expect(result["proximity"]).to eq(0) + expect(response.code).to eq("200") end - it 'proximity square does not overwrite the proximity_radius' do - opts = { proximity_square: 100, proximity_radius: '10' } - target = Hashie::Mash.new(opts.merge(proximity: 'ip')) + it "proximity square does not overwrite the proximity_radius" do + opts = { proximity_square: 100, proximity_radius: "10" } + target = Hashie::Mash.new(opts.merge(proximity: "ip")) expect_any_instance_of(BikeSearcher).to receive(:initialize).with(target) - get '/api/v2/bikes_search/count', opts, format: :json + get "/api/v2/bikes_search/count", opts, format: :json end end - describe 'all_stolen' do - it 'returns the cached file' do + describe "all_stolen" do + it "returns the cached file" do FactoryBot.create(:stolen_bike) t = Time.now.to_i CacheAllStolenWorker.new.perform cached_all_stolen = FileCacheMaintainer.cached_all_stolen - expect(cached_all_stolen['updated_at'].to_i).to be >= t - get '/api/v2/bikes_search/all_stolen', format: :json + expect(cached_all_stolen["updated_at"].to_i).to be >= t + get "/api/v2/bikes_search/all_stolen", format: :json result = JSON.parse(response.body) - expect(response.header['Last-Modified']).to eq Time.at(cached_all_stolen['updated_at'].to_i).httpdate - expect(result).to eq(JSON.parse(File.read(cached_all_stolen['path']))) + expect(response.header["Last-Modified"]).to eq Time.at(cached_all_stolen["updated_at"].to_i).httpdate + expect(result).to eq(JSON.parse(File.read(cached_all_stolen["path"]))) end end end diff --git a/spec/requests/api/v2/manufacturers_request_spec.rb b/spec/requests/api/v2/manufacturers_request_spec.rb index dd0a00d13a..577aee2c2a 100644 --- a/spec/requests/api/v2/manufacturers_request_spec.rb +++ b/spec/requests/api/v2/manufacturers_request_spec.rb @@ -37,7 +37,7 @@ end describe "show" do - let!(:manufacturer) { FactoryBot.create(:manufacturer, name: 'awesome') } + let!(:manufacturer) { FactoryBot.create(:manufacturer, name: "awesome") } it "returns one from a name" do get "/api/v2/manufacturers/awesome" result = response.body diff --git a/spec/requests/api/v2/me_request_spec.rb b/spec/requests/api/v2/me_request_spec.rb index 5b1d9700ba..694142cc49 100644 --- a/spec/requests/api/v2/me_request_spec.rb +++ b/spec/requests/api/v2/me_request_spec.rb @@ -1,19 +1,19 @@ -require 'spec_helper' +require "spec_helper" -describe 'Me API V2' do +describe "Me API V2" do include_context :existing_doorkeeper_app - describe 'unauthorized current' do - it 'Sends correct error code when no user present' do - get '/api/v2/me' + describe "unauthorized current" do + it "Sends correct error code when no user present" do + get "/api/v2/me" expect(response.response_code).to eq(401) - expect(response.body.match('OAuth')).to be_present - expect(response.headers['Content-Type'].match('json')).to be_present - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') + expect(response.body.match("OAuth")).to be_present + expect(response.headers["Content-Type"].match("json")).to be_present + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") end end - describe 'authorized current' do + describe "authorized current" do before { expect(doorkeeper_app).to be_present } it "responds with all available attributes with full scoped token" do @@ -30,58 +30,58 @@ expect(response.response_code).to eq(200) end - it 'responds with all available attributes with full scoped token' do + it "responds with all available attributes with full scoped token" do token.update_attribute :scopes, all_scopes - get '/api/v2/me', format: :json, access_token: token.token + get "/api/v2/me", format: :json, access_token: token.token expect(response.response_code).to eq(200) result = JSON.parse(response.body) - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(result['id']).to eq(user.id.to_s) - expect(result['user'].is_a?(Hash)).to be_truthy - expect(result['bike_ids'].is_a?(Array)).to be_truthy - expect(result['memberships'].is_a?(Array)).to be_truthy + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(result["id"]).to eq(user.id.to_s) + expect(result["user"].is_a?(Hash)).to be_truthy + expect(result["bike_ids"].is_a?(Array)).to be_truthy + expect(result["memberships"].is_a?(Array)).to be_truthy end it "doesn't include bikes if no bikes scoped" do - expect(token.scopes.to_s.match('read_bikes').present?).to be_falsey - get '/api/v2/me', format: :json, access_token: token.token + expect(token.scopes.to_s.match("read_bikes").present?).to be_falsey + get "/api/v2/me", format: :json, access_token: token.token expect(response.response_code).to eq(200) result = JSON.parse(response.body) - expect(result['id']).to eq(user.id.to_s) - expect(result['bike_ids'].present?).to be_falsey + expect(result["id"]).to eq(user.id.to_s) + expect(result["bike_ids"].present?).to be_falsey end it "doesn't include memberships if no memberships scoped" do - expect(token.scopes.to_s.match('read_organization_membership').present?).to be_falsey - get '/api/v2/me', format: :json, access_token: token.token + expect(token.scopes.to_s.match("read_organization_membership").present?).to be_falsey + get "/api/v2/me", format: :json, access_token: token.token expect(response.response_code).to eq(200) result = JSON.parse(response.body) - expect(result['id']).to eq(user.id.to_s) - expect(result['memberships'].present?).to be_falsey + expect(result["id"]).to eq(user.id.to_s) + expect(result["memberships"].present?).to be_falsey end it "doesn't include memberships if no memberships scoped" do - get '/api/v2/me', format: :json, access_token: token.token + get "/api/v2/me", format: :json, access_token: token.token expect(response.response_code).to eq(200) result = JSON.parse(response.body) - expect(result['id']).to eq(user.id.to_s) - expect(result['user'].present?).to be_falsey + expect(result["id"]).to eq(user.id.to_s) + expect(result["user"].present?).to be_falsey end end - describe 'current/bikes' do + describe "current/bikes" do before { expect(doorkeeper_app).to be_present } it "works if it's authorized" do - token.update_attribute :scopes, 'read_bikes' - get '/api/v2/me/bikes', format: :json, access_token: token.token + token.update_attribute :scopes, "read_bikes" + get "/api/v2/me/bikes", format: :json, access_token: token.token # get '/api/v2/me/bikes', {}, 'Authorization' => "Basic #{Base64.encode64("#{token.token}:X")}" result = JSON.parse(response.body) - expect(result['bikes'].is_a?(Array)).to be_truthy + expect(result["bikes"].is_a?(Array)).to be_truthy expect(response.response_code).to eq(200) end it "403s if read_bikes_spec isn't in token" do - get '/api/v2/me/bikes', format: :json, access_token: token.token + get "/api/v2/me/bikes", format: :json, access_token: token.token expect(response.response_code).to eq(403) end end diff --git a/spec/requests/api/v2/selections_request_spec.rb b/spec/requests/api/v2/selections_request_spec.rb index ff61b61574..7a38810977 100644 --- a/spec/requests/api/v2/selections_request_spec.rb +++ b/spec/requests/api/v2/selections_request_spec.rb @@ -1,98 +1,98 @@ -require 'spec_helper' +require "spec_helper" -describe 'Selections API V2' do - describe 'colors' do - it 'responds on index' do +describe "Selections API V2" do + describe "colors" do + it "responds on index" do selection = FactoryBot.create(:color) - get '/api/v2/selections/colors' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['colors'][0] - expect(result['name']).to eq(selection.name) + get "/api/v2/selections/colors" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["colors"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'component_types' do - it 'responds on index with pagination' do + describe "component_types" do + it "responds on index with pagination" do selection = FactoryBot.create(:ctype) - get '/api/v2/selections/component_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['component_types'][0] - expect(result['name']).to eq(selection.name) + get "/api/v2/selections/component_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["component_types"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'cycle_types' do - it 'responds on index with pagination' do + describe "cycle_types" do + it "responds on index with pagination" do selection = CycleType.legacy_selections[0] - get '/api/v2/selections/cycle_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['cycle_types'][0] - expect(result['name']).to eq(selection[:name]) + get "/api/v2/selections/cycle_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["cycle_types"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'frame_materials' do - it 'responds on index with pagination' do - get '/api/v2/selections/frame_materials' + describe "frame_materials" do + it "responds on index with pagination" do + get "/api/v2/selections/frame_materials" selection = FrameMaterial.legacy_selections[0] - expect(response.code).to eq('200') - result = JSON.parse(response.body)['frame_materials'][0] - expect(result['name']).to eq(selection[:name]) + expect(response.code).to eq("200") + result = JSON.parse(response.body)["frame_materials"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'front_gear_types' do - it 'responds on index with pagination' do + describe "front_gear_types" do + it "responds on index with pagination" do selection = FactoryBot.create(:front_gear_type) - get '/api/v2/selections/front_gear_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['front_gear_types'][0] - expect(result['name']).to eq(selection.name) + get "/api/v2/selections/front_gear_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["front_gear_types"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'rear_gear_types' do - it 'responds on index with pagination' do + describe "rear_gear_types" do + it "responds on index with pagination" do selection = FactoryBot.create(:rear_gear_type) - get '/api/v2/selections/rear_gear_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['rear_gear_types'][0] - expect(result['name']).to eq(selection.name) + get "/api/v2/selections/rear_gear_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["rear_gear_types"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'handlebar_types' do - it 'responds on index with pagination' do + describe "handlebar_types" do + it "responds on index with pagination" do selection = HandlebarType.legacy_selections[0] - get '/api/v2/selections/handlebar_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['handlebar_types'][0] - expect(result['name']).to eq(selection[:name]) + get "/api/v2/selections/handlebar_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["handlebar_types"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'propulsion_types' do - it 'responds on index with pagination' do + describe "propulsion_types" do + it "responds on index with pagination" do selection = PropulsionType.legacy_selections[0] - get '/api/v2/selections/propulsion_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['propulsion_types'][0] - expect(result['name']).to eq(selection[:name]) + get "/api/v2/selections/propulsion_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["propulsion_types"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'wheel_size' do - it 'responds on index with pagination' do + describe "wheel_size" do + it "responds on index with pagination" do wheel_size = FactoryBot.create(:wheel_size) FactoryBot.create(:wheel_size) - get '/api/v2/selections/wheel_sizes?per_page=1' - expect(response.header['Total']).to eq('2') + get "/api/v2/selections/wheel_sizes?per_page=1" + expect(response.header["Total"]).to eq("2") pagination_link = '; rel="last", ; rel="next"' - expect(response.header['Link']).to eq(pagination_link) - expect(response.code).to eq('200') - result = JSON.parse(response.body)['wheel_sizes'][0] - expect(result['iso_bsd']).to eq(wheel_size.iso_bsd) - expect(result['popularity']).to eq(wheel_size.popularity) + expect(response.header["Link"]).to eq(pagination_link) + expect(response.code).to eq("200") + result = JSON.parse(response.body)["wheel_sizes"][0] + expect(result["iso_bsd"]).to eq(wheel_size.iso_bsd) + expect(result["popularity"]).to eq(wheel_size.popularity) end end end diff --git a/spec/requests/api/v2/swagger_request_spec.rb b/spec/requests/api/v2/swagger_request_spec.rb index d450e82b2d..cda194c7db 100644 --- a/spec/requests/api/v2/swagger_request_spec.rb +++ b/spec/requests/api/v2/swagger_request_spec.rb @@ -1,20 +1,20 @@ -require 'spec_helper' +require "spec_helper" -describe 'Swagger API V2 docs' do - describe 'all the paths' do - it 'responds with swagger for all the apis' do - get '/api/v2/swagger_doc' +describe "Swagger API V2 docs" do + describe "all the paths" do + it "responds with swagger for all the apis" do + get "/api/v2/swagger_doc" result = JSON(response.body) - expect(response.code).to eq('200') - result['apis'].each do |api| - get "/api/v2/swagger_doc#{api['path']}" - expect(response.code).to eq('200') + expect(response.code).to eq("200") + result["apis"].each do |api| + get "/api/v2/swagger_doc#{api["path"]}" + expect(response.code).to eq("200") end end - it 'redirects to documentation on API call' do - get '/api' - expect(response).to redirect_to('/documentation') + it "redirects to documentation on API call" do + get "/api" + expect(response).to redirect_to("/documentation") end end end diff --git a/spec/requests/api/v2/users_request_spec.rb b/spec/requests/api/v2/users_request_spec.rb index 876b546137..1ff898f31e 100644 --- a/spec/requests/api/v2/users_request_spec.rb +++ b/spec/requests/api/v2/users_request_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require "spec_helper" -describe 'Users API V2' do +describe "Users API V2" do include_context :existing_doorkeeper_app - describe 'unauthorized current' do - it 'Sends correct error code when no user present' do - get '/api/v2/users/current' + describe "unauthorized current" do + it "Sends correct error code when no user present" do + get "/api/v2/users/current" expect(response.response_code).to eq(401) end end - describe 'authorized current' do + describe "authorized current" do let!(:token) { create_doorkeeper_token(scopes: scopes) } let(:scopes) { "public" } @@ -28,44 +28,44 @@ end it "doesn't include bikes if no bikes scoped" do - expect(token.scopes.to_s.match('read_bikes').present?).to be_falsey - get '/api/v2/users/current', format: :json, access_token: token.token + expect(token.scopes.to_s.match("read_bikes").present?).to be_falsey + get "/api/v2/users/current", format: :json, access_token: token.token expect(response.response_code).to eq(200) result = JSON.parse(response.body) - expect(result['id']).to eq(user.id.to_s) - expect(result['bike_ids'].present?).to be_falsey + expect(result["id"]).to eq(user.id.to_s) + expect(result["bike_ids"].present?).to be_falsey end it "doesn't include memberships if no memberships scoped" do - expect(token.scopes.to_s.match('read_organization_membership').present?).to be_falsey - get '/api/v2/users/current', format: :json, access_token: token.token + expect(token.scopes.to_s.match("read_organization_membership").present?).to be_falsey + get "/api/v2/users/current", format: :json, access_token: token.token expect(response.response_code).to eq(200) result = JSON.parse(response.body) - expect(result['id']).to eq(user.id.to_s) - expect(result['memberships'].present?).to be_falsey + expect(result["id"]).to eq(user.id.to_s) + expect(result["memberships"].present?).to be_falsey end it "doesn't include memberships if no memberships scoped" do - get '/api/v2/users/current', format: :json, access_token: token.token + get "/api/v2/users/current", format: :json, access_token: token.token expect(response.response_code).to eq(200) result = JSON.parse(response.body) - expect(result['id']).to eq(user.id.to_s) - expect(result['user'].present?).to be_falsey + expect(result["id"]).to eq(user.id.to_s) + expect(result["user"].present?).to be_falsey end end - describe 'current/bikes' do + describe "current/bikes" do before { expect(doorkeeper_app).to be_present } it "works if it's authorized" do - token.update_attribute :scopes, 'read_bikes' - get '/api/v2/users/current/bikes', format: :json, access_token: token.token + token.update_attribute :scopes, "read_bikes" + get "/api/v2/users/current/bikes", format: :json, access_token: token.token # get '/api/v2/users/current/bikes', {}, 'Authorization' => "Basic #{Base64.encode64("#{token.token}:X")}" result = JSON.parse(response.body) - expect(result['bikes'].is_a?(Array)).to be_truthy + expect(result["bikes"].is_a?(Array)).to be_truthy expect(response.response_code).to eq(200) end it "403s if read_bikes_spec isn't in token" do - get '/api/v2/users/current/bikes', format: :json, access_token: token.token + get "/api/v2/users/current/bikes", format: :json, access_token: token.token expect(response.response_code).to eq(403) end end diff --git a/spec/requests/api/v3/bikes_request_spec.rb b/spec/requests/api/v3/bikes_request_spec.rb index 895806ab45..8a46efdf9a 100644 --- a/spec/requests/api/v3/bikes_request_spec.rb +++ b/spec/requests/api/v3/bikes_request_spec.rb @@ -1,44 +1,44 @@ -require 'spec_helper' +require "spec_helper" -describe 'Bikes API V3' do +describe "Bikes API V3" do let(:manufacturer) { FactoryBot.create(:manufacturer) } let(:color) { FactoryBot.create(:color) } include_context :existing_doorkeeper_app - describe 'find by id' do - it 'returns one with from an id' do + describe "find by id" do + it "returns one with from an id" do bike = FactoryBot.create(:bike) get "/api/v3/bikes/#{bike.id}", format: :json result = JSON.parse(response.body) - expect(response.code).to eq('200') - expect(result['bike']['id']).to eq(bike.id) - expect(response.headers['Content-Type'].match('json')).to be_present - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') + expect(response.code).to eq("200") + expect(result["bike"]["id"]).to eq(bike.id) + expect(response.headers["Content-Type"].match("json")).to be_present + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") end - it 'responds with missing' do - get '/api/v3/bikes/10', format: :json + it "responds with missing" do + get "/api/v3/bikes/10", format: :json result = JSON(response.body) - expect(response.code).to eq('404') - expect(result['error'].present?).to be_truthy - expect(response.headers['Content-Type'].match('json')).to be_present - expect(response.headers['Access-Control-Allow-Origin']).to eq('*') - expect(response.headers['Access-Control-Request-Method']).to eq('*') + expect(response.code).to eq("404") + expect(result["error"].present?).to be_truthy + expect(response.headers["Content-Type"].match("json")).to be_present + expect(response.headers["Access-Control-Allow-Origin"]).to eq("*") + expect(response.headers["Access-Control-Request-Method"]).to eq("*") end end - describe 'create' do + describe "create" do let(:bike_attrs) do { - serial: '69 non-example', + serial: "69 non-example", manufacturer: manufacturer.name, - rear_tire_narrow: 'true', - rear_wheel_bsd: '559', + rear_tire_narrow: "true", + rear_wheel_bsd: "559", color: color.name, - year: '1969', - owner_email: 'fun_times@examples.com', - frame_material: 'steel' + year: "1969", + owner_email: "fun_times@examples.com", + frame_material: "steel", } end let!(:token) { create_doorkeeper_token(scopes: "read_bikes write_bikes") } @@ -49,9 +49,9 @@ context "no token" do let(:token) { nil } - it 'responds with 401' do - post '/api/v3/bikes', bike_attrs.to_json - expect(response.code).to eq('401') + it "responds with 401" do + post "/api/v3/bikes", bike_attrs.to_json + expect(response.code).to eq("401") end end @@ -76,24 +76,24 @@ it "creates a non example bike, with components and " do manufacturer = FactoryBot.create(:manufacturer) - FactoryBot.create(:ctype, name: 'wheel') - FactoryBot.create(:ctype, name: 'Headset') + FactoryBot.create(:ctype, name: "wheel") + FactoryBot.create(:ctype, name: "Headset") front_gear_type = FactoryBot.create(:front_gear_type) handlebar_type_slug = "bmx" components = [ { manufacturer: manufacturer.name, - year: '1999', - component_type: 'headset', - description: 'yeah yay!', - serial_number: '69', - model_name: 'Richie rich' + year: "1999", + component_type: "headset", + description: "yeah yay!", + serial_number: "69", + model_name: "Richie rich", }, { - manufacturer: 'BLUE TEETH', - front_or_rear: 'Both', - component_type: 'wheel' - } + manufacturer: "BLUE TEETH", + front_or_rear: "Both", + component_type: "wheel", + }, ] bike_attrs.merge!(components: components, front_gear_type_slug: front_gear_type.slug, @@ -109,11 +109,11 @@ bike_attrs.to_json, json_headers end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(1) - expect(response.code).to eq('201') - result = JSON.parse(response.body)['bike'] - expect(result['serial']).to eq(bike_attrs[:serial]) - expect(result['manufacturer_name']).to eq(bike_attrs[:manufacturer]) - bike = Bike.find(result['id']) + expect(response.code).to eq("201") + result = JSON.parse(response.body)["bike"] + expect(result["serial"]).to eq(bike_attrs[:serial]) + expect(result["manufacturer_name"]).to eq(bike_attrs[:manufacturer]) + bike = Bike.find(result["id"]) expect(bike.example).to be_falsey expect(bike.is_for_sale).to be_truthy expect(bike.frame_material).to eq(bike_attrs[:frame_material]) @@ -128,7 +128,7 @@ # expect(creation_state.origin).to eq 'api_v3' # We return things will alert if they're written directly to the dom - worth noting, since it might be a problem - expect(result['description']).to eq "" + expect(result["description"]).to eq "" expect(bike.description).to eq "" end @@ -138,21 +138,21 @@ bike_attrs.merge(no_notify: true).to_json, json_headers end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(0) - expect(response.code).to eq('201') + expect(response.code).to eq("201") end - it 'creates an example bike' do - FactoryBot.create(:organization, name: 'Example organization') + it "creates an example bike" do + FactoryBot.create(:organization, name: "Example organization") expect do post "/api/v3/bikes?access_token=#{token.token}", bike_attrs.merge(test: true).to_json, json_headers end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(0) - expect(response.code).to eq('201') - result = JSON.parse(response.body)['bike'] - expect(result['serial']).to eq(bike_attrs[:serial]) - expect(result['manufacturer_name']).to eq(bike_attrs[:manufacturer]) - bike = Bike.unscoped.find(result['id']) + expect(response.code).to eq("201") + result = JSON.parse(response.body)["bike"] + expect(result["serial"]).to eq(bike_attrs[:serial]) + expect(result["manufacturer_name"]).to eq(bike_attrs[:manufacturer]) + bike = Bike.unscoped.find(result["id"]) # expect(bike.creation_state.origin).to eq 'api_v3' expect(bike.example).to be_truthy expect(bike.is_for_sale).to be_falsey @@ -178,9 +178,9 @@ show_address: true, state: "NY", police_report_number: "99999999", - police_report_department: "New York" - # locking_description: "some locking description", - # lock_defeat_description: "broken in some crazy way" + police_report_department: "New York", + # locking_description: "some locking description", + # lock_defeat_description: "broken in some crazy way" } expect do post "/api/v3/bikes?access_token=#{token.token}", @@ -202,11 +202,11 @@ expect(bike.current_stolen_record.show_address).to be_truthy end - it 'does not register a stolen bike unless attrs are present' do + it "does not register a stolen bike unless attrs are present" do bike_attrs[:stolen_record] = { - phone: '', + phone: "", theft_description: "This bike was stolen and that's no fair.", - city: 'Chicago' + city: "Chicago", } expect do post "/api/v3/bikes?access_token=#{token.token}", @@ -214,23 +214,23 @@ json_headers end.to change(Ownership, :count).by 0 result = JSON.parse(response.body) - expect(result['error']).to be_present + expect(result["error"]).to be_present end end - describe 'create v3_accessor' do + describe "create v3_accessor" do let(:organization) { FactoryBot.create(:organization) } let(:bike_attrs) do { - serial: '69 non-example', + serial: "69 non-example", manufacturer: manufacturer.name, - rear_tire_narrow: 'true', - rear_wheel_bsd: '559', + rear_tire_narrow: "true", + rear_wheel_bsd: "559", color: color.name, - year: '1969', - owner_email: 'fun_times@examples.com', + year: "1969", + owner_email: "fun_times@examples.com", organization_slug: organization.slug, - cycle_type: 'bike' + cycle_type: "bike", } end let!(:tokenized_url) { "/api/v2/bikes?access_token=#{v2_access_token.token}" } @@ -238,43 +238,43 @@ FactoryBot.create(:wheel_size, iso_bsd: 559) end - context 'with membership' do + context "with membership" do before do - FactoryBot.create(:membership, user: user, organization: organization, role: 'admin') + FactoryBot.create(:membership, user: user, organization: organization, role: "admin") organization.save ActionMailer::Base.deliveries = [] end - context 'duplicated serial' do + context "duplicated serial" do let(:bike) { FactoryBot.create(:bike, serial_number: bike_attrs[:serial], owner_email: email) } let(:ownership) { FactoryBot.create(:ownership, bike: bike, owner_email: email) } - context 'matching email' do + context "matching email" do let(:email) { bike_attrs[:owner_email] } - it 'returns existing bike if no_duplicate set' do + it "returns existing bike if no_duplicate set" do expect(ownership.claimed).to be_falsey expect do post tokenized_url, bike_attrs.merge(no_duplicate: true).to_json, json_headers end.to change(Bike, :count).by 0 - result = JSON.parse(response.body)['bike'] - expect(response.code).to eq('201') - expect(result['id']).to eq bike.id + result = JSON.parse(response.body)["bike"] + expect(response.code).to eq("201") + expect(result["id"]).to eq bike.id EmailOwnershipInvitationWorker.drain expect(ActionMailer::Base.deliveries).to be_empty end end - context 'non-matching email' do - let(:email) { 'another_email@example.com' } - it 'creates a bike for organization with v3_accessor' do + context "non-matching email" do + let(:email) { "another_email@example.com" } + it "creates a bike for organization with v3_accessor" do expect(ownership.claimed).to be_falsey expect do post tokenized_url, bike_attrs.to_json, json_headers end.to change(Bike, :count).by 1 - result = JSON.parse(response.body)['bike'] + result = JSON.parse(response.body)["bike"] - expect(response.code).to eq('201') - bike = Bike.find(result['id']) + expect(response.code).to eq("201") + bike = Bike.find(result["id"]) expect(bike.creation_organization).to eq(organization) expect(bike.creator).to eq(user) expect(bike.secondary_frame_color).to be_nil @@ -294,9 +294,9 @@ post tokenized_url, bike_attrs.except(:organization_slug).to_json, json_headers result = JSON.parse(response.body) - expect(response.code).to eq('403') + expect(response.code).to eq("403") result = JSON.parse(response.body) - expect(result['error'].is_a?(String)).to be_truthy + expect(result["error"].is_a?(String)).to be_truthy EmailOwnershipInvitationWorker.drain expect(ActionMailer::Base.deliveries).to be_empty end @@ -306,73 +306,73 @@ expect(user.has_membership?).to be_falsey post tokenized_url, bike_attrs.to_json, json_headers result = JSON.parse(response.body) - expect(response.code).to eq('403') + expect(response.code).to eq("403") result = JSON.parse(response.body) - expect(result['error'].is_a?(String)).to be_truthy + expect(result["error"].is_a?(String)).to be_truthy end end - describe 'update' do - let(:params) { { year: 1999, serial_number: 'XXX69XXX' } } + describe "update" do + let(:params) { { year: 1999, serial_number: "XXX69XXX" } } let(:url) { "/api/v3/bikes/#{bike.id}?access_token=#{token.token}" } let(:bike) { FactoryBot.create(:ownership, creator_id: user.id).bike } let!(:token) { create_doorkeeper_token(scopes: "read_user read_bikes write_bikes") } it "doesn't update if user doesn't own the bike" do bike.current_ownership.update_attributes(user_id: FactoryBot.create(:user).id, claimed: true) - allow_any_instance_of(Bike).to receive(:type).and_return('unicorn') + allow_any_instance_of(Bike).to receive(:type).and_return("unicorn") put url, params.to_json, json_headers - expect(response.body.match('do not own that unicorn')).to be_present - expect(response.code).to eq('403') + expect(response.body.match("do not own that unicorn")).to be_present + expect(response.code).to eq("403") end it "doesn't update if not in scope" do - token.update_attribute :scopes, 'public' + token.update_attribute :scopes, "public" put url, params.to_json, json_headers - expect(response.code).to eq('403') + expect(response.code).to eq("403") expect(response.body).to match(/oauth/i) expect(response.body).to match(/permission/i) end it "fails to update bike if required stolen attrs aren't present" do - FactoryBot.create(:country, iso: 'US') + FactoryBot.create(:country, iso: "US") expect(bike.year).to be_nil params[:stolen_record] = { - phone: '', - city: 'Chicago' + phone: "", + city: "Chicago", } put url, params.to_json, json_headers - expect(response.code).to eq('401') - expect(response.body.match('missing phone')).to be_present + expect(response.code).to eq("401") + expect(response.body.match("missing phone")).to be_present end it "updates a bike, adds a stolen record, doesn't update locked attrs" do - FactoryBot.create(:country, iso: 'US') + FactoryBot.create(:country, iso: "US") expect(bike.year).to be_nil serial = bike.serial_number params[:stolen_record] = { - city: 'Chicago', - phone: '1234567890', + city: "Chicago", + phone: "1234567890", show_address: true, - police_report_number: '999999' + police_report_number: "999999", } - params[:owner_email] = 'foo@new_owner.com' + params[:owner_email] = "foo@new_owner.com" expect do put url, params.to_json, json_headers end.to change(Ownership, :count).by(1) - expect(response.code).to eq('200') + expect(response.code).to eq("200") expect(bike.reload.year).to eq(params[:year]) expect(bike.serial_number).to eq(serial) expect(bike.stolen).to be_truthy expect(bike.current_stolen_record.date_stolen.to_i).to be > Time.now.to_i - 10 - expect(bike.current_stolen_record.police_report_number).to eq('999999') + expect(bike.current_stolen_record.police_report_number).to eq("999999") expect(bike.current_stolen_record.show_address).to be_truthy end - it 'updates a bike, adds and removes components' do + it "updates a bike, adds and removes components" do # FactoryBot.create(:manufacturer, name: 'Other') - wheels = FactoryBot.create(:ctype, name: 'wheel') - headsets = FactoryBot.create(:ctype, name: 'Headset') + wheels = FactoryBot.create(:ctype, name: "wheel") + headsets = FactoryBot.create(:ctype, name: "Headset") comp = FactoryBot.create(:component, bike: bike, ctype: headsets) comp2 = FactoryBot.create(:component, bike: bike, ctype: wheels) not_urs = FactoryBot.create(:component) @@ -382,30 +382,30 @@ components = [ { manufacturer: manufacturer.name, - year: '1999', - component_type: 'headset', - description: 'Second component', - serial_number: '69', - model_name: 'Richie rich' + year: "1999", + component_type: "headset", + description: "Second component", + serial_number: "69", + model_name: "Richie rich", }, { - manufacturer: 'BLUE TEETH', - front_or_rear: 'Rear', - description: 'third component' + manufacturer: "BLUE TEETH", + front_or_rear: "Rear", + description: "third component", }, { id: comp.id, - destroy: true + destroy: true, }, { id: comp2.id, - year: '1999', - description: 'First component' - } + year: "1999", + description: "First component", + }, ] params[:is_for_sale] = true params[:components] = components expect do put url, params.to_json, json_headers end.to change(Ownership, :count).by(0) - expect(response.code).to eq('200') + expect(response.code).to eq("200") bike.reload bike.components.reload expect(bike.is_for_sale).to be_truthy @@ -422,16 +422,16 @@ components = [ { id: comp.id, - year: 1999 + year: 1999, }, { id: not_urs.id, - destroy: true - } + destroy: true, + }, ] params[:components] = components put url, params.to_json, json_headers - expect(response.code).to eq('401') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("401") + expect(response.headers["Content-Type"].match("json")).to be_present # response.headers['Access-Control-Allow-Origin'].should eq('*') # response.headers['Access-Control-Request-Method'].should eq('*') expect(bike.reload.components.reload.count).to eq(1) @@ -439,13 +439,13 @@ expect(not_urs.reload.id).to be_present end - it 'claims a bike and updates if it should' do + it "claims a bike and updates if it should" do expect(bike.year).to be_nil bike.current_ownership.update_attributes(owner_email: user.email, creator_id: FactoryBot.create(:user).id, claimed: false) expect(bike.reload.owner).not_to eq(user) put url, params.to_json, json_headers - expect(response.code).to eq('200') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("200") + expect(response.headers["Content-Type"].match("json")).to be_present expect(bike.reload.current_ownership.claimed).to be_truthy expect(bike.owner).to eq(user) expect(bike.year).to eq(params[:year]) @@ -480,77 +480,77 @@ end end - describe 'image' do + describe "image" do let!(:token) { create_doorkeeper_token(scopes: "read_user write_bikes") } it "doesn't post an image to a bike if the bike isn't owned by the user" do bike = FactoryBot.create(:ownership).bike - file = File.open(File.join(Rails.root, 'spec', 'fixtures', 'bike.jpg')) + file = File.open(File.join(Rails.root, "spec", "fixtures", "bike.jpg")) url = "/api/v3/bikes/#{bike.id}/image?access_token=#{token.token}" expect(bike.public_images.count).to eq(0) post url, file: Rack::Test::UploadedFile.new(file) - expect(response.code).to eq('403') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("403") + expect(response.headers["Content-Type"].match("json")).to be_present expect(bike.reload.public_images.count).to eq(0) end - it 'errors on non whitelisted extensions' do + it "errors on non whitelisted extensions" do bike = FactoryBot.create(:ownership, creator_id: user.id).bike - file = File.open(File.join(Rails.root, 'spec', 'spec_helper.rb')) + file = File.open(File.join(Rails.root, "spec", "spec_helper.rb")) url = "/api/v3/bikes/#{bike.id}/image?access_token=#{token.token}" expect(bike.public_images.count).to eq(0) post url, file: Rack::Test::UploadedFile.new(file) expect(response.body.match(/not allowed to upload .?.rb/i)).to be_present - expect(response.code).to eq('401') + expect(response.code).to eq("401") expect(bike.reload.public_images.count).to eq(0) end - it 'posts an image' do + it "posts an image" do bike = FactoryBot.create(:ownership, creator_id: user.id).bike - file = File.open(File.join(Rails.root, 'spec', 'fixtures', 'bike.jpg')) + file = File.open(File.join(Rails.root, "spec", "fixtures", "bike.jpg")) url = "/api/v3/bikes/#{bike.id}/image?access_token=#{token.token}" expect(bike.public_images.count).to eq(0) post url, file: Rack::Test::UploadedFile.new(file) - expect(response.code).to eq('201') - expect(response.headers['Content-Type'].match('json')).to be_present + expect(response.code).to eq("201") + expect(response.headers["Content-Type"].match("json")).to be_present expect(bike.reload.public_images.count).to eq(1) end end - describe 'send_stolen_notification' do + describe "send_stolen_notification" do let(:bike) { FactoryBot.create(:ownership, creator_id: user.id).bike } let(:params) { { message: "Something I'm sending you" } } let(:url) { "/api/v3/bikes/#{bike.id}/send_stolen_notification?access_token=#{token.token}" } let!(:token) { create_doorkeeper_token(scopes: "read_user") } before { bike.update_attribute :stolen, true } - it 'fails to send a stolen notification without read_user' do - token.update_attribute :scopes, 'public' + it "fails to send a stolen notification without read_user" do + token.update_attribute :scopes, "public" post url, params.to_json, json_headers - expect(response.code).to eq('403') - expect(response.body).to match('OAuth') + expect(response.code).to eq("403") + expect(response.body).to match("OAuth") expect(response.body).to match(/permission/i) - expect(response.body).to_not match('is not stolen') + expect(response.body).to_not match("is not stolen") end it "fails if the bike isn't stolen" do bike.update_attribute :stolen, false post url, params.to_json, json_headers - expect(response.code).to eq('400') - expect(response.body.match('is not stolen')).to be_present + expect(response.code).to eq("400") + expect(response.body.match("is not stolen")).to be_present end it "fails if the bike isn't owned by the access token user" do bike.current_ownership.update_attributes(user_id: FactoryBot.create(:user).id, claimed: true) post url, params.to_json, json_headers - expect(response.code).to eq('403') - expect(response.body.match('application is not approved')).to be_present + expect(response.code).to eq("403") + expect(response.body.match("application is not approved")).to be_present end - it 'sends a notification' do + it "sends a notification" do expect do post url, params.to_json, json_headers end.to change(EmailStolenNotificationWorker.jobs, :size).by(1) - expect(response.code).to eq('201') + expect(response.code).to eq("201") end end -end \ No newline at end of file +end diff --git a/spec/requests/api/v3/organizations_request_spec.rb b/spec/requests/api/v3/organizations_request_spec.rb index a0811578ab..0d9d72d269 100644 --- a/spec/requests/api/v3/organizations_request_spec.rb +++ b/spec/requests/api/v3/organizations_request_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" -describe 'Organization API V3' do +describe "Organization API V3" do include_context :existing_doorkeeper_app - describe 'create' do + describe "create" do let(:country) { FactoryBot.create(:country, name: "United States") } let(:state) { FactoryBot.create(:state, name: "Oregon", abbreviation: "OR", country: country) } let(:token) { create_doorkeeper_token(scopes: :write_organizations) } @@ -16,7 +16,7 @@ city: "Portland", country: state.country.name, state: state.name, - zipcode: "97215" + zipcode: "97215", } } let(:location_2) { @@ -27,7 +27,7 @@ city: "Portland", state: state.name, country: state.country.name, - zipcode: "97214" + zipcode: "97214", } } let(:organization_attrs) do @@ -35,21 +35,21 @@ name: "Geoff's Bike Shop", kind: "bike_shop", website: "https://bikes.geoffereth.com", - locations: [location_1, location_2] + locations: [location_1, location_2], } end let(:organization_json) { organization_attrs.to_json } context "invalid auth" do describe "without access token" do - it 'errors and returns a 401' do - post '/api/v3/organizations', organization_json + it "errors and returns a 401" do + post "/api/v3/organizations", organization_json expect(response).to_not be_successful expect_status 401 end end - - context 'without write_organizations scope' do + + context "without write_organizations scope" do let(:invalid_token) { create_doorkeeper_token(scopes: :write_bikes) } it "errors and returns a 403" do post "/api/v3/organizations?access_token=#{invalid_token.token}", organization_json, json_headers @@ -60,7 +60,7 @@ context "without access to the write_organizations feature" do it "errors and returns a 401" do - ENV['ALLOWED_WRITE_ORGANIZATIONS'] = 'some-other-uid' + ENV["ALLOWED_WRITE_ORGANIZATIONS"] = "some-other-uid" post url, organization_json, json_headers expect_status 401 expect_json(error: "Unauthorized. Cannot write organiztions") @@ -68,9 +68,9 @@ end end - describe "valid auth" do + describe "valid auth" do before do - ENV['ALLOWED_WRITE_ORGANIZATIONS'] = token.application.uid + ENV["ALLOWED_WRITE_ORGANIZATIONS"] = token.application.uid end it "requires organization params" do @@ -94,19 +94,19 @@ expect_json(error: "website is invalid") end - it "creates a new organization with locations" do + it "creates a new organization with locations" do post url, organization_json, json_headers expect(response).to be_successful expect_status 201 expect_json(organization: { - name: "Geoff's Bike Shop", - website: "https://bikes.geoffereth.com", - kind: "bike_shop", - locations: [ - { address: "1111 SE Belmont Street, Portland, OR, 97215, United States" }.merge(location_1), - { address: "2222 SE Morrison Street, Portland, OR, 97214, United States" }.merge(location_2) - ] - }) + name: "Geoff's Bike Shop", + website: "https://bikes.geoffereth.com", + kind: "bike_shop", + locations: [ + { address: "1111 SE Belmont Street, Portland, OR, 97215, United States" }.merge(location_1), + { address: "2222 SE Morrison Street, Portland, OR, 97214, United States" }.merge(location_2), + ], + }) end context "location" do @@ -115,11 +115,11 @@ expect(response).to be_successful expect_status 201 end - + it "requires a valid state and country name" do location_attrs = location_1.merge( state: "The best state ever", - country: "The best country ever" + country: "The best country ever", ) org_json = organization_attrs.merge(locations: [location_attrs]).to_json post url, org_json, json_headers @@ -129,7 +129,7 @@ end it "requires name, street, city, state, and country" do - org_json = organization_attrs.merge!(locations: [{foo: "bar"}]).to_json + org_json = organization_attrs.merge!(locations: [{ foo: "bar" }]).to_json post url, org_json, json_headers expect(response).to_not be_successful expect_status 400 @@ -146,4 +146,4 @@ end end end -end \ No newline at end of file +end diff --git a/spec/requests/api/v3/search_request_spec.rb b/spec/requests/api/v3/search_request_spec.rb index 272efc9cfa..aba2882dec 100644 --- a/spec/requests/api/v3/search_request_spec.rb +++ b/spec/requests/api/v3/search_request_spec.rb @@ -1,41 +1,41 @@ -require 'spec_helper' +require "spec_helper" -describe 'Search API V3' do +describe "Search API V3" do let(:manufacturer) { FactoryBot.create(:manufacturer) } let(:color) { FactoryBot.create(:color) } - describe '/' do + describe "/" do let!(:bike) { FactoryBot.create(:bike, manufacturer: manufacturer) } let!(:bike_2) { FactoryBot.create(:stolen_bike, manufacturer: manufacturer) } let(:query_params) { { query_items: [manufacturer.search_id] } } - context 'with per_page' do - it 'returns matching bikes, defaults to stolen' do + context "with per_page" do + it "returns matching bikes, defaults to stolen" do expect(Bike.count).to eq 2 - get '/api/v3/search', query_params.merge(per_page: 1), format: :json - expect(response.header['Total']).to eq('1') + get "/api/v3/search", query_params.merge(per_page: 1), format: :json + expect(response.header["Total"]).to eq("1") result = JSON.parse(response.body) - expect(result['bikes'][0]['id']).to eq bike_2.id + expect(result["bikes"][0]["id"]).to eq bike_2.id end end end - describe '/close_serials' do - let!(:bike) { FactoryBot.create(:bike, manufacturer: manufacturer, serial_number: 'something') } - let(:query_params) { { serial: 'somethind', stolenness: 'non' } } + describe "/close_serials" do + let!(:bike) { FactoryBot.create(:bike, manufacturer: manufacturer, serial_number: "something") } + let(:query_params) { { serial: "somethind", stolenness: "non" } } let(:target_interpreted_params) { Bike.searchable_interpreted_params(query_params, ip: nil) } - context 'with per_page' do - it 'returns matching bikes, defaults to stolen' do - get '/api/v3/search/close_serials', query_params, format: :json + context "with per_page" do + it "returns matching bikes, defaults to stolen" do + get "/api/v3/search/close_serials", query_params, format: :json result = JSON.parse(response.body) - expect(result['bikes'][0]['id']).to eq bike.id - expect(response.header['Total']).to eq('1') + expect(result["bikes"][0]["id"]).to eq bike.id + expect(response.header["Total"]).to eq("1") end end end - describe '/count' do - context 'incorrect stolenness value' do - it 'returns an error message' do - get '/api/v3/search/count', stolenness: 'something else', format: :json + describe "/count" do + context "incorrect stolenness value" do + it "returns an error message" do + get "/api/v3/search/count", stolenness: "something else", format: :json result = JSON.parse(response.body) - expect(result['error']).to match(/stolenness/i) + expect(result["error"]).to match(/stolenness/i) expect(response.status).to eq(400) end end @@ -47,7 +47,7 @@ color_ids: [color.id], location: "Chicago, IL", distance: 20, - stolenness: "stolen" + stolenness: "stolen", } end let(:proximity_query_params) { request_query_params.merge(stolenness: "proximity") } @@ -68,21 +68,21 @@ end end end - context 'nil params' do - it 'succeeds' do - get '/api/v3/search/count', { stolenness: '', query_items: [], serial: '' }, format: :json + context "nil params" do + it "succeeds" do + get "/api/v3/search/count", { stolenness: "", query_items: [], serial: "" }, format: :json # JSON.parse(response.body) expect(response.status).to eq(200) end end - context 'with query items' do + context "with query items" do let!(:bike) { FactoryBot.create(:bike, manufacturer: manufacturer) } let!(:bike_2) { FactoryBot.create(:bike) } let(:query_params) { { query_items: [manufacturer.search_id] } } - it 'succeeds' do - get '/api/v3/search/count', query_params, format: :json + it "succeeds" do + get "/api/v3/search/count", query_params, format: :json result = JSON.parse(response.body) - expect(result['non']).to eq 1 + expect(result["non"]).to eq 1 expect(response.status).to eq(200) end end diff --git a/spec/requests/api/v3/selections_request_spec.rb b/spec/requests/api/v3/selections_request_spec.rb index e5c388eb5e..d5d8ea7833 100644 --- a/spec/requests/api/v3/selections_request_spec.rb +++ b/spec/requests/api/v3/selections_request_spec.rb @@ -1,98 +1,98 @@ -require 'spec_helper' +require "spec_helper" -describe 'Selections API V3' do - describe 'colors' do - it 'responds on index' do +describe "Selections API V3" do + describe "colors" do + it "responds on index" do selection = FactoryBot.create(:color) - get '/api/v3/selections/colors' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['colors'][0] - expect(result['name']).to eq(selection.name) + get "/api/v3/selections/colors" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["colors"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'component_types' do - it 'responds on index with pagination' do + describe "component_types" do + it "responds on index with pagination" do selection = FactoryBot.create(:ctype) - get '/api/v3/selections/component_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['component_types'][0] - expect(result['name']).to eq(selection.name) + get "/api/v3/selections/component_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["component_types"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'cycle_types' do - it 'responds on index with pagination' do + describe "cycle_types" do + it "responds on index with pagination" do selection = CycleType.legacy_selections[0] - get '/api/v3/selections/cycle_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['cycle_types'][0] - expect(result['name']).to eq(selection[:name]) + get "/api/v3/selections/cycle_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["cycle_types"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'frame_materials' do - it 'responds on index with pagination' do - get '/api/v3/selections/frame_materials' + describe "frame_materials" do + it "responds on index with pagination" do + get "/api/v3/selections/frame_materials" selection = FrameMaterial.legacy_selections[0] - expect(response.code).to eq('200') - result = JSON.parse(response.body)['frame_materials'][0] - expect(result['name']).to eq(selection[:name]) + expect(response.code).to eq("200") + result = JSON.parse(response.body)["frame_materials"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'front_gear_types' do - it 'responds on index with pagination' do + describe "front_gear_types" do + it "responds on index with pagination" do selection = FactoryBot.create(:front_gear_type) - get '/api/v3/selections/front_gear_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['front_gear_types'][0] - expect(result['name']).to eq(selection.name) + get "/api/v3/selections/front_gear_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["front_gear_types"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'rear_gear_types' do - it 'responds on index with pagination' do + describe "rear_gear_types" do + it "responds on index with pagination" do selection = FactoryBot.create(:rear_gear_type) - get '/api/v3/selections/rear_gear_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['rear_gear_types'][0] - expect(result['name']).to eq(selection.name) + get "/api/v3/selections/rear_gear_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["rear_gear_types"][0] + expect(result["name"]).to eq(selection.name) end end - describe 'handlebar_types' do - it 'responds on index with pagination' do + describe "handlebar_types" do + it "responds on index with pagination" do selection = HandlebarType.legacy_selections[0] - get '/api/v3/selections/handlebar_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['handlebar_types'][0] - expect(result['name']).to eq(selection[:name]) + get "/api/v3/selections/handlebar_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["handlebar_types"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'propulsion_types' do - it 'responds on index with pagination' do + describe "propulsion_types" do + it "responds on index with pagination" do selection = PropulsionType.legacy_selections[0] - get '/api/v3/selections/propulsion_types' - expect(response.code).to eq('200') - result = JSON.parse(response.body)['propulsion_types'][0] - expect(result['name']).to eq(selection[:name]) + get "/api/v3/selections/propulsion_types" + expect(response.code).to eq("200") + result = JSON.parse(response.body)["propulsion_types"][0] + expect(result["name"]).to eq(selection[:name]) end end - describe 'wheel_size' do - it 'responds on index with pagination' do + describe "wheel_size" do + it "responds on index with pagination" do wheel_size = FactoryBot.create(:wheel_size) FactoryBot.create(:wheel_size) - get '/api/v3/selections/wheel_sizes?per_page=1' - expect(response.header['Total']).to eq('2') + get "/api/v3/selections/wheel_sizes?per_page=1" + expect(response.header["Total"]).to eq("2") pagination_link = '; rel="last", ; rel="next"' - expect(response.header['Link']).to eq(pagination_link) - expect(response.code).to eq('200') - result = JSON.parse(response.body)['wheel_sizes'][0] - expect(result['iso_bsd']).to eq(wheel_size.iso_bsd) - expect(result['popularity']).to eq(wheel_size.popularity) + expect(response.header["Link"]).to eq(pagination_link) + expect(response.code).to eq("200") + result = JSON.parse(response.body)["wheel_sizes"][0] + expect(result["iso_bsd"]).to eq(wheel_size.iso_bsd) + expect(result["popularity"]).to eq(wheel_size.popularity) end end -end \ No newline at end of file +end diff --git a/spec/requests/api/v3/swagger_request_spec.rb b/spec/requests/api/v3/swagger_request_spec.rb index fed7b15fca..805b39fccc 100644 --- a/spec/requests/api/v3/swagger_request_spec.rb +++ b/spec/requests/api/v3/swagger_request_spec.rb @@ -1,14 +1,14 @@ -require 'spec_helper' +require "spec_helper" -describe 'Swagger API V3 docs' do - describe 'all the paths' do - it 'responds with swagger for all the endpoints' do - get '/api/v3/swagger_doc' +describe "Swagger API V3 docs" do + describe "all the paths" do + it "responds with swagger for all the endpoints" do + get "/api/v3/swagger_doc" result = JSON(response.body) - expect(response.code).to eq('200') - result['apis'].each do |api| - get "/api/v3/swagger_doc#{api['path']}" - expect(response.code).to eq('200') + expect(response.code).to eq("200") + result["apis"].each do |api| + get "/api/v3/swagger_doc#{api["path"]}" + expect(response.code).to eq("200") end end end diff --git a/spec/requests/organized/messages_request_spec.rb b/spec/requests/organized/messages_request_spec.rb index 686f795144..4828dcddc7 100644 --- a/spec/requests/organized/messages_request_spec.rb +++ b/spec/requests/organized/messages_request_spec.rb @@ -20,8 +20,8 @@ get base_url, format: :json expect(response.status).to eq(200) expect(json_result).to eq("messages" => []) - expect(response.headers['Access-Control-Allow-Origin']).not_to be_present - expect(response.headers['Access-Control-Request-Method']).not_to be_present + expect(response.headers["Access-Control-Allow-Origin"]).not_to be_present + expect(response.headers["Access-Control-Request-Method"]).not_to be_present end context "with a message" do let!(:organization_message_1) { FactoryBot.create(:organization_message, organization: organization, kind: "geolocated", created_at: Time.now - 1.hour) } @@ -36,8 +36,8 @@ sender_id: organization_message_1.sender_id, bike: { id: bike.id, - title: bike.title_string - } + title: bike.title_string, + }, } end it "renders json, no cors present" do @@ -46,8 +46,8 @@ messages = json_result["messages"] expect(messages.count).to eq 1 expect(messages.first).to eq target.as_json - expect(response.headers['Access-Control-Allow-Origin']).not_to be_present - expect(response.headers['Access-Control-Request-Method']).not_to be_present + expect(response.headers["Access-Control-Allow-Origin"]).not_to be_present + expect(response.headers["Access-Control-Request-Method"]).not_to be_present end end end diff --git a/spec/routing/bikes_routing_spec.rb b/spec/routing/bikes_routing_spec.rb index 2656662758..0cef9fa423 100644 --- a/spec/routing/bikes_routing_spec.rb +++ b/spec/routing/bikes_routing_spec.rb @@ -7,7 +7,7 @@ expect(get: "bikes/scanned/b2100061").to route_to( controller: "bikes", action: "scanned", - scanned_id: "b2100061" + scanned_id: "b2100061", ) end end @@ -16,7 +16,7 @@ expect(get: "bikes/12/scanned").to route_to( controller: "bikes", action: "scanned", - id: "12" + id: "12", ) end end @@ -25,9 +25,9 @@ expect(get: "bikes/scanned?card_id=xxxxxx").to route_to( controller: "bikes", action: "scanned", - card_id: "xxxxxx" + card_id: "xxxxxx", ) end end end -end \ No newline at end of file +end diff --git a/spec/routing/organizations_rounting_spec.rb b/spec/routing/organizations_rounting_spec.rb index 94745b1873..56b6510c1f 100644 --- a/spec/routing/organizations_rounting_spec.rb +++ b/spec/routing/organizations_rounting_spec.rb @@ -1,80 +1,80 @@ -require 'spec_helper' +require "spec_helper" -describe 'organizations routing' do - describe 'landing_pages' do - it 'routes root to ' do - expect(LandingPages::ORGANIZATIONS).to include('university') - expect(get: '/university').to route_to( - controller: 'landing_pages', - organization_id: 'university', - action: 'show' +describe "organizations routing" do + describe "landing_pages" do + it "routes root to " do + expect(LandingPages::ORGANIZATIONS).to include("university") + expect(get: "/university").to route_to( + controller: "landing_pages", + organization_id: "university", + action: "show", ) end end - context 'organized module' do # At least for now... - describe 'root' do - it 'roots to bikes' do - expect(get: '/o/university').to route_to( - controller: 'organized/bikes', - action: 'index', - organization_id: 'university' + context "organized module" do # At least for now... + describe "root" do + it "roots to bikes" do + expect(get: "/o/university").to route_to( + controller: "organized/bikes", + action: "index", + organization_id: "university", ) end end - describe 'users' do - it 'routes to users' do - expect(get: '/o/university/users/new').to route_to( - controller: 'organized/users', - action: 'new', - organization_id: 'university' + describe "users" do + it "routes to users" do + expect(get: "/o/university/users/new").to route_to( + controller: "organized/users", + action: "new", + organization_id: "university", ) end end - describe 'manage root' do - it 'routes to manage' do - expect(get: '/o/university/manage').to route_to( - controller: 'organized/manage', - action: 'index', - organization_id: 'university' + describe "manage root" do + it "routes to manage" do + expect(get: "/o/university/manage").to route_to( + controller: "organized/manage", + action: "index", + organization_id: "university", ) end end - describe 'manage locations' do - it 'routes to manage' do - expect(get: '/o/university/manage/locations').to route_to( - controller: 'organized/manage', - action: 'locations', - organization_id: 'university' + describe "manage locations" do + it "routes to manage" do + expect(get: "/o/university/manage/locations").to route_to( + controller: "organized/manage", + action: "locations", + organization_id: "university", ) end end end - context 'legacy embed' do - describe 'embed' do - it 'routes to organizations#embed' do - expect(get: '/organizations/bike_store/embed').to route_to( - controller: 'organizations', - action: 'embed', - id: 'bike_store' + context "legacy embed" do + describe "embed" do + it "routes to organizations#embed" do + expect(get: "/organizations/bike_store/embed").to route_to( + controller: "organizations", + action: "embed", + id: "bike_store", ) end end - describe 'embed_extended' do - it 'routes to organizations#embed' do - expect(get: '/organizations/cool_cats/embed_extended').to route_to( - controller: 'organizations', - action: 'embed_extended', - id: 'cool_cats' + describe "embed_extended" do + it "routes to organizations#embed" do + expect(get: "/organizations/cool_cats/embed_extended").to route_to( + controller: "organizations", + action: "embed_extended", + id: "cool_cats", ) end end end - context 'organizations new' do - it 'routes to organizations new' do - expect(get: '/organizations/new').to route_to( - controller: 'organizations', - action: 'new' + context "organizations new" do + it "routes to organizations new" do + expect(get: "/organizations/new").to route_to( + controller: "organizations", + action: "new", ) end end diff --git a/spec/serializers/bike_serializer_spec.rb b/spec/serializers/bike_serializer_spec.rb index cb9dceee71..b76b043a36 100644 --- a/spec/serializers/bike_serializer_spec.rb +++ b/spec/serializers/bike_serializer_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe BikeSerializer do - describe 'standard validations' do - let(:bike) { FactoryBot.create(:bike, frame_size: '42') } + describe "standard validations" do + let(:bike) { FactoryBot.create(:bike, frame_size: "42") } let(:component) { FactoryBot.create(:component, bike: bike) } - let(:public_image) { FactoryBot.create(:public_image, imageable_type: 'Bike', imageable_id: bike.id) } + let(:public_image) { FactoryBot.create(:public_image, imageable_type: "Bike", imageable_id: bike.id) } subject { BikeSerializer.new(bike) } it { expect(subject.manufacturer_name).to eq(bike.mnfg_name) } @@ -25,7 +25,7 @@ it { expect(subject.front_gear_type).to eq(bike.front_gear_type) } it { expect(subject.rear_gear_type).to eq(bike.rear_gear_type) } it { expect(subject.stolen_record).to eq(bike.current_stolen_record) } - it { expect(subject.frame_size).to eq('42cm') } + it { expect(subject.frame_size).to eq("42cm") } # it { subject.photo.should == bike.reload.public_images.first.image_url(:large) } # it { subject.thumb.should == bike.reload.public_images.first.image_url(:small) } end diff --git a/spec/serializers/bike_v2_show_serializer_spec.rb b/spec/serializers/bike_v2_show_serializer_spec.rb index c26f007059..b9eeacdd06 100644 --- a/spec/serializers/bike_v2_show_serializer_spec.rb +++ b/spec/serializers/bike_v2_show_serializer_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe BikeV2ShowSerializer do - describe 'standard validations' do + describe "standard validations" do let(:bike) { FactoryBot.create(:bike, frame_size: "42", additional_registration: "XXYY") } let(:component) { FactoryBot.create(:component, bike: bike) } let(:public_image) { FactoryBot.create(:public_image, imageable_type: "Bike", imageable_id: bike.id) } @@ -45,7 +45,7 @@ additional_registration: "XXYY", stolen_record: nil, public_images: [], - components: [] + components: [], } end diff --git a/spec/serializers/ctypes_serializer_spec.rb b/spec/serializers/ctypes_serializer_spec.rb index ba822336e2..49fecae1fa 100644 --- a/spec/serializers/ctypes_serializer_spec.rb +++ b/spec/serializers/ctypes_serializer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe CtypeSerializer do let(:ctype) { FactoryBot.create(:ctype, has_multiple: true) } diff --git a/spec/serializers/membership_serializer_spec.rb b/spec/serializers/membership_serializer_spec.rb index df8de34dba..24ab8e1d60 100644 --- a/spec/serializers/membership_serializer_spec.rb +++ b/spec/serializers/membership_serializer_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe MembershipSerializer do let(:organization) { FactoryBot.create(:organization) } let(:user) { FactoryBot.create(:user) } - let(:membership) { FactoryBot.create(:membership, organization_id: organization.id, user_id: user.id, role: 'member') } + let(:membership) { FactoryBot.create(:membership, organization_id: organization.id, user_id: user.id, role: "member") } subject { MembershipSerializer.new(membership) } it { expect(subject.organization_name).to eq(organization.name) } diff --git a/spec/serializers/organized_message_serializer_spec.rb b/spec/serializers/organized_message_serializer_spec.rb index 305a664678..55ac3f7cbf 100644 --- a/spec/serializers/organized_message_serializer_spec.rb +++ b/spec/serializers/organized_message_serializer_spec.rb @@ -8,4 +8,4 @@ it "works" do expect(serializer.as_json.is_a?(Hash)).to be_truthy end -end \ No newline at end of file +end diff --git a/spec/serializers/user_serializer_spec.rb b/spec/serializers/user_serializer_spec.rb index f417b82137..1e3c609fda 100644 --- a/spec/serializers/user_serializer_spec.rb +++ b/spec/serializers/user_serializer_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe UserSerializer do let(:user) { FactoryBot.create(:user) } diff --git a/spec/services/autocomplete_loader_spec.rb b/spec/services/autocomplete_loader_spec.rb index da3e2e72fa..36ac287a9b 100644 --- a/spec/services/autocomplete_loader_spec.rb +++ b/spec/services/autocomplete_loader_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe AutocompleteLoader do - describe 'reload' do - it 'calls all the things' do + describe "reload" do + it "calls all the things" do autocomplete_loader = AutocompleteLoader.new expect(autocomplete_loader).to receive(:clear) expect(autocomplete_loader).to receive(:load_colors) diff --git a/spec/services/bike_creator_associator_spec.rb b/spec/services/bike_creator_associator_spec.rb index a777a602fe..9411d407e0 100644 --- a/spec/services/bike_creator_associator_spec.rb +++ b/spec/services/bike_creator_associator_spec.rb @@ -1,29 +1,29 @@ -require 'spec_helper' +require "spec_helper" describe BikeCreatorAssociator do let(:subject) { BikeCreatorAssociator } let(:instance) { subject.new } - describe 'create_ownership' do - it 'calls create ownership' do + describe "create_ownership" do + it "calls create ownership" do b_param = BParam.new bike = Bike.new allow(b_param).to receive(:params).and_return({ bike: bike }.as_json) - allow(b_param).to receive(:creator).and_return('creator') + allow(b_param).to receive(:creator).and_return("creator") expect_any_instance_of(OwnershipCreator).to receive(:create_ownership).and_return(true) subject.new(b_param).create_ownership(bike) end - it 'calls create ownership with send_email false if b_param has that' do + it "calls create ownership with send_email false if b_param has that" do b_param = BParam.new bike = Bike.new allow(b_param).to receive(:params).and_return({ bike: { send_email: false } }.as_json) - allow(b_param).to receive(:creator).and_return('creator') + allow(b_param).to receive(:creator).and_return("creator") expect_any_instance_of(OwnershipCreator).to receive(:create_ownership).and_return(true) subject.new(b_param).create_ownership(bike) end end - describe 'create_components' do - it 'calls create components' do + describe "create_components" do + it "calls create components" do b_param = BParam.new bike = Bike.new expect_any_instance_of(ComponentCreator).to receive(:create_components_from_params).and_return(true) @@ -31,8 +31,8 @@ end end - describe 'create_normalized_serial_segments' do - it 'calls create components' do + describe "create_normalized_serial_segments" do + it "calls create components" do b_param = BParam.new bike = Bike.new expect_any_instance_of(SerialNormalizer).to receive(:save_segments).and_return(true) @@ -40,8 +40,8 @@ end end - describe 'create_stolen_record' do - it 'calls create stolen record' do + describe "create_stolen_record" do + it "calls create stolen record" do b_param = BParam.new bike = Bike.new allow(bike).to receive(:creation_organization).and_return(true) @@ -50,22 +50,22 @@ end end - describe 'add_other_listings' do - it 'calls create stolen record' do + describe "add_other_listings" do + it "calls create stolen record" do b_param = BParam.new bike = FactoryBot.create(:bike) - urls = ['http://some_blog.com', 'http://some_thing.com'] + urls = ["http://some_blog.com", "http://some_thing.com"] allow(b_param).to receive(:params).and_return({ bike: { other_listing_urls: urls } }.as_json) subject.new(b_param).add_other_listings(bike) expect(bike.other_listings.reload.pluck(:url)).to eq(urls) end end - describe 'attach_photo' do - it 'creates public images for the attached image' do + describe "attach_photo" do + it "creates public images for the attached image" do bike = FactoryBot.create(:bike) b_param = FactoryBot.create(:b_param) - test_photo = Rack::Test::UploadedFile.new(File.open(File.join(Rails.root, 'spec', 'fixtures', 'bike.jpg'))) + test_photo = Rack::Test::UploadedFile.new(File.open(File.join(Rails.root, "spec", "fixtures", "bike.jpg"))) b_param.image = test_photo b_param.save expect(b_param.image).to be_present @@ -97,7 +97,7 @@ end context "user already has a phone" do let(:user) { FactoryBot.create(:user, phone: "0000000000") } - it 'does not set the phone if the user already has a phone' do + it "does not set the phone if the user already has a phone" do instance.assign_user_attributes(bike) user.reload expect(user.phone).to eq("0000000000") @@ -105,8 +105,8 @@ end end - describe 'associate' do - it 'calls the required methods' do + describe "associate" do + it "calls the required methods" do bike = Bike.new creator = subject.new allow(bike).to receive(:stolen).and_return(true) @@ -120,12 +120,12 @@ expect(creator).to receive(:add_other_listings) creator.associate(bike) end - it 'rescues from the error and add the message to the bike' do + it "rescues from the error and add the message to the bike" do expect(StolenRecordUpdator).to be_present # Load the error bike = Bike.new creator = subject.new allow(bike).to receive(:stolen).and_return(true) - allow(bike).to receive(:create_stolen_record).and_raise(StolenRecordError, 'Gobledy gook') + allow(bike).to receive(:create_stolen_record).and_raise(StolenRecordError, "Gobledy gook") creator.associate(bike) expect(bike.errors.messages[:association_error]).not_to be_nil end diff --git a/spec/services/bike_creator_builder_spec.rb b/spec/services/bike_creator_builder_spec.rb index c7fcd42c44..1cfe69f676 100644 --- a/spec/services/bike_creator_builder_spec.rb +++ b/spec/services/bike_creator_builder_spec.rb @@ -1,21 +1,21 @@ -require 'spec_helper' +require "spec_helper" describe BikeCreatorBuilder do - describe 'new_bike' do - it 'returns a new bike object from the params with the b_param_id' do + describe "new_bike" do + it "returns a new bike object from the params with the b_param_id" do bike = Bike.new b_param = BParam.new allow(b_param).to receive(:id).and_return(9) allow(b_param).to receive(:creator_id).and_return(6) - allow(b_param).to receive(:params).and_return({ bike: { serial_number: 'AAAA' } }.as_json) + allow(b_param).to receive(:params).and_return({ bike: { serial_number: "AAAA" } }.as_json) bike = BikeCreatorBuilder.new(b_param).new_bike - expect(bike.serial_number).to eq('AAAA') + expect(bike.serial_number).to eq("AAAA") expect(bike.updator_id).to eq(6) expect(bike.b_param_id).to eq(9) end end - describe 'add_front_wheel_size' do + describe "add_front_wheel_size" do it "sets the front wheel equal to the rear wheel if it's present" do bike = Bike.new b_param = BParam.new @@ -27,8 +27,8 @@ end end - describe 'add_required_attributes' do - it 'calls the methods it needs to call' do + describe "add_required_attributes" do + it "calls the methods it needs to call" do bike = Bike.new b_param = BParam.new creator = BikeCreatorBuilder.new(b_param) @@ -38,8 +38,8 @@ end end - describe 'verified_bike' do - it 'calls bike_creator_verifier the required attributes' do + describe "verified_bike" do + it "calls bike_creator_verifier the required attributes" do b_param = BParam.new bike = Bike.new expect_any_instance_of(BikeCreatorVerifier).to receive(:verify).and_return(bike) @@ -47,8 +47,8 @@ end end - describe 'build_new' do - it 'calls verified bike on new bike and return the bike' do + describe "build_new" do + it "calls verified bike on new bike and return the bike" do bike = Bike.new creator = BikeCreatorBuilder.new expect(creator).to receive(:new_bike).and_return(bike) @@ -58,8 +58,8 @@ end end - describe 'build' do - it 'returns the b_param bike if one exists' do + describe "build" do + it "returns the b_param bike if one exists" do b_param = BParam.new bike = Bike.new allow(b_param).to receive(:bike).and_return(bike) @@ -67,7 +67,7 @@ expect(BikeCreatorBuilder.new(b_param).build).to eq(bike) end - it 'uses build_new and call other things' do + it "uses build_new and call other things" do b_param = BParam.new bike = Bike.new allow(b_param).to receive(:created_bike).and_return(nil) diff --git a/spec/services/bike_creator_organizer_spec.rb b/spec/services/bike_creator_organizer_spec.rb index 624809376c..fde38a9089 100644 --- a/spec/services/bike_creator_organizer_spec.rb +++ b/spec/services/bike_creator_organizer_spec.rb @@ -1,5 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe BikeCreatorOrganizer do - end diff --git a/spec/services/bike_creator_spec.rb b/spec/services/bike_creator_spec.rb index d93100427e..956abc267e 100644 --- a/spec/services/bike_creator_spec.rb +++ b/spec/services/bike_creator_spec.rb @@ -1,54 +1,54 @@ -require 'spec_helper' +require "spec_helper" describe BikeCreator do - describe 'include_bike_book' do + describe "include_bike_book" do it "returns the bike if stuff isn't present" do creator = BikeCreator.new expect(creator.add_bike_book_data).to be_nil end - it 'adds se bike data if it exists' do - manufacturer = FactoryBot.create(:manufacturer, name: 'SE Bikes') + it "adds se bike data if it exists" do + manufacturer = FactoryBot.create(:manufacturer, name: "SE Bikes") color = FactoryBot.create(:color) bike = { - serial_number: 'Some serial', - description: 'Input description', + serial_number: "Some serial", + description: "Input description", manufacturer_id: manufacturer.id, year: 2014, - frame_model: 'Draft', - primary_frame_color_id: color.id + frame_model: "Draft", + primary_frame_color_id: color.id, } b_param = FactoryBot.create(:b_param, params: { bike: bike }) BikeCreator.new(b_param).add_bike_book_data b_param.reload # pp b_param.params - expect(b_param.params['components'].count).to be > 5 - expect(b_param.params['components'].count { |c| c['is_stock'] }).to be > 5 - expect(b_param.params['components'].count { |c| !c['is_stock'] }).to eq(0) - expect(b_param.bike['description']).not_to eq('Input description') - expect(b_param.bike['serial_number']).to eq('Some serial') - expect(b_param.bike['primary_frame_color_id']).to eq(color.id) + expect(b_param.params["components"].count).to be > 5 + expect(b_param.params["components"].count { |c| c["is_stock"] }).to be > 5 + expect(b_param.params["components"].count { |c| !c["is_stock"] }).to eq(0) + expect(b_param.bike["description"]).not_to eq("Input description") + expect(b_param.bike["serial_number"]).to eq("Some serial") + expect(b_param.bike["primary_frame_color_id"]).to eq(color.id) end end - describe 'build_new_bike' do - it 'calls creator_builder' do + describe "build_new_bike" do + it "calls creator_builder" do b_param = BParam.new expect_any_instance_of(BikeCreatorBuilder).to receive(:build_new).and_return(true) BikeCreator.new(b_param).build_new_bike end end - describe 'build_bike' do - it 'calls creator_builder' do + describe "build_bike" do + it "calls creator_builder" do b_param = BParam.new expect_any_instance_of(BikeCreatorBuilder).to receive(:build).and_return(Bike.new) expect(BikeCreator.new(b_param).build_bike).to be_truthy end end - describe 'create_associations' do - it 'calls creator_associator' do + describe "create_associations" do + it "calls creator_associator" do b_param = BParam.new bike = Bike.new allow(b_param).to receive(:bike).and_return(bike) @@ -57,11 +57,11 @@ end end - describe 'clear_bike' do - it 'removes the existing bike and transfer the errors to a new active record object' do + describe "clear_bike" do + it "removes the existing bike and transfer the errors to a new active record object" do b_param = BParam.new bike = FactoryBot.create(:bike) - bike.errors.add(:rando_error, 'LOLZ') + bike.errors.add(:rando_error, "LOLZ") expect_any_instance_of(BikeCreatorBuilder).to receive(:build).and_return(Bike.new) creator = BikeCreator.new(b_param).clear_bike(bike) expect(creator.errors.messages[:rando_error]).not_to be_nil @@ -69,18 +69,18 @@ end end - describe 'validate_record' do - it 'calls remove associations if the bike was created and there are errors' do + describe "validate_record" do + it "calls remove associations if the bike was created and there are errors" do b_param = BParam.new bike = Bike.new allow(b_param).to receive(:bike).and_return(bike) - allow(bike).to receive(:errors).and_return(messages: 'some errors') + allow(bike).to receive(:errors).and_return(messages: "some errors") creator = BikeCreator.new(b_param) expect(creator).to receive(:clear_bike).and_return(bike) creator.validate_record(bike) end - it 'calls delete the already existing bike if one exists' do + it "calls delete the already existing bike if one exists" do # This is to clean up duplicates, people press the 'add bike button' many times when its slow to respond b_param = BParam.new bike = FactoryBot.create(:bike) @@ -90,7 +90,7 @@ expect(Bike.where(id: bike1.id)).to be_empty end - it 'associates the b_param with the bike and clear the bike_errors if the bike is created' do + it "associates the b_param with the bike and clear the bike_errors if the bike is created" do b_param = BParam.new bike = Bike.new allow(b_param).to receive(:id).and_return(42) @@ -100,9 +100,9 @@ expect(b_param).to receive(:update_attributes).with(created_bike_id: 69, bike_errors: nil) BikeCreator.new(b_param).validate_record(bike) end - describe 'no_duplicate' do - let(:existing_bike) { FactoryBot.create(:bike, serial_number: 'some serial number', owner_email: email) } - let(:new_bike) { FactoryBot.create(:bike, serial_number: 'some serial number', owner_email: new_email) } + describe "no_duplicate" do + let(:existing_bike) { FactoryBot.create(:bike, serial_number: "some serial number", owner_email: email) } + let(:new_bike) { FactoryBot.create(:bike, serial_number: "some serial number", owner_email: new_email) } let!(:ownerships) do FactoryBot.create(:ownership, bike: existing_bike, owner_email: email) FactoryBot.create(:ownership, bike: new_bike, owner_email: new_email) @@ -110,17 +110,17 @@ let(:params) do { bike: { - serial_number: 'some serial number', + serial_number: "some serial number", owner_email: new_email, - no_duplicate: true - } + no_duplicate: true, + }, } end let(:b_param) { FactoryBot.create(:b_param, creator: existing_bike.current_ownership.creator, params: params) } - context 'same email' do - let(:email) { 'something@gmail.com' } - let(:new_email) { 'Something@GMAIL.com' } - it 'finds a duplicate' do + context "same email" do + let(:email) { "something@gmail.com" } + let(:new_email) { "Something@GMAIL.com" } + it "finds a duplicate" do expect(b_param.no_duplicate).to be_truthy expect(b_param.find_duplicate_bike(new_bike)).to be_truthy expect do @@ -131,10 +131,10 @@ expect(Bike.where(id: new_bike.id)).to_not be_present end end - context 'different email' do - let(:email) { 'something@gmail.com' } - let(:new_email) { 'newsomething@gmail.com' } - it 'does not find a non-duplicate' do + context "different email" do + let(:email) { "something@gmail.com" } + let(:new_email) { "newsomething@gmail.com" } + it "does not find a non-duplicate" do expect(b_param.no_duplicate).to be_truthy expect(b_param.find_duplicate_bike(new_bike)).to be_falsey expect do @@ -147,15 +147,15 @@ end end - describe 'save_bike' do + describe "save_bike" do Sidekiq::Testing.inline! do - it 'creates a bike with the parameters it is passed and returns it' do + it "creates a bike with the parameters it is passed and returns it" do organization = FactoryBot.create(:organization) user = FactoryBot.create(:user) manufacturer = FactoryBot.create(:manufacturer) color = FactoryBot.create(:color) wheel_size = FactoryBot.create(:wheel_size) - b_param = BParam.new(origin: 'api_v1') + b_param = BParam.new(origin: "api_v1") creator = BikeCreator.new(b_param) bike = Bike.new # allow(bike).to receive(:id).and_return(69) @@ -163,15 +163,15 @@ expect(creator).to receive(:validate_record).and_return(bike) new_bike = Bike.new( creation_organization_id: organization.id, - propulsion_type: 'sail', - 'cycle_type' => 'stroller', - 'serial_number' => 'BIKE TOKENd', - 'manufacturer_id' => manufacturer.id, - 'rear_tire_narrow' => 'wheelchair', - 'rear_wheel_size_id' => wheel_size.id, - 'primary_frame_color_id' => color.id, - 'handlebar_type' => 'bmx', - 'creator' => user + propulsion_type: "sail", + "cycle_type" => "stroller", + "serial_number" => "BIKE TOKENd", + "manufacturer_id" => manufacturer.id, + "rear_tire_narrow" => "wheelchair", + "rear_wheel_size_id" => wheel_size.id, + "primary_frame_color_id" => color.id, + "handlebar_type" => "bmx", + "creator" => user, ) expect do saved_bike = creator.save_bike(new_bike) @@ -179,7 +179,7 @@ end end - it 'enque listing order working' do + it "enque listing order working" do Sidekiq::Worker.clear_all Sidekiq::Testing.fake! do b_param = BParam.new @@ -194,17 +194,17 @@ end end - describe 'new_bike' do - it 'calls the required methods' do + describe "new_bike" do + it "calls the required methods" do creator = BikeCreator.new expect(creator).to receive(:build_new_bike).and_return(true) creator.new_bike end end - describe 'create_bike' do + describe "create_bike" do Sidekiq::Testing.inline! do - it 'saves the bike' do + it "saves the bike" do b_param = BParam.new bike = Bike.new creator = BikeCreator.new(b_param) @@ -215,14 +215,14 @@ end end - it 'returns the bike instead of saving if the bike has errors' do + it "returns the bike instead of saving if the bike has errors" do b_param = BParam.new - bike = Bike.new(serial_number: 'LOLZ') - bike.errors.add(:errory, 'something') + bike = Bike.new(serial_number: "LOLZ") + bike.errors.add(:errory, "something") creator = BikeCreator.new(b_param) expect(creator).to receive(:build_bike).and_return(bike) response = creator.create_bike - expect(response.errors[:errory]).to eq(['something']) + expect(response.errors[:errory]).to eq(["something"]) end end end diff --git a/spec/services/bike_creator_verifier_spec.rb b/spec/services/bike_creator_verifier_spec.rb index 1111641c65..a9a071deb5 100644 --- a/spec/services/bike_creator_verifier_spec.rb +++ b/spec/services/bike_creator_verifier_spec.rb @@ -1,5 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe BikeCreatorVerifier do - end diff --git a/spec/services/bike_searcher_spec.rb b/spec/services/bike_searcher_spec.rb index b7d75cdc28..110bc687e7 100644 --- a/spec/services/bike_searcher_spec.rb +++ b/spec/services/bike_searcher_spec.rb @@ -1,27 +1,27 @@ -require 'spec_helper' +require "spec_helper" describe BikeSearcher do - describe 'initialize' do - context 'basic serial array' do - it 'deletes the serial gsub expression if it is present' do - params = { query: 'm_940%2Cs%23sdfc%23%2Cc_1' } + describe "initialize" do + context "basic serial array" do + it "deletes the serial gsub expression if it is present" do + params = { query: "m_940%2Cs%23sdfc%23%2Cc_1" } searcher = BikeSearcher.new(params) - expect(searcher.params[:serial]).to eq('sdfc') - expect(searcher.params[:query]).to eq('m_940%2C%2Cc_1') + expect(searcher.params[:serial]).to eq("sdfc") + expect(searcher.params[:query]).to eq("m_940%2C%2Cc_1") end end - context 'troublesome 1' do - it 'deletes the serial gsub expression if it is present' do - params = { query: 's#R910860723#' } + context "troublesome 1" do + it "deletes the serial gsub expression if it is present" do + params = { query: "s#R910860723#" } searcher = BikeSearcher.new(params) - expect(searcher.params[:serial]).to eq('R910860723') - expect(searcher.params[:query]).to eq('') + expect(searcher.params[:serial]).to eq("R910860723") + expect(searcher.params[:query]).to eq("") end end end - describe 'search selectize options' do - it 'returns the selectized items if passed through the expected things' do + describe "search selectize options" do + it "returns the selectized items if passed through the expected things" do manufacturer = FactoryBot.create(:manufacturer) color_1 = FactoryBot.create(:color) color_2 = FactoryBot.create(:color) @@ -34,8 +34,8 @@ manufacturer.autocomplete_result_hash, color_1.autocomplete_result_hash, color_2.autocomplete_result_hash, - { id: 'serial', search_id: 's#8xcvxcvcx#', text: '8xcvxcvcx' }, - { text: 'something+cool', search_id: 'something+cool' } + { id: "serial", search_id: "s#8xcvxcvcx#", text: "8xcvxcvcx" }, + { text: "something+cool", search_id: "something+cool" }, ].as_json result = searcher.selectize_items expect(result).to eq target @@ -44,8 +44,8 @@ end end - describe 'find_bikes' do - it 'calls select manufacturers, attributes, stolen and query if stolen is present' do + describe "find_bikes" do + it "calls select manufacturers, attributes, stolen and query if stolen is present" do search = BikeSearcher.new(stolen: true) expect(search).to receive(:matching_serial).and_return(Bike) expect(search).to receive(:matching_stolenness).and_return(Bike) @@ -54,61 +54,61 @@ expect(search).to receive(:matching_query).and_return(Bike) search.find_bikes end - it 'does not fail if nothing is present' do + it "does not fail if nothing is present" do search = BikeSearcher.new expect(search.find_bikes).not_to be_present end end - describe 'matching_serial' do - it 'finds matching bikes' do - bike = FactoryBot.create(:bike, serial_number: 'st00d-ffer') - search = BikeSearcher.new(serial: 'STood ffer') + describe "matching_serial" do + it "finds matching bikes" do + bike = FactoryBot.create(:bike, serial_number: "st00d-ffer") + search = BikeSearcher.new(serial: "STood ffer") expect(search.matching_serial.first).to eq(bike) end - it 'finds matching bikes' do - bike = FactoryBot.create(:bike, serial_number: 'st00d-ffer') - search = BikeSearcher.new(serial: 'STood') + it "finds matching bikes" do + bike = FactoryBot.create(:bike, serial_number: "st00d-ffer") + search = BikeSearcher.new(serial: "STood") expect(search.matching_serial.first).to eq(bike) end - it 'finds bikes with absent serials' do - bike = FactoryBot.create(:bike, serial_number: 'absent') - search = BikeSearcher.new(serial: 'absent') + it "finds bikes with absent serials" do + bike = FactoryBot.create(:bike, serial_number: "absent") + search = BikeSearcher.new(serial: "absent") expect(search.matching_serial.first).to eq(bike) end - it 'fulls text search' do - bike = FactoryBot.create(:bike, serial_number: 'K10DY00047-bkd') - search = BikeSearcher.new(serial: 'bkd-K1oDYooo47') + it "fulls text search" do + bike = FactoryBot.create(:bike, serial_number: "K10DY00047-bkd") + search = BikeSearcher.new(serial: "bkd-K1oDYooo47") expect(search.matching_serial.first).to eq(bike) end end - describe 'matching_manufacturer' do - it 'finds matching bikes from manufacturer without id' do - manufacturer = FactoryBot.create(:manufacturer, name: 'Special bikes co.') + describe "matching_manufacturer" do + it "finds matching bikes from manufacturer without id" do + manufacturer = FactoryBot.create(:manufacturer, name: "Special bikes co.") bike = FactoryBot.create(:bike, manufacturer: manufacturer) bike2 = FactoryBot.create(:bike) - search = BikeSearcher.new(manufacturer: 'Special', query: '') + search = BikeSearcher.new(manufacturer: "Special", query: "") expect(search.matching_manufacturer(Bike.all).first).to eq(bike) expect(search.matching_manufacturer(Bike.all).pluck(:id).include?(bike2.id)).to be_falsey end it "does not return any bikes if we can't find the manufacturer" do - manufacturer = FactoryBot.create(:manufacturer, name: 'Special bikes co.') + manufacturer = FactoryBot.create(:manufacturer, name: "Special bikes co.") bike = FactoryBot.create(:bike, manufacturer: manufacturer) - search = BikeSearcher.new(manufacturer: '69696969', query: '') + search = BikeSearcher.new(manufacturer: "69696969", query: "") expect(search.matching_manufacturer(Bike.all).count).to eq(0) end - it 'finds matching bikes' do + it "finds matching bikes" do bike = FactoryBot.create(:bike) - search = BikeSearcher.new(manufacturer_id: bike.manufacturer_id, query: 'something') + search = BikeSearcher.new(manufacturer_id: bike.manufacturer_id, query: "something") expect(search.matching_manufacturer(Bike.all).first).to eq(bike) end end - describe 'matching_colors' do - it 'finds matching colors' do + describe "matching_colors" do + it "finds matching colors" do color = FactoryBot.create(:color) bike = FactoryBot.create(:bike, tertiary_frame_color_id: color.id) FactoryBot.create(:bike) @@ -118,50 +118,50 @@ end end - describe 'fuzzy_find_serial' do - it 'finds matching serial segments' do - bike = FactoryBot.create(:bike, serial_number: 'st00d-fferd') + describe "fuzzy_find_serial" do + it "finds matching serial segments" do + bike = FactoryBot.create(:bike, serial_number: "st00d-fferd") bike.create_normalized_serial_segments bike.normalized_serial_segments - search = BikeSearcher.new(serial: 'fferds') + search = BikeSearcher.new(serial: "fferds") result = search.fuzzy_find_serial expect(result.first).to eq(bike) expect(result.count).to eq(1) end it "doesn't find exact matches" do - bike = FactoryBot.create(:bike, serial_number: 'K10DY00047-bkd') - search = BikeSearcher.new(serial: 'bkd-K1oDYooo47') + bike = FactoryBot.create(:bike, serial_number: "K10DY00047-bkd") + search = BikeSearcher.new(serial: "bkd-K1oDYooo47") expect(search.fuzzy_find_serial).to be_empty end end - describe 'matching_stolenness' do + describe "matching_stolenness" do before :each do @non_stolen = FactoryBot.create(:bike) @stolen = FactoryBot.create(:bike, stolen: true) end it "selects only stolen bikes if non-stolen isn't selected" do - search = BikeSearcher.new(stolen: 'on') + search = BikeSearcher.new(stolen: "on") result = search.matching_stolenness(Bike.all) expect(result).to eq([@stolen]) end it "selects only non-stolen bikes if stolen isn't selected" do - search = BikeSearcher.new(non_stolen: 'on') + search = BikeSearcher.new(non_stolen: "on") result = search.matching_stolenness(Bike.all) expect(result).to eq([@non_stolen]) end - it 'returns all bikes' do + it "returns all bikes" do search = BikeSearcher.new.matching_stolenness(Bike.all) expect(search).to eq(Bike.all) end end - describe 'matching_query' do - it 'selects bikes matching the attribute' do - search = BikeSearcher.new(query: 'something') + describe "matching_query" do + it "selects bikes matching the attribute" do + search = BikeSearcher.new(query: "something") bikes = Bike.all - expect(bikes).to receive(:text_search).and_return('booger') - expect(search.matching_query(bikes)).to eq('booger') + expect(bikes).to receive(:text_search).and_return("booger") + expect(search.matching_query(bikes)).to eq("booger") end end end diff --git a/spec/services/bike_updator_spec.rb b/spec/services/bike_updator_spec.rb index be61eacdbc..ee4e70b3e8 100644 --- a/spec/services/bike_updator_spec.rb +++ b/spec/services/bike_updator_spec.rb @@ -1,18 +1,18 @@ -require 'spec_helper' +require "spec_helper" describe BikeUpdator do - describe 'find_bike' do + describe "find_bike" do it "raises an error if it can't find the bike" do expect { BikeUpdator.new(b_params: { id: 696969 }).find_bike }.to raise_error(BikeUpdatorError) end - it 'finds the bike from the bike_params' do + it "finds the bike from the bike_params" do bike = FactoryBot.create(:bike) response = BikeUpdator.new(b_params: { id: bike.id }.as_json).find_bike expect(response).to eq(bike) end end - describe 'ensure_ownership!' do + describe "ensure_ownership!" do it "raises an error if the user doesn't own the bike" do ownership = FactoryBot.create(:ownership) user = FactoryBot.create(:user) @@ -20,7 +20,7 @@ expect { BikeUpdator.new(user: user, b_params: { id: bike.id }.as_json).ensure_ownership! }.to raise_error(BikeUpdatorError) end - it 'returns true if the bike is owned by the user' do + it "returns true if the bike is owned by the user" do ownership = FactoryBot.create(:ownership) user = ownership.creator bike = ownership.bike @@ -28,9 +28,9 @@ end end - describe 'update_stolen_record' do - it 'calls update_stolen_record with the date_stolen if it exists' do - FactoryBot.create(:country, iso: 'US') + describe "update_stolen_record" do + it "calls update_stolen_record with the date_stolen if it exists" do + FactoryBot.create(:country, iso: "US") bike = FactoryBot.create(:bike, stolen: true) updator = BikeUpdator.new(b_params: { id: bike.id, bike: { date_stolen: 963205199 } }.as_json) updator.update_stolen_record @@ -38,19 +38,19 @@ expect(csr.date_stolen.to_i).to be_within(1).of 963205199 end it "creates a stolen record if one doesn't exist" do - FactoryBot.create(:country, iso: 'US') + FactoryBot.create(:country, iso: "US") bike = FactoryBot.create(:bike) BikeUpdator.new(b_params: { id: bike.id, bike: { stolen: true } }.as_json).update_stolen_record expect(bike.stolen_records.count).not_to be_nil end end - describe 'update_ownership' do - it 'calls create_ownership if the email has changed' do + describe "update_ownership" do + it "calls create_ownership if the email has changed" do bike = FactoryBot.create(:bike) user = FactoryBot.create(:user) expect(bike.updator_id).to be_nil - update_bike = BikeUpdator.new(b_params: { id: bike.id, bike: { owner_email: 'another@email.co' } }.as_json, user: user) + update_bike = BikeUpdator.new(b_params: { id: bike.id, bike: { owner_email: "another@email.co" } }.as_json, user: user) expect_any_instance_of(OwnershipCreator).to receive(:create_ownership) update_bike.update_ownership bike.reload @@ -58,36 +58,36 @@ end it "does not call create_ownership if the email hasn't changed" do - bike = FactoryBot.create(:bike, owner_email: 'another@email.co') - update_bike = BikeUpdator.new(b_params: { id: bike.id, bike: { owner_email: 'another@email.co' } }.as_json) + bike = FactoryBot.create(:bike, owner_email: "another@email.co") + update_bike = BikeUpdator.new(b_params: { id: bike.id, bike: { owner_email: "another@email.co" } }.as_json) expect_any_instance_of(OwnershipCreator).not_to receive(:create_ownership) update_bike.update_ownership end end - describe 'update_available_attributes' do - it 'does not let protected attributes be updated' do - FactoryBot.create(:country, iso: 'US') + describe "update_available_attributes" do + it "does not let protected attributes be updated" do + FactoryBot.create(:country, iso: "US") organization = FactoryBot.create(:organization) bike = FactoryBot.create(:bike, - creation_organization_id: organization.id, - example: true, - owner_email: 'foo@bar.com') + creation_organization_id: organization.id, + example: true, + owner_email: "foo@bar.com") ownership = FactoryBot.create(:ownership, bike: bike) user = ownership.creator new_creator = FactoryBot.create(:user) og_bike = bike bike_params = { - description: 'something long', - serial_number: '69', + description: "something long", + serial_number: "69", manufacturer_id: 69, - manufacturer_other: 'Uggity Buggity', + manufacturer_other: "Uggity Buggity", creator: new_creator, creation_organization_id: 69, example: false, hidden: true, stolen: true, - owner_email: ' ' + owner_email: " ", } BikeUpdator.new(user: user, b_params: { id: bike.id, bike: bike_params }.as_json).update_available_attributes expect(bike.reload.serial_number).to eq(og_bike.serial_number) @@ -97,11 +97,11 @@ expect(bike.creator).to eq(og_bike.creator) expect(bike.example).to eq(og_bike.example) expect(bike.hidden).to be_falsey - expect(bike.description).to eq('something long') - expect(bike.owner_email).to eq('foo@bar.com') + expect(bike.description).to eq("something long") + expect(bike.owner_email).to eq("foo@bar.com") end - it 'marks a bike user hidden' do + it "marks a bike user hidden" do organization = FactoryBot.create(:organization) bike = FactoryBot.create(:bike, creation_organization_id: organization.id, example: true) ownership = FactoryBot.create(:ownership, bike: bike) @@ -114,7 +114,7 @@ expect(bike.user_hidden).to be_truthy end - it 'Actually, for now, we let anyone mark anything not stolen' do + it "Actually, for now, we let anyone mark anything not stolen" do bike = FactoryBot.create(:bike, stolen: true) ownership = FactoryBot.create(:ownership, bike: bike) user = ownership.creator @@ -126,12 +126,12 @@ expect(bike.reload.stolen).not_to be_truthy end - it 'updates the bike and set year to nothing if year nil' do + it "updates the bike and set year to nothing if year nil" do bike = FactoryBot.create(:bike, year: 2014) ownership = FactoryBot.create(:ownership, bike: bike) user = ownership.creator new_creator = FactoryBot.create(:user) - bike_params = { coaster_brake: true, year: nil, components_attributes: { '1387762503379' => { 'ctype_id' => '', 'front' => '0', 'rear' => '0', 'ctype_other' => '', 'description' => '', 'manufacturer_id' => '', 'model_name' => '', 'manufacturer_other' => '', 'year' => '', 'serial_number' => '', '_destroy' => '0' } } } + bike_params = { coaster_brake: true, year: nil, components_attributes: { "1387762503379" => { "ctype_id" => "", "front" => "0", "rear" => "0", "ctype_other" => "", "description" => "", "manufacturer_id" => "", "model_name" => "", "manufacturer_other" => "", "year" => "", "serial_number" => "", "_destroy" => "0" } } } update_bike = BikeUpdator.new(user: user, b_params: { id: bike.id, bike: bike_params }.as_json) expect(update_bike).to receive(:update_ownership).and_return(true) update_bike.update_available_attributes @@ -140,7 +140,7 @@ expect(bike.components.count).to eq(0) end - it 'updates the bike sets is_for_sale to false' do + it "updates the bike sets is_for_sale to false" do bike = FactoryBot.create(:bike, is_for_sale: true) ownership = FactoryBot.create(:ownership, bike: bike) user = ownership.creator @@ -151,7 +151,7 @@ end end - it 'enque listing order working' do + it "enque listing order working" do Sidekiq::Testing.fake! bike = FactoryBot.create(:bike, stolen: true) ownership = FactoryBot.create(:ownership, bike: bike) diff --git a/spec/services/component_creator_spec.rb b/spec/services/component_creator_spec.rb index baffe8684b..d9193c45f8 100644 --- a/spec/services/component_creator_spec.rb +++ b/spec/services/component_creator_spec.rb @@ -1,30 +1,30 @@ -require 'spec_helper' +require "spec_helper" describe ComponentCreator do - describe 'set_manufacturer_key' do - context 'manufacturer in db' do - it 'sets the manufacturer_id' do - m = FactoryBot.create(:manufacturer, name: 'SRAM') - c = { manufacturer: 'sram' } + describe "set_manufacturer_key" do + context "manufacturer in db" do + it "sets the manufacturer_id" do + m = FactoryBot.create(:manufacturer, name: "SRAM") + c = { manufacturer: "sram" } component = ComponentCreator.new.set_manufacturer_key(c) expect(component[:manufacturer_id]).to eq(m.id) expect(component[:manufacturer]).not_to be_present end end - context 'unknown manufacturer' do - it 'adds other manufacturer name and set the set the foreign keys' do - m = FactoryBot.create(:manufacturer, name: 'Other') - c = { manufacturer: 'Gobbledy Gooky' } + context "unknown manufacturer" do + it "adds other manufacturer name and set the set the foreign keys" do + m = FactoryBot.create(:manufacturer, name: "Other") + c = { manufacturer: "Gobbledy Gooky" } component = ComponentCreator.new.set_manufacturer_key(c) expect(component[:manufacturer_id]).to eq(m.id) expect(component[:manufacturer]).not_to be_present - expect(component[:manufacturer_other]).to eq('Gobbledy Gooky') + expect(component[:manufacturer_other]).to eq("Gobbledy Gooky") end end - context 'manufacturer_id a manufacturer name' do - it 'sets manufacturer_id correctly' do - m = FactoryBot.create(:manufacturer, name: 'SRAM') - c = { manufacturer_id: 'sram' } + context "manufacturer_id a manufacturer name" do + it "sets manufacturer_id correctly" do + m = FactoryBot.create(:manufacturer, name: "SRAM") + c = { manufacturer_id: "sram" } component = ComponentCreator.new.set_manufacturer_key(c) expect(component[:manufacturer_id]).to eq(m.id) expect(component[:manufacturer]).not_to be_present @@ -32,28 +32,28 @@ end end - describe 'set_component_type' do - it 'sets the component_type from a string' do - ctype = FactoryBot.create(:ctype, name: 'Stuff blows') - c = { component_type: 'sTuff Blows ' } + describe "set_component_type" do + it "sets the component_type from a string" do + ctype = FactoryBot.create(:ctype, name: "Stuff blows") + c = { component_type: "sTuff Blows " } component = ComponentCreator.new.set_component_type(c) expect(component[:ctype_id]).to eq(ctype.id) expect(component[:component_type]).not_to be_present end it "creates a new component type if we don't recognize it" do - c = { component_type: 'Hubs' } + c = { component_type: "Hubs" } component = ComponentCreator.new.set_component_type(c) expect(component[:ctype_id]).to eq(Ctype.unknown.id) - expect(component[:ctype_other]).to eq('Hubs') + expect(component[:ctype_other]).to eq("Hubs") expect(component[:component_type]).not_to be_present end end - describe 'create_component' do - it 'creates the component' do + describe "create_component" do + it "creates the component" do bike = FactoryBot.create(:bike) - manufacturer = FactoryBot.create(:manufacturer, name: 'Somecool THING') - component = { description: 'Stuff', mnfg_name: 'Somecool thing' } + manufacturer = FactoryBot.create(:manufacturer, name: "Somecool THING") + component = { description: "Stuff", mnfg_name: "Somecool thing" } component_creator = ComponentCreator.new(bike: bike) component_creator.create_component(component) expect(bike.reload.components.count).to eq(1) @@ -61,23 +61,23 @@ end it "creates the component and ignore attributes it shouldn't use" do bike = FactoryBot.create(:bike) - component = { description: 'Stuff', cgroup: 'Drivetrain and brakes' } + component = { description: "Stuff", cgroup: "Drivetrain and brakes" } component_creator = ComponentCreator.new(bike: bike) component_creator.create_component(component) expect(bike.reload.components.count).to eq(1) end end - describe 'create_components_from_params' do - it 'returns nil if there are no components' do + describe "create_components_from_params" do + it "returns nil if there are no components" do b_param = BParam.new - allow(b_param).to receive(:params).and_return(s: 'things') + allow(b_param).to receive(:params).and_return(s: "things") component_creator = ComponentCreator.new(b_param: b_param) expect(component_creator.create_components_from_params).to be_nil end - it 'calls the necessary methods to create a component on each component' do + it "calls the necessary methods to create a component on each component" do b_param = BParam.new - components = [{ component_type: 'something' }, { component_type: 'something' }] + components = [{ component_type: "something" }, { component_type: "something" }] allow(b_param).to receive(:params).and_return({ components: components }.as_json) component_creator = ComponentCreator.new(b_param: b_param) expect(component_creator).to receive(:set_manufacturer_key).at_least(2).times.and_return(true) diff --git a/spec/services/geohelper_spec.rb b/spec/services/geohelper_spec.rb index a98bdef070..ea1479bbca 100644 --- a/spec/services/geohelper_spec.rb +++ b/spec/services/geohelper_spec.rb @@ -54,7 +54,7 @@ zipcode: "94103", country: "USA", latitude: 37.7870322, - longitude: -122.4039235 + longitude: -122.4039235, } end it "returns our desires" do diff --git a/spec/services/ownership_creator_spec.rb b/spec/services/ownership_creator_spec.rb index f7e0ff9f73..5e24809df8 100644 --- a/spec/services/ownership_creator_spec.rb +++ b/spec/services/ownership_creator_spec.rb @@ -14,8 +14,8 @@ end end - describe 'send_notification_email' do - it 'sends a notification email' do + describe "send_notification_email" do + it "sends a notification email" do ownership = Ownership.new allow(ownership).to receive(:id).and_return(2) expect do @@ -23,7 +23,7 @@ end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(1) end - it 'does not send a notification email for example bikes' do + it "does not send a notification email for example bikes" do ownership = Ownership.new allow(ownership).to receive(:id).and_return(2) allow(ownership).to receive(:example).and_return(true) @@ -32,7 +32,7 @@ end.to change(EmailOwnershipInvitationWorker.jobs, :size).by(0) end - it 'does not send a notification email for ownerships with no_email set' do + it "does not send a notification email for ownerships with no_email set" do ownership = Ownership.new allow(ownership).to receive(:id).and_return(2) allow(ownership).to receive(:send_email).and_return(false) @@ -42,8 +42,8 @@ end end - describe 'mark_other_ownerships_not_current' do - it 'marks existing ownerships as not current' do + describe "mark_other_ownerships_not_current" do + it "marks existing ownerships as not current" do ownership1 = FactoryBot.create(:ownership) bike = ownership1.bike ownership2 = FactoryBot.create(:ownership, bike: bike) @@ -53,43 +53,43 @@ end end - describe 'current_is_hidden' do - it 'returns true if existing ownerships is user hidden' do + describe "current_is_hidden" do + it "returns true if existing ownerships is user hidden" do ownership = FactoryBot.create(:ownership, user_hidden: true) bike = ownership.bike bike.update_attribute :hidden, true ownership_creator = OwnershipCreator.new(bike: bike) expect(ownership_creator.current_is_hidden).to be_truthy end - it 'returns false' do + it "returns false" do bike = Bike.new ownership_creator = OwnershipCreator.new(bike: bike) expect(ownership_creator.current_is_hidden).to be_falsey end end - describe 'add_errors_to_bike' do - xit 'adds the errors to the bike' do + describe "add_errors_to_bike" do + xit "adds the errors to the bike" do ownership = Ownership.new bike = Bike.new - ownership.errors.add(:problem, 'BALLZ') + ownership.errors.add(:problem, "BALLZ") creator = OwnershipCreator.new(bike: bike) creator.add_errors_to_bike(ownership) - expect(bike.errors.messages[:problem]).to eq('BALLZ') + expect(bike.errors.messages[:problem]).to eq("BALLZ") end end - describe 'ownership_creator' do - it 'calls mark not current and send notification and create a new ownership' do + describe "ownership_creator" do + it "calls mark not current and send notification and create a new ownership" do ownership_creator = OwnershipCreator.new - new_params = { bike_id: 1, user_id: 69, owner_email: 'f@f.com', creator_id: 69, claimed: true, current: true } + new_params = { bike_id: 1, user_id: 69, owner_email: "f@f.com", creator_id: 69, claimed: true, current: true } allow(ownership_creator).to receive(:mark_other_ownerships_not_current).and_return(true) allow(ownership_creator).to receive(:new_ownership_params).and_return(new_params) expect(ownership_creator).to receive(:send_notification_email).and_return(true) expect(ownership_creator).to receive(:current_is_hidden).and_return(true) expect { ownership_creator.create_ownership }.to change(Ownership, :count).by(1) end - it 'calls mark not current and send notification and create a new ownership' do + it "calls mark not current and send notification and create a new ownership" do ownership_creator = OwnershipCreator.new new_params = { creator_id: 69, claimed: true, current: true } allow(ownership_creator).to receive(:mark_other_ownerships_not_current).and_return(true) diff --git a/spec/services/serial_normalizer_spec.rb b/spec/services/serial_normalizer_spec.rb index 0f821803e6..75a8afea8d 100644 --- a/spec/services/serial_normalizer_spec.rb +++ b/spec/services/serial_normalizer_spec.rb @@ -1,68 +1,68 @@ -require 'spec_helper' +require "spec_helper" describe SerialNormalizer do - describe 'normalize' do - it 'normalizes i o 5 2 z and b' do - serial = 'bobs-catzio' + describe "normalize" do + it "normalizes i o 5 2 z and b" do + serial = "bobs-catzio" result = SerialNormalizer.new(serial: serial).normalized - expect(result).to eq('8085 CAT210') + expect(result).to eq("8085 CAT210") end - it 'normalizes -_+= and multiple spaces' do - serial = 's>e-r--i+a_l' + it "normalizes -_+= and multiple spaces" do + serial = "s>e-r--i+a_l" result = SerialNormalizer.new(serial: serial).normalized - expect(result).to eq('5 E R 1 A 1') + expect(result).to eq("5 E R 1 A 1") end - it 'remove leading zeros and ohs' do - serial = '00O38675971596' + it "remove leading zeros and ohs" do + serial = "00O38675971596" result = SerialNormalizer.new(serial: serial).normalized - expect(result).to eq('38675971596') + expect(result).to eq("38675971596") end - it 'returns absent unless present' do - expect(SerialNormalizer.new(serial: ' ').normalized).to eq 'absent' + it "returns absent unless present" do + expect(SerialNormalizer.new(serial: " ").normalized).to eq "absent" end end - describe 'normalized_segments' do - it 'makes normalized segments' do - segments = SerialNormalizer.new(serial: 'some + : serial').normalized_segments + describe "normalized_segments" do + it "makes normalized segments" do + segments = SerialNormalizer.new(serial: "some + : serial").normalized_segments expect(segments.count).to eq(2) - expect(segments[0]).to eq('50ME') + expect(segments[0]).to eq("50ME") end - it 'returns nil if serial is absent' do - segments = SerialNormalizer.new(serial: 'absent').normalized_segments + it "returns nil if serial is absent" do + segments = SerialNormalizer.new(serial: "absent").normalized_segments expect(segments).to eq([]) end end - describe 'save_segments' do - it 'saves normalized segments with the bike_id and not break if we resave' do + describe "save_segments" do + it "saves normalized segments with the bike_id and not break if we resave" do bike = FactoryBot.create(:bike) - SerialNormalizer.new(serial: 'some + : serial').save_segments(bike.id) + SerialNormalizer.new(serial: "some + : serial").save_segments(bike.id) expect(NormalizedSerialSegment.where(bike_id: bike.id).count).to eq(2) end - it 'does not save absent segments' do + it "does not save absent segments" do bike = FactoryBot.create(:bike) - SerialNormalizer.new(serial: 'absent').save_segments(bike.id) + SerialNormalizer.new(serial: "absent").save_segments(bike.id) expect(NormalizedSerialSegment.where(bike_id: bike.id).count).to eq(0) end - it 'rewrites the segments if we save them a second time' do + it "rewrites the segments if we save them a second time" do bike = FactoryBot.create(:bike) - SerialNormalizer.new(serial: 'some + : serial').save_segments(bike.id) + SerialNormalizer.new(serial: "some + : serial").save_segments(bike.id) expect(NormalizedSerialSegment.where(bike_id: bike.id).count).to eq(2) - SerialNormalizer.new(serial: 'another + : THING').save_segments(bike.id) + SerialNormalizer.new(serial: "another + : THING").save_segments(bike.id) segments = NormalizedSerialSegment.where(bike_id: bike.id) expect(segments.count).to eq(2) seg_strings = segments.map(&:segment) - expect(seg_strings.include?('AN0THER')).to be_truthy - expect(seg_strings.include?('TH1NG')).to be_truthy + expect(seg_strings.include?("AN0THER")).to be_truthy + expect(seg_strings.include?("TH1NG")).to be_truthy end - it 'does not make any if the bike is an example bike' do + it "does not make any if the bike is an example bike" do bike = FactoryBot.create(:bike) bike.update_attributes(example: true) - SerialNormalizer.new(serial: 'some + : serial').save_segments(bike.id) + SerialNormalizer.new(serial: "some + : serial").save_segments(bike.id) expect(NormalizedSerialSegment.where(bike_id: bike.id).count).to eq(0) end end diff --git a/spec/services/static_cache_builder_spec.rb b/spec/services/static_cache_builder_spec.rb index e69de29bb2..8b13789179 100644 --- a/spec/services/static_cache_builder_spec.rb +++ b/spec/services/static_cache_builder_spec.rb @@ -0,0 +1 @@ + diff --git a/spec/services/stolen_record_updator_spec.rb b/spec/services/stolen_record_updator_spec.rb index a728882b4f..ce632cd76d 100644 --- a/spec/services/stolen_record_updator_spec.rb +++ b/spec/services/stolen_record_updator_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require "spec_helper" describe StolenRecordUpdator do - describe 'create_new_record' do - it 'creates a new stolen record' do + describe "create_new_record" do + it "creates a new stolen record" do bike = FactoryBot.create(:bike) update_stolen_record = StolenRecordUpdator.new(bike: bike) expect { update_stolen_record.create_new_record }.to change(StolenRecord, :count).by(1) @@ -10,7 +10,7 @@ expect(bike.current_stolen_record).to eq(bike.stolen_records.last) end - it 'calls mark_records_not_current' do + it "calls mark_records_not_current" do bike = FactoryBot.create(:bike, stolen: true) update_stolen_record = StolenRecordUpdator.new(bike: bike) expect(update_stolen_record).to receive(:mark_records_not_current) @@ -18,7 +18,7 @@ end end - describe 'update_records' do + describe "update_records" do it "sets the current stolen record as not current if the bike isn't stolen" do bike = FactoryBot.create(:bike, stolen: true) update_stolen_record = StolenRecordUpdator.new(bike: bike) @@ -33,11 +33,11 @@ update_stolen_record.update_records end - it 'sets the date if date_stolen is present' do + it "sets the date if date_stolen is present" do stolen_record = FactoryBot.create(:stolen_record) bike = stolen_record.bike bike.update_attributes(stolen: true) - time = DateTime.strptime('01-01-1969 06', '%m-%d-%Y %H').end_of_day + time = DateTime.strptime("01-01-1969 06", "%m-%d-%Y %H").end_of_day StolenRecordUpdator.new(bike: bike, date_stolen: time.to_i).update_records expect(bike.reload.current_stolen_record.date_stolen).to be_within(1.second).of time end @@ -51,8 +51,8 @@ end end - describe 'mark_records_not_current' do - it 'marks all the records not current' do + describe "mark_records_not_current" do + it "marks all the records not current" do bike = FactoryBot.create(:bike) stolen_record1 = FactoryBot.create(:stolen_record, bike: bike) bike.save @@ -67,26 +67,26 @@ end end - describe 'update_with_params' do - it 'returns the stolen record if no stolen record is associated' do + describe "update_with_params" do + it "returns the stolen record if no stolen record is associated" do stolen_record = StolenRecord.new updator = StolenRecordUpdator.new.update_with_params(stolen_record) expect(updator).to eq(stolen_record) end - it 'sets the data that is submitted' do + it "sets the data that is submitted" do time = "2018-07-27T11:41:41.484" target_time = 1532659301 sr = { - phone: '2123123', + phone: "2123123", date_stolen: time, timezone: "Asia/Tokyo", - police_report_number: 'XXX', - police_report_department: 'highway 69', - theft_description: 'blah blah blah', - street: 'some address', - city: 'Big town', - zipcode: '60666' + police_report_number: "XXX", + police_report_department: "highway 69", + theft_description: "blah blah blah", + street: "some address", + city: "Big town", + zipcode: "60666", } b_param = BParam.new allow(b_param).to receive(:params).and_return({ stolen_record: sr }.as_json) @@ -98,7 +98,7 @@ expect(stolen_record.theft_description).to eq(sr[:theft_description]) expect(stolen_record.street).to eq(sr[:street]) expect(stolen_record.city).to eq(sr[:city]) - expect(stolen_record.zipcode).to eq('60666') + expect(stolen_record.zipcode).to eq("60666") expect(stolen_record.date_stolen.to_i).to be_within(1).of target_time end @@ -107,7 +107,7 @@ state = FactoryBot.create(:state, country: country) sr = { state: state.abbreviation, - country: country.iso + country: country.iso, } b_param = BParam.new allow(b_param).to receive(:params).and_return({ stolen_record: sr }.as_json) diff --git a/spec/services/webhook_runner_spec.rb b/spec/services/webhook_runner_spec.rb index d4d1b8668f..e08411b197 100644 --- a/spec/services/webhook_runner_spec.rb +++ b/spec/services/webhook_runner_spec.rb @@ -1,19 +1,19 @@ -require 'spec_helper' +require "spec_helper" describe WebhookRunner do - describe 'make_request' do + describe "make_request" do it "doesn't error if webhook doesn't return" do runner = WebhookRunner.new - response = runner.make_request('https://testing.bikeindex.org/about/something') + response = runner.make_request("https://testing.bikeindex.org/about/something") expect(response).to be_present end end - describe 'after_bike_update' do - it 'calls make request' do + describe "after_bike_update" do + it "calls make request" do runner = WebhookRunner.new id = 9999 - expect(runner).to receive(:hook_urls).with('after_bike_update').and_return(['http://tester.com/bikes/#{bike_id}']) + expect(runner).to receive(:hook_urls).with("after_bike_update").and_return(['http://tester.com/bikes/#{bike_id}']) expect(runner).to receive(:make_request).with("http://tester.com/bikes/#{id}") runner.after_bike_update(id) end @@ -21,16 +21,16 @@ it "doesn't fail if there aren't any urls" do runner = WebhookRunner.new id = 9999 - Redis.new.expire(runner.redis_id('after_bike_update'), 0) + Redis.new.expire(runner.redis_id("after_bike_update"), 0) expect(runner.after_bike_update(id)).to be_truthy end end - describe 'after_user_update' do - it 'calls make request' do + describe "after_user_update" do + it "calls make request" do runner = WebhookRunner.new id = 9999 - expect(runner).to receive(:hook_urls).with('after_user_update').and_return(['http://tester.com/users/#{user_id}']) + expect(runner).to receive(:hook_urls).with("after_user_update").and_return(['http://tester.com/users/#{user_id}']) expect(runner).to receive(:make_request).with("http://tester.com/users/#{id}") runner.after_user_update(id) end @@ -38,20 +38,20 @@ it "doesn't fail if there aren't any urls" do runner = WebhookRunner.new id = 9999 - Redis.new.expire(runner.redis_id('after_user_update'), 0) + Redis.new.expire(runner.redis_id("after_user_update"), 0) expect(runner.after_user_update(id)).to be_truthy end end - describe 'hook_urls' do - it 'calls the redis array' do + describe "hook_urls" do + it "calls the redis array" do runner = WebhookRunner.new redis = Redis.new - rid = runner.redis_id('after_bike_update') + rid = runner.redis_id("after_bike_update") redis.expire(rid, 0) - redis.lpush(rid, 'http://tester.com') - expect(redis.lrange(rid, 0, 0)).to eq(['http://tester.com']) - expect(runner.hook_urls('after_bike_update')).to eq(redis.lrange(rid, 0, 0)) + redis.lpush(rid, "http://tester.com") + expect(redis.lrange(rid, 0, 0)).to eq(["http://tester.com"]) + expect(runner.hook_urls("after_bike_update")).to eq(redis.lrange(rid, 0, 0)) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c72d605d3c..0323549140 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,6 @@ -ENV['BASE_URL'] = 'http://test.host' # Assign here because only one .env file -require 'sidekiq/testing' -require 'vcr' +ENV["BASE_URL"] = "http://test.host" # Assign here because only one .env file +require "sidekiq/testing" +require "vcr" VCR.configure do |config| config.cassette_library_dir = "spec/vcr_cassettes" @@ -10,22 +10,22 @@ # For codeclimate test coverage. Only enable if the environmental variable is set - i.e. on CI if ENV["COVERAGE"] - require 'simplecov' + require "simplecov" SimpleCov.start "rails" end -ENV['RAILS_ENV'] ||= 'test' -require File.expand_path('../../config/environment', __FILE__) -require 'rspec/rails' +ENV["RAILS_ENV"] ||= "test" +require File.expand_path("../../config/environment", __FILE__) +require "rspec/rails" # require 'rspec/autorun' -require 'shoulda-matchers' -require 'database_cleaner' +require "shoulda-matchers" +require "database_cleaner" DatabaseCleaner.strategy = :truncation # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. -Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } +Dir[Rails.root.join("spec", "support", "**", "*.rb")].each { |f| require f } RSpec.configure do |config| # Use color in STDOUT diff --git a/spec/support/geocoder_default_location.rb b/spec/support/geocoder_default_location.rb index 77c8e6b4b8..48fac1b037 100644 --- a/spec/support/geocoder_default_location.rb +++ b/spec/support/geocoder_default_location.rb @@ -8,7 +8,7 @@ state: "New York", state_code: "NY", country: "United States", - country_code: "US" + country_code: "US", } end @@ -19,14 +19,14 @@ city: "New York", state: "NY", zipcode: "10007", - country: "USA" + country: "USA", }.as_json end let(:geo_hash) do { data: ["US", "NY", "New York", default_location[:latitude].to_s, default_location[:longitude].to_s], - cache_hit: true + cache_hit: true, } end let(:legacy_production_ip_search_result) { [geo_hash] } diff --git a/spec/support/scheduled_worker.rb b/spec/support/scheduled_worker.rb index 485c9aa637..67eace1d4c 100644 --- a/spec/support/scheduled_worker.rb +++ b/spec/support/scheduled_worker.rb @@ -9,7 +9,7 @@ def clear_scheduled_history shared_examples_for :scheduled_worker_tests do describe "scheduling" do - it 'does not need to run immediately after running' do + it "does not need to run immediately after running" do clear_scheduled_history expect(subject.should_enqueue?).to be_truthy instance.perform diff --git a/spec/support/shared_examples/amountable.rb b/spec/support/shared_examples/amountable.rb index 4b77fa40b2..296c257ff6 100644 --- a/spec/support/shared_examples/amountable.rb +++ b/spec/support/shared_examples/amountable.rb @@ -1,6 +1,6 @@ require "spec_helper" -RSpec.shared_examples 'amountable' do +RSpec.shared_examples "amountable" do let(:model_sym) { subject.class.name.underscore.to_sym } let(:instance) { FactoryBot.create model_sym } describe "amount_formatted" do diff --git a/spec/support/shared_examples/autocomplete_hashable.rb b/spec/support/shared_examples/autocomplete_hashable.rb index 435d50686f..4b960a5f64 100644 --- a/spec/support/shared_examples/autocomplete_hashable.rb +++ b/spec/support/shared_examples/autocomplete_hashable.rb @@ -1,20 +1,20 @@ -require 'spec_helper' +require "spec_helper" -RSpec.shared_examples 'autocomplete_hashable' do +RSpec.shared_examples "autocomplete_hashable" do let(:model_sym) { subject.class.name.underscore.to_sym } let(:instance) { FactoryBot.create model_sym } - describe 'autocomplete_result_hash' do - it 'it is the expected hash' do + describe "autocomplete_result_hash" do + it "it is the expected hash" do result = instance.autocomplete_result_hash instance.autocomplete_hash.each do |key, value| - if key == 'data' + if key == "data" value.each { |k, v| expect(result[k]).to eq v } else expect(result[key]).to eq value end end - expect(result['search_id']).to be_present + expect(result["search_id"]).to be_present end end end diff --git a/spec/support/shared_examples/bike_searchable.rb b/spec/support/shared_examples/bike_searchable.rb index 7cf68cd805..2a58e5548f 100644 --- a/spec/support/shared_examples/bike_searchable.rb +++ b/spec/support/shared_examples/bike_searchable.rb @@ -1,71 +1,71 @@ -require 'spec_helper' +require "spec_helper" -RSpec.shared_examples 'bike_searchable' do +RSpec.shared_examples "bike_searchable" do let(:manufacturer) { FactoryBot.create(:manufacturer) } let(:color) { FactoryBot.create(:color) } - let(:multi_query_items) { [manufacturer.search_id, color.search_id, 'some other string', 'another string'] } - let(:ip_address) { '127.0.0.1' } + let(:multi_query_items) { [manufacturer.search_id, color.search_id, "some other string", "another string"] } + let(:ip_address) { "127.0.0.1" } let(:interpreted_params) { Bike.searchable_interpreted_params(query_params, ip: ip_address) } - describe 'searchable_interpreted_params' do - context 'multiple query_items strings' do + describe "searchable_interpreted_params" do + context "multiple query_items strings" do let(:target) do { manufacturer: manufacturer.id, colors: [color.id], - query: 'some other string another string', - stolenness: 'stolen' + query: "some other string another string", + stolenness: "stolen", } end - context 'with query_params' do + context "with query_params" do let(:query_params) { { serial: nil, query_items: multi_query_items } } - it 'parses search_ids for manufacturers and colors' do + it "parses search_ids for manufacturers and colors" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'with passed ids' do - let(:query_params) { { manufacturer: manufacturer.slug, colors: [color.name], query: 'some other string another string' } } - it 'uses the passed ids' do + context "with passed ids" do + let(:query_params) { { manufacturer: manufacturer.slug, colors: [color.name], query: "some other string another string" } } + it "uses the passed ids" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end end - context 'multiple manufacturer_id and color_ids' do + context "multiple manufacturer_id and color_ids" do let(:manufacturer_2) { FactoryBot.create(:manufacturer) } let(:color_2) { FactoryBot.create(:color) } let(:target) do { manufacturer: [manufacturer.id, manufacturer_2.id], colors: [color.id, color_2.id], - query: 'some other string another string', - stolenness: 'all' + query: "some other string another string", + stolenness: "all", } end - context 'integer ids in query_items' do + context "integer ids in query_items" do let(:query_items) { multi_query_items + [manufacturer_2.search_id, color_2.search_id] } - let(:query_params) { { query_items: query_items, stolenness: 'all' } } - it 'returns them all' do + let(:query_params) { { query_items: query_items, stolenness: "all" } } + it "returns them all" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'name and slug for explicit manufacturer_id, color_ids and query' do + context "name and slug for explicit manufacturer_id, color_ids and query" do let(:query_params) do { query_items: multi_query_items, manufacturer: [manufacturer.slug, manufacturer_2.name], colors: [color.id, color_2.name], - query: 'some other string another string', - stolenness: 'all' + query: "some other string another string", + stolenness: "all", } end - context 'first pass' do - it 'finds the explicit ids and query' do + context "first pass" do + it "finds the explicit ids and query" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'parsing interpreted_params' do - let(:query_params) { target.merge(serial: 'PPPPXXX') } - it 'returns itself without calling the db' do + context "parsing interpreted_params" do + let(:query_params) { target.merge(serial: "PPPPXXX") } + it "returns itself without calling the db" do expect(Manufacturer).to_not receive(:friendly_find) expect(Color).to_not receive(:friendly_find) expect(Bike.searchable_interpreted_params(interpreted_params, ip: ip_address)).to eq interpreted_params @@ -73,143 +73,143 @@ end end end - context 'no query in query_items' do - let(:query_params) { { query_items: [''], stolenness: 'stolen' } } - let(:target) { { stolenness: 'stolen' } } - it 'returns just query' do + context "no query in query_items" do + let(:query_params) { { query_items: [""], stolenness: "stolen" } } + let(:target) { { stolenness: "stolen" } } + it "returns just query" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'with nil query items' do - let(:query_params) { { serial: 'some serial', query_items: nil, stolenness: 'non' } } - let(:target) { { serial: SerialNormalizer.new(serial: 'some serial').normalized, stolenness: 'non' } } - it 'parses serial' do + context "with nil query items" do + let(:query_params) { { serial: "some serial", query_items: nil, stolenness: "non" } } + let(:target) { { serial: SerialNormalizer.new(serial: "some serial").normalized, stolenness: "non" } } + it "parses serial" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'stolenness' do - context 'default' do - let(:target) { { stolenness: 'stolen' } } - context 'nil' do + context "stolenness" do + context "default" do + let(:target) { { stolenness: "stolen" } } + context "nil" do let(:query_params) { {} } - it 'returns stolen' do + it "returns stolen" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'unknown string' do - let(:query_params) { { stolenness: 'Not a thing!' } } - it 'returns stolen' do + context "unknown string" do + let(:query_params) { { stolenness: "Not a thing!" } } + it "returns stolen" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'stolen' do - let(:query_params) { { stolenness: 'stolen' } } - it 'returns stolen' do + context "stolen" do + let(:query_params) { { stolenness: "stolen" } } + it "returns stolen" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end end - context 'all' do - let(:query_params) { { stolenness: 'all' } } + context "all" do + let(:query_params) { { stolenness: "all" } } let(:target) { query_params } - it 'parses serial' do + it "parses serial" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'proximity' do + context "proximity" do include_context :geocoder_default_location - context 'ignored locations' do - context 'proximity of anywhere' do - let(:query_params) { { stolenness: 'proximity', location: 'anywhere', distance: 100 } } - let(:target) { { stolenness: 'stolen' } } - it 'returns a non-proximity search' do + context "ignored locations" do + context "proximity of anywhere" do + let(:query_params) { { stolenness: "proximity", location: "anywhere", distance: 100 } } + let(:target) { { stolenness: "stolen" } } + it "returns a non-proximity search" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end end - context 'input location' do - let(:query_params) { { stolenness: 'proximity', location: 'these parts', distance: '-1' } } - context 'with a distance less 0' do - let(:target) { { stolenness: 'proximity', location: 'these parts', distance: 100, bounding_box: bounding_box } } - it 'returns location and distance of 100' do + context "input location" do + let(:query_params) { { stolenness: "proximity", location: "these parts", distance: "-1" } } + context "with a distance less 0" do + let(:target) { { stolenness: "proximity", location: "these parts", distance: 100, bounding_box: bounding_box } } + it "returns location and distance of 100" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end - context 'with no distance' do - let(:target) { { stolenness: 'proximity', location: 'these parts', distance: 100, bounding_box: bounding_box } } - it 'returns location and distance of 100' do + context "with no distance" do + let(:target) { { stolenness: "proximity", location: "these parts", distance: 100, bounding_box: bounding_box } } + it "returns location and distance of 100" do expect(Bike.searchable_interpreted_params(query_params.except(:distance), ip: ip_address)).to eq target end end - context 'with a broken bounding box' do + context "with a broken bounding box" do let(:nan) { 0.0 / 0 } let(:bounding_box) { [nan, nan, nan, nan] } # Override bounding box stub in geocoder_default_location - let(:target) { { stolenness: 'stolen' } } - it 'returns a non-proximity search' do + let(:target) { { stolenness: "stolen" } } + it "returns a non-proximity search" do expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end end %w(ip you).each do |ip_string| context "Reverse geocode IP lookup for location: '#{ip_string}'" do - let(:query_params) { { stolenness: 'proximity', location: ip_string, distance: 'twelve ' } } - let(:target) { { stolenness: 'proximity', distance: 100, location: 'STUBBED response', bounding_box: bounding_box } } - it 'returns the location and the distance' do - expect(Geocoder).to receive(:search).with(ip_address) { 'STUBBED response' } + let(:query_params) { { stolenness: "proximity", location: ip_string, distance: "twelve " } } + let(:target) { { stolenness: "proximity", distance: 100, location: "STUBBED response", bounding_box: bounding_box } } + it "returns the location and the distance" do + expect(Geocoder).to receive(:search).with(ip_address) { "STUBBED response" } expect(Bike.searchable_interpreted_params(query_params, ip: ip_address)).to eq target end end end context 'a blank ip address for "ip" proximity search' do - let(:query_params) { { stolenness: 'proximity', location: 'ip', distance: '7 ' } } - let(:target) { { stolenness: 'stolen' } } - it 'returns a non-proximity search' do - expect(Bike.searchable_interpreted_params(query_params, ip: ' ')).to eq target + let(:query_params) { { stolenness: "proximity", location: "ip", distance: "7 " } } + let(:target) { { stolenness: "stolen" } } + it "returns a non-proximity search" do + expect(Bike.searchable_interpreted_params(query_params, ip: " ")).to eq target end end end end end - describe 'selected_query_items_options' do - context 'empty' do + describe "selected_query_items_options" do + context "empty" do let(:query_params) { {} } - context 'empty params' do - it 'returns an empty array' do + context "empty params" do + it "returns an empty array" do expect(Bike.selected_query_items_options(interpreted_params)).to eq([]) end end - context 'blank values' do - let(:query_params) { { stolenness: 'all', query: '', query_items: [] } } - it 'returns an empty array' do + context "blank values" do + let(:query_params) { { stolenness: "all", query: "", query_items: [] } } + it "returns an empty array" do expect(Bike.selected_query_items_options(interpreted_params)).to eq([]) end end end - context 'functioning query' do + context "functioning query" do let(:query_params) { { serial: nil, query_items: multi_query_items } } let(:target) do [ - 'some other string another string', + "some other string another string", manufacturer.autocomplete_result_hash, - color.autocomplete_result_hash + color.autocomplete_result_hash, ] end - it 'returns the query items hashes (for display in HTML)' do + it "returns the query items hashes (for display in HTML)" do expect(Bike.selected_query_items_options(interpreted_params)).to eq target end end - context 'unknown manufacturers and colors query' do + context "unknown manufacturers and colors query" do # Instead of erroring, just skip the unknown manufacturers - let(:query_params) { { serial: 'XXX8c8c', query_items: ['m_1000', 'c_999', 'special handlebars'] } } - let(:target) { ['special handlebars'] } - it 'returns the query items without erroring' do + let(:query_params) { { serial: "XXX8c8c", query_items: ["m_1000", "c_999", "special handlebars"] } } + let(:target) { ["special handlebars"] } + it "returns the query items without erroring" do expect(Bike.selected_query_items_options(interpreted_params)).to eq target end end end - describe 'search' do - context 'color_ids of primary, secondary and tertiary' do + describe "search" do + context "color_ids of primary, secondary and tertiary" do let(:color_2) { FactoryBot.create(:color) } let(:bike_1) { FactoryBot.create(:bike, primary_frame_color: color) } let(:bike_2) { FactoryBot.create(:bike, secondary_frame_color: color, tertiary_frame_color: color_2) } @@ -224,91 +224,91 @@ bike_3.secondary_frame_color_id, bike_1.tertiary_frame_color_id, bike_2.tertiary_frame_color_id, - bike_3.tertiary_frame_color_id + bike_3.tertiary_frame_color_id, ] end before do expect(all_color_ids.count(color.id)).to eq 3 # Each bike has color only once end - context 'single color' do - let(:query_params) { { colors: [color.id], stolenness: 'all' } } - it 'matches bikes with the given color' do + context "single color" do + let(:query_params) { { colors: [color.id], stolenness: "all" } } + it "matches bikes with the given color" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike_1.id, bike_2.id, bike_3.id]) end end - context 'second color' do - let(:query_params) { { colors: [color.id, color_2.id], stolenness: 'all' } } - it 'matches just the bike with both colors' do + context "second color" do + let(:query_params) { { colors: [color.id, color_2.id], stolenness: "all" } } + it "matches just the bike with both colors" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike_2.id]) end end - context 'and manufacturer_id' do - let(:query_params) { { colors: [color.id], manufacturer: manufacturer.id, stolenness: 'all' } } - it 'matches just the bike with the matching manufacturer' do + context "and manufacturer_id" do + let(:query_params) { { colors: [color.id], manufacturer: manufacturer.id, stolenness: "all" } } + it "matches just the bike with the matching manufacturer" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike_3.id]) end end end - context 'serial' do + context "serial" do before do expect(bike).to be_present end - context 'stood-ffer' do - let(:bike) { FactoryBot.create(:bike, serial_number: 'st00d-ffer') } - context 'full homoglyph match' do - let(:query_params) { { serial: 'STood ffer', stolenness: 'all' } } - it 'finds matching bikes' do + context "stood-ffer" do + let(:bike) { FactoryBot.create(:bike, serial_number: "st00d-ffer") } + context "full homoglyph match" do + let(:query_params) { { serial: "STood ffer", stolenness: "all" } } + it "finds matching bikes" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike.id]) end end - context 'partial homoglyph match' do - let(:query_params) { { serial: 'ST0oD', stolenness: 'all' } } - it 'finds matching bikes' do + context "partial homoglyph match" do + let(:query_params) { { serial: "ST0oD", stolenness: "all" } } + it "finds matching bikes" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike.id]) end end end - context 'reversed serial' do - let(:bike) { FactoryBot.create(:bike, serial_number: 'K10DY00047-bkd') } - let(:query_params) { { serial: 'bkd-K1oDYooo47', stolenness: 'all' } } - it 'fulls text search' do + context "reversed serial" do + let(:bike) { FactoryBot.create(:bike, serial_number: "K10DY00047-bkd") } + let(:query_params) { { serial: "bkd-K1oDYooo47", stolenness: "all" } } + it "fulls text search" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike.id]) end end end - context 'query' do - let(:bike) { FactoryBot.create(:bike, description: 'Booger') } + context "query" do + let(:bike) { FactoryBot.create(:bike, description: "Booger") } let(:bike_2) { FactoryBot.create(:bike) } - let(:query_params) { { query: 'booger', stolenness: 'all' } } + let(:query_params) { { query: "booger", stolenness: "all" } } before do expect([bike, bike_2].size).to eq 2 end - it 'selects matching the query' do + it "selects matching the query" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike.id]) end end - context 'stolenness' do - context 'non-proximity' do + context "stolenness" do + context "non-proximity" do let(:stolen_bike) { FactoryBot.create(:stolen_bike) } let(:non_stolen_bike) { FactoryBot.create(:bike) } before do expect([stolen_bike, non_stolen_bike].size).to eq 2 end - context 'stolen_search' do - let(:query_params) { { stolenness: 'stolen' } } - it 'only stolen bikes' do + context "stolen_search" do + let(:query_params) { { stolenness: "stolen" } } + it "only stolen bikes" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([stolen_bike.id]) end end - context 'non_stolen search' do - let(:query_params) { { stolenness: 'non' } } - it 'only non_stolen' do + context "non_stolen search" do + let(:query_params) { { stolenness: "non" } } + it "only non_stolen" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([non_stolen_bike.id]) end end - context 'all' do - let(:query_params) { { stolenness: 'all' } } - it 'returns all bikes' do + context "all" do + let(:query_params) { { stolenness: "all" } } + it "returns all bikes" do ids = Bike.search(interpreted_params).pluck(:id) expect(ids.count).to eq 2 expect(ids.include?(stolen_bike.id)).to be_truthy @@ -316,79 +316,79 @@ end end end - context 'proximity' do + context "proximity" do include_context :geocoder_default_location let(:bike_1) { FactoryBot.create(:stolen_bike, latitude: default_location[:latitude], longitude: default_location[:longitude]) } let(:stolen_record_1) { bike_1.find_current_stolen_record } let(:bike_2) { FactoryBot.create(:stolen_bike, latitude: 41.8961603, longitude: -87.677215) } let(:stolen_record_2) { bike_2.find_current_stolen_record } - let(:query_params) { { stolenness: 'proximity', location: 'New York, NY', distance: 200 } } + let(:query_params) { { stolenness: "proximity", location: "New York, NY", distance: 200 } } before do expect(bike_2.stolen_lat).to_not eq stolen_record_1[:latitude] end - it 'finds the bike where we want it to be' do + it "finds the bike where we want it to be" do expect(Bike.search(interpreted_params).pluck(:id)).to eq([bike_1.id]) end end end - describe 'scoped bike' do - context 'organization bike' do - let(:interpreted_params) { Bike.searchable_interpreted_params(query_params, ip: 'd') } + describe "scoped bike" do + context "organization bike" do + let(:interpreted_params) { Bike.searchable_interpreted_params(query_params, ip: "d") } let(:bike_1) { FactoryBot.create(:bike) } let(:bike_2) { FactoryBot.create(:organization_bike) } let(:organization) { bike_2.organizations.first } - let(:query_params) { { stolenness: 'all' } } + let(:query_params) { { stolenness: "all" } } before do expect([bike_1, bike_2].size).to eq 2 expect(organization.bikes.pluck(:id)).to eq([bike_2.id]) end - it 'only finds bikes in the organization' do + it "only finds bikes in the organization" do expect(organization.bikes.search(interpreted_params).pluck(:id)).to eq([bike_2.id]) end end end end - describe 'search_close_serials' do - let(:stolen_bike) { FactoryBot.create(:stolen_bike, serial_number: 'O|ILSZB-111JJJG8', manufacturer: manufacturer) } - let(:non_stolen_bike) { FactoryBot.create(:bike, serial_number: 'O|ILSZB-111JJJJJ') } + describe "search_close_serials" do + let(:stolen_bike) { FactoryBot.create(:stolen_bike, serial_number: "O|ILSZB-111JJJG8", manufacturer: manufacturer) } + let(:non_stolen_bike) { FactoryBot.create(:bike, serial_number: "O|ILSZB-111JJJJJ") } before do expect([non_stolen_bike, stolen_bike].size).to eq 2 end - context 'no serial param' do - let(:query_params) { { query_items: [manufacturer.search_id], stolenness: 'non' } } - it 'returns nil' do + context "no serial param" do + let(:query_params) { { query_items: [manufacturer.search_id], stolenness: "non" } } + it "returns nil" do expect(Bike.search_close_serials(interpreted_params)).to be_nil end end - context 'exact normalized serial' do - let(:query_params) { { serial: '11I528-111JJJJJ', stolenness: 'all' } } # Because drops leading zeros - it 'matches only non-exact' do + context "exact normalized serial" do + let(:query_params) { { serial: "11I528-111JJJJJ", stolenness: "all" } } # Because drops leading zeros + it "matches only non-exact" do expect(Bike.search_close_serials(interpreted_params).pluck(:id)).to eq([stolen_bike.id]) end end - context 'close serial with stolenness' do - let(:query_params) { { serial: '011I528-111JJJk', stolenness: 'non' } } - it 'returns matching stolenness' do + context "close serial with stolenness" do + let(:query_params) { { serial: "011I528-111JJJk", stolenness: "non" } } + it "returns matching stolenness" do expect(Bike.search_close_serials(interpreted_params).pluck(:id)).to eq([non_stolen_bike.id]) end end - context 'close serial with query items' do - let(:query_params) { { serial: '011I528-111JJJk', query_items: [manufacturer.search_id], stolenness: 'all' } } - it 'returns matching' do + context "close serial with query items" do + let(:query_params) { { serial: "011I528-111JJJk", query_items: [manufacturer.search_id], stolenness: "all" } } + it "returns matching" do expect(Bike.search_close_serials(interpreted_params).pluck(:id)).to eq([stolen_bike.id]) end end - context 'close serial on organization bikes' do + context "close serial on organization bikes" do let(:organization) { FactoryBot.create(:organization) } - let(:query_params) { { serial: '011I528-111JJJk', stolenness: 'all' } } + let(:query_params) { { serial: "011I528-111JJJk", stolenness: "all" } } before do FactoryBot.create(:bike_organization, bike: stolen_bike, organization: organization) stolen_bike.update_attribute :creation_organization_id, organization.id expect(organization.bikes.pluck(:id)).to eq([stolen_bike.id]) end - it 'returns matching stolenness' do + it "returns matching stolenness" do expect(organization.bikes.search_close_serials(interpreted_params).pluck(:id)).to eq([stolen_bike.id]) end end diff --git a/spec/support/shared_examples/friendly_name_findable.rb b/spec/support/shared_examples/friendly_name_findable.rb index 9756d4f716..e69c7b5106 100644 --- a/spec/support/shared_examples/friendly_name_findable.rb +++ b/spec/support/shared_examples/friendly_name_findable.rb @@ -1,21 +1,21 @@ -require 'spec_helper' +require "spec_helper" -RSpec.shared_examples 'friendly_name_findable' do +RSpec.shared_examples "friendly_name_findable" do let(:model_sym) { subject.class.name.underscore.to_sym } let(:instance) { FactoryBot.create model_sym } - describe 'friendly_find' do + describe "friendly_find" do before do expect(instance).to be_present end - context 'integer_slug' do - it 'finds by id' do + context "integer_slug" do + it "finds by id" do expect(subject.class.friendly_find(instance.id.to_s)).to eq instance end end - context 'not integer slug' do - it 'finds by the name' do + context "not integer slug" do + it "finds by the name" do expect(subject.class.friendly_find(" #{instance.name} ")).to eq instance end end diff --git a/spec/support/shared_examples/friendly_slug_findable.rb b/spec/support/shared_examples/friendly_slug_findable.rb index 4f8d986206..d11568be2f 100644 --- a/spec/support/shared_examples/friendly_slug_findable.rb +++ b/spec/support/shared_examples/friendly_slug_findable.rb @@ -1,56 +1,56 @@ -require 'spec_helper' +require "spec_helper" -RSpec.shared_examples 'friendly_slug_findable' do +RSpec.shared_examples "friendly_slug_findable" do let(:model_sym) { subject.class.name.underscore.to_sym } let(:instance) { FactoryBot.create model_sym } - describe 'callbacks' do - it 'calls set slug before create' do - obj = FactoryBot.build(model_sym, name: 'something cool and things&') + describe "callbacks" do + it "calls set slug before create" do + obj = FactoryBot.build(model_sym, name: "something cool and things&") expect(obj).to receive :set_slug obj.save end end - describe 'set_slug' do - context 'name' do - it 'slugs it' do - obj = FactoryBot.build(model_sym, name: 'something cool and things&') + describe "set_slug" do + context "name" do + it "slugs it" do + obj = FactoryBot.build(model_sym, name: "something cool and things&") obj.slug = nil obj.set_slug - expect(obj.slug).to eq Slugifyer.slugify('something cool and things&') + expect(obj.slug).to eq Slugifyer.slugify("something cool and things&") end end - context 'existing' do + context "existing" do it "doesn't overwrite" do obj = FactoryBot.build model_sym - obj.slug = 'something cool' + obj.slug = "something cool" obj.set_slug - expect(obj.slug).to eq 'something cool' + expect(obj.slug).to eq "something cool" end end end - describe 'to_param' do - it 'returns slug' do - subject.slug = 'cool slug name' - expect(subject.to_param).to eq 'cool slug name' + describe "to_param" do + it "returns slug" do + subject.slug = "cool slug name" + expect(subject.to_param).to eq "cool slug name" end end - describe 'friendly_find' do + describe "friendly_find" do before do expect(instance).to be_present end - context 'integer_slug' do - it 'finds by id' do + context "integer_slug" do + it "finds by id" do expect(subject.class.friendly_find(instance.id.to_s)).to eq instance end end - context 'non-integer slug' do - it 'finds by the slug' do + context "non-integer slug" do + it "finds by the slug" do expect(subject.class.friendly_find(" #{instance.name}")).to eq instance end end diff --git a/spec/uploaders/image_uploader_spec.rb b/spec/uploaders/image_uploader_spec.rb index ad8160ec19..f1e04df34f 100644 --- a/spec/uploaders/image_uploader_spec.rb +++ b/spec/uploaders/image_uploader_spec.rb @@ -1,5 +1,5 @@ -require 'spec_helper' -require 'carrierwave/test/matchers' +require "spec_helper" +require "carrierwave/test/matchers" describe ImageUploader do include CarrierWave::Test::Matchers @@ -17,19 +17,19 @@ # @uploader.remove! # end - context 'the small version' do - xit 'scales down a landscape image to be exactly 64 by 64 pixels' do + context "the small version" do + xit "scales down a landscape image to be exactly 64 by 64 pixels" do expect(@uploader.large).to be_no_larger_than(1200, 900) end end - context 'the small version' do - xit 'scales down a landscape image to fit within 200 by 200 pixels' do + context "the small version" do + xit "scales down a landscape image to fit within 200 by 200 pixels" do expect(@uploader.medium).to be_no_larger_than(700, 525) end end - context 'the small version' do - xit 'scales down a landscape image to fit within 200 by 200 pixels' do + context "the small version" do + xit "scales down a landscape image to fit within 200 by 200 pixels" do expect(@uploader.small).to have_dimensions(300, 300) end end diff --git a/spec/workers/additional_email_confirmation_worker_spec.rb b/spec/workers/additional_email_confirmation_worker_spec.rb index 8ca4b8eef6..4d8504ba7b 100644 --- a/spec/workers/additional_email_confirmation_worker_spec.rb +++ b/spec/workers/additional_email_confirmation_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe AdditionalEmailConfirmationWorker do it { is_expected.to be_processed_in :notify } - it 'sends a confirm your additional email, email' do + it "sends a confirm your additional email, email" do user_email = FactoryBot.create(:user_email) AdditionalEmailConfirmationWorker.new.perform(user_email.id) expect(ActionMailer::Base.deliveries.empty?).to be_falsey diff --git a/spec/workers/after_bike_save_worker_spec.rb b/spec/workers/after_bike_save_worker_spec.rb index 4671981dc5..97eee299ce 100644 --- a/spec/workers/after_bike_save_worker_spec.rb +++ b/spec/workers/after_bike_save_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe AfterBikeSaveWorker do let(:subject) { AfterBikeSaveWorker } @@ -9,9 +9,9 @@ expect(subject.sidekiq_options["queue"]).to eq "low_priority" end - describe 'enqueuing jobs' do + describe "enqueuing jobs" do let(:bike_id) { FactoryBot.create(:ownership, user_hidden: true).bike_id } - it 'enqueues the duplicate_bike_finder_worker' do + it "enqueues the duplicate_bike_finder_worker" do expect do instance.perform(bike_id) end.to change(DuplicateBikeFinderWorker.jobs, :size).by 1 @@ -48,7 +48,7 @@ let!(:b_param) do FactoryBot.create(:b_param, created_bike_id: bike.id, - params: { bike: { owner_email: bike.owner_email, external_image_urls: passed_external_image_urls } }) + params: { bike: { owner_email: bike.owner_email, external_image_urls: passed_external_image_urls } }) end it "creates and downloads the images" do expect do diff --git a/spec/workers/after_user_change_worker_spec.rb b/spec/workers/after_user_change_worker_spec.rb index 870b7cc29c..1faa6075b0 100644 --- a/spec/workers/after_user_change_worker_spec.rb +++ b/spec/workers/after_user_change_worker_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" describe AfterUserChangeWorker do - it 'Calls webhook runner for the user' do + it "Calls webhook runner for the user" do user = FactoryBot.create(:user) expect_any_instance_of(WebhookRunner).to receive(:after_user_update).with(user.id).once AfterUserChangeWorker.new.perform(user.id) diff --git a/spec/workers/after_user_create_worker_spec.rb b/spec/workers/after_user_create_worker_spec.rb index 9faa884ba9..988f9f9229 100644 --- a/spec/workers/after_user_create_worker_spec.rb +++ b/spec/workers/after_user_create_worker_spec.rb @@ -71,9 +71,9 @@ let!(:country) { Country.united_states } let!(:b_param) do FactoryBot.create(:b_param, - created_bike_id: bike.id, - creator: bike.creator, - params: { bike: { address: "Pier 15 The Embarcadero, 94111", phone: "(111) 222-3333" } }) + created_bike_id: bike.id, + creator: bike.creator, + params: { bike: { address: "Pier 15 The Embarcadero, 94111", phone: "(111) 222-3333" } }) end # We need to manually set the user in this ownership because otherwise rspec can't find it TODO: Rails 5 update maybe let(:ownership) { FactoryBot.create(:ownership, user: user, owner_email: "aftercreate@bikeindex.org") } diff --git a/spec/workers/approve_stolen_listing_worker_spec.rb b/spec/workers/approve_stolen_listing_worker_spec.rb index 9c55da6d88..3e0af7490c 100644 --- a/spec/workers/approve_stolen_listing_worker_spec.rb +++ b/spec/workers/approve_stolen_listing_worker_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require "spec_helper" describe ApproveStolenListingWorker do it { is_expected.to be_processed_in :notify } - it 'enqueues another awesome job' do + it "enqueues another awesome job" do bike = FactoryBot.create(:bike) ApproveStolenListingWorker.perform_async(bike.id) expect(ApproveStolenListingWorker).to have_enqueued_sidekiq_job(bike.id) end - it 'calls stolen twitterbot integration' do + it "calls stolen twitterbot integration" do expect_any_instance_of(StolenTwitterbotIntegration).to receive(:send_tweet).with(111) ApproveStolenListingWorker.new.perform(111) end diff --git a/spec/workers/autocomplete_loader_worker_spec.rb b/spec/workers/autocomplete_loader_worker_spec.rb index 9c5cc67f45..2297e75912 100644 --- a/spec/workers/autocomplete_loader_worker_spec.rb +++ b/spec/workers/autocomplete_loader_worker_spec.rb @@ -7,8 +7,8 @@ expect(subject.sidekiq_options["queue"]).to eq "high_priority" end - it 'calls passed arguments on autocomplete loader' do + it "calls passed arguments on autocomplete loader" do expect_any_instance_of(AutocompleteLoader).to receive(:party) - AutocompleteLoaderWorker.new.perform('party') + AutocompleteLoaderWorker.new.perform("party") end end diff --git a/spec/workers/bike_book_update_worker_spec.rb b/spec/workers/bike_book_update_worker_spec.rb index 8e2c352d34..03382f0ee4 100644 --- a/spec/workers/bike_book_update_worker_spec.rb +++ b/spec/workers/bike_book_update_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe BikeBookUpdateWorker do let(:subject) { BikeBookUpdateWorker } @@ -7,7 +7,7 @@ expect(subject.sidekiq_options["queue"]).to eq "high_priority" end - it 'enqueues listing ordering job' do + it "enqueues listing ordering job" do BikeBookUpdateWorker.perform_async expect(BikeBookUpdateWorker).to have_enqueued_sidekiq_job end @@ -18,31 +18,30 @@ end it "grabs the components and doesn't overwrite components nothing if the bike isn't on bikebook" do - manufacturer = FactoryBot.create(:manufacturer, name: 'SE Bikes') + manufacturer = FactoryBot.create(:manufacturer, name: "SE Bikes") bike = FactoryBot.create(:bike, - manufacturer_id: manufacturer.id, - year: 2014, - frame_model: 'Draft' - ) - ['fork', - 'crankset', - 'pedals', - 'chain', - 'wheel', - 'tire', - 'headset', - 'handlebar', - 'stem', - 'grips/tape', - 'saddle', - 'seatpost'].each { |name| FactoryBot.create(:ctype, name: name) } + manufacturer_id: manufacturer.id, + year: 2014, + frame_model: "Draft") + ["fork", + "crankset", + "pedals", + "chain", + "wheel", + "tire", + "headset", + "handlebar", + "stem", + "grips/tape", + "saddle", + "seatpost"].each { |name| FactoryBot.create(:ctype, name: name) } component1 = FactoryBot.create(:component, - bike: bike, ctype_id: Ctype.friendly_find('fork').id, - description: 'SE straight Leg Hi-Ten w/ Fender Mounts & Wide Tire Clearance') + bike: bike, ctype_id: Ctype.friendly_find("fork").id, + description: "SE straight Leg Hi-Ten w/ Fender Mounts & Wide Tire Clearance") expect(component1.is_stock).to be_falsey component2 = FactoryBot.create(:component, - bike: bike, ctype_id: Ctype.friendly_find('crankset').id, - description: 'Sweet cranks') + bike: bike, ctype_id: Ctype.friendly_find("crankset").id, + description: "Sweet cranks") BikeBookUpdateWorker.new.perform(bike.id) bike.reload expect(bike.components.count).to eq(14) diff --git a/spec/workers/bike_deleter_worker_spec.rb b/spec/workers/bike_deleter_worker_spec.rb index d17673cb6b..d124252504 100644 --- a/spec/workers/bike_deleter_worker_spec.rb +++ b/spec/workers/bike_deleter_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe BikeDeleterWorker do let(:subject) { BikeDeleterWorker } diff --git a/spec/workers/bulk_import_worker_spec.rb b/spec/workers/bulk_import_worker_spec.rb index c34abf2831..e26d597ef8 100644 --- a/spec/workers/bulk_import_worker_spec.rb +++ b/spec/workers/bulk_import_worker_spec.rb @@ -10,7 +10,7 @@ [ %w[manufacturer model year color owner_email serial_number], ["Trek", "Roscoe 8", "2019", "Green", "test@bikeindex.org", "xyz_test"], - ["Surly", "Midnight Special", "2018", "White", "test2@bikeindex.org", "example"] + ["Surly", "Midnight Special", "2018", "White", "test2@bikeindex.org", "example"], ] end let(:csv_lines) { sample_csv_lines } @@ -50,6 +50,7 @@ context "erroring" do let!(:color) { FactoryBot.create(:color, name: "White") } after { tempfile.close && tempfile.unlink } + def bike_matches_target(bike) expect(bike.manufacturer).to eq Manufacturer.other expect(bike.manufacturer_other).to eq "Surly" @@ -59,13 +60,14 @@ def bike_matches_target(bike) expect(bike.owner_email).to eq "test2@bikeindex.org" expect(bike.description).to eq "Midnight Special" end + context "valid bike and an invalid bike with substituted header" do let(:target_line_error) { [2, ["Owner email can't be blank"]] } let(:csv_lines) do [ "Product Description,Vendor,Brand,Color,Size,Serial Number,Customer Last Name,Customer First Name,Customer Email", '"Blah","Blah","Surly","","","XXXXX","","",""', - '"Midnight Special","","Surly","White","19","ZZZZ","","","test2@bikeindex.org"' + '"Midnight Special","","Surly","White","19","ZZZZ","","","test2@bikeindex.org"', ] end it "registers bike, adds row that is an error" do @@ -85,7 +87,7 @@ def bike_matches_target(bike) [ "Product Description,Vendor,Brand,Color,Size,Serial Number,Customer Last Name,Customer First Name,Customer Email", '"\"","\'","Surly","","","XXXXX","","","","', - '"Midnight Special","","Surly","White","19","ZZZZ","","","test2@bikeindex.org"' + '"Midnight Special","","Surly","White","19","ZZZZ","","","test2@bikeindex.org"', ] end it "stores error line, resumes post errored line successfully" do @@ -279,7 +281,7 @@ def bike_matches_target(bike) additional_registration: nil, user_name: nil, send_email: true, - creation_organization_id: nil + creation_organization_id: nil, } end describe "row_to_b_param_hash" do @@ -304,7 +306,7 @@ def bike_matches_target(bike) context "valid organization bike" do let(:organization) { FactoryBot.create(:organization_with_auto_user) } let!(:bulk_import) { FactoryBot.create(:bulk_import, organization: organization) } - let(:row) { { manufacturer: " Surly", serial_number: "na", color: nil, owner_email: "test2@bikeindex.org", year: "2018", model: "Midnight Special", cycle_type: 'tandem' } } + let(:row) { { manufacturer: " Surly", serial_number: "na", color: nil, owner_email: "test2@bikeindex.org", year: "2018", model: "Midnight Special", cycle_type: "tandem" } } it "registers a bike" do expect(organization.auto_user).to_not eq bulk_import.user expect(Bike.count).to eq 0 diff --git a/spec/workers/cache_all_stolen_worker_spec.rb b/spec/workers/cache_all_stolen_worker_spec.rb index 7b6674ec8c..2e5bb1f44a 100644 --- a/spec/workers/cache_all_stolen_worker_spec.rb +++ b/spec/workers/cache_all_stolen_worker_spec.rb @@ -1,28 +1,28 @@ -require 'spec_helper' +require "spec_helper" describe CacheAllStolenWorker do it { is_expected.to be_processed_in :carrierwave } - describe 'output_stolen' do - it 'creates a stolen cache' do + describe "output_stolen" do + it "creates a stolen cache" do FactoryBot.create(:stolen_bike) FileCacheMaintainer.redis.expire(FileCacheMaintainer.info_id, 0) CacheAllStolenWorker.new.perform tsv_record = FileCacheMaintainer.files.last - expect(tsv_record['filename']).to match 'all_stolen_cache.json' + expect(tsv_record["filename"]).to match "all_stolen_cache.json" end end - describe 'write_stolen' do - it 'outputs the correct stolen' do - FactoryBot.create(:stolen_bike, serial_number: 'party seri8al') + describe "write_stolen" do + it "outputs the correct stolen" do + FactoryBot.create(:stolen_bike, serial_number: "party seri8al") cache_all_stolen_worker = CacheAllStolenWorker.new cache_all_stolen_worker.write_stolen result = JSON.parse(File.read(cache_all_stolen_worker.tmp_path)) - expect(result['bikes'].count).to eq(1) - expect(result['bikes'][0]['serial']).to eq('party seri8al') + expect(result["bikes"].count).to eq(1) + expect(result["bikes"][0]["serial"]).to eq("party seri8al") bike_v2_serializer_keys = %w(id title serial manufacturer_name frame_model year frame_colors thumb large_img is_stock_img stolen stolen_location date_stolen frame_material handlebar_type) - expect(result['bikes'][0].keys).to eq bike_v2_serializer_keys + expect(result["bikes"][0].keys).to eq bike_v2_serializer_keys end end end diff --git a/spec/workers/duplicate_bike_finder_worker_spec.rb b/spec/workers/duplicate_bike_finder_worker_spec.rb index 6709c05352..d024cddd3a 100644 --- a/spec/workers/duplicate_bike_finder_worker_spec.rb +++ b/spec/workers/duplicate_bike_finder_worker_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe DuplicateBikeFinderWorker do - it 'takes a bike id and search for groups' do - bike1 = FactoryBot.create(:bike, serial_number: 'applejacks cereal') + it "takes a bike id and search for groups" do + bike1 = FactoryBot.create(:bike, serial_number: "applejacks cereal") bike1.create_normalized_serial_segments - bike2 = FactoryBot.create(:bike, serial_number: 'applejacks Funtimes') + bike2 = FactoryBot.create(:bike, serial_number: "applejacks Funtimes") bike2.create_normalized_serial_segments DuplicateBikeFinderWorker.new.perform(bike1.id) duplicate_group = bike1.normalized_serial_segments.first.duplicate_bike_group @@ -12,23 +12,23 @@ end it "doesn't create a duplicate if only one match" do - bike = FactoryBot.create(:bike, serial_number: 'applejacks') + bike = FactoryBot.create(:bike, serial_number: "applejacks") bike.create_normalized_serial_segments DuplicateBikeFinderWorker.new.perform(bike.id) expect(bike.normalized_serial_segments.first.duplicate_bike_group).to_not be_present end - it 'adds a bike to an existing duplicate bike group' do - bike1 = FactoryBot.create(:bike, serial_number: 'applejacks') + it "adds a bike to an existing duplicate bike group" do + bike1 = FactoryBot.create(:bike, serial_number: "applejacks") bike1.create_normalized_serial_segments - bike2 = FactoryBot.create(:bike, serial_number: 'applejacks') + bike2 = FactoryBot.create(:bike, serial_number: "applejacks") bike2.create_normalized_serial_segments t = Time.at(1441314105) duplicate_group = DuplicateBikeGroup.create(added_bike_at: t) expect(duplicate_group.added_bike_at).to eq(t) bike1.normalized_serial_segments.first.update_attribute :duplicate_bike_group_id, duplicate_group.id bike2.normalized_serial_segments.first.update_attribute :duplicate_bike_group_id, duplicate_group.id - bike3 = FactoryBot.create(:bike, serial_number: 'applejacks') + bike3 = FactoryBot.create(:bike, serial_number: "applejacks") bike3.create_normalized_serial_segments DuplicateBikeFinderWorker.new.perform(bike3.id) expect(bike3.normalized_serial_segments.first.duplicate_bike_group).to eq(duplicate_group) diff --git a/spec/workers/email_admin_contact_stolen_worker_spec.rb b/spec/workers/email_admin_contact_stolen_worker_spec.rb index 6fae5f4a0e..370b519da6 100644 --- a/spec/workers/email_admin_contact_stolen_worker_spec.rb +++ b/spec/workers/email_admin_contact_stolen_worker_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require "spec_helper" describe EmailAdminContactStolenWorker do it { is_expected.to be_processed_in :notify } - describe 'perform' do - it 'sends an email' do + describe "perform" do + it "sends an email" do stolen_record = FactoryBot.create(:stolen_record) FactoryBot.create(:ownership, bike: stolen_record.bike) customer_contact = FactoryBot.create(:customer_contact, bike: stolen_record.bike) diff --git a/spec/workers/email_confirmation_worker_spec.rb b/spec/workers/email_confirmation_worker_spec.rb index b8dfde3913..522aa1eb2f 100644 --- a/spec/workers/email_confirmation_worker_spec.rb +++ b/spec/workers/email_confirmation_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailConfirmationWorker do it { is_expected.to be_processed_in :notify } - it 'sends a welcome email' do + it "sends a welcome email" do user = FactoryBot.create(:user) EmailConfirmationWorker.new.perform(user.id) expect(ActionMailer::Base.deliveries.empty?).to be_falsey diff --git a/spec/workers/email_feedback_notification_worker_spec.rb b/spec/workers/email_feedback_notification_worker_spec.rb index e3690c83b7..d254deff7e 100644 --- a/spec/workers/email_feedback_notification_worker_spec.rb +++ b/spec/workers/email_feedback_notification_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailFeedbackNotificationWorker do it { is_expected.to be_processed_in :notify } - it 'sends an email' do + it "sends an email" do feedback = FactoryBot.create(:feedback) ActionMailer::Base.deliveries = [] EmailFeedbackNotificationWorker.new.perform(feedback.id) diff --git a/spec/workers/email_invoice_worker_spec.rb b/spec/workers/email_invoice_worker_spec.rb index 2f34b5dbac..bd832a1086 100644 --- a/spec/workers/email_invoice_worker_spec.rb +++ b/spec/workers/email_invoice_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailInvoiceWorker do it { is_expected.to be_processed_in :notify } - it 'sends an email' do + it "sends an email" do payment = FactoryBot.create(:payment) ActionMailer::Base.deliveries = [] EmailInvoiceWorker.new.perform(payment.id) diff --git a/spec/workers/email_lightspeed_notification_worker_spec.rb b/spec/workers/email_lightspeed_notification_worker_spec.rb index 926e8779fb..cb545ae0bc 100644 --- a/spec/workers/email_lightspeed_notification_worker_spec.rb +++ b/spec/workers/email_lightspeed_notification_worker_spec.rb @@ -1,11 +1,11 @@ -require 'spec_helper' +require "spec_helper" describe EmailLightspeedNotificationWorker do it { is_expected.to be_processed_in :notify } - it 'sends an email' do + it "sends an email" do organization = FactoryBot.create(:organization) - api_key = 'some key or something' + api_key = "some key or something" ActionMailer::Base.deliveries = [] EmailLightspeedNotificationWorker.new.perform(organization.id, api_key) expect(ActionMailer::Base.deliveries.empty?).to be_falsey diff --git a/spec/workers/email_no_admins_notification_worker_spec.rb b/spec/workers/email_no_admins_notification_worker_spec.rb index b9c3973d6f..96c607c243 100644 --- a/spec/workers/email_no_admins_notification_worker_spec.rb +++ b/spec/workers/email_no_admins_notification_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailNoAdminsNotificationWorker do it { is_expected.to be_processed_in :notify } - it 'sends an email' do + it "sends an email" do organization = FactoryBot.create(:organization) ActionMailer::Base.deliveries = [] EmailNoAdminsNotificationWorker.new.perform(organization.id) diff --git a/spec/workers/email_organization_invitation_worker_spec.rb b/spec/workers/email_organization_invitation_worker_spec.rb index 9362220dc1..9a5e6b0eaf 100644 --- a/spec/workers/email_organization_invitation_worker_spec.rb +++ b/spec/workers/email_organization_invitation_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailOrganizationInvitationWorker do it { is_expected.to be_processed_in :notify } - it 'sends an email' do + it "sends an email" do organization_invitation = FactoryBot.create(:organization_invitation) ActionMailer::Base.deliveries = [] EmailOrganizationInvitationWorker.new.perform(organization_invitation.id) diff --git a/spec/workers/email_ownership_invitation_worker_spec.rb b/spec/workers/email_ownership_invitation_worker_spec.rb index 236f29201c..1fd2c416e7 100644 --- a/spec/workers/email_ownership_invitation_worker_spec.rb +++ b/spec/workers/email_ownership_invitation_worker_spec.rb @@ -1,16 +1,16 @@ -require 'spec_helper' +require "spec_helper" describe EmailOwnershipInvitationWorker do it { is_expected.to be_processed_in :notify } - it 'sends an email' do + it "sends an email" do ownership = FactoryBot.create(:ownership) ActionMailer::Base.deliveries = [] EmailOwnershipInvitationWorker.new.perform(ownership.id) expect(ActionMailer::Base.deliveries).not_to be_empty end - it 'does not send an email if the ownership does not exist' do + it "does not send an email if the ownership does not exist" do ActionMailer::Base.deliveries = [] EmailOwnershipInvitationWorker.new.perform(129291912) expect(ActionMailer::Base.deliveries).to be_empty diff --git a/spec/workers/email_partial_registration_worker_spec.rb b/spec/workers/email_partial_registration_worker_spec.rb index d3710c2fd6..4f9cdc35b8 100644 --- a/spec/workers/email_partial_registration_worker_spec.rb +++ b/spec/workers/email_partial_registration_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailPartialRegistrationWorker do it { is_expected.to be_processed_in :notify } - it 'sends a partial registration email' do + it "sends a partial registration email" do b_param = FactoryBot.create(:b_param) EmailPartialRegistrationWorker.new.perform(b_param.id) expect(ActionMailer::Base.deliveries.empty?).to be_falsey diff --git a/spec/workers/email_recovered_from_link_worker_spec.rb b/spec/workers/email_recovered_from_link_worker_spec.rb index 3a00e612c3..3166168afd 100644 --- a/spec/workers/email_recovered_from_link_worker_spec.rb +++ b/spec/workers/email_recovered_from_link_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe EmailRecoveredFromLinkWorker do it { is_expected.to be_processed_in :notify } @@ -6,7 +6,7 @@ let(:stolen_record) { bike.current_stolen_record } before { stolen_record.add_recovery_information } - it 'sends a recovered from link email' do + it "sends a recovered from link email" do EmailRecoveredFromLinkWorker.new.perform(stolen_record.id) expect(ActionMailer::Base.deliveries.empty?).to be_falsey end diff --git a/spec/workers/email_reset_password_worker_spec.rb b/spec/workers/email_reset_password_worker_spec.rb index 86616bbb5b..1231adc466 100644 --- a/spec/workers/email_reset_password_worker_spec.rb +++ b/spec/workers/email_reset_password_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailResetPasswordWorker do it { is_expected.to be_processed_in :notify } - it 'sends a password_reset email' do + it "sends a password_reset email" do user = FactoryBot.create(:user) EmailResetPasswordWorker.new.perform(user.id) expect(ActionMailer::Base.deliveries.empty?).to be_falsey diff --git a/spec/workers/email_stolen_bike_alert_worker_spec.rb b/spec/workers/email_stolen_bike_alert_worker_spec.rb index 15736fdae9..ce6d54c0f5 100644 --- a/spec/workers/email_stolen_bike_alert_worker_spec.rb +++ b/spec/workers/email_stolen_bike_alert_worker_spec.rb @@ -1,22 +1,22 @@ -require 'spec_helper' +require "spec_helper" describe EmailStolenBikeAlertWorker do it { is_expected.to be_processed_in :notify } - describe 'perform' do - it 'sends an email' do + describe "perform" do + it "sends an email" do stolen_record = FactoryBot.create(:stolen_record) FactoryBot.create(:ownership, bike: stolen_record.bike) info_hash = { - notification_type: 'stolen_twitter_alerter', + notification_type: "stolen_twitter_alerter", bike_id: stolen_record.bike.id, tweet_id: 69, - tweet_string: 'STOLEN - something special', - tweet_account_screen_name: 'bikeindex', - tweet_account_name: 'Bike Index', - tweet_account_image: 'https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png', - location: 'Everywhere', - retweet_screen_names: ['someother_screename'] + tweet_string: "STOLEN - something special", + tweet_account_screen_name: "bikeindex", + tweet_account_name: "Bike Index", + tweet_account_image: "https://pbs.twimg.com/profile_images/3384343656/33893b31d39d69fb4b85912489c497b0_bigger.png", + location: "Everywhere", + retweet_screen_names: ["someother_screename"], } customer_contact = FactoryBot.create(:customer_contact, bike: stolen_record.bike, info_hash: info_hash) ActionMailer::Base.deliveries = [] @@ -24,7 +24,7 @@ expect(ActionMailer::Base.deliveries).not_to be_empty end - it 'does not send an email if the stolen bike has receive_notifications false' do + it "does not send an email if the stolen bike has receive_notifications false" do stolen_record = FactoryBot.create(:stolen_record, receive_notifications: false) stolen_record.bike.update_attribute :stolen, true customer_contact = FactoryBot.create(:customer_contact, bike: stolen_record.bike) diff --git a/spec/workers/email_stolen_notification_worker_spec.rb b/spec/workers/email_stolen_notification_worker_spec.rb index c149f60eb7..56b1928146 100644 --- a/spec/workers/email_stolen_notification_worker_spec.rb +++ b/spec/workers/email_stolen_notification_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe EmailStolenNotificationWorker do let(:subject) { EmailStolenNotificationWorker } @@ -22,7 +22,7 @@ def expect_notification_sent(override_email = nil) expect(ActionMailer::Base.deliveries.empty?).to be_falsey mail = ActionMailer::Base.deliveries.last expect(mail.subject).to eq("Stolen bike contact") - expect(mail.to).to eq([override_email || owner_email, 'lily@bikeindex.org', 'bryan@bikeindex.org']) + expect(mail.to).to eq([override_email || owner_email, "lily@bikeindex.org", "bryan@bikeindex.org"]) end def expect_notification_blocked diff --git a/spec/workers/email_updated_terms_worker_spec.rb b/spec/workers/email_updated_terms_worker_spec.rb index 136965d3a8..7044a7a940 100644 --- a/spec/workers/email_updated_terms_worker_spec.rb +++ b/spec/workers/email_updated_terms_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe EmailUpdatedTermsWorker do let(:user) { FactoryBot.create(:organization_member) } @@ -8,8 +8,8 @@ ActionMailer::Base.deliveries = [] end - context 'user id enqueued' do - it 'sends the updated email' do + context "user id enqueued" do + it "sends the updated email" do subject.redis.lpush(subject.enqueued_emails_key, user.id) subject.perform @@ -18,8 +18,8 @@ end end - context 'user id not enqueued' do - it 'does not send the updated email' do + context "user id not enqueued" do + it "does not send the updated email" do # Ensure we have an empty list subject.redis.lpush(subject.enqueued_emails_key, 1) subject.redis.lpop(subject.enqueued_emails_key) @@ -29,11 +29,11 @@ end end - context 'Mailer errors' do - it 'pushes the email key back on the updated email' do + context "Mailer errors" do + it "pushes the email key back on the updated email" do subject.redis.lpush(subject.enqueued_emails_key, user.id) - allow(CustomerMailer).to receive(:updated_terms_email).and_raise('boom') - expect { subject.perform }.to raise_error('boom') + allow(CustomerMailer).to receive(:updated_terms_email).and_raise("boom") + expect { subject.perform }.to raise_error("boom") expect(ActionMailer::Base.deliveries.empty?).to be_truthy expect(subject.redis.llen(subject.enqueued_emails_key)).to eq 1 @@ -41,8 +41,8 @@ end end - context 'user not found' do - it 'removes from the redis list' do + context "user not found" do + it "removes from the redis list" do subject.redis.lpush(subject.enqueued_emails_key, 42) subject.perform diff --git a/spec/workers/email_welcome_worker_spec.rb b/spec/workers/email_welcome_worker_spec.rb index 2005d0f208..e781f89057 100644 --- a/spec/workers/email_welcome_worker_spec.rb +++ b/spec/workers/email_welcome_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe EmailWelcomeWorker do it { is_expected.to be_processed_in :notify } - it 'enqueues listing ordering job' do + it "enqueues listing ordering job" do user = FactoryBot.create(:user) EmailWelcomeWorker.new.perform(user.id) expect(ActionMailer::Base.deliveries.empty?).to be_falsey diff --git a/spec/workers/get_manufacturer_logo_worker_spec.rb b/spec/workers/get_manufacturer_logo_worker_spec.rb index 45eaa8d61c..ddd9ddfdfb 100644 --- a/spec/workers/get_manufacturer_logo_worker_spec.rb +++ b/spec/workers/get_manufacturer_logo_worker_spec.rb @@ -1,37 +1,37 @@ -require 'spec_helper' +require "spec_helper" describe GetManufacturerLogoWorker do - it 'enqueues listing ordering job' do + it "enqueues listing ordering job" do GetManufacturerLogoWorker.perform_async expect(GetManufacturerLogoWorker).to have_enqueued_sidekiq_job end # Test is failing inexplicably - http://logo.clearbit.com/trekbikes.com?size=400 still works # Since it degrades nicely and isn't required, just ignoring - xit 'Adds a logo, sets source' do - manufacturer = FactoryBot.create(:manufacturer, website: 'https://trekbikes.com') + xit "Adds a logo, sets source" do + manufacturer = FactoryBot.create(:manufacturer, website: "https://trekbikes.com") GetManufacturerLogoWorker.new.perform(manufacturer.id) manufacturer.reload expect(manufacturer.logo).to be_present - expect(manufacturer.logo_source).to eq('Clearbit') + expect(manufacturer.logo_source).to eq("Clearbit") end it "Doesn't break if no logo present" do - manufacturer = FactoryBot.create(:manufacturer, website: 'bbbbbbbbbbbbbbsafasds.net') + manufacturer = FactoryBot.create(:manufacturer, website: "bbbbbbbbbbbbbbsafasds.net") GetManufacturerLogoWorker.new.perform(manufacturer.id) manufacturer.reload expect(manufacturer.logo).to_not be_present expect(manufacturer.logo_source).to be_nil end - it 'returns true if no website present' do + it "returns true if no website present" do manufacturer = FactoryBot.create(:manufacturer) expect(GetManufacturerLogoWorker.new.perform(manufacturer.id)).to be_truthy end - it 'returns true if no website present' do - local_image = File.open(File.join(Rails.root, 'spec', 'fixtures', 'bike.jpg')) - manufacturer = FactoryBot.create(:manufacturer, logo: local_image, website: 'http://example.com') + it "returns true if no website present" do + local_image = File.open(File.join(Rails.root, "spec", "fixtures", "bike.jpg")) + manufacturer = FactoryBot.create(:manufacturer, logo: local_image, website: "http://example.com") expect(manufacturer.logo).to be_present expect(GetManufacturerLogoWorker.new.perform(manufacturer.id)).to be_truthy end diff --git a/spec/workers/image_associator_worker_spec.rb b/spec/workers/image_associator_worker_spec.rb index 90f612ff68..a7198cd4a6 100644 --- a/spec/workers/image_associator_worker_spec.rb +++ b/spec/workers/image_associator_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe ImageAssociatorWorker do let(:subject) { ImageAssociatorWorker } @@ -7,7 +7,7 @@ expect(subject.sidekiq_options["queue"]).to eq "high_priority" end - it 'enqueues another awesome job' do + it "enqueues another awesome job" do ImageAssociatorWorker.perform_async expect(ImageAssociatorWorker).to have_enqueued_sidekiq_job end diff --git a/spec/workers/listicle_image_size_worker_spec.rb b/spec/workers/listicle_image_size_worker_spec.rb index 1adeae27b8..9f57403c14 100644 --- a/spec/workers/listicle_image_size_worker_spec.rb +++ b/spec/workers/listicle_image_size_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe ListicleImageSizeWorker do it { is_expected.to be_processed_in :carrierwave } - it 'enqueues another awesome job' do + it "enqueues another awesome job" do ListicleImageSizeWorker.perform_async expect(ListicleImageSizeWorker).to have_enqueued_sidekiq_job end diff --git a/spec/workers/merge_additional_email_worker_spec.rb b/spec/workers/merge_additional_email_worker_spec.rb index 94040eb23f..ef6e9421f8 100644 --- a/spec/workers/merge_additional_email_worker_spec.rb +++ b/spec/workers/merge_additional_email_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe MergeAdditionalEmailWorker do let(:subject) { MergeAdditionalEmailWorker } @@ -7,14 +7,14 @@ expect(subject.sidekiq_options["queue"]).to eq "high_priority" end - context 'confirmed' do - let(:email) { 'FOO@barexample.com' } + context "confirmed" do + let(:email) { "FOO@barexample.com" } let(:ownership) { FactoryBot.create(:ownership, owner_email: email) } let(:user_email) { FactoryBot.create(:user_email, email: email) } let(:user) { user_email.user } let(:organization_invitation) { FactoryBot.create(:organization_invitation, invitee_email: "#{email.upcase} ") } - context 'existing user account' do + context "existing user account" do let(:bike) { FactoryBot.create(:bike, creator_id: old_user.id) } let(:old_user) { FactoryBot.create(:user_confirmed, email: email) } let(:pre_created_ownership) { FactoryBot.create(:ownership, creator_id: old_user.id) } @@ -27,12 +27,12 @@ let(:old_membership) { FactoryBot.create(:membership, user: old_user, organization: third_organization) } let(:new_membership) { FactoryBot.create(:membership, user: user, organization: third_organization) } - let(:integration) { FactoryBot.create(:integration, user: old_user, information: { 'info' => { 'email' => email, name: 'blargh' } }) } + let(:integration) { FactoryBot.create(:integration, user: old_user, information: { "info" => { "email" => email, name: "blargh" } }) } let(:lock) { FactoryBot.create(:lock, user: old_user) } let(:payment) { FactoryBot.create(:payment, user: old_user) } let(:customer_contact) { FactoryBot.create(:customer_contact, user: old_user, creator: old_user) } let(:stolen_notification) { FactoryBot.create(:stolen_notification, sender: old_user, receiver: old_user) } - let(:oauth_application) { Doorkeeper::Application.create(name: 'MyApp', redirect_uri: 'https://app.com') } + let(:oauth_application) { Doorkeeper::Application.create(name: "MyApp", redirect_uri: "https://app.com") } before do old_user.reload expect(ownership).to be_present @@ -55,7 +55,7 @@ expect(stolen_notification).to be_present end - it 'merges bikes and memberships and deletes user' do + it "merges bikes and memberships and deletes user" do user.reload expect(user.memberships.count).to eq 1 expect(user.ownerships.count).to eq 0 @@ -99,19 +99,19 @@ end end - context 'existing multi-user-account' do - it 'merges all the accounts. It does not create multiple memberships for one org' + context "existing multi-user-account" do + it "merges all the accounts. It does not create multiple memberships for one org" # It would be nice to test this... future todo end - context 'no existing user account' do + context "no existing user account" do before do expect(ownership).to be_present expect(organization_invitation).to be_present expect(user_email.confirmed).to be_truthy end - it 'runs the same things as user_create' do + it "runs the same things as user_create" do user.reload expect(user.memberships.count).to eq 0 expect(user.ownerships.count).to eq 0 @@ -127,10 +127,10 @@ end end - context 'unconfirmed' do + context "unconfirmed" do it "doesn't merge" do ownership = FactoryBot.create(:ownership) - user_email = FactoryBot.create(:user_email, email: ownership.owner_email, confirmation_token: 'token-stuff') + user_email = FactoryBot.create(:user_email, email: ownership.owner_email, confirmation_token: "token-stuff") expect(user_email.confirmed).to be_falsey MergeAdditionalEmailWorker.new.perform(user_email.id) user_email.reload diff --git a/spec/workers/organization_export_worker_spec.rb b/spec/workers/organization_export_worker_spec.rb index 2464f6c766..5622bd9eca 100644 --- a/spec/workers/organization_export_worker_spec.rb +++ b/spec/workers/organization_export_worker_spec.rb @@ -16,7 +16,7 @@ nil, "Black", bike.serial_number, - nil + nil, ] end let(:csv_string) { csv_lines.map { |r| instance.comma_wrapped_string(r) }.join } @@ -64,7 +64,7 @@ # We modify the headers during processing to separate the address into multiple fields [ %w[owner_name address city state zipcode sticker], - ["Maya Skripal", "102 Washington Pl", "State College", "PA", "16801", "A1111"] + ["Maya Skripal", "102 Washington Pl", "State College", "PA", "16801", "A1111"], ] end let!(:bike_code) { FactoryBot.create(:bike_code, organization: organization, code: "a1111") } @@ -147,7 +147,7 @@ nil, email, "George Smith", - "George Smith" # Because of user_name_with_fallback + "George Smith", # Because of user_name_with_fallback ] end let(:target_csv_line) { "\"http://test.host/bikes/#{bike.id}\",\"#{bike.created_at.utc}\",\"Sweet manufacturer <><>>\",\"\\\",,,\\\"\",\"Black, #{secondary_color.name}\",\"#{bike.serial_number}\",\"\",\"\",\"\",\"\",\"#{email}\",\"George Smith\",\"George Smith\"" } @@ -174,7 +174,7 @@ "San Francisco", "CA", "94103", - "" + "", ] end let(:export) { FactoryBot.create(:export_organization, progress: "pending", file: nil, options: { headers: %w[owner_name_or_email link phone additional_registration_number registration_address], bike_code_start: "8z" }) } diff --git a/spec/workers/remove_expired_file_cache_worker_spec.rb b/spec/workers/remove_expired_file_cache_worker_spec.rb index 470790d972..c10f09b54d 100644 --- a/spec/workers/remove_expired_file_cache_worker_spec.rb +++ b/spec/workers/remove_expired_file_cache_worker_spec.rb @@ -1,17 +1,17 @@ -require 'spec_helper' +require "spec_helper" describe RemoveExpiredFileCacheWorker do it { is_expected.to be_processed_in :carrierwave } - describe 'perform' do - it 'removes expired files' do + describe "perform" do + it "removes expired files" do t = (Time.now - 3.days).to_i FileCacheMaintainer.reset_file_info("#{t}_all_stolen_cache.json", t) - FileCacheMaintainer.update_file_info('current_stolen_bikes.tsv') + FileCacheMaintainer.update_file_info("current_stolen_bikes.tsv") expect(FileCacheMaintainer.files.count).to eq 2 RemoveExpiredFileCacheWorker.new.perform expect(FileCacheMaintainer.files.count).to eq 1 - expect(FileCacheMaintainer.files.first['filename']).to eq 'current_stolen_bikes.tsv' + expect(FileCacheMaintainer.files.first["filename"]).to eq "current_stolen_bikes.tsv" end end end diff --git a/spec/workers/send_newsletter_worker_spec.rb b/spec/workers/send_newsletter_worker_spec.rb index ddf68371bc..64e36b9a5d 100644 --- a/spec/workers/send_newsletter_worker_spec.rb +++ b/spec/workers/send_newsletter_worker_spec.rb @@ -1,25 +1,25 @@ -require 'spec_helper' +require "spec_helper" describe SendNewsletterWorker do it { is_expected.to be_processed_in :notify } let(:subject) { SendNewsletterWorker } let(:instance) { subject.new } - context 'no id passed' do + context "no id passed" do let(:user) { FactoryBot.create(:user_confirmed, notification_newsletters: true, banned: false) } let(:user_unemailable) { FactoryBot.create(:user_confirmed, notification_newsletters: false) } let(:user_banned) { FactoryBot.create(:user_confirmed, notification_newsletters: true, banned: true) } let(:user_unconfirmed) { FactoryBot.create(:user, notification_newsletters: true, banned: false) } - it 'enqueues sending to emails' do + it "enqueues sending to emails" do expect([user.id, user_unemailable.id, user_banned.id, user_unconfirmed.id].count).to eq 4 expect(user.confirmed).to be_truthy expect(user.notification_newsletters).to be_truthy Sidekiq::Worker.clear_all Sidekiq::Testing.fake! do expect do - instance.perform('template_id') + instance.perform("template_id") end.to change(subject.jobs, :count).by 1 - expect(subject.jobs.map { |j| j['args'] }.uniq.flatten).to eq(['template_id', user.id]) + expect(subject.jobs.map { |j| j["args"] }.uniq.flatten).to eq(["template_id", user.id]) end end end diff --git a/spec/workers/tsv_creator_worker_spec.rb b/spec/workers/tsv_creator_worker_spec.rb index 01c3c8c537..b548d48cc2 100644 --- a/spec/workers/tsv_creator_worker_spec.rb +++ b/spec/workers/tsv_creator_worker_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' +require "spec_helper" describe TsvCreatorWorker do it { is_expected.to be_processed_in :carrierwave } - it 'enqueues another awesome job' do + it "enqueues another awesome job" do TsvCreatorWorker.perform_async expect(TsvCreatorWorker).to have_enqueued_sidekiq_job end @@ -11,6 +11,6 @@ it "sends tsv creator the method it's passed" do expect_any_instance_of(TsvCreator).to receive(:create_stolen).with(true).and_return(true) expect_any_instance_of(TsvCreator).to receive(:create_stolen).with(false).and_return(true) - TsvCreatorWorker.new.perform('create_stolen', true) + TsvCreatorWorker.new.perform("create_stolen", true) end end diff --git a/spec/workers/unused_ownership_removal_worker_spec.rb b/spec/workers/unused_ownership_removal_worker_spec.rb index 9bbab2f1ed..0f2487a0e9 100644 --- a/spec/workers/unused_ownership_removal_worker_spec.rb +++ b/spec/workers/unused_ownership_removal_worker_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require "spec_helper" describe UnusedOwnershipRemovalWorker do - it 'enqueues listing ordering job' do + it "enqueues listing ordering job" do UnusedOwnershipRemovalWorker.perform_async expect(UnusedOwnershipRemovalWorker).to have_enqueued_sidekiq_job end - it 'makes non existent ownerships not current' do - ownership = Ownership.create(owner_email: 'something@d.com', creator_id: 69, bike_id: 69, current: true) + it "makes non existent ownerships not current" do + ownership = Ownership.create(owner_email: "something@d.com", creator_id: 69, bike_id: 69, current: true) UnusedOwnershipRemovalWorker.new.perform(ownership.id) expect(ownership.reload.current).to be_falsey end diff --git a/spec/workers/update_auth_token_worker_spec.rb b/spec/workers/update_auth_token_worker_spec.rb index d09673f5ff..e947e5ebca 100644 --- a/spec/workers/update_auth_token_worker_spec.rb +++ b/spec/workers/update_auth_token_worker_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require "spec_helper" describe UpdateAuthTokenWorker do let(:subject) { UpdateAuthTokenWorker } @@ -7,7 +7,7 @@ expect(subject.sidekiq_options["queue"]).to eq "high_priority" end - it 'updates the auth token' do + it "updates the auth token" do user = FactoryBot.create(:user) old_t = user.auth_token UpdateAuthTokenWorker.new.perform(user.id)