510 lines
18 KiB
Ruby
510 lines
18 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "spec_helper"
|
|
|
|
describe BookmarkSearchForm, bookmark_search: true do
|
|
describe "options" do
|
|
it "includes flags set to false" do
|
|
bsf = BookmarkSearchForm.new(show_restricted: false, show_private: false)
|
|
expect(bsf.options).to include(show_restricted: false)
|
|
expect(bsf.options).to include(show_private: false)
|
|
end
|
|
end
|
|
|
|
describe "bookmarkable_search_results" do
|
|
describe "sorting" do
|
|
context "when everything is created at a different time" do
|
|
let(:tag) { create(:canonical_fandom) }
|
|
|
|
let!(:work1) do
|
|
travel_to(40.minutes.ago) do
|
|
create(:work, title: "One", fandom_string: tag.name)
|
|
end
|
|
end
|
|
|
|
let!(:work2) do
|
|
travel_to(60.minutes.ago) do
|
|
create(:work, title: "Two", fandom_string: tag.name)
|
|
end
|
|
end
|
|
|
|
let!(:work3) do
|
|
travel_to(50.minutes.ago) do
|
|
create(:work, title: "Three", fandom_string: tag.name)
|
|
end
|
|
end
|
|
|
|
let!(:bookmark1) do
|
|
travel_to(30.minutes.ago) do
|
|
create(:bookmark, bookmarkable: work1)
|
|
end
|
|
end
|
|
|
|
let!(:bookmark2) do
|
|
travel_to(10.minutes.ago) do
|
|
create(:bookmark, bookmarkable: work2)
|
|
end
|
|
end
|
|
|
|
let!(:bookmark3) do
|
|
travel_to(20.minutes.ago) do
|
|
create(:bookmark, bookmarkable: work3)
|
|
end
|
|
end
|
|
|
|
before { run_all_indexing_jobs }
|
|
|
|
context "by Date Updated" do
|
|
it "returns bookmarkables in the correct order" do
|
|
results = BookmarkSearchForm.new(
|
|
parent: tag, sort_column: "bookmarkable_date"
|
|
).bookmarkable_search_results
|
|
expect(results.map(&:title)).to eq %w[One Three Two]
|
|
end
|
|
|
|
it "changes when the work is updated" do
|
|
work2.update_attribute(:revised_at, Time.current)
|
|
run_all_indexing_jobs
|
|
results = BookmarkSearchForm.new(
|
|
parent: tag, sort_column: "bookmarkable_date"
|
|
).bookmarkable_search_results
|
|
expect(results.map(&:title)).to eq %w[Two One Three]
|
|
end
|
|
end
|
|
|
|
context "by Date Bookmarked" do
|
|
it "returns bookmarkables in the correct order" do
|
|
results = BookmarkSearchForm.new(
|
|
parent: tag, sort_column: "created_at"
|
|
).bookmarkable_search_results
|
|
expect(results.map(&:title)).to eq %w[Two Three One]
|
|
end
|
|
|
|
it "changes when a new bookmark is created" do
|
|
create(:bookmark, bookmarkable: work1)
|
|
run_all_indexing_jobs
|
|
results = BookmarkSearchForm.new(
|
|
parent: tag, sort_column: "created_at"
|
|
).bookmarkable_search_results
|
|
expect(results.map(&:title)).to eq %w[One Two Three]
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when everything is created and updated at the same time" do
|
|
before { freeze_time }
|
|
|
|
let(:tag) { create(:canonical_fandom) }
|
|
let!(:work1) { create(:work, fandom_string: tag.name) }
|
|
let!(:work2) { create(:work, fandom_string: tag.name) }
|
|
let!(:bookmark1) { create(:bookmark, bookmarkable: work1) }
|
|
let!(:bookmark2) { create(:bookmark, bookmarkable: work2) }
|
|
|
|
context "doesn't change tied bookmarkables order on work update" do
|
|
it "when sorted by Date Updated" do
|
|
search = BookmarkSearchForm.new(
|
|
parent: tag, sort_column: "bookmarkable_date"
|
|
)
|
|
run_all_indexing_jobs
|
|
res = search.bookmarkable_search_results.map(&:id)
|
|
|
|
[work1, work2].each do |work|
|
|
work.update!(summary: "Updated")
|
|
run_all_indexing_jobs
|
|
expect(search.bookmarkable_search_results.map(&:id)).to eq(res)
|
|
end
|
|
end
|
|
|
|
it "when sorted by Date Bookmarked" do
|
|
run_all_indexing_jobs
|
|
search = BookmarkSearchForm.new(
|
|
parent: tag, sort_column: "created_at"
|
|
)
|
|
run_all_indexing_jobs
|
|
res = search.bookmarkable_search_results.map(&:id)
|
|
|
|
[work1, work2].each do |work|
|
|
work.update!(summary: "Updated")
|
|
run_all_indexing_jobs
|
|
expect(search.bookmarkable_search_results.map(&:id)).to eq(res)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "searching" do
|
|
context "by work language" do
|
|
let(:language) { create(:language, short: "ptBR") }
|
|
|
|
let(:work1) { create(:work) }
|
|
let(:work2) { create(:work, language_id: language.id) }
|
|
|
|
let!(:bookmark1) { create(:bookmark, bookmarkable: work1) }
|
|
let!(:bookmark2) { create(:bookmark, bookmarkable: work2) }
|
|
|
|
let(:unused_language) { create(:language, name: "unused", short: "tlh") }
|
|
|
|
before { run_all_indexing_jobs }
|
|
|
|
it "returns work bookmarkables with specified language" do
|
|
# "Work language" dropdown, with short names
|
|
results = BookmarkSearchForm.new(language_id: "ptBR").bookmarkable_search_results
|
|
expect(results).not_to include work1
|
|
expect(results).to include work2
|
|
|
|
# "Work language" dropdown, with IDs (backward compatibility)
|
|
bsf = BookmarkSearchForm.new(language_id: language.id)
|
|
expect(bsf.language_id).to eq("ptBR")
|
|
results = bsf.bookmarkable_search_results
|
|
expect(results).not_to include work1
|
|
expect(results).to include work2
|
|
|
|
# "Any field on work" or "Search within results", with short names
|
|
results = BookmarkSearchForm.new(bookmarkable_query: "language_id: ptBR").bookmarkable_search_results
|
|
expect(results).not_to include work1
|
|
expect(results).to include work2
|
|
|
|
# "Any field on work" or "Search within results", with IDs (backward compatibility)
|
|
bsf = BookmarkSearchForm.new(bookmarkable_query: "language_id: #{language.id} OR language_id: #{unused_language.id}")
|
|
expect(bsf.bookmarkable_query).to eq("language_id: ptBR OR language_id: tlh")
|
|
results = bsf.bookmarkable_search_results
|
|
expect(results).not_to include work1
|
|
expect(results).to include work2
|
|
end
|
|
end
|
|
|
|
context "using pseud_ids in the bookmarkable query" do
|
|
let(:pseud) { create(:pseud) }
|
|
let(:collection) { create(:collection) }
|
|
|
|
let(:work) { create(:work, authors: [pseud], collections: [collection]) }
|
|
let(:series) { create(:series, authors: [pseud], works: [work]) }
|
|
|
|
let!(:bookmark1) { create(:bookmark, bookmarkable: work) }
|
|
let!(:bookmark2) { create(:bookmark, bookmarkable: series) }
|
|
|
|
before { run_all_indexing_jobs }
|
|
|
|
context "when a work & series are anonymous" do
|
|
let(:collection) { create(:anonymous_collection) }
|
|
|
|
it "doesn't include the work or the series" do
|
|
results = BookmarkSearchForm.new(bookmarkable_query: "pseud_ids: #{pseud.id}").bookmarkable_search_results
|
|
expect(results).not_to include work
|
|
expect(results).not_to include series
|
|
end
|
|
end
|
|
|
|
context "when a work & series are unrevealed" do
|
|
let(:collection) { create(:unrevealed_collection) }
|
|
|
|
it "doesn't include the work or the series" do
|
|
results = BookmarkSearchForm.new(bookmarkable_query: "pseud_ids: #{pseud.id}").bookmarkable_search_results
|
|
expect(results).not_to include work
|
|
expect(results).not_to include series
|
|
end
|
|
end
|
|
|
|
context "when a work & series are neither unrevealed nor anonymous" do
|
|
it "includes the work and the series" do
|
|
results = BookmarkSearchForm.new(bookmarkable_query: "pseud_ids: #{pseud.id}").bookmarkable_search_results
|
|
expect(results).to include work
|
|
expect(results).to include series
|
|
end
|
|
end
|
|
end
|
|
|
|
context "using user_ids in the bookmarkable query" do
|
|
let(:user) { create(:user) }
|
|
let(:collection) { create(:collection) }
|
|
|
|
let(:work) { create(:work, authors: [user.default_pseud], collections: [collection]) }
|
|
let(:series) { create(:series, authors: [user.default_pseud], works: [work]) }
|
|
|
|
let!(:bookmark1) { create(:bookmark, bookmarkable: work) }
|
|
let!(:bookmark2) { create(:bookmark, bookmarkable: series) }
|
|
|
|
before { run_all_indexing_jobs }
|
|
|
|
context "when a work & series are anonymous" do
|
|
let(:collection) { create(:anonymous_collection) }
|
|
|
|
it "doesn't include the work or the series" do
|
|
results = BookmarkSearchForm.new(bookmarkable_query: "user_ids: #{user.id}").bookmarkable_search_results
|
|
expect(results).not_to include work
|
|
expect(results).not_to include series
|
|
end
|
|
end
|
|
|
|
context "when a work & series are unrevealed" do
|
|
let(:collection) { create(:unrevealed_collection) }
|
|
|
|
it "doesn't include the work or the series" do
|
|
results = BookmarkSearchForm.new(bookmarkable_query: "user_ids: #{user.id}").bookmarkable_search_results
|
|
expect(results).not_to include work
|
|
expect(results).not_to include series
|
|
end
|
|
end
|
|
|
|
context "when a work & series are neither unrevealed nor anonymous" do
|
|
it "includes the work and the series" do
|
|
results = BookmarkSearchForm.new(bookmarkable_query: "user_ids: #{user.id}").bookmarkable_search_results
|
|
expect(results).to include work
|
|
expect(results).to include series
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "search_results" do
|
|
describe "sorting" do
|
|
before { freeze_time }
|
|
|
|
let!(:work1) { create(:work) }
|
|
let!(:work2) { create(:work) }
|
|
let(:bookmarker) { create(:user) }
|
|
let!(:bookmark1) { create(:bookmark, bookmarkable: work1, pseud: bookmarker.default_pseud) }
|
|
let!(:bookmark2) { create(:bookmark, bookmarkable: work2, pseud: bookmarker.default_pseud) }
|
|
|
|
context "doesn't change tied bookmark order on work/bookmark update" do
|
|
%w[created_at bookmarkable_date].each do |sort_column|
|
|
it "when sorted by #{sort_column}" do
|
|
search = BookmarkSearchForm.new(
|
|
bookmarker: bookmarker.default_pseud.name, sort_column: sort_column
|
|
)
|
|
run_all_indexing_jobs
|
|
res = search.search_results.map(&:id)
|
|
|
|
[work1, work2].each do |work|
|
|
work.update!(summary: "Updated")
|
|
run_all_indexing_jobs
|
|
expect(search.search_results.map(&:id)).to eq(res)
|
|
end
|
|
|
|
[bookmark1, bookmark2].each do |bookmark|
|
|
bookmark.update!(bookmarker_notes: "Updated")
|
|
run_all_indexing_jobs
|
|
expect(search.search_results.map(&:id)).to eq(res)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "when searching by bookmarker" do
|
|
let(:bookmarker) { create(:user, login: "yabalchoath") }
|
|
|
|
{
|
|
Work: :work,
|
|
Series: :series_with_a_work,
|
|
ExternalWork: :external_work
|
|
}.each_pair do |type, factory|
|
|
it "returns the correct bookmarked #{type.to_s.pluralize} when bookmarker changes username" do
|
|
bookmarkable = create(factory)
|
|
bookmark = create(:bookmark,
|
|
bookmarkable_id: bookmarkable.id,
|
|
bookmarkable_type: type,
|
|
pseud: bookmarker.default_pseud)
|
|
run_all_indexing_jobs
|
|
|
|
result = BookmarkSearchForm.new(bookmarker: "yabalchoath").search_results.first
|
|
expect(result).to eq bookmark
|
|
|
|
bookmarker.login = "cioelle"
|
|
bookmarker.save!
|
|
run_all_indexing_jobs
|
|
|
|
result = BookmarkSearchForm.new(bookmarker: "yabalchoath").search_results.first
|
|
expect(result).to be_nil
|
|
result = BookmarkSearchForm.new(bookmarker: "cioelle").search_results.first
|
|
expect(result).to eq bookmark
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "when searching any bookmarkable field for author of bookmarkable" do
|
|
let(:author) { create(:user, login: "yabalchoath") }
|
|
|
|
{
|
|
Work: :work,
|
|
Series: :series_with_a_work
|
|
}.each_pair do |type, factory|
|
|
it "returns the correct bookmarked #{type.to_s.pluralize} when author changes username" do
|
|
bookmarkable = create(factory, authors: [author.default_pseud])
|
|
bookmark = create(:bookmark, bookmarkable_id: bookmarkable.id, bookmarkable_type: type)
|
|
run_all_indexing_jobs
|
|
|
|
result = BookmarkSearchForm.new(bookmarkable_query: "yabalchoath").search_results.first
|
|
expect(result).to eq bookmark
|
|
|
|
author.login = "cioelle"
|
|
author.save!
|
|
run_all_indexing_jobs
|
|
|
|
result = BookmarkSearchForm.new(bookmarkable_query: "yabalchoath").search_results.first
|
|
expect(result).to be_nil
|
|
result = BookmarkSearchForm.new(bookmarkable_query: "cioelle").search_results.first
|
|
expect(result).to eq bookmark
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#processed_options" do
|
|
it "removes blank options" do
|
|
options = { foo: nil, bar: false }
|
|
searcher = BookmarkSearchForm.new(options)
|
|
expect(searcher.options).to have_key(:bar)
|
|
expect(searcher.options).not_to have_key(:foo)
|
|
end
|
|
|
|
it "renames the notes field" do
|
|
options = { bookmark_notes: "Mordor" }
|
|
searcher = BookmarkSearchForm.new(options)
|
|
expect(searcher.options[:notes]).to eq("Mordor")
|
|
end
|
|
|
|
it "unescapes angle brackets for date fields" do
|
|
options = {
|
|
date: "<1 week ago",
|
|
bookmarkable_date: ">1 year ago",
|
|
title: "escaped >.< field"
|
|
}
|
|
searcher = BookmarkSearchForm.new(options)
|
|
expect(searcher.options[:date]).to eq("<1 week ago")
|
|
expect(searcher.options[:bookmarkable_date]).to eq(">1 year ago")
|
|
expect(searcher.options[:title]).to eq("escaped >.< field")
|
|
end
|
|
|
|
it "renames old warning_ids fields" do
|
|
options = { warning_ids: [13] }
|
|
searcher = BookmarkSearchForm.new(options)
|
|
expect(searcher.options[:archive_warning_ids]).to eq([13])
|
|
end
|
|
end
|
|
|
|
describe "facets" do
|
|
let(:author) { create(:user).default_pseud }
|
|
let(:bookmarker) { create(:user).default_pseud }
|
|
|
|
let(:fandom1) { create(:canonical_fandom) }
|
|
let(:fandom2) { create(:canonical_fandom) }
|
|
let(:fandom3) { create(:fandom, merger: fandom1) }
|
|
|
|
let(:character1) { create(:canonical_character) }
|
|
let(:character2) { create(:canonical_character) }
|
|
let(:character3) { create(:canonical_character) }
|
|
|
|
let(:freeform1) { create(:canonical_freeform) }
|
|
let(:freeform2) { create(:freeform, merger: freeform1) }
|
|
|
|
let(:work1) do
|
|
create(:work,
|
|
fandom_string: fandom1.name,
|
|
character_string: [character1.name, character2.name].join(","),
|
|
authors: [author])
|
|
end
|
|
|
|
let(:work2) do
|
|
create(:work,
|
|
fandom_string: fandom2.name,
|
|
character_string: [character1.name, character2.name].join(","),
|
|
authors: [author])
|
|
end
|
|
|
|
let(:work3) do
|
|
create(:work,
|
|
fandom_string: fandom3.name,
|
|
character_string: [character1.name, character3.name].join(","),
|
|
authors: [author])
|
|
end
|
|
|
|
let!(:bookmark1) { create(:bookmark, pseud: bookmarker, bookmarkable: work1, tag_string: freeform1.name) }
|
|
let!(:bookmark2) { create(:bookmark, pseud: bookmarker, bookmarkable: work2, tag_string: freeform1.name) }
|
|
let!(:bookmark3) { create(:bookmark, pseud: bookmarker, bookmarkable: work3, tag_string: freeform2.name) }
|
|
|
|
before { run_all_indexing_jobs }
|
|
|
|
let(:form) { BookmarkSearchForm.new(faceted: true) }
|
|
let(:facets) { results.facets }
|
|
|
|
def facet_hash(facets)
|
|
facets.to_h { |facet| [facet.name, facet.count] }
|
|
end
|
|
|
|
shared_examples "it calculates the correct counts" do
|
|
it "lists the canonical fandoms with their counts" do
|
|
expect(facet_hash(facets["fandom"])).to eq(
|
|
{
|
|
fandom1.name => 2,
|
|
fandom2.name => 1
|
|
}
|
|
)
|
|
end
|
|
|
|
it "lists the canonical characters with their counts" do
|
|
expect(facet_hash(facets["character"])).to eq(
|
|
{
|
|
character1.name => 3,
|
|
character2.name => 2,
|
|
character3.name => 1
|
|
}
|
|
)
|
|
end
|
|
|
|
it "lists all bookmark tags with their counts" do
|
|
expect(facet_hash(facets["tag"])).to eq(
|
|
{
|
|
freeform1.name => 2,
|
|
freeform2.name => 1
|
|
}
|
|
)
|
|
end
|
|
|
|
context "when excluding tags" do
|
|
let(:form) { BookmarkSearchForm.new(faceted: true, excluded_tag_ids: [fandom2.id]) }
|
|
|
|
it "lists the canonical fandoms with their counts" do
|
|
expect(facet_hash(facets["fandom"])).to eq(
|
|
{
|
|
fandom1.name => 2
|
|
}
|
|
)
|
|
end
|
|
|
|
it "lists the canonical characters with their counts" do
|
|
expect(facet_hash(facets["character"])).to eq(
|
|
{
|
|
character1.name => 2,
|
|
character2.name => 1,
|
|
character3.name => 1
|
|
}
|
|
)
|
|
end
|
|
|
|
it "lists all bookmark tags with their counts" do
|
|
expect(facet_hash(facets["tag"])).to eq(
|
|
{
|
|
freeform1.name => 1,
|
|
freeform2.name => 1
|
|
}
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "for search_results" do
|
|
let(:results) { form.search_results }
|
|
|
|
it_behaves_like "it calculates the correct counts"
|
|
end
|
|
|
|
context "for bookmarkable_search_results" do
|
|
let(:results) { form.bookmarkable_search_results }
|
|
|
|
it_behaves_like "it calculates the correct counts"
|
|
end
|
|
end
|
|
end
|