Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review/interview show #80

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
resources :vacancies, only: %i[new create show]
resources :companies, only: %i[index show] do
resources :reviews, only: %i[new create], controller: 'reviews'
resources :interviews, only: %i[new create], controller: 'interviews'
resources :interviews, only: %i[index new create], controller: 'interviews'
end

resources :subscribers, only: %i[create]
Expand Down
1 change: 0 additions & 1 deletion apps/web/controllers/companies/show.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class Show

def call(params)
result = operation.call(id: params[:id])

case result
when Success
@company = result.value!
Expand Down
2 changes: 1 addition & 1 deletion apps/web/controllers/interviews/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def call(params) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
rollbar.error(result.failure, payload: params.to_h)
end

redirect_to routes.company_path(params[:company_id])
redirect_to routes.company_interviews_path(params[:company_id])
end

private
Expand Down
29 changes: 29 additions & 0 deletions apps/web/controllers/interviews/index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Web
module Controllers
module Interviews
class Index
include Web::Action
include Dry::Monads::Result::Mixin

include Import[
operation: 'companies.operations.show',
interview_operation: 'interviews.operations.list'
]

expose :interviews, :company

def call(params)
result = interview_operation.call(company_id: params[:company_id].to_i)
company_result = operation.call(id: params[:company_id].to_i)
case company_result
when Success
@company = company_result.value!
@interviews = result.value_or([])
when Failure
redirect_to routes.companies_path
end
end
end
end
end
end
2 changes: 1 addition & 1 deletion apps/web/templates/companies/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ ul.list-group
.col-sm-8
h4 = link_to company.name, routes.company_path(company.id), title: company.name
.col-sm-4
= "Рейтинг: #{company.rating_total}"
= "Рейтинг: #{company.rating_total} | Рейтинг интервью: #{company.interview_rating_total}"
.row
.col-sm-8
= company.url
Expand Down
5 changes: 4 additions & 1 deletion apps/web/templates/companies/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ hr.mb-4.mt-4
.col
- if current_account.id
= link_to 'Оставить отзыв', routes.new_company_review_path(company.id), class: 'btn btn-success btn-lg new-vacancy-btn'
= link_to 'Оставить отзыв', routes.new_company_interview_path(company.id), class: 'btn btn-success btn-lg new-vacancy-btn'
/col
/= link_to 'Отзывы об интервью', routes.company_interviews_path(company.id), class: 'btn btn-primary btn-lg new-interview-btn'
- else
= link_to 'Оставить отзыв', '#', class: 'btn btn-success btn-lg new-vacancy-btn disabled'
/.col
/= link_to 'Интервью', '#', class: 'btn btn-success btn-lg new-vacancy-btn disabled'

hr.mb-4.mt-4

Expand Down
74 changes: 74 additions & 0 deletions apps/web/templates/interviews/index.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.row.mt-4
.col
h1
= link_to 'Компании', routes.companies_path
| > #{link_to company.name, routes.company_path(company.id)}
| > Список отзывов об интервью

.row
.col
= company_information(company)

hr.mb-4.mt-4

.row
.col.mb-4.vacancy_details
-if company.ratings.any?
- default_rating_names.each do |rating, description|
.row
.col-8
= description
.col-4
= company_interview_ratings[rating]
- else
| Рейтингов пока нет. Оставте первый рейтинг

.likely.likely-big
.twitter Твитнуть
.facebook Поделиться
.vkontakte Поделиться
.telegram Отправить
.whatsapp Вотсапнуть

hr.mb-4.mt-4

- if current_account.id.nil?
.row
| Только #{link_to 'зарегистрированные пользователи', '/auth/github', class: 'link-in-text' } могут оставлять отзывы о компаниях

.row.mt-4
.col
= link_to 'К списку компаний', routes.companies_path, class: 'btn btn-outline-secondary btn-lg'

.col
- if current_account.id
= link_to 'Оставить отзыв', routes.new_company_interview_path(company.id), class: 'btn btn-success btn-lg new-vacancy-btn'
- else
= link_to 'Оставить отзыв', '#', class: 'btn btn-success btn-lg new-vacancy-btn disabled'

hr.mb-4.mt-4

br

.row
.col.mb-4.vacancy_details
-if interviews.any?
- interviews.each do |interview|
li.list-group-item
.row
/.col-sm-2
/img src="#{review.author.avatar_url}" alt="#{review.author.github} avatar" height="42" width="42"
.col-sm-6
h4 = interview_author(interview)
span = published_at(interview)


.row
hr.mb-4.mt-4

.row
.col
= raw(interview.body)

- else
| Отзывов пока нет. Оставте первый отзыв
53 changes: 53 additions & 0 deletions apps/web/views/interviews/index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
module Web
module Views
module Interviews
class Index
include Web::View

def title
'Отзывы на компании Ruby, Hanami и Rails'
end

# rubocop:disable Layout/LineLength
def seo_meta_information
{
title: 'Отзывы на компании Ruby, Hanami и Rails',
description: 'Отзывы на компании использующие Ruby по всему миру. Бесплатные условия для работодателей и соискателей.',
url: 'https://rubyjobs.dev/companies',
image: ''
}
end

def default_rating_names # rubocop:disable Metrics/MethodLength
{
overall_impression: 'Общее впечатление',
recommendation: 'Рекомендация друзьям'
}
end

def interview_author(interview)
if interview.anonymous
'Anonymous author'
else
raw "#{interview.author.name} (#{link_to interview.author.github, "https://github.com/#{interview.author.github}"})"
end
end

def published_at(interview)
RelativeTime.in_words(interview.created_at, locale: :ru)
end

def company_interview_ratings
Hanami::Utils::Hash.symbolize(company.interview_ratings)
end

def company_information(company)
# last_rating_time = RelativeTime.in_words(company.created_at, locale: :ru)
company_link = link_to company.name, company.url

raw "Компания #{company_link}, рейтинг #{company.rating_total.round}"
end
end
end
end
end
7 changes: 7 additions & 0 deletions db/migrations/20200730182023_change_fields_in_companies.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Hanami::Model.migration do
change do
alter_table :companies do
rename_column :interviews, :interview_ratings
end
end
end
7 changes: 6 additions & 1 deletion lib/core/entities/company.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
class Review < Hanami::Entity
end

class Interview < Hanami::Entity
end

class Company < Hanami::Entity
attributes do
attribute :id, Types::Int

attribute :reviews, Types::Collection(Review)
attribute :interviews, Types::Collection(Interview)

attribute :name, Types::String
attribute :url, Types::String

attribute :rating_total, Types::Float
attribute :ratings, Core::Types::CompanyRatings
attribute :interview_rating_total, Types::Float
attribute :interview_ratings, Core::Types::CompanyRatings

attribute :created_at, Types::Time
attribute :updated_at, Types::Time
Expand Down
31 changes: 28 additions & 3 deletions lib/core/repositories/company_repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ def update_statistic(id, ratings) # rubocop:disable Metrics/AbcSize, Metrics/Met

new_ratings = {}
company_ratings = Hanami::Utils::Hash.symbolize(company.ratings)

ALLOWED_RATINGS.each do |rating|
new_ratings[rating] = company_ratings[rating].to_f if ratings[rating].to_f.zero?

next unless ratings[rating].to_f.positive?

new_ratings[rating] = if company_ratings[rating].to_f.zero?
Expand All @@ -42,7 +40,6 @@ def update_statistic(id, ratings) # rubocop:disable Metrics/AbcSize, Metrics/Met
(company_ratings[rating].to_f + ratings[rating].to_f) / 2
end
end

total_rating = (new_ratings.values.sum / new_ratings.values.count).round(1)

update(id, ratings: new_ratings, rating_total: total_rating)
Expand All @@ -61,6 +58,34 @@ def update_statistic(id, ratings) # rubocop:disable Metrics/AbcSize, Metrics/Met
team_level
].freeze

def update_interview_statistic(id, interviews) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
transaction do |_t|
company = find(id)
new_interviews = {}
company_interviews = Hanami::Utils::Hash.symbolize(company.interview_ratings)
ALLOWED_INTERVIEW_RATINGS.each do |interview|
new_interviews[interview] = company_interviews[interview].to_f if interviews[interview].to_f.zero?

next unless interviews[interview].to_f.positive?

new_interviews[interview] = if company_interviews[interview].to_f.zero?
interviews[interview].to_f
else
(company_interviews[interview].to_f + interviews[interview].to_f) / 2
end
end

total_rating = (new_interviews.values.sum / new_interviews.values.count).round(1)

update(id, interview_ratings: new_interviews, interview_rating_total: total_rating)
end
end

ALLOWED_INTERVIEW_RATINGS = %i[
overall_impression
recommendation
].freeze

private

def where_by_downcased_name(company_name)
Expand Down
1 change: 1 addition & 0 deletions lib/interviews/operations/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def call(payload)
interview = yield persist_interview(payload)

# TODO: move this line with company repo to separate worker
company_repo.update_interview_statistic(payload[:company_id], payload[:interview_rating])
send_notification(interview)

Success(interview)
Expand Down
4 changes: 3 additions & 1 deletion lib/interviews/operations/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ class List < ::Libs::Operation
include Import[interview_repo: 'repositories.interview',]

def call(company_id:)
Success(interview_repo.all_for_companies(company_id))
Success(
interview_repo.all_for_companies(company_id)
)
end
end
end
Expand Down
16 changes: 15 additions & 1 deletion spec/interviews/operations/create_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
end

let(:interview_repo) { instance_double('InterviewRepository', create_with_interview_rating: Interview.new) }
let(:company_repo) { instance_double('CompanyRepository') }
let(:company_repo) { instance_double('CompanyRepository', update_interview_statistic: Company.new) }

let(:params) do
{
Expand All @@ -29,6 +29,20 @@
context 'when successful operation' do
it { expect(subject).to be_success }
it { expect(subject.value!).to be_a(Interview) }

it 'calls company statistic updater' do
expect(company_repo).to receive(:update_interview_statistic).with(
10,
{
author_id: 0,

overall_impression: 3.0,
recommendation: 3.0
}
)

subject
end
end

context 'when interview data is invalid' do
Expand Down
6 changes: 3 additions & 3 deletions spec/web/controllers/interviews/create_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
let(:operation) { ->(*) { Success(Vacancy.new(id: 123)) } }
let(:success_flash) { 'Отзыв успешно создан.' }

it { expect(subject).to redirect_to '/companies/1' }
it { expect(subject).to redirect_to '/companies/1/interviews' }

it 'shows flash message' do
subject
Expand All @@ -44,7 +44,7 @@
let(:operation) { ->(*) { Failure(:error) } }
let(:flash_message) { 'Произошла ошибка, пожалуйста повторите позже' }

it { expect(subject).to redirect_to '/companies/1' }
it { expect(subject).to redirect_to '/companies/1/interviews' }

it 'shows flash message' do
subject
Expand All @@ -59,7 +59,7 @@
let(:company_id) { Fabricate(:company).id }
let(:action) { described_class.new }

it { expect(subject).to redirect_to "/companies/#{company_id}" }
it { expect(subject).to redirect_to "/companies/#{company_id}/interviews" }
end

context 'when not authorised' do
Expand Down
Loading