Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#3009] Initial implementation of activity streams on-site notificati…
…on API
- Loading branch information
Sean Hammond
committed
Nov 6, 2012
1 parent
60d61d8
commit 2398b28
Showing
4 changed files
with
185 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,6 +147,9 @@ | |
DomainObjectOperation, | ||
DomainObject, | ||
) | ||
from dashboard import ( | ||
Dashboard, | ||
) | ||
|
||
import ckan.migration | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import datetime | ||
import sqlalchemy | ||
import meta | ||
|
||
dashboard_table = sqlalchemy.Table('dashboard', meta.metadata, | ||
sqlalchemy.Column('user_id', sqlalchemy.types.UnicodeText, | ||
sqlalchemy.ForeignKey('user.id', onupdate='CASCADE', | ||
ondelete='CASCADE'), | ||
primary_key=True, nullable=False), | ||
sqlalchemy.Column('activity_stream_last_viewed', sqlalchemy.types.DateTime, | ||
nullable=False) | ||
) | ||
|
||
|
||
class Dashboard(object): | ||
'''Saved data used for the user's dashboard.''' | ||
|
||
def __init__(self, user_id): | ||
self.user_id = user_id | ||
self.activity_stream_last_viewed = datetime.datetime.now() | ||
|
||
@classmethod | ||
def get_activity_stream_last_viewed(cls, user_id): | ||
query = meta.Session.query(Dashboard) | ||
query = query.filter(Dashboard.user_id == user_id) | ||
try: | ||
row = query.one() | ||
return row.activity_stream_last_viewed | ||
except sqlalchemy.orm.exc.NoResultFound: | ||
# No dashboard row has been created for this user so they have no | ||
# activity_stream_last_viewed date. Return the oldest date we can | ||
# (i.e. all activities are new to this user). | ||
return datetime.datetime.min | ||
|
||
@classmethod | ||
def update_activity_stream_last_viewed(cls, user_id): | ||
query = meta.Session.query(Dashboard) | ||
query = query.filter(Dashboard.user_id == user_id) | ||
try: | ||
row = query.one() | ||
row.activity_stream_last_viewed = datetime.datetime.now() | ||
except sqlalchemy.orm.exc.NoResultFound: | ||
row = Dashboard(user_id) | ||
meta.Session.add(row) | ||
meta.Session.commit() | ||
|
||
meta.mapper(Dashboard, dashboard_table) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import ckan | ||
from ckan.lib.helpers import json | ||
import paste | ||
import pylons.test | ||
|
||
|
||
class TestDashboard(object): | ||
'''Tests for the logic action functions related to the user's dashboard.''' | ||
|
||
@classmethod | ||
def setup_class(cls): | ||
ckan.tests.CreateTestData.create() | ||
cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) | ||
joeadmin = ckan.model.User.get('joeadmin') | ||
cls.joeadmin = { | ||
'id': joeadmin.id, | ||
'apikey': joeadmin.apikey | ||
} | ||
|
||
@classmethod | ||
def teardown_class(cls): | ||
ckan.model.repo.rebuild_db() | ||
|
||
def new_activities_count(self, user): | ||
'''Return the given user's new activities count from the CKAN API.''' | ||
|
||
params = json.dumps({}) | ||
response = self.app.post('/api/action/dashboard_new_activities_count', | ||
params=params, | ||
extra_environ={'Authorization': str(user['apikey'])}) | ||
assert response.json['success'] is True | ||
new_activities_count = response.json['result'] | ||
return new_activities_count | ||
|
||
def mark_as_read(self, user): | ||
params = json.dumps({}) | ||
response = self.app.post( | ||
'/api/action/dashboard_mark_activities_as_read', | ||
params=params, | ||
extra_environ={'Authorization': str(user['apikey'])}) | ||
assert response.json['success'] is True | ||
|
||
def test_01_num_new_activities_new_user(self): | ||
'''Test retreiving the number of new activities for a new user.''' | ||
|
||
# Create a new user. | ||
params = json.dumps({ | ||
'name': 'mr_new_user', | ||
'email': 'mr@newuser.com', | ||
'password': 'iammrnew', | ||
}) | ||
response = self.app.post('/api/action/user_create', params=params, | ||
extra_environ={'Authorization': str(self.joeadmin['apikey'])}) | ||
assert response.json['success'] is True | ||
new_user = response.json['result'] | ||
|
||
# We expect to find only one new activity for a newly registered user | ||
# (A "{USER} signed up" activity). | ||
assert self.new_activities_count(new_user) == 1 | ||
|
||
self.mark_as_read(new_user) | ||
assert self.new_activities_count(new_user) == 0 | ||
|
||
# Create a dataset. | ||
params = json.dumps({ | ||
'name': 'my_new_package', | ||
}) | ||
response = self.app.post('/api/action/package_create', params=params, | ||
extra_environ={'Authorization': str(new_user['apikey'])}) | ||
assert response.json['success'] is True | ||
|
||
# Now there should be a new 'user created dataset' activity. | ||
assert self.new_activities_count(new_user) == 1 | ||
|
||
# Update the dataset. | ||
params = json.dumps({ | ||
'name': 'my_new_package', | ||
'title': 'updated description', | ||
}) | ||
response = self.app.post('/api/action/package_update', params=params, | ||
extra_environ={'Authorization': str(new_user['apikey'])}) | ||
assert response.json['success'] is True | ||
|
||
assert self.new_activities_count(new_user) == 2 | ||
|
||
self.mark_as_read(new_user) | ||
assert self.new_activities_count(new_user) == 0 |