class HistoryManagerTestCase( BaseTestCase ):

    def set_up_managers( self ):
        super( HistoryManagerTestCase, self ).set_up_managers()
        self.history_mgr = HistoryManager( self.app )

    def test_base( self ):
        user2 = self.user_mgr.create( self.trans, **user2_data )
        user3 = self.user_mgr.create( self.trans, **user3_data )

        self.log( "should be able to create a new history" )
        history1 = self.history_mgr.create( self.trans, name='history1', user=user2 )
        self.assertIsInstance( history1, model.History )
        self.assertEqual( history1.name, 'history1' )
        self.assertEqual( history1.user, user2 )
        self.assertEqual( history1, self.trans.sa_session.query( model.History ).get( history1.id ) )
        self.assertEqual( history1,
            self.trans.sa_session.query( model.History ).filter( model.History.name == 'history1' ).one() )
        self.assertEqual( history1,
            self.trans.sa_session.query( model.History ).filter( model.History.user == user2 ).one() )

        self.log( "should be able to copy a history" )
        history2 = self.history_mgr.copy( self.trans, history1, user=user3 )
        self.assertIsInstance( history2, model.History )
        self.assertEqual( history2.user, user3 )
        self.assertEqual( history2, self.trans.sa_session.query( model.History ).get( history2.id ) )
        self.assertEqual( history2.name, history1.name )
        self.assertNotEqual( history2, history1 )

        self.log( "should be able to query" )
        histories = self.trans.sa_session.query( model.History ).all()
        self.assertEqual( self.history_mgr.one( self.trans, filters=( model.History.id == history1.id ) ), history1 )
        self.assertEqual( self.history_mgr.list( self.trans ), histories )
        self.assertEqual( self.history_mgr.by_id( self.trans, history1.id ), history1 )
        self.assertEqual( self.history_mgr.by_ids( self.trans, [ history2.id, history1.id ] ), [ history2, history1 ] )

        self.log( "should be able to limit and offset" )
        self.assertEqual( self.history_mgr.list( self.trans, limit=1 ), histories[0:1] )
        self.assertEqual( self.history_mgr.list( self.trans, offset=1 ), histories[1:] )
        self.assertEqual( self.history_mgr.list( self.trans, limit=1, offset=1 ), histories[1:2] )

        self.assertEqual( self.history_mgr.list( self.trans, limit=0 ), [] )
        self.assertEqual( self.history_mgr.list( self.trans, offset=3 ), [] )

        self.log( "should be able to order" )
        history3 = self.history_mgr.create( self.trans, name="history3", user=user2 )
        name_first_then_time = ( model.History.name, sqlalchemy.desc( model.History.create_time ) )
        self.assertEqual( self.history_mgr.list( self.trans, order_by=name_first_then_time ),
            [ history2, history1, history3 ] )

    def test_has_user( self ):
        owner = self.user_mgr.create( self.trans, **user2_data )
        non_owner = self.user_mgr.create( self.trans, **user3_data )

        item1 = self.history_mgr.create( self.trans, user=owner )
        item2 = self.history_mgr.create( self.trans, user=owner )
        item3 = self.history_mgr.create( self.trans, user=non_owner )

        self.log( "should be able to list items by user" )
        user_histories = self.history_mgr.by_user( self.trans, owner )
        self.assertEqual( user_histories, [ item1, item2 ] )

    def test_ownable( self ):
        owner = self.user_mgr.create( self.trans, **user2_data )
        non_owner = self.user_mgr.create( self.trans, **user3_data )

        item1 = self.history_mgr.create( self.trans, user=owner )

        self.log( "should be able to poll whether a given user owns an item" )
        self.assertTrue(  self.history_mgr.is_owner( self.trans, item1, owner ) )
        self.assertFalse( self.history_mgr.is_owner( self.trans, item1, non_owner ) )

        self.log( "should raise an error when checking ownership with non-owner" )
        self.assertRaises( exceptions.ItemOwnershipException,
            self.history_mgr.error_unless_owner, self.trans, item1, non_owner )
        self.assertRaises( exceptions.ItemOwnershipException,
            self.history_mgr.get_owned, self.trans, item1.id, non_owner )

        self.log( "should not raise an error when checking ownership with owner" )
        self.assertEqual( self.history_mgr.error_unless_owner( self.trans, item1, owner ), item1 )
        self.assertEqual( self.history_mgr.get_owned( self.trans, item1.id, owner ), item1 )

        self.log( "should not raise an error when checking ownership with admin" )
        self.assertTrue( self.history_mgr.is_owner( self.trans, item1, self.admin_user ) )
        self.assertEqual( self.history_mgr.error_unless_owner( self.trans, item1, self.admin_user ), item1 )
        self.assertEqual( self.history_mgr.get_owned( self.trans, item1.id, self.admin_user ), item1 )

    def test_accessible( self ):
        owner = self.user_mgr.create( self.trans, **user2_data )
        item1 = self.history_mgr.create( self.trans, user=owner )

        non_owner = self.user_mgr.create( self.trans, **user3_data )

        self.log( "should be inaccessible by default except to owner" )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, item1, owner ) )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, item1, self.admin_user ) )
        self.assertFalse( self.history_mgr.is_accessible( self.trans, item1, non_owner ) )

        self.log( "should raise an error when checking accessibility with non-owner" )
        self.assertRaises( exceptions.ItemAccessibilityException,
            self.history_mgr.error_unless_accessible, self.trans, item1, non_owner )
        self.assertRaises( exceptions.ItemAccessibilityException,
            self.history_mgr.get_accessible, self.trans, item1.id, non_owner )

        self.log( "should not raise an error when checking ownership with owner" )
        self.assertEqual( self.history_mgr.error_unless_accessible( self.trans, item1, owner ), item1 )
        self.assertEqual( self.history_mgr.get_accessible( self.trans, item1.id, owner ), item1 )

        self.log( "should not raise an error when checking ownership with admin" )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, item1, self.admin_user ) )
        self.assertEqual( self.history_mgr.error_unless_accessible( self.trans, item1, self.admin_user ), item1 )
        self.assertEqual( self.history_mgr.get_accessible( self.trans, item1.id, self.admin_user ), item1 )

    def test_importable( self ):
        owner = self.user_mgr.create( self.trans, **user2_data )
        self.trans.set_user( owner )
        non_owner = self.user_mgr.create( self.trans, **user3_data )

        item1 = self.history_mgr.create( self.trans, user=owner )

        self.log( "should not be importable by default" )
        self.assertFalse( item1.importable )
        self.assertIsNone( item1.slug )

        self.log( "should be able to make importable (accessible by link) to all users" )
        accessible = self.history_mgr.make_importable( self.trans, item1 )
        self.assertEqual( accessible, item1 )
        self.assertIsNotNone( accessible.slug )
        self.assertTrue( accessible.importable )

        for user in self.user_mgr.list( self.trans ):
            self.assertTrue( self.history_mgr.is_accessible( self.trans, accessible, user ) )

        self.log( "should be able to make non-importable/inaccessible again" )
        inaccessible = self.history_mgr.make_non_importable( self.trans, accessible )
        self.assertEqual( inaccessible, accessible )
        self.assertIsNotNone( inaccessible.slug )
        self.assertFalse( inaccessible.importable )

        self.assertTrue( self.history_mgr.is_accessible( self.trans, inaccessible, owner ) )
        self.assertFalse( self.history_mgr.is_accessible( self.trans, inaccessible, non_owner ) )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, inaccessible, self.admin_user ) )

    def test_published( self ):
        owner = self.user_mgr.create( self.trans, **user2_data )
        self.trans.set_user( owner )
        non_owner = self.user_mgr.create( self.trans, **user3_data )

        item1 = self.history_mgr.create( self.trans, user=owner )

        self.log( "should not be published by default" )
        self.assertFalse( item1.published )
        self.assertIsNone( item1.slug )

        self.log( "should be able to publish (listed publicly) to all users" )
        published = self.history_mgr.publish( self.trans, item1 )
        self.assertEqual( published, item1 )
        self.assertTrue( published.published )
        # note: publishing sets importable to true as well
        self.assertTrue( published.importable )
        self.assertIsNotNone( published.slug )

        for user in self.user_mgr.list( self.trans ):
            self.assertTrue( self.history_mgr.is_accessible( self.trans, published, user ) )

        self.log( "should be able to make non-importable/inaccessible again" )
        unpublished = self.history_mgr.unpublish( self.trans, published )
        self.assertEqual( unpublished, published )
        self.assertFalse( unpublished.published )
        # note: unpublishing does not make non-importable, you must explicitly do that separately
        self.assertTrue( published.importable )
        self.history_mgr.make_non_importable( self.trans, unpublished )
        self.assertFalse( published.importable )
        # note: slug still remains after unpublishing
        self.assertIsNotNone( unpublished.slug )

        self.assertTrue( self.history_mgr.is_accessible( self.trans, unpublished, owner ) )
        self.assertFalse( self.history_mgr.is_accessible( self.trans, unpublished, non_owner ) )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, unpublished, self.admin_user ) )

    def test_sharable( self ):
        owner = self.user_mgr.create( self.trans, **user2_data )
        self.trans.set_user( owner )
        item1 = self.history_mgr.create( self.trans, user=owner )

        non_owner = self.user_mgr.create( self.trans, **user3_data )
        #third_party = self.user_mgr.create( self.trans, **user4_data )

        self.log( "should be unshared by default" )
        self.assertEqual( self.history_mgr.get_share_assocs( self.trans, item1 ), [] )
        self.assertEqual( item1.slug, None )

        self.log( "should be able to share with specific users" )
        share_assoc = self.history_mgr.share_with( self.trans, item1, non_owner )
        self.assertIsInstance( share_assoc, model.HistoryUserShareAssociation )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, item1, non_owner ) )
        self.assertEqual(
            len( self.history_mgr.get_share_assocs( self.trans, item1 ) ), 1 )
        self.assertEqual(
            len( self.history_mgr.get_share_assocs( self.trans, item1, user=non_owner ) ), 1 )
        self.assertIsInstance( item1.slug, basestring )

        self.log( "should be able to unshare with specific users" )
        share_assoc = self.history_mgr.unshare_with( self.trans, item1, non_owner )
        self.assertIsInstance( share_assoc, model.HistoryUserShareAssociation )
        self.assertFalse( self.history_mgr.is_accessible( self.trans, item1, non_owner ) )
        self.assertEqual( self.history_mgr.get_share_assocs( self.trans, item1 ), [] )
        self.assertEqual(
            self.history_mgr.get_share_assocs( self.trans, item1, user=non_owner ), [] )

    #TODO: test slug formation

    def test_anon( self ):
        anon_user = None
        self.trans.set_user( anon_user )

        self.log( "should not allow access and owner for anon user on a history by another anon user (None)" )
        anon_history1 = self.history_mgr.create( self.trans, user=None )
        self.assertFalse( self.history_mgr.is_owner( self.trans, anon_history1, anon_user ) )
        self.assertFalse( self.history_mgr.is_accessible( self.trans, anon_history1, anon_user ) )

        self.log( "should allow access and owner for anon user on a history if it's the session's current history" )
        anon_history2 = self.history_mgr.create( self.trans, user=anon_user )
        self.trans.set_history( anon_history2 )
        self.assertTrue( self.history_mgr.is_owner( self.trans, anon_history2, anon_user ) )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, anon_history2, anon_user ) )

        self.log( "should not allow owner or access for anon user on someone elses history" )
        owner = self.user_mgr.create( self.trans, **user2_data )
        someone_elses = self.history_mgr.create( self.trans, user=owner )
        self.assertFalse( self.history_mgr.is_owner( self.trans, someone_elses, anon_user ) )
        self.assertFalse( self.history_mgr.is_accessible( self.trans, someone_elses, anon_user ) )

        self.log( "should allow access for anon user if the history is published or importable" )
        self.history_mgr.make_importable( self.trans, someone_elses )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, someone_elses, anon_user ) )
        self.history_mgr.publish( self.trans, someone_elses )
        self.assertTrue( self.history_mgr.is_accessible( self.trans, someone_elses, anon_user ) )

    def test_delete_and_purge( self ):
        user2 = self.user_mgr.create( self.trans, **user2_data )
        self.trans.set_user( user2 )

        history1 = self.history_mgr.create( self.trans, name='history1', user=user2 )
        self.trans.set_history( history1 )

        self.assertFalse( history1.deleted )

        self.history_mgr.delete( self.trans, history1 )
        self.assertTrue( history1.deleted )

        self.history_mgr.undelete( self.trans, history1 )
        self.assertFalse( history1.deleted )

        history2 = self.history_mgr.create( self.trans, name='history2', user=user2 )
        self.history_mgr.purge( self.trans, history1 )
        self.assertTrue( history1.purged )

    def test_histories( self ):
        user2 = self.user_mgr.create( self.trans, **user2_data )
        self.trans.set_user( user2 )

        history1 = self.history_mgr.create( self.trans, name='history1', user=user2 )
        self.trans.set_history( history1 )
        history2 = self.history_mgr.create( self.trans, name='history2', user=user2 )

        self.log( "should be able to set or get the current history for a user" )
        self.assertEqual( self.history_mgr.get_current( self.trans ), history1 )
        self.assertEqual( self.history_mgr.set_current( self.trans, history2 ), history2 )
        self.assertEqual( self.history_mgr.get_current( self.trans ), history2 )
        self.assertEqual( self.history_mgr.set_current_by_id( self.trans, history1.id ), history1 )
        self.assertEqual( self.history_mgr.get_current( self.trans ), history1 )
Beispiel #2
0
class HistoryManagerTestCase(BaseTestCase):

    def set_up_managers(self):
        super(HistoryManagerTestCase, self).set_up_managers()
        self.history_manager = HistoryManager(self.app)
        self.hda_manager = hdas.HDAManager(self.app)

    def add_hda_to_history(self, history, **kwargs):
        dataset = self.hda_manager.dataset_manager.create()
        hda = self.hda_manager.create(history=history, dataset=dataset, **kwargs)
        return hda

    def test_base(self):
        user2 = self.user_manager.create(**user2_data)
        user3 = self.user_manager.create(**user3_data)

        self.log("should be able to create a new history")
        history1 = self.history_manager.create(name='history1', user=user2)
        self.assertIsInstance(history1, model.History)
        self.assertEqual(history1.name, 'history1')
        self.assertEqual(history1.user, user2)
        self.assertEqual(history1, self.trans.sa_session.query(model.History).get(history1.id))
        self.assertEqual(history1,
            self.trans.sa_session.query(model.History).filter(model.History.name == 'history1').one())
        self.assertEqual(history1,
            self.trans.sa_session.query(model.History).filter(model.History.user == user2).one())

        history2 = self.history_manager.copy(history1, user=user3)

        self.log("should be able to query")
        histories = self.trans.sa_session.query(model.History).all()
        self.assertEqual(self.history_manager.one(filters=(model.History.id == history1.id)), history1)
        self.assertEqual(self.history_manager.list(), histories)
        self.assertEqual(self.history_manager.by_id(history1.id), history1)
        self.assertEqual(self.history_manager.by_ids([history2.id, history1.id]), [history2, history1])

        self.log("should be able to limit and offset")
        self.assertEqual(self.history_manager.list(limit=1), histories[0:1])
        self.assertEqual(self.history_manager.list(offset=1), histories[1:])
        self.assertEqual(self.history_manager.list(limit=1, offset=1), histories[1:2])

        self.assertEqual(self.history_manager.list(limit=0), [])
        self.assertEqual(self.history_manager.list(offset=3), [])

        self.log("should be able to order")
        history3 = self.history_manager.create(name="history3", user=user2)
        name_first_then_time = (model.History.name, sqlalchemy.desc(model.History.create_time))
        self.assertEqual(self.history_manager.list(order_by=name_first_then_time),
            [history2, history1, history3])

    def test_copy(self):
        user2 = self.user_manager.create(**user2_data)
        user3 = self.user_manager.create(**user3_data)

        self.log("should be able to copy a history (and it's hdas)")
        history1 = self.history_manager.create(name='history1', user=user2)
        tags = [u'tag-one']
        annotation = u'history annotation'
        self.history_manager.set_tags(history1, tags, user=user2)
        self.history_manager.annotate(history1, annotation, user=user2)

        hda = self.add_hda_to_history(history1, name='wat')
        hda_tags = [u'tag-one', u'tag-two']
        hda_annotation = u'annotation'
        self.hda_manager.set_tags(hda, hda_tags, user=user2)
        self.hda_manager.annotate(hda, hda_annotation, user=user2)

        history2 = self.history_manager.copy(history1, user=user3)
        self.assertIsInstance(history2, model.History)
        self.assertEqual(history2.user, user3)
        self.assertEqual(history2, self.trans.sa_session.query(model.History).get(history2.id))
        self.assertEqual(history2.name, history1.name)
        self.assertNotEqual(history2, history1)

        copied_hda = history2.datasets[0]
        copied_hda_tags = self.hda_manager.get_tags(copied_hda)
        self.assertEqual(sorted(hda_tags), sorted(copied_hda_tags))
        copied_hda_annotation = self.hda_manager.annotation(copied_hda)
        self.assertEqual(hda_annotation, copied_hda_annotation)

    def test_has_user(self):
        owner = self.user_manager.create(**user2_data)
        non_owner = self.user_manager.create(**user3_data)

        item1 = self.history_manager.create(user=owner)
        item2 = self.history_manager.create(user=owner)
        self.history_manager.create(user=non_owner)

        self.log("should be able to list items by user")
        user_histories = self.history_manager.by_user(owner)
        self.assertEqual(user_histories, [item1, item2])

    def test_ownable(self):
        owner = self.user_manager.create(**user2_data)
        non_owner = self.user_manager.create(**user3_data)

        item1 = self.history_manager.create(user=owner)

        self.log("should be able to poll whether a given user owns an item")
        self.assertTrue(self.history_manager.is_owner(item1, owner))
        self.assertFalse(self.history_manager.is_owner(item1, non_owner))

        self.log("should raise an error when checking ownership with non-owner")
        self.assertRaises(exceptions.ItemOwnershipException,
            self.history_manager.error_unless_owner, item1, non_owner)
        self.assertRaises(exceptions.ItemOwnershipException,
            self.history_manager.get_owned, item1.id, non_owner)

        self.log("should not raise an error when checking ownership with owner")
        self.assertEqual(self.history_manager.error_unless_owner(item1, owner), item1)
        self.assertEqual(self.history_manager.get_owned(item1.id, owner), item1)

        self.log("should not raise an error when checking ownership with admin")
        self.assertTrue(self.history_manager.is_owner(item1, self.admin_user))
        self.assertEqual(self.history_manager.error_unless_owner(item1, self.admin_user), item1)
        self.assertEqual(self.history_manager.get_owned(item1.id, self.admin_user), item1)

    def test_accessible(self):
        owner = self.user_manager.create(**user2_data)
        item1 = self.history_manager.create(user=owner)

        non_owner = self.user_manager.create(**user3_data)

        self.log("should be inaccessible by default except to owner")
        self.assertTrue(self.history_manager.is_accessible(item1, owner))
        self.assertTrue(self.history_manager.is_accessible(item1, self.admin_user))
        self.assertFalse(self.history_manager.is_accessible(item1, non_owner))

        self.log("should raise an error when checking accessibility with non-owner")
        self.assertRaises(exceptions.ItemAccessibilityException,
            self.history_manager.error_unless_accessible, item1, non_owner)
        self.assertRaises(exceptions.ItemAccessibilityException,
            self.history_manager.get_accessible, item1.id, non_owner)

        self.log("should not raise an error when checking ownership with owner")
        self.assertEqual(self.history_manager.error_unless_accessible(item1, owner), item1)
        self.assertEqual(self.history_manager.get_accessible(item1.id, owner), item1)

        self.log("should not raise an error when checking ownership with admin")
        self.assertTrue(self.history_manager.is_accessible(item1, self.admin_user))
        self.assertEqual(self.history_manager.error_unless_accessible(item1, self.admin_user), item1)
        self.assertEqual(self.history_manager.get_accessible(item1.id, self.admin_user), item1)

    def test_importable(self):
        owner = self.user_manager.create(**user2_data)
        self.trans.set_user(owner)
        non_owner = self.user_manager.create(**user3_data)

        item1 = self.history_manager.create(user=owner)

        self.log("should not be importable by default")
        self.assertFalse(item1.importable)
        self.assertIsNone(item1.slug)

        self.log("should be able to make importable (accessible by link) to all users")
        accessible = self.history_manager.make_importable(item1)
        self.assertEqual(accessible, item1)
        self.assertIsNotNone(accessible.slug)
        self.assertTrue(accessible.importable)

        for user in self.user_manager.list():
            self.assertTrue(self.history_manager.is_accessible(accessible, user))

        self.log("should be able to make non-importable/inaccessible again")
        inaccessible = self.history_manager.make_non_importable(accessible)
        self.assertEqual(inaccessible, accessible)
        self.assertIsNotNone(inaccessible.slug)
        self.assertFalse(inaccessible.importable)

        self.assertTrue(self.history_manager.is_accessible(inaccessible, owner))
        self.assertFalse(self.history_manager.is_accessible(inaccessible, non_owner))
        self.assertTrue(self.history_manager.is_accessible(inaccessible, self.admin_user))

    def test_published(self):
        owner = self.user_manager.create(**user2_data)
        self.trans.set_user(owner)
        non_owner = self.user_manager.create(**user3_data)

        item1 = self.history_manager.create(user=owner)

        self.log("should not be published by default")
        self.assertFalse(item1.published)
        self.assertIsNone(item1.slug)

        self.log("should be able to publish (listed publicly) to all users")
        published = self.history_manager.publish(item1)
        self.assertEqual(published, item1)
        self.assertTrue(published.published)
        # note: publishing sets importable to true as well
        self.assertTrue(published.importable)
        self.assertIsNotNone(published.slug)

        for user in self.user_manager.list():
            self.assertTrue(self.history_manager.is_accessible(published, user))

        self.log("should be able to make non-importable/inaccessible again")
        unpublished = self.history_manager.unpublish(published)
        self.assertEqual(unpublished, published)
        self.assertFalse(unpublished.published)
        # note: unpublishing does not make non-importable, you must explicitly do that separately
        self.assertTrue(published.importable)
        self.history_manager.make_non_importable(unpublished)
        self.assertFalse(published.importable)
        # note: slug still remains after unpublishing
        self.assertIsNotNone(unpublished.slug)

        self.assertTrue(self.history_manager.is_accessible(unpublished, owner))
        self.assertFalse(self.history_manager.is_accessible(unpublished, non_owner))
        self.assertTrue(self.history_manager.is_accessible(unpublished, self.admin_user))

    def test_sharable(self):
        owner = self.user_manager.create(**user2_data)
        self.trans.set_user(owner)
        item1 = self.history_manager.create(user=owner)

        non_owner = self.user_manager.create(**user3_data)
        # third_party = self.user_manager.create( **user4_data )

        self.log("should be unshared by default")
        self.assertEqual(self.history_manager.get_share_assocs(item1), [])
        self.assertEqual(item1.slug, None)

        self.log("should be able to share with specific users")
        share_assoc = self.history_manager.share_with(item1, non_owner)
        self.assertIsInstance(share_assoc, model.HistoryUserShareAssociation)
        self.assertTrue(self.history_manager.is_accessible(item1, non_owner))
        self.assertEqual(
            len(self.history_manager.get_share_assocs(item1)), 1)
        self.assertEqual(
            len(self.history_manager.get_share_assocs(item1, user=non_owner)), 1)
        self.assertIsInstance(item1.slug, string_types)

        self.log("should be able to unshare with specific users")
        share_assoc = self.history_manager.unshare_with(item1, non_owner)
        self.assertIsInstance(share_assoc, model.HistoryUserShareAssociation)
        self.assertFalse(self.history_manager.is_accessible(item1, non_owner))
        self.assertEqual(self.history_manager.get_share_assocs(item1), [])
        self.assertEqual(
            self.history_manager.get_share_assocs(item1, user=non_owner), [])

    # TODO: test slug formation

    def test_anon(self):
        anon_user = None
        self.trans.set_user(anon_user)

        self.log("should not allow access and owner for anon user on a history by another anon user (None)")
        anon_history1 = self.history_manager.create(user=None)
        # do not set the trans.history!
        self.assertFalse(self.history_manager.is_owner(anon_history1, anon_user, current_history=self.trans.history))
        self.assertFalse(self.history_manager.is_accessible(anon_history1, anon_user, current_history=self.trans.history))

        self.log("should allow access and owner for anon user on a history if it's the session's current history")
        anon_history2 = self.history_manager.create(user=anon_user)
        self.trans.set_history(anon_history2)
        self.assertTrue(self.history_manager.is_owner(anon_history2, anon_user, current_history=self.trans.history))
        self.assertTrue(self.history_manager.is_accessible(anon_history2, anon_user, current_history=self.trans.history))

        self.log("should not allow owner or access for anon user on someone elses history")
        owner = self.user_manager.create(**user2_data)
        someone_elses = self.history_manager.create(user=owner)
        self.assertFalse(self.history_manager.is_owner(someone_elses, anon_user, current_history=self.trans.history))
        self.assertFalse(self.history_manager.is_accessible(someone_elses, anon_user, current_history=self.trans.history))

        self.log("should allow access for anon user if the history is published or importable")
        self.history_manager.make_importable(someone_elses)
        self.assertTrue(self.history_manager.is_accessible(someone_elses, anon_user, current_history=self.trans.history))
        self.history_manager.publish(someone_elses)
        self.assertTrue(self.history_manager.is_accessible(someone_elses, anon_user, current_history=self.trans.history))

    def test_delete_and_purge(self):
        user2 = self.user_manager.create(**user2_data)
        self.trans.set_user(user2)

        history1 = self.history_manager.create(name='history1', user=user2)
        self.trans.set_history(history1)

        self.log("should allow deletion and undeletion")
        self.assertFalse(history1.deleted)

        self.history_manager.delete(history1)
        self.assertTrue(history1.deleted)

        self.history_manager.undelete(history1)
        self.assertFalse(history1.deleted)

        self.log("should allow purging")
        history2 = self.history_manager.create(name='history2', user=user2)
        self.history_manager.purge(history2)
        self.assertTrue(history2.deleted)
        self.assertTrue(history2.purged)

    def test_current(self):
        user2 = self.user_manager.create(**user2_data)
        self.trans.set_user(user2)

        history1 = self.history_manager.create(name='history1', user=user2)
        self.trans.set_history(history1)
        history2 = self.history_manager.create(name='history2', user=user2)

        self.log("should be able to set or get the current history for a user")
        self.assertEqual(self.history_manager.get_current(self.trans), history1)
        self.assertEqual(self.history_manager.set_current(self.trans, history2), history2)
        self.assertEqual(self.history_manager.get_current(self.trans), history2)
        self.assertEqual(self.history_manager.set_current_by_id(self.trans, history1.id), history1)
        self.assertEqual(self.history_manager.get_current(self.trans), history1)

    def test_most_recently_used(self):
        user2 = self.user_manager.create(**user2_data)
        self.trans.set_user(user2)

        history1 = self.history_manager.create(name='history1', user=user2)
        self.trans.set_history(history1)
        history2 = self.history_manager.create(name='history2', user=user2)

        self.log("should be able to get the most recently used (updated) history for a given user")
        self.assertEqual(self.history_manager.most_recent(user2), history2)
        self.history_manager.update(history1, {'name': 'new name'})
        self.assertEqual(self.history_manager.most_recent(user2), history1)

    def test_rating(self):
        user2 = self.user_manager.create(**user2_data)
        manager = self.history_manager
        item = manager.create(name='history1', user=user2)

        self.log("should properly handle no ratings")
        self.assertEqual(manager.rating(item, user2), None)
        self.assertEqual(manager.ratings(item), [])
        self.assertEqual(manager.ratings_avg(item), 0)
        self.assertEqual(manager.ratings_count(item), 0)

        self.log("should allow rating by user")
        manager.rate(item, user2, 5)
        self.assertEqual(manager.rating(item, user2), 5)
        self.assertEqual(manager.ratings(item), [5])
        self.assertEqual(manager.ratings_avg(item), 5)
        self.assertEqual(manager.ratings_count(item), 1)

        self.log("should allow updating")
        manager.rate(item, user2, 4)
        self.assertEqual(manager.rating(item, user2), 4)
        self.assertEqual(manager.ratings(item), [4])
        self.assertEqual(manager.ratings_avg(item), 4)
        self.assertEqual(manager.ratings_count(item), 1)

        self.log("should reflect multiple reviews")
        user3 = self.user_manager.create(**user3_data)
        self.assertEqual(manager.rating(item, user3), None)
        manager.rate(item, user3, 1)
        self.assertEqual(manager.rating(item, user3), 1)
        self.assertEqual(manager.ratings(item), [4, 1])
        self.assertEqual(manager.ratings_avg(item), 2.5)
        self.assertEqual(manager.ratings_count(item), 2)
Beispiel #3
0
class HistoryManagerTestCase(BaseTestCase):
    def set_up_managers(self):
        super(HistoryManagerTestCase, self).set_up_managers()
        self.history_mgr = HistoryManager(self.app)

    def test_base(self):
        user2 = self.user_mgr.create(self.trans, **user2_data)
        user3 = self.user_mgr.create(self.trans, **user3_data)

        self.log("should be able to create a new history")
        history1 = self.history_mgr.create(self.trans,
                                           name='history1',
                                           user=user2)
        self.assertIsInstance(history1, model.History)
        self.assertEqual(history1.name, 'history1')
        self.assertEqual(history1.user, user2)
        self.assertEqual(
            history1,
            self.trans.sa_session.query(model.History).get(history1.id))
        self.assertEqual(
            history1,
            self.trans.sa_session.query(
                model.History).filter(model.History.name == 'history1').one())
        self.assertEqual(
            history1,
            self.trans.sa_session.query(
                model.History).filter(model.History.user == user2).one())

        self.log("should be able to copy a history")
        history2 = self.history_mgr.copy(self.trans, history1, user=user3)
        self.assertIsInstance(history2, model.History)
        self.assertEqual(history2.user, user3)
        self.assertEqual(
            history2,
            self.trans.sa_session.query(model.History).get(history2.id))
        self.assertEqual(history2.name, history1.name)
        self.assertNotEqual(history2, history1)

        self.log("should be able to query")
        histories = self.trans.sa_session.query(model.History).all()
        self.assertEqual(
            self.history_mgr.one(self.trans,
                                 filters=(model.History.id == history1.id)),
            history1)
        self.assertEqual(self.history_mgr.list(self.trans), histories)
        self.assertEqual(self.history_mgr.by_id(self.trans, history1.id),
                         history1)
        self.assertEqual(
            self.history_mgr.by_ids(self.trans, [history2.id, history1.id]),
            [history2, history1])

        self.log("should be able to limit and offset")
        self.assertEqual(self.history_mgr.list(self.trans, limit=1),
                         histories[0:1])
        self.assertEqual(self.history_mgr.list(self.trans, offset=1),
                         histories[1:])
        self.assertEqual(self.history_mgr.list(self.trans, limit=1, offset=1),
                         histories[1:2])

        self.assertEqual(self.history_mgr.list(self.trans, limit=0), [])
        self.assertEqual(self.history_mgr.list(self.trans, offset=3), [])

        self.log("should be able to order")
        history3 = self.history_mgr.create(self.trans,
                                           name="history3",
                                           user=user2)
        name_first_then_time = (model.History.name,
                                sqlalchemy.desc(model.History.create_time))
        self.assertEqual(
            self.history_mgr.list(self.trans, order_by=name_first_then_time),
            [history2, history1, history3])

    def test_has_user(self):
        owner = self.user_mgr.create(self.trans, **user2_data)
        non_owner = self.user_mgr.create(self.trans, **user3_data)

        item1 = self.history_mgr.create(self.trans, user=owner)
        item2 = self.history_mgr.create(self.trans, user=owner)
        item3 = self.history_mgr.create(self.trans, user=non_owner)

        self.log("should be able to list items by user")
        user_histories = self.history_mgr.by_user(self.trans, owner)
        self.assertEqual(user_histories, [item1, item2])

        query = self.history_mgr._query_by_user(self.trans, owner)
        self.assertEqual(query.all(), user_histories)

    def test_ownable(self):
        owner = self.user_mgr.create(self.trans, **user2_data)
        non_owner = self.user_mgr.create(self.trans, **user3_data)

        item1 = self.history_mgr.create(self.trans, user=owner)

        self.log("should be able to poll whether a given user owns an item")
        self.assertTrue(self.history_mgr.is_owner(self.trans, item1, owner))
        self.assertFalse(
            self.history_mgr.is_owner(self.trans, item1, non_owner))

        self.log(
            "should raise an error when checking ownership with non-owner")
        self.assertRaises(exceptions.ItemOwnershipException,
                          self.history_mgr.error_unless_owner, self.trans,
                          item1, non_owner)
        self.assertRaises(exceptions.ItemOwnershipException,
                          self.history_mgr.get_owned, self.trans, item1.id,
                          non_owner)

        self.log(
            "should not raise an error when checking ownership with owner")
        self.assertEqual(
            self.history_mgr.error_unless_owner(self.trans, item1, owner),
            item1)
        self.assertEqual(
            self.history_mgr.get_owned(self.trans, item1.id, owner), item1)

        self.log(
            "should not raise an error when checking ownership with admin")
        self.assertTrue(
            self.history_mgr.is_owner(self.trans, item1, self.admin_user))
        self.assertEqual(
            self.history_mgr.error_unless_owner(self.trans, item1,
                                                self.admin_user), item1)
        self.assertEqual(
            self.history_mgr.get_owned(self.trans, item1.id, self.admin_user),
            item1)

    def test_accessible(self):
        owner = self.user_mgr.create(self.trans, **user2_data)
        item1 = self.history_mgr.create(self.trans, user=owner)

        non_owner = self.user_mgr.create(self.trans, **user3_data)

        self.log("should be inaccessible by default except to owner")
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, item1, owner))
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, item1, self.admin_user))
        self.assertFalse(
            self.history_mgr.is_accessible(self.trans, item1, non_owner))

        self.log(
            "should raise an error when checking accessibility with non-owner")
        self.assertRaises(exceptions.ItemAccessibilityException,
                          self.history_mgr.error_unless_accessible, self.trans,
                          item1, non_owner)
        self.assertRaises(exceptions.ItemAccessibilityException,
                          self.history_mgr.get_accessible, self.trans,
                          item1.id, non_owner)

        self.log(
            "should not raise an error when checking ownership with owner")
        self.assertEqual(
            self.history_mgr.error_unless_accessible(self.trans, item1, owner),
            item1)
        self.assertEqual(
            self.history_mgr.get_accessible(self.trans, item1.id, owner),
            item1)

        self.log(
            "should not raise an error when checking ownership with admin")
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, item1, self.admin_user))
        self.assertEqual(
            self.history_mgr.error_unless_accessible(self.trans, item1,
                                                     self.admin_user), item1)
        self.assertEqual(
            self.history_mgr.get_accessible(self.trans, item1.id,
                                            self.admin_user), item1)

    def test_importable(self):
        owner = self.user_mgr.create(self.trans, **user2_data)
        self.trans.set_user(owner)
        non_owner = self.user_mgr.create(self.trans, **user3_data)

        item1 = self.history_mgr.create(self.trans, user=owner)

        self.log("should not be importable by default")
        self.assertFalse(item1.importable)
        self.assertIsNone(item1.slug)

        self.log(
            "should be able to make importable (accessible by link) to all users"
        )
        accessible = self.history_mgr.make_importable(self.trans, item1)
        self.assertEqual(accessible, item1)
        self.assertIsNotNone(accessible.slug)
        self.assertTrue(accessible.importable)

        for user in self.user_mgr.list(self.trans):
            self.assertTrue(
                self.history_mgr.is_accessible(self.trans, accessible, user))

        self.log("should be able to make non-importable/inaccessible again")
        inaccessible = self.history_mgr.make_non_importable(
            self.trans, accessible)
        self.assertEqual(inaccessible, accessible)
        self.assertIsNotNone(inaccessible.slug)
        self.assertFalse(inaccessible.importable)

        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, inaccessible, owner))
        self.assertFalse(
            self.history_mgr.is_accessible(self.trans, inaccessible,
                                           non_owner))
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, inaccessible,
                                           self.admin_user))

    def test_published(self):
        owner = self.user_mgr.create(self.trans, **user2_data)
        self.trans.set_user(owner)
        non_owner = self.user_mgr.create(self.trans, **user3_data)

        item1 = self.history_mgr.create(self.trans, user=owner)

        self.log("should not be published by default")
        self.assertFalse(item1.published)
        self.assertIsNone(item1.slug)

        self.log("should be able to publish (listed publicly) to all users")
        published = self.history_mgr.publish(self.trans, item1)
        self.assertEqual(published, item1)
        self.assertTrue(published.published)
        # note: publishing sets importable to true as well
        self.assertTrue(published.importable)
        self.assertIsNotNone(published.slug)

        for user in self.user_mgr.list(self.trans):
            self.assertTrue(
                self.history_mgr.is_accessible(self.trans, published, user))

        self.log("should be able to make non-importable/inaccessible again")
        unpublished = self.history_mgr.unpublish(self.trans, published)
        self.assertEqual(unpublished, published)
        self.assertFalse(unpublished.published)
        # note: unpublishing does not make non-importable, you must explicitly do that separately
        self.assertTrue(published.importable)
        self.history_mgr.make_non_importable(self.trans, unpublished)
        self.assertFalse(published.importable)
        # note: slug still remains after unpublishing
        self.assertIsNotNone(unpublished.slug)

        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, unpublished, owner))
        self.assertFalse(
            self.history_mgr.is_accessible(self.trans, unpublished, non_owner))
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, unpublished,
                                           self.admin_user))

    def test_sharable(self):
        owner = self.user_mgr.create(self.trans, **user2_data)
        self.trans.set_user(owner)
        item1 = self.history_mgr.create(self.trans, user=owner)

        non_owner = self.user_mgr.create(self.trans, **user3_data)
        #third_party = self.user_mgr.create( self.trans, **user4_data )

        self.log("should be unshared by default")
        self.assertEqual(self.history_mgr.get_share_assocs(self.trans, item1),
                         [])
        self.assertEqual(item1.slug, None)

        self.log("should be able to share with specific users")
        share_assoc = self.history_mgr.share_with(self.trans, item1, non_owner)
        self.assertIsInstance(share_assoc, model.HistoryUserShareAssociation)
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, item1, non_owner))
        self.assertEqual(
            len(self.history_mgr.get_share_assocs(self.trans, item1)), 1)
        self.assertEqual(
            len(
                self.history_mgr.get_share_assocs(self.trans,
                                                  item1,
                                                  user=non_owner)), 1)
        self.assertIsInstance(item1.slug, basestring)

        self.log("should be able to unshare with specific users")
        share_assoc = self.history_mgr.unshare_with(self.trans, item1,
                                                    non_owner)
        self.assertIsInstance(share_assoc, model.HistoryUserShareAssociation)
        self.assertFalse(
            self.history_mgr.is_accessible(self.trans, item1, non_owner))
        self.assertEqual(self.history_mgr.get_share_assocs(self.trans, item1),
                         [])
        self.assertEqual(
            self.history_mgr.get_share_assocs(self.trans,
                                              item1,
                                              user=non_owner), [])

    #TODO: test slug formation

    def test_anon(self):
        anon_user = None
        self.trans.set_user(anon_user)

        self.log(
            "should not allow access and owner for anon user on a history by another anon user (None)"
        )
        anon_history1 = self.history_mgr.create(self.trans, user=None)
        self.assertFalse(
            self.history_mgr.is_owner(self.trans, anon_history1, anon_user))
        self.assertFalse(
            self.history_mgr.is_accessible(self.trans, anon_history1,
                                           anon_user))

        self.log(
            "should allow access and owner for anon user on a history if it's the session's current history"
        )
        anon_history2 = self.history_mgr.create(self.trans, user=anon_user)
        self.trans.set_history(anon_history2)
        self.assertTrue(
            self.history_mgr.is_owner(self.trans, anon_history2, anon_user))
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, anon_history2,
                                           anon_user))

        self.log(
            "should not allow owner or access for anon user on someone elses history"
        )
        owner = self.user_mgr.create(self.trans, **user2_data)
        someone_elses = self.history_mgr.create(self.trans, user=owner)
        self.assertFalse(
            self.history_mgr.is_owner(self.trans, someone_elses, anon_user))
        self.assertFalse(
            self.history_mgr.is_accessible(self.trans, someone_elses,
                                           anon_user))

        self.log(
            "should allow access for anon user if the history is published or importable"
        )
        self.history_mgr.make_importable(self.trans, someone_elses)
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, someone_elses,
                                           anon_user))
        self.history_mgr.publish(self.trans, someone_elses)
        self.assertTrue(
            self.history_mgr.is_accessible(self.trans, someone_elses,
                                           anon_user))

    def test_delete_and_purge(self):
        user2 = self.user_mgr.create(self.trans, **user2_data)
        self.trans.set_user(user2)

        history1 = self.history_mgr.create(self.trans,
                                           name='history1',
                                           user=user2)
        self.trans.set_history(history1)

        self.assertFalse(history1.deleted)

        self.history_mgr.delete(self.trans, history1)
        self.assertTrue(history1.deleted)

        self.history_mgr.undelete(self.trans, history1)
        self.assertFalse(history1.deleted)

        history2 = self.history_mgr.create(self.trans,
                                           name='history2',
                                           user=user2)
        self.history_mgr.purge(self.trans, history1)
        self.assertTrue(history1.purged)

    def test_histories(self):
        user2 = self.user_mgr.create(self.trans, **user2_data)
        self.trans.set_user(user2)

        history1 = self.history_mgr.create(self.trans,
                                           name='history1',
                                           user=user2)
        self.trans.set_history(history1)
        history2 = self.history_mgr.create(self.trans,
                                           name='history2',
                                           user=user2)

        self.log("should be able to set or get the current history for a user")
        self.assertEqual(self.history_mgr.get_current(self.trans), history1)
        self.assertEqual(self.history_mgr.set_current(self.trans, history2),
                         history2)
        self.assertEqual(self.history_mgr.get_current(self.trans), history2)
        self.assertEqual(
            self.history_mgr.set_current_by_id(self.trans, history1.id),
            history1)
        self.assertEqual(self.history_mgr.get_current(self.trans), history1)