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

add remote filter to web/vacancies/index #38

Open
wants to merge 9 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
10 changes: 3 additions & 7 deletions apps/web/controllers/vacancies/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,23 @@ class Index

expose :vacancies
expose :pager
expose :search_query

params do
optional(:page).filled
optional(:query).filled
end

def call(params)
result = operation.call(search_query: search_query, page: params[:page])
@search_query = params[:query] ? search_query_parser.call(params[:query]) : EMPTY_SEARCH_QUERY
result = operation.call(search_query: @search_query, page: params[:page])

case result
when Success
@pager = result.value![:pager]
@vacancies = result.value![:result]
end
end

private

def search_query
params[:query] ? search_query_parser.call(params[:query]) : EMPTY_SEARCH_QUERY
end
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions apps/web/templates/vacancies/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ br
.col-sm-6
= subscribe_form

.row.mb-3
.col
.btn-group.btn-group-toggle
= remote_filter_button(text: 'Любые', remote_value: nil)
= remote_filter_button(text: 'Удаленные', remote_value: 'true')
= remote_filter_button(text: 'В офисе', remote_value: 'false')
/hr

/.row.mt-3.mb-3
Expand Down
24 changes: 24 additions & 0 deletions apps/web/views/vacancies/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@ def subscribe_form # rubocop:disable Metrics/MethodLength
end
end
end

def remote_filter_button(text:, remote_value:)
link_params =
if remote_value == current_remote_query
{ class: 'btn btn-light active' }
else
{ class: 'btn btn-light', href: remote_filter_button_href(remote_value) }
end

html.a(link_params) do
html.input(type: 'radio')
html.span { text }
end
end

private

def current_remote_query
search_query[:remote] if search_query[:remote] == 'true' || search_query[:remote] == 'false'
end

def remote_filter_button_href(remote_value)
routes.root_path(remote_value.nil? ? {} : { query: "remote:#{remote_value}" })
end
end
end
end
Expand Down
24 changes: 15 additions & 9 deletions lib/core/queries/vacancy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,29 @@ def initialize(repo = VacancyRepository.new)
@repo = repo
end

def all_with_contact(limit:, page:)
all_with_contact_relation(limit: limit, page: page).to_a
def all_with_contact(limit:, page:, remote_available: nil)
all_with_contact_relation(limit: limit, page: page, remote_available: remote_available).to_a
end

def pager_for_all_with_contact(limit:, page:)
def pager_for_all_with_contact(limit:, page:, remote_available: nil)
Hanami::Pagination::Pager.new(
all_with_contact_relation(limit: limit, page: page).pager
all_with_contact_relation(limit: limit, page: page, remote_available: remote_available).pager
)
end

private

def all_with_contact_relation(limit:, page:)
repo.aggregate(:contact)
.where(published: true, archived: false, deleted_at: nil)
.map_to(::Vacancy).order { created_at.desc }
.per_page(limit).page(page || 1)
def all_with_contact_relation(limit:, page:, remote_available:)
relation = repo.aggregate(:contact)
.where(published: true, archived: false, deleted_at: nil)
.map_to(::Vacancy).order { created_at.desc }
.per_page(limit).page(page || 1)

unless remote_available.nil?
relation = relation.where(remote_available: remote_available)
end

relation
end
end
end
9 changes: 7 additions & 2 deletions lib/vacancies/operations/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ class List < ::Libs::Operation
PAGINATION_LIMIT = 10

def call(search_query: {}, page: 1) # rubocop:disable Lint/UnusedMethodArgument
pager = vacancy_query.pager_for_all_with_contact(limit: PAGINATION_LIMIT, page: page || 1)
result = vacancy_query.all_with_contact(limit: PAGINATION_LIMIT, page: page || 1)
remote_available = { 'true' => true, 'false' => false }[search_query[:remote]]
pager = vacancy_query.pager_for_all_with_contact(limit: PAGINATION_LIMIT,
page: page || 1,
remote_available: remote_available)
result = vacancy_query.all_with_contact(limit: PAGINATION_LIMIT,
page: page || 1,
remote_available: remote_available)

Success(result: result, pager: pager)
end
Expand Down
15 changes: 13 additions & 2 deletions spec/core/queries/vacancy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
let(:repo) { described_class.new }

describe '#all_with_contact' do
subject { repo.all_with_contact(limit: 10, page: 1) }
subject { repo.all_with_contact(limit: 10, page: 1, remote_available: remote_available) }

before { Fabricate.create(:vacancy, published: published, archived: archived, deleted_at: deleted_at) }
let(:remote_available) { nil }

before do
Fabricate.create(:vacancy, published: published, archived: archived,
deleted_at: deleted_at, remote_available: false)
end

context 'when vacancy published and not archived or deleted' do
let(:published) { true }
Expand All @@ -16,6 +21,12 @@
it { expect(subject.count).to eq(1) }
it { expect(subject).to all(be_a(Vacancy)) }
it { expect(subject.first.contact).to be_a(Contact) }

context 'when remote_available is true' do
let(:remote_available) { true }

it { expect(subject).to eq([]) }
end
end

context 'when vacancy published and archived' do
Expand Down
50 changes: 50 additions & 0 deletions spec/vacancies/operations/list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,56 @@
it { expect(subject.value!).to eq(result: [], pager: pager) }
end

context 'with remote query' do
subject { operation.call(search_query: { remote: remote_query }) }

let(:vacancies) { [] }

context 'when remote_query nil' do
let(:remote_query) { nil }

it do
expect(vacancy_query)
.to receive(:all_with_contact)
.with(limit: 10, page: 1, remote_available: nil)
subject
end
end

context 'when remote_query not true or false string' do
let(:remote_query) { 'not true or false string' }

it do
expect(vacancy_query)
.to receive(:all_with_contact)
.with(limit: 10, page: 1, remote_available: nil)
subject
end
end

context 'when remote_query true' do
let(:remote_query) { 'true' }

it do
expect(vacancy_query)
.to receive(:all_with_contact)
.with(limit: 10, page: 1, remote_available: true)
subject
end
end

context 'when remote_query false' do
let(:remote_query) { 'false' }

it do
expect(vacancy_query)
.to receive(:all_with_contact)
.with(limit: 10, page: 1, remote_available: false)
subject
end
end
end

context 'with real dependencies' do
subject { operation.call }

Expand Down
2 changes: 1 addition & 1 deletion spec/web/controllers/vacancies/index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
expect(action.pager).to eq(pager)
end

context 'when params inlcludes query param' do
context 'when params includes query param' do
let(:params) { { query: 'remote:true search text' } }

it { expect(subject).to be_success }
Expand Down
66 changes: 65 additions & 1 deletion spec/web/views/vacancies/index_spec.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,76 @@
# frozen_string_literal: true

RSpec.describe Web::Views::Vacancies::Index, type: :view do
let(:exposures) { Hash[format: :html] }
let(:params) { Hash[] }
let(:search_query) { Hash[] }
let(:exposures) { Hash[format: :html, flash: {}, params: params, vacancies: [], search_query: search_query] }
let(:template) { Hanami::View::Template.new('apps/web/templates/vacancies/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

describe 'remote radiobuttons' do
let(:rendered) { without_indentation(view.render) }

before { allow(view).to receive(:pagination) }

it do
expect(rendered).to include without_indentation <<~HTML
<div class="btn-group btn-group-toggle">
<a class="btn btn-light active"><span>Любые</span></a>
<a class="btn btn-light" href="/?query=remote%3Atrue"><span>Удаленные</span></a>
<a class="btn btn-light" href="/?query=remote%3Afalse"><span>В офисе</span></a>
</div>
HTML
end

context 'when remote is true' do
let(:search_query) { Hash[remote: 'true'] }

it do
expect(rendered).to include without_indentation <<~HTML
<div class="btn-group btn-group-toggle">
<a class="btn btn-light" href="/"><span>Любые</span></a>
<a class="btn btn-light active"><span>Удаленные</span></a>
<a class="btn btn-light" href="/?query=remote%3Afalse"><span>В офисе</span></a>
</div>
HTML
end
end

context 'when remote is false' do
let(:search_query) { Hash[remote: 'false'] }

it do
expect(rendered).to include without_indentation <<~HTML
<div class="btn-group btn-group-toggle">
<a class="btn btn-light" href="/"><span>Любые</span></a>
<a class="btn btn-light" href="/?query=remote%3Atrue"><span>Удаленные</span></a>
<a class="btn btn-light active"><span>В офисе</span></a>
</div>
HTML
end
end

context 'when remote is not valid' do
let(:search_query) { Hash[remote: 'foo'] }

it do
expect(rendered).to include without_indentation <<~HTML
<div class="btn-group btn-group-toggle">
<a class="btn btn-light active"><span>Любые</span></a>
<a class="btn btn-light" href="/?query=remote%3Atrue"><span>Удаленные</span></a>
<a class="btn btn-light" href="/?query=remote%3Afalse"><span>В офисе</span></a>
</div>
HTML
end
end
end

def without_indentation(string)
string.strip.gsub("\n", '')
end
end