From e7658e984260a6c6622f7135977cff16f80906ee Mon Sep 17 00:00:00 2001 From: Roland Burrows Date: Wed, 31 Oct 2018 23:28:03 -0600 Subject: [PATCH 1/2] Add rubocop integration and automatically fix issues --- .rubocop.yml | 3 + Gemfile | 49 +-- Gemfile.lock | 24 ++ Rakefile | 2 +- app/controllers/api/v1/events_controller.rb | 397 +++++++++--------- app/controllers/api/v1/settings_controller.rb | 238 +++++------ app/controllers/api/v1/users_controller.rb | 395 +++++++++-------- app/controllers/application_controller.rb | 64 ++- app/controllers/assets_controller.rb | 76 ++-- app/controllers/receiver_controller.rb | 184 ++++---- app/models/event.rb | 18 +- app/models/user.rb | 48 +-- app/serializers/application_serializer.rb | 2 +- app/serializers/event_serializer.rb | 4 +- app/serializers/setting_serializer.rb | 4 +- app/serializers/user_serializer.rb | 4 +- bin/bundle | 2 +- bin/rails | 2 +- config.ru | 2 +- config/application.rb | 2 +- config/boot.rb | 2 +- config/environment.rb | 2 +- config/environments/test.rb | 2 +- .../initializers/active_model_serializer.rb | 10 +- config/initializers/version.rb | 2 +- config/routes.rb | 26 +- config/unicorn.rb | 12 +- db/migrate/20140822200153_create_events.rb | 48 +-- db/migrate/20140906160955_create_settings.rb | 16 +- db/migrate/20140906223942_create_users.rb | 21 +- ...0141014135702_add_asm_group_id_to_event.rb | 2 +- db/schema.rb | 79 ++-- db/seeds.rb | 21 +- lib/permissions.rb | 10 +- .../api/v1/events_controller_spec.rb | 275 ++++++------ .../api/v1/settings_controller_spec.rb | 215 +++++----- .../api/v1/users_controller_spec.rb | 313 +++++++------- spec/factories/events.rb | 42 +- spec/factories/settings.rb | 12 +- spec/factories/users.rb | 12 +- spec/rails_helper.rb | 9 +- spec/spec_helper.rb | 8 +- 42 files changed, 1310 insertions(+), 1349 deletions(-) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..d3f356e --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,3 @@ +AllCops: + Exclude: + - spec/**/* diff --git a/Gemfile b/Gemfile index 6319ae7..c55d44b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,39 +1,40 @@ source 'https://rubygems.org' group :development, :test do - gem 'sqlite3' - gem 'rspec' - gem 'rspec-rails' - gem 'factory_girl' - gem 'factory_girl_rails' - gem 'rspec_api_test' - gem 'pry-nav' - gem 'pry' + gem 'factory_girl' + gem 'factory_girl_rails' + gem 'pry' + gem 'pry-nav' + gem 'rspec' + gem 'rspec-rails' + gem 'rspec_api_test' + gem 'rubocop' + gem 'sqlite3' end group :production do - gem 'pg' - gem 'rails_12factor' + gem 'pg' + gem 'rails_12factor' end -gem 'unicorn' -gem 'json' +gem 'active_model_serializers', '>= 0.9.0' +gem 'bcrypt', '~> 3.1.7' gem 'bourbon' -gem 'rails', '4.0.8' -gem 'sass-rails', '~> 4.0.2' -gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' -gem 'jquery-rails' -gem 'turbolinks' -gem 'jbuilder', '~> 1.2' -gem 'bcrypt', '~> 3.1.7' -gem "active_model_serializers", '>= 0.9.0' -gem "ember-rails", "~>0.18" -gem 'ember-source', '~> 1.11.1' gem 'ember-data-source', '~> 1.0.0.beta' gem 'ember-handlebars-template', '~> 0.1.5' +gem 'ember-rails', '~>0.18' +gem 'ember-source', '~> 1.11.1' +gem 'jbuilder', '~> 1.2' +gem 'jquery-rails' +gem 'json' +gem 'rails', '4.0.8' +gem 'sass-rails', '~> 4.0.2' +gem 'turbolinks' +gem 'uglifier', '>= 1.3.0' +gem 'unicorn' group :doc do - gem 'sdoc', require: false + gem 'sdoc', require: false end -ruby "2.2.4" +ruby '2.2.4' diff --git a/Gemfile.lock b/Gemfile.lock index 535cc53..96d7667 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -28,6 +28,7 @@ GEM thread_safe (~> 0.1) tzinfo (~> 0.3.37) arel (4.0.2) + ast (2.4.0) barber (0.9.2) ember-source (>= 1.0, < 3) execjs (>= 1.2, < 3) @@ -71,6 +72,7 @@ GEM http-cookie (1.0.2) domain_name (~> 0.5) i18n (0.7.0) + jaro_winkler (1.5.1) jbuilder (1.5.3) activesupport (>= 3.0.0) multi_json (>= 1.2.0) @@ -87,8 +89,12 @@ GEM minitest (4.7.5) multi_json (1.11.2) netrc (0.10.3) + parallel (1.12.1) + parser (2.5.3.0) + ast (~> 2.4.0) pg (0.18.1) polyglot (0.3.5) + powerpack (0.1.2) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -116,6 +122,7 @@ GEM activesupport (= 4.0.8) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) + rainbow (3.0.0) raindrops (0.13.0) rake (10.4.2) rdoc (4.2.0) @@ -150,6 +157,15 @@ GEM bundler rest-client rspec (>= 2.0.0) + rubocop (0.60.0) + jaro_winkler (~> 1.5.1) + parallel (~> 1.10) + parser (>= 2.5, != 2.5.1.1) + powerpack (~> 0.1) + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.4.0) + ruby-progressbar (1.10.0) sass (3.2.19) sass-rails (4.0.5) railties (>= 4.0.0, < 5.0) @@ -185,6 +201,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.6) + unicode-display_width (1.4.0) unicorn (4.8.3) kgio (~> 2.6) rack @@ -215,9 +232,16 @@ DEPENDENCIES rspec rspec-rails rspec_api_test + rubocop sass-rails (~> 4.0.2) sdoc sqlite3 turbolinks uglifier (>= 1.3.0) unicorn + +RUBY VERSION + ruby 2.2.4p230 + +BUNDLED WITH + 1.16.2 diff --git a/Rakefile b/Rakefile index ea97e80..3dd1162 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,6 @@ # 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', __dir__) EventKit::Application.load_tasks diff --git a/app/controllers/api/v1/events_controller.rb b/app/controllers/api/v1/events_controller.rb index 3998380..f3439b7 100644 --- a/app/controllers/api/v1/events_controller.rb +++ b/app/controllers/api/v1/events_controller.rb @@ -2,206 +2,199 @@ require 'permissions' class Api::V1::EventsController < ApplicationController - - # ========================================================================== - # INDEX - # ========================================================================== - # TYPE: GET - # PATH: /events - # SUMMARY: Retrieves a list of all the Event records. - # - def index - query = params.except(:action, :controller, :offset, :limit, :descending, :sortby, :since, :like, :detailed, :format, :token) - - if params[:like] then - if params[:raw] then - # WILD CARD SEARCH - events = Event.where(["raw LIKE ?", "%#{query[:raw]}%"]) - elsif params[:detailed] then - # DETAILED SEARCH - details = JSON.parse params[:detailed] - - details.each do |key, values| - statement_array = [] - value_array = [] - - values.each do |value| - if key == "newsletter_id" or key == "newsletter_user_list_id" or key == "newsletter_send_id" - statement_array << "newsletter LIKE ?" - value_array << "%\"#{key}\":\"#{value}\"%" - - statement_array << "newsletter LIKE ?" - value_array << "%\"#{key}\":#{value}%" - elsif key == "additional_arguments" - hash = JSON.parse value - hash.each do |k, v| - statement_array << "additional_arguments LIKE ?" - value_array << "%\"#{k}\":\"#{v}\"%" - - statement_array << "additional_arguments LIKE ?" - value_array << "%\"#{k}\":#{v}%" - end - else - statement_array << "\"#{key}\" LIKE ?" - value_array << "%#{value}%" - end - end - - statement = statement_array.join(" OR ") - value_array.insert(0, statement) - - if events then - events = events.where(value_array) - else - events = Event.where(value_array) - end - end - end - - count = events.count - elsif query.keys.count then - # LOOK FOR SPECIFIC RECORDS - events = Event.where(query) - count = events.count - else - # RETRIEVE ALL RECORDS - events = [] - Event.find_each do |record| - events << record - end - count = events.count - end - - if params[:since] then - events = Event.where("timestamp > ?", params[:since].to_i) - end - - descending = false - - if params[:descending] then - descending_value = params[:descending].to_i - descending = descending_value != 0 - end - - if params[:sortby] then - ordering = descending ? 'DESC' : 'ASC' - events = events.order("#{params[:sortby]} #{ordering}") - elsif descending then - events = events.order("id DESC") - end - - if params[:limit] then - events = events.limit(params[:limit]) - end - - if params[:offset] then - events = events.offset(params[:offset]) - end - - respond_to do |format| - format.html { - self.user_has_permissions(Permissions::VIEW) do - render json: { - :events => events, - :meta => { - :total => count - } - } - end - } - format.csv { - self.user_has_permissions(Permissions::DOWNLOAD) do - send_data events.to_csv - end - } - end - end - - # ========================================================================== - # CREATE - # ========================================================================== - # TYPE: POST - # PATH: /events - # SUMMARY: Creates a new Event record with the given parameters. - # - def create - self.user_has_permissions(Permissions::POST) do - properties = event_params(params) - record = Event.create(properties) - render json: record - end - end - - # ========================================================================== - # SHOW - # ========================================================================== - # TYPE: GET - # PATH: /events/:id - # SUMMARY: Retrieves a specific Event record. - # - def show - self.user_has_permissions(Permissions::VIEW) do - if Event.where(id: params[:id]).present? then - event = Event.find(params[:id]) - render json: event - else - render json: { - :message => :error, - :error => "Event record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - # ========================================================================== - # UPDATE - # ========================================================================== - # TYPE: PUT - # PATH: /events/:id - # SUMMARY: Updates a specific Event record with given parameters. - # - def update - self.user_has_permissions(Permissions::EDIT) do - id = params[:id] - if Event.where(id: id).present? then - event = Event.find(id) - event.update(event_params(params)) - render json: event - else - render json: { - :message => :error, - :error => "Event record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - # ========================================================================== - # DESTROY - # ========================================================================== - # TYPE: DELETE - # PATH: /events/:id - # SUMMARY: Destroys a specific Event record. - # - def destroy - self.user_has_permissions(Permissions::EDIT) do - id = params[:id] - if Event.where(id: id).present? then - event = Event.find(id) - event.destroy - render json: {} - else - render json: { - :message => :error, - :error => "Event record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - private - def event_params(params) - params.require(:event).permit(:timestamp, :event, :email, :"smtp-id", :sg_event_id, :sg_message_id, :category, :newsletter, :response, :reason, :ip, :useragent, :attempt, :status, :type, :url, :additional_arguments, :event_post_timestamp, :raw, :asm_group_id) - end - + # ========================================================================== + # INDEX + # ========================================================================== + # TYPE: GET + # PATH: /events + # SUMMARY: Retrieves a list of all the Event records. + # + def index + query = params.except(:action, :controller, :offset, :limit, :descending, :sortby, :since, :like, :detailed, :format, :token) + + if params[:like] + if params[:raw] + # WILD CARD SEARCH + events = Event.where(['raw LIKE ?', "%#{query[:raw]}%"]) + elsif params[:detailed] + # DETAILED SEARCH + details = JSON.parse params[:detailed] + + details.each do |key, values| + statement_array = [] + value_array = [] + + values.each do |value| + if (key == 'newsletter_id') || (key == 'newsletter_user_list_id') || (key == 'newsletter_send_id') + statement_array << 'newsletter LIKE ?' + value_array << "%\"#{key}\":\"#{value}\"%" + + statement_array << 'newsletter LIKE ?' + value_array << "%\"#{key}\":#{value}%" + elsif key == 'additional_arguments' + hash = JSON.parse value + hash.each do |k, v| + statement_array << 'additional_arguments LIKE ?' + value_array << "%\"#{k}\":\"#{v}\"%" + + statement_array << 'additional_arguments LIKE ?' + value_array << "%\"#{k}\":#{v}%" + end + else + statement_array << "\"#{key}\" LIKE ?" + value_array << "%#{value}%" + end + end + + statement = statement_array.join(' OR ') + value_array.insert(0, statement) + + events = if events + events.where(value_array) + else + Event.where(value_array) + end + end + end + + count = events.count + elsif query.keys.count + # LOOK FOR SPECIFIC RECORDS + events = Event.where(query) + count = events.count + else + # RETRIEVE ALL RECORDS + events = [] + Event.find_each do |record| + events << record + end + count = events.count + end + + events = Event.where('timestamp > ?', params[:since].to_i) if params[:since] + + descending = false + + if params[:descending] + descending_value = params[:descending].to_i + descending = descending_value != 0 + end + + if params[:sortby] + ordering = descending ? 'DESC' : 'ASC' + events = events.order("#{params[:sortby]} #{ordering}") + elsif descending + events = events.order('id DESC') + end + + events = events.limit(params[:limit]) if params[:limit] + + events = events.offset(params[:offset]) if params[:offset] + + respond_to do |format| + format.html do + user_has_permissions(Permissions::VIEW) do + render json: { + events: events, + meta: { + total: count + } + } + end + end + format.csv do + user_has_permissions(Permissions::DOWNLOAD) do + send_data events.to_csv + end + end + end + end + + # ========================================================================== + # CREATE + # ========================================================================== + # TYPE: POST + # PATH: /events + # SUMMARY: Creates a new Event record with the given parameters. + # + def create + user_has_permissions(Permissions::POST) do + properties = event_params(params) + record = Event.create(properties) + render json: record + end + end + + # ========================================================================== + # SHOW + # ========================================================================== + # TYPE: GET + # PATH: /events/:id + # SUMMARY: Retrieves a specific Event record. + # + def show + user_has_permissions(Permissions::VIEW) do + if Event.where(id: params[:id]).present? + event = Event.find(params[:id]) + render json: event + else + render json: { + message: :error, + error: "Event record with ID #{params[:id]} not found." + }, status: 404 + end + end + end + + # ========================================================================== + # UPDATE + # ========================================================================== + # TYPE: PUT + # PATH: /events/:id + # SUMMARY: Updates a specific Event record with given parameters. + # + def update + user_has_permissions(Permissions::EDIT) do + id = params[:id] + if Event.where(id: id).present? + event = Event.find(id) + event.update(event_params(params)) + render json: event + else + render json: { + message: :error, + error: "Event record with ID #{params[:id]} not found." + }, status: 404 + end + end + end + + # ========================================================================== + # DESTROY + # ========================================================================== + # TYPE: DELETE + # PATH: /events/:id + # SUMMARY: Destroys a specific Event record. + # + def destroy + user_has_permissions(Permissions::EDIT) do + id = params[:id] + if Event.where(id: id).present? + event = Event.find(id) + event.destroy + render json: {} + else + render json: { + message: :error, + error: "Event record with ID #{params[:id]} not found." + }, status: 404 + end + end + end + + private + + def event_params(params) + params.require(:event).permit(:timestamp, :event, :email, :"smtp-id", :sg_event_id, :sg_message_id, :category, :newsletter, :response, :reason, :ip, :useragent, :attempt, :status, :type, :url, :additional_arguments, :event_post_timestamp, :raw, :asm_group_id) + end end diff --git a/app/controllers/api/v1/settings_controller.rb b/app/controllers/api/v1/settings_controller.rb index c6ba931..bb802b0 100644 --- a/app/controllers/api/v1/settings_controller.rb +++ b/app/controllers/api/v1/settings_controller.rb @@ -1,137 +1,131 @@ class Api::V1::SettingsController < ApplicationController + # ========================================================================== + # INDEX + # ========================================================================== + # TYPE: GET + # PATH: /settings + # SUMMARY: Retrieves a list of all the Setting records. + # + def index + query = params.except(:action, :controller, :offset, :limit, :descending, :sortby) + if query.keys.count + # LOOK FOR SPECIFIC RECORDS + settings = Setting.where(query) + else + # RETRIEVE ALL RECORDS + settings = [] + Setting.find_each do |record| + settings << record + end + end - # ========================================================================== - # INDEX - # ========================================================================== - # TYPE: GET - # PATH: /settings - # SUMMARY: Retrieves a list of all the Setting records. - # - def index - query = params.except(:action, :controller, :offset, :limit, :descending, :sortby) + descending = false - if query.keys.count then - # LOOK FOR SPECIFIC RECORDS - settings = Setting.where(query) - else - # RETRIEVE ALL RECORDS - settings = [] - Setting.find_each do |record| - settings << record - end - end + if params[:descending] + descending = params[:descending] == 'true' || params[:descending] == '1' + end - descending = false + if params[:sortby] + ordering = descending ? 'DESC' : 'ASC' + settings = settings.order("#{params[:sortby]} #{ordering}") + elsif descending + settings = settings.order('id DESC') + end - if params[:descending] then - descending = params[:descending] == 'true' || params[:descending] == '1' - end + settings = settings.limit(params[:limit]) if params[:limit] - if params[:sortby] then - ordering = descending ? 'DESC' : 'ASC' - settings = settings.order("#{params[:sortby]} #{ordering}") - elsif descending then - settings = settings.order("id DESC") - end + settings = settings.offset(params[:offset]) if params[:offset] - if params[:limit] then - settings = settings.limit(params[:limit]) - end + render json: { + settings: settings, + meta: { + total: Setting.where(query).count + } + } + end - if params[:offset] then - settings = settings.offset(params[:offset]) - end + # ========================================================================== + # CREATE + # ========================================================================== + # TYPE: POST + # PATH: /settings + # SUMMARY: Creates a new Setting record with the given parameters. + # + def create + properties = setting_params(params) + record = Setting.create(properties) + render json: record + end - render json: { - :settings => settings, - :meta => { - :total => Setting.where(query).count - } - } - end + # ========================================================================== + # SHOW + # ========================================================================== + # TYPE: GET + # PATH: /settings/:id + # SUMMARY: Retrieves a specific Setting record. + # + def show + if Setting.where(id: params[:id]).present? + setting = Setting.find(params[:id]) + render json: setting + else + render json: { + message: :error, + error: "Setting record with ID #{params[:id]} not found." + }, status: 404 + end + end - # ========================================================================== - # CREATE - # ========================================================================== - # TYPE: POST - # PATH: /settings - # SUMMARY: Creates a new Setting record with the given parameters. - # - def create - properties = setting_params(params) - record = Setting.create(properties) - render json: record - end + # ========================================================================== + # UPDATE + # ========================================================================== + # TYPE: PUT + # PATH: /settings/:id + # SUMMARY: Updates a specific Setting record with given parameters. + # + def update + user_has_permissions(Permissions::EDIT) do + id = params[:id] + if Setting.where(id: id).present? + setting = Setting.find(id) + setting.update(setting_params(params)) + render json: setting + else + render json: { + message: :error, + error: "Setting record with ID #{params[:id]} not found." + }, status: 404 + end + end + end - # ========================================================================== - # SHOW - # ========================================================================== - # TYPE: GET - # PATH: /settings/:id - # SUMMARY: Retrieves a specific Setting record. - # - def show - if Setting.where(id: params[:id]).present? then - setting = Setting.find(params[:id]) - render json: setting - else - render json: { - :message => :error, - :error => "Setting record with ID #{params[:id]} not found." - }, :status => 404 - end - end + # ========================================================================== + # DESTROY + # ========================================================================== + # TYPE: DELETE + # PATH: /settings/:id + # SUMMARY: Destroys a specific Setting record. + # + def destroy + user_has_permissions(Permissions::EDIT) do + id = params[:id] + if Setting.where(id: id).present? + setting = Setting.find(id) + setting.destroy + render json: {} + else + render json: { + message: :error, + error: "Setting record with ID #{params[:id]} not found." + }, status: 404 + end + end + end - # ========================================================================== - # UPDATE - # ========================================================================== - # TYPE: PUT - # PATH: /settings/:id - # SUMMARY: Updates a specific Setting record with given parameters. - # - def update - self.user_has_permissions(Permissions::EDIT) do - id = params[:id] - if Setting.where(id: id).present? then - setting = Setting.find(id) - setting.update(setting_params(params)) - render json: setting - else - render json: { - :message => :error, - :error => "Setting record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - # ========================================================================== - # DESTROY - # ========================================================================== - # TYPE: DELETE - # PATH: /settings/:id - # SUMMARY: Destroys a specific Setting record. - # - def destroy - self.user_has_permissions(Permissions::EDIT) do - id = params[:id] - if Setting.where(id: id).present? then - setting = Setting.find(id) - setting.destroy - render json: {} - else - render json: { - :message => :error, - :error => "Setting record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - private - def setting_params(params) - params.require(:setting).permit(:name, :value) - end + private + def setting_params(params) + params.require(:setting).permit(:name, :value) + end end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index cafe6e4..6e3dbe0 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -2,205 +2,198 @@ require 'bcrypt' class Api::V1::UsersController < ApplicationController - - include ::BCrypt - - # ========================================================================== - # INDEX - # ========================================================================== - # TYPE: GET - # PATH: /users - # SUMMARY: Retrieves a list of all the User records. - # - def index - def find_users - query = params.except(:action, :controller, :offset, :limit, :descending, :sortby) - - if query.keys.count then - # LOOK FOR SPECIFIC RECORDS - users = User.where(query) - else - # RETRIEVE ALL RECORDS - users = [] - User.find_each do |record| - users << record - end - end - - descending = false - - if params[:descending] then - descending = params[:descending] == 'true' || params[:descending] == '1' - end - - if params[:sortby] then - ordering = descending ? 'DESC' : 'ASC' - users = users.order("#{params[:sortby]} #{ordering}") - elsif descending then - users = users.order("id DESC") - end - - if params[:limit] then - users = users.limit(params[:limit]) - end - - if params[:offset] then - users = users.offset(params[:offset]) - end - - render json: { - :users => users.as_json(except: [:password, :token_expires]), - :meta => { - :total => User.where(query).count - } - } - end - - if User.count == 0 - find_users - else - self.user_has_permissions(Permissions::EDIT) do - find_users - end - end - end - - # ========================================================================== - # CREATE - # ========================================================================== - # TYPE: POST - # PATH: /users - # SUMMARY: Creates a new User record with the given parameters. - # - def create - - def new_user - properties = user_params(params) - - if properties[:password] - properties[:password] = Password.create(properties[:password]) - end - - if User.count == 0 - properties[:permissions] = Permissions::VIEW | Permissions::EDIT | Permissions::DOWNLOAD | Permissions::POST - end - if properties[:username] - self.check_for_duplicate_username(properties[:username], nil) do - record = User.create(properties) - record.issue_token - record.save - render json: record - end - end - end - - if User.count == 0 - new_user - else - self.user_has_permissions(Permissions::EDIT) do - new_user - end - end - end - - # ========================================================================== - # SHOW - # ========================================================================== - # TYPE: GET - # PATH: /users/:id - # SUMMARY: Retrieves a specific User record. - # - def show - self.user_has_permissions(Permissions::EDIT) do - if User.where(id: params[:id]).present? then - user = User.find(params[:id]) - render json: user - else - render json: { - :message => :error, - :error => "User record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - # ========================================================================== - # UPDATE - # ========================================================================== - # TYPE: PUT - # PATH: /users/:id - # SUMMARY: Updates a specific User record with given parameters. - # - def update - self.user_has_permissions(Permissions::EDIT) do - id = params[:id].to_i - if User.where(id: id).present? then - user = User.find(id) - - properties = user_params(params) - - if properties[:password] - properties[:password] = Password.create(properties[:password]) - end - - if properties[:username] - self.check_for_duplicate_username(properties[:username], id) do - user.update(properties) - render json: user - end - end - else - render json: { - :message => :error, - :error => "User record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - def check_for_duplicate_username(username, id, &block) - if User.where(username: username).present? then - user = User.where(username: username).first - if user.id == id - if block - block.call - end - else - render json: { - :message => :error, - :error => "A user with username \"#{username}\" already exists." - }, :status => 409 - end - elsif block - block.call - end - end - - # ========================================================================== - # DESTROY - # ========================================================================== - # TYPE: DELETE - # PATH: /users/:id - # SUMMARY: Destroys a specific User record. - # - def destroy - self.user_has_permissions(Permissions::EDIT) do - id = params[:id] - if User.where(id: id).present? then - user = User.find(id) - user.destroy - render json: {} - else - render json: { - :message => :error, - :error => "User record with ID #{params[:id]} not found." - }, :status => 404 - end - end - end - - private - def user_params(params) - params.require(:user).permit(:username, :password, :permissions) - end + include ::BCrypt + + # ========================================================================== + # INDEX + # ========================================================================== + # TYPE: GET + # PATH: /users + # SUMMARY: Retrieves a list of all the User records. + # + def index + def find_users + query = params.except(:action, :controller, :offset, :limit, :descending, :sortby) + + if query.keys.count + # LOOK FOR SPECIFIC RECORDS + users = User.where(query) + else + # RETRIEVE ALL RECORDS + users = [] + User.find_each do |record| + users << record + end + end + + descending = false + + if params[:descending] + descending = params[:descending] == 'true' || params[:descending] == '1' + end + + if params[:sortby] + ordering = descending ? 'DESC' : 'ASC' + users = users.order("#{params[:sortby]} #{ordering}") + elsif descending + users = users.order('id DESC') + end + + users = users.limit(params[:limit]) if params[:limit] + + users = users.offset(params[:offset]) if params[:offset] + + render json: { + users: users.as_json(except: %i[password token_expires]), + meta: { + total: User.where(query).count + } + } + end + + if User.count == 0 + find_users + else + user_has_permissions(Permissions::EDIT) do + find_users + end + end + end + + # ========================================================================== + # CREATE + # ========================================================================== + # TYPE: POST + # PATH: /users + # SUMMARY: Creates a new User record with the given parameters. + # + def create + def new_user + properties = user_params(params) + + if properties[:password] + properties[:password] = Password.create(properties[:password]) + end + + if User.count == 0 + properties[:permissions] = Permissions::VIEW | Permissions::EDIT | Permissions::DOWNLOAD | Permissions::POST + end + if properties[:username] + check_for_duplicate_username(properties[:username], nil) do + record = User.create(properties) + record.issue_token + record.save + render json: record + end + end + end + + if User.count == 0 + new_user + else + user_has_permissions(Permissions::EDIT) do + new_user + end + end + end + + # ========================================================================== + # SHOW + # ========================================================================== + # TYPE: GET + # PATH: /users/:id + # SUMMARY: Retrieves a specific User record. + # + def show + user_has_permissions(Permissions::EDIT) do + if User.where(id: params[:id]).present? + user = User.find(params[:id]) + render json: user + else + render json: { + message: :error, + error: "User record with ID #{params[:id]} not found." + }, status: 404 + end + end + end + + # ========================================================================== + # UPDATE + # ========================================================================== + # TYPE: PUT + # PATH: /users/:id + # SUMMARY: Updates a specific User record with given parameters. + # + def update + user_has_permissions(Permissions::EDIT) do + id = params[:id].to_i + if User.where(id: id).present? + user = User.find(id) + + properties = user_params(params) + + if properties[:password] + properties[:password] = Password.create(properties[:password]) + end + + if properties[:username] + check_for_duplicate_username(properties[:username], id) do + user.update(properties) + render json: user + end + end + else + render json: { + message: :error, + error: "User record with ID #{params[:id]} not found." + }, status: 404 + end + end + end + + def check_for_duplicate_username(username, id, &block) + if User.where(username: username).present? + user = User.where(username: username).first + if user.id == id + yield if block + else + render json: { + message: :error, + error: "A user with username \"#{username}\" already exists." + }, status: 409 + end + elsif block + yield + end + end + + # ========================================================================== + # DESTROY + # ========================================================================== + # TYPE: DELETE + # PATH: /users/:id + # SUMMARY: Destroys a specific User record. + # + def destroy + user_has_permissions(Permissions::EDIT) do + id = params[:id] + if User.where(id: id).present? + user = User.find(id) + user.destroy + render json: {} + else + render json: { + message: :error, + error: "User record with ID #{params[:id]} not found." + }, status: 404 + end + end + end + + private + + def user_params(params) + params.require(:user).permit(:username, :password, :permissions) + end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 49f0a63..e089040 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,37 +1,35 @@ 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: :null_session + # Prevent CSRF attacks by raising an exception. + # For APIs, you may want to use :null_session instead. + # protect_from_forgery with: :null_session - def user_has_permissions(permission_level_needed, &block) - token = request.headers["X-Auth-Token"] - if !token and params[:token] then - token = params[:token] - end - permitted = true - if User.where(token: token).present? then - user = User.where(token: token).first - permitted = (user.permissions & permission_level_needed) == permission_level_needed - else - permitted = false - end + def user_has_permissions(permission_level_needed, &block) + token = request.headers['X-Auth-Token'] + token = params[:token] if !token && params[:token] + permitted = true + if User.where(token: token).present? + user = User.where(token: token).first + permitted = (user.permissions & permission_level_needed) == permission_level_needed + else + permitted = false + end - if block then - if permitted then - block.call - else - render json: { - :message => :error, - :error => "Unauthorized access." - }, :status => 401 - end - else - return permitted - end - end + if block + if permitted + yield + else + render json: { + message: :error, + error: 'Unauthorized access.' + }, status: 401 + end + else + return permitted + end + end - def user_from_token - token = request.headers["X-Auth-Token"] - User.where(token: token).first - end -end \ No newline at end of file + def user_from_token + token = request.headers['X-Auth-Token'] + User.where(token: token).first + end +end diff --git a/app/controllers/assets_controller.rb b/app/controllers/assets_controller.rb index 1686419..1d9e514 100644 --- a/app/controllers/assets_controller.rb +++ b/app/controllers/assets_controller.rb @@ -9,42 +9,42 @@ require 'permissions' class AssetsController < ApplicationController - before_filter :authenticate - - include BCrypt - - def authenticate - if User.count > 0 then - - if cookies['auth_token'] and User.where(token: cookies['auth_token']) - found_user = User.where(token: cookies['auth_token']).first - unless found_user.is_token_expired - found_user.renew_expiration - @user = found_user - return - end - end - - authenticate_or_request_with_http_basic('Authorized users only') do |u, p| - valid = false - - if User.where(username: u).present? - User.where(username: u).each do |user| - if Password.new(user.password).is_password? p and (user.permissions & Permissions::VIEW == Permissions::VIEW) - valid = true - user.issue_token - @user = user - end - end - end - - valid - end - end - end - - def index - @version = VERSION - cookies['auth_token'] = { :value => @user.token, :expires => Time.at(@user.token_expires) } unless @user.nil? - end + before_filter :authenticate + + include BCrypt + + def authenticate + if User.count > 0 + + if cookies['auth_token'] && User.where(token: cookies['auth_token']) + found_user = User.where(token: cookies['auth_token']).first + unless found_user.is_token_expired + found_user.renew_expiration + @user = found_user + return + end + end + + authenticate_or_request_with_http_basic('Authorized users only') do |u, p| + valid = false + + if User.where(username: u).present? + User.where(username: u).each do |user| + next unless Password.new(user.password).is_password?(p) && (user.permissions & Permissions::VIEW == Permissions::VIEW) + + valid = true + user.issue_token + @user = user + end + end + + valid + end + end + end + + def index + @version = VERSION + cookies['auth_token'] = { value: @user.token, expires: Time.at(@user.token_expires) } unless @user.nil? + end end diff --git a/app/controllers/receiver_controller.rb b/app/controllers/receiver_controller.rb index 1d1876d..4afcb05 100644 --- a/app/controllers/receiver_controller.rb +++ b/app/controllers/receiver_controller.rb @@ -9,98 +9,94 @@ require 'permissions' class ReceiverController < ApplicationController - - before_filter :header_check - - include BCrypt - - def header_check - agent = request.headers["User-Agent"] - if agent == "SendGrid Event API" or agent == "SendGrid Event API Test" - if User.count > 0 then - authenticate_or_request_with_http_basic('Authorized users only') do |u, p| - valid = false - - if User.where(username: u).present? - User.where(username: u).each do |user| - if Password.new(user.password).is_password? p and (user.permissions & Permissions::POST == Permissions::POST) - valid = true - user.issue_token - end - end - end - - valid - end - end - else - render json: { - :message => :error, - :error => "Request rejected." - }, :status => 403 - end - end - - def handle_post - # Handle Post - if params[:_json] then - events = params[:_json] - columns = Event.columns_hash - - events.each do |event| - props = { - "raw" => event.to_json, - "event_post_timestamp" => Time.now.to_i - } - - unique_args = Hash.new - - event.each do |key, value| - next if key == "id" - - if key == "type" then - props["type_id"] = value - elsif columns[key] then - if value.is_a? String then - value = value.gsub(/\\\//,"/") - elsif value.is_a? Array or value.is_a? Hash then - value = value.to_json - end - props[key] = value - else - unique_args[key] = to_string(value) - end - end - - props["additional_arguments"] = unique_args.to_json - Event.create(props) - end - - render json: { - :message => :"Post accepted" - } - else - render json: { - :message => :error, - :error => "Unexpected content-type. Expecting JSON." - }, status => 400 - end - - # Delete Old Records - if Setting.where(name: 'autodelete_time').present? - value = Setting.where(name: 'autodelete_time').first.value.to_i - if value > 0 - now = Time.now.to_i - threshold = now - (value * 30 * 24 * 60 * 60) - Event.where(["timestamp < ?", threshold]).each do |event| - event.destroy - end - end - end - end - - def to_string(value) - (value.is_a? Array or value.is_a? Hash) ? value.to_json : value - end - + before_filter :header_check + + include BCrypt + + def header_check + agent = request.headers['User-Agent'] + if (agent == 'SendGrid Event API') || (agent == 'SendGrid Event API Test') + if User.count > 0 + authenticate_or_request_with_http_basic('Authorized users only') do |u, p| + valid = false + + if User.where(username: u).present? + User.where(username: u).each do |user| + if Password.new(user.password).is_password?(p) && (user.permissions & Permissions::POST == Permissions::POST) + valid = true + user.issue_token + end + end + end + + valid + end + end + else + render json: { + message: :error, + error: 'Request rejected.' + }, status: 403 + end + end + + def handle_post + # Handle Post + if params[:_json] + events = params[:_json] + columns = Event.columns_hash + + events.each do |event| + props = { + 'raw' => event.to_json, + 'event_post_timestamp' => Time.now.to_i + } + + unique_args = {} + + event.each do |key, value| + next if key == 'id' + + if key == 'type' + props['type_id'] = value + elsif columns[key] + if value.is_a? String + value = value.gsub(/\\\//, '/') + elsif value.is_a?(Array) || value.is_a?(Hash) + value = value.to_json + end + props[key] = value + else + unique_args[key] = to_string(value) + end + end + + props['additional_arguments'] = unique_args.to_json + Event.create(props) + end + + render json: { + message: :"Post accepted" + } + else + render json: { + message: :error, + error: 'Unexpected content-type. Expecting JSON.' + }, status => 400 + end + + # Delete Old Records + if Setting.where(name: 'autodelete_time').present? + value = Setting.where(name: 'autodelete_time').first.value.to_i + if value > 0 + now = Time.now.to_i + threshold = now - (value * 30 * 24 * 60 * 60) + Event.where(['timestamp < ?', threshold]).each(&:destroy) + end + end + end + + def to_string(value) + value.is_a?(Array) || value.is_a?(Hash) ? value.to_json : value + end end diff --git a/app/models/event.rb b/app/models/event.rb index 085527e..f441db4 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,12 +1,10 @@ class Event < ActiveRecord::Base - - def self.to_csv - CSV.generate do |csv| - csv << column_names - all.each do |event| - csv << event.attributes.values_at(*column_names) - end - end - end - + def self.to_csv + CSV.generate do |csv| + csv << column_names + all.each do |event| + csv << event.attributes.values_at(*column_names) + end + end + end end diff --git a/app/models/user.rb b/app/models/user.rb index ac4736e..17cae08 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,29 +1,27 @@ class User < ActiveRecord::Base + def issue_token + now = Time.now.to_i + token = self.token + if now > token_expires + self.token = loop do + token = SecureRandom.urlsafe_base64(nil, false) + break token unless User.exists?(token: token) + end + self.token = token + renew_expiration + end + save + end - def issue_token - now = Time.now.to_i - token = self.token - if now > self.token_expires then - self.token = loop do - token = SecureRandom.urlsafe_base64(nil, false) - break token unless (User.exists?(token: token)) - end - self.token = token - self.renew_expiration - end - self.save - end - - def renew_expiration - days = 7 - now = Time.now.to_i - self.token_expires = now + (days * 24 * 60 * 60) - self.save - end - - def is_token_expired - now = Time.now.to_i - return now > self.token_expires - end + def renew_expiration + days = 7 + now = Time.now.to_i + self.token_expires = now + (days * 24 * 60 * 60) + save + end + def is_token_expired + now = Time.now.to_i + now > token_expires + end end diff --git a/app/serializers/application_serializer.rb b/app/serializers/application_serializer.rb index 860f73d..a9e3708 100644 --- a/app/serializers/application_serializer.rb +++ b/app/serializers/application_serializer.rb @@ -1,3 +1,3 @@ class ApplicationSerializer < ActiveModel::Serializer - attributes :id + attributes :id end diff --git a/app/serializers/event_serializer.rb b/app/serializers/event_serializer.rb index 270d629..30a781f 100644 --- a/app/serializers/event_serializer.rb +++ b/app/serializers/event_serializer.rb @@ -1,4 +1,4 @@ class EventSerializer < ActiveModel::Serializer - # Included attributes - attributes :id, :timestamp, :event, :email, :"smtp-id", :sg_event_id, :sg_message_id, :category, :newsletter, :response, :reason, :ip, :useragent, :attempt, :status, :type_id, :url, :additional_arguments, :event_post_timestamp, :raw, :asm_group_id + # Included attributes + attributes :id, :timestamp, :event, :email, :"smtp-id", :sg_event_id, :sg_message_id, :category, :newsletter, :response, :reason, :ip, :useragent, :attempt, :status, :type_id, :url, :additional_arguments, :event_post_timestamp, :raw, :asm_group_id end diff --git a/app/serializers/setting_serializer.rb b/app/serializers/setting_serializer.rb index 338506d..fd10eb4 100644 --- a/app/serializers/setting_serializer.rb +++ b/app/serializers/setting_serializer.rb @@ -1,4 +1,4 @@ class SettingSerializer < ActiveModel::Serializer - # Included attributes - attributes :id, :name, :value + # Included attributes + attributes :id, :name, :value end diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index 9e8677d..769f2aa 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -1,4 +1,4 @@ class UserSerializer < ApplicationSerializer - # Included attributes - attributes :id, :username, :permissions, :token + # Included attributes + attributes :id, :username, :permissions, :token end diff --git a/bin/bundle b/bin/bundle index 66e9889..f19acf5 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,3 @@ #!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails index 728cd85..0739660 100755 --- a/bin/rails +++ b/bin/rails @@ -1,4 +1,4 @@ #!/usr/bin/env ruby -APP_PATH = File.expand_path('../../config/application', __FILE__) +APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands' diff --git a/config.ru b/config.ru index 5bc2a61..bd83b25 100644 --- a/config.ru +++ b/config.ru @@ -1,4 +1,4 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require ::File.expand_path('../config/environment', __FILE__) run Rails.application diff --git a/config/application.rb b/config/application.rb index a8845f1..c85f8e7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,4 +1,4 @@ -require File.expand_path('../boot', __FILE__) +require File.expand_path('boot', __dir__) require 'rails/all' diff --git a/config/boot.rb b/config/boot.rb index 5e5f0c1..126c4a8 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,4 +1,4 @@ # Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) diff --git a/config/environment.rb b/config/environment.rb index 785aadd..bba177f 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,5 @@ # Load the Rails application. -require File.expand_path('../application', __FILE__) +require File.expand_path('application', __dir__) # Initialize the Rails application. EventKit::Application.initialize! diff --git a/config/environments/test.rb b/config/environments/test.rb index 64111b9..383421b 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -14,7 +14,7 @@ # Configure static asset server for tests with Cache-Control for performance. config.serve_static_assets = true - config.static_cache_control = "public, max-age=3600" + config.static_cache_control = 'public, max-age=3600' # Show full error reports and disable caching. config.consider_all_requests_local = true diff --git a/config/initializers/active_model_serializer.rb b/config/initializers/active_model_serializer.rb index fc3300a..fff26a1 100644 --- a/config/initializers/active_model_serializer.rb +++ b/config/initializers/active_model_serializer.rb @@ -1,7 +1,7 @@ # ========================================================================== -# Active Model Serializer +# Active Model Serializer # ========================================================================== -# This file sets up the ActiveModel Serializer to include the ids of +# This file sets up the ActiveModel Serializer to include the ids of # relationships. # # This file should be stored at: @@ -9,6 +9,6 @@ # ActiveModel::Serializer.setup do |config| - config.embed = :ids - config.embed_in_root = true -end \ No newline at end of file + config.embed = :ids + config.embed_in_root = true +end diff --git a/config/initializers/version.rb b/config/initializers/version.rb index c9ad603..20a3206 100644 --- a/config/initializers/version.rb +++ b/config/initializers/version.rb @@ -1 +1 @@ -VERSION = "1.1.2" \ No newline at end of file +VERSION = '1.1.2'.freeze diff --git a/config/routes.rb b/config/routes.rb index 8e133f4..33abbb5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,18 +1,18 @@ EventKit::Application.routes.draw do - root :to => 'assets#index' - get "assets/index" - post "/" => 'receiver#handle_post' + root to: 'assets#index' + get 'assets/index' + post '/' => 'receiver#handle_post' - namespace :api do - namespace :v1 do - # Events - resources :events + namespace :api do + namespace :v1 do + # Events + resources :events - # Settings - resources :settings + # Settings + resources :settings - # Users - resources :users - end - end + # Users + resources :users + end + end end diff --git a/config/unicorn.rb b/config/unicorn.rb index 80c4fd0..685d858 100644 --- a/config/unicorn.rb +++ b/config/unicorn.rb @@ -1,22 +1,22 @@ -worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3) +worker_processes Integer(ENV['WEB_CONCURRENCY'] || 3) timeout 30 preload_app true -before_fork do |server, worker| +before_fork do |_server, _worker| Signal.trap 'TERM' do puts 'Unicorn master intercepting TERM and sending myself QUIT instead' Process.kill 'QUIT', Process.pid end - defined?(ActiveRecord::Base) and + defined?(ActiveRecord::Base) && ActiveRecord::Base.connection.disconnect! end -after_fork do |server, worker| +after_fork do |_server, _worker| Signal.trap 'TERM' do puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT' end - defined?(ActiveRecord::Base) and + defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection -end \ No newline at end of file +end diff --git a/db/migrate/20140822200153_create_events.rb b/db/migrate/20140822200153_create_events.rb index f0c02f1..393071e 100644 --- a/db/migrate/20140822200153_create_events.rb +++ b/db/migrate/20140822200153_create_events.rb @@ -1,26 +1,26 @@ class CreateEvents < ActiveRecord::Migration - def change - create_table :events do |t| - t.integer :timestamp, :limit => 8 - t.text :event - t.text :email - t.text :"smtp-id" - t.text :sg_event_id - t.text :sg_message_id - t.text :category - t.text :newsletter - t.text :response - t.text :reason - t.text :ip - t.text :useragent - t.text :attempt - t.text :status - t.text :type_id - t.text :url - t.text :additional_arguments - t.integer :event_post_timestamp, :limit => 8 - t.text :raw - t.timestamps - end - end + def change + create_table :events do |t| + t.integer :timestamp, limit: 8 + t.text :event + t.text :email + t.text :"smtp-id" + t.text :sg_event_id + t.text :sg_message_id + t.text :category + t.text :newsletter + t.text :response + t.text :reason + t.text :ip + t.text :useragent + t.text :attempt + t.text :status + t.text :type_id + t.text :url + t.text :additional_arguments + t.integer :event_post_timestamp, limit: 8 + t.text :raw + t.timestamps + end + end end diff --git a/db/migrate/20140906160955_create_settings.rb b/db/migrate/20140906160955_create_settings.rb index d8f1a7e..309c7ee 100644 --- a/db/migrate/20140906160955_create_settings.rb +++ b/db/migrate/20140906160955_create_settings.rb @@ -1,10 +1,10 @@ class CreateSettings < ActiveRecord::Migration - def change - create_table :settings do |t| - t.string :name - t.text :value - t.integer :visible - t.timestamps - end - end + def change + create_table :settings do |t| + t.string :name + t.text :value + t.integer :visible + t.timestamps + end + end end diff --git a/db/migrate/20140906223942_create_users.rb b/db/migrate/20140906223942_create_users.rb index ec63297..eecdd6a 100644 --- a/db/migrate/20140906223942_create_users.rb +++ b/db/migrate/20140906223942_create_users.rb @@ -1,13 +1,12 @@ - class CreateUsers < ActiveRecord::Migration - def change - create_table :users do |t| - t.integer :permissions, :default => 1 - t.string :token - t.integer :token_expires, :default => 0 - t.string :username - t.binary :password - t.timestamps - end - end + def change + create_table :users do |t| + t.integer :permissions, default: 1 + t.string :token + t.integer :token_expires, default: 0 + t.string :username + t.binary :password + t.timestamps + end + end end diff --git a/db/migrate/20141014135702_add_asm_group_id_to_event.rb b/db/migrate/20141014135702_add_asm_group_id_to_event.rb index 45f5bd8..f90b179 100644 --- a/db/migrate/20141014135702_add_asm_group_id_to_event.rb +++ b/db/migrate/20141014135702_add_asm_group_id_to_event.rb @@ -1,5 +1,5 @@ class AddAsmGroupIdToEvent < ActiveRecord::Migration def change - add_column :events, :asm_group_id, :integer, :limit => 2 + add_column :events, :asm_group_id, :integer, limit: 2 end end diff --git a/db/schema.rb b/db/schema.rb index 8d18815..fcd799c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,4 +1,3 @@ -# 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. @@ -11,49 +10,47 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20141014135702) do - - create_table "events", force: true do |t| - t.integer "timestamp", limit: 8 - t.text "event" - t.text "email" - t.text "smtp-id" - t.text "sg_event_id" - t.text "sg_message_id" - t.text "category" - t.text "newsletter" - t.text "response" - t.text "reason" - t.text "ip" - t.text "useragent" - t.text "attempt" - t.text "status" - t.text "type_id" - t.text "url" - t.text "additional_arguments" - t.integer "event_post_timestamp", limit: 8 - t.text "raw" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "asm_group_id", limit: 2 +ActiveRecord::Schema.define(version: 20_141_014_135_702) do + create_table 'events', force: true do |t| + t.integer 'timestamp', limit: 8 + t.text 'event' + t.text 'email' + t.text 'smtp-id' + t.text 'sg_event_id' + t.text 'sg_message_id' + t.text 'category' + t.text 'newsletter' + t.text 'response' + t.text 'reason' + t.text 'ip' + t.text 'useragent' + t.text 'attempt' + t.text 'status' + t.text 'type_id' + t.text 'url' + t.text 'additional_arguments' + t.integer 'event_post_timestamp', limit: 8 + t.text 'raw' + t.datetime 'created_at' + t.datetime 'updated_at' + t.integer 'asm_group_id', limit: 2 end - create_table "settings", force: true do |t| - t.string "name" - t.text "value" - t.integer "visible" - t.datetime "created_at" - t.datetime "updated_at" + create_table 'settings', force: true do |t| + t.string 'name' + t.text 'value' + t.integer 'visible' + t.datetime 'created_at' + t.datetime 'updated_at' end - create_table "users", force: true do |t| - t.integer "permissions", default: 1 - t.string "token" - t.integer "token_expires", default: 0 - t.string "username" - t.binary "password" - t.datetime "created_at" - t.datetime "updated_at" + create_table 'users', force: true do |t| + t.integer 'permissions', default: 1 + t.string 'token' + t.integer 'token_expires', default: 0 + t.string 'username' + t.binary 'password' + t.datetime 'created_at' + t.datetime 'updated_at' end - end diff --git a/db/seeds.rb b/db/seeds.rb index 09776cc..fbcdda3 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -6,18 +6,17 @@ # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) # Mayor.create(name: 'Emanuel', city: cities.first) - # Setup Default Settings #=========================================================================# -Setting.create({ - name: "is_setup", - value: "0", - visible: 0 -}) +Setting.create( + name: 'is_setup', + value: '0', + visible: 0 +) -Setting.create({ - name: "autodelete_time", - value: "6", - visible: 1 -}) \ No newline at end of file +Setting.create( + name: 'autodelete_time', + value: '6', + visible: 1 +) diff --git a/lib/permissions.rb b/lib/permissions.rb index 8094670..ebeeb1b 100644 --- a/lib/permissions.rb +++ b/lib/permissions.rb @@ -1,6 +1,6 @@ module Permissions - VIEW = 1 << 0 - DOWNLOAD = 1 << 1 - POST = 1 << 2 - EDIT = 1 << 3 -end \ No newline at end of file + VIEW = 1 << 0 + DOWNLOAD = 1 << 1 + POST = 1 << 2 + EDIT = 1 << 3 +end diff --git a/spec/controllers/api/v1/events_controller_spec.rb b/spec/controllers/api/v1/events_controller_spec.rb index 080bfa5..b054a3d 100644 --- a/spec/controllers/api/v1/events_controller_spec.rb +++ b/spec/controllers/api/v1/events_controller_spec.rb @@ -1,159 +1,148 @@ require 'rails_helper' require 'spec_helper' -RSpec.describe Api::V1::EventsController, :type => :controller do +RSpec.describe Api::V1::EventsController, type: :controller do + before(:each) do + @user = FactoryGirl.create(:user) + end - before(:each) do - @user = FactoryGirl.create(:user) - end + describe 'GET #index' do + context 'with no token' do + it 'receives an error' do + get :index + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - describe 'GET #index' do - context "with no token" do - it "receives an error" do - get :index - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + context 'with a valid token' do + context 'with no parameters given' do + it 'retrieves a list of all events' do + FactoryGirl.create_list(:event, 10) + get :index, token: @user.token + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('events') + expect(json['events'].length).to equal(10) + expect(json['meta']['total']).to equal(10) + end + end - context "with a valid token" do - context "with no parameters given" do - it "retrieves a list of all events" do - FactoryGirl.create_list(:event, 10) - get :index, token: @user.token - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("events") - expect(json["events"].length).to equal(10) - expect(json["meta"]["total"]).to equal(10) - end - end + context 'with specific parameters given' do + it 'retrieves a list of events matching the parameters' do + FactoryGirl.create_list(:event, 10) + get :index, token: @user.token, ip: '98.765.43.210' + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('events') + end + end + end + end - context "with specific parameters given" do - it "retrieves a list of events matching the parameters" do - FactoryGirl.create_list(:event, 10) - get :index, {token: @user.token, ip: "98.765.43.210"} - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("events") - end - end - end - end + describe 'POST #create' do + context 'with no token' do + it 'receives an error' do + post :create, + event: { + event: 'delivered' + } + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - describe 'POST #create' do - context "with no token" do - it "receives an error" do - post :create, { - :event => { - :event => "delivered" - } - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + context 'with a valid token' do + it 'creates a new event' do + post :create, + token: @user.token, + event: { + event: 'delivered' + } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('event') + expect(json['event']['event']).to include('delivered') + end + end + end - context "with a valid token" do - it "creates a new event" do - post :create, { - :token => @user.token, - :event => { - :event => "delivered" - } - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("event") - expect(json["event"]["event"]).to include("delivered") - end - end - end + describe 'GET #show' do + context 'with no token' do + it 'receives an error' do + get :show, + id: 1 + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - describe 'GET #show' do - context "with no token" do - it "receives an error" do - get :show, { - id: 1 - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + context 'with a valid token' do + it 'retrieves the event with the given ID' do + FactoryGirl.create_list(:event, 10) + get :show, + token: @user.token, + id: 1 + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('event') + end + end + end - context "with a valid token" do - it "retrieves the event with the given ID" do - FactoryGirl.create_list(:event, 10) - get :show, { - :token => @user.token, - :id => 1 - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("event") - end - end - end + describe 'PUT #update' do + context 'with no token' do + it 'receives an error' do + put :update, + id: 1, + event: { + email: 'rspec@example.none' + } + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - describe 'PUT #update' do - context "with no token" do - it "receives an error" do - put :update, { - id: 1, - :event => { - :email => "rspec@example.none" - } - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + context 'with a valid token' do + it 'updates an event with the given ID' do + FactoryGirl.create_list(:event, 10) + put :update, + token: @user.token, + id: 1, + event: { + email: 'rspec@example.none' + } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('event') + expect(json['event']['email']).to include('rspec@example.none') + end + end + end - context "with a valid token" do - it "updates an event with the given ID" do - FactoryGirl.create_list(:event, 10) - put :update, { - :token => @user.token, - :id => 1, - :event => { - :email => "rspec@example.none" - } - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("event") - expect(json["event"]["email"]).to include("rspec@example.none") - end - end - end + describe 'DELETE #destroy' do + context 'with no token' do + it 'receives an error' do + delete :destroy, + id: 1 + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - describe 'DELETE #destroy' do - context "with no token" do - it "receives an error" do - delete :destroy, { - id: 1 - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end - - context "with a valid token" do - it "deletes an event with the given ID" do - FactoryGirl.create_list(:event, 10) - delete :destroy, { - :token => @user.token, - :id => 1 - } - expect(response).to be_success - - get :show, { - :token => @user.token, - :id => 1 - } - expect(response).to have_http_status(404) - end - end - end + context 'with a valid token' do + it 'deletes an event with the given ID' do + FactoryGirl.create_list(:event, 10) + delete :destroy, + token: @user.token, + id: 1 + expect(response).to be_success + get :show, + token: @user.token, + id: 1 + expect(response).to have_http_status(404) + end + end + end end diff --git a/spec/controllers/api/v1/settings_controller_spec.rb b/spec/controllers/api/v1/settings_controller_spec.rb index 0b1f05c..5f0385b 100644 --- a/spec/controllers/api/v1/settings_controller_spec.rb +++ b/spec/controllers/api/v1/settings_controller_spec.rb @@ -1,124 +1,115 @@ require 'rails_helper' -RSpec.describe Api::V1::SettingsController, :type => :controller do +RSpec.describe Api::V1::SettingsController, type: :controller do + before(:each) do + @user = FactoryGirl.create(:user) + end - before(:each) do - @user = FactoryGirl.create(:user) - end + describe 'GET #index' do + context 'with no parameters given' do + it 'retrieves a list of all settings' do + FactoryGirl.create_list(:setting, 10) + get :index + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('settings') + expect(json['meta']['total']).to equal(json['settings'].length) + end + end - describe 'GET #index' do - context "with no parameters given" do - it "retrieves a list of all settings" do - FactoryGirl.create_list(:setting, 10) - get :index - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("settings") - expect(json["meta"]["total"]).to equal(json["settings"].length) - end - end + context 'with specific parameters given' do + it 'retrieves a list of settings matching the parameters' do + FactoryGirl.create_list(:setting, 10) + get :index, name: 'setting1' + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('settings') + end + end + end - context "with specific parameters given" do - it "retrieves a list of settings matching the parameters" do - FactoryGirl.create_list(:setting, 10) - get :index, name: "setting1" - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("settings") - end - end - end + describe 'POST #create' do + it 'creates a new setting' do + post :create, + setting: { + name: 'is_testing', + value: 'true' + } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('setting') + expect(json['setting']['name']).to include('is_testing') + expect(json['setting']['value']).to include('true') + end + end - describe 'POST #create' do - it "creates a new setting" do - post :create, { - :setting => { - :name => "is_testing", - :value => "true" - } - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("setting") - expect(json["setting"]["name"]).to include("is_testing") - expect(json["setting"]["value"]).to include("true") - end - end + describe 'GET #show' do + it 'retrieves the setting with the given ID' do + FactoryGirl.create_list(:setting, 10) + get :show, + id: 1 + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('setting') + end + end - describe 'GET #show' do - it "retrieves the setting with the given ID" do - FactoryGirl.create_list(:setting, 10) - get :show, { - :id => 1 - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("setting") - end - end + describe 'PUT #update' do + context 'with no token' do + it 'receives an error' do + put :update, + id: 1, + setting: { + name: 'foo', + value: 'bar' + } + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - describe 'PUT #update' do - context "with no token" do - it "receives an error" do - put :update, { - id: 1, - :setting => { - :name => "foo", - :value => "bar" - } - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + context 'with a valid token' do + it 'updates a setting with the given ID' do + FactoryGirl.create_list(:setting, 10) + put :update, + token: @user.token, + id: 1, + setting: { + name: 'foo', + value: 'bar' + } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('setting') + expect(json['setting']['name']).to include('foo') + expect(json['setting']['value']).to include('bar') + end + end + end - context "with a valid token" do - it "updates a setting with the given ID" do - FactoryGirl.create_list(:setting, 10) - put :update, { - :token => @user.token, - :id => 1, - :setting => { - :name => "foo", - :value => "bar" - } - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("setting") - expect(json["setting"]["name"]).to include("foo") - expect(json["setting"]["value"]).to include("bar") - end - end - end + describe 'DELETE #destroy' do + context 'with no token' do + it 'receives an error' do + delete :destroy, + id: 1 + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - describe 'DELETE #destroy' do - context "with no token" do - it "receives an error" do - delete :destroy, { - id: 1 - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end - - context "with a valid token" do - it "deletes a setting with the given ID" do - FactoryGirl.create_list(:setting, 10) - delete :destroy, { - :token => @user.token, - :id => 1 - } - expect(response).to be_success - - get :show, { - :token => @user.token, - :id => 1 - } - expect(response).to have_http_status(404) - end - end - end + context 'with a valid token' do + it 'deletes a setting with the given ID' do + FactoryGirl.create_list(:setting, 10) + delete :destroy, + token: @user.token, + id: 1 + expect(response).to be_success + get :show, + token: @user.token, + id: 1 + expect(response).to have_http_status(404) + end + end + end end diff --git a/spec/controllers/api/v1/users_controller_spec.rb b/spec/controllers/api/v1/users_controller_spec.rb index 3d32733..edf1f3f 100644 --- a/spec/controllers/api/v1/users_controller_spec.rb +++ b/spec/controllers/api/v1/users_controller_spec.rb @@ -1,176 +1,165 @@ require 'rails_helper' -RSpec.describe Api::V1::UsersController, :type => :controller do - describe 'GET #index' do - context "with no existing users in the database" do - it "returns a success" do - get :index - expect(response).to be_success - end - end - context "with some existing users in the database" do - context "with no token" do - it "receives an error" do - FactoryGirl.create_list(:user, 10) - get :index - json = JSON.parse(response.body) - expect(json).to include("error") - end - end +RSpec.describe Api::V1::UsersController, type: :controller do + describe 'GET #index' do + context 'with no existing users in the database' do + it 'returns a success' do + get :index + expect(response).to be_success + end + end + context 'with some existing users in the database' do + context 'with no token' do + it 'receives an error' do + FactoryGirl.create_list(:user, 10) + get :index + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - context "with a valid token" do - context "with no parameters given" do - it "retrieves a list of all users" do - FactoryGirl.create_list(:user, 10) - get :index, token: "12345" - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("users") - expect(json["users"].length).to equal(10) - expect(json["meta"]["total"]).to equal(10) - end - end + context 'with a valid token' do + context 'with no parameters given' do + it 'retrieves a list of all users' do + FactoryGirl.create_list(:user, 10) + get :index, token: '12345' + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('users') + expect(json['users'].length).to equal(10) + expect(json['meta']['total']).to equal(10) + end + end - context "with specific parameters given" do - it "retrieves a list of users matching the parameters" do - FactoryGirl.create_list(:user, 10) - get :index, {token: "12345", username: "rspec1"} - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("users") - end - end - end - end - end + context 'with specific parameters given' do + it 'retrieves a list of users matching the parameters' do + FactoryGirl.create_list(:user, 10) + get :index, token: '12345', username: 'rspec1' + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('users') + end + end + end + end + end - describe 'POST #create' do - context "with no existing users in the database" do - it "creates a new user without a valid token" do - post :create, { - :user => { - :username => "foobar" - } - } - expect(response).to be_success - end - end - context "with some existing users in the database" do - context "with no token" do - it "receives an error" do - FactoryGirl.create_list(:user, 10) - post :create, { - :user => { - :username => "foobar" - } - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + describe 'POST #create' do + context 'with no existing users in the database' do + it 'creates a new user without a valid token' do + post :create, + user: { + username: 'foobar' + } + expect(response).to be_success + end + end + context 'with some existing users in the database' do + context 'with no token' do + it 'receives an error' do + FactoryGirl.create_list(:user, 10) + post :create, + user: { + username: 'foobar' + } + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - context "with a valid token" do - it "creates a new user" do - FactoryGirl.create_list(:user, 10) - post :create, { - :token => "12345", - :user => { - :username => "foobar" - } - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("user") - expect(json["user"]["username"]).to include("foobar") - end - end - end - end + context 'with a valid token' do + it 'creates a new user' do + FactoryGirl.create_list(:user, 10) + post :create, + token: '12345', + user: { + username: 'foobar' + } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('user') + expect(json['user']['username']).to include('foobar') + end + end + end + end - describe 'GET #show' do - context "with no token" do - it "receives an error" do - get :show, { - id: 1 - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + describe 'GET #show' do + context 'with no token' do + it 'receives an error' do + get :show, + id: 1 + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - context "with a valid token" do - it "retrieves the user with the given ID" do - FactoryGirl.create_list(:user, 10) - get :show, { - :token => "12345", - :id => 1 - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("user") - end - end - end + context 'with a valid token' do + it 'retrieves the user with the given ID' do + FactoryGirl.create_list(:user, 10) + get :show, + token: '12345', + id: 1 + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('user') + end + end + end - describe 'PUT #update' do - context "with no token" do - it "receives an error" do - put :update, { - id: 1, - :user => { - :username => "rspec@example.none" - } - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + describe 'PUT #update' do + context 'with no token' do + it 'receives an error' do + put :update, + id: 1, + user: { + username: 'rspec@example.none' + } + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - context "with a valid token" do - it "updates an user with the given ID" do - FactoryGirl.create_list(:user, 10) - put :update, { - :token => "12345", - :id => 1, - :user => { - :username => "rspec@example.none" - } - } - expect(response).to be_success - json = JSON.parse(response.body) - expect(json).to include("user") - expect(json["user"]["username"]).to include("rspec@example.none") - end - end - end + context 'with a valid token' do + it 'updates an user with the given ID' do + FactoryGirl.create_list(:user, 10) + put :update, + token: '12345', + id: 1, + user: { + username: 'rspec@example.none' + } + expect(response).to be_success + json = JSON.parse(response.body) + expect(json).to include('user') + expect(json['user']['username']).to include('rspec@example.none') + end + end + end - describe 'DELETE #destroy' do - context "with no token" do - it "receives an error" do - delete :destroy, { - id: 1 - } - json = JSON.parse(response.body) - expect(json).to include("error") - end - end + describe 'DELETE #destroy' do + context 'with no token' do + it 'receives an error' do + delete :destroy, + id: 1 + json = JSON.parse(response.body) + expect(json).to include('error') + end + end - context "with a valid token" do - it "deletes an user with the given ID" do - FactoryGirl.create_list(:user, 10) - delete :destroy, { - :token => "12345", - :id => 1 - } - expect(response).to be_success - - get :show, { - :token => "12345", - :id => 1 - } - expect(response).to have_http_status(404) - end - end - end + context 'with a valid token' do + it 'deletes an user with the given ID' do + FactoryGirl.create_list(:user, 10) + delete :destroy, + token: '12345', + id: 1 + expect(response).to be_success + get :show, + token: '12345', + id: 1 + expect(response).to have_http_status(404) + end + end + end end diff --git a/spec/factories/events.rb b/spec/factories/events.rb index db14395..073f023 100644 --- a/spec/factories/events.rb +++ b/spec/factories/events.rb @@ -1,22 +1,22 @@ FactoryGirl.define do - factory :event do - timestamp Time.now.to_i - event {["bounce", "click", "deferred", "delivered", "dropped", "open", "processed", "spamreport", "unsubscribe", "group_unsubscribe", "group_resubscribe"].sample} - sequence(:email) { |n| "awesomeemail#{n}@example.none"} - sequence(:"smtp-id") { |n| "LU6cMZ9jhyWNCv5xJ4e831oVu#{n}"} - sequence(:"sg_event_id") { |n| "FyYtL0ZDIuhbsTh2RZynZk8bQaSMgopRBGpy0sfJzJCFWyV#{n}"} - sequence(:"sg_message_id") { |n| "9gyRRQgAVT5rZqLTZSr1ykhSSdM2BE6#{n}"} - category '["Test","Newsletter"]' - newsletter '{"newsletter_id":12345,"newsletter_user_list_id":67890,"newsletter_send_id":4815162342}' - response "250 OK" - reason "Bounced Address" - ip {["12.345.67.890","98.765.43.210"].sample} - useragent "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/123456" - attempt 0 - status "5.0.0" - type_id "block" - url "https://sendgrid.com" - additional_arguments '{"foo":"bar"}' - event_post_timestamp Time.now.to_i - end -end \ No newline at end of file + factory :event do + timestamp Time.now.to_i + event { %w[bounce click deferred delivered dropped open processed spamreport unsubscribe group_unsubscribe group_resubscribe].sample } + sequence(:email) { |n| "awesomeemail#{n}@example.none" } + sequence(:"smtp-id") { |n| "LU6cMZ9jhyWNCv5xJ4e831oVu#{n}" } + sequence(:sg_event_id) { |n| "FyYtL0ZDIuhbsTh2RZynZk8bQaSMgopRBGpy0sfJzJCFWyV#{n}" } + sequence(:sg_message_id) { |n| "9gyRRQgAVT5rZqLTZSr1ykhSSdM2BE6#{n}" } + category '["Test","Newsletter"]' + newsletter '{"newsletter_id":12345,"newsletter_user_list_id":67890,"newsletter_send_id":4815162342}' + response '250 OK' + reason 'Bounced Address' + ip { ['12.345.67.890', '98.765.43.210'].sample } + useragent 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_0_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/123456' + attempt 0 + status '5.0.0' + type_id 'block' + url 'https://sendgrid.com' + additional_arguments '{"foo":"bar"}' + event_post_timestamp Time.now.to_i + end +end diff --git a/spec/factories/settings.rb b/spec/factories/settings.rb index 7f7dd88..f4f6f9d 100644 --- a/spec/factories/settings.rb +++ b/spec/factories/settings.rb @@ -1,7 +1,7 @@ FactoryGirl.define do - factory :setting do - name { |n| "setting#{n}"} - value { |n| "value#{n}"} - visible 0 - end -end \ No newline at end of file + factory :setting do + name { |n| "setting#{n}" } + value { |n| "value#{n}" } + visible 0 + end +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index d417eea..983ad80 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -1,9 +1,9 @@ require 'permissions' FactoryGirl.define do - factory :user do - permissions Permissions::VIEW | Permissions::EDIT | Permissions::POST - token "12345" - username { |n| "rspec#{n}"} - end -end \ No newline at end of file + factory :user do + permissions Permissions::VIEW | Permissions::EDIT | Permissions::POST + token '12345' + username { |n| "rspec#{n}" } + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index ade912e..d98a275 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,11 +1,10 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' +ENV['RAILS_ENV'] ||= 'test' require 'spec_helper' -require File.expand_path("../../config/environment", __FILE__) +require File.expand_path('../config/environment', __dir__) require 'rspec/rails' require 'factory_girl' - # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are # run as spec files by default. This means that files in spec/support that end @@ -13,7 +12,7 @@ # run twice. It is recommended that you do not name files matching this glob to # end with _spec.rb. You can configure this pattern with the --pattern # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. -Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } +Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } # Checks for pending migrations before tests are run. # If you are not using ActiveRecord, you can remove this line. @@ -21,7 +20,7 @@ RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - #config.fixture_path = "#{::Rails.root}/spec/fixtures" + # config.fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d2569cd..5648a95 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,9 +4,9 @@ require 'rails_helper' require 'rspec/rails' -ENV["RAILS_ENV"] ||= 'test' -require File.expand_path("../../config/environment", __FILE__) +ENV['RAILS_ENV'] ||= 'test' +require File.expand_path('../config/environment', __dir__) RSpec.configure do |config| - config.include FactoryGirl::Syntax::Methods -end \ No newline at end of file + config.include FactoryGirl::Syntax::Methods +end From fce35c04633e6b4071da6976bfc4f102180954e4 Mon Sep 17 00:00:00 2001 From: Roland Burrows Date: Wed, 31 Oct 2018 23:40:53 -0600 Subject: [PATCH 2/2] Add test coverage analysis --- .gitignore | 4 +++- Gemfile | 1 + Gemfile.lock | 7 +++++++ README.md | 14 +++++++++++--- spec/spec_helper.rb | 2 ++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index f12d53c..1e3a496 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,6 @@ *.sublime-workspace **/*/.DS_Store -.DS_Store \ No newline at end of file +.DS_Store + +coverage/* diff --git a/Gemfile b/Gemfile index c55d44b..a22922b 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ group :development, :test do gem 'rspec-rails' gem 'rspec_api_test' gem 'rubocop' + gem 'simplecov' gem 'sqlite3' end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index 96d7667..bad17a7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -46,6 +46,7 @@ GEM execjs coffee-script-source (1.9.1) diff-lcs (1.2.5) + docile (1.3.1) domain_name (0.5.23) unf (>= 0.0.5, < 1.0.0) ember-data-source (1.0.0.beta.16.1) @@ -175,6 +176,11 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) + simplecov (0.16.1) + docile (~> 1.1) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) slop (3.6.0) sprockets (2.12.4) hike (~> 1.2) @@ -235,6 +241,7 @@ DEPENDENCIES rubocop sass-rails (~> 4.0.2) sdoc + simplecov sqlite3 turbolinks uglifier (>= 1.3.0) diff --git a/README.md b/README.md index 61ca388..994a912 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,21 @@ -# EventKit Rails +## EventKit Rails EventKit Rails is a Ruby on Rails port of [EventKit](https://github.com/sendgrid/eventkit), an open source project to receive notifications for [SendGrid's Event Webhook](https://sendgrid.com/docs/API_Reference/Webhooks/event.html). This project can be deployed to a rails server, or quickly deployed to [Heroku](http://heroku.com) using the "Deploy Heroku Button" (see below). -# Tech Stack +## Tech Stack EventKit Rails uses [Ruby on Rails](http://rubyonrails.org) for the backend, including ActiveRecord and Postgres for the production database. The backend is API driven, which is used by the [EmberJS](http://emberjs.com) frontend. The frontend also uses [Ember Data](http://emberjs.com/guides/models/) to handle the communication between the frontend and backend. -# Deploying To Heroku +## Deploying To Heroku You can easily deploy EventKit Rails to your Heroku account with a few clicks using the button below. If you don't currently have a Heroku account, you can [set one up for free](https://www.heroku.com/pricing) on their website. [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) + +## Testing + +To run the tests: + +`rpsec` + +A test coverage report will be generated at `coverage/index.html`. diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5648a95..cfb0297 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +require 'simplecov' +SimpleCov.start require 'rubygems' require 'factory_girl_rails' require 'rspec_api_test'