diff --git a/app/controllers/api/v0/classified_listings_controller.rb b/app/controllers/api/v0/classified_listings_controller.rb index ecf105787..ddd101085 100644 --- a/app/controllers/api/v0/classified_listings_controller.rb +++ b/app/controllers/api/v0/classified_listings_controller.rb @@ -16,10 +16,13 @@ module Api def index @classified_listings = ClassifiedListing.published. select(ATTRIBUTES_FOR_SERIALIZATION). - includes(:user, :organization, :taggings) - - @classified_listings = @classified_listings.where(category: params[:category]) if params[:category].present? + includes(:user, :organization, :taggings, :classified_listing_category) + if params[:category].present? + category = ClassifiedListingCategory.find_by(slug: params[:category]) + @classified_listings = + @classified_listings.where(classified_listing_category: category) + end @classified_listings = @classified_listings.order(bumped_at: :desc) per_page = (params[:per_page] || 30).to_i @@ -51,8 +54,8 @@ module Api end ATTRIBUTES_FOR_SERIALIZATION = %i[ - id user_id organization_id title slug body_markdown - cached_tag_list category processed_html published + id user_id organization_id title slug body_markdown cached_tag_list + category classified_listing_category_id category processed_html published ].freeze private_constant :ATTRIBUTES_FOR_SERIALIZATION diff --git a/app/controllers/classified_listings_controller.rb b/app/controllers/classified_listings_controller.rb index 628360e8f..d7410670b 100644 --- a/app/controllers/classified_listings_controller.rb +++ b/app/controllers/classified_listings_controller.rb @@ -16,14 +16,15 @@ class ClassifiedListingsController < ApplicationController return redirect_to "/internal/listings/#{@displayed_classified_listing.id}/edit" end - @classified_listings = if params[:category].blank? - published_listings. - order("bumped_at DESC"). - includes(:user, :organization, :taggings). - limit(12) - else - ClassifiedListing.none - end + @classified_listings = + if params[:category].blank? + published_listings. + order("bumped_at DESC"). + includes(:user, :organization, :taggings, :classified_listing_category). + limit(12) + else + ClassifiedListing.none + end set_surrogate_key_header "classified-listings-#{params[:category]}" end diff --git a/app/controllers/concerns/classified_listings_toolkit.rb b/app/controllers/concerns/classified_listings_toolkit.rb index 8bff8b1dd..ed95c863a 100644 --- a/app/controllers/concerns/classified_listings_toolkit.rb +++ b/app/controllers/concerns/classified_listings_toolkit.rb @@ -13,11 +13,14 @@ module ClassifiedListingsToolkit @classified_listing.save 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] - @classified_listing.category = listing_params[:category] if listing_params[:category] + 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] @@ -45,7 +48,6 @@ module ClassifiedListingsToolkit authorize @classified_listing, :authorized_organization_poster? if @classified_listing.organization_id.present? @classified_listing.user_id = current_user.id - cost = ClassifiedListing.cost_by_category(@classified_listing.category) org = Organization.find_by(id: @classified_listing.organization_id) if listing_params[:action] == "draft" @@ -56,6 +58,14 @@ module ClassifiedListingsToolkit available_org_credits = org.credits.unspent if org 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 + end + + cost = @classified_listing.cost # we use the org's credits if available, otherwise we default to the user's if org && available_org_credits.size >= cost create_listing(org, cost) @@ -66,14 +76,18 @@ module ClassifiedListingsToolkit end end + ALLOWED_PARAMS = %i[ + title body_markdown category 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. 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" end - accessible = %i[title body_markdown category tag_list expires_at contact_via_connect location organization_id action] - params.require(:classified_listing).permit(accessible) + params.require(:classified_listing).permit(ALLOWED_PARAMS) end def create_draft @@ -124,7 +138,7 @@ module ClassifiedListingsToolkit def update authorize @classified_listing - cost = ClassifiedListing.cost_by_category(@classified_listing.category) + cost = @classified_listing.cost # NOTE: this should probably be split in three different actions: bump, unpublish, publish return bump_listing(cost) if listing_params[:action] == "bump" diff --git a/app/controllers/internal/classified_listings_controller.rb b/app/controllers/internal/classified_listings_controller.rb index 263819f7e..7c6ccad81 100644 --- a/app/controllers/internal/classified_listings_controller.rb +++ b/app/controllers/internal/classified_listings_controller.rb @@ -3,7 +3,10 @@ class Internal::ClassifiedListingsController < Internal::ApplicationController layout "internal" def index - @classified_listings = ClassifiedListing.includes(%i[user organization]).page(params[:page]).order("bumped_at DESC").per(50) + @classified_listings = + ClassifiedListing.includes(%i[user classified_listing_category]). + page(params[:page]).order("bumped_at DESC").per(50) + @classified_listings = @classified_listings.where(category: params[:filter]) if params[:filter].present? end @@ -14,25 +17,29 @@ class Internal::ClassifiedListingsController < Internal::ApplicationController def update @classified_listing = ClassifiedListing.find(params[:id]) handle_publish_status if listing_params[:published] - bump_listing if listing_params[:action] == "bump" + bump_listing(@classified_listing.cost) if listing_params[:action] == "bump" update_listing_details clear_listings_cache flash[:success] = "Listing updated successfully" - redirect_to "/internal/listings/#{@classified_listing.id}/edit" + redirect_to edit_internal_classified_listing_path(@classified_listing) end def destroy @classified_listing = ClassifiedListing.find(params[:id]) @classified_listing.destroy flash[:warning] = "'#{@classified_listing.title}' was destroyed successfully" - redirect_to "/internal/listings" + redirect_to internal_classified_listings_path end private + ALLOWED_PARAMS = %i[ + published body_markdown title category classified_listing_category_id tag_list action + ].freeze + private_constant :ALLOWED_PARAMS + def listing_params - allowed_params = %i[published body_markdown title category tag_list action] - params.require(:classified_listing).permit(allowed_params) + params.require(:classified_listing).permit(ALLOWED_PARAMS) end def handle_publish_status diff --git a/app/controllers/social_previews_controller.rb b/app/controllers/social_previews_controller.rb index 771fb10be..15751d8bb 100644 --- a/app/controllers/social_previews_controller.rb +++ b/app/controllers/social_previews_controller.rb @@ -51,6 +51,7 @@ class SocialPreviewsController < ApplicationController private + # TODO: [thepracticaldev/oss] don't hardcode this def define_categories cat_info = { "collabs": ["Collaborators Wanted", "#5AE8D9"], diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 64bdbdf14..73496ad97 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -4,6 +4,7 @@ class StoriesController < ApplicationController title path id user_id comments_count positive_reactions_count organization_id reading_time video_thumbnail_url video video_duration_in_minutes language experience_level_rating experience_level_rating_distribution cached_user cached_organization + classified_listing_category_id ], methods: %i[ readable_publish_date cached_tag_list_array flare_tag class_name @@ -331,7 +332,7 @@ class StoriesController < ApplicationController end def assign_classified_listings - @classified_listings = ClassifiedListing.where(published: true).select(:title, :category, :slug, :bumped_at) + @classified_listings = ClassifiedListing.where(published: true).select(:title, :category, :classified_listing_category_id, :slug, :bumped_at) end def set_user_json_ld diff --git a/app/javascript/listings/elements/categories.jsx b/app/javascript/listings/elements/categories.jsx index 05de8e7c6..4deefce37 100644 --- a/app/javascript/listings/elements/categories.jsx +++ b/app/javascript/listings/elements/categories.jsx @@ -19,7 +19,7 @@ class Categories extends Component { details = () => { const { categoriesForDetails } = this.props; - const rules = categoriesForDetails.map(category => { + const rules = categoriesForDetails.map((category) => { const paragraphText = `${category.name}: ${category.rules}`; return

{paragraphText}

; }); @@ -42,7 +42,7 @@ class Categories extends Component { <%= f.submit "Bump Listing ⏫", class: "btn btn-secondary" %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index 83a17916b..b515c2496 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -47,11 +47,12 @@ Rails.application.routes.draw do resources :articles, only: %i[index show update] resources :broadcasts, only: %i[index new create edit update] resources :buffer_updates, only: %i[create update] + # TODO: [mkohl] Change this to a single resource definition resources :classified_listings, only: %i[index edit update destroy] + resources :listings, only: %i[index edit update destroy], controller: "classified_listings" resources :comments, only: [:index] resources :events, only: %i[index create update] resources :feedback_messages, only: %i[index show] - resources :listings, only: %i[index edit update destroy], controller: "classified_listings" resources :pages, only: %i[index new create edit update destroy] resources :mods, only: %i[index update] resources :moderator_actions, only: %i[index] diff --git a/db/seeds.rb b/db/seeds.rb index 691f95e6c..31547c213 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -418,7 +418,54 @@ end ############################################################################## -puts <<-ASCII # rubocop:disable Rails/Output +counter += 1 +Rails.logger.info "#{counter}. Creating Classified Listing Categories" + +CATEGORIES = [ + { + slug: "cfp", + cost: 1, + name: "Conference CFP", + rules: "Currently open for proposals,with link to form." + }, + { + slug: "education", + cost: 1, + name: "Education/Courses", + rules: "Educational material and/or schools/bootcamps." + }, + { + slug: "jobs", + cost: 25, + name: "Job Listings", + rules: "Companies offering employment right now." + }, + { + slug: "forsale", + cost: 1, + name: "Stuff for Sale", + rules: "Personally owned physical items for sale." + }, + { + slug: "events", + cost: 1, + name: "Upcoming Events", + rules: "In-person or online events with date included." + }, + { + slug: "misc", + cost: 1, + name: "Miscellaneous", + rules: "Must not fit in any other category." + } +].freeze + +CATEGORIES.each { |attributes| ClassifiedListingCategory.create(attributes) } + +############################################################################## + +# rubocop:disable Rails/Output +puts <<-ASCII @@ -447,3 +494,4 @@ puts <<-ASCII # rubocop:disable Rails/Output All done! ASCII +# rubocop:enable Rails/Output diff --git a/spec/factories/classified_listing_categories.rb b/spec/factories/classified_listing_categories.rb index 1b3268414..f2a087659 100644 --- a/spec/factories/classified_listing_categories.rb +++ b/spec/factories/classified_listing_categories.rb @@ -7,6 +7,8 @@ FactoryBot.define do trait :cfp do name { "Conference CFP" } + slug { "cfp" } + cost { 5 } end end end diff --git a/spec/factories/classified_listings.rb b/spec/factories/classified_listings.rb index 0f3c1f10d..0df205968 100644 --- a/spec/factories/classified_listings.rb +++ b/spec/factories/classified_listings.rb @@ -3,8 +3,14 @@ FactoryBot.define do user title { Faker::Book.title + " #{rand(1000)}" } body_markdown { Faker::Hipster.paragraph(sentence_count: 2) } - category { "education" } published { true } bumped_at { Time.current } + + after(:build) do |cl| + if cl.classified_listing_category_id.blank? + category = ClassifiedListingCategory.first || create(:classified_listing_category) + cl.classified_listing_category_id = category.id + end + end end end diff --git a/spec/models/classified_listing_spec.rb b/spec/models/classified_listing_spec.rb index 1e6b1be8d..74556d638 100644 --- a/spec/models/classified_listing_spec.rb +++ b/spec/models/classified_listing_spec.rb @@ -32,18 +32,6 @@ RSpec.describe ClassifiedListing, type: :model do end end - # TODO: remove this once we are live with the new ClassifiedListingCategory model - describe "classified listing category" do - it "automatically assigns a category on save" do - create(:classified_listing_category) - - cl = build(:classified_listing, user_id: user.id) - cl.save - expect(cl).to be_valid - expect(cl.reload.classified_listing_category).to be_present - end - end - describe "body html" do it "converts markdown to html" do expect(classified_listing.processed_html).to include("

") @@ -100,15 +88,5 @@ RSpec.describe ClassifiedListing, type: :model do end end end - - describe ".cost_by_category" do - it "returns the cost per category" do - expected_cost = described_class::CATEGORIES_AVAILABLE.dig("cfp", "cost") - expect(described_class.cost_by_category("cfp")).to eq(expected_cost) - end - - it "returns 0 with invalid category" do - expect(described_class.cost_by_category("invalid")).to eq(0) - end - end end + diff --git a/spec/requests/api/v0/classified_listings_spec.rb b/spec/requests/api/v0/classified_listings_spec.rb index 71c252d28..e03ac2ce1 100644 --- a/spec/requests/api/v0/classified_listings_spec.rb +++ b/spec/requests/api/v0/classified_listings_spec.rb @@ -1,6 +1,13 @@ require "rails_helper" RSpec.describe "Api::V0::ClassifiedListings", type: :request do + let_it_be_readonly(:cfp_category) do + create(:classified_listing_category, :cfp) + end + let_it_be_readonly(:edu_category) do + create(:classified_listing_category) + end + shared_context "when user is authorized" do let(:api_secret) { create(:api_secret) } let(:user) { api_secret.user } @@ -12,14 +19,14 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do { title: "Title", body_markdown: "Markdown text", - category: "cfp" + classified_listing_category_id: cfp_category.id } end let(:draft_params) do { title: "Title draft", body_markdown: "Markdown draft text", - category: "cfp", + classified_listing_category_id: cfp_category.id, action: "draft" } end @@ -36,8 +43,8 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do let(:user2) { create(:user) } before do - create_list(:classified_listing, 3, user: user1, category: "cfp") - create_list(:classified_listing, 4, user: user2) + create_list(:classified_listing, 3, user: user1, classified_listing_category_id: cfp_category.id) + create_list(:classified_listing, 4, user: user2, classified_listing_category_id: edu_category.id) end end @@ -239,21 +246,31 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do describe "user must have enough credit to create a classified listing" do include_context "when user is authorized" + include_context "when param list is valid" it "fails to create a classified listing if user does not have enough credit" do - post_classified_listing(category: "cfp") + post_classified_listing(listing_params) expect(response).to have_http_status(:payment_required) end it "fails to create a classifiedlisting if the org does not have enough credit" do org = user_admin_organization(user) - post_classified_listing(category: "cfp", organization_id: org.id) + post_classified_listing( + **listing_params, + organization_id: org.id, + ) expect(response).to have_http_status(:payment_required) end end describe "user cannot create a classified with a request lacking mandatory parameters" do - let(:invalid_params) { { title: "Title", category: "cfp" } } + let(:invalid_params) do + { + title: "Title", + category: "cfp", + classified_listing_category_id: cfp_category.id + } + end include_context "when user is authorized" include_context "when user has enough credit" @@ -338,15 +355,9 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do end it "cannot create a draft due to internal error" do - listing = create(:classified_listing, user_id: user.id) - allow(ClassifiedListing).to receive_messages(cost_by_category: nil, new: listing) allow(Organization).to receive(:find_by) - allow(listing).to receive(:save) do - listing.errors.add(:base) - false - end - post_classified_listing(draft_params) - expect(response.parsed_body["errors"]["base"]).to eq(["is invalid"]) + post_classified_listing(draft_params.except(:classified_listing_category_id)) + expect(response.parsed_body["errors"]["category"]).to eq(["not a valid category"]) expect(response).to have_http_status(:unprocessable_entity) end @@ -384,7 +395,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do expect(listing.title).to eq(listing_params[:title]) expect(listing.body_markdown).to eq(listing_params[:body_markdown]) - expect(listing.category).to eq(listing_params[:category]) + expect(listing.category).to eq(cfp_category.slug) end it "creates a classified listing with a location" do @@ -491,7 +502,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do end it "bumps the listing and subtract credits" do - cost = ClassifiedListing.cost_by_category(listing.category) + cost = listing.cost create_list(:credit, cost, user: user) previous_bumped_at = listing.bumped_at expect do @@ -501,7 +512,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do end it "bumps the org listing using org credits before user credits" do - cost = ClassifiedListing.cost_by_category(org_listing.category) + cost = org_listing.cost create_list(:credit, cost, organization: organization) create_list(:credit, cost, user: user) previous_bumped_at = org_listing.bumped_at @@ -512,7 +523,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do end it "bumps the org listing using user credits if org credits insufficient and user credits are" do - cost = ClassifiedListing.cost_by_category(org_listing.category) + cost = org_listing.cost create_list(:credit, cost, user: user) previous_bumped_at = org_listing.bumped_at expect do @@ -526,7 +537,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do include_context "when user is authorized" it "publishes a draft and charges user credits if first publish" do - cost = ClassifiedListing.cost_by_category(listing_draft.category) + cost = listing_draft.cost create_list(:credit, cost, user: user) expect do put_classified_listing(listing_draft.id, action: "publish") @@ -534,14 +545,14 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do end it "publishes a draft and ensures published column is true" do - cost = ClassifiedListing.cost_by_category(listing_draft.category) + cost = listing_draft.cost create_list(:credit, cost, user: user) put_classified_listing(listing_draft.id, action: "publish") expect(listing_draft.reload.published).to eq(true) end it "publishes an org draft and charges org credits if first publish" do - cost = ClassifiedListing.cost_by_category(org_listing_draft.category) + cost = org_listing_draft.cost create_list(:credit, cost, organization: organization) expect do put_classified_listing(org_listing_draft.id, action: "publish") @@ -549,7 +560,7 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do end it "publishes an org draft and ensures published column is true" do - cost = ClassifiedListing.cost_by_category(org_listing_draft.category) + cost = org_listing_draft.cost create_list(:credit, cost, organization: organization) put_classified_listing(org_listing_draft.id, action: "publish") expect(org_listing_draft.reload.published).to eq(true) @@ -594,7 +605,8 @@ RSpec.describe "Api::V0::ClassifiedListings", type: :request do end it "fails if category is invalid" do - put_classified_listing(listing.id, title: "New title", category: "unknown") + 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/) end diff --git a/spec/requests/classified_listings_spec.rb b/spec/requests/classified_listings_spec.rb index a53db700d..aa381c991 100644 --- a/spec/requests/classified_listings_spec.rb +++ b/spec/requests/classified_listings_spec.rb @@ -1,13 +1,16 @@ require "rails_helper" RSpec.describe "ClassifiedListings", type: :request do + let_it_be_readonly(:edu_category) do + create(:classified_listing_category, cost: 1) + end let(:user) { create(:user) } let(:listing_params) do { classified_listing: { title: "something", body_markdown: "something else", - category: "cfp", + classified_listing_category_id: edu_category.id, tag_list: "", contact_via_connect: true } @@ -18,7 +21,7 @@ RSpec.describe "ClassifiedListings", type: :request do classified_listing: { title: "this a draft", body_markdown: "something draft", - category: "cfp", + classified_listing_category_id: edu_category.id, tag_list: "", contact_via_connect: true, action: "draft" @@ -144,13 +147,15 @@ RSpec.describe "ClassifiedListings", type: :request do create_list(:credit, 25, user: user) end + let_it_be_readonly(:cfp_category) { create(:classified_listing_category, :cfp) } + context "when the listing is invalid" do let(:invalid_params) do { classified_listing: { title: "nothing", body_markdown: "", - category: "cfp", + classified_listing_category_id: cfp_category.id, tag_list: "" } } @@ -195,9 +200,9 @@ RSpec.describe "ClassifiedListings", type: :request do end it "properly deducts the amount of credits" do - post "/listings", params: listing_params - listing_cost = ClassifiedListing.categories_available[:cfp][:cost] - expect(user.credits.spent.size).to eq(listing_cost) + expect do + post "/listings", params: listing_params + end.to change { user.credits.spent.size }.by(edu_category.cost) end it "creates a listing draft under the org" do @@ -305,7 +310,7 @@ RSpec.describe "ClassifiedListings", type: :request do end it "bumps the listing and subtract credits" do - cost = ClassifiedListing.cost_by_category(listing.category) + cost = listing.cost create_list(:credit, cost, user: user) previous_bumped_at = listing.bumped_at expect do @@ -315,7 +320,7 @@ RSpec.describe "ClassifiedListings", type: :request do end it "bumps the org listing using org credits before user credits" do - cost = ClassifiedListing.cost_by_category(org_listing.category) + cost = org_listing.cost create_list(:credit, cost, organization: organization) create_list(:credit, cost, user: user) previous_bumped_at = org_listing.bumped_at @@ -326,7 +331,7 @@ RSpec.describe "ClassifiedListings", type: :request do end it "bumps the org listing using user credits if org credits insufficient and user credits are" do - cost = ClassifiedListing.cost_by_category(org_listing.category) + cost = org_listing.cost create_list(:credit, cost, user: user) previous_bumped_at = org_listing.bumped_at expect do @@ -340,7 +345,7 @@ RSpec.describe "ClassifiedListings", type: :request do let(:params) { { classified_listing: { action: "publish" } } } it "publishes a draft and charges user credits if first publish" do - cost = ClassifiedListing.cost_by_category(listing_draft.category) + cost = listing_draft.cost create_list(:credit, cost, user: user) expect do put "/listings/#{listing_draft.id}", params: params @@ -348,14 +353,14 @@ RSpec.describe "ClassifiedListings", type: :request do end it "publishes a draft and ensures published column is true" do - cost = ClassifiedListing.cost_by_category(listing_draft.category) + cost = listing_draft.cost create_list(:credit, cost, user: user) put "/listings/#{listing_draft.id}", params: params expect(listing_draft.reload.published).to eq(true) end it "publishes an org draft and charges org credits if first publish" do - cost = ClassifiedListing.cost_by_category(org_listing_draft.category) + cost = org_listing_draft.cost create_list(:credit, cost, organization: organization) expect do put "/listings/#{org_listing_draft.id}", params: params @@ -363,7 +368,7 @@ RSpec.describe "ClassifiedListings", type: :request do end it "publishes an org draft and ensures published column is true" do - cost = ClassifiedListing.cost_by_category(org_listing_draft.category) + cost = org_listing_draft.cost create_list(:credit, cost, organization: organization) put "/listings/#{org_listing_draft.id}", params: params expect(org_listing_draft.reload.published).to eq(true) diff --git a/spec/requests/listings_spec.rb b/spec/requests/listings_spec.rb index cb9502b17..4efb9beeb 100644 --- a/spec/requests/listings_spec.rb +++ b/spec/requests/listings_spec.rb @@ -3,8 +3,20 @@ require "rails_helper" RSpec.describe "/listings", type: :request do let(:user) { create(:user) } let(:organization) { create(:organization) } + let(:cl_category) { create(:classified_listing_category, cost: 1) } - describe "GETS /listings" do + let(:params) do + { + classified_listing: { + title: "Hey", + classified_listing_category_id: cl_category.id, + body_markdown: "hey hey my my", + tag_list: "ruby, rails, go" + } + } + end + + describe "GET /listings" do it "has page content" do get "/listings" expect(response.body).to include("classified-filters") @@ -30,63 +42,51 @@ RSpec.describe "/listings", type: :request do end it "creates proper listing if credits are available" do - post "/listings", params: { - classified_listing: { title: "Hey", category: "education", body_markdown: "hey hey my my" } - } + post "/listings", params: params expect(ClassifiedListing.last.processed_html).to include("hey my") end it "spends credits" do num_credits = Credit.where(spent: true).size - post "/listings", params: { - classified_listing: { title: "Hey", category: "education", body_markdown: "hey hey my my" } - } + post "/listings", params: params expect(Credit.where(spent: true).size).to be > num_credits end it "adds tags" do - post "/listings", params: { - classified_listing: { title: "Hey", category: "education", body_markdown: "hey hey my my", tag_list: "ruby, rails, go" } - } + post "/listings", params: params expect(ClassifiedListing.last.cached_tag_list).to include("rails") end it "creates the listing under the user" do - post "/listings", params: { - classified_listing: { title: "Hey", category: "education", body_markdown: "hey hey my my", tag_list: "ruby, rails, go" } - } + post "/listings", params: params expect(ClassifiedListing.last.user_id).to eq user.id end it "creates the listing for the user if no organization_id is selected" do create(:organization_membership, user_id: user.id, organization_id: organization.id) - post "/listings", params: { - classified_listing: { title: "Hey", category: "education", body_markdown: "hey hey my my", tag_list: "ruby, rails, go" } - } + post "/listings", params: params expect(ClassifiedListing.last.organization_id).to eq nil expect(ClassifiedListing.last.user_id).to eq user.id end it "creates the listing for the organization" do create(:organization_membership, user_id: user.id, organization_id: organization.id) - post "/listings", params: { - classified_listing: { title: "Hey", category: "education", body_markdown: "hey hey my my", tag_list: "ruby, rails, go", organization_id: organization.id } - } + params[:classified_listing][:organization_id] = organization.id + post "/listings", params: params expect(ClassifiedListing.last.organization_id).to eq(organization.id) end it "does not create an org listing if a different org member doesn't belong to the org" do another_org = create(:organization) create(:organization_membership, user_id: user.id, organization_id: another_org.id) + params[:classified_listing][:organization_id] = organization.id expect do - post "/listings", params: { - classified_listing: { title: "Hey", category: "education", body_markdown: "hey hey my my", tag_list: "ruby, rails, go", organization_id: organization.id } - } + post "/listings", params: params end.to raise_error Pundit::NotAuthorizedError end end - describe "GETS /listings/edit" do + describe "GET /listings/edit" do let(:classified_listing) { create(:classified_listing, user_id: user.id) } before do diff --git a/spec/requests/social_previews_spec.rb b/spec/requests/social_previews_spec.rb index d0cf79226..df26b61b1 100644 --- a/spec/requests/social_previews_spec.rb +++ b/spec/requests/social_previews_spec.rb @@ -7,7 +7,6 @@ RSpec.describe "SocialPreviews", type: :request do let(:article) { create(:article, user_id: user.id, tags: tag.name) } let(:comment) { create(:comment, user_id: user.id, commentable: article) } let(:image_url) { "https://hcti.io/v1/image/6c52de9d-4d37-4008-80f8-67155589e1a1" } - let(:listing) { create(:classified_listing, user_id: user.id, category: "cfp") } before do stub_request(:post, /hcti.io/). @@ -136,9 +135,11 @@ RSpec.describe "SocialPreviews", type: :request do end describe "GET /social_previews/listing/:id" do + let(:listing) { create(:classified_listing, user_id: user.id) } + it "renders pretty category name" do get "/social_previews/listing/#{listing.id}" - expect(response.body).to include CGI.escapeHTML("Call For Proposal") + expect(response.body).to include CGI.escapeHTML("Education") end it "renders consistent HTML between requests" do diff --git a/spec/services/search/classified_listing_spec.rb b/spec/services/search/classified_listing_spec.rb index fe41c2440..50904d4b3 100644 --- a/spec/services/search/classified_listing_spec.rb +++ b/spec/services/search/classified_listing_spec.rb @@ -31,9 +31,10 @@ RSpec.describe Search::ClassifiedListing, type: :service, elasticsearch: true do context "with a term filter" do it "searches by category" do - classified_listing.update(category: "forhire") + new_category = create(:classified_listing_category, :cfp) + classified_listing.update(classified_listing_category_id: new_category.id) index_documents(classified_listing) - params = { size: 5, category: "forhire" } + params = { size: 5, category: new_category.slug } classified_listing_docs = described_class.search_documents(params: params) expect(classified_listing_docs.count).to eq(1) @@ -121,8 +122,9 @@ RSpec.describe Search::ClassifiedListing, type: :service, elasticsearch: true do end it "sorts documents for a given field" do - classified_listing.update(category: "forhire") - classified_listing2 = FactoryBot.create(:classified_listing, category: "cfp") + classified_listing = create(:classified_listing) + cfp = create(:classified_listing_category, :cfp) + classified_listing2 = create(:classified_listing, classified_listing_category_id: cfp.id) index_documents([classified_listing, classified_listing2]) params = { size: 5, sort_by: "category", sort_direction: "asc" }