diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2011-06-22 22:47:44 -0400 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2011-06-22 22:47:44 -0400 |
commit | e29674c17e846b227d44d62b64f3f2c47c81c488 (patch) | |
tree | 79b3fea20c52a103f25621afc6b848b8c8e942fb | |
parent | f0bb55bec42b03b2a8720e04bf72c6b1ef99984c (diff) | |
download | askbot-e29674c17e846b227d44d62b64f3f2c47c81c488.tar.gz askbot-e29674c17e846b227d44d62b64f3f2c47c81c488.tar.bz2 askbot-e29674c17e846b227d44d62b64f3f2c47c81c488.zip |
voting for comments works
-rw-r--r-- | askbot/models/__init__.py | 7 | ||||
-rw-r--r-- | askbot/skins/default/media/js/post.js | 93 | ||||
-rwxr-xr-x | askbot/skins/default/media/style/style.css | 25 | ||||
-rw-r--r-- | askbot/skins/default/templates/macros.html | 8 | ||||
-rw-r--r-- | askbot/tests/db_api_tests.py | 42 | ||||
-rw-r--r-- | askbot/views/commands.py | 9 | ||||
-rw-r--r-- | askbot/views/writers.py | 7 |
7 files changed, 100 insertions, 91 deletions
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 4cf713b2..66992dad 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -336,7 +336,12 @@ def user_assert_can_vote_for_post( :param:post can be instance of question or answer """ - if self == post.author: + #todo: after unifying models this if else will go away + if isinstance(post, Comment): + post_author = post.user + else: + post_author = post.author + if self == post_author: raise django_exceptions.PermissionDenied(_('cannot vote for own posts')) blocked_error_message = _( diff --git a/askbot/skins/default/media/js/post.js b/askbot/skins/default/media/js/post.js index e836ac32..5fbf0ad8 100644 --- a/askbot/skins/default/media/js/post.js +++ b/askbot/skins/default/media/js/post.js @@ -142,22 +142,17 @@ var CPValidator = function(){ }(); /** - * @enum {number} - */ -var VoteType = { - UP: 0, - DOWN: 1, -}; - -/** * @constructor * @extends {SimpleControl} - * @param {VoteType} vote_type - * @param {string} vote_url + * @param {Comment} comment to upvote */ -var CommentVoteButton = function(vote_type, vote_url){ +var CommentVoteButton = function(comment){ SimpleControl.call(this); /** + * @param {Comment} + */ + this._comment = comment; + /** * @type {boolean} */ this._voted = false; @@ -165,33 +160,9 @@ var CommentVoteButton = function(vote_type, vote_url){ * @type {number} */ this._score = 0; - /** - * @type {VoteType} - */ - this._vote_type = vote_type; - /** - * @type {string} - */ - this._vote_url = vote_url; - /** - * @type {?number} - */ - this._post_id; }; inherits(CommentVoteButton, SimpleControl); /** - * @param {number} - */ -CommentVoteButton.prototype.setCommentId = function(post_id){ - this._post_id = post_id; -}; -/** - * a hack. this method is to be called before CommentVoteButton.getElement() - */ -CommentVoteButton.prototype.setCommentElement = function(celem){ - this._comment_element = celem; -}; -/** * @param {number} score */ CommentVoteButton.prototype.setScore = function(score){ @@ -205,14 +176,17 @@ CommentVoteButton.prototype.setScore = function(score){ */ CommentVoteButton.prototype.setVoted = function(voted){ this._voted = voted; + if (this._element){ + this._element.addClass('upvoted'); + } }; CommentVoteButton.prototype.getVoteHandler = function(){ var me = this; + var comment = this._comment; return function(){ var voted = me._voted; - var post_id = me._post_id; - var url = me._vote_url; + var post_id = me._comment.getId(); var data = { cancel_vote: voted ? true:false, post_id: post_id @@ -221,14 +195,14 @@ CommentVoteButton.prototype.getVoteHandler = function(){ type: 'POST', data: data, dataType: 'json', - url: url, + url: askbot['urls']['upvote_comment'], cache: false, success: function(data){ me.setScore(data['score']); me.setVoted(true); }, error: function(xhr, textStatus, exception) { - showMessage(me.getElement(), xhr.responseText, 'after'); + showMessage(comment.getElement(), xhr.responseText, 'after'); } }); }; @@ -236,33 +210,34 @@ CommentVoteButton.prototype.getVoteHandler = function(){ CommentVoteButton.prototype.decorate = function(element){ this._element = element; - this.setHandler(this.getVoteHandler()); - var comment_vote = this._element.find('.upvote'); - if (this._element.parent()){ - var height = this._element.parent().height(); - this._element.height(height); - } var element = this._element; - this._comment_element.mouseenter(function(){ - elment.addClass('hover'); + var comment = this._comment; + /* can't call comment.getElement() here due + * an issue in the getElement() of comment + * so use an "illegal" access to comment._element here + */ + comment._element.mouseenter(function(){ + //outside height may not be known + var height = comment.getElement().height(); + element.height(height); + element.addClass('hover'); }); - this._comment_element.mouseleave(function(){ + comment._element.mouseleave(function(){ element.removeClass('hover'); }); }; CommentVoteButton.prototype.createDom = function(){ - this._element = this.makeElement('span'); - if (this._vote_type === VoteType.UP){ - this._element.addClass('upvote'); - } else if (this._vote_type === VoteType.DOWN){ - this._element.addClass('downvote'); + this._element = this.makeElement('div'); + if (this._score > 0){ + this._element.html(this._score); } + this._element.addClass('upvote'); if (this._voted){ - this._element.addClass('voted'); + this._element.addClass('upvoted'); } this.decorate(this._element); }; @@ -1188,10 +1163,7 @@ Comment.prototype.decorate = function(element){ this._edit_link.decorate(edit_link); } - var url = askbot['urls']['upvote_comment']; - var vote = new CommentVoteButton(VoteType.UP, url); - vote.setCommentId(comment_id); - vote.setCommentElement(this._element); + var vote = new CommentVoteButton(this); vote.decorate(this._element.find('.comment-votes .upvote')); this._blank = false; @@ -1235,14 +1207,11 @@ Comment.prototype.setContent = function(data){ var votes = this.makeElement('div'); votes.addClass('comment-votes'); - var vote_url = askbot['urls']['upvote_comment']; - var vote = new CommentVoteButton(VoteType.UP, vote_url); + var vote = new CommentVoteButton(this); if (this._data['upvoted_by_user']){ vote.setVoted(true); } vote.setScore(this._data['score']); - vote.setCommentId(this._data['id']); - vote.setCommentElement(this._element); votes.append(vote.getElement()); this._element.append(votes); diff --git a/askbot/skins/default/media/style/style.css b/askbot/skins/default/media/style/style.css index c1474432..85bc8801 100755 --- a/askbot/skins/default/media/style/style.css +++ b/askbot/skins/default/media/style/style.css @@ -968,20 +968,29 @@ a:hover.medal { } div.comment .comment-votes { - position:absolute; + position: absolute; width: 20px; - height: 25px; - margin-left: -20px; + margin: -2px 0 0 -20px; } -div.comment .comment-votes .upvote.hover { +div.comment .upvote { + width: 20px; + height: 20px; + padding: 3px 0 0 3px; + font-weight: bold; + color: #777; +} + +div.comment .upvote.upvoted { + color: #d64000; +} + +div.comment .upvote.hover { background: url(../images/go-up-grey.png) no-repeat; - padding-left: 16px; } -div.comment .comment-votes .upvote:hover { +div.comment .upvote:hover { background: url(../images/go-up-orange.png) no-repeat; - padding-left: 16px; } .comments div.controls { @@ -1807,7 +1816,7 @@ button::-moz-focus-inner { border-top: 1px dotted #ccccce; margin: 0; color: #444; - padding: 2px 3px 5px 3px; + padding: 5px 3px 5px 3px; overflow: auto; } diff --git a/askbot/skins/default/templates/macros.html b/askbot/skins/default/templates/macros.html index 5e401cb8..23177c0b 100644 --- a/askbot/skins/default/templates/macros.html +++ b/askbot/skins/default/templates/macros.html @@ -453,12 +453,12 @@ poor design of the data or methods on data objects #} {%- macro comment_votes(comment = None) -%} <div class="comment-votes"> {% if comment.score > 0 %} - <span class="upvote{% if comment.voted_by_user %} upvoted{% endif %}"> + <div class="upvote{% if comment.upvoted_by_user %} upvoted{% endif %}"> {{comment.score}} - </span> + </div> {% else %} - <span class="upvote"> - </span> + <div class="upvote"> + </div> {% endif %} </div> {%- endmacro -%} diff --git a/askbot/tests/db_api_tests.py b/askbot/tests/db_api_tests.py index 2bb39084..18fc174b 100644 --- a/askbot/tests/db_api_tests.py +++ b/askbot/tests/db_api_tests.py @@ -3,6 +3,7 @@ functions that happen on behalf of users e.g. ``some_user.do_something(...)`` """ +from django.core import exceptions from askbot.tests.utils import AskbotTestCase from askbot import models from askbot import const @@ -38,16 +39,6 @@ class DBApiTests(AskbotTestCase): self.assertTrue(post.deleted_by == None) self.assertTrue(post.deleted_at == None) - def test_get_question_comments(self): - comment = self.user.post_comment( - parent_post = self.question, - body_text = 'lalalalalalalalal hahahah' - ) - self.other_user.upvote(comment) - comments = self.question.get_comments(visitor = self.other_user) - self.assertEquals(len(comments), 1) - self.assertEquals(comments[0].upvoted_by_user, True) - def test_flag_question(self): self.user.set_status('m') self.user.flag_post(self.question) @@ -355,3 +346,34 @@ class GlobalTagSubscriberGetterTests(AskbotTestCase): expected_subscribers = set([self.u2,]), reason = 'bad' ) + +class CommentTests(AskbotTestCase): + """unfortunately, not very useful tests, + as assertions of type "user can" are not inside + the User.upvote() function + todo: refactor vote processing code + """ + def setUp(self): + self.create_user() + self.create_user(username = 'other_user') + self.question = self.post_question() + self.now = datetime.datetime.now() + self.comment = self.user.post_comment( + parent_post = self.question, + body_text = 'lalalalalalalalal hahahah' + ) + + def test_other_user_can_upvote_comment(self): + self.other_user.upvote(self.comment) + comments = self.question.get_comments(visitor = self.other_user) + self.assertEquals(len(comments), 1) + self.assertEquals(comments[0].upvoted_by_user, True) + + + def test_other_user_can_cancel_upvote(self): + self.test_other_user_can_upvote_comment() + comment = models.Comment.objects.get(id = self.comment.id) + self.assertEquals(comment.score, 1) + self.other_user.upvote(comment, cancel = True) + comment = models.Comment.objects.get(id = self.comment.id) + self.assertEquals(comment.score, 0) diff --git a/askbot/views/commands.py b/askbot/views/commands.py index d6fe4759..04d4ef1b 100644 --- a/askbot/views/commands.py +++ b/askbot/views/commands.py @@ -35,7 +35,6 @@ def process_vote(user = None, vote_direction = None, post = None): also in the future make keys in response data be more meaningful right now they are kind of cryptic - "status", "count" """ - if user.is_anonymous(): raise exceptions.PermissionDenied(_('anonymous users cannot vote')) @@ -539,8 +538,6 @@ def swap_question_with_answer(request): @decorators.ajax_only @decorators.post_only def upvote_comment(request): - import pdb - pdb.set_trace() if request.user.is_anonymous(): raise exceptions.PermissionDenied(_('Please sign in to vote')) form = forms.VoteForm(request.POST) @@ -548,7 +545,11 @@ def upvote_comment(request): comment_id = form.cleaned_data['post_id'] cancel_vote = form.cleaned_data['cancel_vote'] comment = models.Comment.objects.get(id = comment_id) - request.user.upvote(comment, cancel = cancel_vote) + process_vote( + post = comment, + vote_direction = 'up', + user = request.user + ) else: raise ValueError return {'score': comment.score} diff --git a/askbot/views/writers.py b/askbot/views/writers.py index 8ec85bad..c5a69c1d 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -529,7 +529,7 @@ def __generate_comments_json(obj, user):#non-view generates json data for the po comment_owner = comment.get_owner() - json_comments.append({'id' : comment.id, + comment_data = {'id' : comment.id, 'object_id': obj.id, 'comment_age': diff_date(comment.added_at), 'html': comment.html, @@ -538,7 +538,10 @@ def __generate_comments_json(obj, user):#non-view generates json data for the po 'user_id': comment_owner.id, 'is_deletable': is_deletable, 'is_editable': is_editable, - }) + 'score': comment.score, + 'upvoted_by_user': getattr(comment, 'upvoted_by_user', False) + } + json_comments.append(comment_data) data = simplejson.dumps(json_comments) return HttpResponse(data, mimetype="application/json") |