app/taggable/taggable_tests.py
changeset 2679 0ede2f3adbc1
equal deleted inserted replaced
2678:a525a55833f1 2679:0ede2f3adbc1
       
     1 #!/usr/bin/env python
       
     2 
       
     3 #Copyright 2008 Adam A. Crossland
       
     4 #
       
     5 #Licensed under the Apache License, Version 2.0 (the "License");
       
     6 #you may not use this file except in compliance with the License.
       
     7 #You may obtain a copy of the License at
       
     8 #
       
     9 #http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 #Unless required by applicable law or agreed to in writing, software
       
    12 #distributed under the License is distributed on an "AS IS" BASIS,
       
    13 #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 #See the License for the specific language governing permissions and
       
    15 #limitations under the License.
       
    16 
       
    17 import sys
       
    18 import os.path
       
    19 
       
    20 APPENGINE_PATH = '../../thirdparty/google_appengine'
       
    21 
       
    22 # Add app-engine related libraries to your path
       
    23 paths = [
       
    24     APPENGINE_PATH,
       
    25     os.path.join(APPENGINE_PATH, 'lib', 'django'),
       
    26     os.path.join(APPENGINE_PATH, 'lib', 'webob'),
       
    27     os.path.join(APPENGINE_PATH, 'lib', 'yaml', 'lib')
       
    28 ]
       
    29 for path in paths:
       
    30   if not os.path.exists(path): 
       
    31     raise 'Path does not exist: %s' % path
       
    32 sys.path = paths + sys.path
       
    33 
       
    34 import unittest
       
    35 from google.appengine.api import apiproxy_stub_map
       
    36 from google.appengine.api import datastore_file_stub
       
    37 from google.appengine.api import mail_stub
       
    38 from google.appengine.api import user_service_stub
       
    39 from google.appengine.ext import webapp
       
    40 from google.appengine.ext import db
       
    41 from google.appengine.api.memcache import memcache_stub
       
    42 from taggable import *
       
    43 
       
    44 APP_ID = u'taggable'
       
    45 AUTH_DOMAIN = 'gmail.com'
       
    46 LOGGED_IN_USER = 'me@example.com'  # set to '' for no logged in user
       
    47 
       
    48 BLOG_NAME='test_blog'
       
    49 
       
    50 class BlogIndex(db.Model):
       
    51     "A global counter used to provide the index of the next blog post."
       
    52     index = db.IntegerProperty(required=True, default=0)
       
    53     "The next available index for a Post."
       
    54 
       
    55 class Post(Taggable, db.Model):
       
    56     index = db.IntegerProperty(required=True, default=0)
       
    57     body = db.TextProperty(required = True)
       
    58     title = db.StringProperty()
       
    59     added = db.DateTimeProperty(auto_now_add=True)
       
    60     added_month = db.IntegerProperty()
       
    61     added_year = db.IntegerProperty()
       
    62     edited = db.DateTimeProperty()
       
    63         
       
    64     def __init__(self, parent=None, key_name=None, app=None, **entity_values):
       
    65         db.Model.__init__(self, parent, key_name, app, **entity_values)
       
    66         Taggable.__init__(self)
       
    67         
       
    68     def get_all_posts():
       
    69         return db.GqlQuery("SELECT * from Post ORDER BY added DESC")
       
    70     Get_All_Posts = staticmethod(get_all_posts)
       
    71         
       
    72     @classmethod        
       
    73     def get_posts(cls, start_index=0, count=10):
       
    74         start_index = int(start_index) # Just make sure that we have an int
       
    75         posts = Post.gql('WHERE index <= :1 ORDER BY index DESC', start_index).fetch(count + 1)
       
    76         if len(posts) > count:
       
    77             posts = posts[:count]
       
    78             
       
    79         return posts
       
    80 
       
    81     @classmethod
       
    82     def new_post(cls, new_title=None, new_body=None, new_tags=[]):
       
    83         new_post = None
       
    84         if new_title is not None and new_body is not None:
       
    85             def txn():
       
    86                 blog_index = BlogIndex.get_by_key_name(BLOG_NAME)
       
    87                 if blog_index is None:
       
    88                     blog_index = BlogIndex(key_name=BLOG_NAME)
       
    89                 new_index = blog_index.index
       
    90                 blog_index.index += 1
       
    91                 blog_index.put()
       
    92             
       
    93                 new_post_key_name = BLOG_NAME + str(new_index)
       
    94                 new_post = Post(key_name=new_post_key_name, parent=blog_index,
       
    95                                index = new_index, title = new_title,
       
    96                                body = new_body)
       
    97                 new_post.put()
       
    98                 
       
    99                 return new_post
       
   100             new_post = db.run_in_transaction(txn)
       
   101         
       
   102             new_post.tags = new_tags
       
   103             new_post.put()
       
   104         else:
       
   105             raise Exception("Must supply both new_title and new_body when creating a new Post.")
       
   106         
       
   107         return new_post
       
   108     
       
   109     def delete(self):
       
   110         # Perform any actions that are required to maintain data integrity
       
   111         # when this Post is delete.
       
   112         # Disassociate this Post from any Tag
       
   113         self.set_tags([])
       
   114         
       
   115         # Finally, call the real delete
       
   116         db.Model.delete(self)
       
   117 
       
   118 class MyTest(unittest.TestCase):
       
   119 
       
   120     def setUp(self):
       
   121       # Start with a fresh api proxy.
       
   122       apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
       
   123 
       
   124       # Use a fresh stub datastore.
       
   125       stub = datastore_file_stub.DatastoreFileStub(APP_ID, '/dev/null', '/dev/null')
       
   126       apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', stub)
       
   127 
       
   128       # Use a fresh memcache stub.
       
   129       apiproxy_stub_map.apiproxy.RegisterStub('memcache', memcache_stub.MemcacheServiceStub())
       
   130         
       
   131       # Use a fresh stub UserService.
       
   132       apiproxy_stub_map.apiproxy.RegisterStub(
       
   133           'user', user_service_stub.UserServiceStub())
       
   134       os.environ['AUTH_DOMAIN'] = AUTH_DOMAIN
       
   135       os.environ['USER_EMAIL'] = LOGGED_IN_USER
       
   136       os.environ['APPLICATION_ID'] = APP_ID
       
   137 
       
   138     def testSimpleTagAdding(self):
       
   139       new_post = Post.new_post(new_title='test post 1', new_body='This is a test post.  Please ignore.')
       
   140       assert new_post is not None
       
   141         
       
   142       new_post.tags = "test, testing, tests"
       
   143       self.assertEqual(len(new_post.tags), 3)
       
   144 
       
   145     def testComplexTagAdding(self):
       
   146       new_post = Post.new_post(new_title='test post 1', new_body='This is a test post.  Please ignore.')
       
   147       assert new_post is not None
       
   148         
       
   149       new_post.tags = "  test, testing, tests,,,tag with spaces"
       
   150       self.assertEqual(len(new_post.tags), 4)
       
   151 
       
   152       tag = new_post.tags[3]
       
   153       assert tag is not None
       
   154       self.assertEqual(tag.tag, 'tag with spaces')
       
   155       self.assertEqual(tag.tagged_count, 1)
       
   156 
       
   157       tag2 = Tag.get_by_name('tag with spaces')
       
   158       assert tag2 is not None
       
   159       self.assertEqual(tag.tag, 'tag with spaces')
       
   160       self.assertEqual(tag.tagged_count, 1)
       
   161 
       
   162     def testTagDeletion(self):
       
   163       new_post = Post.new_post(new_title='test post 2', new_body='This is a test post.  Please continue to ignore.')
       
   164       assert new_post is not None
       
   165         
       
   166       new_post.tags = "test, testing, tests"
       
   167       self.assertEqual(len(new_post.tags), 3)
       
   168 
       
   169       new_post.tags = "test"
       
   170       self.assertEqual(len(new_post.tags), 1)
       
   171 
       
   172     def testTagCounts(self):
       
   173       new_post3 = Post.new_post(new_title='test post 3', new_body='This is a test post.  Please continue to ignore.')
       
   174       assert new_post3 is not None
       
   175       new_post3.tags = "foo, bar, baz"
       
   176       new_post4 = Post.new_post(new_title='test post 4', new_body='This is a test post.  Please continue to ignore.')
       
   177       assert new_post4 is not None
       
   178       new_post4.tags = "bar, baz, bletch"
       
   179       new_post5 = Post.new_post(new_title='test post 5', new_body='This is a test post.  Please continue to ignore.')
       
   180       assert new_post5 is not None
       
   181       new_post5.tags = "baz, bletch, quux"
       
   182       
       
   183       foo_tag = Tag.get_by_name('foo')
       
   184       assert foo_tag is not None
       
   185       self.assertEqual(foo_tag.tagged_count, 1)
       
   186       
       
   187       bar_tag = Tag.get_by_name('bar')
       
   188       assert bar_tag is not None
       
   189       self.assertEqual(bar_tag.tagged_count, 2)
       
   190       
       
   191       baz_tag = Tag.get_by_name('baz')
       
   192       assert baz_tag is not None
       
   193       self.assertEqual(baz_tag.tagged_count, 3)
       
   194       
       
   195       bletch_tag = Tag.get_by_name('bletch')
       
   196       assert bletch_tag is not None
       
   197       self.assertEqual(bletch_tag.tagged_count, 2)
       
   198       
       
   199       quux_tag = Tag.get_by_name('quux')
       
   200       assert quux_tag is not None
       
   201       self.assertEqual(quux_tag.tagged_count, 1)
       
   202       
       
   203       new_post3.tags = 'bar, baz'
       
   204       foo_tag = Tag.get_by_name('foo')
       
   205       assert foo_tag is not None
       
   206       self.assertEqual(len(new_post3.tags), 2)
       
   207       self.assertEqual(foo_tag.tagged_count, 0)
       
   208       
       
   209     def testTagGetTagsForKey(self):
       
   210       new_post = Post.new_post(new_title='test post 6', new_body='This is a test post.  Please continue to ignore.', new_tags='foo,bar,bletch,quux')
       
   211       assert new_post is not None
       
   212 
       
   213       tags = Tag.get_tags_for_key(new_post.key())
       
   214       assert tags is not None
       
   215       self.assertEqual(type(tags), type([]))
       
   216       self.assertEqual(len(tags), 4)
       
   217     
       
   218     def testTagGetByName(self):
       
   219       new_post = Post.new_post(new_title='test post 6', new_body='This is a test post.  Please continue to ignore.', new_tags='foo,bar,bletch,quux')
       
   220       assert new_post is not None
       
   221 
       
   222       quux_tag = Tag.get_by_name('quux')
       
   223       assert quux_tag is not None
       
   224       
       
   225       zizzle_tag = Tag.get_by_name('zizzle')
       
   226       assert zizzle_tag is None
       
   227       
       
   228     def testTagsString(self):
       
   229       new_post = Post.new_post(new_title='test post 6', new_body='This is a test post.  Please continue to ignore.', new_tags='  pal,poll ,,pip,pony')
       
   230       assert new_post is not None
       
   231       self.assertEqual(new_post.tags_string(), "pal,poll,pip,pony")
       
   232       new_post.tag_separator = "|"
       
   233       self.assertEqual(new_post.tags_string(), "pal|poll|pip|pony")
       
   234       new_post.tag_separator = " , "
       
   235       self.assertEqual(new_post.tags_string(), "pal , poll , pip , pony")
       
   236       
       
   237       new_post.tag_separator = ", "
       
   238       new_post.tags = "pal, pill, pip"
       
   239       self.assertEqual(len(new_post.tags), 3)
       
   240       self.assertEqual(new_post.tags_string(), "pal, pill, pip")
       
   241       
       
   242 if __name__ == '__main__':
       
   243     unittest.main()