diff --git a/app/controllers/api/v1/profiles_controller.rb b/app/controllers/api/v1/profiles_controller.rb index 0753494..258a979 100644 --- a/app/controllers/api/v1/profiles_controller.rb +++ b/app/controllers/api/v1/profiles_controller.rb @@ -3,10 +3,10 @@ module V1 class ProfilesController < ApiController def index if params[:search].blank? - profiles = Profile.active.open_to_work + profiles = Profile.active.open_to_work.order_by_premium profiles = profiles.map { |profile| format_profile(profile) } else - profiles = Profile.active.open_to_work.get_profile_job_categories_json(params[:search]) + profiles = Profile.active.open_to_work.order_by_premium.get_profile_job_categories_json(params[:search]) end render status: :ok, json: { data: profiles } end diff --git a/app/models/profile.rb b/app/models/profile.rb index a395890..ce155f7 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -1,30 +1,22 @@ class Profile < ApplicationRecord belongs_to :user + has_one_attached :photo has_one :personal_info, dependent: :destroy has_many :professional_infos, dependent: :destroy has_many :education_infos, dependent: :destroy has_many :profile_job_categories, dependent: :destroy - - has_many :followers, class_name: 'Connection', foreign_key: :followed_profile_id, dependent: :destroy, - inverse_of: :follower - - has_many :followed_profiles, class_name: 'Connection', foreign_key: :follower_id, - dependent: :destroy, inverse_of: :followed_profile - - has_many :connections, foreign_key: :followed_profile_id, dependent: :destroy, inverse_of: :followed_profile - - has_many :job_categories, through: :profile_job_categories - has_many :invitation_requests, dependent: :destroy - - has_one_attached :photo has_many :invitations, dependent: :destroy - has_many :posts, through: :user has_many :notifications, dependent: :destroy - + has_many :invitation_requests, dependent: :destroy + has_many :posts, through: :user + has_many :job_categories, through: :profile_job_categories has_many :reports_submitted, class_name: 'Report', dependent: :destroy - has_many :reports_received, class_name: 'Report', as: :reportable, dependent: :destroy - + has_many :connections, foreign_key: :followed_profile_id, dependent: :destroy, inverse_of: :followed_profile + has_many :followers, class_name: 'Connection', foreign_key: :followed_profile_id, dependent: :destroy, + inverse_of: :follower + has_many :followed_profiles, class_name: 'Connection', foreign_key: :follower_id, dependent: :destroy, + inverse_of: :followed_profile accepts_nested_attributes_for :personal_info accepts_nested_attributes_for :professional_infos accepts_nested_attributes_for :education_infos @@ -47,22 +39,24 @@ def profile_permalink user.full_name.to_s end + def self.order_by_premium + joins(user: :subscription).order('subscriptions.status DESC, users.full_name ASC') + end + def self.advanced_search(search_query) left_outer_joins(:job_categories, :personal_info, :user).where( - 'job_categories.name LIKE :term OR - personal_infos.city LIKE :term OR - users.full_name LIKE :term OR users.search_name LIKE :term', + 'job_categories.name LIKE :term OR personal_infos.city LIKE :term OR users.full_name LIKE :term + OR users.search_name LIKE :term', { term: "%#{sanitize_sql_like(search_query)}%" } ).public_profile.active.uniq end def self.get_profile_job_categories_json(query) profiles = search_by_job_categories(query) - profiles_json = profiles.map do |profile| + profiles.map do |profile| { user_id: profile.user_id, full_name: profile.full_name, job_categories: ProfileJobCategory.generate_profile_job_categories_json(profile.id) } - end - profiles_json.as_json + end.as_json end def self.search_by_job_categories(query) @@ -99,10 +93,7 @@ def self.most_followed(limit) def inactive! super user.update(old_name: user.full_name, full_name: 'Perfil Desativado') - user.posts.each do |post| - post.update(old_status: post.status) - end - + user.posts.each { |post| post.update(old_status: post.status) } user.posts.each(&:archived!) Connection.where(follower: self).or(Connection.where(followed_profile: self)).find_each(&:inactive!) end @@ -110,9 +101,7 @@ def inactive! def active! super user.update(full_name: user.old_name) - user.posts.each do |post| - post.update(status: post.old_status) - end + user.posts.each { |post| post.update(status: post.old_status) } Connection.where(follower: self).or(Connection.where(followed_profile: self)).find_each(&:active!) end diff --git a/spec/models/profile_spec.rb b/spec/models/profile_spec.rb index 217d17f..5c2c04c 100644 --- a/spec/models/profile_spec.rb +++ b/spec/models/profile_spec.rb @@ -248,4 +248,35 @@ expect(Connection.active.count).to eq 2 end end + + describe '#order_by_premium' do + it 'retorna perfis premium primeiro e depois os perfis free' do + create(:user, :free, full_name: 'André Porteira') + create(:user, :free, full_name: 'Eliseu Ramos') + create(:user, full_name: 'Moisés Campus') + user_premium_inactive = create(:user, full_name: 'Joao Almeida') + user_premium_inactive.subscription.inactive! + + result = Profile.order_by_premium + + expect(result.first.full_name).to eq 'Moisés Campus' + expect(result.second.full_name).to eq 'André Porteira' + expect(result.third.full_name).to eq 'Eliseu Ramos' + expect(result.fourth.full_name).to eq 'Joao Almeida' + end + + it 'ordena por nome em caso de mesmo status de assinatura' do + create(:user, :free, full_name: 'André Almeida') + create(:user, :free, full_name: 'André Barbosa') + create(:user, full_name: 'André Campus') + create(:user, full_name: 'André Dias') + + result = Profile.order_by_premium + + expect(result.first.full_name).to eq 'André Campus' + expect(result.second.full_name).to eq 'André Dias' + expect(result.third.full_name).to eq 'André Almeida' + expect(result.fourth.full_name).to eq 'André Barbosa' + end + end end diff --git a/spec/requests/apis/v1/search_user_by_job_categories_spec.rb b/spec/requests/apis/v1/search_user_by_job_categories_spec.rb index b8a5ccb..4c821f1 100644 --- a/spec/requests/apis/v1/search_user_by_job_categories_spec.rb +++ b/spec/requests/apis/v1/search_user_by_job_categories_spec.rb @@ -67,13 +67,13 @@ expect(json_response['data'].class).to eq Array expect(json_response['data'].first.keys).not_to include 'created_at' expect(json_response['data'].first.keys).not_to include 'updated_at' - expect(json_response['data'].first['profile_id']).to eq 1 - expect(json_response['data'].first['full_name']).to eq 'Joao Almeida' - expect(json_response['data'].first['job_categories']).to eq [{ 'name' => 'Ruby on Rails', - 'description' => 'Especialista em Ruby.' }] - expect(json_response['data'].second['profile_id']).to eq 2 - expect(json_response['data'].second['full_name']).to eq 'André Porteira' - expect(json_response['data'].second['job_categories']).to eq [] + expect(json_response['data'].first['profile_id']).to eq 2 + expect(json_response['data'].first['full_name']).to eq 'André Porteira' + expect(json_response['data'].first['job_categories']).to eq [] + expect(json_response['data'].second['profile_id']).to eq 1 + expect(json_response['data'].second['full_name']).to eq 'Joao Almeida' + expect(json_response['data'].second['job_categories']).to eq [{ 'name' => 'Ruby on Rails', + 'description' => 'Especialista em Ruby.' }] end it 'retorna um erro interno do servidor' do @@ -86,5 +86,39 @@ expect(json_response.class).to eq Hash expect(json_response['error']).to eq 'Houve um erro interno no servidor ao processar sua solicitação.' end + + it 'retorna perfis premium primeiro e depois os perfis comuns' do + create(:user, :free, full_name: 'Eliseu Ramos') + create(:user, :free, full_name: 'André Porteira') + create(:user, full_name: 'Moisés Campus') + create(:user, full_name: 'Joao Almeida') + + get '/api/v1/profiles' + + expect(response.status).to eq 200 + json_response = JSON.parse(response.body) + expect(json_response['data'].count).to eq 4 + expect(json_response['data'].first['full_name']).to eq 'Joao Almeida' + expect(json_response['data'].second['full_name']).to eq 'Moisés Campus' + expect(json_response['data'].third['full_name']).to eq 'André Porteira' + expect(json_response['data'].fourth['full_name']).to eq 'Eliseu Ramos' + end + + it 'retorna perfis premium primeiro e depois os perfis free na busca com parâmetro' do + ruby = create(:job_category, name: 'Ruby on Rails') + + user_premium = create(:user, full_name: 'Moisés Campus') + user_premium.profile.profile_job_categories.create(job_category: ruby, description: 'Sou um especialista em Ruby') + user_free = create(:user, :free, full_name: 'André Almeida') + user_free.profile.profile_job_categories.create(job_category: ruby, description: 'Fiz um e-commerce em Ruby') + + get '/api/v1/profiles', params: { search: 'ruby' } + + expect(response.status).to eq 200 + json_response = JSON.parse(response.body) + expect(json_response['data'].count).to eq 2 + expect(json_response['data'].first['full_name']).to eq 'Moisés Campus' + expect(json_response['data'].second['full_name']).to eq 'André Almeida' + end end end diff --git a/spec/system/connections/user_follows_another_user_spec.rb b/spec/system/connections/user_follows_another_user_spec.rb index 611217c..ce3dd7e 100644 --- a/spec/system/connections/user_follows_another_user_spec.rb +++ b/spec/system/connections/user_follows_another_user_spec.rb @@ -17,7 +17,7 @@ expect(mail).to have_received(:deliver_later) expect(Connection.count).to eq 1 - expect(page).to have_current_path profile_path(followed) + expect(page).to have_current_path profile_path(followed.profile.slug) expect(page).to have_content('Agora você está seguindo Eliseu Ramos') expect(page).not_to have_button('Seguir', exact: true) expect(page).to have_button('Deixar de Seguir', exact: true)