PageRenderTime 80ms CodeModel.GetById 6ms app.highlight 65ms RepoModel.GetById 2ms app.codeStats 0ms

/test/functional/test_history_functions.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 900 lines | 810 code | 19 blank | 71 comment | 47 complexity | b3d6a5cd2e8f7352e74bd0d84f505814 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1import urllib
  2import galaxy.model
  3from galaxy.model.orm import *
  4from base.test_db_util import sa_session
  5from base.twilltestcase import *
  6
  7
  8class TestHistory( TwillTestCase ):
  9
 10    def test_000_history_behavior_between_logout_login( self ):
 11        """Testing history behavior between logout and login"""
 12        self.logout()
 13        self.history_options()
 14        # Create a new, empty history named anonymous
 15        name = 'anonymous'
 16        self.new_history( name=name )
 17        global anonymous_history
 18        anonymous_history = (
 19            sa_session.query( galaxy.model.History )
 20                .filter( and_( galaxy.model.History.table.c.deleted == False, galaxy.model.History.table.c.name == name ) )
 21                .order_by( desc( galaxy.model.History.table.c.create_time ) )
 22                .first()
 23        )
 24        assert anonymous_history is not None, "Problem retrieving anonymous_history from database"
 25        # Upload a dataset to anonymous_history so it will be set as the current history after login
 26        self.upload_file( '1.bed', dbkey='hg18' )
 27        self.login( email='test1@bx.psu.edu', username='regular-user1' )
 28        global regular_user1
 29        regular_user1 = sa_session.query( galaxy.model.User ) \
 30                                  .filter( galaxy.model.User.table.c.email == 'test1@bx.psu.edu' ) \
 31                                  .first()
 32        assert regular_user1 is not None, 'Problem retrieving user with email "test1@bx.psu.edu" from the database'
 33        # Current history should be anonymous_history
 34        self.check_history_for_string( name )
 35        self.logout()
 36        # Login as the same user again to ensure anonymous_history is still the current history
 37        self.login( email=regular_user1.email )
 38        self.check_history_for_string( name )
 39        self.logout()
 40        self.login( email='test2@bx.psu.edu', username='regular-user2' )
 41        global regular_user2
 42        regular_user2 = sa_session.query( galaxy.model.User ) \
 43                                  .filter( galaxy.model.User.table.c.email == 'test2@bx.psu.edu' ) \
 44                                  .first()
 45        assert regular_user2 is not None, 'Problem retrieving user with email "test2@bx.psu.edu" from the database'
 46        self.logout()
 47        self.login( email='test3@bx.psu.edu', username='regular-user3' )
 48        global regular_user3
 49        regular_user3 = sa_session.query( galaxy.model.User ) \
 50                                  .filter( galaxy.model.User.table.c.email == 'test3@bx.psu.edu' ) \
 51                                  .first()
 52        assert regular_user3 is not None, 'Problem retrieving user with email "test3@bx.psu.edu" from the database'
 53        self.logout()
 54        self.login( email='test@bx.psu.edu', username='admin-user' )
 55        global admin_user
 56        admin_user = sa_session.query( galaxy.model.User ) \
 57                               .filter( galaxy.model.User.table.c.email == 'test@bx.psu.edu' ) \
 58                               .one()
 59        assert admin_user is not None, 'Problem retrieving user with email "test@bx.psu.edu" from the database'
 60        # Get the admin_user private role for later use
 61        global admin_user_private_role
 62        admin_user_private_role = None
 63        for role in admin_user.all_roles():
 64            if role.name == admin_user.email and role.description == 'Private Role for %s' % admin_user.email:
 65                admin_user_private_role = role
 66                break
 67        if not admin_user_private_role:
 68            raise AssertionError( "Private role not found for user '%s'" % admin_user.email )
 69        historyA = sa_session.query( galaxy.model.History ) \
 70                             .filter( and_( galaxy.model.History.table.c.deleted == False,
 71                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
 72                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
 73                             .first()
 74        assert historyA is not None, "Problem retrieving historyA from database"
 75        assert not historyA.deleted, "After login, historyA is deleted"
 76        # Make sure the last used history is set for the next session after login
 77        self.logout()
 78        self.login( email=admin_user.email )
 79        historyB = sa_session.query( galaxy.model.History ) \
 80                             .filter( and_( galaxy.model.History.table.c.deleted == False,
 81                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
 82                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
 83                             .first()
 84        assert historyB is not None, "Problem retrieving historyB from database"
 85        assert historyA.id == historyB.id, "After the same user logged out and back in, their last used history was not associated with their new session"
 86
 87    def test_005_deleting_histories( self ):
 88        """Testing deleting histories"""
 89        # Logged in as admin_user
 90        historyB = sa_session.query( galaxy.model.History ) \
 91                             .filter( and_( galaxy.model.History.table.c.deleted == False,
 92                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
 93                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
 94                             .first()
 95        assert historyB is not None, "Problem retrieving historyB from database"
 96        self.delete_history( self.security.encode_id( historyB.id ) )
 97        sa_session.refresh( historyB )
 98        if not historyB.deleted:
 99            raise AssertionError( "Problem deleting history id %d" % historyB.id )
100        # Since we deleted the current history, make sure the history frame was refreshed
101        self.check_history_for_string( 'Your history is empty.' )
102        # We'll now test deleting a list of histories
103        # After deleting the current history, a new one should have been created
104        global history1
105        history1 = sa_session.query( galaxy.model.History ) \
106                             .filter( and_( galaxy.model.History.table.c.deleted == False,
107                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
108                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
109                             .first()
110        assert history1 is not None, "Problem retrieving history1 from database"
111        self.upload_file( '1.bed', dbkey='hg18' )
112        self.new_history( name=urllib.quote( 'history2' ) )
113        global history2
114        history2 = sa_session.query( galaxy.model.History ) \
115                             .filter( and_( galaxy.model.History.table.c.deleted == False,
116                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
117                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
118                             .first()
119        assert history2 is not None, "Problem retrieving history2 from database"
120        self.upload_file( '2.bed', dbkey='hg18' )
121        ids = '%s,%s' % ( self.security.encode_id( history1.id ), self.security.encode_id( history2.id ) )
122        self.delete_history( ids )
123        # Since we deleted the current history, make sure the history frame was refreshed
124        self.check_history_for_string( 'Your history is empty.' )
125        try:
126            self.view_stored_active_histories( strings_displayed=[ history1.name ] )
127            raise AssertionError( "History %s is displayed in the active history list after it was deleted" % history1.name )
128        except:
129            pass
130        self.view_stored_deleted_histories( strings_displayed=[ history1.name ] )
131        try:
132            self.view_stored_active_histories( strings_displayed=[ history2.name ] )
133            raise AssertionError( "History %s is displayed in the active history list after it was deleted" % history2.name )
134        except:
135            pass
136        self.view_stored_deleted_histories( strings_displayed=[ history2.name ] )
137        sa_session.refresh( history1 )
138        if not history1.deleted:
139            raise AssertionError( "Problem deleting history id %d" % history1.id )
140        if not history1.default_permissions:
141            raise AssertionError( "Default permissions were incorrectly deleted from the db for history id %d when it was deleted" % history1.id )
142        sa_session.refresh( history2 )
143        if not history2.deleted:
144            raise AssertionError( "Problem deleting history id %d" % history2.id )
145        if not history2.default_permissions:
146            raise AssertionError( "Default permissions were incorrectly deleted from the db for history id %d when it was deleted" % history2.id )
147        # Current history is empty
148        self.history_options( user=True )
149
150    def test_010_history_rename( self ):
151        """Testing renaming a history"""
152        # Logged in as admin_user
153        global history3
154        history3 = sa_session.query( galaxy.model.History ) \
155                             .filter( galaxy.model.History.table.c.deleted == False ) \
156                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
157                             .first()
158        assert history3 is not None, "Problem retrieving history3 from database"
159        if history3.deleted:
160            raise AssertionError( "History id %d deleted when it should not be" % latest_history.id )
161        self.rename_history( self.security.encode_id( history3.id ), history3.name, new_name=urllib.quote( 'history 3' ) )
162        sa_session.refresh( history3 )
163
164    def test_015_history_list( self ):
165        """Testing viewing previously stored active histories"""
166        # Logged in as admin_user
167        self.view_stored_active_histories()
168
169    def test_020_share_current_history( self ):
170        """Testing sharing the current history which contains only public datasets"""
171        # Logged in as admin_user
172        # Test sharing an empty history - current history is history3
173        self.share_current_history( regular_user1.email,
174                                    strings_displayed=[ history3.name ],
175                                    strings_displayed_after_submit=[ 'You cannot share an empty history.' ] )
176        # Make history3 sharable by adding a dataset
177        self.upload_file( '1.bed', dbkey='hg18' )
178        # Current history is no longer empty
179        self.history_options( user=True, active_datasets=True, activatable_datasets=True )
180        # Test sharing history3 with yourself
181        self.share_current_history( admin_user.email,
182                                    strings_displayed=[ history3.name ],
183                                    strings_displayed_after_submit=[ 'You cannot send histories to yourself.' ] )
184        # Share history3 with 1 valid user
185        self.share_current_history( regular_user1.email,
186                                    strings_displayed=[ history3.name ] )
187        # Check out list of histories to make sure history3 was shared
188        self.view_stored_active_histories( strings_displayed=[ 'operation=share' ] )
189        # Make history3 accessible via link.
190        self.make_accessible_via_link( self.security.encode_id( history3.id ),
191                                     strings_displayed=[ 'Make History Accessible via Link' ],
192                                     strings_displayed_after_submit=[ 'Anyone can view and import this history' ] )
193        # Make sure history3 is now accessible.
194        sa_session.refresh( history3 )
195        if not history3.importable:
196            raise AssertionError( "History 3 is not marked as importable after make_accessible_via_link" )
197        # Try importing history3
198        #Importing your own history was enabled in 5248:dc9efb540f61.
199        #self.import_history_via_url( self.security.encode_id( history3.id ),
200        #                             admin_user.email,
201        #                             strings_displayed_after_submit=[ 'You cannot import your own history.' ] )
202        # Disable access via link for history3.
203        self.disable_access_via_link( self.security.encode_id( history3.id ),
204                                     strings_displayed=[ 'Anyone can view and import this history' ],
205                                     strings_displayed_after_submit=[ 'Make History Accessible via Link' ] )
206        # Try importing history3 after disabling access via link. To do this, need to login as regular user 2, who cannot access
207        # history via sharing or via link.
208        self.logout()
209        self.login( email=regular_user2.email )
210        self.import_history_via_url( self.security.encode_id( history3.id ),
211                                     admin_user.email,
212                                     strings_displayed_after_submit=[ 'History is not accessible to the current user' ] )
213        self.logout()
214        self.login( email=admin_user.email )
215        # Test sharing history3 with an invalid user
216        self.share_current_history( 'jack@jill.com',
217                                    strings_displayed_after_submit=[ 'jack@jill.com is not a valid Galaxy user.' ] )
218
219    def test_025_delete_shared_current_history( self ):
220        """Testing deleting the current history after it was shared"""
221        # Logged in as admin_user
222        self.delete_current_history(
223            strings_displayed=[ "History (%s) has been shared with others, unshare it before deleting it." % history3.name ] )
224
225    def test_030_clone_shared_history( self ):
226        """Testing copying a shared history"""
227        # logged in as admin user
228        self.logout()
229        self.login( email=regular_user1.email )
230        # Shared history3 affects history options
231        self.history_options( user=True, histories_shared_by_others=True )
232        # Shared history3 should be in regular_user1's list of shared histories
233        self.view_shared_histories( strings_displayed=[ history3.name, admin_user.email ] )
234        self.copy_history( self.security.encode_id( history3.id ),
235                            'activatable',
236                            strings_displayed_after_submit=[ 'has been created.' ] )
237        global history3_clone1
238        history3_clone1 = sa_session.query( galaxy.model.History ) \
239                                    .filter( and_( galaxy.model.History.table.c.deleted == False,
240                                                   galaxy.model.History.table.c.user_id == regular_user1.id ) ) \
241                                    .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
242                                    .first()
243        assert history3_clone1 is not None, "Problem retrieving history3_clone1 from database"
244        # Check list of histories to make sure shared history3 was cloned
245        strings_displayed = [ "Copy of '%s' shared by '%s'" % ( history3.name, admin_user.email ) ]
246        self.view_stored_active_histories( strings_displayed=strings_displayed )
247
248    def test_035_clone_current_history( self ):
249        """Testing copying the current history"""
250        # logged in as regular_user1
251        self.logout()
252        self.login( email=admin_user.email )
253
254        # Current history should be history3, add more datasets to history3, then delete them so we can
255        # test cloning activatable datasets as well as only the active datasets
256        self.upload_file( '2.bed', dbkey='hg18' )
257        hda_2_bed = (
258            sa_session.query( galaxy.model.HistoryDatasetAssociation )
259                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history3.id,
260                               galaxy.model.HistoryDatasetAssociation.table.c.name == '2.bed' ) )
261                .first() )
262        assert hda_2_bed is not None, "Problem retrieving hda_2_bed from database"
263        self.delete_history_item( str( hda_2_bed.id ) )
264
265        self.upload_file( '3.bed', dbkey='hg18' )
266        hda_3_bed = (
267            sa_session.query( galaxy.model.HistoryDatasetAssociation )
268                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history3.id,
269                               galaxy.model.HistoryDatasetAssociation.table.c.name == '3.bed' ) )
270                .first() )
271        assert hda_3_bed is not None, "Problem retrieving hda_3_bed from database"
272        self.delete_history_item( str( hda_3_bed.id ) )
273
274        # Test cloning activatable datasets
275        self.copy_history( self.security.encode_id( history3.id ),
276                            'activatable',
277                            strings_displayed_after_submit=['has been created.' ] )
278        global history3_clone2
279        history3_clone2 = sa_session.query( galaxy.model.History ) \
280                                    .filter( and_( galaxy.model.History.table.c.deleted == False,
281                                                   galaxy.model.History.table.c.user_id == admin_user.id ) ) \
282                                    .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
283                                    .first()
284        assert history3_clone2 is not None, "Problem retrieving history3_clone2 from database"
285
286        # Check list of histories to make sure shared history3 was cloned
287        self.view_stored_active_histories( strings_displayed=[ "Copy of '%s'" % history3.name ] )
288        # Switch to the cloned history to make sure activatable datasets were cloned
289        self.switch_history( id=self.security.encode_id( history3_clone2.id ), name=history3_clone2.name )
290        hda_2_bed = (
291            sa_session.query( galaxy.model.HistoryDatasetAssociation )
292                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history3_clone2.id,
293                               galaxy.model.HistoryDatasetAssociation.table.c.name == '2.bed' ) )
294                .first() )
295        assert hda_2_bed is not None, "Problem retrieving hda_2_bed from database"
296        hda_3_bed = (
297            sa_session.query( galaxy.model.HistoryDatasetAssociation )
298                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history3_clone2.id,
299                               galaxy.model.HistoryDatasetAssociation.table.c.name == '3.bed' ) )
300                .first() )
301        assert hda_3_bed is not None, "Problem retrieving hda_3_bed from database"
302
303        # Make sure the deleted datasets are included in the cloned history
304        # check for encoded ids
305        #   - these will be available bc the refreshed page will have bootstrapped json for the hdas
306        #NOTE: that these WON'T be available when refreshes become less common
307        #   (when the backbone.js is fully integrated and refreshes aren't used after every history function)
308        self.check_history_for_exact_string( self.security.encode_id( hda_2_bed.id ), show_deleted=True )
309        self.check_history_for_exact_string( self.security.encode_id( hda_3_bed.id ), show_deleted=True )
310
311        # Test cloning only active datasets
312        self.copy_history(
313            self.security.encode_id( history3.id ),
314            'active',
315            strings_displayed_after_submit=[ 'has been created.' ] )
316        global history3_clone3
317        history3_clone3 = (
318            sa_session.query( galaxy.model.History )
319                .filter( and_( galaxy.model.History.table.c.deleted == False,
320                               galaxy.model.History.table.c.user_id == admin_user.id ) )
321                .order_by( desc( galaxy.model.History.table.c.create_time ) )
322                .first()
323        )
324        assert history3_clone3 is not None, "Problem retrieving history3_clone3 from database"
325
326        # Check list of histories to make sure shared history3 was cloned
327        self.view_stored_active_histories( strings_displayed=[ "Copy of '%s'" % history3.name ] )
328
329        # Switch to the cloned history to make sure ONLY activatable datasets were cloned
330        self.switch_history( id=self.security.encode_id( history3_clone3.id ) )
331        # Make sure the deleted datasets are NOT included in the cloned history
332        #   - again using the bootstrapped json for the hdas
333        try:
334            self.check_history_for_exact_string( '"deleted": true', show_deleted=True )
335            #self.check_history_for_string( 'This dataset has been deleted.', show_deleted=True )
336            raise AssertionError( "Deleted datasets incorrectly included in cloned history history3_clone3" )
337        except:
338            pass
339
340    def test_040_sharing_mulitple_histories_with_multiple_users( self ):
341        """Testing sharing multiple histories containing only public datasets with multiple users"""
342        # Logged in as admin_user
343        self.new_history()
344        global history4
345        history4 = sa_session.query( galaxy.model.History ) \
346                             .filter( and_( galaxy.model.History.table.c.deleted == False,
347                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
348                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
349                             .first()
350        assert history4 is not None, "Problem retrieving history4 from database"
351        self.rename_history( self.security.encode_id( history4.id ), history4.name, new_name=urllib.quote( 'history 4' ) )
352        sa_session.refresh( history4 )
353        # Galaxy's new history sharing code does not yet support sharing multiple histories; when support for sharing multiple histories is added,
354        # this test will be uncommented and updated.
355        """
356        self.upload_file( '2.bed', dbkey='hg18' )
357        ids = '%s,%s' % ( self.security.encode_id( history3.id ), self.security.encode_id( history4.id ) )
358        emails = '%s,%s' % ( regular_user2.email, regular_user3.email )
359        self.share_histories_with_users( ids,
360                                         emails,
361                                         strings_displayed=[ 'Share 2 histories', history4.name ] )
362        self.logout()
363        self.login( email=regular_user2.email )
364        # Shared history3 should be in regular_user2's list of shared histories
365        self.view_shared_histories( strings_displayed=[ history3.name, admin_user.email ] )
366        self.logout()
367        self.login( email=regular_user3.email )
368        # Shared history3 should be in regular_user3's list of shared histories
369        self.view_shared_histories( cstrings_displayed=[ history3.name, admin_user.email ] )
370        """
371
372    def test_045_change_permissions_on_current_history( self ):
373        """Testing changing permissions on the current history"""
374        # Logged in as regular_user3
375        self.logout()
376        self.login( email=admin_user.email )
377        # Current history is history4
378        self.new_history()
379        global history5
380        history5 = sa_session.query( galaxy.model.History ) \
381                             .filter( and_( galaxy.model.History.table.c.deleted == False,
382                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
383                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
384                             .first()
385        assert history5 is not None, "Problem retrieving history5 from database"
386        self.rename_history( self.security.encode_id( history5.id ), history5.name, new_name=urllib.quote( 'history 5' ) )
387        # Current history is history5
388        sa_session.refresh( history5 )
389        # Due to the limitations of twill ( not functional with the permissions forms ), we're forced
390        # to do this manually.  At this point, we just want to restrict the access permission on history5
391        # to the admin_user
392        global access_action
393        access_action = galaxy.model.Dataset.permitted_actions.DATASET_ACCESS.action
394        dhp = galaxy.model.DefaultHistoryPermissions( history5, access_action, admin_user_private_role )
395        sa_session.add( dhp )
396        sa_session.flush()
397        sa_session.refresh( history5 )
398        global history5_default_permissions
399        history5_default_permissions = [ dhp.action for dhp in history5.default_permissions ]
400        # Sort for later comparison
401        history5_default_permissions.sort()
402        self.upload_file( '1.bed', dbkey='hg18' )
403        history5_dataset1 = None
404        for hda in history5.datasets:
405            if hda.name == '1.bed':
406                history5_dataset1 = hda.dataset
407                break
408        assert history5_dataset1 is not None, "Problem retrieving history5_dataset1 from the database"
409        # The permissions on the dataset should be restricted from sharing with anyone due to the
410        # inherited history permissions
411        dataset_permissions = [ a.action for a in history5_dataset1.actions ]
412        dataset_permissions.sort()
413        if dataset_permissions != history5_default_permissions:
414            err_msg = "Dataset permissions for history5_dataset1 (%s) were not correctly inherited from history permissions (%s)" \
415                % ( str( dataset_permissions ), str( history5_default_permissions ) )
416            raise AssertionError( err_msg )
417        # Make sure when we logout and login, the history default permissions are preserved
418        self.logout()
419        self.login( email=admin_user.email )
420        sa_session.refresh( history5 )
421        current_history_permissions = [ dhp.action for dhp in history5.default_permissions ]
422        current_history_permissions.sort()
423        if current_history_permissions != history5_default_permissions:
424            raise AssertionError( "With logout and login, the history default permissions are not preserved" )
425
426    def test_050_sharing_restricted_history_by_making_datasets_public( self ):
427        """Testing sharing a restricted history by making the datasets public"""
428        # Logged in as admin_user
429        action_strings_displayed = [ 'The following datasets can be shared with %s by updating their permissions' % regular_user1.email ]
430        # Current history is history5
431        self.share_current_history( regular_user1.email,
432                                    action='public',
433                                    action_strings_displayed=action_strings_displayed )
434        self.logout()
435        self.login( email=regular_user1.email )
436        # Shared history5 should be in regular_user1's list of shared histories
437        self.view_shared_histories( strings_displayed=[ history5.name, admin_user.email ] )
438        # Clone restricted history5
439        self.copy_history( self.security.encode_id( history5.id ),
440                            'activatable',
441                            strings_displayed_after_submit=[ 'has been created.' ] )
442        global history5_clone1
443        history5_clone1 = sa_session.query( galaxy.model.History ) \
444                                    .filter( and_( galaxy.model.History.table.c.deleted == False,
445                                                   galaxy.model.History.table.c.user_id == regular_user1.id ) ) \
446                                    .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
447                                    .first()
448        assert history5_clone1 is not None, "Problem retrieving history5_clone1 from database"
449        # Check list of histories to make sure shared history5 was cloned
450        self.view_stored_active_histories( strings_displayed=[ "Copy of '%s'" % history5.name ] )
451        # Make sure the dataset is accessible
452        self.switch_history( id=self.security.encode_id( history5_clone1.id ), name=history5_clone1.name )
453        self.check_history_for_string( 'chr1' )
454        self.logout()
455        self.login( email=admin_user.email )
456
457    def test_055_sharing_restricted_history_by_making_new_sharing_role( self ):
458        """Testing sharing a restricted history by associating a new sharing role with protected datasets"""
459        # At this point, history5 should have 1 item, 1.bed, which is public.  We'll add another
460        # item which will be private to admin_user due to the permissions on history5
461        self.upload_file( '2.bed', dbkey='hg18' )
462        strings_displayed_after_submit = [ 'The following datasets can be shared with %s with no changes' % regular_user2.email,
463                                         'The following datasets can be shared with %s by updating their permissions' % regular_user2.email ]
464        self.share_current_history( regular_user2.email,
465                                    strings_displayed_after_submit=strings_displayed_after_submit,
466                                    action='private' )
467        # We should now have a new sharing role
468        global sharing_role
469        role_name = 'Sharing role for: %s, %s' % ( admin_user.email, regular_user2.email )
470        sharing_role = sa_session.query( galaxy.model.Role ).filter( galaxy.model.Role.table.c.name == role_name ).first()
471        if not sharing_role:
472            # May have created a sharing role in a previous functional test suite from the opposite direction.
473            role_name = 'Sharing role for: %s, %s' % ( regular_user2.email, admin_user.email )
474            sharing_role = sa_session.query( galaxy.model.Role ) \
475                                     .filter( and_( galaxy.model.Role.table.c.type == role_type,
476                                                    galaxy.model.Role.table.c.name == role_name ) ) \
477                                     .first()
478        if not sharing_role:
479            raise AssertionError( "Privately sharing a dataset did not properly create a sharing role" )
480        # The DATASET_ACCESS permission on 2.bed was originally associated with admin_user's private role.
481        # Since we created a new sharing role for 2.bed, the original permission should have been eliminated,
482        # replaced with the sharing role.
483        history5_dataset2 = None
484        for hda in history5.datasets:
485            if hda.name == '2.bed':
486                history5_dataset2 = hda.dataset
487                break
488        assert history5_dataset2 is not None, "Problem retrieving history5_dataset2 from the database"
489        for dp in history5_dataset2.actions:
490            if dp.action == 'access':
491                assert dp.role == sharing_role, "Associating new sharing role with history5_dataset2 did not correctly eliminate original DATASET ACCESS permissions"
492        self.logout()
493        self.login( email=regular_user2.email )
494        # Shared history5 should be in regular_user2's list of shared histories
495        self.view_shared_histories( strings_displayed=[ history5.name, admin_user.email ] )
496        # Clone restricted history5
497        self.copy_history( self.security.encode_id( history5.id ),
498                            'activatable',
499                            strings_displayed_after_submit=[ 'has been created.' ] )
500        global history5_clone2
501        history5_clone2 = sa_session.query( galaxy.model.History ) \
502                                    .filter( and_( galaxy.model.History.table.c.deleted == False,
503                                                   galaxy.model.History.table.c.user_id == regular_user2.id ) ) \
504                                    .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
505                                    .first()
506        assert history5_clone2 is not None, "Problem retrieving history5_clone2 from database"
507        # Check list of histories to make sure shared history3 was cloned
508        self.view_stored_active_histories( strings_displayed=[ "Copy of '%s'" % history5.name ] )
509        # Make sure the dataset is accessible
510        self.switch_history( id=self.security.encode_id( history5_clone2.id ), name=history5_clone2.name )
511       # Make sure both datasets are in the history
512        self.check_history_for_string( '1.bed' )
513        self.check_history_for_string( '2.bed' )
514        # Get both new hdas from the db that were created for the shared history
515        hda_1_bed = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \
516                              .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history5_clone2.id,
517                                             galaxy.model.HistoryDatasetAssociation.table.c.name == '1.bed' ) ) \
518                              .first()
519        assert hda_1_bed is not None, "Problem retrieving hda_1_bed from database"
520        hda_2_bed = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \
521                              .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history5_clone2.id,
522                                             galaxy.model.HistoryDatasetAssociation.table.c.name == '2.bed' ) ) \
523                              .first()
524        assert hda_2_bed is not None, "Problem retrieving hda_2_bed from database"
525        # Make sure 1.bed is accessible since it is public
526        self.display_history_item( str( hda_1_bed.id ), strings_displayed=[ 'chr1' ] )
527        # Make sure 2.bed is accessible since it is associated with a sharing role
528        self.display_history_item( str( hda_2_bed.id ), strings_displayed=[ 'chr1' ] )
529        # Delete the clone so the next test will be valid
530        self.delete_history( id=self.security.encode_id( history5_clone2.id ) )
531
532    def test_060_sharing_restricted_history_with_multiple_users_by_changing_no_permissions( self ):
533        """Testing sharing a restricted history with multiple users, making no permission changes"""
534        # Logged in as regular_user2
535        self.logout()
536        self.login( email=admin_user.email )
537        # History5 can be shared with any user, since it contains a public dataset ( 1.bed ).  However, only
538        # regular_user2 should be able to access history5's 2.bed dataset since it is associated with a
539        # sharing role, and regular_user3 should be able to access history5's 1.bed, but not 2.bed even
540        # though they can see it in their shared history.
541
542        # We first need to unshare history5 from regular_user2 so that we can re-share it.
543        self.unshare_history( self.security.encode_id( history5.id ),
544                              self.security.encode_id( regular_user2.id ),
545                              strings_displayed=[ regular_user1.email, regular_user2.email ] )
546
547        # Make sure the history was unshared correctly
548        self.logout()
549        self.login( email=regular_user2.email )
550        self.visit_page( "root/history_options" )
551        try:
552            self.check_page_for_string( 'List</a> histories shared with you by others' )
553            raise AssertionError( "history5 still shared with regular_user2 after unsharing it with that user." )
554        except:
555            pass
556
557        self.logout()
558        self.login( admin_user.email )
559        email = '%s,%s' % ( regular_user2.email, regular_user3.email )
560        strings_displayed_after_submit = [
561            'The following datasets can be shared with %s with no changes' % email,
562            'The following datasets can be shared with %s by updating their permissions' % email
563        ]
564
565        # history5 will be shared with regular_user1, regular_user2 and regular_user3
566        self.share_current_history( email,
567                                    strings_displayed_after_submit=strings_displayed_after_submit,
568                                    action='share_anyway' )
569        # Check security on copy of history5 for regular_user2
570        self.logout()
571        self.login( email=regular_user2.email )
572        # Shared history5 should be in regular_user2's list of shared histories
573        self.view_shared_histories( strings_displayed=[ history5.name, admin_user.email ] )
574        # Clone restricted history5
575        self.copy_history( self.security.encode_id( history5.id ),
576                            'activatable',
577                            strings_displayed_after_submit=[ 'has been created.' ] )
578        global history5_clone3
579        history5_clone3 = (
580            sa_session.query( galaxy.model.History )
581                .filter( and_( galaxy.model.History.table.c.deleted == False,
582                               galaxy.model.History.table.c.user_id == regular_user2.id ) )
583                .order_by( desc( galaxy.model.History.table.c.create_time ) )
584                .first() )
585        assert history5_clone3 is not None, "Problem retrieving history5_clone3 from database"
586
587        # Check list of histories to make sure shared history3 was cloned
588        self.view_stored_active_histories( strings_displayed=[ "Copy of '%s'" % history5.name ] )
589        # Make sure the dataset is accessible
590        self.switch_history( id=self.security.encode_id( history5_clone3.id ), name=history5_clone3.name )
591        # Make sure both datasets are in the history
592        self.check_history_for_string( '1.bed' )
593        self.check_history_for_string( '2.bed' )
594        # Get both new hdas from the db that were created for the shared history
595        hda_1_bed = (
596            sa_session.query( galaxy.model.HistoryDatasetAssociation )
597                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history5_clone3.id,
598                               galaxy.model.HistoryDatasetAssociation.table.c.name == '1.bed' ) )
599                .first() )
600        assert hda_1_bed is not None, "Problem retrieving hda_1_bed from database"
601        hda_2_bed = (
602            sa_session.query( galaxy.model.HistoryDatasetAssociation )
603                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history5_clone3.id,
604                               galaxy.model.HistoryDatasetAssociation.table.c.name == '2.bed' ) )
605                .first() )
606        assert hda_2_bed is not None, "Problem retrieving hda_2_bed from database"
607
608        # Make sure 1.bed is accessible since it is public
609        self.display_history_item( str( hda_1_bed.id ), strings_displayed=[ 'chr1' ] )
610        # Make sure 2.bed is accessible since it is associated with a sharing role
611        self.display_history_item( str( hda_2_bed.id ), strings_displayed=[ 'chr1' ] )
612        # Delete the clone so the next test will be valid
613        self.delete_history( id=self.security.encode_id( history5_clone3.id ) )
614        # Check security on copy of history5 for regular_user3
615        self.logout()
616        self.login( email=regular_user3.email )
617        # Shared history5 should be in regular_user2's list of shared histories
618        self.view_shared_histories( strings_displayed=[ history5.name, admin_user.email ] )
619
620        # Clone restricted history5
621        self.copy_history( self.security.encode_id( history5.id ),
622                            'activatable',
623                            strings_displayed_after_submit=[ 'has been created.' ] )
624        global history5_clone4
625        history5_clone4 = (
626            sa_session.query( galaxy.model.History )
627                .filter( and_( galaxy.model.History.table.c.deleted == False,
628                               galaxy.model.History.table.c.user_id == regular_user3.id ) )
629                .order_by( desc( galaxy.model.History.table.c.create_time ) )
630                .first() )
631        assert history5_clone4 is not None, "Problem retrieving history5_clone4 from database"
632
633        # Check list of histories to make sure shared history3 was cloned
634        self.view_stored_active_histories( strings_displayed=[ "Copy of '%s'" % history5.name ] )
635        # Make sure the dataset is accessible
636        self.switch_history( id=self.security.encode_id( history5_clone4.id ), name=history5_clone4.name )
637        # Make sure both datasets are in the history
638        self.check_history_for_string( '1.bed' )
639        self.check_history_for_string( '2.bed' )
640        # Get both new hdas from the db that were created for the shared history
641        hda_1_bed = (
642            sa_session.query( galaxy.model.HistoryDatasetAssociation )
643                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history5_clone4.id,
644                               galaxy.model.HistoryDatasetAssociation.table.c.name == '1.bed' ) )
645                .first() )
646        assert hda_1_bed is not None, "Problem retrieving hda_1_bed from database"
647        hda_2_bed = (
648            sa_session.query( galaxy.model.HistoryDatasetAssociation )
649                .filter( and_( galaxy.model.HistoryDatasetAssociation.table.c.history_id == history5_clone4.id,
650                               galaxy.model.HistoryDatasetAssociation.table.c.name == '2.bed' ) )
651                .first() )
652        assert hda_2_bed is not None, "Problem retrieving hda_2_bed from database"
653        # Make sure 1.bed is accessible since it is public
654        self.display_history_item( str( hda_1_bed.id ), strings_displayed=[ 'chr1' ] )
655        # Make sure 2.bed is not accessible since it is protected
656        try:
657            self.display_history_item( str( hda_2_bed.id ), strings_displayed=[ 'chr1' ] )
658            raise AssertionError( "History item 2.bed is accessible by user %s when is should not be" % regular_user3.email )
659        except:
660            pass
661
662        # check the history page json for hda_2_bed and if it's accessible
663        def hda_2_bed_is_inaccessible( hda_list ):
664            for hda in hda_list:
665                if hda[ 'id' ] == self.security.encode_id( hda_2_bed.id ):
666                    return ( not hda[ 'accessible' ] )
667            return False
668        self.check_history_json( r'\bhdaJSON\s*=\s*(.*);', hda_2_bed_is_inaccessible )
669
670        # Admin users can view all datasets ( using the history/view feature ), so make sure 2.bed is accessible to the admin
671        self.logout()
672        self.login( email=admin_user.email )
673        self.view_history( str( hda_2_bed.history_id ), strings_displayed=[ '<td>NM_005997_cds_0_0_chr1_147962193_r</td>' ] )
674        self.logout()
675        self.login( email=regular_user3.email )
676
677        # Delete the clone so the next test will be valid
678        self.delete_history( id=self.security.encode_id( history5_clone4.id ) )
679
680    def test_065_sharing_private_history_by_choosing_to_not_share( self ):
681        """Testing sharing a restricted history with multiple users by choosing not to share"""
682        # Logged in as regular_user3 - login as admin
683        self.logout()
684        self.login( email=admin_user.email )
685
686        # Unshare history5 from regular_user2
687        self.unshare_history( self.security.encode_id( history5.id ),
688                              self.security.encode_id( regular_user2.id ),
689                              strings_displayed=[ regular_user1.email, regular_user2.email ] )
690        # Unshare history5 from regular_user3
691        self.unshare_history( self.security.encode_id( history5.id ),
692                              self.security.encode_id( regular_user3.id ),
693                              strings_displayed=[ regular_user1.email, regular_user3.email ] )
694
695        # Make sure the histories were unshared correctly
696        self.logout()
697        self.login( email=regular_user2.email )
698        self.visit_page( "root/history_options" )
699        try:
700            self.check_page_for_string( 'List</a> histories shared with you by others' )
701            raise AssertionError( "history5 still shared with regular_user2 after unshaing it with that user." )
702        except:
703            pass
704
705        self.logout()
706        self.login( email=regular_user3.email )
707        self.visit_page( "root/history_options" )
708        try:
709            self.check_page_for_string( 'List</a> histories shared with you by others' )
710            raise AssertionError( "history5 still shared with regular_user3 after unshaing it with that user." )
711        except:
712            pass
713        self.logout()
714        self.login( email=admin_user.email )
715
716    def test_070_history_show_and_hide_deleted_datasets( self ):
717        """Testing displaying deleted history items"""
718        #NOTE: due to the new client-side rendering of the history, this test isn't very apt
719        #   (a) searching for strings in the dom doesn't work (they won't be twill's html) and
720        #   (b) all datasets are included in the bootstrapped hda json regardless of the show_deleted setting
721        #CE: for now, I'm changing this to simply check whether the show_deleted flag
722        #   is being properly passed to the history control
723        #TODO: this test needs to be moved to client-side testing framework (selenium or other)
724
725        # Logged in as admin_user
726        # create a new history and upload a new hda (1.bed) into it
727        self.new_history( name=urllib.quote( 'show hide deleted datasets' ) )
728        latest_history = (
729            sa_session.query( galaxy.model.History )
730                .filter( and_( galaxy.model.History.table.c.deleted == False,
731                               galaxy.model.History.table.c.user_id == admin_user.id ) )
732                .order_by( desc( galaxy.model.History.table.c.create_time ) )
733                .first() )
734        assert latest_history is not None, "Problem retrieving latest_history from database"
735        self.upload_file('1.bed', dbkey='hg18')
736        latest_hda = (
737            sa_session.query( galaxy.model.HistoryDatasetAssociation )
738                .order_by( desc( galaxy.model.HistoryDatasetAssociation.table.c.create_time ) )
739                .first() )
740
741        # delete that item and make sure the 'history empty' message shows
742        self.home()
743        log.info( 'deleting last hda' )
744        self.delete_history_item( str( latest_hda.id ) )
745        # check the historyPanel settings.show_deleted for a null json value (no show_deleted in query string)
746        self.check_history_json( r'\bshow_deleted\s*:\s*(.*),', lambda x: x == None )
747
748        # reload this history with the show_deleted flag set in the query string
749        #   the deleted dataset should be there with the proper 'deleted' text
750        self.home()
751        log.info( 'turning show_deleted on' )
752        #self.visit_url( "%s/history/?show_deleted=True" % self.url )
753        # check the historyPanel settings.show_deleted for a true json value
754        self.check_history_json( r'\bshow_deleted\s*:\s*(.*),', lambda x: x == True, show_deleted=True )
755
756        # reload this history again with the show_deleted flag set TO FALSE in the query string
757        #   make sure the 'history empty' message shows
758        self.home()
759        log.info( 'turning show_deleted off' )
760        #self.visit_url( "%s/history/?show_deleted=False" % self.url )
761        # check the historyPanel settings.show_deleted for a false json value
762        self.check_history_json( r'\bshow_deleted\s*:\s*(.*),', lambda x: x == False, show_deleted=False )
763
764        # delete this history
765        self.delete_history( self.security.encode_id( latest_history.id ) )
766
767    def test_075_deleting_and_undeleting_history_items( self ):
768        """Testing deleting and un-deleting history items"""
769        # logged in as admin_user
770
771        # Deleting the current history in the last method created a new history
772        latest_history = (
773            sa_session.query( galaxy.model.History )
774                .filter( and_( galaxy.model.History.table.c.deleted == False,
775                               galaxy.model.History.table.c.user_id == admin_user.id ) )
776                .order_by( desc( galaxy.model.History.table.c.create_time ) )
777                .first() )
778        assert latest_history is not None, "Problem retrieving latest_history from database"
779
780        self.rename_history( self.security.encode_id( latest_history.id ),
781            latest_history.name, new_name=urllib.quote( 'delete undelete history items' ) )
782        # Add a new history item
783        self.upload_file( '1.bed', dbkey='hg15' )
784        latest_hda = sa_session.query( galaxy.model.HistoryDatasetAssociation ) \
785                               .order_by( desc( galaxy.model.HistoryDatasetAssociation.table.c.create_time ) ) \
786                               .first()
787        self.home()
788        self.visit_url( "%s/history/?show_deleted=False" % self.url )
789        self.check_page_for_string( '1.bed' )
790        self.check_page_for_string( 'hg15' )
791        self.assertEqual( len( self.get_history_as_data_list() ), 1 )
792        # Delete the history item
793        self.delete_history_item( str( latest_hda.id ), strings_displayed=[ "Your history is empty" ] )
794        self.assertEqual( len( self.get_history_as_data_list() ), 0 )
795        # Try deleting an invalid hid
796        try:
797            self.delete_history_item( 'XXX' )
798            raise AssertionError( "Inproperly able to delete hda_id 'XXX' which is not an integer" )
799        except:
800            pass
801        # Undelete the history item
802        self.undelete_history_item( str( latest_hda.id ) )
803        self.home()
804        self.visit_url( "%s/history/?show_deleted=False" % self.url )
805        self.check_page_for_string( '1.bed' )
806        self.check_page_for_string( 'hg15' )
807        self.delete_history( self.security.encode_id( latest_history.id ) )
808
809    def test_080_copying_history_items_between_histories( self ):
810        """Testing copying history items between histories"""
811        # logged in as admin_user
812        self.new_history( name=urllib.quote( 'copy history items' ) )
813        history6 = sa_session.query( galaxy.model.History ) \
814                             .filter( and_( galaxy.model.History.table.c.deleted == False,
815                                            galaxy.model.History.table.c.user_id == admin_user.id ) ) \
816                             .order_by( desc( galaxy.model.History.table.c.create_time ) ) \
817                             .first()
818        assert history6 is not None, "Problem retrieving history6 from database"
819        self.upload_file( '1.bed', dbkey='hg18' )
820        hda1 = sa_session.query( galaxy.model.HistoryDatase

Large files files are truncated, but you can click here to view the full file