def test_anvil_workspace_page(self, mock_logger): # Requesting to load data from a workspace without an existing project url = reverse( anvil_workspace_page, args=[TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME]) collaborator_response = self._check_login_permissions(url, mock_logger) self.assertEqual(collaborator_response.get('Content-Type'), 'text/html') initial_json = self.get_initial_page_json(collaborator_response) self.assertEqual(initial_json['user']['username'], 'test_user_collaborator') response = self.client.post(url) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/create_project_from_workspace/{}/{}'.format( TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME)) self.mock_get_ws_access_level.assert_called_with( self.manager_user, TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME) # Test error handling when token refresh fails self.mock_get_ws_access_level.side_effect = TerraRefreshTokenFailedException( 'Failed to refresh token') response = self.client.post(url) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/login/google-oauth2?next=/workspace/{}/{}'.format( TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME)) self.mock_get_ws_access_level.assert_called_with( self.manager_user, TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME) # Requesting to load data for an existing project self.mock_get_ws_access_level.reset_mock() url = reverse(anvil_workspace_page, args=[TEST_WORKSPACE_NAMESPACE, TEST_WORKSPACE_NAME]) response = self.client.post(url) self.assertEqual(response.status_code, 302) self.assertEqual(response.url, '/project/R0001_1kg/project_page') self.mock_get_ws_access_level.assert_not_called() # Test login locally remove_token( self.manager_user ) # The user will be same as logging in locally after the access token is removed response = self.client.post(url) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/login/google-oauth2?next=/workspace/my-seqr-billing/anvil-1kg%2520project%2520n%25C3%25A5me%2520with%2520uni%25C3%25A7%25C3%25B8de' ) self.mock_get_ws_access_level.assert_not_called()
def test_is_google_authenticated(self, mock_social_auth_key): user = User.objects.get(username='******') r = is_google_authenticated(user) self.assertTrue(r) remove_token(user) r = is_google_authenticated(user) self.assertTrue(r) local_user = User.objects.get(username='******') r = is_google_authenticated(local_user) self.assertFalse(r) mock_social_auth_key.__bool__.return_value = False r = is_google_authenticated(user) self.assertFalse(r)
def test_is_anvil_authenticated(self, mock_social_auth_key, mock_terra_url): mock_social_auth_key.__bool__.return_value = False mock_terra_url.__bool__.return_value = True user = User.objects.get(username='******') r = is_anvil_authenticated(user) self.assertFalse(r) mock_social_auth_key.__bool__.return_value = True mock_terra_url.__bool__.return_value = False r = is_anvil_authenticated(user) self.assertFalse(r) mock_terra_url.__bool__.return_value = True r = is_anvil_authenticated(user) self.assertTrue(r) remove_token(user) r = is_anvil_authenticated(user) self.assertFalse(r)
def logout_view(request): user = request.user remove_token(user) logout(request) logger.info('Logged out {}'.format(user.email), extra={'user': user}) return redirect('/login')
def test_create_project_from_workspace(self, mock_file_exist, mock_email, mock_add_service_account, mock_has_service_account, mock_load_file, mock_api_logger, mock_sleep, mock_utils_logger): # Requesting to load data from a workspace without an existing project url = reverse( create_project_from_workspace, args=[TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME]) # Test user doesn't login response = self.client.post(url) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/login/google-oauth2?next=/api/create_project_from_workspace/submit/{}/{}' .format(TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME)) # Test the user needs sufficient workspace permissions self.check_manager_login(url) mock_utils_logger.warning.assert_called_with( 'User does not have sufficient permissions for workspace {}/{}'. format(TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME)) # Test missing required fields in the request body response = self.client.post(url, content_type='application/json', data=json.dumps({})) self.assertEqual(response.status_code, 400) self.assertEqual( response.reason_phrase, 'Field(s) "genomeVersion, uploadedFileId, dataPath" are required') self.mock_get_ws_access_level.assert_called_with( self.manager_user, TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME, meta_fields=['workspace.bucketName']) data = { 'genomeVersion': '38', 'uploadedFileId': 'test_temp_file_id', 'dataPath': '/test_path', } response = self.client.post(url, content_type='application/json', data=json.dumps(data)) self.assertEqual(response.status_code, 400) self.assertEqual( response.reason_phrase, 'Must agree to grant seqr access to the data in the associated workspace.' ) # Test parsing sample data error mock_load_file.return_value = LOAD_SAMPLE_DATA + BAD_SAMPLE_DATA response = self.client.post(url, content_type='application/json', data=json.dumps(REQUEST_BODY)) self.assertEqual(response.status_code, 400) response_json = response.json() self.assertListEqual(response_json['errors'], [ 'NA19679 is the mother of NA19674 but doesn\'t have a separate record in the table' ]) # Test adding service account exception mock_load_file.return_value = LOAD_SAMPLE_DATA mock_add_service_account.side_effect = TerraAPIException( 'Failed to grant seqr service account access to the workspace {}/{}' .format(TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME), 400) response = self.client.post(url, content_type='application/json', data=json.dumps(REQUEST_BODY)) self.assertEqual(response.status_code, 400) self.assertEqual( response.json()['error'], 'Failed to grant seqr service account access to the workspace {}/{}' .format(TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME)) # Test adding service account never processes mock_add_service_account.reset_mock(side_effect=True) mock_add_service_account.return_value = True mock_has_service_account.return_value = False response = self.client.post(url, content_type='application/json', data=json.dumps(REQUEST_BODY)) self.assertEqual(response.status_code, 400) self.assertEqual( response.json()['error'], 'Failed to grant seqr service account access to the workspace') mock_has_service_account.assert_called_with( self.manager_user, TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME) self.assertEqual(mock_has_service_account.call_count, 3) self.assertEqual(mock_sleep.call_count, 3) # Test bad data path mock_sleep.reset_mock() mock_has_service_account.reset_mock() mock_has_service_account.return_value = True mock_file_exist.return_value = False response = self.client.post( url, content_type='application/json', data=json.dumps(REQUEST_BODY_NO_SLASH_DATA_PATH)) self.assertEqual(response.status_code, 400) self.assertEqual(response.json()['error'], 'Data file or path test_no_slash_path is not found.') mock_file_exist.assert_called_with( 'gs://test_bucket/test_no_slash_path') mock_has_service_account.assert_called_with( self.manager_user, TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME) self.assertEqual(mock_has_service_account.call_count, 1) self.assertEqual(mock_sleep.call_count, 1) # Test valid operation mock_sleep.reset_mock() mock_has_service_account.reset_mock() mock_add_service_account.return_value = False mock_file_exist.return_value = True response = self.client.post(url, content_type='application/json', data=json.dumps(REQUEST_BODY)) self.assertEqual(response.status_code, 200) project = Project.objects.get( workspace_namespace=TEST_WORKSPACE_NAMESPACE, workspace_name=TEST_NO_PROJECT_WORKSPACE_NAME) response_json = response.json() self.assertEqual(project.guid, response_json['projectGuid']) self.assertListEqual([ project.genome_version, project.description, project.workspace_namespace, project.workspace_name ], [ '38', 'A test project', TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME ]) mock_add_service_account.assert_called_with( self.manager_user, TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME) mock_has_service_account.assert_not_called() mock_sleep.assert_not_called() mock_file_exist.assert_called_with('gs://test_bucket/test_path') email_body = """ [email protected] requested to load data from AnVIL workspace "{namespace}/{name}" at "gs://test_bucket/test_path" to seqr project {{project_name}} (guid: {guid}) The sample IDs to load are attached. """.format(namespace=TEST_WORKSPACE_NAMESPACE, name=TEST_NO_PROJECT_WORKSPACE_NAME, guid=project.guid) mock_email.assert_called_with( subject='AnVIL data loading request', body=email_body.format( project_name=TEST_NO_PROJECT_WORKSPACE_NAME), to=['*****@*****.**', '*****@*****.**'], attachments=[('{}_sample_ids.tsv'.format(project.guid), 'NA19675\nNA19678\nHG00735')]) html_project_name = '<a href="http://testserver/project/{guid}/project_page">{name}</a>'.format( name=TEST_NO_PROJECT_WORKSPACE_NAME, guid=project.guid) mock_email.return_value.attach_alternative.assert_called_with( email_body.format(project_name=html_project_name), 'text/html') mock_email.return_value.send.assert_called() # Test project exist url = reverse( create_project_from_workspace, args=[TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME]) response = self.client.post(url) self.assertEqual(response.status_code, 400) self.assertEqual( response.reason_phrase, 'Project "{name}" for workspace "{namespace}/{name}" exists.'. format(namespace=TEST_WORKSPACE_NAMESPACE, name=TEST_NO_PROJECT_WORKSPACE_NAME)) # Test sending email exception url = reverse( create_project_from_workspace, args=[TEST_WORKSPACE_NAMESPACE, TEST_NO_PROJECT_WORKSPACE_NAME2]) mock_email.side_effect = Exception( 'Something wrong while sending email.') response = self.client.post(url, content_type='application/json', data=json.dumps(REQUEST_BODY)) self.assertEqual(response.status_code, 200) mock_api_logger.error.assert_called_with( 'Exception while sending email to user test_user_manager. Something wrong while sending email.' ) # Test logged in locally remove_token( self.manager_user ) # The user will look like having logged in locally after the access token is removed response = self.client.post(url) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, '/login/google-oauth2?next=/api/create_project_from_workspace/submit/my-seqr-billing/anvil-no-project-workspace2' )
def logout_view(request): user = request.user remove_token(user) logout(request) logger.info('Logged out {}'.format(user.email), user) return redirect('/')