class GitHubOAuthTests(TestCase): fixtures = ['eric', 'test_data'] def setUp(self): self.client.login(username='******', password='******') self.user = User.objects.get(pk=1) self.project = Project.objects.get(slug='pip') self.org = RemoteOrganization.objects.create(slug='rtfd', json='') self.privacy = self.project.version_privacy_level self.service = GitHubService(user=self.user, account=None) self.external_version = get(Version, project=self.project, type=EXTERNAL) self.external_build = get(Build, project=self.project, version=self.external_version) self.integration = get(GitHubWebhook, project=self.project, provider_data={'url': 'https://github.com/'}) self.provider_data = [{ "config": { "url": "https://example.com/webhook" }, "url": "https://api.github.com/repos/test/Hello-World/hooks/12345678", }] def test_make_project_pass(self): repo_json = { 'name': 'testrepo', 'full_name': 'testuser/testrepo', 'description': 'Test Repo', 'git_url': 'git://github.com/testuser/testrepo.git', 'private': False, 'ssh_url': 'ssh://[email protected]:testuser/testrepo.git', 'html_url': 'https://github.com/testuser/testrepo', 'clone_url': 'https://github.com/testuser/testrepo.git', } repo = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsInstance(repo, RemoteRepository) self.assertEqual(repo.name, 'testrepo') self.assertEqual(repo.full_name, 'testuser/testrepo') self.assertEqual(repo.description, 'Test Repo') self.assertEqual( repo.avatar_url, settings.OAUTH_AVATAR_USER_DEFAULT_URL, ) self.assertIn(self.user, repo.users.all()) self.assertEqual(repo.organization, self.org) self.assertEqual( repo.clone_url, 'https://github.com/testuser/testrepo.git', ) self.assertEqual( repo.ssh_url, 'ssh://[email protected]:testuser/testrepo.git', ) self.assertEqual(repo.html_url, 'https://github.com/testuser/testrepo') def test_make_project_fail(self): repo_json = { 'name': '', 'full_name': '', 'description': '', 'git_url': '', 'private': True, 'ssh_url': '', 'html_url': '', 'clone_url': '', } github_project = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsNone(github_project) def test_make_organization(self): org_json = { 'html_url': 'https://github.com/testorg', 'name': 'Test Org', 'email': '*****@*****.**', 'login': '******', 'avatar_url': 'https://images.github.com/foobar', } org = self.service.create_organization(org_json) self.assertIsInstance(org, RemoteOrganization) self.assertEqual(org.slug, 'testorg') self.assertEqual(org.name, 'Test Org') self.assertEqual(org.email, '*****@*****.**') self.assertEqual(org.avatar_url, 'https://images.github.com/foobar') self.assertEqual(org.url, 'https://github.com/testorg') def test_import_with_no_token(self): """User without a GitHub SocialToken does not return a service.""" services = GitHubService.for_user(self.user) self.assertEqual(services, []) def test_multiple_users_same_repo(self): repo_json = { 'name': '', 'full_name': 'testrepo/multiple', 'description': '', 'git_url': '', 'private': False, 'ssh_url': '', 'html_url': '', 'clone_url': '', } github_project = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) user2 = User.objects.get(pk=2) service = GitHubService(user=user2, account=None) github_project_2 = service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsInstance(github_project, RemoteRepository) self.assertIsInstance(github_project_2, RemoteRepository) self.assertNotEqual(github_project_2, github_project) github_project_3 = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) github_project_4 = service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsInstance(github_project_3, RemoteRepository) self.assertIsInstance(github_project_4, RemoteRepository) self.assertEqual(github_project, github_project_3) self.assertEqual(github_project_2, github_project_4) github_project_5 = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) github_project_6 = service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertEqual(github_project, github_project_5) self.assertEqual(github_project_2, github_project_6) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_send_build_status_successful(self, session, mock_logger): session().post.return_value.status_code = 201 success = self.service.send_build_status(self.external_build, self.external_build.commit, BUILD_STATUS_SUCCESS) self.assertTrue(success) mock_logger.info.assert_called_with( "GitHub commit status created for project: %s, commit status: %s", self.project, BUILD_STATUS_SUCCESS) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_send_build_status_404_error(self, session, mock_logger): session().post.return_value.status_code = 404 success = self.service.send_build_status(self.external_build, self.external_build.commit, BUILD_STATUS_SUCCESS) self.assertFalse(success) mock_logger.info.assert_called_with( 'GitHub project does not exist or user does not have ' 'permissions: project=%s, user=%s, status=%s, url=%s', self.project, self.user, 404, 'https://api.github.com/repos/pypa/pip/statuses/297') @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_send_build_status_value_error(self, session, mock_logger): session().post.side_effect = ValueError success = self.service.send_build_status(self.external_build, self.external_build.commit, BUILD_STATUS_SUCCESS) self.assertFalse(success) mock_logger.exception.assert_called_with( 'GitHub commit status creation failed for project: %s', self.project, ) @override_settings(DEFAULT_PRIVACY_LEVEL='private') def test_make_private_project(self): """ Test ability to import ``public`` repositories under ``private`` level. """ repo_json = { 'name': 'testrepo', 'full_name': 'testuser/testrepo', 'description': 'Test Repo', 'git_url': 'git://github.com/testuser/testrepo.git', 'private': False, 'ssh_url': 'ssh://[email protected]:testuser/testrepo.git', 'html_url': 'https://github.com/testuser/testrepo', 'clone_url': 'https://github.com/testuser/testrepo.git', } repo = self.service.create_repository(repo_json, organization=self.org) self.assertIsNotNone(repo) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_setup_webhook_successful(self, session, mock_logger): session().post.return_value.status_code = 201 session().post.return_value.json.return_value = {} success, _ = self.service.setup_webhook(self.project, self.integration) self.integration.refresh_from_db() self.assertTrue(success) self.assertIsNotNone(self.integration.secret) mock_logger.info.assert_called_with( "GitHub webhook creation successful for project: %s", self.project, ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_setup_webhook_404_error(self, session, mock_logger): session().post.return_value.status_code = 404 success, _ = self.service.setup_webhook(self.project, self.integration) self.integration.refresh_from_db() self.assertFalse(success) self.assertIsNone(self.integration.secret) mock_logger.info.assert_called_with( 'GitHub project does not exist or user does not have ' 'permissions: project=%s', self.project, ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_setup_webhook_value_error(self, session, mock_logger): session().post.side_effect = ValueError success = self.service.setup_webhook(self.project, self.integration) self.integration.refresh_from_db() self.assertIsNone(self.integration.secret) mock_logger.exception.assert_called_with( 'GitHub webhook creation failed for project: %s', self.project, ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_update_webhook_successful(self, session, mock_logger): session().patch.return_value.status_code = 201 session().patch.return_value.json.return_value = {} success, _ = self.service.update_webhook(self.project, self.integration) self.integration.refresh_from_db() self.assertTrue(success) self.assertIsNotNone(self.integration.secret) mock_logger.info.assert_called_with( "GitHub webhook update successful for project: %s", self.project, ) @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') @mock.patch('readthedocs.oauth.services.github.GitHubService.setup_webhook' ) def test_update_webhook_404_error(self, setup_webhook, session): session().patch.return_value.status_code = 404 self.service.update_webhook(self.project, self.integration) setup_webhook.assert_called_once_with(self.project, self.integration) @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') @mock.patch('readthedocs.oauth.services.github.GitHubService.setup_webhook' ) def test_update_webhook_no_provider_data(self, setup_webhook, session): self.integration.provider_data = None self.integration.save() session().patch.side_effect = AttributeError self.service.update_webhook(self.project, self.integration) setup_webhook.assert_called_once_with(self.project, self.integration) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_update_webhook_value_error(self, session, mock_logger): session().patch.side_effect = ValueError self.service.update_webhook(self.project, self.integration) self.integration.refresh_from_db() self.assertIsNone(self.integration.secret) mock_logger.exception.assert_called_with( 'GitHub webhook update failed for project: %s', self.project, ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_get_provider_data_successful(self, session, mock_logger): self.integration.provider_data = {} self.integration.save() webhook_data = self.provider_data rtd_webhook_url = 'https://{domain}{path}'.format( domain=settings.PRODUCTION_DOMAIN, path=reverse( 'api_webhook', kwargs={ 'project_slug': self.project.slug, 'integration_pk': self.integration.pk, }, )) webhook_data[0]["config"]["url"] = rtd_webhook_url session().get.return_value.status_code = 200 session().get.return_value.json.return_value = webhook_data self.service.get_provider_data(self.project, self.integration) self.integration.refresh_from_db() self.assertEqual(self.integration.provider_data, webhook_data[0]) mock_logger.info.assert_called_with( 'GitHub integration updated with provider data for project: %s', self.project, ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_get_provider_data_404_error(self, session, mock_logger): self.integration.provider_data = {} self.integration.save() session().get.return_value.status_code = 404 self.service.get_provider_data(self.project, self.integration) self.integration.refresh_from_db() self.assertEqual(self.integration.provider_data, {}) mock_logger.info.assert_called_with( 'GitHub project does not exist or user does not have ' 'permissions: project=%s', self.project, ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_get_provider_data_attribute_error(self, session, mock_logger): self.integration.provider_data = {} self.integration.save() session().get.side_effect = AttributeError self.service.get_provider_data(self.project, self.integration) self.integration.refresh_from_db() self.assertEqual(self.integration.provider_data, {}) mock_logger.exception.assert_called_with( 'GitHub webhook Listing failed for project: %s', self.project, )
class GitHubOAuthTests(TestCase): fixtures = ['eric', 'test_data'] def setUp(self): self.client.login(username='******', password='******') self.user = User.objects.get(pk=1) self.project = Project.objects.get(slug='pip') self.org = RemoteOrganization.objects.create(slug='rtfd', json='') self.privacy = self.project.version_privacy_level self.service = GitHubService(user=self.user, account=None) self.external_version = get(Version, project=self.project, type=EXTERNAL) self.external_build = get( Build, project=self.project, version=self.external_version ) def test_make_project_pass(self): repo_json = { 'name': 'testrepo', 'full_name': 'testuser/testrepo', 'description': 'Test Repo', 'git_url': 'git://github.com/testuser/testrepo.git', 'private': False, 'ssh_url': 'ssh://[email protected]:testuser/testrepo.git', 'html_url': 'https://github.com/testuser/testrepo', 'clone_url': 'https://github.com/testuser/testrepo.git', } repo = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsInstance(repo, RemoteRepository) self.assertEqual(repo.name, 'testrepo') self.assertEqual(repo.full_name, 'testuser/testrepo') self.assertEqual(repo.description, 'Test Repo') self.assertEqual( repo.avatar_url, settings.OAUTH_AVATAR_USER_DEFAULT_URL, ) self.assertIn(self.user, repo.users.all()) self.assertEqual(repo.organization, self.org) self.assertEqual( repo.clone_url, 'https://github.com/testuser/testrepo.git', ) self.assertEqual( repo.ssh_url, 'ssh://[email protected]:testuser/testrepo.git', ) self.assertEqual(repo.html_url, 'https://github.com/testuser/testrepo') def test_make_project_fail(self): repo_json = { 'name': '', 'full_name': '', 'description': '', 'git_url': '', 'private': True, 'ssh_url': '', 'html_url': '', 'clone_url': '', } github_project = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsNone(github_project) def test_make_organization(self): org_json = { 'html_url': 'https://github.com/testorg', 'name': 'Test Org', 'email': '*****@*****.**', 'login': '******', 'avatar_url': 'https://images.github.com/foobar', } org = self.service.create_organization(org_json) self.assertIsInstance(org, RemoteOrganization) self.assertEqual(org.slug, 'testorg') self.assertEqual(org.name, 'Test Org') self.assertEqual(org.email, '*****@*****.**') self.assertEqual(org.avatar_url, 'https://images.github.com/foobar') self.assertEqual(org.url, 'https://github.com/testorg') def test_import_with_no_token(self): """User without a GitHub SocialToken does not return a service.""" services = GitHubService.for_user(self.user) self.assertEqual(services, []) def test_multiple_users_same_repo(self): repo_json = { 'name': '', 'full_name': 'testrepo/multiple', 'description': '', 'git_url': '', 'private': False, 'ssh_url': '', 'html_url': '', 'clone_url': '', } github_project = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) user2 = User.objects.get(pk=2) service = GitHubService(user=user2, account=None) github_project_2 = service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsInstance(github_project, RemoteRepository) self.assertIsInstance(github_project_2, RemoteRepository) self.assertNotEqual(github_project_2, github_project) github_project_3 = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) github_project_4 = service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertIsInstance(github_project_3, RemoteRepository) self.assertIsInstance(github_project_4, RemoteRepository) self.assertEqual(github_project, github_project_3) self.assertEqual(github_project_2, github_project_4) github_project_5 = self.service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) github_project_6 = service.create_repository( repo_json, organization=self.org, privacy=self.privacy, ) self.assertEqual(github_project, github_project_5) self.assertEqual(github_project_2, github_project_6) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_send_build_status_successful(self, session, mock_logger): session().post.return_value.status_code = 201 success = self.service.send_build_status( self.external_build, BUILD_STATUS_SUCCESS ) self.assertTrue(success) mock_logger.info.assert_called_with( "GitHub commit status created for project: %s, commit status: %s", self.project, BUILD_STATUS_SUCCESS ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_send_build_status_404_error(self, session, mock_logger): session().post.return_value.status_code = 404 success = self.service.send_build_status( self.external_build, BUILD_STATUS_SUCCESS ) self.assertFalse(success) mock_logger.info.assert_called_with( 'GitHub project does not exist or user does not have ' 'permissions: project=%s', self.project ) @mock.patch('readthedocs.oauth.services.github.log') @mock.patch('readthedocs.oauth.services.github.GitHubService.get_session') def test_send_build_status_value_error(self, session, mock_logger): session().post.side_effect = ValueError success = self.service.send_build_status( self.external_build, BUILD_STATUS_SUCCESS ) self.assertFalse(success) mock_logger.exception.assert_called_with( 'GitHub commit status creation failed for project: %s', self.project, ) @override_settings(DEFAULT_PRIVACY_LEVEL='private') def test_make_private_project(self): """ Test ability to import ``public`` repositories under ``private`` level. """ repo_json = { 'name': 'testrepo', 'full_name': 'testuser/testrepo', 'description': 'Test Repo', 'git_url': 'git://github.com/testuser/testrepo.git', 'private': False, 'ssh_url': 'ssh://[email protected]:testuser/testrepo.git', 'html_url': 'https://github.com/testuser/testrepo', 'clone_url': 'https://github.com/testuser/testrepo.git', } repo = self.service.create_repository(repo_json, organization=self.org) self.assertIsNotNone(repo)