Skip to content
Snippets Groups Projects

Implement searching, storing and revisiting searches

Files
13
+ 147
0
defmodule PropertySearchContext do
use WhiteBread.Context
use Hound.Helpers
alias PropTrackr.Accounts
alias PropTrackr.Repo
alias PropTrackr.Accounts.User
alias PropTrackr.Properties.Property
scenario_starting_state fn _state ->
Ecto.Adapters.SQL.Sandbox.checkout(PropTrackr.Repo)
Ecto.Adapters.SQL.Sandbox.mode(PropTrackr.Repo, {:shared, self()})
Hound.start_session()
%{}
end
scenario_finalize fn _status, _state ->
Ecto.Adapters.SQL.Sandbox.checkin(PropTrackr.Repo)
Hound.end_session()
end
given_ ~r/^there exists following accounts$/, fn state, %{ table_data: table } ->
table
|> Enum.map(fn user_details -> User.changeset(%User{}, user_details) end)
|> Enum.each(fn changeset -> Repo.insert!(changeset) end)
existing_user = List.first(table)
{
:ok,
state
|> Map.put(:email, existing_user[:email])
}
end
given_ ~r/^the following properties exist$/, fn state, %{ table_data: table } ->
owner = Repo.get_by(User, email: state[:email])
advertisements =
table
|> Enum.map(fn details -> details |> Map.put(:reference, Ecto.UUID.generate()) end)
|> Enum.map(fn details -> {Ecto.build_assoc(owner, :properties, details), details} end)
|> Enum.map(fn {assoc, details} -> Property.changeset(assoc, details) end)
|> Enum.map(fn changeset -> Repo.insert!(changeset) end)
countries = Enum.map(advertisements, fn advertisement -> advertisement.location end)
|> Enum.map(fn location -> String.split(location, ",") end)
|> Enum.map(fn location -> List.last(location) end)
|> Enum.map(fn location -> String.trim(location) end)
|> Enum.uniq()
areas = Enum.map(advertisements, fn advertisement -> advertisement.location end)
|> Enum.map(fn location -> String.split(location, ",") end)
|> Enum.map(fn location -> List.first(location) end)
|> Enum.map(fn location -> String.trim(location) end)
|> Enum.uniq()
{
:ok,
state
|> Map.put(:advertisements, advertisements)
|> Map.put(:countries, countries)
|> Map.put(:areas, areas)
}
end
and_ ~r/^I want to perform a search$/, fn state ->
navigate_to("/")
click({:id, "search"})
{:ok, state}
end
then_ ~r/^I should see all countries of the properties in the filter options$/, fn state ->
countries = state[:countries]
Enum.each(countries, fn country ->
assert find_element(:css, "option[value='#{country}']")
end)
{:ok, state}
end
and_ ~r/^I should see all cities of the properties in the filter options$/, fn state ->
areas = state[:areas]
Enum.each(areas, fn area ->
assert find_element(:css, "option[value='#{area}']")
end)
{:ok, state}
end
and_ ~r/^I should see a max price filter with the max price of the properties$/, fn state ->
advertisements = state[:advertisements]
prices = Enum.map(advertisements, fn advertisement -> advertisement.price end)
max_price = Enum.max(prices)
assert visible_in_page? ~r/#{max_price}/
max_price_element = find_element(:css, "input[id='max_price']")
assert max_price_element
{:ok, state}
end
and_ ~r/^I should see a min price filter with the min price of the properties$/, fn state ->
advertisements = state[:advertisements]
prices = Enum.map(advertisements, fn advertisement -> advertisement.price end)
min_price = Enum.min(prices)
assert visible_in_page? ~r/#{min_price}/
min_price_element = find_element(:css, "input[id='min_price']")
assert min_price_element
{:ok, state}
end
and_ ~r/^I should see a max room filter with the room count of the properties$/, fn state ->
advertisements = state[:advertisements]
rooms = Enum.map(advertisements, fn advertisement -> advertisement.room_count end)
max_rooms = Enum.max(rooms)
assert visible_in_page? ~r/#{max_rooms}/
max_rooms_element = find_element(:css, "input[id='max_rooms']")
assert max_rooms_element
{:ok, state}
end
and_ ~r/^I should see a min room filter with the room count of the properties$/, fn state ->
advertisements = state[:advertisements]
rooms = Enum.map(advertisements, fn advertisement -> advertisement.room_count end)
min_rooms = Enum.max(rooms)
assert visible_in_page? ~r/#{min_rooms}/
min_rooms_element = find_element(:css, "input[id='min_rooms']")
assert min_rooms_element
{:ok, state}
end
when_ ~r/^I click on the search button$/, fn state ->
click({:id, "search_button"})
{:ok, state}
end
then_ ~r/^I should see "(?<count>[^"]+)" properties$/, fn state, %{ count: count } ->
el_count = length(find_all_elements(:class, "property-card"))
assert el_count == String.to_integer(count)
{:ok, state}
end
end
Loading