Ejemplo n.º 1
0
    def test_delete_user(self):
        user_to_del = User(name='user_delete',
                           email='*****@*****.**',
                           email_confirmed=1,
                           is_paid=1)
        user_to_del.set_password('asdfasdf')
        user_to_del.save()

        sourcefile = Sourcefile(width=20,
                                height=20,
                                file_key="asdf",
                                thumb_key="asdf_t")
        sourcefile.save()
        sharedfile = Sharedfile(source_id=sourcefile.id,
                                name="my shared file",
                                user_id=user_to_del.id,
                                content_type="image/png",
                                share_key="ok")
        sharedfile.save()
        user_shake = user_to_del.shake()
        sharedfile.add_to_shake(user_shake)

        self.post_url('/admin/delete-user',
                      arguments={
                          'user_id': user_to_del.id,
                          'user_name': user_to_del.name
                      })

        deleted_user = User.get('id = %s and name = %s', user_to_del.id,
                                user_to_del.name)
        self.assertEqual(deleted_user.deleted, 1)

        sf = Sharedfile.get('id=%s', sharedfile.id)
        self.assertEqual(sf.deleted, 1)
Ejemplo n.º 2
0
    def test_oembed_response_json_for_link(self):
        url = 'https://vimeo.com/20379529'
        sourcefile = Sourcefile(width=100,
                                height=100,
                                data="{'junk':'here'}",
                                type='link',
                                file_key="asdfasdfasdfasdfasdf")
        sourcefile.save()

        sharedfile = Sharedfile(source_id=sourcefile.id,
                                user_id=self.user.id,
                                name=url,
                                title="Some Title",
                                source_url=url,
                                content_type='text/html')
        sharedfile.save()
        sharedfile.share_key = base36encode(sharedfile.id)
        sharedfile.save()
        sharedfile = Sharedfile.get('id = %s', 1)
        file_time_stamp = int(time.mktime(sharedfile.created_at.timetuple()))
        self.http_client.fetch(
            self.get_url("/services/oembed?url=http%3A//mltshp.com/p/1"),
            self.stop)
        response = self.wait()
        j_response = json_decode(response.body)
        self.assertEqual(j_response['type'], "link")
        self.assertEqual(j_response['url'], url)
Ejemplo n.º 3
0
    def test_pagination_returns_correct_counts(self):
        """
        This tests creating 111 shared files for a user and then tests that pagination
        on their user page returns the correct pages
        """
        user = User.get('name="admin"')
        user_shake = user.shake()
        source_file = Sourcefile(width=10,
                                 height=10,
                                 file_key='mumbles',
                                 thumb_key='bumbles')
        source_file.save()

        missing_ids = []

        for i in range(111):
            sf = Sharedfile(source_id=source_file.id,
                            user_id=user.id,
                            name="shgaredfile.png",
                            title='shared file',
                            share_key='asdf',
                            content_type='image/png',
                            deleted=0)
            sf.save()
            sf.add_to_shake(user_shake)

        for i in range(12):
            response = self.fetch('/user/admin/%s' % (i + 1))
            self.assertEqual(response.code, 200)
Ejemplo n.º 4
0
    def test_query_friend_shake_before_after(self):
        """
        Admin (user_a), who user2 (user_b) follows, uploads 10 files, which appear in
        Admin's stream.

        /friends/before/{share_key} should return all files that came before passed in share_key
        while /friends/after/{share_key} should return those that came after.

        We assume there is already one file uploaded by Admin (share_key -> 1)
        """
        files = []
        for x in range(10):
            source_file = Sourcefile(width=10, height=10, file_key='mumbles', thumb_key='bumbles')
            source_file.save()
            sf = Sharedfile(source_id = source_file.id, user_id = self.user_a.id, name="shgaredfile.png",
                            title='shared file', content_type='image/png', deleted=0)
            sf.save()
            sf.share_key = base36encode(sf.id)
            sf.save()
            sf.add_to_shake(self.user_a.shake())
            files.append(sf)

        request = signed_request(self.access_token, self.get_url('/api/friends/before/%s' % files[3].share_key))
        self.http_client.fetch(request, self.stop)
        response = self.wait()
        j_response = json_decode(response.body)
        self.assertEqual(4, len(j_response['friend_shake']))

        request = signed_request(self.access_token, self.get_url('/api/friends/after/%s' % files[3].share_key))
        self.http_client.fetch(request, self.stop)
        response = self.wait()
        j_response = json_decode(response.body)
        self.assertEqual(6, len(j_response['friend_shake']))
Ejemplo n.º 5
0
    def test_paginated_sharedfiles_and_count(self):
        """
        Tests both the pagination of a shake's shared files and the count
        """
        sharedfiles = []
        sourcefile = Sourcefile(width=20,
                                height=20,
                                file_key="asdf",
                                thumb_key="asdf_t")
        sourcefile.save()

        for i in range(31):
            sf = Sharedfile(source_id=sourcefile.id,
                            name="my shared file",
                            user_id=self.user.id,
                            content_type="image/png",
                            share_key="1",
                            description="some\ndescription\nhere",
                            source_url="https://www.mltshp.com/?hi")
            sf.save()
            sf.add_to_shake(self.shake)
            sharedfiles.append(sf)

        self.assertEqual(len(self.shake.sharedfiles()), 10)  #default
        self.assertEqual(len(self.shake.sharedfiles(page=1)), 10)
        self.assertEqual(len(self.shake.sharedfiles(page=2)), 10)
        self.assertEqual(len(self.shake.sharedfiles(page=3)), 10)
        self.assertEqual(len(self.shake.sharedfiles(page=4)), 1)

        self.assertEqual(len(self.shake.sharedfiles(page=1, per_page=31)), 31)
Ejemplo n.º 6
0
class ConversationModelTests(BaseTestCase):

    def setUp(self):
        """
        Create a user, a source file and a shared file to user in tests.
        """
        super(ConversationModelTests, self).setUp()
        self.user = User(name='example',email='*****@*****.**',
            verify_email_token = 'created', password='******', email_confirmed=1,
            is_paid=1)
        self.user.save()
        self.another_user = User(name='somethingelse',email='*****@*****.**',
            verify_email_token = 'created', password='******', email_confirmed=1,
            is_paid=1)
        self.another_user.save()
        self.sourcefile = Sourcefile(width=20,height=20,file_key="asdf", \
            thumb_key="asdf_t")
        self.sourcefile.save()
        self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=self.user.id, content_type="image/png", share_key="ok")
        self.sharedfile.save()

    def test_relevant_comments(self):
        """
        Conversation.relevant_comments returns all the comments for the conversation at hand.
        """
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.another_user.id, body='test')
        comment.save()

        another_user_conversation = Conversation.get('user_id = %s', self.another_user.id)
        self.assertEqual(1, len(another_user_conversation.relevant_comments()))

        comment2 = Comment(sharedfile_id=self.sharedfile.id, user_id=self.another_user.id, body='two')
        comment2.save()
        self.assertEqual(2, len(another_user_conversation.relevant_comments()))

    def test_for_user_doesnt_return_muted_conversations(self):
        """
        When we create a Comment, conversation gets created for the sharedfile owner and the
        commenter.  The conversation should appear for the commenter, unless the conversation
        gets muted, in which case it doesn't get returned.
        """
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.another_user.id, body='test')
        comment.save()

        another_user_conversation = Conversation.get('user_id = %s', self.another_user.id)
        self.assertEqual(0, another_user_conversation.muted)
        self.assertEqual(1, len(Conversation.for_user(self.another_user.id)))

        another_user_conversation.muted = 1
        another_user_conversation.save()
        self.assertEqual(0, len(Conversation.for_user(self.another_user.id)))
Ejemplo n.º 7
0
 def _create_sharedfile(self, user):
     """
     Utility to create a stub sharedfile for the user.
     """
     sourcefile = Sourcefile(width=20,height=20,file_key="asdf",thumb_key="asdf_t")
     sourcefile.save()
     sharedfile = Sharedfile(source_id=sourcefile.id, name="the name",user_id=user.id, \
         content_type="image/png", title='the title', description="the description", \
         source_url="https://www.mltshp.com/?hi")
     sharedfile.save()
     sharedfile.share_key = lib.utilities.base36encode(sharedfile.id)
     sharedfile.save()
     return sharedfile
Ejemplo n.º 8
0
 def _post_to_shake(self, user, to_shake=None):
     """
     Utility method for creating a post to a shake.  If shake is
     not specified, the newly created sharedfile will be added to
     the user's shake.
     """
     source_file = Sourcefile(width=10, height=10, file_key='mumbles', thumb_key='bumbles')
     source_file.save()
     sf = Sharedfile(source_id=source_file.id, user_id=user.id, name="sharedfile.png",
                     title='shared file', content_type='image/png', deleted=0)
     sf.save()
     sf.share_key = base36encode(sf.id)
     sf.save()
     if to_shake:
         sf.add_to_shake(to_shake)
     else:
         sf.add_to_shake(user.shake())
     return sf
Ejemplo n.º 9
0
    def test_subscription_timeline_shows_appropriate_images(self):
        """
        We have a user subscribe to the shakes of 2 other users.  The users
        that are being subscribed to have one sharedfile each, both pointing
        to same source file.

        When a user subscribes, his timeline will be populated with last 10
        posts from user being subscribed to.  In this case, timeline will
        suppress dupes.
        """
        user1 = User(name='user', email='*****@*****.**', is_paid=1)
        user1.save()

        source_file = Sourcefile(width=10,
                                 height=10,
                                 file_key='mumbles',
                                 thumb_key='bumbles')
        source_file.save()
        users = ['user2', 'user3', 'user4']
        for name in users:
            user = User(name=name, email='*****@*****.**' % (name), is_paid=1)
            user.save()
            sf = Sharedfile(source_id=source_file.id, user_id = user.id, name='%s file.jpg' % (name), \
                title='%s file' % (name), share_key='%s' % (name), content_type='image/jpg', deleted=0)
            sf.save()
            sf.add_to_shake(user.shake())

        # have user follow two users' shakes
        user2 = User.get('name=%s', 'user2')
        user3 = User.get('name=%s', 'user3')
        user1.subscribe(user2.shake())
        user1.subscribe(user3.shake())

        shared_files = user1.sharedfiles_from_subscriptions()
        self.assertEqual(1, len(shared_files))
        self.assertEqual(shared_files[0].source_id, source_file.id)

        shared_files[0].deleted = 1
        shared_files[0].save()

        # they should no longer see the shared file since it
        # was deleted.
        shared_files = user1.sharedfiles_from_subscriptions()
        self.assertEqual(0, len(shared_files))
Ejemplo n.º 10
0
    def test_non_signed_in_permalink_view(self):
        user = User(name='admin', email='*****@*****.**', email_confirmed=1)
        user.save()
        src = Sourcefile(width=100,
                         height=100,
                         file_key="asdf",
                         thumb_key="asdfqwer")
        src.save()
        sf = Sharedfile(source_id=src.id,
                        user_id=1,
                        name="some.jpg",
                        title="some",
                        share_key="1",
                        content_type="image/jpg")
        sf.save()

        self.http_client.fetch(self.get_url('/p/1'), self.stop)
        response = self.wait()
        self.assertEqual(response.code, 200)
Ejemplo n.º 11
0
    def test_user_paid_account_rss_works(self):
        sourcefile = Sourcefile(width=20,
                                height=20,
                                file_key="asdf",
                                thumb_key="asdf_t")
        sourcefile.save()
        sharedfile = Sharedfile(source_id=sourcefile.id, name="the name",user_id=self.user.id, \
            content_type="image/png", description="description", source_url="https://www.mltshp.com/?hi")
        sharedfile.save()
        sharedfile.share_key = lib.utilities.base36encode(sharedfile.id)
        sharedfile.save()

        sharedfile.add_to_shake(self.user.shake())

        response = self.fetch_url('/user/admin/rss')
        self.assertEqual(response.headers['Content-Type'], 'application/xml')
        parsed_xml = lib.utilities.parse_xml(response.body)
        self.assertEqual(parsed_xml['rss']['channel']['item']['link'],
                         'https://mltshp.com/p/1')
Ejemplo n.º 12
0
    def test_created_shake_contains_file(self):
        """
        This test creates three users. User A creates a shake (asdf) and adds a file to it.
        User B follows User A
        User C follows User A
        User B follows User A's shake (asdf)

        Getting shared files for B sees file.
        Getting shared files for C does not see file.
        Getting shared files for A does not see file.
        """
        user_a = User(name='user_a',
                      email='*****@*****.**',
                      email_confirmed=1,
                      is_paid=1,
                      stripe_plan_id="mltshp-double")
        user_a.set_password('asdfasdf')
        user_a.save()
        user_b = User(name='user_b',
                      email='*****@*****.**',
                      email_confirmed=1,
                      is_paid=1)
        user_b.set_password('asdfasdf')
        user_b.save()
        user_c = User(name='user_c',
                      email='*****@*****.**',
                      email_confirmed=1,
                      is_paid=1)
        user_c.set_password('asdfasdf')
        user_c.save()

        self.sign_in('user_a', 'asdfasdf')
        arguments = {
            'name': 'asdf',
            'description': 'A shake test.',
            'title': 'Shake Test',
        }
        self.post_url('/shake/create', arguments=arguments)

        self.sign_in('user_b', 'asdfasdf')
        shake = Shake.get('name = %s', 'asdf')
        self.post_url('/shake/%s/subscribe?json=1' % shake.id)

        #create a shared file and source file
        sourcefile = Sourcefile(width=20,
                                height=20,
                                file_key="asdf",
                                thumb_key="asdf_t")
        sourcefile.save()
        sharedfile = Sharedfile(source_id=sourcefile.id, name="the name",user_id=user_a.id, \
            content_type="image/png", description="description", source_url="https://www.mltshp.com/?hi")
        sharedfile.save()
        sharedfile.share_key = lib.utilities.base36encode(sharedfile.id)
        sharedfile.save()

        new_shake = Shake.get('name=%s', 'asdf')

        sharedfile.add_to_shake(new_shake)

        shared_files = Sharedfile.from_subscriptions(user_b.id)

        self.assertEqual(len(shared_files), 1)
        self.assertEqual(shared_files[0].user_id, user_a.id)

        #contains one sub to their created shake
        self.assertEqual(len(Sharedfile.from_subscriptions(user_a.id)), 1)
        self.assertEqual(len(Sharedfile.from_subscriptions(user_c.id)), 0)
Ejemplo n.º 13
0
class CommentModelTests(BaseTestCase):

    def setUp(self):
        """
        Create a user sourcefile and sharedfile to work with.
        """
        super(CommentModelTests, self).setUp() # register connection.
        self.user = User(name='thename',email='*****@*****.**',verify_email_token='created',email_confirmed=1, is_paid=1)
        self.user.save()
        self.sourcefile = Sourcefile(width=20,height=20,file_key="asdf",thumb_key="asdf_t")
        self.sourcefile.save()
        self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
            content_type="image/png", share_key="ok")
        self.sharedfile.save()

        self.visitor = User(name='visitor',email='*****@*****.**',verify_email_token='created',email_confirmed=1, is_paid=1)
        self.visitor.save()

    def test_as_json(self):
        """
        Make sure as_json returns comment body and user dict in the dict response.
        """
        comment = Comment.add(user=self.user, sharedfile=self.sharedfile, body='hello')
        comment_j = comment.as_json()
        self.assertEqual(comment_j['body'], comment.body)
        self.assertEqual(comment_j['user'], comment.user().as_json())

    def test_body_formatted(self):
        """
        Comment.body_formatted should escape HTML character as well as replace line breaks (\n)
        with <br>.
        """
        body ="""<hello>
break
"time"""
        body_formatted = """&lt;hello&gt;<br>break<br>&quot;time"""
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body=body)
        comment.save()
        self.assertEqual(body_formatted, comment.body_formatted())

    def test_user(self):
        """
        Comment.user should return the user or None, if that user doesn't exist for some
        reason.
        """
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body="just a comment")
        comment.save()
        self.assertEqual(comment.user().id, self.user.id)
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=None, body="just a comment")
        comment.save()
        self.assertEqual(None, comment.user())

    def test_creating_comment_creates_conversation_for_commentor(self):
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.visitor.id, body="just a comment")
        comment.save()

        new_conversation = Conversation.get("user_id = %s and sharedfile_id = %s", self.visitor.id, self.sharedfile.id)
        self.assertTrue(new_conversation)

    def test_creating_second_comment_doesnt_create_additional_conversation(self):
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.visitor.id, body="just a comment")
        comment.save()
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.visitor.id, body="another comment")
        comment.save()

        new_conversation = Conversation.where("user_id = %s and sharedfile_id = %s", self.visitor.id, self.sharedfile.id)
        self.assertEqual(len(new_conversation), 1)

    def test_creating_comment_creates_conversation_for_sharedfile_owner(self):
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.visitor.id, body="just a comment")
        comment.save()

        new_conversation = Conversation.get("user_id = %s and sharedfile_id = %s", self.user.id, self.sharedfile.id)

        self.assertTrue(new_conversation)

    def test_creating_second_comment_doesnt_create_additional_conversation_for_sharedfile_owner(self):
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.visitor.id, body="just a comment")
        comment.save()

        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.visitor.id, body="another comment")
        comment.save()

        new_conversation = Conversation.where("user_id = %s and sharedfile_id = %s", self.user.id, self.sharedfile.id)
        self.assertEqual(len(new_conversation), 1)

    def test_comment_chopped_body(self):
        """
        Submits some lengthy comments and predicts their responses.
        """
        c_list = [
        """This is a comment <a href="/">With a url</a> in the middle of it.""",
        """











        """,
        """I am a long comment that really doesn't say much. Sorry. It's long and doesn't really add
anything to the conversation.""",
        """I am a long comment that really doesn't say much. Sorry. Good! and doesn't really add
anything to the conversation.""",
        ]


        new_c = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body=c_list[0])
        new_c.save()
        self.assertEqual(new_c.chopped_body(), "This is a comment With a url in the middle of it.")

        new_c = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body=c_list[1])
        new_c.save()
        self.assertEqual(new_c.chopped_body(), "&hellip;")

        new_c = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body=c_list[2])
        new_c.save()
        self.assertEqual(new_c.chopped_body(), "I am a long comment that really doesn't say much. Sorry. It's&hellip;")

        new_c = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body=c_list[3])
        new_c.save()
        self.assertEqual(new_c.chopped_body(), "I am a long comment that really doesn't say much. Sorry. Good!")

    def test_comment_mention_extraction(self):
        user_a = User(name='user_a',email='*****@*****.**',verify_email_token='created',email_confirmed=1, is_paid=1)
        user_a.save()
        user_b = User(name='userb',email='*****@*****.**',verify_email_token='created',email_confirmed=1, is_paid=1)
        user_b.save()
        user_c = User(name='user-c',email='*****@*****.**',verify_email_token='created',email_confirmed=1, is_paid=1)
        user_c.save()
        user_d = User(name='Userd',email='*****@*****.**',verify_email_token='created',email_confirmed=1, is_paid=1)
        user_d.save()

        body = """@thename hey there @user_a,@user_a
            and @userk and @userd and @userB
            @user-cdub also @user-c there."""
        new_c = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body=body)
        mentions = new_c.extract_mentions()
        self.assertEqual(self.user.id, mentions[0].id)
        self.assertEqual(user_a.id, mentions[1].id)
        self.assertEqual(user_b.id, mentions[3].id)
        self.assertEqual(user_c.id, mentions[4].id)
        self.assertEqual(user_d.id, mentions[2].id)
Ejemplo n.º 14
0
class CeleryTaskTests(BaseTestCase):
    def setUp(self):
        super(CeleryTaskTests, self).setUp()  # register connection.

        #create two users.
        self.user_a = User(name='user_a',
                           email='*****@*****.**',
                           verify_email_token='created')
        self.user_a.save()
        self.user_b = User(name='user_b',
                           email='*****@*****.**',
                           verify_email_token='created')
        self.user_b.save()

        #have the second user follow the first
        self.shake_a = Shake.get('user_id = %s and type=%s', self.user_a.id,
                                 'user')
        self.user_b.subscribe(self.shake_a)

        #user one adds two files to their shake
        self.source = Sourcefile(width=20,
                                 height=20,
                                 file_key="asdf",
                                 thumb_key="asdf_t")
        self.source.save()

        self.shared_1 = Sharedfile(source_id=self.source.id, name="my shared file",user_id=self.user_a.id, \
            content_type="image/png", share_key="oj")
        self.shared_1.save()

        self.shared_2 = Sharedfile(source_id=self.source.id, name="my shared file",user_id=self.user_a.id, \
            content_type="image/png", share_key="ok")
        self.shared_2.save()

    def test_task_timeline_add_posts(self):
        """
        this test calls the task directly to see if it inserts items into user b's timeline
        """
        add_posts(shake_id=self.shake_a.id,
                  sharedfile_id=self.shared_1.id,
                  sourcefile_id=self.source.id)
        timeline = Post.get('id = 1')
        self.assertFalse(timeline.seen)

        add_posts(shake_id=self.shake_a.id,
                  sharedfile_id=self.shared_2.id,
                  sourcefile_id=self.source.id)
        timeline = Post.get('id = 2')
        self.assertTrue(timeline.seen)

    def test_task_timeline_delete_posts(self):
        """
        this test calls delete_posts directly to ensure deleted files get marked as deleted
        """
        add_posts(shake_id=self.shake_a.id,
                  sharedfile_id=self.shared_1.id,
                  sourcefile_id=self.source.id)
        add_posts(shake_id=self.shake_a.id,
                  sharedfile_id=self.shared_2.id,
                  sourcefile_id=self.source.id)

        delete_posts(sharedfile_id=self.shared_1.id)
        delete_posts(sharedfile_id=self.shared_2.id)

        posts = Post.all()
        for post in posts:
            self.assertTrue(post.deleted)

    @patch('tweepy.API', MockTweepy.API)
    def test_tweet_best_posts(self):
        old_likes = options.likes_to_tweet
        old_magic = options.likes_to_magic
        old_debug = options.debug
        try:
            options.likes_to_tweet = 1
            options.likes_to_magic = 1
            options.debug = False
            add_posts(shake_id=self.shake_a.id,
                      sharedfile_id=self.shared_1.id,
                      sourcefile_id=self.source.id)
            self.user_b.add_favorite(self.shared_1)
            # this like should trigger a tweet
            self.assertEqual(MockTweepy.count, 1)
            mf = Magicfile.get("sharedfile_id = %s", self.shared_1.id)
            self.assertIsNotNone(mf)
        finally:
            options.likes_to_tweet = old_likes
            options.likes_to_magic = old_magic
            options.debug = old_debug
Ejemplo n.º 15
0
class NotificationModelTests(BaseTestCase):
    def setUp(self):
        """
        Create a user, source and shared file.
        """
        super(NotificationModelTests, self).setUp()
        self.user = User(name='example',
                         email='*****@*****.**',
                         verify_email_token='created',
                         password='******',
                         email_confirmed=1,
                         is_paid=1)
        self.user.save()
        self.user2 = User(name='example2',
                          email='*****@*****.**',
                          verify_email_token='created',
                          password='******',
                          email_confirmed=1,
                          is_paid=1)
        self.user2.save()


        self.sourcefile = Sourcefile(width=20,height=20,file_key="asdf", \
            thumb_key="asdf_t")
        self.sourcefile.save()
        self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=self.user.id, content_type="image/png", share_key="ok")
        self.sharedfile.save()

    def test_new_subscriber_notification(self):
        #generate a notification
        new_sub = Subscription(user_id=self.user2.id, shake_id=1)
        new_sub.save()

        notification = Notification.new_subscriber(sender=self.user2,
                                                   receiver=self.user,
                                                   action_id=new_sub.id)

        sent_notification = Notification.get("id=%s", notification.id)
        self.assertEqual(sent_notification.id, notification.id)
        self.assertEqual(sent_notification.sender_id, self.user2.id)
        self.assertEqual(sent_notification.receiver_id, self.user.id)
        self.assertEqual(sent_notification.action_id, new_sub.id)
        self.assertEqual(sent_notification.type, 'subscriber')

    def test_new_favorite_notification(self):
        notification = Notification.new_favorite(sender=self.user2,
                                                 sharedfile=self.sharedfile)

        sent_notification = Notification.get("id=%s", notification.id)
        self.assertEqual(sent_notification.id, notification.id)
        self.assertEqual(sent_notification.sender_id, self.user2.id)
        self.assertEqual(sent_notification.receiver_id, self.user.id)
        self.assertEqual(sent_notification.action_id, 1)
        self.assertEqual(sent_notification.type, 'favorite')

    def test_deleting_favorite_notification(self):
        notification = Notification.new_favorite(sender=self.user2,
                                                 sharedfile=self.sharedfile)

        sent_notification = Notification.get("id=%s", notification.id)
        sent_notification.delete()
        check_delete_notification = Notification.get("id=%s", notification.id)
        self.assertTrue(check_delete_notification.deleted)

    def test_new_save_notification(self):
        notification = Notification.new_save(sender=self.user2,
                                             sharedfile=self.sharedfile)

        sent_notification = Notification.get("id=%s", notification.id)
        self.assertEqual(sent_notification.id, notification.id)
        self.assertEqual(sent_notification.sender_id, self.user2.id)
        self.assertEqual(sent_notification.receiver_id, self.user.id)
        self.assertEqual(sent_notification.action_id, 1)
        self.assertEqual(sent_notification.type, 'save')

    def test_new_comment_notification(self):
        new_comment = Comment(user_id=self.user2.id,
                              sharedfile_id=self.sharedfile.id,
                              body="Testing comment")
        new_comment.save()

        sent_notification = Notification.get("id=%s", 1)

        self.assertEqual(sent_notification.sender_id, self.user2.id)
        self.assertEqual(sent_notification.receiver_id, self.user.id)
        self.assertEqual(sent_notification.action_id, 1)
        self.assertEqual(sent_notification.type, 'comment')

    def test_new_comment_doesnt_store_for_same_user(self):
        new_comment = Comment(user_id=self.user.id,
                              sharedfile_id=self.sharedfile.id,
                              body="Testing comment")
        new_comment.save()

        sent_notification = Notification.get("id=%s", 1)

        self.assertFalse(sent_notification)
Ejemplo n.º 16
0
class UserModelTests(BaseTestCase):
    def setUp(self):
        """
        Create a user, a source file and a shared file to user in tests.
        """
        super(UserModelTests, self).setUp()
        self.user = User(name='example',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        self.user.save()
        self.sourcefile = Sourcefile(width=20,height=20,file_key="asdf", \
            thumb_key="asdf_t")
        self.sourcefile.save()
        self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=self.user.id, content_type="image/png", share_key="ok")
        self.sharedfile.save()
        self.user_shake = self.user.shake()
        self.sharedfile.add_to_shake(self.user_shake)

    def test_user_uniqueness(self):
        """
        Can't create a user with same user name or email.  Save should return False, no new
        users should be added.
        """
        user = User(name='unique_user',
                    email='*****@*****.**',
                    verify_email_token='created',
                    password='******',
                    email_confirmed=1,
                    is_paid=1)
        user.save()
        users_in_db = User.all("where name = '%s'" % ('unique_user'))
        self.assertEqual(1, len(users_in_db))

        # same name, different email shouldn't save.
        user = User(name='unique_user',
                    email='*****@*****.**',
                    verify_email_token='created',
                    password='******',
                    email_confirmed=1,
                    is_paid=1)
        self.assertFalse(user.save())
        users_in_db = User.all("where name = '%s'" % ('unique_user'))
        self.assertEqual(1, len(users_in_db))

        # same email, different name
        user = User(name='different_name',
                    email='*****@*****.**',
                    verify_email_token='created',
                    password='******',
                    email_confirmed=1,
                    is_paid=1)
        self.assertFalse(user.save())
        users_in_db = User.all("where email = '%s'" %
                               ('*****@*****.**'))
        self.assertEqual(1, len(users_in_db))

        # both different, should save.
        user = User(name='different_name',
                    email='*****@*****.**',
                    verify_email_token='created',
                    password='******',
                    email_confirmed=1,
                    is_paid=1)
        self.assertTrue(user.save())
        users_in_db = User.all("where email = %s and name = %s",
                               '*****@*****.**', 'different_name')
        self.assertEqual(1, len(users_in_db))

    def test_user_password_storage(self):
        """
        Tests that a set of passwords correctly get set as the hashed_password
        """
        options.auth_secret = 'ne4om9og3maw8orp2ot9quos5ed8aj3lam6up3ja'
        passwords = [
            ('asdf1234', 'f9d7082750f934412bb8e86c83432a027f2e92fb'),
            ('k23(jsdjfsdlk'
             'wlkj\nfpbd)', '0ccc0cbce78403de22b5065a81238d9ab0a82f1f'),
            ('$55233234234', '8b57e7ee9feab3d7083debc1f2c97810329ed3bb')
        ]
        for password in passwords:
            u = User(name=self.generate_string_of_len(random.randint(1, 30)),
                     email=self.generate_string_of_len(6) + '@example.com',
                     email_confirmed=1,
                     is_paid=1)
            u.set_and_confirm_password(password[0], password[0])
            u.save()
            self.assertEqual(u.hashed_password, password[1])

    #def test_existing_user_and_password_are_upgraded_to_bcrypt(self):
    #    """
    #    Tests that a set of users with existing hashed password get upgraded on calling authenticate
    #    """
    #    options.auth_secret = 'ne4om9og3maw8orp2ot9quos5ed8aj3lam6up3ja'
    #    passwords = [
    #                    ('asdf1234', 'f9d7082750f934412bb8e86c83432a027f2e92fb'),
    #                    ('k23(jsdjfsdlk''wlkj\nfpbd)', '0ccc0cbce78403de22b5065a81238d9ab0a82f1f'),
    #                    ('$55233234234', '8b57e7ee9feab3d7083debc1f2c97810329ed3bb')
    #                ]
    #    for password in passwords:
    #        this_user = self.generate_string_of_len(random.randint(1,30))
    #        u = User(name=this_user, email=self.generate_string_of_len(6) + '@example.com', email_confirmed=1, is_paid=1)
    #        u.set_and_confirm_password(password[0],password[0])
    #        u.save()
    #        u.authenticate(this_user, password[0])
    #        u = User.get(u.id)
    #        self.assertNotEqual(u.hashed_password, password[1])
    #        #YOU WERE HERE TESTING THAT CALLING AUTH UPGRADES TO BCRYPT

    def test_user_name_is_unique(self):
        name = self.generate_string_of_len(random.randint(1, 30))
        password = self.generate_string_of_len(10)

        first_user = User(name=name,
                          email=self.generate_string_of_len(6) +
                          '@example.com',
                          email_confirmed=1,
                          is_paid=1)
        first_user.set_and_confirm_password(password, password)
        first_user.save()

        second_user = User(name=name,
                           email=self.generate_string_of_len(6) +
                           '@example.com',
                           email_confirmed=1,
                           is_paid=1)
        second_user.set_and_confirm_password(password, password)
        self.assertFalse(second_user.save())

    def test_email_verifier(self):
        invalid_emails = [
            'asdfasd@', 'asdfi [email protected]', 'ijoafd', 'sdfdsfsijof@dslkfj'
        ]
        valid_emails = [
            '*****@*****.**', '*****@*****.**', '*****@*****.**',
            '*****@*****.**', '*****@*****.**'
        ]

        for i_email in invalid_emails:
            invalid_user = User(name=self.generate_string_of_len(
                random.randint(1, 30)),
                                email=i_email,
                                email_confirmed=1,
                                is_paid=1)
            self.assertFalse(invalid_user.save())

        for v_email in valid_emails:
            valid_user = User(name=self.generate_string_of_len(
                random.randint(1, 30)),
                              email=v_email,
                              email_confirmed=1,
                              is_paid=1)
            self.assertTrue(valid_user.save())

    def test_shared_files_count_ignores_deleted(self):
        """
        This test checks that an account with deleted files will not return them in the
        User.sharedfiles() or User.sharedfiles_count() methods
        """
        # User should have one sharedfile have one from the setUp
        self.assertEqual(self.user.sharedfiles_count(), 1)

        missing_ids = []
        for i in range(50):
            sf = Sharedfile(source_id=self.sourcefile.id,
                            user_id=self.user.id,
                            name="shgaredfile.png",
                            title='shared file',
                            share_key='asdf',
                            content_type='image/png')
            sf.save()
            sf.add_to_shake(self.user_shake)
            if i and (50 % i) == 0:  #2 5 10 and 25
                sf.delete()
                missing_ids.append(sf.id)

        self.assertEqual(self.user.sharedfiles_count(), 46)

        users_shared_files = self.user.sharedfiles()
        for f in users_shared_files:
            self.assertTrue(f.id not in missing_ids)

    def test_subscription_timeline_shows_appropriate_images(self):
        """
        We have a user subscribe to the shakes of 2 other users.  The users
        that are being subscribed to have one sharedfile each, both pointing
        to same source file.

        When a user subscribes, his timeline will be populated with last 10
        posts from user being subscribed to.  In this case, timeline will
        suppress dupes.
        """
        user1 = User(name='user', email='*****@*****.**', is_paid=1)
        user1.save()

        source_file = Sourcefile(width=10,
                                 height=10,
                                 file_key='mumbles',
                                 thumb_key='bumbles')
        source_file.save()
        users = ['user2', 'user3', 'user4']
        for name in users:
            user = User(name=name, email='*****@*****.**' % (name), is_paid=1)
            user.save()
            sf = Sharedfile(source_id=source_file.id, user_id = user.id, name='%s file.jpg' % (name), \
                title='%s file' % (name), share_key='%s' % (name), content_type='image/jpg', deleted=0)
            sf.save()
            sf.add_to_shake(user.shake())

        # have user follow two users' shakes
        user2 = User.get('name=%s', 'user2')
        user3 = User.get('name=%s', 'user3')
        user1.subscribe(user2.shake())
        user1.subscribe(user3.shake())

        shared_files = user1.sharedfiles_from_subscriptions()
        self.assertEqual(1, len(shared_files))
        self.assertEqual(shared_files[0].source_id, source_file.id)

        shared_files[0].deleted = 1
        shared_files[0].save()

        # they should no longer see the shared file since it
        # was deleted.
        shared_files = user1.sharedfiles_from_subscriptions()
        self.assertEqual(0, len(shared_files))

    def test_profile_image_url(self):
        """
        If there is no user.profile_image, or set to False, should return the default.

        Otherwise, should return an Amazon URL.
        """
        self.assertEqual(None, self.user.profile_image)
        self.assertEqual('/static/images/default-icon-venti.svg',
                         self.user.profile_image_url())

        self.user.profile_image = False
        self.user.save()
        self.assertEqual('/static/images/default-icon-venti.svg',
                         self.user.profile_image_url())

        self.user.profile_image = True
        self.user.save()
        self.assertEqual(
            1,
            self.user.profile_image_url().count(
                'amazonaws.com/account/1/profile.jpg'))

    def test_add_favorite(self):
        """
        A user should be able to favorite a sharedfile if:
         - it belongs to another user
         - it's not already favorited
         - if it's been favorited, but favorite was "deleted"

        A user shouldn't be able to favorite a sharedfile if they own it.
        """
        # Create new user with their own sharedfile.
        new_user = User(name='newuser',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        new_user.save()
        new_sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=new_user.id, content_type="image/png", share_key="ok")
        new_sharedfile.save()

        # One should be able to favorite another user's sharedfile
        self.assertTrue(self.user.add_favorite(new_sharedfile))
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(1, len(favorites))

        # Can't favorite an already favorited sharedfile.
        self.assertFalse(self.user.add_favorite(new_sharedfile))
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(1, len(favorites))

        # A favorite with "deleted" flag set, should have flag unset and
        # return True when add_favorite called
        favorite = Favorite.get("user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        favorite.deleted = True
        favorite.save()
        self.assertTrue(self.user.add_favorite(new_sharedfile))
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(1, len(favorites))

        # Can't favorite one's own sharedfile.
        self.assertTrue(self.sharedfile.user_id, self.user.id)
        self.assertFalse(self.user.add_favorite(self.sharedfile))
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, self.sharedfile.id)
        self.assertEqual(0, len(favorites))

    def test_add_favorite_deleted_sharedfile(self):
        """
        User.add_favorite should return False if sharedfile is deleted
        and no Favorite entries should be logged.
        """
        # Create new user with their own sharedfile.
        new_user = User(name='newuser',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        new_user.save()
        new_sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=new_user.id, content_type="image/png", share_key="ok")
        new_sharedfile.save()

        new_sharedfile.delete()
        self.assertFalse(self.user.add_favorite(new_sharedfile))
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(0, len(favorites))

    def test_remove_favorite(self):
        """
        User.remove_favorite should return False if the sharedfile has never been favorited or
        has been removed.

        Should return true if removing favorite succeeds
        """
        # Create new user with their own sharedfile.
        new_user = User(name='newuser',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        new_user.save()
        new_sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=new_user.id, content_type="image/png", share_key="ok")
        new_sharedfile.save()

        # remove_favorite should return false when sharedfile not already favorited.
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(0, len(favorites))
        self.assertFalse(self.user.remove_favorite(new_sharedfile))

        # remove_favorite should return True when unfavoring succeeds, deleted
        # flag on Favorite should be set to 0.  Should return false on a subsequent
        # attempt on remove_favorite
        self.user.add_favorite(new_sharedfile)
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(1, len(favorites))
        self.assertTrue(self.user.remove_favorite(new_sharedfile))
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(0, len(favorites))

        # remove_favorite on deleted favorite should return False.
        favorites = Favorite.all("where user_id = %s and sharedfile_id = %s and deleted = 1", \
            self.user.id, new_sharedfile.id)
        self.assertEqual(1, len(favorites))
        self.assertFalse(self.user.remove_favorite(new_sharedfile))

    def test_has_favorite(self):
        """
        User.has_favorite should return True if a user has favorited a file.  Should return
        False if no entry exists, or if entry is marked as "deleted"
        """
        # Create new user with their own sharedfile.
        new_user = User(name='newuser',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        new_user.save()
        new_sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=new_user.id, content_type="image/png", share_key="ok")
        new_sharedfile.save()

        self.assertFalse(self.user.has_favorite(new_sharedfile))
        self.user.add_favorite(new_sharedfile)
        self.assertTrue(self.user.has_favorite(new_sharedfile))

        favorite = Favorite.get("user_id = %s and sharedfile_id = %s and deleted = 0", \
            self.user.id, new_sharedfile.id)
        favorite.deleted = True
        favorite.save()
        self.assertFalse(self.user.has_favorite(new_sharedfile))

    def test_saved_sharedfile(self):
        """
        User.saved_sharedfile should return None if no
        sharedfile saved, otherwisew will return the sharedfile
        if it was saved by user.  If more than one shardfile saved
        by user, it will still return 1.
        """
        # Create new user to be doing the saving, and its own sharedfile.
        new_user = User(name='newuser',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        new_user.save()

        self.assertEqual(None, new_user.saved_sharedfile(self.sharedfile))
        self.sharedfile.save_to_shake(new_user)
        # check to make sure we get a Sharedfile object back, not None
        self.assertEqual(type(self.sharedfile),
                         type(new_user.saved_sharedfile(self.sharedfile)))
        # save another file to user
        self.sharedfile.save_to_shake(new_user)
        self.assertEqual(type(self.sharedfile),
                         type(new_user.saved_sharedfile(self.sharedfile)))

    def test_use_invitation(self):
        """
        user.send_invitation() should send two invitations out and create them with messages saying they are from
        that user.
        """
        self.user.add_invitations(5)

        self.user.send_invitation('*****@*****.**')
        self.user.send_invitation('*****@*****.**')

        self.assertEqual(self.user.invitation_count, 3)

        invitations_sent = invitation.Invitation.all()
        self.assertEqual(len(invitations_sent), 2)
        for i in invitations_sent:
            self.assertEqual(i.user_id, self.user.id)
            self.assertTrue(
                i.email_address in ['*****@*****.**', '*****@*****.**'])

    def test_flag_nsfw(self):
        """
        User.flag_nsfw flag should set the nsfw field to 1 in DB.
        """
        self.assertEqual(self.user.nsfw, False)
        self.user.flag_nsfw()
        fetched_user = User.get('id = %s', self.user.id)
        self.assertEqual(self.user.nsfw, True)

    def test_unflag_nsfw(self):
        """
        User.unflag_nsfw should set the nsfw field to 0 in DB.
        """
        self.user.nsfw = True
        self.user.save()
        fetched_user = User.get('id = %s', self.user.id)
        self.assertEqual(self.user.nsfw, True)
        self.user.unflag_nsfw()
        fetched_user = User.get('id = %s', self.user.id)
        self.assertEqual(self.user.nsfw, False)

    def test_shakes_method_returns_managed_and_owned(self):
        """
        Tests that the shakes method returns the correct shake counts
        when called with managed and without.
        """

        #a new person with a shake
        shake_owner = User(name='user1',
                           email='*****@*****.**',
                           email_confirmed=1,
                           is_paid=1)
        shake_owner.set_password('asdfasdf')
        shake_owner.save()
        group_shake = shake_owner.create_group_shake(title='asdf',
                                                     name='asdf',
                                                     description='adsf')

        personal_shake = self.user.create_group_shake(title='qwer',
                                                      name='qwer',
                                                      description='qwer')

        #here's the cool part
        group_shake.add_manager(self.user)

        shakes_managed = self.user.shakes(include_managed=True)
        self.assertEqual(len(shakes_managed), 3)

        shakes_owned = self.user.shakes()
        self.assertEqual(len(shakes_owned), 2)
        self.assertEqual(shakes_owned[0].type, 'user')
        self.assertEqual(shakes_owned[1].type, 'group')

    def test_cannot_upload_if_over_file_upload_limit_unpaid(self):
        """
        Tests whether a user can upload a file if they are over the limit for this month.
        """
        self.user.stripe_plan_id = "mltshp-single"
        self.user.save()

        file_name = 'red.gif'
        file_content_type = 'image/gif'
        file_path = os.path.abspath("test/files/%s" % (file_name))
        file_sha1 = Sourcefile.get_sha1_file_key(file_path)

        sf = Sharedfile.create_from_file(file_path=file_path,
                                         file_name=file_name,
                                         sha1_value=file_sha1,
                                         content_type=file_content_type,
                                         user_id=self.user.id)
        sf.size = 410000000
        sf.save()

        self.assertFalse(self.user.can_upload_this_month())

    def test_can_upload_if_over_file_upload_limit_paid(self):
        """
        Tests whether a user can upload a file if they are over the limit and have paid
        for the double scoop plan.
        """
        self.user.stripe_plan_id = "mltshp-double"
        self.user.save()

        file_name = 'red.gif'
        file_content_type = 'image/gif'
        file_path = os.path.abspath("test/files/%s" % (file_name))
        file_sha1 = Sourcefile.get_sha1_file_key(file_path)

        sf = Sharedfile.create_from_file(file_path=file_path,
                                         file_name=file_name,
                                         sha1_value=file_sha1,
                                         content_type=file_content_type,
                                         user_id=self.user.id)
        sf.size = 310000000
        sf.save()

        self.assertTrue(self.user.can_upload_this_month())

    def test_total_file_count_for_this_month(self):
        """
        tests that the current amount of new files uploaded for the current month is correct
        """
        images = ['red.gif', 'blue.gif', 'green.gif', 'love.gif']
        for image in images:
            file_name = image
            file_content_type = 'image/gif'
            file_path = os.path.abspath("test/files/%s" % (file_name))
            file_sha1 = Sourcefile.get_sha1_file_key(file_path)

            sf = Sharedfile.create_from_file(file_path=file_path,
                                             file_name=file_name,
                                             sha1_value=file_sha1,
                                             content_type=file_content_type,
                                             user_id=self.user.id)

        month_days = calendar.monthrange(datetime.utcnow().year,
                                         datetime.utcnow().month)
        start_time = datetime.utcnow().strftime("%Y-%m-01")
        end_time = datetime.utcnow().strftime("%Y-%m-" + str(month_days[1]))

        self.assertEqual(
            self.user.uploaded_kilobytes(start_time=start_time,
                                         end_time=end_time), 72)

    def test_is_admin(self):
        """
        Only user's with the name admin should return True when User.is_admin is called.
        """
        admin = User(name='admin',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        admin.save()
        someone_else = User(name='someoneelse',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        someone_else.save()
        self.assertTrue(admin.is_admin())
        self.assertFalse(someone_else.is_admin())

    def test_find_by_name_fragment(self):
        """
        User.find_by_name_fragment should return empty array
        if None or '' is passed in.  Otherwise, should search and find
        usernames.
        """
        admin = User(name='admin',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        admin.save()
        another_user = User(name='another',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, is_paid=1)
        another_user.save()

        self.assertEqual([], User.find_by_name_fragment('nothing'))
        self.assertEqual([], User.find_by_name_fragment())

        self.assertEqual(2, len(User.find_by_name_fragment('a')))
        self.assertEqual('admin', User.find_by_name_fragment('ad')[0].name)

        # test limit
        self.assertEqual(1, len(User.find_by_name_fragment('a', limit=1)))

    def test_user_delete(self):
        self.user.create_group_shake(title='balrag',
                                     name="blahr",
                                     description="affafa")

        another_user = User(name='example2',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1, paid=1)
        another_user.save()
        new_group_shake = another_user.create_group_shake(title='weiurywiuer',
                                                          name="werqwerew",
                                                          description="affafa")

        self.user.subscribe_to_user(another_user)

        new_group_shake.add_manager(self.user)

        self.user.delete()
        user = User.get('name=%s', 'example')
        self.assertEqual(user.email, '*****@*****.**' % (user.id))
        self.assertEqual(user.hashed_password, 'deleteduseracct')
        self.assertEqual(user.about, '')
        self.assertEqual(user.website, '')
        self.assertEqual(user.nsfw, 1)
        self.assertEqual(user.recommended, 0)
        self.assertEqual(user.is_paid, 1)
        self.assertEqual(user.deleted, 1)
        self.assertEqual(user.verify_email_token, 'deleted')
        self.assertEqual(user.reset_password_token, 'deleted')
        self.assertEqual(user.profile_image, 0)
        self.assertEqual(user.disable_notifications, 1)
        self.assertEqual(user.invitation_count, 0)

        shared_files = Sharedfile.all()
        for shared_file in shared_files:
            self.assertEqual(shared_file.deleted, 1)

        ssfs = Shakesharedfile.all()
        for ssf in ssfs:
            self.assertEqual(ssf.deleted, 1)

        subscriptions = Subscription.where("user_id = %s", self.user.id)
        for sub in subscriptions:
            self.assertEqual(sub.deleted, 1)

        managing = ShakeManager.where("user_id = %s", self.user.id)
        for m in managing:
            self.assertEqual(m.deleted, 1)
Ejemplo n.º 17
0
class CommentTests(BaseAsyncTestCase):
    def setUp(self):
        super(CommentTests, self).setUp()
        self.admin = User(name='admin',
                          email='*****@*****.**',
                          email_confirmed=1,
                          is_paid=1)
        self.admin.set_password('asdfasdf')
        self.admin.save()
        self.sid = self.sign_in('admin', 'asdfasdf')
        self.xsrf = self.get_xsrf()
        self.flake = str(time.time())
        self.src = Sourcefile(width=1,
                              height=1,
                              file_key='asdf',
                              thumb_key='qwer')
        self.src.save()
        self.shf = Sharedfile(source_id=self.src.id,
                              user_id=self.admin.id,
                              name='shared.jpg',
                              title='shared',
                              share_key='1',
                              content_type='image/jpg')
        self.shf.save()

    def test_saving_a_comment_is_stored(self):
        #submit a comment to /share_key/save_comment
        body = """This is a comment.

        A multi-line comment.&amp;

        That is all.&_xsrf=asdf
        """
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape(body), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        comments = self.shf.comments()
        self.assertEqual(len(comments), 1)
        self.assertEqual(comments[0].body, body.strip())

    def test_blank_comment_doesnt_save(self):
        body = ""
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape(body), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        comments = self.shf.comments()
        self.assertEqual(len(comments), 0)

    def test_saving_an_empty_comment_not_stored(self):
        #submit a comment to /share_key/save_comment
        body = """
        """
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape(body), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        comments = self.shf.comments()
        self.assertEqual(len(comments), 0)

    def test_saving_not_signed_in_not_stored(self):
        #submit a comment to /share_key/save_comment
        body = """
        This is a comment.
        """
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s' % (self.xsrf)},
            "body=%s&_xsrf=%s" % (url_escape(body), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        comments = self.shf.comments()
        self.assertEqual(len(comments), 0)
Ejemplo n.º 18
0
class AccountTests(test.base.BaseAsyncTestCase):
    def setUp(self):
        super(AccountTests, self).setUp()
        self.user = User(name='admin',
                         email='*****@*****.**',
                         email_confirmed=1,
                         is_paid=1)
        self.user.set_password('asdfasdf')
        self.user.save()
        self.sign_in("admin", "asdfasdf")

    def test_user_paid_account_rss_works(self):
        sourcefile = Sourcefile(width=20,
                                height=20,
                                file_key="asdf",
                                thumb_key="asdf_t")
        sourcefile.save()
        sharedfile = Sharedfile(source_id=sourcefile.id, name="the name",user_id=self.user.id, \
            content_type="image/png", description="description", source_url="https://www.mltshp.com/?hi")
        sharedfile.save()
        sharedfile.share_key = lib.utilities.base36encode(sharedfile.id)
        sharedfile.save()

        sharedfile.add_to_shake(self.user.shake())

        response = self.fetch_url('/user/admin/rss')
        self.assertEqual(response.headers['Content-Type'], 'application/xml')
        parsed_xml = lib.utilities.parse_xml(response.body)
        self.assertEqual(parsed_xml['rss']['channel']['item']['link'],
                         'https://mltshp.com/p/1')

    def test_user_unpaid_account_rss_404s(self):
        self.user.update_attribute("is_paid", 0)
        self.user.save()

        response = self.fetch_url('/user/admin/rss')
        self.assertEqual(response.code, 404)

    def test_like_save_view_count_is_returned(self):
        sharedfile = test.factories.sharedfile(self.user,
                                               view_count=25,
                                               save_count=50,
                                               like_count=100)
        response = self.fetch_url('/user/%s/counts' % self.user.name)
        j_response = json_decode(response.body)
        self.assertEqual(j_response['likes'], 100)
        self.assertEqual(j_response['saves'], 50)
        self.assertEqual(j_response['views'], 25)

    def test_email_not_confirmed_puts_notice_at_top(self):
        self.user.email_confirmed = 0
        self.user.save()

        response = self.fetch_url('/')
        self.assertTrue(
            response.body.find('Please visit settings to confirm your email!')
            > -1)

        response = self.fetch_url('/incoming')
        self.assertTrue(
            response.body.find('Please visit settings to confirm your email!')
            > -1)

        response = self.fetch_url('/friends')
        self.assertTrue(
            response.body.find('Please visit settings to confirm your email!')
            > -1)

    def test_quick_notifications(self):
        """
        /account/quick-notifications should return without error when populated with
        all possible  notification types.

        Page should also not be accessible if you're not signed in.
        """
        self.user2 = User(name='example2',email='*****@*****.**', \
            verify_email_token = 'created', password='******', email_confirmed=1,
            is_paid=1)
        self.user2.save()
        self.sourcefile = Sourcefile(width=20,height=20,file_key="asdf", \
            thumb_key="asdf_t")
        self.sourcefile.save()
        self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file", \
            user_id=self.user.id, content_type="image/png", share_key="ok")
        self.sharedfile.save()
        self.shake = Shake(user_id=self.user2.id,
                           name='asdf',
                           type='group',
                           title='My Test Shake',
                           description='Testing this shake test.')
        self.shake.save()

        # new subscription
        new_sub = Subscription(user_id=self.user2.id, shake_id=1)
        new_sub.save()
        new_subscriber = Notification.new_subscriber(sender=self.user2,
                                                     receiver=self.user,
                                                     action_id=new_sub.id)
        # new favorite
        new_favorite = Notification.new_favorite(sender=self.user2,
                                                 sharedfile=self.sharedfile)
        # new save
        new_save = Notification.new_save(sender=self.user2,
                                         sharedfile=self.sharedfile)
        # new comment
        new_comment = Comment(user_id=self.user2.id,
                              sharedfile_id=self.sharedfile.id,
                              body="Testing comment")
        new_comment.save()
        # new mention
        new_mention = Notification.new_mention(receiver=self.user,
                                               comment=new_comment)
        # new invitation
        new_mention = Notification.new_invitation(sender=self.user2,
                                                  receiver=self.user,
                                                  action_id=self.shake.id)

        response = self.fetch_url('/account/quick-notifications')
        self.assertEqual(200, response.code)
        self.sign_out()
        response = self.fetch_url('/account/quick-notifications',
                                  follow_redirects=False)
        self.assertEqual(302, response.code)
Ejemplo n.º 19
0
class SourcefileModelTests(BaseTestCase):
    def setUp(self):
        """
        Create a user sourcefile and sharedfile to work with.
        """
        super(SourcefileModelTests, self).setUp()  # register connection.
        self.user = User(name='thename',
                         email='*****@*****.**',
                         verify_email_token='created',
                         email_confirmed=0,
                         is_paid=1)
        self.user.save()
        self.sourcefile = Sourcefile(width=20,
                                     height=20,
                                     file_key="asdf",
                                     thumb_key="asdf_t")
        self.sourcefile.save()
        self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
            content_type="image/png", share_key="ok")
        self.sharedfile.save()

    def testGetByShareKey(self):
        existing_source_file = Sourcefile.get_by_file_key('asdf')
        self.assertEqual(self.sourcefile.id, existing_source_file.id)

    def test_sha1_file_encoding(self):
        sha1_key = Sourcefile.get_sha1_file_key(
            os.path.join(os.path.dirname(os.path.dirname(__file__)),
                         "files/love.gif"))
        self.assertEqual("ac7180f6b038d5ae4f2297989e39a900995bb8fc", sha1_key)

    def test_make_oembed_url(self):
        v_urls = [
            'https://vimeo.com/7100569',
            'https://www.youtube.com/watch?v=bDOYN-6gdRE'
        ]
        o_encoded = [
            'https://vimeo.com/api/oembed.json?url=https%3A%2F%2Fvimeo.com%2F7100569&maxwidth=550',
            'https://www.youtube.com/oembed?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DbDOYN-6gdRE&maxwidth=550&format=json'
        ]

        oembed_url = Sourcefile.make_oembed_url(v_urls[0])
        self.assertEqual(oembed_url, o_encoded[0])
        oembed_url = Sourcefile.make_oembed_url(v_urls[1])
        self.assertEqual(oembed_url, o_encoded[1])

    def test_fail_to_make_oembed_url(self):
        bad_urls = [
            'http://cnn.com/7100569', 'http://www.waxy.org/watch?v=bDOYN-6gdRE'
        ]
        for url in bad_urls:
            self.assertEqual(Sourcefile.make_oembed_url(url), None)

    def test_create_from_json_oembed(self):
        o_encoded = [
            'https://vimeo.com/api/oembed.json?url=https%3A%2F%2Fvimeo.com%2F7100569',
            'https://www.youtube.com/oembed?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DbDOYN-6gdRE&format=json&maxwidth=550'
        ]
        #get each url
        #and
        #
        test_responses = [
            r'{"provider_url": "https:\/\/www.youtube.com\/", "title": "Auto-Tune the News #8: dragons. geese. Michael Vick. (ft. T-Pain)", "html": "<object width=\"425\" height=\"344\"><param name=\"movie\" value=\"https:\/\/www.youtube.com\/e\/bDOYN-6gdRE\"><\/param><param name=\"allowFullScreen\" value=\"true\"><\/param><param name=\"allowscriptaccess\" value=\"always\"><\/param><embed src=\"https:\/\/www.youtube.com\/e\/bDOYN-6gdRE\" type=\"application\/x-shockwave-flash\" width=\"425\" height=\"344\" allowscriptaccess=\"always\" allowfullscreen=\"true\"><\/embed><\/object>", "author_name": "schmoyoho", "height": 344, "thumbnail_width": 480, "width": 425, "version": "1.0", "author_url": "https:\/\/www.youtube.com\/user\/schmoyoho", "provider_name": "YouTube", "thumbnail_url": "http:\/\/i3.ytimg.com\/vi\/bDOYN-6gdRE\/hqdefault.jpg", "type": "video", "thumbnail_height": 360}',
            r'{"type":"video","version":"1.0","provider_name":"Vimeo","provider_url":"https:\/\/vimeo.com\/","title":"Brad!","author_name":"Casey Donahue","author_url":"https:\/\/vimeo.com\/caseydonahue","is_plus":"1","html":"<iframe src=\"https:\/\/player.vimeo.com\/video\/7100569\" width=\"1280\" height=\"720\" frameborder=\"0\"><\/iframe>","width":"1280","height":"720","duration":"118","description":"Brad finally gets the attention he deserves.","thumbnail_url":"http:\/\/b.vimeocdn.com\/ts\/294\/128\/29412830_1280.jpg","thumbnail_width":1280,"thumbnail_height":720,"video_id":"7100569"}',
        ]
        for response in test_responses:
            Sourcefile.create_from_json_oembed(response)
Ejemplo n.º 20
0
    def test_rss_feed_works(self):
        """
        Testing that the RSS feed works.
        """
        self.user.stripe_plan_id = "mltshp-double"
        self.user.save()

        arguments = {
            'name': 'yo',
            'description': 'My little corner of the world',
            'title': 'title'
        }
        response = self.post_url('/shake/create', arguments=arguments)
        s = Shake.get('name=%s', 'yo')
        #create a shared file and source file
        sourcefile = Sourcefile(width=20,
                                height=20,
                                file_key="asdf",
                                thumb_key="asdf_t")
        sourcefile.save()
        sharedfile = Sharedfile(source_id=sourcefile.id, name="the name",user_id=self.user.id, \
            content_type="image/png", description="description", source_url="https://www.mltshp.com/?hi")
        sharedfile.save()
        sharedfile.share_key = lib.utilities.base36encode(sharedfile.id)
        sharedfile.save()
        sharedfile.add_to_shake(s)

        #create a shared file video
        x = json_encode({
            "provider_url":
            "https://www.youtube.com/",
            "version":
            "1.0",
            "title":
            "YouTube iFrame Embed Option",
            "type":
            "video",
            "thumbnail_width":
            480,
            "height":
            334,
            "width":
            550,
            "html":
            "<iframe class=\"youtube-player\" type=\"text/html\" width=\"550\" height=\"334\" src=\"https://www.youtube.com/embed/NtzDtV2Jbk8?rnd=0.277468004525&autoplay=0\" frameborder=\"0\" id=\"ytframe\"></iframe>",
            "author_name":
            "jameslawsonsmith",
            "provider_name":
            "YouTube",
            "thumbnail_url":
            "http://i3.ytimg.com/vi/NtzDtV2Jbk8/hqdefault.jpg",
            "thumbnail_height":
            360,
            "author_url":
            "https://www.youtube.com/user/jameslawsonsmith"
        })
        sourcefile = Sourcefile(width=480,
                                height=620,
                                file_key="qwer",
                                thumb_key="qwer_t",
                                type="link",
                                data=x)
        sourcefile.save()
        sharedfile = Sharedfile(source_id=sourcefile.id, name="another name", user_id=self.user.id, \
            content_type="text/html", description="description", source_url="https://www.youtube.com/watch?v=EmcMG4uxiHk")
        sharedfile.save()
        sharedfile.share_key = lib.utilities.base36encode(sharedfile.id)
        sharedfile.save()
        sharedfile.add_to_shake(s)

        response = self.fetch_url('/shake/yo/rss')
        self.assertEqual(response.headers['Content-Type'], 'application/xml')
        parsed_xml = lib.utilities.parse_xml(response.body)
        self.assertEqual(parsed_xml['rss']['channel']['item']['link'],
                         'https://mltshp.com/p/1')
Ejemplo n.º 21
0
class ConversationTests(test.base.BaseAsyncTestCase):
    def setUp(self):
        super(ConversationTests, self).setUp()
        self.admin = User(name='admin',
                          email='*****@*****.**',
                          email_confirmed=1,
                          is_paid=1)
        self.admin.set_password('asdfasdf')
        self.admin.save()

        self.user2 = User(name='user2',
                          email='*****@*****.**',
                          email_confirmed=1,
                          is_paid=1)
        self.user2.set_password('asdfasdf')
        self.user2.save()

        self.sid = self.sign_in('user2', 'asdfasdf')
        self.xsrf = self.get_xsrf()

        self.src = Sourcefile(width=1,
                              height=1,
                              file_key='asdf',
                              thumb_key='qwer')
        self.src.save()
        self.shf = Sharedfile(source_id=self.src.id,
                              user_id=self.admin.id,
                              name='shared.jpg',
                              title='shared',
                              share_key='1',
                              content_type='image/jpg')
        self.shf.save()

    def test_creating_a_new_comment_creates_a_conversation(self):
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape("a comment"), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        conversations = Conversation.all()
        self.assertEqual(len(conversations), 2)

    def test_creating_a_new_comment_does_not_create_a_duplicate_conversation(
            self):
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape("a comment"), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape("a second comment"), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        conversations = Conversation.all()
        self.assertEqual(len(conversations), 2)

    def test_another_user_commenting_will_update_the_files_activity_at(self):
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape("a comment"), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        time.sleep(1)

        sf = Sharedfile.get('id=%s', self.shf.id)
        activity_one = sf.activity_at

        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape("a second comment"), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        sf = Sharedfile.get('id=%s', self.shf.id)
        activity_two = sf.activity_at

        self.assertTrue(activity_two > activity_one)

    def test_deleting_a_file_will_set_conversation_to_muted(self):
        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape("a comment"), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        request = HTTPRequest(
            self.get_url('/p/%s/comment' % self.shf.share_key), 'POST',
            {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "body=%s&_xsrf=%s" % (url_escape("a second comment"), self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        self.shf.delete()

        conversations = Conversation.all()
        self.assertEqual(conversations[0].muted, 1)
        self.assertEqual(conversations[1].muted, 1)

    def test_muting_conversation(self):
        """
        Add a comment, which will create a conversation for the commenter (user2) and sharedfile owner (admin).
                
        When user2 tries to mute admin's conversation, it should fail and admin's conversation state will remain 
        unchanged.  When muting own converastion, "muted" flag should change to true.
        
        Contingent on user2 being signed in. (see setUp)
        """
        comment = Comment(sharedfile_id=self.shf.id,
                          user_id=self.user2.id,
                          body='test')
        comment.save()

        admin_conversation = Conversation.get('user_id = %s', self.admin.id)
        user2_conversation = Conversation.get('user_id = %s', self.user2.id)
        self.assertEqual(admin_conversation.muted, 0)
        self.assertEqual(user2_conversation.muted, 0)

        request = HTTPRequest(
            self.get_url('/conversations/%s/mute' % admin_conversation.id),
            'POST', {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "_xsrf=%s" % (self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()
        request = HTTPRequest(
            self.get_url('/conversations/%s/mute' % user2_conversation.id),
            'POST', {'Cookie': '_xsrf=%s;sid=%s' % (self.xsrf, self.sid)},
            "_xsrf=%s" % (self.xsrf))
        self.http_client.fetch(request, self.stop)
        response = self.wait()

        # refetch from DB, and verify mute flags remain 0.
        admin_conversation = Conversation.get('user_id = %s', self.admin.id)
        user2_conversation = Conversation.get('user_id = %s', self.user2.id)
        self.assertEqual(admin_conversation.muted, 0)
        self.assertEqual(user2_conversation.muted, 1)

    def test_order_of_conversations_changes_when_new_comment_is_created(self):
        pass
Ejemplo n.º 22
0
class SharedfileModelTests(BaseTestCase):

    def setUp(self):
        """
        Create a user sourcefile and sharedfile to work with.
        """
        super(SharedfileModelTests, self).setUp() # register connection.
        self.user = User(name='thename',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        self.user.set_password('pass')
        self.user.save()
        self.sourcefile = Sourcefile(width=20,height=20,file_key="asdf",thumb_key="asdf_t")
        self.sourcefile.save()
        self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
            content_type="image/png", share_key="1", description="some\ndescription\nhere", source_url="http://www.mltshp.com/?hi")
        self.sharedfile.save()

    def test_file_size_is_saved_in_newly_uploaded_file(self):
        """
        Tests that a brand new file upload saves the file size
        """
        file_name = '1.png'
        file_content_type = 'image/png'
        file_path = os.path.abspath("test/files/1.png")
        file_sha1 = Sourcefile.get_sha1_file_key(file_path)
        file_size = os.path.getsize(file_path)

        sf = Sharedfile.create_from_file(
            file_path = file_path,
            file_name = file_name,
            sha1_value = file_sha1,
            content_type = file_content_type,
            user_id = self.user.id)
        self.assertEqual(sf.size, 69)

    def test_file_size_is_not_saved_in_a_simple_share(self):
        """
        Tests that just saving a file does not create a file size record
        """
        new_user = User(name='newguy',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user.set_password('pass')
        new_user.save()

        new_sharedfile = self.sharedfile.save_to_shake(new_user)
        self.assertEqual(new_sharedfile.size, 0)

    def test_attributes_are_saved(self):
        """
        Just a test to check that description and source-url are being saved.
        """
        sf = Sharedfile.get('id=1')
        self.assertEqual(sf.description, "some\ndescription\nhere")
        self.assertEqual(sf.source_url, "http://www.mltshp.com/?hi")

    def test_can_save(self):
        """
        A Sharedfile not owned by the user should be be saveable.
        If a Sharedfile already belongs to user, should not be saveable.
        Sharedfile.can_save should return False when no user specified.
        """
        self.assertFalse(self.sharedfile.can_save(self.user))
        user = User(name='newuser',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        user.save()
        self.assertTrue(self.sharedfile.can_save(user))
        self.assertFalse(self.sharedfile.can_save(None))
        self.assertFalse(self.sharedfile.can_save())

    def test_can_delete(self):
        """
        A Sharedfile should only be deletable if belongs to the user.
        Sharedfile.can_delete should return False when no user specified.
        """
        new_user = User(name='thename',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user.save()
        self.assertEqual(self.user.id, self.sharedfile.user_id)
        self.assertTrue(self.sharedfile.can_delete(self.user))
        self.assertFalse(self.sharedfile.can_delete(new_user))
        self.assertFalse(self.sharedfile.can_delete(None))
        self.assertFalse(self.sharedfile.can_delete())

    def test_can_favor(self):
        """
        A Sharedfile is favorable if it doesn't belong to the user and
        it has not been favorited in the past.
        Sharedfile.can_save should return False when no user specified.
        """
        self.assertFalse(self.sharedfile.can_favor(self.user))

        # Create a new shared file that doesn't belong to user.
        new_user = User(name='new_email',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user.save()
        self.assertTrue(self.sharedfile.can_favor(new_user))
        new_user.add_favorite(self.sharedfile)
        self.assertFalse(self.sharedfile.can_favor(new_user))

        self.assertFalse(self.sharedfile.can_favor(None))
        self.assertFalse(self.sharedfile.can_favor())

    def test_can_unfavor(self):
        """
        Sharedfile.can_unfavor only if the Sharedfile is already favorited.

        Should return False if no user is passed in, or never been favorited
        in the first place.
        """
        # Create a new shared file that doesn't belong to user.
        new_user = User(name='new_email',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user.save()
        self.assertFalse(self.sharedfile.can_unfavor(new_user))
        new_user.add_favorite(self.sharedfile)
        self.assertTrue(self.sharedfile.can_unfavor(new_user))

        self.assertFalse(self.sharedfile.can_unfavor(None))
        self.assertFalse(self.sharedfile.can_unfavor())

    def test_can_edit(self):
        """
        Sharedfile.can_edit should return True only if Sharedfile belongs to user

        Should return false if no user is passed in.
        """
        self.assertEqual(self.sharedfile.user_id, self.user.id)
        self.assertTrue(self.sharedfile.can_edit(self.user))
        new_user = User(name='new_email',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user.save()
        self.assertFalse(self.sharedfile.can_edit(new_user))

        self.assertFalse(self.sharedfile.can_edit(None))
        self.assertFalse(self.sharedfile.can_edit())


    def test_save_file_to_user(self):
        """
        When saving file to another user, it creates an exact copy of sharedfile with following conditions:

         * id, user_id and share_key will be different.
         * name, content_type and source_id should be the same.
         * parent_id should point to original sharedfile's id
         * original_id should point to the shared file id if it was 0 (in this case it is)
         * user id of new file should belong to new user.

        Returns an instance of the new shared file.
        """
        user = User(name='newuser',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        user.save()
        new_file = self.sharedfile.save_to_shake(user)

        # make sure id is not None, meaning it's saved.
        self.assertNotEqual(new_file.id, None)

        # id is not the same as old id (pretty impossible)
        self.assertNotEqual(new_file.id, self.sharedfile.id)
        self.assertNotEqual(new_file.share_key, self.sharedfile.share_key)

        # original_id should be the id of the share it was saved from
        # since that was the original share
        self.assertEqual(new_file.original_id, self.sharedfile.id)

        # User id of new file should be user id of user it's saved to.
        self.assertEqual(new_file.user_id, user.id)

        self.assertEqual(new_file.name, self.sharedfile.name)
        self.assertEqual(new_file.content_type, self.sharedfile.content_type)
        self.assertEqual(new_file.source_id, self.sharedfile.source_id)

        # parent_shared_file_id should point to original
        self.assertEqual(new_file.parent_id, self.sharedfile.id)

        #final test, a share of a share needs to still point to original_id of the first share
        user = User(name='anotheruser',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        user.save()
        newer_file = new_file.save_to_shake(user)

        self.assertEqual(newer_file.parent_id, new_file.id)
        self.assertEqual(newer_file.original_id, self.sharedfile.id)

    def test_parent(self):
        new_sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
            content_type="image/png", share_key="another_share_key", parent_id=self.sharedfile.id)
        new_sharedfile.save()
        parent = new_sharedfile.parent()
        self.assertEqual(parent.id, self.sharedfile.id)

    def test_parent_user(self):
        """
        Creates new user and sharedfile, pointing to the sharedfile in setUp.
        """
        user = User(name='anewusername',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        user.save()
        new_sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=user.id, \
            content_type="image/png", share_key="another_share_key", parent_id=self.sharedfile.id)
        new_sharedfile.save()
        parent_user = new_sharedfile.parent_user()
        self.assertEqual(parent_user.id, self.sharedfile.user_id)

    def test_source_file(self):
        """
        The Sourcefile object returned should match the one we associated.
        """
        fetched_sourcefile = self.sharedfile.sourcefile()
        self.assertEqual(fetched_sourcefile.id, self.sourcefile.id)

    def test_user(self):
        """
        The User object returned should match the one we associated.
        """
        fetched_user = self.sharedfile.user()
        self.assertEqual(fetched_user.id, self.user.id)

    def test_get_by_share_key(self):
        """
        The Sharedfile object should match the object with the same share_key created in setUp.
        """
        fetched_sharedfile = Sharedfile.get_by_share_key("1")
        self.assertEqual(fetched_sharedfile.id, self.sharedfile.id)

    def test_get_by_share_key_deleted(self):
        """
        If sharedfile is deleted should not be returned by get_by_share_key().
        """
        self.sharedfile.delete()
        fetched_sharedfile = Sharedfile.get_by_share_key("ok")
        self.assertEqual(fetched_sharedfile, None)

    def test_saving_sets_the_created_and_updated_at(self):
        """
        When we saved sharedfile, it's created and updated_at should be set in UTC.
        We check the date to make sure it's within last 5 seconds.
        """
        created_at =  self.sharedfile.created_at
        updated_at = self.sharedfile.updated_at
        five_seconds = timedelta(seconds=5)
        if (datetime.utcnow() - created_at) < five_seconds:
            created_at_is_recent = True
        else:
            created_at_is_recent = False
        self.assertTrue(created_at_is_recent)

        if (datetime.utcnow() - updated_at) < five_seconds:
            modified_at_is_recent = True
        else:
            modified_at_is_recent = False
        self.assertTrue(created_at_is_recent)

    def test_incoming(self):
        """
        Sharedfile.incoming should return only last 10 added sharedfiles.
        """
        # Adding 50 sharedfiles.
        for i in range(50):
            share_key = "%s" % i
            self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
                content_type="image/png", share_key=share_key)
            self.sharedfile.save()

        # should have 26 including file created in setUp.
        all_files = Sharedfile.all()
        self.assertEqual(len(all_files), 51)

        # only returns 10.
        incoming = Sharedfile.incoming()
        self.assertEqual(len(incoming), 10)

        # in order of last added -- biggest id to smallest
        last_seen = None
        for incoming_file in incoming:
            if not last_seen:
                last_seen = incoming_file.id
                continue
            if incoming_file.id < last_seen:
                less_then = True
            else:
                less_then = False
            self.assertTrue(less_then)

    def test_incoming_doesnt_include_deleted(self):
        """
        Sharedfile.incoming should should not return any deleted files.
        """
        self.assertEqual(len(Sharedfile.incoming()), 1)
        self.sharedfile.delete()
        self.assertEqual(len(Sharedfile.incoming()), 0)

    def test_incoming_doesnt_include_nsfw_users(self):
        """
        Sharedfile.incoming should not return files from users marked nsfw
        """
        # Adding 10 sharedfiles.
        for i in range(10):
            share_key = "%s" % i
            self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
                content_type="image/png", share_key=share_key)
            self.sharedfile.save()


        self.user.nsfw = 1
        self.user.save()

        # should return 0
        incoming = Sharedfile.incoming()
        self.assertEqual(len(incoming), 0)

        self.user.nsfw = 0
        self.user.save()

        # should return 10
        incoming = Sharedfile.incoming()
        self.assertEqual(len(incoming), 10)

    def test_incoming_includes_nsfw_users_if_asked(self):
        """
        Sharedfile.incoming should NOT return files from users marked nsfw if the include_nsfw is True
        """
        # Adding 10 sharedfiles.
        for i in range(10):
            share_key = "%s" % i
            self.sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
                content_type="image/png", share_key=share_key)
            self.sharedfile.save()

        self.user.nsfw = 1
        self.user.save()

        # should return 10
        incoming = Sharedfile.incoming(filter=False)
        self.assertEqual(len(incoming), 0)


    def test_delete(self):
        """
        A regular sharedfile created without deleted parameter specified (as in setUp)
        will have that flag set to 0.  Calling delete() changes flag to 1 and persists to DB.
        """
        self.assertEqual(self.sharedfile.deleted, 0)
        self.sharedfile.delete()
        self.assertEqual(self.sharedfile.deleted, 1)
        fetched_sharedfile = Sharedfile.get("id= %s", self.sharedfile.id)
        self.assertEqual(fetched_sharedfile.deleted, 1)

    def test_deleting_sharedfile_also_mutes_conversations(self):
        new_comment = Comment(user_id=self.user.id, sharedfile_id=self.sharedfile.id)
        new_comment.save()
        self.sharedfile.delete()

        muted_conversation = Conversation.get('user_id=%s and sharedfile_id=%s and muted = 1', self.user.id, self.sharedfile.id)
        self.assertTrue(muted_conversation)

    def test_sharedfile_from_existing_file(self):
        test_files = os.path.join(os.path.dirname(os.path.dirname(__file__)), "files")
        file_key = Sourcefile.get_sha1_file_key(test_files + "/1.png")
        shutil.copyfile("%s/1.png" % (test_files), "/tmp/%s" % (file_key))

        shared_file1 = Sharedfile.create_from_file("/tmp/%s" % (file_key),"1.png", file_key, "image/png", self.user.id)
        shared_file2 = Sharedfile.create_from_file("/tmp/%s" % (file_key),"1.png", file_key, "image/png", self.user.id)

        self.assertEqual(shared_file1.source_id, shared_file2.source_id)

    def test_sharedfile_from_new_file(self):
        test_files = os.path.join(os.path.dirname(os.path.dirname(__file__)), "files")
        file_key = Sourcefile.get_sha1_file_key(test_files + "/1.png")
        shutil.copyfile("%s/1.png" % (test_files), "/tmp/%s" % (file_key))
        shared_file = Sharedfile.create_from_file("/tmp/%s" % (file_key),"1.png", file_key, "image/png", self.user.id)
        self.assertEqual(shared_file.id, 2)
        self.assertEqual(shared_file.source_id, 2)

    def test_get_title(self):
        """
        If there is no title or title is blank, Sharedfile.get_title should return
        the name, otherwise returns title.

        if sans_quotes argument set to True, all quotes should be escaped. Off by default
        """
        self.assertEqual(self.sharedfile.title, None)
        self.assertEqual(self.sharedfile.get_title(), self.sharedfile.name)
        self.sharedfile.title = ''
        self.sharedfile.save()
        self.assertEqual(self.sharedfile.get_title(), self.sharedfile.name)
        self.sharedfile.title = 'New title'
        self.sharedfile.save()
        self.assertEqual(self.sharedfile.get_title(), 'New title')
        self.sharedfile.title = 'New "title" and "junk"'
        self.assertEqual(self.sharedfile.get_title(), 'New "title" and "junk"')
        self.assertEqual(self.sharedfile.get_title(sans_quotes=True), 'New &quot;title&quot; and &quot;junk&quot;')

    def test_calculate_view_count(self):
        """
        View count should return all views for an image, should not count
        user views as equal.
        """
        self.assertEqual(0, self.sharedfile.calculate_view_count())
        self.sharedfile.add_view()
        self.sharedfile.add_view()
        self.sharedfile.add_view()
        self.sharedfile.add_view(user_id=self.user.id)
        self.assertEqual(3, self.sharedfile.calculate_view_count())

    def test_save_count(self):
        """
        Should return a total count of direct saves of the images, combined with
        how many people saved the original (parent) sharedfile.

        A = self.sharedfile
        self.user = uploads A
        new_user = saves A, into B -- A: 1, b: 0
        new_user2 = saves B, into C -- A: 2, b: 1, c: 0
        new_user3 = saves C, into D -- A: 3, b: 1, c: 1
        """
        # Set up users we'll need.
        new_user = User(name='new_user',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user.save()
        new_user2 = User(name='new_user_2',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user2.save()
        new_user3 = User(name='new_user_3',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user3.save()
        a = self.sharedfile
        self.assertEqual(0, a.save_count())
        b = a.save_to_shake(new_user)
        self.assertEqual(1, a.save_count())
        self.assertEqual(0, b.save_count())
        c = b.save_to_shake(new_user2)
        self.assertEqual(2, a.save_count())
        self.assertEqual(1, b.save_count())
        self.assertEqual(0, c.save_count())
        d = c.save_to_shake(new_user3)
        self.assertEqual(3, a.save_count())
        self.assertEqual(1, b.save_count())
        self.assertEqual(1, c.save_count())

    def test_favorites_for_user(self):
        """
        Returns favorites for user, sorted in reverse order of when they were added.

        TODO: test the before_id & after_id parameters.
        """
        new_user = User(name='new_user',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
        new_user.save()
        another_sharedfile = Sharedfile(source_id=self.sourcefile.id, name="my shared file",user_id=self.user.id, \
            content_type="image/png", share_key="ok", description="some\ndescription\nhere", source_url="http://www.mltshp.com/?hi")
        another_sharedfile.save()

        #one favorite shared file
        new_user.add_favorite(self.sharedfile)
        new_user.add_favorite(another_sharedfile)

        #this should only return one, since we don't dupe source_ids
        sfs = Sharedfile.favorites_for_user(new_user.id)
        self.assertEqual(sfs[0].id, self.sharedfile.id)

        #but really, underneath we should have two favorites
        fs = Favorite.where('user_id = %s', new_user.id)

        self.assertEqual(2, len(fs))






    def test_sharedfile_saved_to_group_shake(self):
        test_files = os.path.join(os.path.dirname(os.path.dirname(__file__)), "files")
        file_key = Sourcefile.get_sha1_file_key(test_files + "/1.png")
        shutil.copyfile("%s/1.png" % (test_files), "/tmp/%s" % (file_key))

        #create a new shake
        group_shake = Shake(user_id=self.user.id, type='group', title='asdf', name='asdf')
        group_shake.save()

        a_shared_file = Sharedfile.create_from_file("/tmp/%s" % (file_key),"1.png", file_key, "image/png", self.user.id, group_shake.id)
        self.assertTrue(group_shake.can_update(self.user.id))

        a_shared_file.add_to_shake(self.user.shake())

        ssfs = Shakesharedfile.all()
        for ssf in ssfs:
            self.assertEqual(ssf.sharedfile_id, a_shared_file.id)

    def test_can_user_delete_from_shake(self):
        """
        A user can only delete from a shake if they are the owner of the sharedfile
        or the owner of the shake.
        """
        user_shake = self.user.shake()
        self.sharedfile.add_to_shake(user_shake)
        self.assertEqual(True, self.sharedfile.can_user_delete_from_shake(self.user, user_shake))

        # A user that doesn't own the sharedfile
        new_user = User(name='new_user',email='*****@*****.**',verify_email_token='created', email_confirmed=0)
        new_user.save()
        self.assertEqual(False, self.sharedfile.can_user_delete_from_shake(new_user, user_shake))

        # Owner of a group shake, but file doesn't belong to them.
        group_shake = Shake(user_id=new_user.id, type='group', title='Bears', name='bears')
        group_shake.save()
        self.sharedfile.add_to_shake(group_shake)
        self.assertEqual(True, self.sharedfile.can_user_delete_from_shake(new_user, group_shake))
        # owner of file, but not of shake.
        self.assertEqual(True, self.sharedfile.can_user_delete_from_shake(self.user, group_shake))


    def test_delete_from_shake(self):
        """
        Deleting a sharedfile from a shake sets the shakesharedfile 'deleted' to 1.

        Sharedfile.delete_from_shake retuns True if delete successful or False otherwise.
        """
        user_shake = self.user.shake()
        self.sharedfile.add_to_shake(user_shake)
        ssf = Shakesharedfile.get("sharedfile_id = %s", self.sharedfile.id)
        # original file is not deleted
        self.assertEqual(ssf.deleted, 0)
        # delete should work
        self.assertEqual(True, self.sharedfile.delete_from_shake(user_shake))
        ssf = Shakesharedfile.get("sharedfile_id = %s", self.sharedfile.id)
        self.assertEqual(ssf.deleted, 1)


    #def test_favorite_count(self):
    #    """
    #    Should return total favorite count for current image. Should not
    #    count removed favorites.
    #    """
    #    self.assertEqual(0, self.sharedfile.favorite_count())
    #    # Create some users to save images to.
    #    new_user = User(name='new_user',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
    #    new_user.save()
    #    new_user2 = User(name='new_user_2',email='*****@*****.**',verify_email_token='created',email_confirmed=0)
    #    new_user2.save()
    #    new_user.add_favorite(self.sharedfile)
    #    self.assertEqual(1, self.sharedfile.favorite_count())
    #    new_user2.add_favorite(self.sharedfile)
    #    self.assertEqual(2, self.sharedfile.favorite_count())
    #    new_user2.remove_favorite(self.sharedfile)
    #    self.assertEqual(1, self.sharedfile.favorite_count())

    def test_comment_count(self):
        """
        Comment count should return the number of comments belonging to
        shard file. Should not count deleted comments.
        """
        self.assertEqual(0, self.sharedfile.comment_count())
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body="just a comment")
        comment.save()
        self.assertEqual(1, self.sharedfile.comment_count())
        comment = Comment(sharedfile_id=self.sharedfile.id, user_id=self.user.id, body="just a comment", deleted=True)
        comment.save()
        self.assertEqual(1, self.sharedfile.comment_count())

    def test_set_nsfw(self):
        """
        When a user flags an image as NSFW, a new NSFWLog entry is created with
        that user's id and sharedfile's id, with current timestamp.  The NSFW
        flag on the sharedfile's sourcefile also gets flipped to 1.
        """
        sourcefile = self.sharedfile.sourcefile()
        self.assertEqual(0, self.sourcefile.nsfw)
        self.assertEqual(0, len(NSFWLog.all()))
        self.sharedfile.set_nsfw(self.user)
        fetched_sf = Sharedfile.get("id = %s", self.sharedfile.id)
        fetched_source = fetched_sf.sourcefile()
        self.assertEqual(1, fetched_source.nsfw)
        self.assertEqual(1, len(NSFWLog.all()))
        log_entry = NSFWLog.all()[0]
        self.assertEqual(self.user.id, log_entry.user_id)
        self.assertEqual(self.sharedfile.id, log_entry.sharedfile_id)
        self.assertEqual(fetched_source.id, log_entry.sourcefile_id)
        self.assertTrue(log_entry.created_at - datetime.utcnow() <= timedelta(seconds=2))


    def test_as_json_with_user_context(self):
        """
        as_json should return the correct 'saved' and 'liked' flags
        if user_context is provided.
        """
        new_user = User(name='newuser', email='*****@*****.**', verify_email_token='created', email_confirmed=0)
        new_user.save()
        sf_dict = self.sharedfile.as_json(user_context=new_user)
        self.assertEqual(False, sf_dict['saved'])
        self.assertEqual(False, sf_dict['liked'])

        self.sharedfile.save_to_shake(new_user)
        sf_dict = self.sharedfile.as_json(user_context=new_user)
        self.assertEqual(True, sf_dict['saved'])
        self.assertEqual(False, sf_dict['liked'])

        new_user.add_favorite(self.sharedfile)
        sf_dict = self.sharedfile.as_json(user_context=new_user)
        self.assertEqual(True, sf_dict['saved'])
        self.assertEqual(True, sf_dict['liked'])


    def test_likers_list(self):
        """
        Tests that likers are returned. Should not include deleted likers.
        """
        pass

    def test_save_count(self):
        """
        Tests that people who saved it are returned. Should not included deleted saves.
        """
        pass

    def test_tag_search(self):
        self.sharedfile.description = """#here #is some #tags that I got for #you. 
            #here is another word that #is not to be duplicated."""
        tags = self.sharedfile.find_tags()
        self.assertEqual(tags, set(['is', 'you', 'here', 'tags']))

    def test_tags_are_not_too_long(self):
        self.sharedfile.description = """#asdfasdfasdfasdfasdf is twenty and 
        this is 21 #asdfasdfasdfasdfasdfz and this is 22 #asdfasdfasdfasdfasdfxx"""
        tags = self.sharedfile.find_tags()
        self.assertEqual(tags, set(['asdfasdfasdfasdfasdf']))

    def test_tags_dont_find_urls(self):
        self.sharedfile.description = """#cool Some descriptions have urls in them like
            this one here http://cnn.com/#bad and this 
            http://www.cnn.com/?canada#worse #great?"""
        tags = self.sharedfile.find_tags()
        self.assertEqual(tags, set(['cool', 'great']))

    def test_tags_dont_include_nonchars(self):
        self.sharedfile.description = """#cool-bad #cool-good 
            #cool #cool?dunno 234238273#238023osidjf waht e#e can I do? i dunno
            """
        tags = self.sharedfile.find_tags()
        self.assertEqual(tags, set(['cool']))
        
    def test_tags_dont_exist(self):
        self.sharedfile.description = """234238273#238023osidjf e#e 
        https://twitter.com/#!/jJIe 
            """
        tags = self.sharedfile.find_tags()
        self.assertEqual(tags, set([]))

    def test_tags_created_on_save(self):
        self.sharedfile.description = """#here #is some #tags that I got for #you. 
            #here is another word that #is not to be duplicated."""

        self.sharedfile.save()
        tags = Tag.all()
        for tag in tags:
            self.assertTrue(tag.name in ['is', 'you', 'here', 'tags'])

    def test_tags_assigned_on_save(self):
        self.sharedfile.description = """#here #is some #tags that I got for #you. 
            #here is another word that #is not to be duplicated."""

        self.sharedfile.save()

        tags = self.sharedfile.tags()
        for tag in tags:
            self.assertTrue(tag.name in ['is', 'you', 'here', 'tags'])

        
    def test_tags_become_deleted_on_overwrite(self):
        #create a file with tags
        self.sharedfile.description = """#here #is some #tags that I got for #you. 
            #here is another word that #is not to be duplicated."""
        self.sharedfile.save()

        #load the file back up and change the description
        self.sharedfile = Sharedfile.get("id = %s", self.sharedfile.id)
        self.sharedfile.description = "some #all #newtags #not #old"
        self.sharedfile.save()

        #save the file and check that the new tags are only returned
        tags = self.sharedfile.tags()
        for tf in tags:
            self.assertTrue(tf.name in ['all', 'newtags', 'not', 'old'])

        #load the deleted tags and check that they are the same as the original
        tagged_files = TaggedFile.where("deleted = 1")
        for tf in tagged_files:
            t = Tag.get('id = %s', tf.tag_id)
            self.assertTrue(t.name in ['here', 'is', 'tags', 'you'])


    def test_tags_completely_disappear_on_clearing(self):
        #create a new sharedfile
        #set the description with tags
        self.sharedfile.description = """#here #is some #tags that I got for #you. 
            #here is another word that #is not to be duplicated."""
        self.sharedfile.save()
        
        #set a new description that has no tags
        self.sharedfile.description = "I have no tags."
        self.sharedfile.save()

        #verify tags() is empty.
        tags = self.sharedfile.tags()
        self.assertEqual(tags, [])

        #verify the original tags are all deleted=1
        tagged_files = TaggedFile.all()
        for tf in tagged_files:
            self.assertEqual(tf.deleted, 1)

    def test_tags_with_numbers_are_created(self):
        self.sharedfile.description = """#here1 #is2 some #tags3 that I got for #you4. 
            #here1 is another word that #is2 not to be duplicated."""

        self.sharedfile.save()
        tags = self.sharedfile.tags()
        for tag in tags:
            self.assertTrue(tag.name in ['is2', 'you4', 'here1', 'tags3'])


    def test_tags_with_different_case(self):
        self.sharedfile.description = """This #TAG should only appear #tag once in
        this #tAg list and also #YES1YES #yes1yes."""

        self.sharedfile.save()
        tags = self.sharedfile.tags()
        for tag in tags:
            self.assertTrue(tag.name in ['tag', 'yes1yes'])
        
    def test_saving_a_file_from_someone_doesnt_run_tagging(self):
        self.sharedfile.description = """This #TAG should only appear #tag once in
            this #tAg list and also #YES1YES #yes1yes."""
        self.sharedfile.save(ignore_tags=True)

        self.assertEqual([], self.sharedfile.tags())

    def test_deleting_shared_file_deletes_tags(self):
        self.sharedfile.description = """#here1 #is2 some #tags3 that I got for #you4. 
            #here1 is another word that #is2 not to be duplicated."""
        self.sharedfile.save()

        self.sharedfile.delete()

        tf = TaggedFile.all()
        for t in tf:
            self.assertEqual(t.deleted, 1)