From 68f829e11c058c55a6695b5812aa0577b5b1eea1 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 3 Apr 2017 19:27:30 +0200 Subject: Add basic logging of who resolved report --- app/models/report.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/models') diff --git a/app/models/report.rb b/app/models/report.rb index 05dc8cff1..fd8e46aac 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -3,6 +3,7 @@ class Report < ApplicationRecord belongs_to :account belongs_to :target_account, class_name: 'Account' + belongs_to :action_taken_by_account, class_name: 'Account' scope :unresolved, -> { where(action_taken: false) } scope :resolved, -> { where(action_taken: true) } -- cgit From 4c53af64f0b10bc11473df5e3fd1cd7a11b755f6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 01:33:34 +0200 Subject: Fix ActionController::Parameters in API issue --- app/controllers/api/v1/apps_controller.rb | 8 +++++++- app/controllers/api/v1/follows_controller.rb | 8 ++++++-- app/controllers/api/v1/media_controller.rb | 8 +++++++- app/controllers/api/v1/reports_controller.rb | 12 +++++++++--- app/controllers/api/v1/statuses_controller.rb | 14 +++++++++----- app/models/status.rb | 2 +- 6 files changed, 39 insertions(+), 13 deletions(-) (limited to 'app/models') diff --git a/app/controllers/api/v1/apps_controller.rb b/app/controllers/api/v1/apps_controller.rb index ca9dd0b7e..2ec7280af 100644 --- a/app/controllers/api/v1/apps_controller.rb +++ b/app/controllers/api/v1/apps_controller.rb @@ -4,6 +4,12 @@ class Api::V1::AppsController < ApiController respond_to :json def create - @app = Doorkeeper::Application.create!(name: params[:client_name], redirect_uri: params[:redirect_uris], scopes: (params[:scopes] || Doorkeeper.configuration.default_scopes), website: params[:website]) + @app = Doorkeeper::Application.create!(name: app_params[:client_name], redirect_uri: app_params[:redirect_uris], scopes: (app_params[:scopes] || Doorkeeper.configuration.default_scopes), website: app_params[:website]) + end + + private + + def app_params + params.permit(:client_name, :redirect_uris, :scopes, :website) end end diff --git a/app/controllers/api/v1/follows_controller.rb b/app/controllers/api/v1/follows_controller.rb index c22dacbaa..7c0f44f03 100644 --- a/app/controllers/api/v1/follows_controller.rb +++ b/app/controllers/api/v1/follows_controller.rb @@ -7,7 +7,7 @@ class Api::V1::FollowsController < ApiController respond_to :json def create - raise ActiveRecord::RecordNotFound if params[:uri].blank? + raise ActiveRecord::RecordNotFound if follow_params[:uri].blank? @account = FollowService.new.call(current_user.account, target_uri).try(:target_account) render action: :show @@ -16,6 +16,10 @@ class Api::V1::FollowsController < ApiController private def target_uri - params[:uri].strip.gsub(/\A@/, '') + follow_params[:uri].strip.gsub(/\A@/, '') + end + + def follow_params + params.permit(:uri) end end diff --git a/app/controllers/api/v1/media_controller.rb b/app/controllers/api/v1/media_controller.rb index f8139ade7..aed3578d7 100644 --- a/app/controllers/api/v1/media_controller.rb +++ b/app/controllers/api/v1/media_controller.rb @@ -10,10 +10,16 @@ class Api::V1::MediaController < ApiController respond_to :json def create - @media = MediaAttachment.create!(account: current_user.account, file: params[:file]) + @media = MediaAttachment.create!(account: current_user.account, file: media_params[:file]) rescue Paperclip::Errors::NotIdentifiedByImageMagickError render json: { error: 'File type of uploaded media could not be verified' }, status: 422 rescue Paperclip::Error render json: { error: 'Error processing thumbnail for uploaded media' }, status: 500 end + + private + + def media_params + params.permit(:file) + end end diff --git a/app/controllers/api/v1/reports_controller.rb b/app/controllers/api/v1/reports_controller.rb index 46bdddbc1..f83c573cb 100644 --- a/app/controllers/api/v1/reports_controller.rb +++ b/app/controllers/api/v1/reports_controller.rb @@ -12,13 +12,19 @@ class Api::V1::ReportsController < ApiController end def create - status_ids = params[:status_ids].is_a?(Enumerable) ? params[:status_ids] : [params[:status_ids]] + status_ids = report_params[:status_ids].is_a?(Enumerable) ? report_params[:status_ids] : [report_params[:status_ids]] @report = Report.create!(account: current_account, - target_account: Account.find(params[:account_id]), + target_account: Account.find(report_params[:account_id]), status_ids: Status.find(status_ids).pluck(:id), - comment: params[:comment]) + comment: report_params[:comment]) render :show end + + private + + def report_params + params.permit(:account_id, :comment, status_ids: []) + end end diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 024258c0e..4ece7e702 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -62,11 +62,11 @@ class Api::V1::StatusesController < ApiController end def create - @status = PostStatusService.new.call(current_user.account, params[:status], params[:in_reply_to_id].blank? ? nil : Status.find(params[:in_reply_to_id]), media_ids: params[:media_ids], - sensitive: params[:sensitive], - spoiler_text: params[:spoiler_text], - visibility: params[:visibility], - application: doorkeeper_token.application) + @status = PostStatusService.new.call(current_user.account, status_params[:status], status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]), media_ids: status_params[:media_ids], + sensitive: status_params[:sensitive], + spoiler_text: status_params[:spoiler_text], + visibility: status_params[:visibility], + application: doorkeeper_token.application) render action: :show end @@ -111,4 +111,8 @@ class Api::V1::StatusesController < ApiController @status = Status.find(params[:id]) raise ActiveRecord::RecordNotFound unless @status.permitted?(current_account) end + + def status_params + params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, media_ids: []) + end end diff --git a/app/models/status.rb b/app/models/status.rb index 81b26fd14..daf128572 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -188,7 +188,7 @@ class Status < ApplicationRecord end before_validation do - text.strip! + text&.strip! spoiler_text&.strip! self.reply = !(in_reply_to_id.nil? && thread.nil?) unless reply -- cgit From b510a56c0c3d8c1a48bb295a85b688af94466723 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 4 Apr 2017 02:00:10 +0200 Subject: Only call regeneration worker after first login after a 14 day break --- app/controllers/application_controller.rb | 9 ++++++++- app/controllers/oauth/authorizations_controller.rb | 7 +++++++ app/models/feed.rb | 12 ++---------- app/workers/regeneration_worker.rb | 4 ++-- 4 files changed, 19 insertions(+), 13 deletions(-) (limited to 'app/models') diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ef9364897..c06142fd4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -39,7 +39,14 @@ class ApplicationController < ActionController::Base end def set_user_activity - current_user.touch(:current_sign_in_at) if !current_user.nil? && (current_user.current_sign_in_at.nil? || current_user.current_sign_in_at < 24.hours.ago) + return unless !current_user.nil? && (current_user.current_sign_in_at.nil? || current_user.current_sign_in_at < 24.hours.ago) + + # Mark user as signed-in today + current_user.update_tracked_fields(request) + + # If the sign in is after a two week break, we need to regenerate their feed + RegenerationWorker.perform_async(current_user.account_id) if current_user.last_sign_in_at < 14.days.ago + return end def check_suspension diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb index feaad04f6..7c25266d8 100644 --- a/app/controllers/oauth/authorizations_controller.rb +++ b/app/controllers/oauth/authorizations_controller.rb @@ -3,6 +3,7 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController skip_before_action :authenticate_resource_owner! + before_action :set_locale before_action :store_current_location before_action :authenticate_resource_owner! @@ -11,4 +12,10 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController def store_current_location store_location_for(:user, request.url) end + + def set_locale + I18n.locale = current_user.try(:locale) || I18n.default_locale + rescue I18n::InvalidLocale + I18n.locale = I18n.default_locale + end end diff --git a/app/models/feed.rb b/app/models/feed.rb index 5e1905e15..3cbc160a0 100644 --- a/app/models/feed.rb +++ b/app/models/feed.rb @@ -10,17 +10,9 @@ class Feed max_id = '+inf' if max_id.blank? since_id = '-inf' if since_id.blank? unhydrated = redis.zrevrangebyscore(key, "(#{max_id}", "(#{since_id}", limit: [0, limit], with_scores: true).map(&:last).map(&:to_i) + status_map = Status.where(id: unhydrated).cache_ids.map { |s| [s.id, s] }.to_h - # If we're after most recent items and none are there, we need to precompute the feed - if unhydrated.empty? && max_id == '+inf' && since_id == '-inf' - RegenerationWorker.perform_async(@account.id, @type) - @statuses = Status.send("as_#{@type}_timeline", @account).cache_ids.paginate_by_max_id(limit, nil, nil) - else - status_map = Status.where(id: unhydrated).cache_ids.map { |s| [s.id, s] }.to_h - @statuses = unhydrated.map { |id| status_map[id] }.compact - end - - @statuses + unhydrated.map { |id| status_map[id] }.compact end private diff --git a/app/workers/regeneration_worker.rb b/app/workers/regeneration_worker.rb index 289b63d84..82665b581 100644 --- a/app/workers/regeneration_worker.rb +++ b/app/workers/regeneration_worker.rb @@ -5,7 +5,7 @@ class RegenerationWorker sidekiq_options queue: 'pull', backtrace: true - def perform(account_id, timeline_type) - PrecomputeFeedService.new.call(timeline_type, Account.find(account_id)) + def perform(account_id, _ = :home) + PrecomputeFeedService.new.call(:home, Account.find(account_id)) end end -- cgit From 81c76fe375d9342e5a436db05c8e25305c650e8d Mon Sep 17 00:00:00 2001 From: Samy KACIMI Date: Wed, 5 Apr 2017 00:29:56 +0200 Subject: add more tests to models --- Gemfile | 1 + Gemfile.lock | 3 + app/models/block.rb | 5 +- app/models/follow.rb | 9 ++- app/models/follow_request.rb | 5 +- app/models/mention.rb | 5 +- config/database.yml | 4 ++ spec/fabricators/account_fabricator.rb | 2 +- spec/fabricators/block_fabricator.rb | 3 +- spec/fabricators/follow_fabricator.rb | 3 +- spec/fabricators/follow_request_fabricator.rb | 3 +- spec/fabricators/mention_fabricator.rb | 4 ++ spec/fabricators/user_fabricator.rb | 2 +- spec/models/account_spec.rb | 69 ++++++++++++++++++++++ spec/models/block_spec.rb | 17 ++++++ spec/models/domain_block_spec.rb | 18 ++++++ spec/models/follow_request_spec.rb | 19 ++++++ spec/models/follow_spec.rb | 19 ++++++ spec/models/mention_spec.rb | 17 ++++++ spec/models/user_spec.rb | 44 ++++++++++++++ spec/rails_helper.rb | 2 + .../matchers/model/model_have_error_on_field.rb | 15 +++++ 22 files changed, 252 insertions(+), 17 deletions(-) create mode 100644 spec/fabricators/mention_fabricator.rb create mode 100644 spec/support/matchers/model/model_have_error_on_field.rb (limited to 'app/models') diff --git a/Gemfile b/Gemfile index 4c6314763..87ea77735 100644 --- a/Gemfile +++ b/Gemfile @@ -70,6 +70,7 @@ group :test do gem 'simplecov', require: false gem 'webmock' gem 'rspec-sidekiq' + gem 'faker' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 26c7b9962..a774a89ba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -149,6 +149,8 @@ GEM erubis (2.7.0) execjs (2.7.0) fabrication (2.15.2) + faker (1.6.6) + i18n (~> 0.5) fast_blank (1.0.0) font-awesome-rails (4.6.3.1) railties (>= 3.2, < 5.1) @@ -470,6 +472,7 @@ DEPENDENCIES doorkeeper dotenv-rails fabrication + faker fast_blank font-awesome-rails fuubar diff --git a/app/models/block.rb b/app/models/block.rb index 9c55703c9..ae456a6b6 100644 --- a/app/models/block.rb +++ b/app/models/block.rb @@ -3,9 +3,8 @@ class Block < ApplicationRecord include Paginable - belongs_to :account - belongs_to :target_account, class_name: 'Account' + belongs_to :account, required: true + belongs_to :target_account, class_name: 'Account', required: true - validates :account, :target_account, presence: true validates :account_id, uniqueness: { scope: :target_account_id } end diff --git a/app/models/follow.rb b/app/models/follow.rb index 8bfe8b2f6..fd7325f05 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -3,11 +3,14 @@ class Follow < ApplicationRecord include Paginable - belongs_to :account, counter_cache: :following_count - belongs_to :target_account, class_name: 'Account', counter_cache: :followers_count + belongs_to :account, counter_cache: :following_count, required: true + + belongs_to :target_account, + class_name: 'Account', + counter_cache: :followers_count, + required: true has_one :notification, as: :activity, dependent: :destroy - validates :account, :target_account, presence: true validates :account_id, uniqueness: { scope: :target_account_id } end diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb index 4224ab15d..20e1332dd 100644 --- a/app/models/follow_request.rb +++ b/app/models/follow_request.rb @@ -3,12 +3,11 @@ class FollowRequest < ApplicationRecord include Paginable - belongs_to :account - belongs_to :target_account, class_name: 'Account' + belongs_to :account, required: true + belongs_to :target_account, class_name: 'Account', required: true has_one :notification, as: :activity, dependent: :destroy - validates :account, :target_account, presence: true validates :account_id, uniqueness: { scope: :target_account_id } def authorize! diff --git a/app/models/mention.rb b/app/models/mention.rb index 10a9cb1cd..03e76fcc4 100644 --- a/app/models/mention.rb +++ b/app/models/mention.rb @@ -1,11 +1,10 @@ # frozen_string_literal: true class Mention < ApplicationRecord - belongs_to :account, inverse_of: :mentions - belongs_to :status + belongs_to :account, inverse_of: :mentions, required: true + belongs_to :status, required: true has_one :notification, as: :activity, dependent: :destroy - validates :account, :status, presence: true validates :account, uniqueness: { scope: :status } end diff --git a/config/database.yml b/config/database.yml index 5ec342f93..390113480 100644 --- a/config/database.yml +++ b/config/database.yml @@ -3,6 +3,10 @@ default: &default pool: <%= ENV["DB_POOL"] || ENV['MAX_THREADS'] || 5 %> timeout: 5000 encoding: unicode + host: localhost + username: samy + password: tardis + port: 32769 development: <<: *default diff --git a/spec/fabricators/account_fabricator.rb b/spec/fabricators/account_fabricator.rb index 3a7c00bf5..567de05f4 100644 --- a/spec/fabricators/account_fabricator.rb +++ b/spec/fabricators/account_fabricator.rb @@ -1,3 +1,3 @@ Fabricator(:account) do - username "alice" + username { Faker::Internet.user_name(nil, %w(_)) } end diff --git a/spec/fabricators/block_fabricator.rb b/spec/fabricators/block_fabricator.rb index 9a5a6808f..379931ba6 100644 --- a/spec/fabricators/block_fabricator.rb +++ b/spec/fabricators/block_fabricator.rb @@ -1,3 +1,4 @@ Fabricator(:block) do - + account + target_account { Fabricate(:account) } end diff --git a/spec/fabricators/follow_fabricator.rb b/spec/fabricators/follow_fabricator.rb index 9d9d06f12..9b25dc547 100644 --- a/spec/fabricators/follow_fabricator.rb +++ b/spec/fabricators/follow_fabricator.rb @@ -1,3 +1,4 @@ Fabricator(:follow) do - + account + target_account { Fabricate(:account) } end diff --git a/spec/fabricators/follow_request_fabricator.rb b/spec/fabricators/follow_request_fabricator.rb index 9c3733cef..78a057919 100644 --- a/spec/fabricators/follow_request_fabricator.rb +++ b/spec/fabricators/follow_request_fabricator.rb @@ -1,3 +1,4 @@ Fabricator(:follow_request) do - + account + target_account { Fabricate(:account) } end diff --git a/spec/fabricators/mention_fabricator.rb b/spec/fabricators/mention_fabricator.rb new file mode 100644 index 000000000..cb5fe4299 --- /dev/null +++ b/spec/fabricators/mention_fabricator.rb @@ -0,0 +1,4 @@ +Fabricator(:mention) do + account + status +end diff --git a/spec/fabricators/user_fabricator.rb b/spec/fabricators/user_fabricator.rb index c08559137..16b3b1f6f 100644 --- a/spec/fabricators/user_fabricator.rb +++ b/spec/fabricators/user_fabricator.rb @@ -1,6 +1,6 @@ Fabricator(:user) do account - email "alice@example.com" + email { Faker::Internet.email } password "123456789" confirmed_at { Time.now } end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 91c8d75cf..fbc9a7d40 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -209,4 +209,73 @@ RSpec.describe Account, type: :model do expect(subject.match('Check this out https://medium.com/@alice/some-article#.abcdef123')).to be_nil end end + + describe 'validations' do + it 'has a valid fabricator' do + account = Fabricate.build(:account) + account.valid? + expect(account).to be_valid + end + + it 'is invalid without a username' do + account = Fabricate.build(:account, username: nil) + account.valid? + expect(account).to model_have_error_on_field(:username) + end + + it 'is invalid is the username already exists' do + account_1 = Fabricate(:account, username: 'the_doctor') + account_2 = Fabricate.build(:account, username: 'the_doctor') + account_2.valid? + expect(account_2).to model_have_error_on_field(:username) + end + + context 'when is local' do + it 'is invalid if the username doesn\'t only contains letters, numbers and underscores' do + account = Fabricate.build(:account, username: 'the-doctor') + account.valid? + expect(account).to model_have_error_on_field(:username) + end + + it 'is invalid if the username is longer then 30 characters' do + account = Fabricate.build(:account, username: Faker::Lorem.characters(31)) + account.valid? + expect(account).to model_have_error_on_field(:username) + end + end + end + + describe 'scopes' do + describe 'remote' do + it 'returns an array of accounts who have a domain' do + account_1 = Fabricate(:account, domain: nil) + account_2 = Fabricate(:account, domain: 'example.com') + expect(Account.remote).to match_array([account_2]) + end + end + + describe 'local' do + it 'returns an array of accounts who do not have a domain' do + account_1 = Fabricate(:account, domain: nil) + account_2 = Fabricate(:account, domain: 'example.com') + expect(Account.local).to match_array([account_1]) + end + end + + describe 'silenced' do + it 'returns an array of accounts who are silenced' do + account_1 = Fabricate(:account, silenced: true) + account_2 = Fabricate(:account, silenced: false) + expect(Account.silenced).to match_array([account_1]) + end + end + + describe 'suspended' do + it 'returns an array of accounts who are suspended' do + account_1 = Fabricate(:account, suspended: true) + account_2 = Fabricate(:account, suspended: false) + expect(Account.suspended).to match_array([account_1]) + end + end + end end diff --git a/spec/models/block_spec.rb b/spec/models/block_spec.rb index 6862de6fc..cabb41c3e 100644 --- a/spec/models/block_spec.rb +++ b/spec/models/block_spec.rb @@ -1,5 +1,22 @@ require 'rails_helper' RSpec.describe Block, type: :model do + describe 'validations' do + it 'has a valid fabricator' do + block = Fabricate.build(:block) + expect(block).to be_valid + end + it 'is invalid without an account' do + block = Fabricate.build(:block, account: nil) + block.valid? + expect(block).to model_have_error_on_field(:account) + end + + it 'is invalid without a target_account' do + block = Fabricate.build(:block, target_account: nil) + block.valid? + expect(block).to model_have_error_on_field(:target_account) + end + end end diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index ad5403110..b19c8083e 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -1,5 +1,23 @@ require 'rails_helper' RSpec.describe DomainBlock, type: :model do + describe 'validations' do + it 'has a valid fabricator' do + domain_block = Fabricate.build(:domain_block) + expect(domain_block).to be_valid + end + it 'is invalid without a domain' do + domain_block = Fabricate.build(:domain_block, domain: nil) + domain_block.valid? + expect(domain_block).to model_have_error_on_field(:domain) + end + + it 'is invalid if the domain already exists' do + domain_block_1 = Fabricate(:domain_block, domain: 'dalek.com') + domain_block_2 = Fabricate.build(:domain_block, domain: 'dalek.com') + domain_block_2.valid? + expect(domain_block_2).to model_have_error_on_field(:domain) + end + end end diff --git a/spec/models/follow_request_spec.rb b/spec/models/follow_request_spec.rb index f2ec642d8..cc6f8ee62 100644 --- a/spec/models/follow_request_spec.rb +++ b/spec/models/follow_request_spec.rb @@ -3,4 +3,23 @@ require 'rails_helper' RSpec.describe FollowRequest, type: :model do describe '#authorize!' describe '#reject!' + + describe 'validations' do + it 'has a valid fabricator' do + follow_request = Fabricate.build(:follow_request) + expect(follow_request).to be_valid + end + + it 'is invalid without an account' do + follow_request = Fabricate.build(:follow_request, account: nil) + follow_request.valid? + expect(follow_request).to model_have_error_on_field(:account) + end + + it 'is invalid without a target account' do + follow_request = Fabricate.build(:follow_request, target_account: nil) + follow_request.valid? + expect(follow_request).to model_have_error_on_field(:target_account) + end + end end diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index eb21f3e18..0fae25352 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -5,4 +5,23 @@ RSpec.describe Follow, type: :model do let(:bob) { Fabricate(:account, username: 'bob') } subject { Follow.new(account: alice, target_account: bob) } + + describe 'validations' do + it 'has a valid fabricator' do + follow = Fabricate.build(:follow) + expect(follow).to be_valid + end + + it 'is invalid without an account' do + follow = Fabricate.build(:follow, account: nil) + follow.valid? + expect(follow).to model_have_error_on_field(:account) + end + + it 'is invalid without a target_account' do + follow = Fabricate.build(:follow, target_account: nil) + follow.valid? + expect(follow).to model_have_error_on_field(:target_account) + end + end end diff --git a/spec/models/mention_spec.rb b/spec/models/mention_spec.rb index 5c91fda02..dbcf6a32c 100644 --- a/spec/models/mention_spec.rb +++ b/spec/models/mention_spec.rb @@ -1,5 +1,22 @@ require 'rails_helper' RSpec.describe Mention, type: :model do + describe 'validations' do + it 'has a valid fabricator' do + mention = Fabricate.build(:mention) + expect(mention).to be_valid + end + it 'is invalid without an account' do + mention = Fabricate.build(:mention, account: nil) + mention.valid? + expect(mention).to model_have_error_on_field(:account) + end + + it 'is invalid without a status' do + mention = Fabricate.build(:mention, status: nil) + mention.valid? + expect(mention).to model_have_error_on_field(:status) + end + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 64de06749..1a3254185 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,5 +1,49 @@ require 'rails_helper' RSpec.describe User, type: :model do + describe 'validations' do + it 'is invalid without an account' do + user = Fabricate.build(:user, account: nil) + user.valid? + expect(user).to model_have_error_on_field(:account) + end + it 'is invalid without a valid locale' do + user = Fabricate.build(:user, locale: 'toto') + user.valid? + expect(user).to model_have_error_on_field(:locale) + end + + it 'is invalid without a valid email' do + user = Fabricate.build(:user, email: 'john@') + user.valid? + expect(user).to model_have_error_on_field(:email) + end + end + + describe 'scopes' do + describe 'recent' do + it 'returns an array of recent users ordered by id' do + user_1 = Fabricate(:user) + user_2 = Fabricate(:user) + expect(User.recent).to match_array([user_2, user_1]) + end + end + + describe 'admins' do + it 'returns an array of users who are admin' do + user_1 = Fabricate(:user, admin: false) + user_2 = Fabricate(:user, admin: true) + expect(User.admins).to match_array([user_2]) + end + end + + describe 'confirmed' do + it 'returns an array of users who are confirmed' do + user_1 = Fabricate(:user, confirmed_at: nil) + user_2 = Fabricate(:user, confirmed_at: Time.now) + expect(User.confirmed).to match_array([user_2]) + end + end + end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 977c7bdc0..faac96982 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -8,6 +8,8 @@ require 'rspec/rails' require 'webmock/rspec' require 'paperclip/matchers' +Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } + ActiveRecord::Migration.maintain_test_schema! WebMock.disable_net_connect!(allow: 'localhost:7575') Sidekiq::Testing.inline! diff --git a/spec/support/matchers/model/model_have_error_on_field.rb b/spec/support/matchers/model/model_have_error_on_field.rb new file mode 100644 index 000000000..5d5fe1c7b --- /dev/null +++ b/spec/support/matchers/model/model_have_error_on_field.rb @@ -0,0 +1,15 @@ +RSpec::Matchers.define :model_have_error_on_field do |expected| + match do |record| + if record.errors.empty? + record.valid? + end + + record.errors.has_key?(expected) + end + + failure_message do |record| + keys = record.errors.keys + + "expect record.errors(#{keys}) to include #{expected}" + end +end -- cgit From 79ef756f645153b91643765573230814257d0cbf Mon Sep 17 00:00:00 2001 From: Samy KACIMI Date: Wed, 5 Apr 2017 00:47:17 +0200 Subject: fix rubocop issues --- Gemfile | 2 +- app/models/follow.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/Gemfile b/Gemfile index 87ea77735..0deed9ae0 100644 --- a/Gemfile +++ b/Gemfile @@ -69,8 +69,8 @@ end group :test do gem 'simplecov', require: false gem 'webmock' - gem 'rspec-sidekiq' gem 'faker' + gem 'rspec-sidekiq' end group :development do diff --git a/app/models/follow.rb b/app/models/follow.rb index fd7325f05..b6b9dca7c 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -4,7 +4,7 @@ class Follow < ApplicationRecord include Paginable belongs_to :account, counter_cache: :following_count, required: true - + belongs_to :target_account, class_name: 'Account', counter_cache: :followers_count, -- cgit From 6a1da87cd32a077c8df2e82cbdc222c201ddda41 Mon Sep 17 00:00:00 2001 From: Brad Urani Date: Wed, 5 Apr 2017 06:02:58 +0000 Subject: Eliminate unnecessary queries and query clauses with none and all --- app/models/status.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/models/status.rb b/app/models/status.rb index daf128572..6948ad77c 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -161,9 +161,9 @@ class Status < ApplicationRecord return where.not(visibility: [:private, :direct]) if account.nil? if target_account.blocking?(account) # get rid of blocked peeps - where('1 = 0') + none elsif account.id == target_account.id # author can see own stuff - where('1 = 1') + all elsif account.following?(target_account) # followers can see followers-only stuff, but also things they are mentioned in joins('LEFT OUTER JOIN mentions ON statuses.id = mentions.status_id AND mentions.account_id = ' + account.id.to_s) .where('statuses.visibility != ? OR mentions.id IS NOT NULL', Status.visibilities[:direct]) -- cgit