From ba9f76625fb04df5e1cbdf593923ff4b76712e4a Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 23 Jul 2020 20:58:07 +0300 Subject: [PATCH 1/5] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC?= =?UTF-8?q?=D0=B0=20=D1=81=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=D0=BC=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/config/routes.rb | 2 +- apps/web/controllers/interviews/index.rb | 29 +++++++++++++ apps/web/templates/companies/show.html.slim | 17 +++++--- apps/web/templates/interviews/index.html.slim | 40 ++++++++++++++++++ apps/web/views/interviews/index.rb | 42 +++++++++++++++++++ spec/web/controllers/interviews/index_spec.rb | 9 ++++ spec/web/views/interviews/index_spec.rb | 10 +++++ 7 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 apps/web/controllers/interviews/index.rb create mode 100644 apps/web/templates/interviews/index.html.slim create mode 100644 apps/web/views/interviews/index.rb create mode 100644 spec/web/controllers/interviews/index_spec.rb create mode 100644 spec/web/views/interviews/index_spec.rb diff --git a/apps/web/config/routes.rb b/apps/web/config/routes.rb index 4e1692f..937590e 100644 --- a/apps/web/config/routes.rb +++ b/apps/web/config/routes.rb @@ -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] diff --git a/apps/web/controllers/interviews/index.rb b/apps/web/controllers/interviews/index.rb new file mode 100644 index 0000000..ab79924 --- /dev/null +++ b/apps/web/controllers/interviews/index.rb @@ -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 :company, :interviews + + def call(params) + result = operation.call(id: params[:id]) + + case result + when Success + @company = result.value! + @reviews = interview_operation.call(company_id: @company.id).value_or([]) + when Failure + redirect_to routes.companies_path + end + end + end + end + end +end diff --git a/apps/web/templates/companies/show.html.slim b/apps/web/templates/companies/show.html.slim index dec03f9..4186237 100644 --- a/apps/web/templates/companies/show.html.slim +++ b/apps/web/templates/companies/show.html.slim @@ -35,14 +35,19 @@ hr.mb-4.mt-4 | Только #{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 + ul class="nav nav-pills" + .col + li class="nav-item" + = link_to 'К списку компаний', routes.companies_path, class: 'btn btn-outline-secondary btn-lg' - 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 + li class="nav-item" + = link_to 'Оставить отзыв', routes.new_company_review_path(company.id), class: 'btn btn-success btn-lg new-vacancy-btn' + .col + li class="nav-item" + = link_to 'Интервью', routes.company_interviews_path(company.id), class: 'btn btn-active btn-lg new-vacancy-btn' - else + li class="nav-item" = link_to 'Оставить отзыв', '#', class: 'btn btn-success btn-lg new-vacancy-btn disabled' hr.mb-4.mt-4 diff --git a/apps/web/templates/interviews/index.html.slim b/apps/web/templates/interviews/index.html.slim new file mode 100644 index 0000000..2392082 --- /dev/null +++ b/apps/web/templates/interviews/index.html.slim @@ -0,0 +1,40 @@ +.row.mt-4 + .col + h1 + = link_to 'Компании', routes.companies_path + +.row.mt-3.mb-3 + .col + | RubyJobs.dev — бесплатная площадка для размещения вакансий, отзывов на компанию и поиска разработчиков на Ruby, Hanami и Rails. + +- if current_account.id.nil? + br + + .row.mt-3.mb-3 + .col + | Только #{link_to 'зарегистрированные пользователи', '/auth/github', class: 'link-in-text' } могут оставлять отзывы о компаниях + +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 + | Отзывов пока нет. Оставте первый отзыв \ No newline at end of file diff --git a/apps/web/views/interviews/index.rb b/apps/web/views/interviews/index.rb new file mode 100644 index 0000000..baec684 --- /dev/null +++ b/apps/web/views/interviews/index.rb @@ -0,0 +1,42 @@ +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 + end + end + end +end diff --git a/spec/web/controllers/interviews/index_spec.rb b/spec/web/controllers/interviews/index_spec.rb new file mode 100644 index 0000000..e00d30e --- /dev/null +++ b/spec/web/controllers/interviews/index_spec.rb @@ -0,0 +1,9 @@ +RSpec.describe Web::Controllers::Interviews::::Index, type: :action do + let(:action) { described_class.new } + let(:params) { Hash[] } + + it 'is successful' do + response = action.call(params) + expect(response[0]).to eq 200 + end +end diff --git a/spec/web/views/interviews/index_spec.rb b/spec/web/views/interviews/index_spec.rb new file mode 100644 index 0000000..eefd4af --- /dev/null +++ b/spec/web/views/interviews/index_spec.rb @@ -0,0 +1,10 @@ +RSpec.describe Web::Views::Interviews::::Index, type: :view do + let(:exposures) { Hash[format: :html] } + let(:template) { Hanami::View::Template.new('apps/web/templates/interviews/index.html.slim') } + let(:view) { described_class.new(template, exposures) } + let(:rendered) { view.render } + + it 'exposes #format' do + expect(view.format).to eq exposures.fetch(:format) + end +end From 02047871d2fe2f6a61af15b18652f75b554b49ef Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 23 Jul 2020 22:26:45 +0300 Subject: [PATCH 2/5] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE=D1=81=D0=BC=D0=BE=D1=82?= =?UTF-8?q?=D1=80=D0=B5=D1=82=D1=8C=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B2=D1=8C=D1=8E=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20(=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=B2=D0=B8=D0=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/controllers/companies/show.rb | 1 - apps/web/controllers/interviews/index.rb | 12 ++++++------ apps/web/templates/interviews/index.html.slim | 2 ++ lib/interviews/operations/list.rb | 4 +++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/web/controllers/companies/show.rb b/apps/web/controllers/companies/show.rb index 7028559..dd0b3d2 100644 --- a/apps/web/controllers/companies/show.rb +++ b/apps/web/controllers/companies/show.rb @@ -16,7 +16,6 @@ class Show def call(params) result = operation.call(id: params[:id]) - case result when Success @company = result.value! diff --git a/apps/web/controllers/interviews/index.rb b/apps/web/controllers/interviews/index.rb index ab79924..b1b14ca 100644 --- a/apps/web/controllers/interviews/index.rb +++ b/apps/web/controllers/interviews/index.rb @@ -10,15 +10,15 @@ class Index interview_operation: 'interviews.operations.list' ] - expose :company, :interviews + expose :interviews, :company def call(params) - result = operation.call(id: params[:id]) - - case result + result = interview_operation.call(company_id: params[:company_id].to_i) + company_result = operation.call(id: params[:company_id].to_i) + case result && company_result when Success - @company = result.value! - @reviews = interview_operation.call(company_id: @company.id).value_or([]) + @interviews = result.value_or([]) + @company = company_result.value! when Failure redirect_to routes.companies_path end diff --git a/apps/web/templates/interviews/index.html.slim b/apps/web/templates/interviews/index.html.slim index 2392082..ef0244a 100644 --- a/apps/web/templates/interviews/index.html.slim +++ b/apps/web/templates/interviews/index.html.slim @@ -2,6 +2,8 @@ .col h1 = link_to 'Компании', routes.companies_path + | > #{link_to company.name, routes.company_path(company.id)} + | > Список отзывов .row.mt-3.mb-3 .col diff --git a/lib/interviews/operations/list.rb b/lib/interviews/operations/list.rb index 7a209f1..4700ecc 100644 --- a/lib/interviews/operations/list.rb +++ b/lib/interviews/operations/list.rb @@ -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 From 0481db463450e2610b5f901c228a99c76bc6d068 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 24 Jul 2020 21:42:08 +0300 Subject: [PATCH 3/5] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B8=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=D1=82=D0=B7=D1=8B=D0=B2=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=BE=D0=B1=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D1=8C=D1=8E=20(=D0=B1=D0=B5=D0=B7=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D0=B2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/controllers/interviews/create.rb | 2 +- apps/web/templates/companies/index.html.slim | 2 +- apps/web/templates/companies/show.html.slim | 20 ++++---- apps/web/templates/interviews/index.html.slim | 46 ++++++++++++++++--- apps/web/views/interviews/index.rb | 11 +++++ ...5224_add_interview_ratings_to_companies.rb | 2 +- lib/core/entities/company.rb | 7 ++- lib/core/repositories/company_repository.rb | 31 +++++++++++-- lib/interviews/operations/create.rb | 1 + 9 files changed, 97 insertions(+), 25 deletions(-) diff --git a/apps/web/controllers/interviews/create.rb b/apps/web/controllers/interviews/create.rb index 56da8f4..5be8915 100644 --- a/apps/web/controllers/interviews/create.rb +++ b/apps/web/controllers/interviews/create.rb @@ -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 diff --git a/apps/web/templates/companies/index.html.slim b/apps/web/templates/companies/index.html.slim index a3a50b7..c258a02 100644 --- a/apps/web/templates/companies/index.html.slim +++ b/apps/web/templates/companies/index.html.slim @@ -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 diff --git a/apps/web/templates/companies/show.html.slim b/apps/web/templates/companies/show.html.slim index 4186237..39f67c5 100644 --- a/apps/web/templates/companies/show.html.slim +++ b/apps/web/templates/companies/show.html.slim @@ -35,20 +35,18 @@ hr.mb-4.mt-4 | Только #{link_to 'зарегистрированные пользователи', '/auth/github', class: 'link-in-text' } могут оставлять отзывы о компаниях .row.mt-4 - ul class="nav nav-pills" - .col - li class="nav-item" - = link_to 'К списку компаний', routes.companies_path, class: 'btn btn-outline-secondary btn-lg' + .col + = link_to 'К списку компаний', routes.companies_path, class: 'btn btn-outline-secondary btn-lg' + + .col - if current_account.id - .col - li class="nav-item" - = link_to 'Оставить отзыв', routes.new_company_review_path(company.id), class: 'btn btn-success btn-lg new-vacancy-btn' - .col - li class="nav-item" - = link_to 'Интервью', routes.company_interviews_path(company.id), class: 'btn btn-active btn-lg new-vacancy-btn' + = link_to 'Оставить отзыв', routes.new_company_review_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 - li class="nav-item" = 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 diff --git a/apps/web/templates/interviews/index.html.slim b/apps/web/templates/interviews/index.html.slim index ef0244a..1f5a17a 100644 --- a/apps/web/templates/interviews/index.html.slim +++ b/apps/web/templates/interviews/index.html.slim @@ -3,18 +3,50 @@ h1 = link_to 'Компании', routes.companies_path | > #{link_to company.name, routes.company_path(company.id)} - | > Список отзывов + | > Список отзывов об интервью -.row.mt-3.mb-3 +.row .col - | RubyJobs.dev — бесплатная площадка для размещения вакансий, отзывов на компанию и поиска разработчиков на Ruby, Hanami и Rails. + = 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? - br + .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' - .row.mt-3.mb-3 - .col - | Только #{link_to 'зарегистрированные пользователи', '/auth/github', class: 'link-in-text' } могут оставлять отзывы о компаниях +hr.mb-4.mt-4 br diff --git a/apps/web/views/interviews/index.rb b/apps/web/views/interviews/index.rb index baec684..de208f6 100644 --- a/apps/web/views/interviews/index.rb +++ b/apps/web/views/interviews/index.rb @@ -36,6 +36,17 @@ def interview_author(interview) 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.rou}" + end end end end diff --git a/db/migrations/20200722145224_add_interview_ratings_to_companies.rb b/db/migrations/20200722145224_add_interview_ratings_to_companies.rb index 4a1390e..8028e02 100644 --- a/db/migrations/20200722145224_add_interview_ratings_to_companies.rb +++ b/db/migrations/20200722145224_add_interview_ratings_to_companies.rb @@ -4,7 +4,7 @@ change do alter_table :companies do add_column :interview_rating_total, Float, null: false, default: 0.0 - add_column :interviews, 'jsonb', default: '{}', null: false + add_column :interview_ratings, 'jsonb', default: '{}', null: false end end end diff --git a/lib/core/entities/company.rb b/lib/core/entities/company.rb index e018260..d03236a 100644 --- a/lib/core/entities/company.rb +++ b/lib/core/entities/company.rb @@ -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 diff --git a/lib/core/repositories/company_repository.rb b/lib/core/repositories/company_repository.rb index be2dffe..e323b9d 100644 --- a/lib/core/repositories/company_repository.rb +++ b/lib/core/repositories/company_repository.rb @@ -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? @@ -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) @@ -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) diff --git a/lib/interviews/operations/create.rb b/lib/interviews/operations/create.rb index 23ce658..543d258 100644 --- a/lib/interviews/operations/create.rb +++ b/lib/interviews/operations/create.rb @@ -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) From ad373a3fcf8f039468f5d3d59f4bbeb6ec10b480 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 27 Jul 2020 17:46:22 +0300 Subject: [PATCH 4/5] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/views/interviews/index.rb | 2 +- spec/interviews/operations/create_spec.rb | 16 +++++- .../web/controllers/interviews/create_spec.rb | 6 +-- spec/web/controllers/interviews/index_spec.rb | 53 ++++++++++++++++--- spec/web/views/interviews/index_spec.rb | 2 +- 5 files changed, 67 insertions(+), 12 deletions(-) diff --git a/apps/web/views/interviews/index.rb b/apps/web/views/interviews/index.rb index de208f6..5392519 100644 --- a/apps/web/views/interviews/index.rb +++ b/apps/web/views/interviews/index.rb @@ -45,7 +45,7 @@ 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.rou}" + raw "Компания #{company_link}, рейтинг #{company.rating_total.round}" end end end diff --git a/spec/interviews/operations/create_spec.rb b/spec/interviews/operations/create_spec.rb index dae5387..77467cb 100644 --- a/spec/interviews/operations/create_spec.rb +++ b/spec/interviews/operations/create_spec.rb @@ -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 { @@ -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 diff --git a/spec/web/controllers/interviews/create_spec.rb b/spec/web/controllers/interviews/create_spec.rb index 4a6797c..bc5411a 100644 --- a/spec/web/controllers/interviews/create_spec.rb +++ b/spec/web/controllers/interviews/create_spec.rb @@ -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 @@ -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 @@ -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 diff --git a/spec/web/controllers/interviews/index_spec.rb b/spec/web/controllers/interviews/index_spec.rb index e00d30e..ba0fae3 100644 --- a/spec/web/controllers/interviews/index_spec.rb +++ b/spec/web/controllers/interviews/index_spec.rb @@ -1,9 +1,50 @@ -RSpec.describe Web::Controllers::Interviews::::Index, type: :action do - let(:action) { described_class.new } - let(:params) { Hash[] } +RSpec.describe Web::Controllers::Interviews::Index, type: :action do + subject { action.call(params) } - it 'is successful' do - response = action.call(params) - expect(response[0]).to eq 200 + let(:action) { described_class.new(operation: operation, interview_operation: interview_operation) } + + let(:params) { { id: 0 } } + + context 'when operation returns success value' do + let(:operation) { ->(*) { Success(Company.new(id: 0)) } } + let(:interview_operation) { ->(*) { Success([Interview.new]) } } + + it { expect(subject).to be_success } + + it 'call operation with a right contract' do + expect(operation).to receive(:call).with(id: 0) + subject + end + + it 'exposes vacancy' do + subject + expect(action.company).to eq(Company.new(id: 0)) + expect(action.interviews).to eq([Interview.new]) + end + end + + context 'when operation returns failure value' do + let(:operation) { ->(*) { Failure(:not_found) } } + let(:interview_operation) { ->(*) { Success([Interview.new]) } } + + it { expect(subject).to redirect_to '/companies' } + + it 'call operation with a right contract' do + expect(operation).to receive(:call).with(id: 0) + subject + end + end + + context 'with real dependencies' do + subject { action.call(params) } + + let(:action) { described_class.new } + let(:params) { { id: company.id } } + + let(:company) { Fabricate.create(:company) } + + before { Fabricate(:review, company_id: company.id) } + + it { expect(subject).to be_success } end end diff --git a/spec/web/views/interviews/index_spec.rb b/spec/web/views/interviews/index_spec.rb index eefd4af..c6137a9 100644 --- a/spec/web/views/interviews/index_spec.rb +++ b/spec/web/views/interviews/index_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe Web::Views::Interviews::::Index, type: :view do +RSpec.describe Web::Views::Interviews::Index, type: :view do let(:exposures) { Hash[format: :html] } let(:template) { Hanami::View::Template.new('apps/web/templates/interviews/index.html.slim') } let(:view) { described_class.new(template, exposures) } From 80eceadbf6d279d9500326b8790491184e2356dc Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 30 Jul 2020 21:27:47 +0300 Subject: [PATCH 5/5] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BF=D0=BE=20=D0=BC=D0=B8=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=D0=BC=20=D0=B8=20=D0=BF=D0=BE=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=BB=D0=B5=D1=80=D1=83=20interv?= =?UTF-8?q?iews/index?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/controllers/interviews/index.rb | 4 ++-- .../20200722145224_add_interview_ratings_to_companies.rb | 2 +- db/migrations/20200730182023_change_fields_in_companies.rb | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 db/migrations/20200730182023_change_fields_in_companies.rb diff --git a/apps/web/controllers/interviews/index.rb b/apps/web/controllers/interviews/index.rb index b1b14ca..a445f58 100644 --- a/apps/web/controllers/interviews/index.rb +++ b/apps/web/controllers/interviews/index.rb @@ -15,10 +15,10 @@ class Index 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 result && company_result + case company_result when Success - @interviews = result.value_or([]) @company = company_result.value! + @interviews = result.value_or([]) when Failure redirect_to routes.companies_path end diff --git a/db/migrations/20200722145224_add_interview_ratings_to_companies.rb b/db/migrations/20200722145224_add_interview_ratings_to_companies.rb index 8028e02..4a1390e 100644 --- a/db/migrations/20200722145224_add_interview_ratings_to_companies.rb +++ b/db/migrations/20200722145224_add_interview_ratings_to_companies.rb @@ -4,7 +4,7 @@ change do alter_table :companies do add_column :interview_rating_total, Float, null: false, default: 0.0 - add_column :interview_ratings, 'jsonb', default: '{}', null: false + add_column :interviews, 'jsonb', default: '{}', null: false end end end diff --git a/db/migrations/20200730182023_change_fields_in_companies.rb b/db/migrations/20200730182023_change_fields_in_companies.rb new file mode 100644 index 0000000..2b03bf3 --- /dev/null +++ b/db/migrations/20200730182023_change_fields_in_companies.rb @@ -0,0 +1,7 @@ +Hanami::Model.migration do + change do + alter_table :companies do + rename_column :interviews, :interview_ratings + end + end +end