Commit 7ff63463 by Kevin Chugh

Merge pull request #45 from edx/feature/kevin/notifications_restful_take_2

restore notifications api post-merge-rollback
parents d2bf94ef 66d867d4
post "#{APIPREFIX}/notifications" do
# get all notifications for a set of users and a range of dates
# for example
# http://localhost:4567/api/v1/notifications?api_key=PUT_YOUR_API_KEY_HERE
# with POST params
# user_ids=1217716,196353
# from=2013-03-18+13%3A52%3A47+-0400
# to=2013-03-19+13%3A53%3A11+-0400
# note this takes date format 8601 year-month-day-(hours:minutes:seconds difference from UTC
notifications_by_date_range_and_user_ids(CGI.unescape(params[:from]).to_time, CGI.unescape(params[:to]).to_time,params[:user_ids].split(','))
end
......@@ -72,6 +72,7 @@ require './api/votes'
require './api/flags'
require './api/pins'
require './api/notifications_and_subscriptions'
require './api/notifications'
if RACK_ENV.to_s == "development"
get "#{APIPREFIX}/clean" do
......
......@@ -4,7 +4,6 @@ development:
database: cs_comments_service_development
hosts:
- localhost:27017
test:
sessions:
default:
......
......@@ -203,4 +203,74 @@ helpers do
end.compact
end
def notifications_by_date_range_and_user_ids start_date_time, end_date_time, user_ids
#given a date range and a user, find all of the notifiable content
#key by thread id, and return notification messages for each user
#first, find the subscriptions for the users
subscriptions = Subscription.where(:subscriber_id.in => user_ids)
#get the thhread ids
thread_ids = subscriptions.collect{|t| t.source_id}.uniq
#find all the comments
comments = Comment.by_date_range_and_thread_ids start_date_time, end_date_time, thread_ids
#and get the threads too, b/c we'll need them for the title
thread_map = Hash[CommentThread.where(:_id.in => thread_ids).all.map { |t| [t.id, t] }]
#now build a thread to users subscription map
subscriptions_map = {}
subscriptions.each do |s|
if not subscriptions_map.keys.include? s.source_id.to_s
subscriptions_map[s.source_id.to_s] = []
end
subscriptions_map[s.source_id] << s.subscriber_id
end
#notification map will be user => course => thread => [comment bodies]
notification_map = {}
comments.each do |c|
current_thread = thread_map[c.comment_thread_id]
#do not include threads or comments who have current or historical abuse flags
if current_thread.abuse_flaggers.to_a.empty? and
current_thread.historical_abuse_flaggers.to_a.empty? and
c.abuse_flaggers.to_a.empty? and
c.historical_abuse_flaggers.to_a.empty?
user_ids = subscriptions_map[c.comment_thread_id.to_s]
user_ids.each do |u|
if not notification_map.keys.include? u
notification_map[u] = {}
end
if not notification_map[u].keys.include? c.course_id
notification_map[u][c.course_id] = {}
end
if not notification_map[u][c.course_id].include? c.comment_thread_id.to_s
t = notification_map[u][c.course_id][c.comment_thread_id.to_s] = {}
t["content"] = []
t["title"] = current_thread.title
t["commentable_id"] = current_thread.commentable_id
else
t = notification_map[u][c.course_id][c.comment_thread_id.to_s]
end
content_obj = {}
content_obj["username"] = c.author_with_anonymity(:username, "(anonymous)")
content_obj["updated_at"] = c.updated_at
content_obj["body"] = c.body
t["content"] << content_obj
end
end
end
notification_map.to_json
end
end
......@@ -97,6 +97,14 @@ class Comment < Content
end
end
end
def self.by_date_range_and_thread_ids from_when, to_when, thread_ids
#return all content between from_when and to_when
self.where(:created_at.gte => (from_when)).where(:created_at.lte => (to_when)).
where(:comment_thread_id.in => thread_ids)
end
private
def set_thread_last_activity_at
......
require 'spec_helper'
describe "app" do
describe "notifications" do
before(:each) { init_without_subscriptions }
describe "POST /api/v1/notifications" do
it "returns notifications by class and user" do
start_time = Time.now
user = User.create(:email => "test@example.com",:external_id => 1,:username => "example")
commentable = Commentable.new("question_1")
random_string = (0...8).map{ ('a'..'z').to_a[rand(26)] }.join
thread = CommentThread.new(title: "Test title", body: "elephant otter", course_id: "1", commentable_id: commentable.id, comments_text_dummy: random_string)
thread.author = user
thread.save!
subscription = Subscription.create({:subscriber_id => user._id.to_s, :source_id => thread._id.to_s})
dummy = random_string = (0..5).map{ ('a'..'z').to_a[rand(26)] }.join
comment = Comment.new
comment.comment_thread_id = thread.id
comment.body = dummy
comment.author_id = user.id
comment.course_id = 'test course'
comment.save!
sleep 1
end_time = Time.now
post "/api/v1/notifications", from: CGI::escape(start_time.to_s), to: CGI::escape(end_time.to_s), user_ids: subscription.subscriber_id
last_response.should be_ok
last_response.body.to_s.include?(dummy).should == true
end
it "returns only threads subscribed to by user" do
# first make a dummy thread and comment and a subscription
commentable = Commentable.new("question_1")
user = User.create(:email => "test@example.com",:external_id => 1,:username => "example")
random_string = (0...8).map{ ('a'..'z').to_a[rand(26)] }.join
thread = CommentThread.new(title: "Test title", body: "elephant otter", course_id: "1", commentable_id: commentable.id, comments_text_dummy: random_string)
thread.author = user
thread.save!
subscription = Subscription.create({:subscriber_id => user._id.to_s, :source_id => thread._id.to_s})
comment = Comment.new(body: random_string, course_id: "1", commentable_id: commentable.id)
comment.author = user
comment.comment_thread = thread
comment.save!
start_time = Date.today - 100.days
sleep 1
end_time = Time.now + 5.seconds
post "/api/v1/notifications", from: CGI::escape(start_time.to_s), to: CGI::escape(end_time.to_s), user_ids: user.id
last_response.should be_ok
payload = JSON.parse last_response.body
courses = payload[user.id.to_s]
thread_ids = []
courses.each do |k,v|
v.each do |kk,vv|
thread_ids << kk
end
end
#now make sure the threads are a subset of the user's subscriptions
subscriptions = Subscription.where(:subscriber_id => user.id.to_s)
subscribed_thread_ids = subscriptions.collect{|s| s.source_id}
(subscribed_thread_ids.to_set.superset? thread_ids.to_set).should == true
end
it "returns only unflagged threads" do
start_time = Date.today - 100.days
user = User.create(:email => "test@example.com",:external_id => 1,:username => "example")
sleep 1
end_time = Time.now + 5.seconds
post "/api/v1/notifications", from: CGI::escape(start_time.to_s), to: CGI::escape(end_time.to_s), user_ids: user.id
last_response.should be_ok
payload = JSON.parse last_response.body
courses = payload[user.id.to_s]
thread_ids = []
courses.each do |k,v|
v.each do |kk,vv|
thread_ids << kk
end
end
#now flag the first thread
thread = CommentThread.find thread_ids.first
thread.historical_abuse_flaggers << ["1"]
sleep 1
end_time = Time.now + 5.seconds
post "/api/v1/notifications", from: CGI::escape(start_time.to_s), to: CGI::escape(end_time.to_s), user_ids: user.id
last_response.should be_ok
payload = JSON.parse last_response.body
courses = payload[user.id.to_s]
new_thread_ids = []
courses.each do |k,v|
v.each do |kk,vv|
new_thread_ids << kk
end
end
(new_thread_ids.include? thread.id).should == false
end
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment