Commit 23cb2de3 by Rocky Duan

store anonymity as a separate attribute and make author required again

parent f5d3af22
......@@ -39,14 +39,14 @@ get '/api/v1/:commentable_id/threads' do |commentable_id|
end
post '/api/v1/:commentable_id/threads' do |commentable_id|
thread = CommentThread.new(params.slice(*%w[title body course_id]).merge(commentable_id: commentable_id))
thread = CommentThread.new(params.slice(*%w[title body course_id anonymous]).merge(commentable_id: commentable_id))
thread.tags = params["tags"] || ""
thread.author = user
thread.save
if thread.errors.any?
error 400, thread.errors.full_messages.to_json
else
user.subscribe(thread) if params["auto_subscribe"] and user
user.subscribe(thread) if params["auto_subscribe"]
thread.to_hash.to_json
end
end
......@@ -77,13 +77,13 @@ put '/api/v1/threads/:thread_id' do |thread_id|
end
post '/api/v1/threads/:thread_id/comments' do |thread_id|
comment = thread.comments.new(params.slice(*%w[body course_id]))
comment = thread.comments.new(params.slice(*%w[body course_id anonymous]))
comment.author = user
comment.save
if comment.errors.any?
error 400, comment.errors.full_messages.to_json
else
user.subscribe(thread) if params["auto_subscribe"] and user
user.subscribe(thread) if params["auto_subscribe"]
comment.to_hash.to_json
end
end
......
......@@ -10,15 +10,17 @@ class Comment < Content
field :body, type: String
field :course_id, type: String
field :endorsed, type: Boolean, default: false
field :anonymous, type: Boolean, default: false
belongs_to :author, class_name: "User", index: true
belongs_to :comment_thread, index: true
attr_accessible :body, :course_id, :endorsed
attr_accessible :body, :course_id, :endorsed, :anonymous
validates_presence_of :body
validates_presence_of :course_id # do we really need this?
validates_presence_of :comment_thread
validates_presence_of :author
before_destroy :delete_descendants # TODO async
after_create :generate_notifications
......@@ -39,9 +41,9 @@ class Comment < Content
if params[:recursive]
self.class.hash_tree(subtree(sort: sort_by_parent_and_time)).first
else
as_document.slice(*%w[body course_id endorsed created_at updated_at])
as_document.slice(*%w[body course_id endorsed anonymous created_at updated_at])
.merge("id" => _id)
.merge("user_id" => (author.id if author))
.merge("user_id" => author.id)
.merge("depth" => depth)
.merge("thread_id" => comment_thread.id)
.merge("votes" => votes.slice(*%w[count up_count down_count point]))
......@@ -50,7 +52,7 @@ class Comment < Content
private
def generate_notifications
if comment_thread.subscribers or (author.followers if author)
if comment_thread.subscribers or (author.followers if not anonymous)
notification = Notification.new(
notification_type: "post_reply",
info: {
......@@ -60,10 +62,10 @@ private
commentable_id: comment_thread.commentable_id,
},
)
notification.actor = author
notification.actor = author if not anonymous
notification.target = self
receivers = comment_thread.subscribers
if author
if not anonymous
receivers = (receivers + author.followers).uniq_by(&:id)
end
receivers.delete(author)
......
......@@ -11,6 +11,7 @@ class CommentThread < Content
field :body, type: String
field :course_id, type: String, index: true
field :commentable_id, type: String, index: true
field :anonymous, type: Boolean, default: false
include Sunspot::Mongoid
searchable do
......@@ -28,12 +29,13 @@ class CommentThread < Content
belongs_to :author, class_name: "User", inverse_of: :comment_threads, index: true, autosave: true
has_many :comments, dependent: :destroy, autosave: true# Use destroy to envoke callback on the top-level comments TODO async
attr_accessible :title, :body, :course_id, :commentable_id
attr_accessible :title, :body, :course_id, :commentable_id, :anonymous
validates_presence_of :title
validates_presence_of :body
validates_presence_of :course_id # do we really need this?
validates_presence_of :commentable_id
validates_presence_of :author
validate :tag_names_valid
validate :tag_names_unique
......@@ -69,9 +71,9 @@ class CommentThread < Content
end
def to_hash(params={})
doc = as_document.slice(*%w[title body course_id commentable_id created_at updated_at])
doc = as_document.slice(*%w[title body course_id anonymous commentable_id created_at updated_at])
.merge("id" => _id)
.merge("user_id" => (author.id if author))
.merge("user_id" => author.id)
.merge("votes" => votes.slice(*%w[count up_count down_count point]))
.merge("tags" => tags_array)
......@@ -96,7 +98,7 @@ class CommentThread < Content
private
def generate_notifications
if subscribers or (author.followers if author)
if subscribers or (author.followers if not anonymous)
notification = Notification.new(
notification_type: "post_topic",
info: {
......@@ -106,10 +108,10 @@ private
thread_title: title,
},
)
notification.actor = author
notification.actor = author if not anonymous
notification.target = self
receivers = commentable.subscribers
if author
if not anonymous
receivers = (receivers + author.followers).uniq_by(&:id)
end
receivers.delete(author)
......
......@@ -99,12 +99,13 @@ describe "app" do
end
it "allows anonymous comment" do
thread = CommentThread.first.to_hash(recursive: true)
post "/api/v1/threads/#{thread["id"]}/comments", default_params.merge(user_id: nil)
post "/api/v1/threads/#{thread["id"]}/comments", default_params.merge(anonymous: true)
last_response.should be_ok
changed_thread = CommentThread.find(thread["id"]).to_hash(recursive: true)
changed_thread["children"].length.should == thread["children"].length + 1
comment = changed_thread["children"].select{|c| c["body"] == "new comment"}.first
comment.should_not be_nil
comment["anonymous"].should be_true
end
it "returns 400 when the thread does not exist" do
post "/api/v1/threads/does_not_exist/comments", default_params
......
......@@ -58,12 +58,12 @@ describe "app" do
CommentThread.where(title: "Interesting question").first.should_not be_nil
end
it "allows anonymous thread" do
params = default_params.dup
params.delete(:user_id)
post '/api/v1/question_1/threads', params
post '/api/v1/question_1/threads', default_params.merge(anonymous: true)
last_response.should be_ok
CommentThread.count.should == 3
CommentThread.where(title: "Interesting question").first.should_not be_nil
c = CommentThread.where(title: "Interesting question").first
c.should_not be_nil
c["anonymous"].should be_true
end
it "create a new comment thread for a new commentable object" do
post '/api/v1/does_not_exist/threads', default_params
......
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