diff --git a/.gitignore b/.gitignore
index e38a997..bc8e397 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,7 @@
/tmp
coverage
.env
+
+.byebug_history
+
+*.lock
diff --git a/.rubocop.yml b/.rubocop.yml
index 7881188..ba12389 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -4,5 +4,5 @@ Documentation:
AllCops:
RunRailsCops: true
Exclude:
- - db/**
- - config/**
+ - db/**/*
+ - config/**/*
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..3d52269
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,4 @@
+language: ruby
+rvm:
+ - 2.2.3
+sudo: false
diff --git a/Gemfile b/Gemfile
index 11bdaf2..041e4c0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -2,6 +2,7 @@ source 'https://rubygems.org'
ruby '2.2.3'
gem 'rails', '4.2.5'
+gem 'bootstrap_form'
gem 'devise'
gem 'http_logger'
gem 'jquery-rails'
diff --git a/Gemfile.lock b/Gemfile.lock
index 0c46029..81efd61 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -47,6 +47,7 @@ GEM
bcrypt (3.1.10)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
+ bootstrap_form (2.3.0)
builder (3.2.2)
byebug (8.2.0)
capybara (2.5.0)
@@ -251,6 +252,7 @@ PLATFORMS
DEPENDENCIES
annotate
+ bootstrap_form
byebug
coveralls
devise
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..54b3c6b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,9 @@
+# QuickSubmit
+
+[](https://travis-ci.org/MITLibraries/QuickSubmit)
+[](https://gemnasium.com/MITLibraries/QuickSubmit)
+[](https://codeclimate.com/github/MITLibraries/QuickSubmit)
+
+## What is this?
+
+QuickSubmit will be a brief form where users can upload an article along with sparse metadata. This will be transformed into METS and then SWORD and submitted to an Institutional Repository (DSpace for now).
diff --git a/README.rdoc b/README.rdoc
deleted file mode 100644
index dd4e97e..0000000
--- a/README.rdoc
+++ /dev/null
@@ -1,28 +0,0 @@
-== README
-
-This README would normally document whatever steps are necessary to get the
-application up and running.
-
-Things you may want to cover:
-
-* Ruby version
-
-* System dependencies
-
-* Configuration
-
-* Database creation
-
-* Database initialization
-
-* How to run the test suite
-
-* Services (job queues, cache servers, search engines, etc.)
-
-* Deployment instructions
-
-* ...
-
-
-Please feel free to use a different markup language if you do not plan to run
-rake doc:app.
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index f9cd5b3..01154bc 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -12,4 +12,5 @@
*
*= require_tree .
*= require_self
+ *= require rails_bootstrap_forms
*/
diff --git a/app/assets/stylesheets/submission.css b/app/assets/stylesheets/submission.css
new file mode 100644
index 0000000..88a1e09
--- /dev/null
+++ b/app/assets/stylesheets/submission.css
@@ -0,0 +1,3 @@
+label.required:after {
+ content:" *";
+}
diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb
new file mode 100644
index 0000000..3db53b3
--- /dev/null
+++ b/app/controllers/submissions_controller.rb
@@ -0,0 +1,26 @@
+class SubmissionsController < ApplicationController
+ before_action :authenticate_user!
+
+ def new
+ @submission = Submission.new
+ @submission.user = current_user
+ end
+
+ def create
+ @submission = Submission.new(submission_params)
+ @submission.user = current_user
+ if @submission.save
+ flash.notice = 'Your Submission is now in progress.'
+ redirect_to root_path
+ else
+ render 'new'
+ end
+ end
+
+ private
+
+ def submission_params
+ params.require(:submission).permit(:title, :agreed_to_license, :author,
+ :journal, :doi, :grant_number, :doe)
+ end
+end
diff --git a/app/models/submission.rb b/app/models/submission.rb
new file mode 100644
index 0000000..25b5ace
--- /dev/null
+++ b/app/models/submission.rb
@@ -0,0 +1,23 @@
+# == Schema Information
+#
+# Table name: submissions
+#
+# id :integer not null, primary key
+# user_id :integer
+# title :string not null
+# journal :string
+# doi :string
+# author :string
+# doe :boolean
+# grant_number :string
+# agreed_to_license :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+class Submission < ActiveRecord::Base
+ belongs_to :user
+ validates :user, presence: true
+ validates :title, presence: true
+ validates :agreed_to_license, inclusion: { in: [true] }
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 44fd3a9..fdc0b96 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -11,6 +11,7 @@
class User < ActiveRecord::Base
devise :omniauthable, omniauth_providers: [:mit_oauth2]
+ has_many :submissions
def self.from_omniauth(auth)
where(uid: auth.uid).first_or_create do |user|
diff --git a/app/views/submissions/new.html.erb b/app/views/submissions/new.html.erb
new file mode 100644
index 0000000..ec132ae
--- /dev/null
+++ b/app/views/submissions/new.html.erb
@@ -0,0 +1,23 @@
+
MIT DSpace Quick Submit
+
+<%= bootstrap_form_for(@submission, layout: :horizontal, label_col: "col-sm-2", control_col: "col-sm-10") do |f| %>
+ <%= f.alert_message "Please fix the errors below." %>
+ <%= f.text_field :author %>
+ <%= f.text_field :title %>
+ <%= f.text_field :journal %>
+ <%= f.text_field :doi %>
+ <%= f.text_field :grant_number %>
+
+ <%= f.form_group :doe do %>
+ <%= f.check_box :doe, label: "This submission was funded in part by grants from the DOE." %>
+ <% end %>
+
+ <%= f.form_group :agreed_to_license do %>
+ <%= f.check_box :agreed_to_license,
+ label: "I am authorized to submit this article." %>
+ <% end %>
+
+ <%= f.form_group do %>
+ <%= f.submit %>
+ <% end %>
+<% end %>
diff --git a/config/routes.rb b/config/routes.rb
index f011ee0..1d64e32 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,10 +1,12 @@
Rails.application.routes.draw do
+ resources :submissions, only: [:new, :create]
+
devise_for :users, :controllers => {
:omniauth_callbacks => 'users/omniauth_callbacks'
}
devise_scope :user do
- get 'sign_in', to: 'devise/sessions#new', as: :new_user_session
+ get 'sign_in', to: 'devise/sessions#new', as: :user_session
delete 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
end
diff --git a/db/migrate/20151116184904_create_submissions.rb b/db/migrate/20151116184904_create_submissions.rb
new file mode 100644
index 0000000..6074429
--- /dev/null
+++ b/db/migrate/20151116184904_create_submissions.rb
@@ -0,0 +1,17 @@
+class CreateSubmissions < ActiveRecord::Migration
+ def change
+ create_table :submissions do |t|
+ t.belongs_to :user, index: true
+
+ t.string :title, null: false
+ t.string :journal
+ t.string :doi
+ t.string :author
+ t.boolean :doe
+ t.string :grant_number
+ t.boolean :agreed_to_license
+
+ t.timestamps null: false
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f719470..ae625f0 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,22 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150101010101) do
+ActiveRecord::Schema.define(version: 20151116184904) do
+
+ create_table "submissions", force: :cascade do |t|
+ t.integer "user_id"
+ t.string "title", null: false
+ t.string "journal"
+ t.string "doi"
+ t.string "author"
+ t.boolean "doe"
+ t.string "grant_number"
+ t.boolean "agreed_to_license"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ add_index "submissions", ["user_id"], name: "index_submissions_on_user_id"
create_table "users", force: :cascade do |t|
t.string "email", null: false
diff --git a/test/controllers/submissions_controller_test.rb b/test/controllers/submissions_controller_test.rb
new file mode 100644
index 0000000..52e7dd7
--- /dev/null
+++ b/test/controllers/submissions_controller_test.rb
@@ -0,0 +1,25 @@
+require 'test_helper'
+
+class SubmissionsControllerTest < ActionController::TestCase
+ test 'non signed in user should redirect to login requesting new' do
+ get :new
+ assert_response :redirect
+ end
+
+ test 'signed in user should get new' do
+ sign_in users(:one)
+ get :new
+ assert_response :success
+ end
+
+ test 'non signed in user should redirect to login posting to create' do
+ post :create
+ assert_response :redirect
+ end
+
+ test 'signed in user can post to create' do
+ sign_in users(:one)
+ post :create, submission: { 'title': '' }
+ assert_response :success
+ end
+end
diff --git a/test/features/static_test.rb b/test/features/static_test.rb
index fbc6483..560f652 100644
--- a/test/features/static_test.rb
+++ b/test/features/static_test.rb
@@ -15,8 +15,8 @@ def teardown
test 'sign in link' do
visit root_path
- assert page.has_link?('Sign in')
- refute page.has_link?('Sign out')
+ assert_link('Sign in')
+ refute_link('Sign out')
end
test 'sign out link' do
@@ -27,7 +27,7 @@ def teardown
visit '/users/auth/mit_oauth2/callback'
visit root_path
- assert page.has_link?('Sign out')
- refute page.has_link?('Sign in')
+ assert_link('Sign out')
+ refute_link('Sign in')
end
end
diff --git a/test/features/submission_test.rb b/test/features/submission_test.rb
new file mode 100644
index 0000000..3b55163
--- /dev/null
+++ b/test/features/submission_test.rb
@@ -0,0 +1,70 @@
+require 'test_helper'
+
+class SubmissionPagesTest < Capybara::Rails::TestCase
+ def setup
+ Rails.application.env_config['devise.mapping'] = Devise.mappings[:user]
+ Rails.application.env_config['omniauth.auth'] =
+ OmniAuth.config.mock_auth[:mit_oauth2]
+ OmniAuth.config.test_mode = true
+ end
+
+ def teardown
+ OmniAuth.config.test_mode = false
+ OmniAuth.config.mock_auth[:mit_oauth2] = nil
+ end
+
+ def mock_auth
+ OmniAuth.config.mock_auth[:mit_oauth2] =
+ OmniAuth::AuthHash.new(provider: 'mit_oauth2',
+ uid: '123545',
+ info: { email: 'bob@asdf.com' })
+ visit '/users/auth/mit_oauth2/callback'
+ end
+
+ test 'requires signed_in user' do
+ visit new_submission_path
+ assert_equal(root_path, current_path)
+ assert_text('Sign in')
+ assert_text('You need to sign in or sign up before continuing.')
+ end
+
+ test 'authenticated users can view the form' do
+ mock_auth
+ visit new_submission_path
+ assert_equal(new_submission_path, current_path)
+ end
+
+ test 'invalid form retains valid portions' do
+ mock_auth
+ visit new_submission_path
+ fill_in('Journal', with: 'Super Mega Journal')
+ click_on('Create Submission')
+ assert_text('Please fix the errors below')
+ assert_text("Title can't be blank")
+ assert_text('Agreed to license is not included in the list')
+ assert_selector("input[value='Super Mega Journal']")
+ end
+
+ test 'invalid form submit does not create new submissions' do
+ mock_auth
+ subs = Submission.count
+ visit new_submission_path
+ fill_in('Journal', with: 'Super Mega Journal')
+ click_on('Create Submission')
+ assert_equal(Submission.count, subs)
+ end
+
+ test 'valid form creates new submission' do
+ mock_auth
+ subs = Submission.count
+ visit new_submission_path
+ fill_in('Journal', with: 'Super Mega Journal')
+ fill_in('Title', with: 'Alphabetical Order is Good Enough')
+ check('I am authorized to submit this article.')
+ click_on('Create Submission')
+ assert_equal(Submission.count, (subs + 1))
+ assert_equal('bob@asdf.com', Submission.last.user.email)
+ assert_equal(root_path, current_path)
+ assert_text('Your Submission is now in progress')
+ end
+end
diff --git a/test/fixtures/submissions.yml b/test/fixtures/submissions.yml
new file mode 100644
index 0000000..d26161f
--- /dev/null
+++ b/test/fixtures/submissions.yml
@@ -0,0 +1,33 @@
+# == Schema Information
+#
+# Table name: submissions
+#
+# id :integer not null, primary key
+# user_id :integer
+# title :string not null
+# journal :string
+# doi :string
+# author :string
+# doe :boolean
+# grant_number :string
+# agreed_to_license :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+sub_one:
+ title: 'Popcorn is a fruit.'
+ agreed_to_license: true
+ user: one
+
+sub_two:
+ title: 'Simple Secret Substitution Songs'
+ user: two
+ journal: 'Journal of Popcorn Management'
+ doi: 'doi:10.10.1038/nphys1170'
+ author: 'Lastname, Firstname'
+ doe: true
+ grant_number: 'asdf123'
+ agreed_to_license: true
diff --git a/test/integration/authentication_test.rb b/test/integration/authentication_test.rb
index 0b22d60..66f4de6 100644
--- a/test/integration/authentication_test.rb
+++ b/test/integration/authentication_test.rb
@@ -15,7 +15,7 @@ def teardown
def silence_omniauth
previous_logger = OmniAuth.config.logger
- # OmniAuth.config.logger = Logger.new('/dev/null')
+ OmniAuth.config.logger = Logger.new('/dev/null')
yield
ensure
OmniAuth.config.logger = previous_logger
diff --git a/test/models/submission_test.rb b/test/models/submission_test.rb
new file mode 100644
index 0000000..e3f846c
--- /dev/null
+++ b/test/models/submission_test.rb
@@ -0,0 +1,43 @@
+# == Schema Information
+#
+# Table name: submissions
+#
+# id :integer not null, primary key
+# user_id :integer
+# title :string not null
+# journal :string
+# doi :string
+# author :string
+# doe :boolean
+# grant_number :string
+# agreed_to_license :boolean
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+require 'test_helper'
+
+class SubmissionTest < ActiveSupport::TestCase
+ test 'valid submission' do
+ sub = submissions(:sub_one)
+ assert sub.valid?
+ end
+
+ test 'invalid without title' do
+ sub = submissions(:sub_one)
+ sub.title = ''
+ assert_not sub.valid?
+ end
+
+ test 'invalid without user' do
+ sub = submissions(:sub_one)
+ sub.user_id = ''
+ assert_not sub.valid?
+ end
+
+ test 'invalid without agreed_to_license' do
+ sub = submissions(:sub_one)
+ sub.agreed_to_license = false
+ assert_not sub.valid?
+ end
+end