diff --git a/Gemfile.lock b/Gemfile.lock index f2dec7fe..5f0581e7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -560,7 +560,7 @@ GEM websocket-extensions (0.1.5) wicked_pdf (2.8.0) activesupport - wkhtmltopdf-binary (0.12.6.7) + wkhtmltopdf-binary (0.12.6.8) wkhtmltopdf-heroku (3.0.0) xpath (3.2.0) nokogiri (~> 1.8) diff --git a/app/controllers/web/account/vacancies_controller.rb b/app/controllers/web/account/vacancies_controller.rb index ae721b4e..97dc0ecf 100644 --- a/app/controllers/web/account/vacancies_controller.rb +++ b/app/controllers/web/account/vacancies_controller.rb @@ -21,6 +21,7 @@ def create @vacancy = Web::Account::VacancyForm.new(params[:vacancy]) @vacancy.creator = current_user + change_visibility(@vacancy) if @vacancy.save f(:success) redirect_to account_vacancies_path @@ -31,15 +32,14 @@ def create end def update - @vacancy = current_user.vacancies.find params[:id] - authorize @vacancy - vacancy = @vacancy.becomes(Web::Account::VacancyForm) - if vacancy.update(params[:vacancy]) - change_visibility(@vacancy) + vacancy = current_user.vacancies.find params[:id] + authorize vacancy + @vacancy = vacancy.becomes(Web::Account::VacancyForm) + change_visibility(@vacancy) + if @vacancy.update(params[:vacancy]) f(:success) redirect_to account_vacancies_path else - @vacancy = vacancy.becomes(Vacancy) f(:error) render :edit, status: :unprocessable_entity end @@ -50,6 +50,10 @@ def destroy; end private def change_visibility(vacancy) - vacancy.archive! if params[:archive] + if params[:on_moderate] + vacancy.send_to_moderate + else + vacancy.send_to_draft + end end end diff --git a/app/models/vacancy.rb b/app/models/vacancy.rb index 898effe9..d08e5eda 100644 --- a/app/models/vacancy.rb +++ b/app/models/vacancy.rb @@ -94,7 +94,7 @@ class Vacancy < ApplicationRecord belongs_to :country, optional: true aasm :state, column: :state, timestamps: true do - state :idle + state :idle, initial: true state :on_moderate state :published state :archived @@ -108,6 +108,10 @@ class Vacancy < ApplicationRecord transitions from: %i[idle canceled], to: :on_moderate end + event :send_to_draft do + transitions to: :idle + end + event :archive do transitions to: :archived end diff --git a/app/policies/vacancy_policy.rb b/app/policies/vacancy_policy.rb index 3968fd0f..4c2b5e6b 100644 --- a/app/policies/vacancy_policy.rb +++ b/app/policies/vacancy_policy.rb @@ -6,6 +6,6 @@ def edit? end def update? - @user.admin? || !@record.published? + @user.admin? || (!@record.published? && !@record.archived?) end end diff --git a/app/views/web/account/vacancies/_form.html.slim b/app/views/web/account/vacancies/_form.html.slim index 99efbbce..1de6e60a 100644 --- a/app/views/web/account/vacancies/_form.html.slim +++ b/app/views/web/account/vacancies/_form.html.slim @@ -51,8 +51,10 @@ = f.input :direction_list, input_html: { value: f.object.direction_list.to_s } .row.mt-5 .col-sm.d-flex.mb-3 - .me-3 = f.button :submit, class: 'btn-primary' - - if local_assigns.fetch(:show_archive_button, false) + .me-3 = f.submit t('.idle'), class: 'btn btn-success me-1 me-sm-3', name: 'idle' + - if vacancy.may_send_to_moderate? + .me-3 = f.submit t('.on_moderate'), class: 'btn btn-outline-primary', name: 'on_moderate' + / - if local_assigns.fetch(:show_archive_button, false) .me-3 = f.button :submit, t('.archive'), data: { confirm: t('confirm') }, class: 'btn-outline-primary', name: 'archive' .col-sm.d-flex.justify-content-end.mb-3 = link_to t('.cancel'), url_for(:back), class: 'btn btn-outline-secondary' diff --git a/config/locales/en.activerecord.yml b/config/locales/en.activerecord.yml index 76263c53..4c9113d2 100644 --- a/config/locales/en.activerecord.yml +++ b/config/locales/en.activerecord.yml @@ -24,6 +24,7 @@ en: restore: Restore from archive send_to_moderate: Send to moderate cancel: Cancel + send_to_draft: To draft attributes: resume/answer: content: Answer diff --git a/config/locales/en.views.yml b/config/locales/en.views.yml index 9bf72c8b..d58955bc 100644 --- a/config/locales/en.views.yml +++ b/config/locales/en.views.yml @@ -226,6 +226,8 @@ en: form: archive: Archive cancel: Cancel + idle: Draft + on_moderate: On moderate new: header: New vacancy edit: diff --git a/config/locales/ru.activerecord.yml b/config/locales/ru.activerecord.yml index b31c2c29..cc829580 100644 --- a/config/locales/ru.activerecord.yml +++ b/config/locales/ru.activerecord.yml @@ -16,6 +16,7 @@ ru: restore: Восстановить из архива send_to_moderate: Отправить на модерацию cancel: Отклонить + send_to_draft: В черновик models: career: Карьерный трек diff --git a/config/locales/ru.views.yml b/config/locales/ru.views.yml index 57bbfe07..45bedb34 100644 --- a/config/locales/ru.views.yml +++ b/config/locales/ru.views.yml @@ -256,6 +256,8 @@ ru: form: archive: В архив cancel: Отмена + idle: Черновик + on_moderate: На модерацию new: header: Новая вакансия edit: diff --git a/test/controllers/web/account/vacancies_controller_test.rb b/test/controllers/web/account/vacancies_controller_test.rb index 14b1e728..e69b20f5 100644 --- a/test/controllers/web/account/vacancies_controller_test.rb +++ b/test/controllers/web/account/vacancies_controller_test.rb @@ -53,6 +53,32 @@ class Web::Account::VacanciesControllerTest < ActionDispatch::IntegrationTest assert_redirected_to root_path end + test 'can not edit a archived job' do + user = users(:one) + archived_vacancy = vacancies(:archived_one) + sign_out @hr + sign_in user + + get edit_account_vacancy_path(archived_vacancy) + + assert_redirected_to root_path + end + + test 'can not update archived job' do + attrs = FactoryBot.attributes_for :vacancy + user = users(:one) + archived_vacancy = vacancies(:archived_one) + sign_out @hr + sign_in user + + patch account_vacancy_path(archived_vacancy), params: { vacancy: attrs } + assert_response :redirect + + archived_vacancy.reload + + assert { archived_vacancy.title != attrs[:title] } + end + test '#update' do attrs = FactoryBot.attributes_for :vacancy vacancy = vacancies(:one) @@ -79,4 +105,19 @@ class Web::Account::VacanciesControllerTest < ActionDispatch::IntegrationTest assert { published_vacancy.title != attrs[:title] } end + + test '#send_to_moderate' do + vacancy = vacancies(:draft_full) + attrs = FactoryBot.attributes_for(:vacancy) + params = { + on_moderate: true, + vacancy: attrs + } + + patch(account_vacancy_path(vacancy), params:) + vacancy.reload + + assert_redirected_to account_vacancies_path + assert { vacancy.on_moderate? } + end end diff --git a/test/controllers/web/admin/vacancies_controller_test.rb b/test/controllers/web/admin/vacancies_controller_test.rb index 59c395b6..95ca42c3 100644 --- a/test/controllers/web/admin/vacancies_controller_test.rb +++ b/test/controllers/web/admin/vacancies_controller_test.rb @@ -54,7 +54,7 @@ class Web::Admin::VacanciesControllerTest < ActionDispatch::IntegrationTest end test '#publish' do - vacancy = vacancies(:archived) + vacancy = vacancies(:archived_one) state_event = :publish attrs = vacancy.attributes.merge(state_event:) previous_published_at = vacancy.published_at @@ -91,7 +91,7 @@ class Web::Admin::VacanciesControllerTest < ActionDispatch::IntegrationTest end test '#restore' do - vacancy = vacancies(:archived) + vacancy = vacancies(:archived_one) patch restore_admin_vacancy_path(vacancy), params: { go_to: admin_vacancies_path(locale: I18n.locale) } diff --git a/test/fixtures/vacancies.yml b/test/fixtures/vacancies.yml index 2f965e02..348c0286 100644 --- a/test/fixtures/vacancies.yml +++ b/test/fixtures/vacancies.yml @@ -120,14 +120,23 @@ without_city_name: salary_from: 1000 salary_to: 2000 -archived: +archived_full: <<: *DEFAULTS - title: Archeved vacancy + title: Archeved vacancy full state: archived salary_from: 1000 salary_to: 2000 salary_currency: rub +archived_one: + <<: *DEFAULTS + title: Archeved vacancy one + state: archived + salary_from: 1000 + salary_to: 2000 + salary_currency: rub + creator: one + on_moderate: <<: *DEFAULTS title: On moderate vacancy @@ -151,3 +160,10 @@ over_month_old: title: Фронтендер salary_to: 2000 published_at: <%= 2.month.ago.to_fs(:db) %> + +draft_full: + <<: *DEFAULTS + title: Draft + state: idle + salary_from: 1000 + salary_to: 2000