PageRenderTime 36ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/test/functional/test_sample_tracking.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 940 lines | 879 code | 2 blank | 59 comment | 17 complexity | ec79c219450da84e920eceab0d3d8203 MD5 | raw file
  1. import galaxy.model
  2. from galaxy.model.orm import *
  3. from base.twilltestcase import *
  4. from base.test_db_util import *
  5. # TODO: Functional tests start failing at 025, fix or eliminate rest of tests.
  6. class TestFormsAndSampleTracking( TwillTestCase ):
  7. # ====== Setup Users, Groups & Roles required for this test suite =========
  8. def test_000_initiate_users( self ):
  9. """Ensuring all required user accounts exist"""
  10. self.logout()
  11. self.login( email='test1@bx.psu.edu', username='regular-user1' )
  12. global regular_user1
  13. regular_user1 = get_user( 'test1@bx.psu.edu' )
  14. assert regular_user1 is not None, 'Problem retrieving user with email "test1@bx.psu.edu" from the database'
  15. global regular_user1_private_role
  16. regular_user1_private_role = get_private_role( regular_user1 )
  17. self.logout()
  18. self.login( email='test2@bx.psu.edu', username='regular-user2' )
  19. global regular_user2
  20. regular_user2 = get_user( 'test2@bx.psu.edu' )
  21. assert regular_user2 is not None, 'Problem retrieving user with email "test2@bx.psu.edu" from the database'
  22. global regular_user2_private_role
  23. regular_user2_private_role = get_private_role( regular_user2 )
  24. self.logout()
  25. self.login( email='test3@bx.psu.edu', username='regular-user3' )
  26. global regular_user3
  27. regular_user3 = get_user( 'test3@bx.psu.edu' )
  28. assert regular_user3 is not None, 'Problem retrieving user with email "test3@bx.psu.edu" from the database'
  29. global regular_user3_private_role
  30. regular_user3_private_role = get_private_role( regular_user3 )
  31. self.logout()
  32. self.login( email='test@bx.psu.edu', username='admin-user' )
  33. global admin_user
  34. admin_user = get_user( 'test@bx.psu.edu' )
  35. assert admin_user is not None, 'Problem retrieving user with email "test@bx.psu.edu" from the database'
  36. global admin_user_private_role
  37. admin_user_private_role = get_private_role( admin_user )
  38. def test_005_create_required_groups_and_roles( self ):
  39. """Testing creating all required groups and roles for this script"""
  40. # Logged in as admin_user
  41. # Create role1
  42. name = 'Role1'
  43. description = "This is Role1's description"
  44. user_ids = [ str( admin_user.id ), str( regular_user1.id ), str( regular_user3.id ) ]
  45. self.create_role( name=name,
  46. description=description,
  47. in_user_ids=user_ids,
  48. in_group_ids=[],
  49. create_group_for_role='no',
  50. private_role=admin_user.email )
  51. # Get the role object for later tests
  52. global role1
  53. role1 = get_role_by_name( name )
  54. # Create group1
  55. name = 'Group1'
  56. self.create_group( name=name, in_user_ids=[ str( regular_user1.id ) ], in_role_ids=[ str( role1.id ) ] )
  57. # Get the group object for later tests
  58. global group1
  59. group1 = get_group_by_name( name )
  60. assert group1 is not None, 'Problem retrieving group named "Group1" from the database'
  61. # NOTE: To get this to work with twill, all select lists on the ~/admin/role page must contain at least
  62. # 1 option value or twill throws an exception, which is: ParseError: OPTION outside of SELECT
  63. # Due to this bug in twill, we create the role, we bypass the page and visit the URL in the
  64. # associate_users_and_groups_with_role() method.
  65. #
  66. #create role2
  67. name = 'Role2'
  68. description = 'This is Role2'
  69. user_ids = [ str( admin_user.id ) ]
  70. group_ids = [ str( group1.id ) ]
  71. private_role = admin_user.email
  72. self.create_role( name=name,
  73. description=description,
  74. in_user_ids=user_ids,
  75. in_group_ids=group_ids,
  76. private_role=private_role )
  77. # Get the role object for later tests
  78. global role2
  79. role2 = get_role_by_name( name )
  80. assert role2 is not None, 'Problem retrieving role named "Role2" from the database'
  81. def test_006_create_library_and_folder( self ):
  82. """Testing creating the target data library and folder"""
  83. # Logged in as admin_user
  84. for index in range( 0, 2 ):
  85. name = 'library%s' % str( index + 1 )
  86. description = '%s description' % name
  87. synopsis = '%s synopsis' % name
  88. self.create_library( name=name, description=description, synopsis=synopsis )
  89. # Get the libraries for later use
  90. global library1
  91. library1 = get_library( 'library1', 'library1 description', 'library1 synopsis' )
  92. assert library1 is not None, 'Problem retrieving library (library1) from the database'
  93. global library2
  94. library2 = get_library( 'library2', 'library2 description', 'library2 synopsis' )
  95. assert library2 is not None, 'Problem retrieving library (library2) from the database'
  96. # setup add_library_item permission to regular_user1
  97. # Set permissions on the library, sort for later testing.
  98. permissions_in = [ 'LIBRARY_ACCESS' ]
  99. permissions_out = []
  100. # Role1 members are: admin_user, regular_user1, regular_user3.
  101. # Each of these users will be permitted for LIBRARY_ACCESS, LIBRARY_ADD on
  102. # library1 and library2.
  103. for library in [ library1, library2 ]:
  104. self.library_permissions( self.security.encode_id( library.id ),
  105. library.name,
  106. str( role1.id ),
  107. permissions_in,
  108. permissions_out )
  109. # adding a folder
  110. for library in [ library1, library2 ]:
  111. name = "%s_folder1" % library.name
  112. description = "%s description" % name
  113. self.add_folder( 'library_admin',
  114. self.security.encode_id( library.id ),
  115. self.security.encode_id( library.root_folder.id ),
  116. name=name,
  117. description=description )
  118. global library1_folder1
  119. library1_folder1 = get_folder( library1.root_folder.id, 'library1_folder1', 'library1_folder1 description' )
  120. assert library1_folder1 is not None, 'Problem retrieving library folder named "library1_folder1" from the database'
  121. global library2_folder1
  122. library2_folder1 = get_folder( library2.root_folder.id, 'library2_folder1', 'library2_folder1 description' )
  123. assert library2_folder1 is not None, 'Problem retrieving library folder named "library2_folder1" from the database'
  124. # add folders 4 levels deep to library1_folder1
  125. # level 2
  126. name = "%s_folder2" % library2.name
  127. description = "%s description" % name
  128. self.add_folder( 'library_admin',
  129. self.security.encode_id( library2.id ),
  130. self.security.encode_id( library2_folder1.id ),
  131. name=name,
  132. description=description )
  133. global library2_folder2
  134. library2_folder2 = get_folder( library2_folder1.id, name, description )
  135. assert library2_folder2 is not None, 'Problem retrieving library folder named "%s" from the database' % name
  136. # level 3
  137. name = "%s_folder3" % library2.name
  138. description = "%s description" % name
  139. self.add_folder( 'library_admin',
  140. self.security.encode_id( library2.id ),
  141. self.security.encode_id( library2_folder2.id ),
  142. name=name,
  143. description=description )
  144. global library2_folder3
  145. library2_folder3 = get_folder( library2_folder2.id, name, description )
  146. assert library2_folder3 is not None, 'Problem retrieving library folder named "%s" from the database' % name
  147. # level 4
  148. name = "%s_folder4" % library2.name
  149. description = "%s description" % name
  150. self.add_folder( 'library_admin',
  151. self.security.encode_id( library2.id ),
  152. self.security.encode_id( library2_folder3.id ),
  153. name=name,
  154. description=description )
  155. global library2_folder4
  156. library2_folder4 = get_folder( library2_folder3.id, name, description )
  157. assert library2_folder4 is not None, 'Problem retrieving library folder named "%s" from the database' % name
  158. #
  159. # ====== Form definition test methods ================================================
  160. #
  161. def test_010_create_request_form_definition( self ):
  162. """Testing creating a sequencing request form definition, editing the name and description and adding fields"""
  163. # Logged in as admin_user
  164. # Create a form definition
  165. tmp_name = "Temp form"
  166. tmp_desc = "Temp form description"
  167. form_type = galaxy.model.FormDefinition.types.REQUEST
  168. self.create_form( name=tmp_name,
  169. description=tmp_desc,
  170. form_type=form_type,
  171. num_fields=0,
  172. field_name='1_field_name',
  173. strings_displayed=[ 'Create a new form definition' ],
  174. strings_displayed_after_submit=[ tmp_name, tmp_desc, form_type ] )
  175. tmp_form = get_form( tmp_name )
  176. # Edit the name and description of the form definition, and add 3 fields.
  177. new_name = "Request Form"
  178. new_desc = "Request Form description"
  179. # labels
  180. global request_field_label1
  181. request_field_label1 = 'Request form field1'
  182. global request_field_label2
  183. request_field_label2 = 'Request form field2'
  184. global request_field_label3
  185. request_field_label3 = 'Request form field3'
  186. # field names
  187. global request_form_field_name1
  188. request_form_field_name1 = 'request_form_field1'
  189. global request_form_field_name2
  190. request_form_field_name2 = 'request_form_field2'
  191. global request_form_field_name3
  192. request_form_field_name3 = 'request_form_field3'
  193. field_dicts = [ dict( label=request_field_label1,
  194. desc='Description of '+request_field_label1,
  195. type='SelectField',
  196. required='optional',
  197. selectlist=[ 'option1', 'option2' ],
  198. name=request_form_field_name1 ),
  199. dict( label=request_field_label2,
  200. desc='Description of '+request_field_label2,
  201. type='AddressField',
  202. required='optional',
  203. name=request_form_field_name2 ),
  204. dict( label=request_field_label3,
  205. desc='Description of '+request_field_label3,
  206. type='TextField',
  207. required='required',
  208. name=request_form_field_name3 ) ]
  209. self.edit_form( id=self.security.encode_id( tmp_form.current.id ),
  210. new_form_name=new_name,
  211. new_form_desc=new_desc,
  212. field_dicts=field_dicts,
  213. field_index=len( tmp_form.fields ),
  214. strings_displayed=[ 'Edit form definition "%s"' % tmp_name ],
  215. strings_displayed_after_submit=[ "The form '%s' has been updated with the changes." % new_name ] )
  216. # Get the form_definition object for later tests
  217. global request_form_definition1
  218. request_form_definition1 = get_form( new_name )
  219. assert request_form_definition1 is not None, 'Problem retrieving form named "%s" from the database' % new_name
  220. assert len( request_form_definition1.fields ) == len( tmp_form.fields ) + len( field_dicts )
  221. # check form view
  222. self.view_form( id=self.security.encode_id( request_form_definition1.current.id ),
  223. form_name=new_name,
  224. form_desc=new_desc,
  225. form_type=form_type,
  226. field_dicts=field_dicts )
  227. def test_015_create_sample_form_definition( self ):
  228. """Testing creating sequencing sample form definition and adding fields"""
  229. name = "Sample Form"
  230. desc = "This is Sample Form's description"
  231. form_type = galaxy.model.FormDefinition.types.SAMPLE
  232. global sample_form_layout_grid_name
  233. sample_form_layout_grid_name = 'Layout Grid1'
  234. self.create_form( name=name,
  235. description=desc,
  236. form_type=form_type,
  237. form_layout_name=sample_form_layout_grid_name,
  238. num_fields=0,
  239. field_name='1_field_name',
  240. strings_displayed=[ 'Create a new form definition' ],
  241. strings_displayed_after_submit=[ "The form '%s' has been updated with the changes." % name ] )
  242. tmp_form = get_form( name )
  243. # now add fields to the sample form definition
  244. global sample_field_label1
  245. sample_field_label1 = 'Sample form field1'
  246. global sample_field_label2
  247. sample_field_label2 = 'Sample form field2'
  248. global sample_field_label3
  249. sample_field_label3 = 'Sample form field3'
  250. field_dicts = [ dict( label=sample_field_label1,
  251. desc='Description of '+sample_field_label1,
  252. type='SelectField',
  253. required='optional',
  254. selectlist=[ 'option1', 'option2' ],
  255. name='sample_form_field1' ),
  256. dict( label=sample_field_label2,
  257. desc='Description of '+sample_field_label2,
  258. type='TextField',
  259. required='optional',
  260. name='sample_form_field2' ),
  261. dict( label=sample_field_label3,
  262. desc='Description of '+sample_field_label3,
  263. type='TextField',
  264. required='required',
  265. name='sample_form_field3' ) ]
  266. self.edit_form( id=self.security.encode_id( tmp_form.current.id ),
  267. new_form_name=name,
  268. new_form_desc=desc,
  269. field_dicts=field_dicts,
  270. field_index=len( tmp_form.fields ),
  271. strings_displayed=[ 'Edit form definition "%s"' % name ],
  272. strings_displayed_after_submit=[ "The form '%s' has been updated with the changes." % name ] )
  273. global sample_form_definition1
  274. sample_form_definition1 = get_form( name )
  275. assert sample_form_definition1 is not None, "Error retrieving form %s from db" % name
  276. assert len( sample_form_definition1.fields ) == len( field_dicts )
  277. # check form view
  278. self.view_form( id=self.security.encode_id( sample_form_definition1.current.id ),
  279. form_name=name,
  280. form_desc=desc,
  281. form_type=form_type,
  282. form_layout_name=sample_form_layout_grid_name,
  283. field_dicts=field_dicts )
  284. def test_020_create_request_type( self ):
  285. """Testing creating a request_type"""
  286. name = 'Request type1'
  287. sample_states = [ ( 'New', 'Sample entered into the system' ),
  288. ( 'Received', 'Sample tube received' ),
  289. ( 'Library Started', 'Sample library preparation' ),
  290. ( 'Run Started', 'Sequence run in progress' ),
  291. ( 'Done', 'Sequence run complete' ) ]
  292. self.create_request_type( name,
  293. name+" description",
  294. self.security.encode_id( request_form_definition1.id ),
  295. self.security.encode_id( sample_form_definition1.id ),
  296. sample_states,
  297. strings_displayed=[ 'Create a new request type' ],
  298. strings_displayed_after_submit=[ "The request type has been created." ] )
  299. global request_type1
  300. request_type1 = get_request_type_by_name( name )
  301. assert request_type1 is not None, 'Problem retrieving request type named "%s" from the database' % name
  302. # check view
  303. self.view_request_type( self.security.encode_id( request_type1.id ),
  304. request_type1.name,
  305. strings_displayed=[ request_form_definition1.name,
  306. sample_form_definition1.name ],
  307. sample_states=sample_states)
  308. # Set permissions
  309. permissions_in = [ k for k, v in galaxy.model.RequestType.permitted_actions.items() ]
  310. permissions_out = []
  311. # Role1 members are: admin_user, regular_user1, regular_user3. Each of these users will be permitted for
  312. # REQUEST_TYPE_ACCESS on this request_type
  313. self.request_type_permissions( self.security.encode_id( request_type1.id ),
  314. request_type1.name,
  315. str( role1.id ),
  316. permissions_in,
  317. permissions_out )
  318. # Make sure the request_type1 is not accessible by regular_user2 since regular_user2 does not have Role1.
  319. self.logout()
  320. self.login( email=regular_user2.email )
  321. self.visit_url( '%s/requests_common/create_request?cntrller=requests&request_type=True' % self.url )
  322. try:
  323. self.check_page_for_string( 'There are no request types created for a new request.' )
  324. raise AssertionError, 'The request_type %s is accessible by %s when it should be restricted' % ( request_type1.name, regular_user2.email )
  325. except:
  326. pass
  327. self.logout()
  328. self.login( email=admin_user.email )
  329. # ====== Sequencing request test methods - regular user perspective ================
  330. def test_025_create_request( self ):
  331. """Testing creating a sequencing request as a regular user"""
  332. # logged in as admin_user
  333. # Create a user_address
  334. self.logout()
  335. self.login( email=regular_user1.email )
  336. # add new address for this user
  337. address_dict = dict( short_desc="Office",
  338. name="James Bond",
  339. institution="MI6" ,
  340. address="MI6 Headquarters",
  341. city="London",
  342. state="London",
  343. postal_code="007",
  344. country="United Kingdom",
  345. phone="007-007-0007" )
  346. self.add_user_address( self.security.encode_id( regular_user1.id ), address_dict )
  347. global user_address1
  348. user_address1 = get_user_address( regular_user1, address_dict[ 'short_desc' ] )
  349. # Set field values - the tuples in the field_values list include the field_value, and True if refresh_on_change
  350. # is required for that field.
  351. field_value_tuples = [ ( request_form_field_name1, 'option1', False ),
  352. ( request_form_field_name2, ( str( user_address1.id ), str( user_address1.id ) ), True ),
  353. ( request_form_field_name3, 'field3 value', False ) ]
  354. # Create the request
  355. name = 'Request1'
  356. desc = 'Request1 Description'
  357. self.create_request( cntrller='requests',
  358. request_type_id=self.security.encode_id( request_type1.id ),
  359. name=name,
  360. desc=desc,
  361. field_value_tuples=field_value_tuples,
  362. strings_displayed=[ 'Create a new sequencing request',
  363. request_field_label1,
  364. request_field_label2,
  365. request_field_label3 ],
  366. strings_displayed_after_submit=[ 'The sequencing request has been created.',
  367. name, desc ] )
  368. global request1
  369. request1 = get_request_by_name( name )
  370. # Make sure the request's state is now set to NEW
  371. assert request1.state is not request1.states.NEW, "The state of the request '%s' should be set to '%s'" \
  372. % ( request1.name, request1.states.NEW )
  373. # check request page
  374. self.view_request( cntrller='requests',
  375. request_id=self.security.encode_id( request1.id ),
  376. strings_displayed=[ 'Sequencing request "%s"' % request1.name,
  377. 'There are no samples.' ],
  378. strings_not_displayed=[ request1.states.SUBMITTED,
  379. request1.states.COMPLETE,
  380. request1.states.REJECTED,
  381. 'Submit request' ] ) # this button should NOT show up as there are no samples yet
  382. # check if the request is showing in the 'new' filter
  383. self.check_request_grid( cntrller='requests',
  384. state=request1.states.NEW,
  385. strings_displayed=[ request1.name ] )
  386. self.view_request_history( cntrller='requests',
  387. request_id=self.security.encode_id( request1.id ),
  388. strings_displayed=[ 'History of sequencing request "%s"' % request1.name,
  389. request1.states.NEW,
  390. 'Sequencing request created' ],
  391. strings_not_displayed=[ request1.states.SUBMITTED,
  392. request1.states.COMPLETE,
  393. request1.states.REJECTED ] )
  394. def test_030_edit_basic_request_info( self ):
  395. """Testing editing the basic information and email settings of a sequencing request"""
  396. # logged in as regular_user1
  397. fields = [ ( request_form_field_name1, 'option2' ),
  398. ( request_form_field_name2, str( user_address1.id ) ),
  399. ( request_form_field_name3, 'field3 value (edited)' ) ]
  400. new_name=request1.name + ' (Renamed)'
  401. new_desc=request1.desc + ' (Re-described)'
  402. self.edit_basic_request_info( request_id=self.security.encode_id( request1.id ),
  403. cntrller='requests',
  404. name=request1.name,
  405. new_name=new_name,
  406. new_desc=new_desc,
  407. new_fields=fields,
  408. strings_displayed=[ 'Edit sequencing request "%s"' % request1.name ],
  409. strings_displayed_after_submit=[ new_name, new_desc ] )
  410. refresh( request1 )
  411. # define the sample states when we want an email notification
  412. global email_notification_sample_states
  413. email_notification_sample_states = [ request1.type.states[2], request1.type.states[4] ]
  414. # check email notification settings
  415. check_sample_states = []
  416. for state in email_notification_sample_states:
  417. check_sample_states.append( ( state.name, state.id, True ) )
  418. strings_displayed = [ 'Edit sequencing request "%s"' % request1.name,
  419. 'Email notification settings' ]
  420. additional_emails = [ 'test@.bx.psu.edu', 'test2@.bx.psu.edu' ]
  421. strings_displayed_after_submit = [ "The changes made to the email notification settings have been saved",
  422. '\r\n'.join( additional_emails ) ]
  423. self.edit_request_email_settings( cntrller='requests',
  424. request_id=self.security.encode_id( request1.id ),
  425. check_request_owner=True,
  426. additional_emails='\r\n'.join( additional_emails ),
  427. check_sample_states=check_sample_states,
  428. strings_displayed=strings_displayed,
  429. strings_displayed_after_submit=strings_displayed_after_submit )
  430. # lastly check the details in the request page
  431. strings_displayed = [ 'Sequencing request "%s"' % new_name,
  432. new_desc ]
  433. for field in fields:
  434. strings_displayed.append( field[1] )
  435. for state_name, id, is_checked in check_sample_states:
  436. strings_displayed.append( state_name )
  437. for email in additional_emails:
  438. strings_displayed.append( email )
  439. self.view_request( cntrller='requests',
  440. request_id=self.security.encode_id( request1.id ),
  441. strings_displayed=strings_displayed,
  442. strings_not_displayed=[] )
  443. def test_035_add_samples_to_request( self ):
  444. """Testing adding samples to request"""
  445. # logged in as regular_user1
  446. # Sample fields - the tuple represents a sample name and a list of sample form field values
  447. target_library_info = dict(library=self.security.encode_id(library2.id),
  448. folder=self.security.encode_id(library2_folder1.id) )
  449. sample_value_tuples = \
  450. [ ( 'Sample1', target_library_info, [ 'option1', 'sample1 field2 value', 'sample1 field3 value' ] ),
  451. ( 'Sample2', target_library_info, [ 'option2', 'sample2 field2 value', 'sample2 field3 value' ] ),
  452. ( 'Sample3', target_library_info, [ 'option1', 'sample3 field2 value', 'sample3 field3 value' ] ) ]
  453. strings_displayed_after_submit = [ 'Unsubmitted' ]
  454. for sample_name, lib_info, field_values in sample_value_tuples:
  455. strings_displayed_after_submit.append( sample_name )
  456. strings_displayed_after_submit.append( library2.name )
  457. strings_displayed_after_submit.append( library2_folder1.name )
  458. # add the sample values too
  459. for values in field_values:
  460. strings_displayed_after_submit.append( values )
  461. # list folders that populates folder selectfield when a data library is selected
  462. folder_options = [ library2_folder1.name, library2_folder2.name, library2_folder3.name, library2_folder4.name ] # Add samples to the request
  463. self.add_samples( cntrller='requests',
  464. request_id=self.security.encode_id( request1.id ),
  465. sample_value_tuples=sample_value_tuples,
  466. folder_options=folder_options,
  467. strings_displayed=[ 'Add samples to sequencing request "%s"' % request1.name,
  468. '<input type="text" name="sample_0_name" value="Sample_1" size="10"/>' ], # sample name input field
  469. strings_displayed_after_submit=strings_displayed_after_submit )
  470. # check the new sample field values on the request page
  471. strings_displayed = [ 'Sequencing request "%s"' % request1.name,
  472. 'Submit request' ] # this button should appear now
  473. strings_displayed.extend( strings_displayed_after_submit )
  474. strings_displayed_count = []
  475. strings_displayed_count.append( ( library2.name, len( sample_value_tuples ) ) )
  476. strings_displayed_count.append( ( library2_folder1.name, len( sample_value_tuples ) ) )
  477. self.view_request( cntrller='requests',
  478. request_id=self.security.encode_id( request1.id ),
  479. strings_displayed=strings_displayed,
  480. strings_displayed_count=strings_displayed_count )
  481. def test_040_edit_samples_of_new_request( self ):
  482. """Testing editing the sample information of new request1"""
  483. # logged in as regular_user1
  484. # target data library - change it to library1
  485. target_library_info = dict(library=self.security.encode_id( library1.id ),
  486. folder=self.security.encode_id( library1_folder1.id ) )
  487. new_sample_value_tuples = \
  488. [ ( 'Sample1_renamed', target_library_info, [ 'option2', 'sample1 field2 value edited', 'sample1 field3 value edited' ] ),
  489. ( 'Sample2_renamed', target_library_info, [ 'option1', 'sample2 field2 value edited', 'sample2 field3 value edited' ] ),
  490. ( 'Sample3_renamed', target_library_info, [ 'option2', 'sample3 field2 value edited', 'sample3 field3 value edited' ] ) ]
  491. strings_displayed_after_submit = [ 'Unsubmitted' ]
  492. for sample_name, lib_info, field_values in new_sample_value_tuples:
  493. strings_displayed_after_submit.append( sample_name )
  494. # add the sample values too
  495. for values in field_values:
  496. strings_displayed_after_submit.append( values )
  497. strings_displayed = [ 'Edit Current Samples of Sequencing Request "%s"' % request1.name,
  498. '<input type="text" name="sample_0_name" value="Sample1" size="10"/>', # sample name input field
  499. library2_folder1.name, # all the folders in library2 should show up in the folder selectlist
  500. library2_folder2.name,
  501. library2_folder3.name,
  502. library2_folder4.name ]
  503. # Add samples to the request
  504. self.edit_samples( cntrller='requests',
  505. request_id=self.security.encode_id( request1.id ),
  506. sample_value_tuples=new_sample_value_tuples,
  507. strings_displayed=strings_displayed,
  508. strings_displayed_after_submit=strings_displayed_after_submit )
  509. # check the changed sample field values on the request page
  510. strings_displayed = [ 'Sequencing request "%s"' % request1.name ]
  511. strings_displayed.extend( strings_displayed_after_submit )
  512. strings_displayed_count = []
  513. strings_displayed_count.append( ( library1.name, len( new_sample_value_tuples ) ) )
  514. strings_displayed_count.append( ( library1_folder1.name, len( new_sample_value_tuples ) ) )
  515. self.view_request( cntrller='requests',
  516. request_id=self.security.encode_id( request1.id ),
  517. strings_displayed=strings_displayed,
  518. strings_displayed_count=strings_displayed_count )
  519. def test_045_submit_request( self ):
  520. """Testing submitting a sequencing request"""
  521. # logged in as regular_user1
  522. self.submit_request( cntrller='requests',
  523. request_id=self.security.encode_id( request1.id ),
  524. request_name=request1.name,
  525. strings_displayed_after_submit=[ 'The sequencing request has been submitted.' ] )
  526. refresh( request1 )
  527. # Make sure the request is showing in the 'submitted' filter
  528. self.check_request_grid( cntrller='requests',
  529. state=request1.states.SUBMITTED,
  530. strings_displayed=[ request1.name ] )
  531. # Make sure the request's state is now set to 'submitted'
  532. assert request1.state is not request1.states.SUBMITTED, "The state of the sequencing request '%s' should be set to '%s'" \
  533. % ( request1.name, request1.states.SUBMITTED )
  534. # the sample state should appear once for each sample
  535. strings_displayed_count = [ ( request1.type.states[0].name, len( request1.samples ) ) ]
  536. # after submission, these buttons should not appear
  537. strings_not_displayed = [ 'Add sample', 'Submit request' ]
  538. # check the request page
  539. self.view_request( cntrller='requests',
  540. request_id=self.security.encode_id( request1.id ),
  541. strings_displayed=[ request1.states.SUBMITTED ],
  542. strings_displayed_count=strings_displayed_count,
  543. strings_not_displayed=strings_not_displayed )
  544. strings_displayed=[ 'History of sequencing request "%s"' % request1.name,
  545. 'Sequencing request submitted by %s' % regular_user1.email,
  546. 'Sequencing request created' ]
  547. strings_displayed_count = [ ( request1.states.SUBMITTED, 1 ) ]
  548. self.view_request_history( cntrller='requests',
  549. request_id=self.security.encode_id( request1.id ),
  550. strings_displayed=strings_displayed,
  551. strings_displayed_count=strings_displayed_count,
  552. strings_not_displayed=[ request1.states.COMPLETE,
  553. request1.states.REJECTED ] )
  554. # ====== Sequencing request test methods - Admin perspective ================
  555. def test_050_receive_request_as_admin( self ):
  556. """Testing receiving a sequencing request and assigning it barcodes"""
  557. # logged in as regular_user1
  558. self.logout()
  559. # login as a admin_user to assign bar codes to samples
  560. self.login( email=admin_user.email )
  561. self.check_request_grid( cntrller='requests_admin',
  562. state=request1.states.SUBMITTED,
  563. strings_displayed=[ request1.name ] )
  564. strings_displayed = [ request1.states.SUBMITTED,
  565. 'Reject this request',
  566. 'Add sample',
  567. 'Edit samples' ]
  568. self.view_request( cntrller='requests_admin',
  569. request_id=self.security.encode_id( request1.id ),
  570. strings_displayed=strings_displayed )
  571. # Set bar codes for the samples
  572. bar_codes = [ '10001', '10002', '10003' ]
  573. strings_displayed_after_submit = [ 'Changes made to the samples have been saved.' ]
  574. strings_displayed_after_submit.extend( bar_codes )
  575. self.add_bar_codes( cntrller='requests_admin',
  576. request_id=self.security.encode_id( request1.id ),
  577. bar_codes=bar_codes,
  578. strings_displayed=[ 'Edit Current Samples of Sequencing Request "%s"' % request1.name ],
  579. strings_displayed_after_submit=strings_displayed_after_submit )
  580. # the second sample state should appear once for each sample
  581. strings_displayed_count = [ ( request1.type.states[1].name, len( request1.samples ) ),
  582. ( request1.type.states[0].name, 0 ) ]
  583. # check the request page
  584. self.view_request( cntrller='requests_admin',
  585. request_id=self.security.encode_id( request1.id ),
  586. strings_displayed=bar_codes,
  587. strings_displayed_count=strings_displayed_count )
  588. # the sample state descriptions of the future states should not appear
  589. # here the state names are not checked as all of them appear at the top of
  590. # the page like: state1 > state2 > state3
  591. strings_not_displayed=[ request1.type.states[2].desc,
  592. request1.type.states[3].desc,
  593. request1.type.states[4].desc ]
  594. # check history of each sample
  595. for sample in request1.samples:
  596. strings_displayed = [ 'History of sample "%s"' % sample.name,
  597. 'Sequencing request submitted and sample state set to %s' % request1.type.states[0].name,
  598. request1.type.states[0].name,
  599. request1.type.states[1].name ]
  600. self.view_sample_history( cntrller='requests_admin',
  601. sample_id=self.security.encode_id( sample.id ),
  602. strings_displayed=strings_displayed,
  603. strings_not_displayed=strings_not_displayed )
  604. def test_055_request_lifecycle( self ):
  605. """Testing request life-cycle as it goes through all the states"""
  606. # logged in as admin_user
  607. self.check_request_grid( cntrller='requests_admin',
  608. state=request1.states.SUBMITTED,
  609. strings_displayed=[ request1.name ] )
  610. strings_displayed=[ 'History of sequencing request "%s"' % request1.name ]
  611. # Change the states of all the samples of this request to ultimately be COMPLETE
  612. for index, state in enumerate( request_type1.states ):
  613. # start from the second state onwards
  614. if index > 1:
  615. # status message
  616. if index == len( request_type1.states ) - 1:
  617. status_msg = 'All samples of this sequencing request are in the final sample state (%s).' % state.name
  618. else:
  619. status_msg = 'All samples of this sequencing request are in the (%s) sample state. ' % state.name
  620. # check email notification message
  621. email_msg = ''
  622. if state.id in [ email_state.id for email_state in email_notification_sample_states ]:
  623. email_msg = 'Email notification failed as SMTP server not set in config file'
  624. self.change_sample_state( request_id=self.security.encode_id( request1.id ),
  625. sample_ids=[ sample.id for sample in request1.samples ],
  626. new_sample_state_id=self.security.encode_id( state.id ),
  627. strings_displayed=[ 'Edit Current Samples of Sequencing Request "%s"' % request1.name ],
  628. strings_displayed_after_submit = [ status_msg, email_msg ] )
  629. # check request history page
  630. if index == len( request_type1.states ) - 1:
  631. strings_displayed.append( status_msg )
  632. else:
  633. strings_displayed.append( status_msg )
  634. self.view_request_history( cntrller='requests_admin',
  635. request_id=self.security.encode_id( request1.id ),
  636. strings_displayed=strings_displayed,
  637. strings_not_displayed=[ request1.states.REJECTED ] )
  638. refresh( request1 )
  639. # check if the request's state is now set to 'complete'
  640. self.check_request_grid( cntrller='requests_admin',
  641. state='Complete',
  642. strings_displayed=[ request1.name ] )
  643. assert request1.state is not request1.states.COMPLETE, "The state of the sequencing request '%s' should be set to '%s'" \
  644. % ( request1.name, request1.states.COMPLETE )
  645. def test_060_admin_create_request_on_behalf_of_regular_user( self ):
  646. """Testing creating and submitting a request as an admin on behalf of a regular user"""
  647. # Logged in as regular_user1
  648. self.logout()
  649. self.login( email=admin_user.email )
  650. # Create the request
  651. name = "Request2"
  652. desc = 'Request2 Description'
  653. # new address
  654. new_address_dict = dict( short_desc="Home",
  655. name="Sherlock Holmes",
  656. institution="None" ,
  657. address="221B Baker Street",
  658. city="London",
  659. state="London",
  660. postal_code="34534",
  661. country="United Kingdom",
  662. phone="007-007-0007" )
  663. # Set field values - the tuples in the field_values list include the field_value, and True if refresh_on_change
  664. # is required for that field.
  665. field_value_tuples = [ ( request_form_field_name1, 'option2', False ),
  666. ( request_form_field_name2, ( 'new', new_address_dict ) , True ),
  667. ( request_form_field_name3, 'field_2_value', False ) ]
  668. self.create_request( cntrller='requests_admin',
  669. request_type_id=self.security.encode_id( request_type1.id ),
  670. other_users_id=self.security.encode_id( regular_user1.id ),
  671. name=name,
  672. desc=desc,
  673. field_value_tuples=field_value_tuples,
  674. strings_displayed=[ 'Create a new sequencing request',
  675. request_field_label1,
  676. request_field_label2,
  677. request_field_label3 ],
  678. strings_displayed_after_submit=[ "The sequencing request has been created.",
  679. name, desc ] )
  680. global request2
  681. request2 = get_request_by_name( name )
  682. global user_address2
  683. user_address2 = get_user_address( regular_user1, new_address_dict[ 'short_desc' ] )
  684. # Make sure the request is showing in the 'new' filter
  685. self.check_request_grid( cntrller='requests_admin',
  686. state=request2.states.NEW,
  687. strings_displayed=[ request2.name ] )
  688. # Make sure the request's state is now set to 'new'
  689. assert request2.state is not request2.states.NEW, "The state of the request '%s' should be set to '%s'" \
  690. % ( request2.name, request2.states.NEW )
  691. target_library_info = dict(library='none', folder='none' )
  692. # Sample fields - the tuple represents a sample name and a list of sample form field values
  693. sample_value_tuples = \
  694. [ ( 'Sample1', target_library_info, [ 'option1', 'sample1 field2 value', 'sample1 field3 value' ] ),
  695. ( 'Sample2', target_library_info, [ 'option2', 'sample2 field2 value', 'sample2 field3 value' ] ),
  696. ( 'Sample3', target_library_info, [ 'option1', 'sample3 field2 value', 'sample3 field3 value' ] ) ]
  697. strings_displayed_after_submit = [ 'Unsubmitted' ]
  698. for sample_name, lib_info, field_values in sample_value_tuples:
  699. strings_displayed_after_submit.append( sample_name )
  700. for values in field_values:
  701. strings_displayed_after_submit.append( values )
  702. # Add samples to the request
  703. self.add_samples( cntrller='requests_admin',
  704. request_id=self.security.encode_id( request2.id ),
  705. sample_value_tuples=sample_value_tuples,
  706. strings_displayed=[ 'Add samples to sequencing request "%s"' % request2.name,
  707. '<input type="text" name="sample_0_name" value="Sample_1" size="10"/>' ], # sample name input field
  708. strings_displayed_after_submit=strings_displayed_after_submit )
  709. # Submit the request
  710. select_target_library_message = "Select a target data library and folder for a sample before selecting it's datasets to transfer from the external service"
  711. self.submit_request( cntrller='requests_admin',
  712. request_id=self.security.encode_id( request2.id ),
  713. request_name=request2.name,
  714. strings_displayed_after_submit=[ select_target_library_message,
  715. 'The sequencing request has been submitted.' ] )
  716. refresh( request2 )
  717. # Make sure the request is showing in the 'submitted' filter
  718. self.check_request_grid( cntrller='requests_admin',
  719. state=request2.states.SUBMITTED,
  720. strings_displayed=[ request2.name ] )
  721. # Make sure the request's state is now set to 'submitted'
  722. assert request2.state is not request2.states.SUBMITTED, "The state of the sequencing request '%s' should be set to '%s'" \
  723. % ( request2.name, request2.states.SUBMITTED )
  724. # Make sure both requests are showing in the 'All' filter
  725. self.check_request_grid( cntrller='requests_admin',
  726. state='All',
  727. strings_displayed=[ request1.name, request2.name ] )
  728. # list folders that populates folder selectfield when a data library is selected
  729. folder_options = [ library2_folder1.name, library2_folder2.name, library2_folder3.name, library2_folder4.name ]
  730. # set the target data library to library2 using sample operation user interface
  731. self.change_sample_target_data_library( cntrller='requests',
  732. request_id=self.security.encode_id( request2.id ),
  733. sample_ids=[ sample.id for sample in request2.samples ],
  734. new_library_id=self.security.encode_id( library2.id ),
  735. new_folder_id=self.security.encode_id( library2_folder1.id ),
  736. folder_options=folder_options,
  737. strings_displayed=[ 'Edit Current Samples of Sequencing Request "%s"' % request2.name ],
  738. strings_displayed_after_submit=[ 'Changes made to the samples have been saved.' ] )
  739. # check the changed target data library & folder on the request page
  740. strings_displayed_count = []
  741. strings_displayed_count.append( ( library2.name, len( request1.samples ) ) )
  742. strings_displayed_count.append( ( library2_folder1.name, len( request1.samples ) ) )
  743. strings_displayed = [ 'Sequencing request "%s"' % name, regular_user1.email, request2.states.SUBMITTED ]
  744. self.view_request( cntrller='requests',
  745. request_id=self.security.encode_id( request2.id ),
  746. strings_displayed=strings_displayed,
  747. strings_not_displayed=[ select_target_library_message ],
  748. strings_displayed_count=strings_displayed_count )
  749. def test_065_reject_request( self ):
  750. """Testing rejecting a request"""
  751. # Logged in as admin_user
  752. rejection_reason="This is why the sequencing request was rejected."
  753. self.reject_request( request_id=self.security.encode_id( request2.id ),
  754. request_name=request2.name,
  755. comment=rejection_reason,
  756. strings_displayed=[ 'Reject sequencing request "%s"' % request2.name ],
  757. strings_displayed_after_submit=[ 'Sequencing request (%s) has been rejected.' % request2.name ] )
  758. refresh( request2 )
  759. # Make sure the request is showing in the 'rejected' filter
  760. self.check_request_grid( cntrller='requests_admin',
  761. state=request2.states.REJECTED,
  762. strings_displayed=[ request2.name ] )
  763. # Make sure the request's state is now set to REJECTED
  764. assert request2.state is not request2.states.REJECTED, "The state of the request '%s' should be set to '%s'" \
  765. % ( request2.name, request2.states.REJECTED )
  766. # The rejection reason should show up in the request page and the request history page
  767. rejection_message = 'Sequencing request marked rejected by %s. Reason: %s' % ( admin_user.email, rejection_reason )
  768. strings_displayed = [ request2.states.REJECTED,
  769. rejection_message ]
  770. self.view_request( cntrller='requests',
  771. request_id=self.security.encode_id( request2.id ),
  772. strings_displayed=strings_displayed )
  773. self.view_request_history( cntrller='requests',
  774. request_id=self.security.encode_id( request2.id ),
  775. strings_displayed=strings_displayed )
  776. # login as the regular user to make sure that the request2 is fully editable
  777. self.logout()
  778. self.login( email=regular_user1.email )
  779. strings_displayed=[ 'Sequencing request "%s"' % request2.name,
  780. request1.states.REJECTED,
  781. rejection_message ]
  782. visible_buttons = [ 'Add sample', 'Edit samples', 'Submit request' ]
  783. strings_displayed.extend( visible_buttons )
  784. self.view_request( cntrller='requests',
  785. request_id=self.security.encode_id( request2.id ),
  786. strings_displayed=strings_displayed,
  787. strings_not_displayed=[ request1.states.SUBMITTED,
  788. request1.states.COMPLETE,
  789. request1.states.NEW] )
  790. def __test_070_select_datasets_for_transfer( self ):
  791. """Testing selecting datasets for data transfer"""
  792. # Logged in as admin_user
  793. self.logout()
  794. self.login( email=admin_user.email )
  795. # Setup the dummy datasets for sample1 of request1
  796. sample_datasets = [ '/path/to/sample1_dataset1',
  797. '/path/to/sample1_dataset2',
  798. '/path/to/sample1_dataset3' ]
  799. sample_dataset_file_names = [ dataset.split( '/' )[-1] for dataset in sample_datasets ]
  800. global request1_sample1
  801. request1_sample1 = request1.get_sample( 'Sample1_renamed' )
  802. external_service = request1_sample1.external_service
  803. strings_displayed_after_submit = [ 'Datasets (%s) have been selected for sample (%s)' % \
  804. ( str( sample_dataset_file_names )[1:-1].replace( "'", "" ), request1_sample1.name ) ]
  805. strings_displayed = [ 'Select datasets to transfer from data directory configured for the sequencer' ]
  806. self.add_datasets_to_sample( request_id=self.security.encode_id( request2.id ),
  807. sample_id= self.security.encode_id( request1_sample1.id ),
  808. external_service_id=self.security.encode_id( external_serviceexternal_service.id ),
  809. sample_datasets=sample_datasets,
  810. strings_displayed=strings_displayed,
  811. strings_displayed_after_submit=strings_displayed_after_submit )
  812. assert len( request1_sample1.datasets ) == len( sample_datasets )
  813. # check the sample dataset info page
  814. for sample1_dataset in request1_sample1.datasets:
  815. strings_displayed = [ '"%s" Dataset' % request1_sample1.name,
  816. sample1_dataset.file_path,
  817. sample1_dataset.transfer_status.NOT_STARTED ]
  818. self.view_sample_dataset( sample_dataset_id=self.security.encode_id( sample1_dataset.id ),
  819. strings_displayed=strings_displayed )
  820. def __test_075_manage_sample_datasets( self ):
  821. """Testing renaming, deleting and initiating transfer of sample datasets"""
  822. # Logged in as admin_user
  823. # Check renaming datasets
  824. new_sample_dataset_names = [ ( 'path', request1_sample1.datasets[0].name ),
  825. ( 'to', request1_sample1.datasets[1].name+'/renamed' ),
  826. ( 'none', request1_sample1.datasets[2].name+'_renamed' ) ]
  827. sample_dataset_ids = [ self.security.encode_id( dataset.id ) for dataset in request1_sample1.datasets ]
  828. strings_displayed = [ 'Rename datasets for Sample "%s"' % request1_sample1.name ]
  829. strings_displayed_after_submit = [ 'Changes saved successfully.' ]
  830. strings_displayed_after_submit.extend( [ new_name for prefix, new_name in new_sample_dataset_names ] )
  831. self.rename_sample_datasets( sample_id=self.security.encode_id( request1_sample1.id ),
  832. sample_dataset_ids=sample_dataset_ids,
  833. new_sample_dataset_names=new_sample_dataset_names,
  834. strings_displayed=strings_displayed )
  835. # Check deletion
  836. sample_dataset_ids = [ self.security.encode_id( request1_sample1.datasets[0].id ) ]
  837. strings_displayed = [ 'Manage "%s" datasets' % request1_sample1.name ]
  838. strings_displayed_after_submit = [ '%i datasets have been deleted.' % len( sample_dataset_ids ) ]
  839. strings_not_displayed = [ request1_sample1.datasets[0].name ]
  840. self.delete_sample_datasets( sample_id=self.security.encode_id( request1_sample1.id ),
  841. sample_dataset_ids=sample_dataset_ids,
  842. strings_displayed=strings_displayed,
  843. strings_displayed_after_submit=strings_displayed_after_submit,
  844. strings_not_displayed=strings_not_displayed )
  845. refresh( request1_sample1 )
  846. assert len( request1_sample1.datasets ) == ( len( new_sample_dataset_names )-1 )
  847. # Check data transfer
  848. # In this test we only test transfer initiation. For data transfer to complete
  849. # successfully we need RabbitMQ setup. Since that is not possible in the functional
  850. # tests framework, this checks if correct error message is displayed and the transfer
  851. # status of the sample datasets remains at 'Not started' when the Transfer button is clicked.
  852. sample_dataset_ids = [ self.security.encode_id( dataset.id ) for dataset in request1_sample1.datasets ]
  853. strings_displayed = [ 'Manage "%s" datasets' % request1_sample1.name ]
  854. strings_displayed_count = [ ( galaxy.model.SampleDataset.transfer_status.NOT_STARTED, len( request1_sample1.datasets ) ) ]
  855. strings_displayed_after_submit = [ "Error in sequencer login information. Please set your API Key in your User Preferences to transfer datasets." ]
  856. strings_not_displayed = [ galaxy.model.SampleDataset.transfer_status.IN_QUEUE,
  857. galaxy.model.SampleDataset.transfer_status.TRANSFERRING,
  858. galaxy.model.SampleDataset.transfer_status.ADD_TO_LIBRARY,
  859. galaxy.model.SampleDataset.transfer_status.COMPLETE ]
  860. self.start_sample_datasets_transfer( sample_id=self.security.encode_id( request1_sample1.id ),
  861. sample_dataset_ids=sample_dataset_ids,
  862. strings_displayed=strings_displayed,
  863. strings_displayed_after_submit=strings_displayed_after_submit,
  864. strings_not_displayed=strings_not_displayed,
  865. strings_displayed_count=strings_displayed_count )
  866. # check the sample dataset info page
  867. for sample1_dataset in request1_sample1.datasets:
  868. strings_displayed = [ '"%s" Dataset' % request1_sample1.name,
  869. sample1_dataset.file_path,
  870. sample1_dataset.transfer_status.NOT_STARTED ]
  871. self.view_sample_dataset( sample_dataset_id=self.security.encode_id( sample1_dataset.id ),
  872. strings_displayed=strings_displayed )
  873. def test_999_reset_data_for_later_test_runs( self ):
  874. """Reseting data to enable later test runs to pass"""
  875. # Logged in as admin_user
  876. self.logout()
  877. self.login( email=admin_user.email )
  878. ##################
  879. # Purge all libraries
  880. ##################
  881. for library in [ library1, library2 ]:
  882. self.delete_library_item( 'library_admin',
  883. self.security.encode_id( library.id ),
  884. self.security.encode_id( library.id ),
  885. library.name,
  886. item_type='library' )
  887. self.purge_library( self.security.encode_id( library.id ), library.name )
  888. ##################
  889. # Mark all requests deleted and delete all their samples
  890. ##################
  891. for request in [ request1, request2 ]:
  892. # delete samples
  893. for sample in request.samples:
  894. # delete sample datasets
  895. for sample_dataset in sample.datasets:
  896. delete_obj( sample_dataset )
  897. delete_obj( sample )
  898. mark_obj_deleted( request )
  899. ##################
  900. # Delete request_type permissions
  901. ##################
  902. for request_type in [ request_type1 ]:
  903. delete_request_type_permissions( request_type.id )
  904. ##################
  905. # Mark all request_types deleted
  906. ##################
  907. for request_type in [ request_type1 ]:
  908. mark_obj_deleted( request_type )
  909. ##################
  910. # Mark all forms deleted
  911. ##################
  912. for form in [ request_form_definition1, sample_form_definition1 ]:
  913. self.mark_form_deleted( self.security.encode_id( form.current.id ) )
  914. ##################
  915. # Mark all user_addresses deleted
  916. ##################
  917. for user_address in [ user_address1, user_address2 ]:
  918. mark_obj_deleted( user_address )
  919. ##################
  920. # Delete all non-private roles
  921. ##################
  922. for role in [ role1, role2 ]:
  923. self.mark_role_deleted( self.security.encode_id( role.id ), role.name )
  924. self.purge_role( self.security.encode_id( role.id ), role.name )
  925. # Manually delete the role from the database
  926. refresh( role )
  927. delete_obj( role )
  928. ##################
  929. # Delete all groups
  930. ##################
  931. for group in [ group1 ]:
  932. self.mark_group_deleted( self.security.encode_id( group.id ), group.name )
  933. self.purge_group( self.security.encode_id( group.id ), group.name )
  934. # Manually delete the group from the database
  935. refresh( group )
  936. delete_obj( group )