diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1a572b5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+!.keep
+*.DS_Store
+*.swo
+*.swp
+/.bundle
+/.env
+/.foreman
+/coverage/*
+/db/*.sqlite3
+/log/*
+/public/system
+/public/assets
+/tags
+/tmp/*
diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..83e16f8
--- /dev/null
+++ b/.rspec
@@ -0,0 +1,2 @@
+--color
+--require spec_helper
diff --git a/.ruby-version b/.ruby-version
new file mode 100644
index 0000000..b1b25a5
--- /dev/null
+++ b/.ruby-version
@@ -0,0 +1 @@
+2.2.2
diff --git a/.sample.env b/.sample.env
new file mode 100644
index 0000000..69f32de
--- /dev/null
+++ b/.sample.env
@@ -0,0 +1,6 @@
+# http://ddollar.github.com/foreman/
+ASSET_HOST=localhost:3000
+HOST=localhost:3000
+RACK_ENV=development
+SECRET_KEY_BASE=development_secret
+EXECJS_RUNTIME=Node
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..7c1a081
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,21 @@
+before_install:
+ - "echo '--colour' > ~/.rspec"
+ - "echo 'gem: --no-document' > ~/.gemrc"
+ - export DISPLAY=:99.0
+ - sh -e /etc/init.d/xvfb start
+install:
+ - bin/setup
+branches:
+ only:
+ - master
+cache:
+ - bundler
+language:
+ - ruby
+notifications:
+ email: false
+rvm:
+ - 2.2.2
+addons:
+ postgresql: "9.3"
+sudo: false
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..95c9ae5
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,59 @@
+source "https://rubygems.org"
+
+ruby "2.2.2"
+
+gem "airbrake"
+gem "autoprefixer-rails"
+gem "bourbon", "~> 4.2.0"
+gem "coffee-rails", "~> 4.1.0"
+gem "delayed_job_active_record"
+gem "email_validator"
+gem "flutie"
+gem "high_voltage"
+gem "i18n-tasks"
+gem "jquery-rails"
+gem "neat", "~> 1.7.0"
+gem "newrelic_rpm", ">= 3.9.8"
+gem "normalize-rails", "~> 3.0.0"
+gem "pg"
+gem "rack-canonical-host"
+gem "rails", "4.2.1"
+gem "recipient_interceptor"
+gem "refills"
+gem "sass-rails", "~> 5.0"
+gem "simple_form"
+gem "title"
+gem "uglifier"
+gem "unicorn"
+
+group :development do
+ gem "spring"
+ gem "spring-commands-rspec"
+ gem "web-console"
+end
+
+group :development, :test do
+ gem "awesome_print"
+ gem "bundler-audit", require: false
+ gem "byebug"
+ gem "dotenv-rails"
+ gem "factory_girl_rails"
+ gem "pry-rails"
+ gem "rspec-rails", "~> 3.1.0"
+end
+
+group :test do
+ gem "capybara-webkit", ">= 1.2.0"
+ gem "database_cleaner"
+ gem "formulaic"
+ gem "launchy"
+ gem "shoulda-matchers", require: false
+ gem "simplecov", require: false
+ gem "timecop"
+ gem "webmock"
+end
+
+group :staging, :production do
+ gem "rails_stdout_logging"
+ gem "rack-timeout"
+end
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..1cdfdda
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,315 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ actionmailer (4.2.1)
+ actionpack (= 4.2.1)
+ actionview (= 4.2.1)
+ activejob (= 4.2.1)
+ mail (~> 2.5, >= 2.5.4)
+ rails-dom-testing (~> 1.0, >= 1.0.5)
+ actionpack (4.2.1)
+ actionview (= 4.2.1)
+ activesupport (= 4.2.1)
+ rack (~> 1.6)
+ rack-test (~> 0.6.2)
+ rails-dom-testing (~> 1.0, >= 1.0.5)
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
+ actionview (4.2.1)
+ activesupport (= 4.2.1)
+ builder (~> 3.1)
+ erubis (~> 2.7.0)
+ rails-dom-testing (~> 1.0, >= 1.0.5)
+ rails-html-sanitizer (~> 1.0, >= 1.0.1)
+ activejob (4.2.1)
+ activesupport (= 4.2.1)
+ globalid (>= 0.3.0)
+ activemodel (4.2.1)
+ activesupport (= 4.2.1)
+ builder (~> 3.1)
+ activerecord (4.2.1)
+ activemodel (= 4.2.1)
+ activesupport (= 4.2.1)
+ arel (~> 6.0)
+ activesupport (4.2.1)
+ i18n (~> 0.7)
+ json (~> 1.7, >= 1.7.7)
+ minitest (~> 5.1)
+ thread_safe (~> 0.3, >= 0.3.4)
+ tzinfo (~> 1.1)
+ addressable (2.3.8)
+ airbrake (4.2.1)
+ builder
+ multi_json
+ arel (6.0.0)
+ autoprefixer-rails (5.2.0)
+ execjs
+ json
+ awesome_print (1.6.1)
+ binding_of_caller (0.7.2)
+ debug_inspector (>= 0.0.1)
+ bourbon (4.2.3)
+ sass (~> 3.4)
+ thor
+ builder (3.2.2)
+ bundler-audit (0.3.1)
+ bundler (~> 1.2)
+ thor (~> 0.18)
+ byebug (5.0.0)
+ columnize (= 0.9.0)
+ capybara (2.4.4)
+ mime-types (>= 1.16)
+ nokogiri (>= 1.3.3)
+ rack (>= 1.0.0)
+ rack-test (>= 0.5.4)
+ xpath (~> 2.0)
+ capybara-webkit (1.5.2)
+ capybara (>= 2.3.0, < 2.5.0)
+ json
+ coderay (1.1.0)
+ coffee-rails (4.1.0)
+ coffee-script (>= 2.2.0)
+ railties (>= 4.0.0, < 5.0)
+ coffee-script (2.4.1)
+ coffee-script-source
+ execjs
+ coffee-script-source (1.9.1.1)
+ columnize (0.9.0)
+ crack (0.4.2)
+ safe_yaml (~> 1.0.0)
+ database_cleaner (1.4.1)
+ debug_inspector (0.0.2)
+ delayed_job (4.0.6)
+ activesupport (>= 3.0, < 5.0)
+ delayed_job_active_record (4.0.3)
+ activerecord (>= 3.0, < 5.0)
+ delayed_job (>= 3.0, < 4.1)
+ diff-lcs (1.2.5)
+ docile (1.1.5)
+ dotenv (2.0.1)
+ dotenv-rails (2.0.1)
+ dotenv (= 2.0.1)
+ easy_translate (0.5.0)
+ json
+ thread
+ thread_safe
+ email_validator (1.6.0)
+ activemodel
+ erubis (2.7.0)
+ execjs (2.5.2)
+ factory_girl (4.5.0)
+ activesupport (>= 3.0.0)
+ factory_girl_rails (4.5.0)
+ factory_girl (~> 4.5.0)
+ railties (>= 3.0.0)
+ flutie (2.0.0)
+ formulaic (0.2.0)
+ activesupport
+ capybara
+ i18n
+ globalid (0.3.5)
+ activesupport (>= 4.1.0)
+ high_voltage (2.3.0)
+ highline (1.7.2)
+ i18n (0.7.0)
+ i18n-tasks (0.8.3)
+ activesupport
+ easy_translate (>= 0.5.0)
+ erubis
+ highline
+ i18n
+ term-ansicolor
+ terminal-table
+ jquery-rails (4.0.3)
+ rails-dom-testing (~> 1.0)
+ railties (>= 4.2.0)
+ thor (>= 0.14, < 2.0)
+ json (1.8.3)
+ kgio (2.9.3)
+ launchy (2.4.3)
+ addressable (~> 2.3)
+ loofah (2.0.2)
+ nokogiri (>= 1.5.9)
+ mail (2.6.3)
+ mime-types (>= 1.16, < 3)
+ method_source (0.8.2)
+ mime-types (2.6.1)
+ mini_portile (0.6.2)
+ minitest (5.7.0)
+ multi_json (1.11.0)
+ neat (1.7.2)
+ bourbon (>= 4.0)
+ sass (>= 3.3)
+ newrelic_rpm (3.12.0.288)
+ nokogiri (1.6.6.2)
+ mini_portile (~> 0.6.0)
+ normalize-rails (3.0.3)
+ pg (0.18.2)
+ pry (0.10.1)
+ coderay (~> 1.1.0)
+ method_source (~> 0.8.1)
+ slop (~> 3.4)
+ pry-rails (0.3.4)
+ pry (>= 0.9.10)
+ rack (1.6.1)
+ rack-canonical-host (0.1.0)
+ addressable
+ rack (~> 1.0)
+ rack-test (0.6.3)
+ rack (>= 1.0)
+ rack-timeout (0.2.4)
+ rails (4.2.1)
+ actionmailer (= 4.2.1)
+ actionpack (= 4.2.1)
+ actionview (= 4.2.1)
+ activejob (= 4.2.1)
+ activemodel (= 4.2.1)
+ activerecord (= 4.2.1)
+ activesupport (= 4.2.1)
+ bundler (>= 1.3.0, < 2.0)
+ railties (= 4.2.1)
+ sprockets-rails
+ rails-deprecated_sanitizer (1.0.3)
+ activesupport (>= 4.2.0.alpha)
+ rails-dom-testing (1.0.6)
+ activesupport (>= 4.2.0.beta, < 5.0)
+ nokogiri (~> 1.6.0)
+ rails-deprecated_sanitizer (>= 1.0.1)
+ rails-html-sanitizer (1.0.2)
+ loofah (~> 2.0)
+ rails_stdout_logging (0.0.3)
+ railties (4.2.1)
+ actionpack (= 4.2.1)
+ activesupport (= 4.2.1)
+ rake (>= 0.8.7)
+ thor (>= 0.18.1, < 2.0)
+ raindrops (0.13.0)
+ rake (10.4.2)
+ recipient_interceptor (0.1.2)
+ mail
+ refills (0.1.0)
+ rspec-core (3.1.7)
+ rspec-support (~> 3.1.0)
+ rspec-expectations (3.1.2)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.1.0)
+ rspec-mocks (3.1.3)
+ rspec-support (~> 3.1.0)
+ rspec-rails (3.1.0)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ railties (>= 3.0)
+ rspec-core (~> 3.1.0)
+ rspec-expectations (~> 3.1.0)
+ rspec-mocks (~> 3.1.0)
+ rspec-support (~> 3.1.0)
+ rspec-support (3.1.2)
+ safe_yaml (1.0.4)
+ sass (3.4.14)
+ sass-rails (5.0.3)
+ railties (>= 4.0.0, < 5.0)
+ sass (~> 3.1)
+ sprockets (>= 2.8, < 4.0)
+ sprockets-rails (>= 2.0, < 4.0)
+ tilt (~> 1.1)
+ shoulda-matchers (2.8.0)
+ activesupport (>= 3.0.0)
+ simple_form (3.1.0)
+ actionpack (~> 4.0)
+ activemodel (~> 4.0)
+ simplecov (0.10.0)
+ docile (~> 1.1.0)
+ json (~> 1.8)
+ simplecov-html (~> 0.10.0)
+ simplecov-html (0.10.0)
+ slop (3.6.0)
+ spring (1.3.6)
+ spring-commands-rspec (1.0.4)
+ spring (>= 0.9.1)
+ sprockets (3.2.0)
+ rack (~> 1.0)
+ sprockets-rails (2.3.1)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ sprockets (>= 2.8, < 4.0)
+ term-ansicolor (1.3.0)
+ tins (~> 1.0)
+ terminal-table (1.4.5)
+ thor (0.19.1)
+ thread (0.2.0)
+ thread_safe (0.3.5)
+ tilt (1.4.1)
+ timecop (0.7.4)
+ tins (1.5.2)
+ title (0.0.5)
+ i18n
+ rails (>= 3.1)
+ tzinfo (1.2.2)
+ thread_safe (~> 0.1)
+ uglifier (2.7.1)
+ execjs (>= 0.3.0)
+ json (>= 1.8.0)
+ unicorn (4.9.0)
+ kgio (~> 2.6)
+ rack
+ raindrops (~> 0.7)
+ web-console (2.1.2)
+ activemodel (>= 4.0)
+ binding_of_caller (>= 0.7.2)
+ railties (>= 4.0)
+ sprockets-rails (>= 2.0, < 4.0)
+ webmock (1.21.0)
+ addressable (>= 2.3.6)
+ crack (>= 0.3.2)
+ xpath (2.0.0)
+ nokogiri (~> 1.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ airbrake
+ autoprefixer-rails
+ awesome_print
+ bourbon (~> 4.2.0)
+ bundler-audit
+ byebug
+ capybara-webkit (>= 1.2.0)
+ coffee-rails (~> 4.1.0)
+ database_cleaner
+ delayed_job_active_record
+ dotenv-rails
+ email_validator
+ factory_girl_rails
+ flutie
+ formulaic
+ high_voltage
+ i18n-tasks
+ jquery-rails
+ launchy
+ neat (~> 1.7.0)
+ newrelic_rpm (>= 3.9.8)
+ normalize-rails (~> 3.0.0)
+ pg
+ pry-rails
+ rack-canonical-host
+ rack-timeout
+ rails (= 4.2.1)
+ rails_stdout_logging
+ recipient_interceptor
+ refills
+ rspec-rails (~> 3.1.0)
+ sass-rails (~> 5.0)
+ shoulda-matchers
+ simple_form
+ simplecov
+ spring
+ spring-commands-rspec
+ timecop
+ title
+ uglifier
+ unicorn
+ web-console
+ webmock
+
+BUNDLED WITH
+ 1.10.3
diff --git a/Procfile b/Procfile
new file mode 100644
index 0000000..7934897
--- /dev/null
+++ b/Procfile
@@ -0,0 +1,2 @@
+web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
+worker: bundle exec rake jobs:work
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c97d836
--- /dev/null
+++ b/README.md
@@ -0,0 +1,40 @@
+# Omnibus
+
+## Getting Started
+
+After you have cloned this repo, run this setup script to set up your machine
+with the necessary dependencies to run and test this app:
+
+ % ./bin/setup
+
+It assumes you have a machine equipped with Ruby, Postgres, etc. If not, set up
+your machine with [this script].
+
+[this script]: https://github.com/thoughtbot/laptop
+
+After setting up, you can run the application using [foreman]:
+
+ % foreman start
+
+If you don't have `foreman`, see [Foreman's install instructions][foreman]. It
+is [purposefully excluded from the project's `Gemfile`][exclude].
+
+[foreman]: https://github.com/ddollar/foreman
+[exclude]: https://github.com/ddollar/foreman/pull/437#issuecomment-41110407
+
+## Guidelines
+
+Use the following guides for getting things done, programming well, and
+programming in style.
+
+* [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol)
+* [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices)
+* [Style](http://github.com/thoughtbot/guides/blob/master/style)
+
+## Deploying
+
+If you have previously run the `./bin/setup` script,
+you can deploy to staging and production with:
+
+ $ ./bin/deploy staging
+ $ ./bin/deploy production
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..4a77cd0
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,17 @@
+# 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__)
+
+Rails.application.load_tasks
+task(:default).clear
+task default: [:spec]
+
+if defined? RSpec
+ task(:spec).clear
+ RSpec::Core::RakeTask.new(:spec) do |t|
+ t.verbose = false
+ end
+end
+
+task default: "bundler:audit"
diff --git a/app/assets/images/.keep b/app/assets/images/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
new file mode 100644
index 0000000..646c5ab
--- /dev/null
+++ b/app/assets/javascripts/application.js
@@ -0,0 +1,15 @@
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
+//
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// compiled file.
+//
+// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
+// about supported directives.
+//
+//= require jquery
+//= require jquery_ujs
+//= require_tree .
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
new file mode 100644
index 0000000..e701338
--- /dev/null
+++ b/app/assets/stylesheets/application.scss
@@ -0,0 +1,8 @@
+@charset "utf-8";
+
+@import "normalize-rails";
+@import "bourbon";
+@import "base/grid-settings";
+@import "neat";
+@import "base/base";
+@import "refills/flashes";
diff --git a/app/assets/stylesheets/base/_base.scss b/app/assets/stylesheets/base/_base.scss
new file mode 100644
index 0000000..ddc350d
--- /dev/null
+++ b/app/assets/stylesheets/base/_base.scss
@@ -0,0 +1,15 @@
+// Bitters 1.0.0
+// http://bitters.bourbon.io
+// Copyright 2013-2015 thoughtbot, inc.
+// MIT License
+
+@import "variables";
+
+// Neat Settings -- uncomment if using Neat -- must be imported before Neat
+// @import "grid-settings";
+
+@import "buttons";
+@import "forms";
+@import "lists";
+@import "tables";
+@import "typography";
diff --git a/app/assets/stylesheets/base/_buttons.scss b/app/assets/stylesheets/base/_buttons.scss
new file mode 100644
index 0000000..f902f60
--- /dev/null
+++ b/app/assets/stylesheets/base/_buttons.scss
@@ -0,0 +1,31 @@
+#{$all-button-inputs},
+button {
+ @include appearance(none);
+ -webkit-font-smoothing: antialiased;
+ background-color: $action-color;
+ border-radius: $base-border-radius;
+ border: none;
+ color: #fff;
+ cursor: pointer;
+ display: inline-block;
+ font-family: $base-font-family;
+ font-size: $base-font-size;
+ font-weight: 600;
+ line-height: 1;
+ padding: 0.75em 1em;
+ text-decoration: none;
+ user-select: none;
+ vertical-align: middle;
+ white-space: nowrap;
+
+ &:hover,
+ &:focus {
+ background-color: darken($action-color, 15%);
+ color: #fff;
+ }
+
+ &:disabled {
+ cursor: not-allowed;
+ opacity: 0.5;
+ }
+}
diff --git a/app/assets/stylesheets/base/_forms.scss b/app/assets/stylesheets/base/_forms.scss
new file mode 100644
index 0000000..db4a796
--- /dev/null
+++ b/app/assets/stylesheets/base/_forms.scss
@@ -0,0 +1,78 @@
+fieldset {
+ background-color: lighten($base-border-color, 10%);
+ border: $base-border;
+ margin: 0 0 $small-spacing;
+ padding: $base-spacing;
+}
+
+input,
+label,
+select {
+ display: block;
+ font-family: $base-font-family;
+ font-size: $base-font-size;
+}
+
+label {
+ font-weight: 600;
+ margin-bottom: $small-spacing / 2;
+
+ &.required::after {
+ content: "*";
+ }
+
+ abbr {
+ display: none;
+ }
+}
+
+#{$all-text-inputs},
+select[multiple=multiple],
+textarea {
+ background-color: $base-background-color;
+ border: $base-border;
+ border-radius: $base-border-radius;
+ box-shadow: $form-box-shadow;
+ box-sizing: border-box;
+ font-family: $base-font-family;
+ font-size: $base-font-size;
+ margin-bottom: $base-spacing / 2;
+ padding: $base-spacing / 3;
+ transition: border-color;
+ width: 100%;
+
+ &:hover {
+ border-color: darken($base-border-color, 10%);
+ }
+
+ &:focus {
+ border-color: $action-color;
+ box-shadow: $form-box-shadow-focus;
+ outline: none;
+ }
+}
+
+textarea {
+ resize: vertical;
+}
+
+input[type="search"] {
+ @include appearance(none);
+}
+
+input[type="checkbox"],
+input[type="radio"] {
+ display: inline;
+ margin-right: $small-spacing / 2;
+}
+
+input[type="file"] {
+ padding-bottom: $small-spacing;
+ width: 100%;
+}
+
+select {
+ margin-bottom: $base-spacing;
+ max-width: 100%;
+ width: auto;
+}
diff --git a/app/assets/stylesheets/base/_grid-settings.scss b/app/assets/stylesheets/base/_grid-settings.scss
new file mode 100644
index 0000000..c42bdaf
--- /dev/null
+++ b/app/assets/stylesheets/base/_grid-settings.scss
@@ -0,0 +1,14 @@
+@import "neat-helpers"; // or "../neat/neat-helpers" when not in Rails
+
+// Neat Overrides
+// $column: 90px;
+// $gutter: 30px;
+// $grid-columns: 12;
+// $max-width: em(1088);
+
+// Neat Breakpoints
+$medium-screen: em(640);
+$large-screen: em(860);
+
+$medium-screen-up: new-breakpoint(min-width $medium-screen 4);
+$large-screen-up: new-breakpoint(min-width $large-screen 8);
diff --git a/app/assets/stylesheets/base/_lists.scss b/app/assets/stylesheets/base/_lists.scss
new file mode 100644
index 0000000..c989d90
--- /dev/null
+++ b/app/assets/stylesheets/base/_lists.scss
@@ -0,0 +1,31 @@
+ul,
+ol {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+
+ &%default-ul {
+ list-style-type: disc;
+ margin-bottom: $small-spacing;
+ padding-left: $base-spacing;
+ }
+
+ &%default-ol {
+ list-style-type: decimal;
+ margin-bottom: $small-spacing;
+ padding-left: $base-spacing;
+ }
+}
+
+dl {
+ margin-bottom: $small-spacing;
+
+ dt {
+ font-weight: bold;
+ margin-top: $small-spacing;
+ }
+
+ dd {
+ margin: 0;
+ }
+}
diff --git a/app/assets/stylesheets/base/_tables.scss b/app/assets/stylesheets/base/_tables.scss
new file mode 100644
index 0000000..8c5cc31
--- /dev/null
+++ b/app/assets/stylesheets/base/_tables.scss
@@ -0,0 +1,25 @@
+table {
+ @include font-feature-settings("kern", "liga", "tnum");
+ border-collapse: collapse;
+ margin: $small-spacing 0;
+ table-layout: fixed;
+ width: 100%;
+}
+
+th {
+ border-bottom: 1px solid darken($base-border-color, 15%);
+ font-weight: 600;
+ padding: $small-spacing 0;
+ text-align: left;
+}
+
+td {
+ border-bottom: $base-border;
+ padding: $small-spacing 0;
+}
+
+tr,
+td,
+th {
+ vertical-align: middle;
+}
diff --git a/app/assets/stylesheets/base/_typography.scss b/app/assets/stylesheets/base/_typography.scss
new file mode 100644
index 0000000..358559c
--- /dev/null
+++ b/app/assets/stylesheets/base/_typography.scss
@@ -0,0 +1,55 @@
+body {
+ @include font-feature-settings("kern", "liga", "pnum");
+ -webkit-font-smoothing: antialiased;
+ color: $base-font-color;
+ font-family: $base-font-family;
+ font-size: $base-font-size;
+ line-height: $base-line-height;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-family: $heading-font-family;
+ font-size: $base-font-size;
+ line-height: $heading-line-height;
+ margin: 0 0 $small-spacing;
+}
+
+p {
+ margin: 0 0 $small-spacing;
+}
+
+a {
+ color: $action-color;
+ text-decoration: none;
+ transition: color 0.1s linear;
+
+ &:active,
+ &:focus,
+ &:hover {
+ color: darken($action-color, 15%);
+ }
+
+ &:active,
+ &:focus {
+ outline: none;
+ }
+}
+
+hr {
+ border-bottom: $base-border;
+ border-left: none;
+ border-right: none;
+ border-top: none;
+ margin: $base-spacing 0;
+}
+
+img,
+picture {
+ margin: 0;
+ max-width: 100%;
+}
diff --git a/app/assets/stylesheets/base/_variables.scss b/app/assets/stylesheets/base/_variables.scss
new file mode 100644
index 0000000..7594759
--- /dev/null
+++ b/app/assets/stylesheets/base/_variables.scss
@@ -0,0 +1,35 @@
+// Typography
+$base-font-family: $helvetica;
+$heading-font-family: $base-font-family;
+
+// Font Sizes
+$base-font-size: 1em;
+
+// Line height
+$base-line-height: 1.5;
+$heading-line-height: 1.2;
+
+// Other Sizes
+$base-border-radius: 3px;
+$base-spacing: $base-line-height * 1em;
+$small-spacing: $base-spacing / 2;
+$base-z-index: 0;
+
+// Colors
+$blue: #477dca;
+$dark-gray: #333;
+$medium-gray: #999;
+$light-gray: #ddd;
+
+// Font Colors
+$base-background-color: #fff;
+$base-font-color: $dark-gray;
+$action-color: $blue;
+
+// Border
+$base-border-color: $light-gray;
+$base-border: 1px solid $base-border-color;
+
+// Forms
+$form-box-shadow: inset 0 1px 3px rgba(#000, 0.06);
+$form-box-shadow-focus: $form-box-shadow, 0 0 5px adjust-color($action-color, $lightness: -5%, $alpha: -0.3);
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
new file mode 100644
index 0000000..d83690e
--- /dev/null
+++ b/app/controllers/application_controller.rb
@@ -0,0 +1,5 @@
+class ApplicationController < ActionController::Base
+ # Prevent CSRF attacks by raising an exception.
+ # For APIs, you may want to use :null_session instead.
+ protect_from_forgery with: :exception
+end
diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
new file mode 100644
index 0000000..de6be79
--- /dev/null
+++ b/app/helpers/application_helper.rb
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
diff --git a/app/helpers/flashes_helper.rb b/app/helpers/flashes_helper.rb
new file mode 100644
index 0000000..bef014f
--- /dev/null
+++ b/app/helpers/flashes_helper.rb
@@ -0,0 +1,5 @@
+module FlashesHelper
+ def user_facing_flashes
+ flash.to_hash.slice("alert", "error", "notice", "success")
+ end
+end
diff --git a/app/mailers/.keep b/app/mailers/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/models/.keep b/app/models/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/views/application/_analytics.html.erb b/app/views/application/_analytics.html.erb
new file mode 100644
index 0000000..5ae6470
--- /dev/null
+++ b/app/views/application/_analytics.html.erb
@@ -0,0 +1,7 @@
+<% if ENV["SEGMENT_KEY"] %>
+
+<% end %>
diff --git a/app/views/application/_flashes.html.erb b/app/views/application/_flashes.html.erb
new file mode 100644
index 0000000..0849058
--- /dev/null
+++ b/app/views/application/_flashes.html.erb
@@ -0,0 +1,7 @@
+<% if flash.any? %>
+
+ <% user_facing_flashes.each do |key, value| -%>
+
<%= value %>
+ <% end -%>
+
+<% end %>
diff --git a/app/views/application/_javascript.html.erb b/app/views/application/_javascript.html.erb
new file mode 100644
index 0000000..a738f79
--- /dev/null
+++ b/app/views/application/_javascript.html.erb
@@ -0,0 +1,12 @@
+<%= javascript_include_tag :application %>
+
+<%= yield :javascript %>
+
+<%= render "analytics" %>
+
+<% if Rails.env.test? %>
+ <%= javascript_tag do %>
+ $.fx.off = true;
+ $.ajaxSetup({ async: false });
+ <% end %>
+<% end %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
new file mode 100644
index 0000000..3e38f12
--- /dev/null
+++ b/app/views/layouts/application.html.erb
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ <%#
+ Configure default and controller-, and view-specific titles in
+ config/locales/en.yml. For more see:
+ https://github.com/calebthompson/title#usage
+ %>
+ <%= title %>
+ <%= stylesheet_link_tag :application, media: "all" %>
+ <%= csrf_meta_tags %>
+
+
+ <%= render "flashes" -%>
+ <%= yield %>
+ <%= render "javascript" %>
+
+
diff --git a/app/views/pages/.keep b/app/views/pages/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/bin/bundle b/bin/bundle
new file mode 100755
index 0000000..66e9889
--- /dev/null
+++ b/bin/bundle
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+load Gem.bin_path('bundler', 'bundle')
diff --git a/bin/delayed_job b/bin/delayed_job
new file mode 100755
index 0000000..edf1959
--- /dev/null
+++ b/bin/delayed_job
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
+require 'delayed/command'
+Delayed::Command.new(ARGV).daemonize
diff --git a/bin/deploy b/bin/deploy
new file mode 100755
index 0000000..deb2ae9
--- /dev/null
+++ b/bin/deploy
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Run this script to deploy the app to Heroku.
+
+set -e
+
+branch="$(git symbolic-ref HEAD --short)"
+target="${1:-staging}"
+
+git push "$target" "$branch:master"
+heroku run rake db:migrate --remote "$target"
+heroku restart --remote "$target"
diff --git a/bin/rails b/bin/rails
new file mode 100755
index 0000000..5191e69
--- /dev/null
+++ b/bin/rails
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+APP_PATH = File.expand_path('../../config/application', __FILE__)
+require_relative '../config/boot'
+require 'rails/commands'
diff --git a/bin/rake b/bin/rake
new file mode 100755
index 0000000..1724048
--- /dev/null
+++ b/bin/rake
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+require_relative '../config/boot'
+require 'rake'
+Rake.application.run
diff --git a/bin/setup b/bin/setup
new file mode 100755
index 0000000..2658863
--- /dev/null
+++ b/bin/setup
@@ -0,0 +1,56 @@
+#!/usr/bin/env sh
+
+# Set up Rails app. Run this script immediately after cloning the codebase.
+# https://github.com/thoughtbot/guides/tree/master/protocol
+
+# Exit if any subcommand fails
+set -e
+
+# Set up Ruby dependencies via Bundler
+gem install bundler --conservative
+bundle check || bundle install
+
+# Set up configurable environment variables
+if [ ! -f .env ]; then
+ cp .sample.env .env
+fi
+
+# Set up database and add any development seed data
+bundle exec rake db:setup dev:prime
+
+# Add binstubs to PATH via export PATH=".git/safe/../../bin:$PATH" in ~/.zshenv
+mkdir -p .git/safe
+
+# Pick a port for Foreman
+if ! grep --quiet --no-messages --fixed-strings 'port' .foreman; then
+ printf 'port: 8000\n' >> .foreman
+fi
+
+if ! command -v foreman > /dev/null; then
+ printf 'Foreman is not installed.\n'
+ printf 'See https://github.com/ddollar/foreman for install instructions.\n'
+fi
+
+# Only if this isn't CI
+# if [ -z "$CI" ]; then
+# fi
+
+# Set up the staging and production apps.
+if heroku join --app omnibus-staging &> /dev/null; then
+ git remote add staging git@heroku.com:omnibus-staging.git || true
+ printf 'You are a collaborator on the "omnibus-staging" Heroku app
+'
+else
+ printf 'Ask for access to the "omnibus-staging" Heroku app
+'
+fi
+
+if heroku join --app omnibus-production &> /dev/null; then
+ git remote add production git@heroku.com:omnibus-production.git || true
+ printf 'You are a collaborator on the "omnibus-production" Heroku app
+'
+else
+ printf 'Ask for access to the "omnibus-production" Heroku app
+'
+fi
+
diff --git a/browserslist b/browserslist
new file mode 100644
index 0000000..1e8f87e
--- /dev/null
+++ b/browserslist
@@ -0,0 +1,4 @@
+Last 2 versions
+Explorer >= 9
+iOS >= 7.1
+Android >= 4.4
diff --git a/config.ru b/config.ru
new file mode 100644
index 0000000..bd83b25
--- /dev/null
+++ b/config.ru
@@ -0,0 +1,4 @@
+# This file is used by Rack-based servers to start the application.
+
+require ::File.expand_path('../config/environment', __FILE__)
+run Rails.application
diff --git a/config/application.rb b/config/application.rb
new file mode 100644
index 0000000..6aadcf8
--- /dev/null
+++ b/config/application.rb
@@ -0,0 +1,50 @@
+require File.expand_path('../boot', __FILE__)
+
+require "rails"
+# Pick the frameworks you want:
+require "active_model/railtie"
+require "active_job/railtie"
+require "active_record/railtie"
+require "action_controller/railtie"
+require "action_mailer/railtie"
+require "action_view/railtie"
+require "sprockets/railtie"
+# require "rails/test_unit/railtie"
+
+# Require the gems listed in Gemfile, including any gems
+# you've limited to :test, :development, or :production.
+Bundler.require(*Rails.groups)
+
+module Omnibus
+ class Application < Rails::Application
+ config.i18n.enforce_available_locales = true
+
+ config.generators do |generate|
+ generate.helper false
+ generate.javascript_engine false
+ generate.request_specs false
+ generate.routing_specs false
+ generate.stylesheets false
+ generate.test_framework :rspec
+ generate.view_specs false
+ end
+
+ config.action_controller.action_on_unpermitted_parameters = :raise
+ # 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.
+
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
+ # config.time_zone = 'Central Time (US & Canada)'
+
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+ # config.i18n.default_locale = :de
+
+ # Do not swallow errors in after_commit/after_rollback callbacks.
+ config.active_record.raise_in_transactional_callbacks = true
+
+ config.active_job.queue_adapter = :delayed_job
+ end
+end
diff --git a/config/boot.rb b/config/boot.rb
new file mode 100644
index 0000000..6b750f0
--- /dev/null
+++ b/config/boot.rb
@@ -0,0 +1,3 @@
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
+
+require 'bundler/setup' # Set up gems listed in the Gemfile.
diff --git a/config/database.yml b/config/database.yml
new file mode 100644
index 0000000..98a1cb4
--- /dev/null
+++ b/config/database.yml
@@ -0,0 +1,12 @@
+development: &default
+ adapter: postgresql
+ database: omnibus_development
+ encoding: utf8
+ host: localhost
+ min_messages: warning
+ pool: 2
+ timeout: 5000
+
+test:
+ <<: *default
+ database: omnibus_test
diff --git a/config/environment.rb b/config/environment.rb
new file mode 100644
index 0000000..ee8d90d
--- /dev/null
+++ b/config/environment.rb
@@ -0,0 +1,5 @@
+# Load the Rails application.
+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
new file mode 100644
index 0000000..8dc3668
--- /dev/null
+++ b/config/environments/development.rb
@@ -0,0 +1,44 @@
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # In the development environment your application's code is reloaded on
+ # every request. This slows down response time but is perfect for development
+ # since you don't have to restart the web server when you make code changes.
+ config.cache_classes = false
+
+ # Do not eager load code on boot.
+ config.eager_load = false
+
+ # Show full error reports and disable caching.
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+
+ # Don't care if the mailer can't send.
+ config.action_mailer.raise_delivery_errors = true
+ config.action_mailer.delivery_method = :test
+
+ # Print deprecation notices to the Rails logger.
+ config.active_support.deprecation = :log
+
+ # Raise an error on page load if there are pending migrations.
+ config.active_record.migration_error = :page_load
+
+ # Debug mode disables concatenation and preprocessing of assets.
+ # This option may cause significant delays in view rendering with a large
+ # number of complex assets.
+ config.assets.debug = true
+
+ # Asset digests allow you to set far-future HTTP expiration dates on all assets,
+ # yet still be able to expire them through the digest params.
+ config.assets.digest = true
+
+ # Adds additional error checking when serving assets at runtime.
+ # Checks for improperly declared sprockets dependencies.
+ # Raises helpful error messages.
+ config.assets.raise_runtime_errors = true
+
+ # Raises error for missing translations
+ config.action_view.raise_on_missing_translations = true
+
+ config.action_mailer.default_url_options = { host: "localhost:5000" }
+end
diff --git a/config/environments/production.rb b/config/environments/production.rb
new file mode 100644
index 0000000..9584177
--- /dev/null
+++ b/config/environments/production.rb
@@ -0,0 +1,92 @@
+require Rails.root.join("config/smtp")
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # Code is not reloaded between requests.
+ config.cache_classes = true
+
+ # Eager load code on boot. This eager loads most of Rails and
+ # your application in memory, allowing both threaded web servers
+ # and those relying on copy on write to perform better.
+ # Rake tasks automatically ignore this option for performance.
+ config.eager_load = true
+
+ # Full error reports are disabled and caching is turned on.
+ config.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
+
+ # Enable Rack::Cache to put a simple HTTP cache in front of your application
+ # Add `rack-cache` to your Gemfile before enabling this.
+ # For large-scale production use, consider using a caching reverse proxy like
+ # NGINX, varnish or squid.
+ # config.action_dispatch.rack_cache = true
+
+ # 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.static_cache_control = "public, max-age=#{1.year.to_i}"
+ # Enable deflate / gzip compression of controller-generated responses
+ config.middleware.use Rack::Deflater
+
+ # Ensure requests are only served from one, canonical host name
+ config.middleware.use Rack::CanonicalHost, ENV.fetch("HOST")
+
+ # Compress JavaScripts and CSS.
+ config.assets.js_compressor = :uglifier
+ # config.assets.css_compressor = :sass
+
+ # Do not fallback to assets pipeline if a precompiled asset is missed.
+ config.assets.compile = false
+
+ # Asset digests allow you to set far-future HTTP expiration dates on all assets,
+ # yet still be able to expire them through the digest params.
+ config.assets.digest = true
+
+ # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
+
+ # Specifies the header that your server uses for sending files.
+ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
+
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+ # config.force_ssl = true
+
+ # Use the lowest log level to ensure availability of diagnostic information
+ # when problems arise.
+ config.log_level = :debug
+
+ # Prepend all log lines with the following tags.
+ # config.log_tags = [ :subdomain, :uuid ]
+
+ # Use a different logger for distributed setups.
+ # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
+
+ # Use a different cache store in production.
+ # config.cache_store = :mem_cache_store
+
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server.
+ config.action_controller.asset_host = ENV.fetch("ASSET_HOST", ENV.fetch("HOST"))
+
+ # Ignore bad email addresses and do not raise email delivery errors.
+ # Set this to true and configure the email server for immediate delivery to raise delivery errors.
+ # config.action_mailer.raise_delivery_errors = false
+ config.action_mailer.delivery_method = :smtp
+ config.action_mailer.smtp_settings = SMTP_SETTINGS
+
+
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
+ # the I18n.default_locale when a translation cannot be found).
+ config.i18n.fallbacks = true
+
+ # Send deprecation notices to registered listeners.
+ config.active_support.deprecation = :notify
+
+ # Use default logging formatter so that PID and timestamp are not suppressed.
+ config.log_formatter = ::Logger::Formatter.new
+
+ # Do not dump schema after migrations.
+ config.active_record.dump_schema_after_migration = false
+
+ config.action_mailer.default_url_options = { host: ENV.fetch("HOST") }
+end
+Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
diff --git a/config/environments/staging.rb b/config/environments/staging.rb
new file mode 100644
index 0000000..d0e0f88
--- /dev/null
+++ b/config/environments/staging.rb
@@ -0,0 +1,11 @@
+require_relative "production"
+
+Mail.register_interceptor(
+ RecipientInterceptor.new(ENV.fetch("EMAIL_RECIPIENTS"))
+)
+
+Rails.application.configure do
+ # ...
+
+ config.action_mailer.default_url_options = { host: ENV.fetch("HOST") }
+end
diff --git a/config/environments/test.rb b/config/environments/test.rb
new file mode 100644
index 0000000..793219d
--- /dev/null
+++ b/config/environments/test.rb
@@ -0,0 +1,46 @@
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # The test environment is used exclusively to run your application's
+ # test suite. You never need to work with it otherwise. Remember that
+ # your test database is "scratch space" for the test suite and is wiped
+ # and recreated between test runs. Don't rely on the data there!
+ config.cache_classes = true
+
+ # Do not eager load code on boot. This avoids loading your whole application
+ # just for the purpose of running a single test. If you are using a tool that
+ # preloads Rails for running tests, you may have to set it to true.
+ 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'
+
+ # Show full error reports and disable caching.
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+
+ # Raise exceptions instead of rendering exception templates.
+ config.action_dispatch.show_exceptions = false
+
+ # Disable request forgery protection in test environment.
+ config.action_controller.allow_forgery_protection = false
+
+ # Tell Action Mailer not to deliver emails to the real world.
+ # The :test delivery method accumulates sent emails in the
+ # ActionMailer::Base.deliveries array.
+ config.action_mailer.delivery_method = :test
+
+ # Randomize the order test cases are executed.
+ config.active_support.test_order = :random
+
+ # Print deprecation notices to the stderr.
+ config.active_support.deprecation = :stderr
+
+ # Raises error for missing translations
+ config.action_view.raise_on_missing_translations = true
+
+ config.action_mailer.default_url_options = { host: "www.example.com" }
+
+ config.active_job.queue_adapter = :inline
+end
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
new file mode 100644
index 0000000..5380ae1
--- /dev/null
+++ b/config/i18n-tasks.yml
@@ -0,0 +1,13 @@
+search:
+ paths:
+ - "app/controllers"
+ - "app/helpers"
+ - "app/presenters"
+ - "app/views"
+
+ignore_unused:
+ - activerecord.*
+ - date.*
+ - simple_form.*
+ - time.*
+ - titles.*
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
new file mode 100644
index 0000000..13abef8
--- /dev/null
+++ b/config/initializers/assets.rb
@@ -0,0 +1,11 @@
+# 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 = (ENV["ASSETS_VERSION"] || "1.0")
+
+# Add additional assets to the asset load path
+# Rails.application.config.assets.paths << Emoji.images_path
+
+# Precompile additional assets.
+# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
+# Rails.application.config.assets.precompile += %w( search.js )
diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb
new file mode 100644
index 0000000..59385cd
--- /dev/null
+++ b/config/initializers/backtrace_silencers.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
+# Rails.backtrace_cleaner.remove_silencers!
diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb
new file mode 100644
index 0000000..7f70458
--- /dev/null
+++ b/config/initializers/cookies_serializer.rb
@@ -0,0 +1,3 @@
+# Be sure to restart your server when you modify this file.
+
+Rails.application.config.action_dispatch.cookies_serializer = :json
diff --git a/config/initializers/disable_xml_params.rb b/config/initializers/disable_xml_params.rb
new file mode 100644
index 0000000..c24d969
--- /dev/null
+++ b/config/initializers/disable_xml_params.rb
@@ -0,0 +1,3 @@
+# Protect against injection attacks
+# http://www.kb.cert.org/vuls/id/380039
+ActionDispatch::ParamsParser::DEFAULT_PARSERS.delete(Mime::XML)
diff --git a/config/initializers/errors.rb b/config/initializers/errors.rb
new file mode 100644
index 0000000..13c1795
--- /dev/null
+++ b/config/initializers/errors.rb
@@ -0,0 +1,34 @@
+require "net/http"
+require "net/smtp"
+
+# Example:
+# begin
+# some http call
+# rescue *HTTP_ERRORS => error
+# notify_hoptoad error
+# end
+
+HTTP_ERRORS = [
+ EOFError,
+ Errno::ECONNRESET,
+ Errno::EINVAL,
+ Net::HTTPBadResponse,
+ Net::HTTPHeaderSyntaxError,
+ Net::ProtocolError,
+ Timeout::Error
+]
+
+SMTP_SERVER_ERRORS = [
+ IOError,
+ Net::SMTPAuthenticationError,
+ Net::SMTPServerBusy,
+ Net::SMTPUnknownError,
+ TimeoutError
+]
+
+SMTP_CLIENT_ERRORS = [
+ Net::SMTPFatalError,
+ Net::SMTPSyntaxError
+]
+
+SMTP_ERRORS = SMTP_SERVER_ERRORS + SMTP_CLIENT_ERRORS
diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb
new file mode 100644
index 0000000..4a994e1
--- /dev/null
+++ b/config/initializers/filter_parameter_logging.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Configure sensitive parameters which will be filtered from the log file.
+Rails.application.config.filter_parameters += [:password]
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
new file mode 100644
index 0000000..ac033bf
--- /dev/null
+++ b/config/initializers/inflections.rb
@@ -0,0 +1,16 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format. Inflections
+# are locale specific, and you may define rules for as many different
+# locales as you wish. All of these examples are active by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
+
+# These inflection rules are supported but not enabled by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.acronym 'RESTful'
+# end
diff --git a/config/initializers/json_encoding.rb b/config/initializers/json_encoding.rb
new file mode 100644
index 0000000..292542f
--- /dev/null
+++ b/config/initializers/json_encoding.rb
@@ -0,0 +1 @@
+ActiveSupport::JSON::Encoding.time_precision = 0
diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb
new file mode 100644
index 0000000..dc18996
--- /dev/null
+++ b/config/initializers/mime_types.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
new file mode 100644
index 0000000..9c03570
--- /dev/null
+++ b/config/initializers/session_store.rb
@@ -0,0 +1,3 @@
+# Be sure to restart your server when you modify this file.
+
+Rails.application.config.session_store :cookie_store, key: '_omnibus_session'
diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb
new file mode 100644
index 0000000..d5492e5
--- /dev/null
+++ b/config/initializers/simple_form.rb
@@ -0,0 +1,166 @@
+# Use this setup block to configure all options available in SimpleForm.
+SimpleForm.setup do |config|
+ # Wrappers are used by the form builder to generate a
+ # complete input. You can remove any component from the
+ # wrapper, change the order or even add your own to the
+ # stack. The options given below are used to wrap the
+ # whole input.
+ config.wrappers :default, class: :input,
+ hint_class: :field_with_hint, error_class: :field_with_errors do |b|
+ ## Extensions enabled by default
+ # Any of these extensions can be disabled for a
+ # given input by passing: `f.input EXTENSION_NAME => false`.
+ # You can make any of these extensions optional by
+ # renaming `b.use` to `b.optional`.
+
+ # Determines whether to use HTML5 (:email, :url, ...)
+ # and required attributes
+ b.use :html5
+
+ # Calculates placeholders automatically from I18n
+ # You can also pass a string as f.input placeholder: "Placeholder"
+ b.use :placeholder
+
+ ## Optional extensions
+ # They are disabled unless you pass `f.input EXTENSION_NAME => true`
+ # to the input. If so, they will retrieve the values from the model
+ # if any exists. If you want to enable any of those
+ # extensions by default, you can change `b.optional` to `b.use`.
+
+ # Calculates maxlength from length validations for string inputs
+ b.optional :maxlength
+
+ # Calculates pattern from format validations for string inputs
+ b.optional :pattern
+
+ # Calculates min and max from length validations for numeric inputs
+ b.optional :min_max
+
+ # Calculates readonly automatically from readonly attributes
+ b.optional :readonly
+
+ ## Inputs
+ b.use :label_input
+ b.use :hint, wrap_with: { tag: :span, class: :hint }
+ b.use :error, wrap_with: { tag: :span, class: :error }
+
+ ## full_messages_for
+ # If you want to display the full error message for the attribute, you can
+ # use the component :full_error, like:
+ #
+ # b.use :full_error, wrap_with: { tag: :span, class: :error }
+ end
+
+ # The default wrapper to be used by the FormBuilder.
+ config.default_wrapper = :default
+
+ # Define the way to render check boxes / radio buttons with labels.
+ # Defaults to :nested for bootstrap config.
+ # inline: input + label
+ # nested: label > input
+ config.boolean_style = :nested
+
+ # Default class for buttons
+ config.button_class = 'btn'
+
+ # Method used to tidy up errors. Specify any Rails Array method.
+ # :first lists the first message for each field.
+ # Use :to_sentence to list all errors for each field.
+ # config.error_method = :first
+
+ # Default tag used for error notification helper.
+ config.error_notification_tag = :div
+
+ # CSS class to add for error notification helper.
+ config.error_notification_class = 'error_notification'
+
+ # ID to add for error notification helper.
+ # config.error_notification_id = nil
+
+ # Series of attempts to detect a default label method for collection.
+ # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
+
+ # Series of attempts to detect a default value method for collection.
+ # config.collection_value_methods = [ :id, :to_s ]
+
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
+ # config.collection_wrapper_tag = nil
+
+ # You can define the class to use on all collection wrappers. Defaulting to none.
+ # config.collection_wrapper_class = nil
+
+ # You can wrap each item in a collection of radio/check boxes with a tag,
+ # defaulting to :span. Please note that when using :boolean_style = :nested,
+ # SimpleForm will force this option to be a label.
+ # config.item_wrapper_tag = :span
+
+ # You can define a class to use in all item wrappers. Defaulting to none.
+ # config.item_wrapper_class = nil
+
+ # How the label text should be generated altogether with the required text.
+ # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
+
+ # You can define the class to use on all labels. Default is nil.
+ # config.label_class = nil
+
+ # You can define the default class to be used on forms. Can be overriden
+ # with `html: { :class }`. Defaulting to none.
+ # config.default_form_class = nil
+
+ # You can define which elements should obtain additional classes
+ # config.generate_additional_classes_for = [:wrapper, :label, :input]
+
+ # Whether attributes are required by default (or not). Default is true.
+ # config.required_by_default = true
+
+ # Tell browsers whether to use the native HTML5 validations (novalidate form option).
+ # These validations are enabled in SimpleForm's internal config but disabled by default
+ # in this configuration, which is recommended due to some quirks from different browsers.
+ # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,
+ # change this configuration to true.
+ config.browser_validations = false
+
+ # Collection of methods to detect if a file type was given.
+ # config.file_methods = [ :mounted_as, :file?, :public_filename ]
+
+ # Custom mappings for input types. This should be a hash containing a regexp
+ # to match as key, and the input type that will be used when the field name
+ # matches the regexp as value.
+ # config.input_mappings = { /count/ => :integer }
+
+ # Custom wrappers for input types. This should be a hash containing an input
+ # type as key and the wrapper that will be used for all inputs with specified type.
+ # config.wrapper_mappings = { string: :prepend }
+
+ # Namespaces where SimpleForm should look for custom input classes that
+ # override default inputs.
+ # config.custom_inputs_namespaces << "CustomInputs"
+
+ # Default priority for time_zone inputs.
+ # config.time_zone_priority = nil
+
+ # Default priority for country inputs.
+ # config.country_priority = nil
+
+ # When false, do not use translations for labels.
+ # config.translate_labels = true
+
+ # Automatically discover new inputs in Rails' autoload path.
+ # config.inputs_discovery = true
+
+ # Cache SimpleForm inputs discovery
+ # config.cache_discovery = !Rails.env.development?
+
+ # Default class for inputs
+ # config.input_class = nil
+
+ # Define the default class of the input wrapper of the boolean input.
+ config.boolean_label_class = 'checkbox'
+
+ # Defines if the default input wrapper class should be included in radio
+ # collection wrappers.
+ # config.include_default_input_wrapper_class = true
+
+ # Defines which i18n scope will be used in Simple Form.
+ # config.i18n_scope = 'simple_form'
+end
diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb
new file mode 100644
index 0000000..33725e9
--- /dev/null
+++ b/config/initializers/wrap_parameters.rb
@@ -0,0 +1,14 @@
+# Be sure to restart your server when you modify this file.
+
+# This file contains settings for ActionController::ParamsWrapper which
+# is enabled by default.
+
+# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
+ActiveSupport.on_load(:action_controller) do
+ wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
+end
+
+# To enable root element in JSON for ActiveRecord objects.
+# ActiveSupport.on_load(:active_record) do
+# self.include_root_in_json = true
+# end
diff --git a/config/locales/en.yml b/config/locales/en.yml
new file mode 100644
index 0000000..631ab2b
--- /dev/null
+++ b/config/locales/en.yml
@@ -0,0 +1,19 @@
+en:
+ date:
+ formats:
+ default:
+ "%m/%d/%Y"
+ with_weekday:
+ "%a %m/%d/%y"
+
+ time:
+ formats:
+ default:
+ "%a, %b %-d, %Y at %r"
+ date:
+ "%b %-d, %Y"
+ short:
+ "%B %d"
+
+ titles:
+ application: Omnibus
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
new file mode 100644
index 0000000..2374383
--- /dev/null
+++ b/config/locales/simple_form.en.yml
@@ -0,0 +1,31 @@
+en:
+ simple_form:
+ "yes": 'Yes'
+ "no": 'No'
+ required:
+ text: 'required'
+ mark: '*'
+ # You can uncomment the line below if you need to overwrite the whole required html.
+ # When using html, text and mark won't be used.
+ # html: '*'
+ error_notification:
+ default_message: "Please review the problems below:"
+ # Examples
+ # labels:
+ # defaults:
+ # password: 'Password'
+ # user:
+ # new:
+ # email: 'E-mail to sign in.'
+ # edit:
+ # email: 'E-mail.'
+ # hints:
+ # defaults:
+ # username: 'User name to sign in.'
+ # password: 'No special characters, please.'
+ # include_blanks:
+ # defaults:
+ # age: 'Rather not say'
+ # prompts:
+ # defaults:
+ # age: 'Select your age'
diff --git a/config/newrelic.yml b/config/newrelic.yml
new file mode 100644
index 0000000..ccf25ca
--- /dev/null
+++ b/config/newrelic.yml
@@ -0,0 +1,34 @@
+common: &default_settings
+ app_name: "omnibus"
+ audit_log:
+ enabled: false
+ browser_monitoring:
+ auto_instrument: true
+ capture_params: false
+ developer_mode: false
+ error_collector:
+ capture_source: true
+ enabled: true
+ ignore_errors: "ActionController::RoutingError,Sinatra::NotFound"
+ license_key: "<%= ENV["NEW_RELIC_LICENSE_KEY"] %>"
+ log_level: info
+ monitor_mode: true
+ transaction_tracer:
+ enabled: true
+ record_sql: obfuscated
+ stack_trace_threshold: 0.500
+ transaction_threshold: apdex_f
+development:
+ <<: *default_settings
+ monitor_mode: false
+ developer_mode: true
+test:
+ <<: *default_settings
+ monitor_mode: false
+production:
+ <<: *default_settings
+ monitor_mode: true
+staging:
+ <<: *default_settings
+ app_name: "omnibus (Staging)"
+ monitor_mode: true
diff --git a/config/routes.rb b/config/routes.rb
new file mode 100644
index 0000000..1daf9a4
--- /dev/null
+++ b/config/routes.rb
@@ -0,0 +1,2 @@
+Rails.application.routes.draw do
+end
diff --git a/config/secrets.yml b/config/secrets.yml
new file mode 100644
index 0000000..0bfb22d
--- /dev/null
+++ b/config/secrets.yml
@@ -0,0 +1,14 @@
+default: &default
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
+
+development:
+ <<: *default
+
+test:
+ <<: *default
+
+staging:
+ <<: *default
+
+production:
+ <<: *default
diff --git a/config/smtp.rb b/config/smtp.rb
new file mode 100644
index 0000000..0440e09
--- /dev/null
+++ b/config/smtp.rb
@@ -0,0 +1,9 @@
+SMTP_SETTINGS = {
+ address: ENV.fetch("SMTP_ADDRESS"), # example: "smtp.sendgrid.net"
+ authentication: :plain,
+ domain: ENV.fetch("SMTP_DOMAIN"), # example: "heroku.com"
+ enable_starttls_auto: true,
+ password: ENV.fetch("SMTP_PASSWORD"),
+ port: "587",
+ user_name: ENV.fetch("SMTP_USERNAME")
+}
diff --git a/config/unicorn.rb b/config/unicorn.rb
new file mode 100644
index 0000000..555cf62
--- /dev/null
+++ b/config/unicorn.rb
@@ -0,0 +1,30 @@
+# https://devcenter.heroku.com/articles/rails-unicorn
+
+worker_processes (ENV["UNICORN_WORKERS"] || 3).to_i
+timeout (ENV["UNICORN_TIMEOUT"] || 15).to_i
+preload_app true
+
+before_fork do |_server, _worker|
+ Signal.trap "TERM" do
+ puts "Unicorn master intercepting TERM, sending myself QUIT instead"
+ Process.kill "QUIT", Process.pid
+ end
+
+ if defined? ActiveRecord::Base
+ ActiveRecord::Base.connection.disconnect!
+ end
+end
+
+after_fork do |_server, _worker|
+ Signal.trap "TERM" do
+ puts "Unicorn worker intercepting TERM, waiting for master to send QUIT"
+ end
+
+ if defined? ActiveRecord::Base
+ config = ActiveRecord::Base.configurations[Rails.env] ||
+ Rails.application.config.database_configuration[Rails.env]
+ config["reaping_frequency"] = (ENV["DB_REAPING_FREQUENCY"] || 10).to_i
+ config["pool"] = (ENV["DB_POOL"] || 2).to_i
+ ActiveRecord::Base.establish_connection(config)
+ end
+end
diff --git a/db/migrate/20150610152841_create_delayed_jobs.rb b/db/migrate/20150610152841_create_delayed_jobs.rb
new file mode 100644
index 0000000..27fdcf6
--- /dev/null
+++ b/db/migrate/20150610152841_create_delayed_jobs.rb
@@ -0,0 +1,22 @@
+class CreateDelayedJobs < ActiveRecord::Migration
+ def self.up
+ create_table :delayed_jobs, force: true do |table|
+ table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue
+ table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually.
+ table.text :handler, null: false # YAML-encoded string of the object that will do work
+ table.text :last_error # reason for last failure (See Note below)
+ table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
+ table.datetime :locked_at # Set when a client is working on this object
+ table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
+ table.string :locked_by # Who is working on this object (if locked)
+ table.string :queue # The name of the queue this job is in
+ table.timestamps null: true
+ end
+
+ add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority"
+ end
+
+ def self.down
+ drop_table :delayed_jobs
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 0000000..2c36347
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,35 @@
+# encoding: UTF-8
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# Note that this schema.rb definition is the authoritative source for your
+# database schema. If you need to create the application database on another
+# system, you should be using db:schema:load, not running all the migrations
+# from scratch. The latter is a flawed and unsustainable approach (the more migrations
+# you'll amass, the slower it'll run and the greater likelihood for issues).
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema.define(version: 20150610152841) do
+
+ # These are extensions that must be enabled in order to support this database
+ enable_extension "plpgsql"
+
+ create_table "delayed_jobs", force: :cascade do |t|
+ t.integer "priority", default: 0, null: false
+ t.integer "attempts", default: 0, null: false
+ t.text "handler", null: false
+ t.text "last_error"
+ t.datetime "run_at"
+ t.datetime "locked_at"
+ t.datetime "failed_at"
+ t.string "locked_by"
+ t.string "queue"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
+
+end
diff --git a/db/seeds.rb b/db/seeds.rb
new file mode 100644
index 0000000..4edb1e8
--- /dev/null
+++ b/db/seeds.rb
@@ -0,0 +1,7 @@
+# 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).
+#
+# Examples:
+#
+# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
+# Mayor.create(name: 'Emanuel', city: cities.first)
diff --git a/lib/assets/.keep b/lib/assets/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/lib/tasks/.keep b/lib/tasks/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/lib/tasks/bundler_audit.rake b/lib/tasks/bundler_audit.rake
new file mode 100644
index 0000000..00c1263
--- /dev/null
+++ b/lib/tasks/bundler_audit.rake
@@ -0,0 +1,12 @@
+if Rails.env.development? || Rails.env.test?
+ require "bundler/audit/cli"
+
+ namespace :bundler do
+ desc "Updates the ruby-advisory-db and runs audit"
+ task :audit do
+ %w(update check).each do |command|
+ Bundler::Audit::CLI.start [command]
+ end
+ end
+ end
+end
diff --git a/lib/tasks/development_seeds.rake b/lib/tasks/development_seeds.rake
new file mode 100644
index 0000000..b9a7a2d
--- /dev/null
+++ b/lib/tasks/development_seeds.rake
@@ -0,0 +1,12 @@
+if Rails.env.development? || Rails.env.test?
+ require "factory_girl"
+
+ namespace :dev do
+ desc "Seed data for development environment"
+ task prime: "db:setup" do
+ include FactoryGirl::Syntax::Methods
+
+ # create(:user, email: "user@example.com", password: "password")
+ end
+ end
+end
diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb
new file mode 100644
index 0000000..201a069
--- /dev/null
+++ b/lib/templates/erb/scaffold/_form.html.erb
@@ -0,0 +1,13 @@
+<%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
+ <%%= f.error_notification %>
+
+
+ <%- attributes.each do |attribute| -%>
+ <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
+ <%- end -%>
+
+
+
+ <%%= f.button :submit %>
+
+<%% end %>
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 0000000..7b93ab6
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ The page you were looking for doesn't exist (404)
+
+
+
+
+
+
+
+
The page you were looking for doesn't exist.
+
You may have mistyped the address or the page may have moved.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/public/422.html b/public/422.html
new file mode 100644
index 0000000..db2ff83
--- /dev/null
+++ b/public/422.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ The change you wanted was rejected (422)
+
+
+
+
+
+
+
+
The change you wanted was rejected.
+
Maybe you tried to change something you didn't have access to.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/public/500.html b/public/500.html
new file mode 100644
index 0000000..e93b854
--- /dev/null
+++ b/public/500.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ We're sorry, but something went wrong (500)
+
+
+
+
+
+
+
+
We're sorry, but something went wrong.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..e69de29
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..3c9c7c0
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,5 @@
+# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
+#
+# To ban all spiders from the entire site uncomment the next two lines:
+# User-agent: *
+# Disallow: /
diff --git a/spec/controllers/.keep b/spec/controllers/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/features/.keep b/spec/features/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/helpers/.keep b/spec/helpers/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb
new file mode 100644
index 0000000..71211b8
--- /dev/null
+++ b/spec/i18n_spec.rb
@@ -0,0 +1,17 @@
+require 'i18n/tasks'
+
+describe 'I18n' do
+ let(:i18n) { I18n::Tasks::BaseTask.new }
+ let(:missing_keys) { i18n.missing_keys }
+ let(:unused_keys) { i18n.unused_keys }
+
+ it 'does not have missing keys' do
+ expect(missing_keys).to be_empty,
+ "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them"
+ end
+
+ it 'does not have unused keys' do
+ expect(unused_keys).to be_empty,
+ "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them"
+ end
+end
diff --git a/spec/lib/.keep b/spec/lib/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb
new file mode 100644
index 0000000..789d2cb
--- /dev/null
+++ b/spec/rails_helper.rb
@@ -0,0 +1,23 @@
+ENV["RAILS_ENV"] = "test"
+
+require File.expand_path("../../config/environment", __FILE__)
+
+require "rspec/rails"
+require "shoulda/matchers"
+
+Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file }
+
+module Features
+ # Extend this module in spec/support/features/*.rb
+ include Formulaic::Dsl
+end
+
+RSpec.configure do |config|
+ config.include Features, type: :feature
+ config.infer_base_class_for_anonymous_controllers = false
+ config.infer_spec_type_from_file_location!
+ config.use_transactional_fixtures = false
+end
+
+ActiveRecord::Migration.maintain_test_schema!
+Capybara.javascript_driver = :webkit
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..46e4254
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,22 @@
+if ENV.fetch("COVERAGE", false)
+ require "simplecov"
+ SimpleCov.start "rails"
+end
+
+require "webmock/rspec"
+
+# http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
+RSpec.configure do |config|
+ config.expect_with :rspec do |expectations|
+ expectations.syntax = :expect
+ end
+
+ config.mock_with :rspec do |mocks|
+ mocks.syntax = :expect
+ mocks.verify_partial_doubles = true
+ end
+
+ config.order = :random
+end
+
+WebMock.disable_net_connect!(allow_localhost: true)
diff --git a/spec/support/action_mailer.rb b/spec/support/action_mailer.rb
new file mode 100644
index 0000000..b9563a3
--- /dev/null
+++ b/spec/support/action_mailer.rb
@@ -0,0 +1,5 @@
+RSpec.configure do |config|
+ config.before(:each) do
+ ActionMailer::Base.deliveries.clear
+ end
+end
diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb
new file mode 100644
index 0000000..36dcc88
--- /dev/null
+++ b/spec/support/database_cleaner.rb
@@ -0,0 +1,21 @@
+RSpec.configure do |config|
+ config.before(:suite) do
+ DatabaseCleaner.clean_with(:deletion)
+ end
+
+ config.before(:each) do
+ DatabaseCleaner.strategy = :transaction
+ end
+
+ config.before(:each, js: true) do
+ DatabaseCleaner.strategy = :deletion
+ end
+
+ config.before(:each) do
+ DatabaseCleaner.start
+ end
+
+ config.after(:each) do
+ DatabaseCleaner.clean
+ end
+end
diff --git a/spec/support/factory_girl.rb b/spec/support/factory_girl.rb
new file mode 100644
index 0000000..eec437f
--- /dev/null
+++ b/spec/support/factory_girl.rb
@@ -0,0 +1,3 @@
+RSpec.configure do |config|
+ config.include FactoryGirl::Syntax::Methods
+end
diff --git a/spec/support/features/.keep b/spec/support/features/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/support/i18n.rb b/spec/support/i18n.rb
new file mode 100644
index 0000000..3d4094d
--- /dev/null
+++ b/spec/support/i18n.rb
@@ -0,0 +1,3 @@
+RSpec.configure do |config|
+ config.include AbstractController::Translation
+end
diff --git a/spec/support/matchers/.keep b/spec/support/matchers/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/support/mixins/.keep b/spec/support/mixins/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/support/shared_examples/.keep b/spec/support/shared_examples/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/vendor/assets/javascripts/.keep b/vendor/assets/javascripts/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep
new file mode 100644
index 0000000..e69de29