Merge pull request #4744 from tgxworld/feature_seen_unseen_search

FEATURE: Search can be scoped to posts that the current user has seen…
This commit is contained in:
Guo Xiang Tan 2017-03-09 07:11:19 +08:00 committed by GitHub
commit 9cc79363e0
2 changed files with 68 additions and 4 deletions

View File

@ -315,6 +315,29 @@ class Search
end
end
advanced_filter(/in:seen/) do |posts|
if @guardian.user
posts
.joins("INNER JOIN post_timings ON
post_timings.topic_id = posts.topic_id
AND post_timings.post_number = posts.post_number
AND post_timings.user_id = #{Post.sanitize(@guardian.user.id)}
")
end
end
advanced_filter(/in:unseen/) do |posts|
if @guardian.user
posts
.joins("LEFT JOIN post_timings ON
post_timings.topic_id = posts.topic_id
AND post_timings.post_number = posts.post_number
AND post_timings.user_id = #{Post.sanitize(@guardian.user.id)}
")
.where("post_timings.user_id IS NULL")
end
end
advanced_filter(/category:(.+)/) do |posts,match|
exact = false
@ -729,10 +752,10 @@ class Search
if @order == :likes
# likes are a pain to aggregate so skip
posts_query(@limit, private_messages: opts[:private_messages])
.select('topics.id', "post_number")
.select('topics.id', "posts.post_number")
else
posts_query(@limit, aggregate_search: true, private_messages: opts[:private_messages])
.select('topics.id', "#{min_or_max}(post_number) post_number")
.select('topics.id', "#{min_or_max}(posts.post_number) post_number")
.group('topics.id')
end
@ -761,6 +784,7 @@ class Search
post_sql = aggregate_post_sql(opts)
added = 0
aggregate_posts(post_sql[:default]).each do |p|
@results.add(p)
added += 1

View File

@ -462,9 +462,49 @@ describe Search do
it 'supports wiki' do
topic = Fabricate(:topic)
Fabricate(:post, raw: 'this is a test 248', wiki: true, topic: topic)
topic_2 = Fabricate(:topic)
post = Fabricate(:post, raw: 'this is a test 248', wiki: true, topic: topic)
Fabricate(:post, raw: 'this is a test 248', wiki: false, topic: topic_2)
expect(Search.execute('test 248 in:wiki').posts.length).to eq(1)
expect(Search.execute('test 248').posts.length).to eq(2)
expect(Search.execute('test 248 in:wiki').posts.first).to eq(post)
end
it 'supports searching for posts that the user has seen/unseen' do
topic = Fabricate(:topic)
topic_2 = Fabricate(:topic)
post = Fabricate(:post, raw: 'logan is longan', topic: topic)
post_2 = Fabricate(:post, raw: 'longan is logan', topic: topic_2)
[post.user, topic.user].each do |user|
PostTiming.create!(
post_number: post.post_number,
topic: topic,
user: user,
msecs: 1
)
end
expect(post.seen?(post.user)).to eq(true)
expect(Search.execute('longan').posts.sort).to eq([post, post_2])
expect(Search.execute('longan in:seen', guardian: Guardian.new(post.user)).posts)
.to eq([post])
expect(Search.execute('longan in:seen').posts.sort).to eq([post, post_2])
expect(Search.execute('longan in:seen', guardian: Guardian.new(post_2.user)).posts)
.to eq([])
expect(Search.execute('longan', guardian: Guardian.new(post_2.user)).posts.sort)
.to eq([post, post_2])
expect(Search.execute('longan in:unseen', guardian: Guardian.new(post_2.user)).posts.sort)
.to eq([post, post_2])
expect(Search.execute('longan in:unseen', guardian: Guardian.new(post.user)).posts)
.to eq([post_2])
end
it 'supports before and after, in:first, user:, @username' do