[deploy] Classified listings refactor part 3 (#7498)

* Ignore category column

* Move view oriented class methods to helper

* Start refactoring ClassifiedListingsToolkit

* Add attr_accessor instead of category

* Replace old category column with association

* More cleanup

* Trigger Travis

* Don't rename associations, category_slug -> category

* Indiana Kohl and the missing newline

* More refactoring and spec fixes

* Add dashboard for classified listing categories

* Remove TODO comment

Co-authored-by: rhymes <rhymesete@gmail.com>
This commit is contained in:
Michael Kohl 2020-05-01 05:57:01 +07:00 committed by GitHub
parent 7ebd95f193
commit 46f94b135d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 303 additions and 109 deletions

View file

@ -0,0 +1,46 @@
module Admin
class ClassifiedListingCategoriesController < Admin::ApplicationController
# Overwrite any of the RESTful controller actions to implement custom behavior
# For example, you may want to send an email after a foo is updated.
#
# def update
# super
# send_foo_updated_email(requested_resource)
# end
# Override this method to specify custom lookup behavior.
# This will be used to set the resource for the `show`, `edit`, and `update`
# actions.
#
# def find_resource(param)
# Foo.find_by!(slug: param)
# end
# The result of this lookup will be available as `requested_resource`
# Override this if you have certain roles that require a subset
# this will be used to set the records shown on the `index` action.
#
# def scoped_resource
# if current_user.super_admin?
# resource_class
# else
# resource_class.with_less_stuff
# end
# end
# Override `resource_params` if you want to transform the submitted
# data before it's persisted. For example, the following would turn all
# empty values into nil values. It uses other APIs such as `resource_class`
# and `dashboard`:
#
# def resource_params
# params.require(resource_class.model_name.param_key).
# permit(dashboard.permitted_attributes).
# transform_values { |value| value == "" ? nil : value }
# end
# See https://administrate-prototype.herokuapp.com/customizing_controller_actions
# for more information
end
end

View file

@ -55,7 +55,7 @@ module Api
ATTRIBUTES_FOR_SERIALIZATION = %i[
id user_id organization_id title slug body_markdown cached_tag_list
category classified_listing_category_id category processed_html published
classified_listing_category_id processed_html published
].freeze
private_constant :ATTRIBUTES_FOR_SERIALIZATION

View file

@ -1,6 +1,15 @@
class ClassifiedListingsController < ApplicationController
include ClassifiedListingsToolkit
JSON_OPTIONS = {
only: %i[
title processed_html tag_list category id user_id slug contact_via_connect location
],
include: {
author: { only: %i[username name], methods: %i[username profile_image_90] }
}
}.freeze
before_action :set_classified_listing, only: %i[edit update destroy]
before_action :set_cache_control_headers, only: %i[index]
before_action :raise_suspended, only: %i[new create update]
@ -13,18 +22,22 @@ class ClassifiedListingsController < ApplicationController
if params[:view] == "moderate"
not_found unless @displayed_classified_listing
return redirect_to "/internal/listings/#{@displayed_classified_listing.id}/edit"
return redirect_to edit_internal_listing_path(id: @displayed_classified_listing.id)
end
@classified_listings =
if params[:category].blank?
published_listings.
order("bumped_at DESC").
includes(:user, :organization, :taggings, :classified_listing_category).
includes(:user, :organization, :taggings).
limit(12)
else
ClassifiedListing.none
end
@listings_json = @classified_listings.to_json(JSON_OPTIONS)
@displayed_listing_json = @displayed_classified_listing.to_json(JSON_OPTIONS)
set_surrogate_key_header "classified-listings-#{params[:category]}"
end

View file

@ -4,33 +4,22 @@ module ClassifiedListingsToolkit
MANDATORY_FIELDS_FOR_UPDATE = %i[body_markdown title tag_list].freeze
def unpublish_listing
@classified_listing.published = false
@classified_listing.save
@classified_listing.update(published: false)
end
def publish_listing
@classified_listing.published = true
@classified_listing.save
@classified_listing.update(published: true)
end
# TODO: why not just @classified_listing.update(listing_params)?
def update_listing_details
@classified_listing.title = listing_params[:title] if listing_params[:title]
@classified_listing.body_markdown = listing_params[:body_markdown] if listing_params[:body_markdown]
@classified_listing.tag_list = listing_params[:tag_list] if listing_params[:tag_list]
if listing_params[:classified_listing_category_id]
@classified_listing.classified_listing_category_id = listing_params[:classified_listing_category_id]
end
@classified_listing.location = listing_params[:location] if listing_params[:location]
@classified_listing.expires_at = listing_params[:expires_at] if listing_params[:expires_at]
@classified_listing.contact_via_connect = listing_params[:contact_via_connect] if listing_params[:contact_via_connect]
@classified_listing.save
# [thepracticaldev/oss] Not entirely sure what the intention behind the
# original code was, but at least this is more compact.
filtered_params = listing_params.reject { |_k, v| v.nil? }
@classified_listing.update(filtered_params)
end
def bump_listing_success
@classified_listing.bumped_at = Time.current
saved = @classified_listing.save
saved
@classified_listing.update(bumped_at: Time.current)
end
def clear_listings_cache
@ -59,7 +48,6 @@ module ClassifiedListingsToolkit
available_user_credits = current_user.credits.unspent
unless @classified_listing.valid?
# TODO: [thepracticaldev/oss] For now the credits are needed in the view
@credits = current_user.credits.unspent
process_unsuccessful_creation
return
@ -77,15 +65,15 @@ module ClassifiedListingsToolkit
end
ALLOWED_PARAMS = %i[
title body_markdown category classified_listing_category_id tag_list
title body_markdown classified_listing_category_id tag_list
expires_at contact_via_connect location organization_id action
].freeze
# Never trust parameters from the scary internet, only allow a specific list through.
# Filter for a set of known safe params
def listing_params
if params["classified_listing"]["tags"].present?
params["classified_listing"]["tags"] = params["classified_listing"]["tags"].join(", ")
params["classified_listing"]["tag_list"] = params["classified_listing"].delete "tags"
tags = params["classified_listing"].delete("tags")
if tags.present?
params["classified_listing"]["tag_list"] = tags.join(", ")
end
params.require(:classified_listing).permit(ALLOWED_PARAMS)
end

View file

@ -0,0 +1,73 @@
require "administrate/base_dashboard"
class ClassifiedListingCategoryDashboard < Administrate::BaseDashboard
# ATTRIBUTE_TYPES
# a hash that describes the type of each of the model's fields.
#
# Each different type represents an Administrate::Field object,
# which determines how the attribute is displayed
# on pages throughout the dashboard.
ATTRIBUTE_TYPES = {
classified_listings: Field::HasMany,
id: Field::Number,
cost: Field::Number,
created_at: Field::DateTime,
name: Field::String,
rules: Field::String,
slug: Field::String,
updated_at: Field::DateTime
}.freeze
# COLLECTION_ATTRIBUTES
# an array of attributes that will be displayed on the model's index page.
#
# By default, it's limited to four items to reduce clutter on index pages.
# Feel free to add, remove, or rearrange items.
COLLECTION_ATTRIBUTES = %i[
name
slug
rules
cost
].freeze
# SHOW_PAGE_ATTRIBUTES
# an array of attributes that will be displayed on the model's show page.
SHOW_PAGE_ATTRIBUTES = %i[
id
name
slug
rules
cost
created_at
updated_at
].freeze
# FORM_ATTRIBUTES
# an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = %i[
name
slug
rules
cost
].freeze
# COLLECTION_FILTERS
# a hash that defines filters that can be used while searching via the search
# field of the dashboard.
#
# For example to add an option to search for open resources by typing "open:"
# in the search field:
#
# COLLECTION_FILTERS = {
# open: ->(resources) { resources.where(open: true) }
# }.freeze
COLLECTION_FILTERS = {}.freeze
# Overwrite this method to customize how classified listing categories are displayed
# across all pages of the admin dashboard.
#
# def display_resource(classified_listing_category)
# "ClassifiedListingCategory ##{classified_listing_category.id}"
# end
end

View file

@ -30,6 +30,7 @@ class DashboardManifest
html_variant_successes
sponsorships
pro_memberships
classified_listing_categories
].freeze
# DASHBOARDS = [
# :users,

View file

@ -0,0 +1,19 @@
module ClassifiedListingHelper
def select_options_for_categories
ClassifiedListingCategory.select(:id, :name, :cost).map do |cl|
["#{cl.name} (#{cl.cost} #{'Credit'.pluralize(cl.cost)})", cl.id]
end
end
def categories_for_display
ClassifiedListingCategory.pluck(:slug, :name).map do |slug, name|
{ slug: slug, name: name }
end
end
def categories_available
ClassifiedListingCategory.all.each_with_object({}) do |cat, h|
h[cat.slug] = cat.attributes.slice("cost", "name", "rules")
end.deep_symbolize_keys
end
end

View file

@ -2,8 +2,8 @@ class ClassifiedListingTag < LiquidTagBase
PARTIAL = "classified_listings/liquid".freeze
def initialize(_tag_name, slug_path_url, _tokens)
striped_path = ActionController::Base.helpers.strip_tags(slug_path_url).strip
@listing = get_listing(striped_path)
stripped_path = ActionController::Base.helpers.strip_tags(slug_path_url).strip
@listing = get_listing(stripped_path)
end
def render(_context)
@ -24,7 +24,7 @@ class ClassifiedListingTag < LiquidTagBase
hash = get_hash(url)
raise StandardError, "Invalid URL or slug. Listing not found." if hash.nil?
listing = ClassifiedListing.find_by(hash)
listing = ClassifiedListing.in_category(hash[:category]).find_by(slug: hash[:slug])
raise StandardError, "Invalid URL or slug. Listing not found." unless listing
listing

View file

@ -1,4 +1,6 @@
class ClassifiedListing < ApplicationRecord
self.ignored_columns = ["category"]
include Searchable
SEARCH_SERIALIZER = Search::ClassifiedListingSerializer
@ -6,10 +8,9 @@ class ClassifiedListing < ApplicationRecord
attr_accessor :action
# This allows to create a listing from a catgory string.
# TODO: [mkohl] refactor once column was dropped.
before_validation :assign_classified_listing_category
# Note: categories were hardcoded at first and this model was only added later,
# so the association name is a bit verbose since the original "category" attribute
# was kept to minimize code changes.
belongs_to :classified_listing_category
belongs_to :user
belongs_to :organization, optional: true
@ -29,38 +30,19 @@ class ClassifiedListing < ApplicationRecord
validates :location, length: { maximum: 32 }
validate :restrict_markdown_input
validate :validate_tags
validate :validate_category
scope :published, -> { where(published: true) }
scope :in_category, lambda { |slug|
joins(:classified_listing_category).
where("classified_listing_categories.slug" => slug)
}
# TODO: refactor this class method block
def self.select_options_for_categories
ClassifiedListingCategory.select(:id, :name, :cost).map do |cl|
["#{cl.name} (#{cl.cost} #{'Credit'.pluralize(cl.cost)})", cl.id]
end
end
def self.categories_for_display
ClassifiedListingCategory.pluck(:slug, :name).map do |slug, name|
{ slug: slug, name: name }
end
end
def self.categories_available
ClassifiedListingCategory.all.each_with_object({}) do |cat, h|
h[cat.slug] = cat.attributes.slice("cost", "name", "rules")
end.deep_symbolize_keys
end
delegate :cost, to: :classified_listing_category
def category
classified_listing_category&.slug
end
def cost
@cost = classified_listing_category&.cost ||
ClassifiedListingCategory.select(:cost).find_by(slug: category)&.cost
end
def author
organization || user
end
@ -82,7 +64,6 @@ class ClassifiedListing < ApplicationRecord
def modify_inputs
ActsAsTaggableOn::Taggable::Cache.included(ClassifiedListing)
ActsAsTaggableOn.default_parser = ActsAsTaggableOn::TagParser
self.category = category.to_s.downcase
self.body_markdown = body_markdown.to_s.gsub(/\r\n/, "\n")
end
@ -93,11 +74,6 @@ class ClassifiedListing < ApplicationRecord
errors.add(:body_markdown, "is not allowed to include liquid tags.") if markdown_string.include?("{% ")
end
def validate_category
categories = ClassifiedListingCategory.pluck(:slug)
errors.add(:category, "not a valid category") unless category.in?(categories)
end
def validate_tags
errors.add(:tag_list, "exceed the maximum of 8 tags") if tag_list.length > 8
end
@ -105,14 +81,4 @@ class ClassifiedListing < ApplicationRecord
def create_slug
self.slug = "#{title.downcase.parameterize.delete('_')}-#{rand(100_000).to_s(26)}"
end
def assign_classified_listing_category
return if classified_listing_category_id.present?
category = ClassifiedListingCategory.find_by(slug: attributes["category"])
return unless category
self.category = category.slug
self.classified_listing_category_id = category.id
end
end

View file

@ -9,8 +9,8 @@
<div id="listingform-data"
data-listing="<%= classified_listing.to_json(only: %i[id title body_markdown category cached_tag_list]) %>"
data-organizations="<%= @organizations.to_json(only: %i[id name]) %>"
data-categories-for-select="<%= ClassifiedListing.select_options_for_categories.to_json %>"
data-categories-for-details="<%= ClassifiedListing.categories_available.transform_values { |value_hash| value_hash.except(:cost) }.values.to_json %>">
data-categories-for-select="<%= select_options_for_categories.to_json %>"
data-categories-for-details="<%= categories_available.transform_values { |value_hash| value_hash.except(:cost) }.values.to_json %>">
<div style="height: 745px;">
<div class="field">
<%= form.label "title" %>

View file

@ -28,25 +28,19 @@
<div class="home">
<div class="classifieds-container" id="classifieds-index-container"
data-category="<%= params[:category] %>" data-listings="<%= @classified_listings.to_json(
only: %i[title processed_html tag_list category id user_id slug contact_via_connect location],
include: {
author: { only: %i[username name], methods: %i[username profile_image_90] }
}
) %>"
data-allcategories="<%= ClassifiedListing.categories_for_display.to_json %>"
data-category="<%= params[:category] %>" data-listings="<%= @listings_json %>"
data-allcategories="<%= categories_for_display.to_json %>"
<% if @displayed_classified_listing %>
data-displayedlisting="<%= @displayed_classified_listing.to_json(
only: %i[title processed_html tag_list category id user_id slug contact_via_connect location],
include: {
author: { only: %i[username name], methods: %i[username profile_image_90] }
},
) %> "
data-displayedlisting="<%= @displayed_listing_json %> "
<% end %>
>
<div class="classified-filters">
<div class="classified-filters-categories">
<a href="/listings" class="<%= "selected" if params[:category].blank? %> data-no-instant="true">all</a><% ClassifiedListing.categories_for_display.each do |cat| %><a href="/listings/<%= cat[:slug] %>" class="<%= "selected" if params[:category] == cat[:slug] %> data-no-instant="true"><%= cat[:name] %></a><% end %><a href='/listings/new' class='classified-create-link'>Create a Listing</a>
<a href="/listings" class="<%= "selected" if params[:category].blank? %> data-no-instant="true">all</a>
<% categories_for_display.each do |cat| %>
<a href="/listings/<%= cat[:slug] %>" class="<%= "selected" if params[:category] == cat[:slug] %> data-no-instant="true"><%= cat[:name] %></a>
<% end %>
<a href='/listings/new' class='classified-create-link'>Create a Listing</a>
<% if @displayed_classified_listing %>
<div class="classified-listings-modal-background" role='presentation'></div>
<% end %>

View file

@ -18,7 +18,7 @@
</div>
<div class="form-group">
<%= form.label :classified_listing_category_id %>
<%= form.select :classified_listing_category_id, ClassifiedListing.select_options_for_categories %>
<%= form.select :classified_listing_category_id, select_options_for_categories %>
</div>
<div class="form-check">
<%= form.check_box :published, checked: @classified_listing.published? %>

View file

@ -11,7 +11,7 @@
</div>
<div class="form-group">
<%= label_tag(:filter, "Category") %>
<%= select_tag(:filter, options_for_select(ClassifiedListing.categories_available.keys, params[:filter]), include_blank: true) %>
<%= select_tag(:filter, options_for_select(categories_available.keys, params[:filter]), include_blank: true) %>
</div>
<div class="form-group">
<%= label_tag(:include_unpublished, "Include unpublished listings") %>

View file

@ -308,6 +308,7 @@ ActiveRecord::Schema.define(version: 2020_04_26_124118) do
t.string "slug"
t.string "status", default: "active"
t.datetime "updated_at", null: false
t.index ["slug"], name: "index_chat_channels_on_slug", unique: true
end
create_table "classified_listing_categories", force: :cascade do |t|
@ -1216,9 +1217,9 @@ ActiveRecord::Schema.define(version: 2020_04_26_124118) do
t.datetime "updated_at", null: false
t.string "username"
t.string "website_url"
t.string "youtube_url"
t.boolean "welcome_notifications", default: true, null: false
t.datetime "workshop_expiration"
t.string "youtube_url"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["created_at"], name: "index_users_on_created_at"
t.index ["email"], name: "index_users_on_email", unique: true

View file

@ -4,7 +4,7 @@ SEEDS_MULTIPLIER = [1, ENV["SEEDS_MULTIPLIER"].to_i].max
counter = 0
Rails.logger.info "Seeding with multiplication factor: #{SEEDS_MULTIPLIER}"
##############################################################################
##############################################################################/
counter += 1
Rails.logger.info "#{counter}. Creating Organizations"
@ -371,6 +371,49 @@ end
##############################################################################
counter += 1
Rails.logger.info "#{counter}. Creating Classified Listings"
users_in_random_order.each { |user| Credit.add_to(user, rand(100)) }
users = users_in_random_order.to_a
listings_categories = ClassifiedListingCategory.pluck(:id)
listings_categories.each.with_index(1) do |category_id, index|
# rotate users if they are less than the categories
user = users.at(index % users.length)
2.times do
ClassifiedListing.create!(
user: user,
title: Faker::Lorem.sentence,
body_markdown: Faker::Markdown.random,
location: Faker::Address.city,
organization_id: user.organizations.first&.id,
classified_listing_category_id: category_id,
contact_via_connect: true,
published: true,
bumped_at: Time.current,
tag_list: Tag.order(Arel.sql("RANDOM()")).first(2).pluck(:name),
)
end
end
##############################################################################
counter += 1
Rails.logger.info "#{counter}. Creating Pages"
5.times do
Page.create!(
title: Faker::Hacker.say_something_smart,
body_markdown: Faker::Markdown.random,
slug: Faker::Internet.slug,
description: Faker::Books::Dune.quote,
template: %w[contained full_within_layout].sample,
)
end
##############################################################################
counter += 1
Rails.logger.info "#{counter}. Creating Classified Listing Categories"

View file

@ -10,5 +10,11 @@ FactoryBot.define do
slug { "cfp" }
cost { 5 }
end
trait :jobs do
name { "Job Listings" }
slug { "jobs" }
cost { 1 }
end
end
end

View file

@ -0,0 +1,41 @@
require "rails_helper"
RSpec.describe ClassifiedListingHelper, type: :helper do
let_it_be_readonly(:cat1) { create(:classified_listing_category, cost: 1) }
let_it_be_readonly(:cat2) { create(:classified_listing_category, :cfp, cost: 5) }
describe "select_options_for_categories" do
it "returns the correct options array" do
expect(helper.select_options_for_categories).to match_array(
[
["#{cat1.name} (1 Credit)", cat1.id],
["#{cat2.name} (5 Credits)", cat2.id],
]
)
end
end
describe "categories_for_display" do
it "return the correct hash of slug and name pairs" do
expect(helper.categories_for_display).to match_array(
[
{ slug: cat1.slug, name: cat1.name },
{ slug: cat2.slug, name: cat2.name },
]
)
end
end
describe "categories_available" do
it "returns a hash with slugs as keys" do
expected = [cat1.slug.to_sym, cat2.slug.to_sym]
expect(helper.categories_available.keys).to match_array(expected)
end
it "categories have the correct keys" do
cfp_category = helper.categories_available[:cfp]
expect(cfp_category.keys).to match_array(%i[cost name rules])
end
end
end

View file

@ -6,7 +6,7 @@ RSpec.describe CacheBuster, type: :labor do
let(:article) { create(:article, user_id: user.id) }
let(:comment) { create(:comment, user_id: user.id, commentable: article) }
let(:organization) { create(:organization) }
let(:listing) { create(:classified_listing, user_id: user.id, category: "cfp") }
let(:listing) { create(:classified_listing, user_id: user.id) }
let(:podcast) { create(:podcast) }
let(:podcast_episode) { create(:podcast_episode, podcast_id: podcast.id) }
let(:tag) { create(:tag) }

View file

@ -9,7 +9,6 @@ RSpec.describe ClassifiedListingTag, type: :liquid_tag do
title: "save me pls",
body_markdown: "sigh sigh sigh",
processed_html: "<p>sigh sigh sigh</p>",
category: "cfp",
tag_list: %w[a b c],
organization_id: nil,
)
@ -22,7 +21,6 @@ RSpec.describe ClassifiedListingTag, type: :liquid_tag do
title: "this old af",
body_markdown: "exxpired",
processed_html: "<p>exxpired</p>",
category: "cfp",
tag_list: %w[x y z],
organization_id: nil,
bumped_at: datetime,
@ -43,7 +41,6 @@ RSpec.describe ClassifiedListingTag, type: :liquid_tag do
title: "this is a job posting",
body_markdown: "wow code lots get not only money but satisfaction from work",
processed_html: "<p>wow code lots get not only money but satisfaction from work</p>",
category: "misc",
tag_list: %w[a b c],
organization_id: org.id,
)

View file

@ -127,7 +127,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do
describe "GET /api/listings/:id" do
include_context "with 7 listings and 2 user"
let(:listing) { ClassifiedListing.where(category: "cfp").last }
let(:listing) { ClassifiedListing.in_category("cfp").last }
context "when unauthenticated" do
it "returns a published listing" do
@ -293,7 +293,8 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do
it "fails if category is invalid" do
post_classified_listing(title: "Title", body_markdown: "body", category: "unknown")
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body.dig("errors", "category").first).to match(/not a valid category/)
expect(response.parsed_body.dig("errors", "classified_listing_category").first).
to match(/must exist/)
end
it "does not subtract credits or create a listing if the listing is not valid" do
@ -312,8 +313,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do
post_classified_listing(listing_params)
expect(response).to have_http_status(:created)
listing_cost = ClassifiedListing.categories_available[:cfp][:cost]
expect(user.credits.spent.size).to eq(listing_cost)
expect(user.credits.spent.size).to eq(cfp_category.cost)
end
it "creates a listing draft under the org" do
@ -357,7 +357,8 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do
it "cannot create a draft due to internal error" do
allow(Organization).to receive(:find_by)
post_classified_listing(draft_params.except(:classified_listing_category_id))
expect(response.parsed_body["errors"]["category"]).to eq(["not a valid category"])
expect(response.parsed_body.dig("errors", "classified_listing_category").first).
to match(/must exist/)
expect(response).to have_http_status(:unprocessable_entity)
end
@ -608,7 +609,8 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do
max_id = ClassifiedListingCategory.maximum(:id)
put_classified_listing(listing.id, title: "New title", classified_listing_category_id: max_id + 1)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body.dig("errors", "category").first).to match(/not a valid category/)
expect(response.parsed_body.dig("errors", "classified_listing_category").first).
to match(/must exist/)
end
it "updates the title of his listing" do

View file

@ -62,7 +62,7 @@ RSpec.describe Search::ClassifiedListing, type: :service do
end
it "searches by slug" do
slug_classified_listing = FactoryBot.create(:classified_listing, title: "A slug is created from this title in a callback")
slug_classified_listing = create(:classified_listing, title: "A slug is created from this title in a callback")
index_documents(slug_classified_listing)
params = { size: 5, slug: "slug" }
@ -136,7 +136,7 @@ RSpec.describe Search::ClassifiedListing, type: :service do
it "sorts documents by bumped_at by default" do
classified_listing.update(bumped_at: 1.year.ago)
classified_listing2 = FactoryBot.create(:classified_listing, bumped_at: Time.current)
classified_listing2 = create(:classified_listing, bumped_at: Time.current)
index_documents([classified_listing, classified_listing2])
params = { size: 5 }
@ -148,7 +148,7 @@ RSpec.describe Search::ClassifiedListing, type: :service do
it "paginates the results" do
classified_listing.update(bumped_at: 1.year.ago)
classified_listing2 = FactoryBot.create(:classified_listing, bumped_at: Time.current)
classified_listing2 = create(:classified_listing, bumped_at: Time.current)
index_documents([classified_listing, classified_listing2])
first_page_params = { page: 0, per_page: 1, sort_by: "bumped_at", order: "dsc" }
@ -162,8 +162,12 @@ RSpec.describe Search::ClassifiedListing, type: :service do
end
it "returns an empty Array if no results are found" do
classified_listing.update(category: "forhire")
classified_listing2 = FactoryBot.create(:classified_listing, category: "cfp")
jobs_category = create(:classified_listing_category, :jobs)
classified_listing.update(classified_listing_category: jobs_category)
cfp_category = create(:classified_listing_category, :cfp)
classified_listing2 = create(:classified_listing,
classified_listing_category: cfp_category)
index_documents([classified_listing, classified_listing2])
params = { page: 3, per_page: 1 }