1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 import six
.moves
.urllib
.parse
as urlparse
21 from mediagoblin
.tools
import template
, mail
23 from mediagoblin
.db
.models
import Notification
, CommentSubscription
24 from mediagoblin
.db
.base
import Session
26 from mediagoblin
.notifications
import mark_comment_notification_seen
28 from mediagoblin
.tests
.tools
import fixture_add_comment
, \
29 fixture_media_entry
, fixture_add_user
, \
30 fixture_comment_subscription
33 class TestNotifications
:
34 @pytest.fixture(autouse
=True)
35 def setup(self
, test_app
):
36 self
.test_app
= test_app
38 # TODO: Possibly abstract into a decorator like:
39 # @as_authenticated_user('chris')
40 self
.test_user
= fixture_add_user(privileges
=[u
'active',u
'commenter'])
42 self
.current_user
= None
46 def login(self
, username
=u
'chris', password
=u
'toast'):
47 response
= self
.test_app
.post(
50 'password': password
})
54 assert urlparse
.urlsplit(response
.location
)[2] == '/'
55 assert 'mediagoblin/root.html' in template
.TEMPLATE_TEST_CONTEXT
57 ctx
= template
.TEMPLATE_TEST_CONTEXT
['mediagoblin/root.html']
59 assert Session
.merge(ctx
['request'].user
).username
== username
61 self
.current_user
= ctx
['request'].user
64 self
.test_app
.get('/auth/logout/')
65 self
.current_user
= None
67 @pytest.mark
.parametrize('wants_email', [True, False])
68 def test_comment_notification(self
, wants_email
):
71 - if a notification is created when posting a comment on
72 another users media entry.
73 - that the comment data is consistent and exists.
76 user
= fixture_add_user('otherperson', password
='nosreprehto',
77 wants_comment_notification
=wants_email
,
78 privileges
=[u
'active',u
'commenter'])
80 assert user
.wants_comment_notification
== wants_email
84 media_entry
= fixture_media_entry(uploader
=user
.id, state
=u
'processed')
86 media_entry_id
= media_entry
.id
88 subscription
= fixture_comment_subscription(media_entry
)
90 subscription_id
= subscription
.id
92 media_uri_id
= '/u/{0}/m/{1}/'.format(user
.username
,
94 media_uri_slug
= '/u/{0}/m/{1}/'.format(user
.username
,
98 media_uri_id
+ 'comment/add/',
100 'comment_content': u
'Test comment #42'
104 notifications
= Notification
.query
.filter_by(
105 user_id
=user
.id).all()
107 assert len(notifications
) == 1
109 notification
= notifications
[0]
111 assert notification
.seen
== False
112 assert notification
.user_id
== user
.id
113 assert notification
.obj().get_actor
.id == self
.test_user
.id
114 assert notification
.obj().content
== u
'Test comment #42'
116 if wants_email
== True:
117 assert mail
.EMAIL_TEST_MBOX_INBOX
== [
118 {'from': 'notice@mediagoblin.example.org',
119 'message': 'Content-Type: text/plain; \
120 charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: \
121 base64\nSubject: GNU MediaGoblin - chris commented on your \
122 post\nFrom: notice@mediagoblin.example.org\nTo: \
123 otherperson@example.com\n\nSGkgb3RoZXJwZXJzb24sCmNocmlzIGNvbW1lbnRlZCBvbiB5b3VyIHBvc3QgKGh0dHA6Ly9sb2Nh\nbGhvc3Q6ODAvdS9vdGhlcnBlcnNvbi9tL3NvbWUtdGl0bGUvYy8xLyNjb21tZW50KSBhdCBHTlUg\nTWVkaWFHb2JsaW4KClRlc3QgY29tbWVudCAjNDIKCkdOVSBNZWRpYUdvYmxpbg==\n',
124 'to': [u
'otherperson@example.com']}]
126 assert mail
.EMAIL_TEST_MBOX_INBOX
== []
129 # Save the ids temporarily because of DetachedInstanceError
130 notification_id
= notification
.id
131 comment_id
= notification
.obj().get_comment_link().id
134 self
.login('otherperson', 'nosreprehto')
136 self
.test_app
.get(media_uri_slug
+ 'c/{0}/'.format(comment_id
))
138 notification
= Notification
.query
.filter_by(id=notification_id
).first()
140 assert notification
.seen
== True
142 self
.test_app
.get(media_uri_slug
+ 'notifications/silence/')
144 subscription
= CommentSubscription
.query
.filter_by(id=subscription_id
)\
147 assert subscription
.notify
== False
149 notifications
= Notification
.query
.filter_by(
150 user_id
=user_id
).all()
152 # User should not have been notified
153 assert len(notifications
) == 1
155 def test_mark_all_comment_notifications_seen(self
):
156 """ Test that mark_all_comments_seen works"""
158 user
= fixture_add_user('otherperson', password
='nosreprehto',
159 privileges
=[u
'active'])
161 media_entry
= fixture_media_entry(uploader
=user
.id, state
=u
'processed')
163 fixture_comment_subscription(media_entry
)
165 media_uri_id
= '/u/{0}/m/{1}/'.format(user
.username
,
170 media_uri_id
+ 'comment/add/',
172 'comment_content': u
'Test comment #43'
177 media_uri_id
+ 'comment/add/',
179 'comment_content': u
'Test comment #44'
183 notifications
= Notification
.query
.filter_by(
184 user_id
=user
.id).all()
186 assert len(notifications
) == 2
188 # both comments should not be marked seen
189 assert notifications
[0].seen
== False
190 assert notifications
[1].seen
== False
192 # login with other user to mark notifications seen
194 self
.login('otherperson', 'nosreprehto')
196 # mark all comment notifications seen
197 res
= self
.test_app
.get('/notifications/comments/mark_all_seen/')
200 assert urlparse
.urlsplit(res
.location
)[2] == '/'
202 notifications
= Notification
.query
.filter_by(
203 user_id
=user
.id).all()
205 # both notifications should be marked seen
206 assert notifications
[0].seen
== True
207 assert notifications
[1].seen
== True