Beispiel #1
0
class GitLabOAuthTests(TestCase):

    fixtures = ['eric', 'test_data']

    repo_response_data = {
        'lfs_enabled': True,
        'request_access_enabled': False,
        'approvals_before_merge': 0,
        'forks_count': 12,
        'only_allow_merge_if_all_discussions_are_resolved': False,
        'container_registry_enabled': True,
        'web_url': 'https://gitlab.com/testorga/testrepo',
        'owner': {
            'username': '******',
            'web_url': 'https://gitlab.com/testorga',
            'name': 'Test Orga',
            'state': 'active',
            'avatar_url': 'https://secure.gravatar.com/avatar/test',
            'id': 42,
        },
        'wiki_enabled': True,
        'id': 42,
        'merge_requests_enabled': True,
        'archived': False,
        'snippets_enabled': True,
        'http_url_to_repo': 'https://gitlab.com/testorga/testrepo.git',
        'namespace': {
            'kind': 'user',
            'name': 'Test Orga',
            'parent_id': None,
            'plan': 'early_adopter',
            'path': 'testorga',
            'id': 42,
            'full_path': 'testorga',
        },
        'star_count': 1,
        '_links': {
            'repo_branches':
            'http://gitlab.com/api/v4/projects/42/repository/branches',
            'merge_requests':
            'http://gitlab.com/api/v4/projects/42/merge_requests',
            'self': 'http://gitlab.com/api/v4/projects/42',
            'labels': 'http://gitlab.com/api/v4/projects/42/labels',
            'members': 'http://gitlab.com/api/v4/projects/42/members',
            'events': 'http://gitlab.com/api/v4/projects/42/events',
            'issues': 'http://gitlab.com/api/v4/projects/42/issues',
        },
        'resolve_outdated_diff_discussions': False,
        'issues_enabled': True,
        'path_with_namespace': 'testorga/testrepo',
        'ci_config_path': None,
        'shared_with_groups': [],
        'description': 'Test Repo',
        'default_branch': 'master',
        'visibility': 'public',
        'ssh_url_to_repo': '[email protected]:testorga/testrepo.git',
        'public_jobs': True,
        'path': 'testrepo',
        'import_status': 'none',
        'only_allow_merge_if_pipeline_succeeds': False,
        'open_issues_count': 0,
        'last_activity_at': '2017-11-28T14:21:17.570Z',
        'name': 'testrepo',
        'printing_merge_request_link_enabled': True,
        'name_with_namespace': 'testorga / testrepo',
        'created_at': '2017-11-27T19:19:30.906Z',
        'shared_runners_enabled': True,
        'creator_id': 389803,
        'avatar_url': None,
        'permissions': {
            'group_access': None,
            'project_access': {
                'notification_level': 3,
                'access_level': 40,
            },
        },
        'tag_list': [],
        'jobs_enabled': True,
    }

    group_response_data = {
        'id': 1,
        'name': 'Test Orga',
        'path': 'testorga',
        'description': 'An interesting group',
        'visibility': 'public',
        'lfs_enabled': True,
        'avatar_url': 'https://secure.gravatar.com/avatar/test',
        'web_url': 'https://gitlab.com/groups/testorga',
        'request_access_enabled': False,
        'full_name': 'Test Orga',
        'full_path': 'testorga',
        'parent_id': None,
    }

    def setUp(self):
        self.client.login(username='******', password='******')
        self.user = User.objects.get(pk=1)
        self.project = Project.objects.get(slug='pip')
        self.project.repo = 'https://gitlab.com/testorga/testrepo'
        self.project.save()
        self.org = RemoteOrganization.objects.create(slug='testorga', json='')
        self.privacy = self.project.version_privacy_level
        self.service = GitLabService(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(GitLabWebhook,
                               project=self.project,
                               provider_data={'id': '999999999'})
        self.provider_data = [{
            'id':
            1084320,
            'url':
            'https://readthedocs.io/api/v2/webhook/test/99999999/',
        }]

    def get_private_repo_data(self):
        """Manipulate repo response data to get private repo data."""
        data = self.repo_response_data.copy()
        data.update({
            'visibility': 'private',
        })
        return data

    def test_make_project_pass(self):
        with mock.patch('readthedocs.oauth.services.gitlab.GitLabService.is_owned_by') as m:  # yapf: disable
            m.return_value = True
            repo = self.service.create_repository(
                self.repo_response_data,
                organization=self.org,
                privacy=self.privacy,
            )
        self.assertIsInstance(repo, RemoteRepository)
        self.assertEqual(repo.name, 'testrepo')
        self.assertEqual(repo.full_name, 'testorga / testrepo')
        self.assertEqual(repo.description, 'Test Repo')
        self.assertEqual(
            repo.avatar_url,
            'https://secure.gravatar.com/avatar/test',
        )
        self.assertIn(self.user, repo.users.all())
        self.assertEqual(repo.organization, self.org)
        self.assertEqual(
            repo.clone_url,
            'https://gitlab.com/testorga/testrepo.git',
        )
        self.assertEqual(repo.ssh_url, '[email protected]:testorga/testrepo.git')
        self.assertEqual(repo.html_url, 'https://gitlab.com/testorga/testrepo')
        self.assertTrue(repo.admin)
        self.assertFalse(repo.private)

    def test_make_private_project_fail(self):
        repo = self.service.create_repository(
            self.get_private_repo_data(),
            organization=self.org,
            privacy=self.privacy,
        )
        self.assertIsNone(repo)

    def test_make_private_project_success(self):
        repo = self.service.create_repository(
            self.get_private_repo_data(),
            organization=self.org,
            privacy=constants.PRIVATE,
        )
        self.assertIsInstance(repo, RemoteRepository)
        self.assertTrue(repo.private, True)

    def test_make_organization(self):
        org = self.service.create_organization(self.group_response_data)
        self.assertIsInstance(org, RemoteOrganization)
        self.assertEqual(org.slug, 'testorga')
        self.assertEqual(org.name, 'Test Orga')
        self.assertEqual(
            org.avatar_url,
            'https://secure.gravatar.com/avatar/test',
        )
        self.assertEqual(org.url, 'https://gitlab.com/testorga')

    @override_settings(DEFAULT_PRIVACY_LEVEL='private')
    def test_make_private_project(self):
        """
        Test ability to import ``public`` repositories under ``private`` level.
        """
        data = self.repo_response_data.copy()
        data['visibility'] = 'public'
        with mock.patch('readthedocs.oauth.services.gitlab.GitLabService.is_owned_by') as m:  # yapf: disable
            m.return_value = True
            repo = self.service.create_repository(data, organization=self.org)
        self.assertIsNotNone(repo)

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.get_session')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService._get_repo_id')
    def test_send_build_status_successful(self, repo_id, session, mock_logger):
        session().post.return_value.status_code = 201
        repo_id().return_value = '9999'

        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(
            "GitLab commit status created for project: %s, commit status: %s",
            self.project, BUILD_STATUS_SUCCESS)

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.get_session')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService._get_repo_id')
    def test_send_build_status_404_error(self, repo_id, session, mock_logger):
        session().post.return_value.status_code = 404
        repo_id().return_value = '9999'

        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(
            'GitLab project does not exist or user does not have '
            'permissions: project=%s', self.project)

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.get_session')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService._get_repo_id')
    def test_send_build_status_value_error(self, repo_id, session,
                                           mock_logger):
        session().post.side_effect = ValueError
        repo_id().return_value = '9999'

        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(
            'GitLab commit status creation failed for project: %s',
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.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(
            "GitLab webhook creation successful for project: %s",
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.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(
            'Gitlab project does not exist or user does not have '
            'permissions: project=%s',
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.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(
            'GitLab webhook creation failed for project: %s',
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.get_session')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService._get_repo_id')
    def test_update_webhook_successful(self, repo_id, session, mock_logger):
        repo_id.return_value = '9999'
        session().put.return_value.status_code = 200
        session().put.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(
            "GitLab webhook update successful for project: %s",
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.get_session')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.setup_webhook'
                )
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService._get_repo_id')
    def test_update_webhook_404_error(self, repo_id, setup_webhook, session):
        repo_id.return_value = '9999'
        session().put.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.gitlab.GitLabService.get_session')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.setup_webhook'
                )
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService._get_repo_id')
    def test_update_webhook_no_provider_data(self, repo_id, setup_webhook,
                                             session):
        self.integration.provider_data = None
        self.integration.save()

        repo_id.return_value = '9999'
        session().put.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.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.get_session')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService._get_repo_id')
    def test_update_webhook_value_error(self, repo_id, session, mock_logger):
        repo_id.return_value = '9999'
        session().put.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(
            'GitLab webhook update failed for project: %s',
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.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]["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(
            'GitLab integration updated with provider data for project: %s',
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.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(
            'GitLab project does not exist or user does not have '
            'permissions: project=%s',
            self.project,
        )

    @mock.patch('readthedocs.oauth.services.gitlab.log')
    @mock.patch('readthedocs.oauth.services.gitlab.GitLabService.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(
            'GitLab webhook Listing failed for project: %s',
            self.project,
        )
Beispiel #2
0
class GitLabOAuthTests(TestCase):

    fixtures = ['eric', 'test_data']

    repo_response_data = {
        'lfs_enabled': True,
        'request_access_enabled': False,
        'approvals_before_merge': 0,
        'forks_count': 12,
        'only_allow_merge_if_all_discussions_are_resolved': False,
        'container_registry_enabled': True,
        'web_url': 'https://gitlab.com/testorga/testrepo',
        'owner': {
            'username': '******',
            'web_url': 'https://gitlab.com/testorga',
            'name': 'Test Orga',
            'state': 'active',
            'avatar_url': 'https://secure.gravatar.com/avatar/test',
            'id': 42,
        },
        'wiki_enabled': True,
        'id': 42,
        'merge_requests_enabled': True,
        'archived': False,
        'snippets_enabled': True,
        'http_url_to_repo': 'https://gitlab.com/testorga/testrepo.git',
        'namespace': {
            'kind': 'user',
            'name': 'Test Orga',
            'parent_id': None,
            'plan': 'early_adopter',
            'path': 'testorga',
            'id': 42,
            'full_path': 'testorga',
        },
        'star_count': 1,
        '_links': {
            'repo_branches': 'http://gitlab.com/api/v4/projects/42/repository/branches',
            'merge_requests': 'http://gitlab.com/api/v4/projects/42/merge_requests',
            'self': 'http://gitlab.com/api/v4/projects/42',
            'labels': 'http://gitlab.com/api/v4/projects/42/labels',
            'members': 'http://gitlab.com/api/v4/projects/42/members',
            'events': 'http://gitlab.com/api/v4/projects/42/events',
            'issues': 'http://gitlab.com/api/v4/projects/42/issues',
        },
        'resolve_outdated_diff_discussions': False,
        'issues_enabled': True,
        'path_with_namespace': 'testorga/testrepo',
        'ci_config_path': None,
        'shared_with_groups': [],
        'description': 'Test Repo',
        'default_branch': 'master',
        'visibility': 'public',
        'ssh_url_to_repo': '[email protected]:testorga/testrepo.git',
        'public_jobs': True,
        'path': 'testrepo',
        'import_status': 'none',
        'only_allow_merge_if_pipeline_succeeds': False,
        'open_issues_count': 0,
        'last_activity_at': '2017-11-28T14:21:17.570Z',
        'name': 'testrepo',
        'printing_merge_request_link_enabled': True,
        'name_with_namespace': 'testorga / testrepo',
        'created_at': '2017-11-27T19:19:30.906Z',
        'shared_runners_enabled': True,
        'creator_id': 389803,
        'avatar_url': None,
        'permissions': {
            'group_access': None,
            'project_access': {
                'notification_level': 3,
                'access_level': 40,
            },
        },
        'tag_list': [],
        'jobs_enabled': True,
    }

    group_response_data = {
        'id': 1,
        'name': 'Test Orga',
        'path': 'testorga',
        'description': 'An interesting group',
        'visibility': 'public',
        'lfs_enabled': True,
        'avatar_url': 'https://secure.gravatar.com/avatar/test',
        'web_url': 'https://gitlab.com/groups/testorga',
        'request_access_enabled': False,
        'full_name': 'Test Orga',
        'full_path': 'testorga',
        'parent_id': None,
    }

    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='testorga', json='')
        self.privacy = self.project.version_privacy_level
        self.service = GitLabService(user=self.user, account=None)

    def get_private_repo_data(self):
        """Manipulate repo response data to get private repo data."""
        data = self.repo_response_data.copy()
        data.update({
            'visibility': 'private',
        })
        return data

    def test_make_project_pass(self):
        with mock.patch('readthedocs.oauth.services.gitlab.GitLabService.is_owned_by') as m:  # yapf: disable
            m.return_value = True
            repo = self.service.create_repository(
                self.repo_response_data, organization=self.org,
                privacy=self.privacy)
        self.assertIsInstance(repo, RemoteRepository)
        self.assertEqual(repo.name, 'testrepo')
        self.assertEqual(repo.full_name, 'testorga / testrepo')
        self.assertEqual(repo.description, 'Test Repo')
        self.assertEqual(
            repo.avatar_url,
            'https://secure.gravatar.com/avatar/test',
        )
        self.assertIn(self.user, repo.users.all())
        self.assertEqual(repo.organization, self.org)
        self.assertEqual(
            repo.clone_url,
            'https://gitlab.com/testorga/testrepo.git',
        )
        self.assertEqual(repo.ssh_url, '[email protected]:testorga/testrepo.git')
        self.assertEqual(repo.html_url, 'https://gitlab.com/testorga/testrepo')
        self.assertTrue(repo.admin)
        self.assertFalse(repo.private)

    def test_make_private_project_fail(self):
        repo = self.service.create_repository(
            self.get_private_repo_data(), organization=self.org,
            privacy=self.privacy)
        self.assertIsNone(repo)

    def test_make_private_project_success(self):
        repo = self.service.create_repository(
            self.get_private_repo_data(), organization=self.org,
            privacy=constants.PRIVATE)
        self.assertIsInstance(repo, RemoteRepository)
        self.assertTrue(repo.private, True)

    def test_make_organization(self):
        org = self.service.create_organization(self.group_response_data)
        self.assertIsInstance(org, RemoteOrganization)
        self.assertEqual(org.slug, 'testorga')
        self.assertEqual(org.name, 'Test Orga')
        self.assertEqual(
            org.avatar_url,
            'https://secure.gravatar.com/avatar/test',
        )
        self.assertEqual(org.url, 'https://gitlab.com/testorga')
class GitLabOAuthTests(TestCase):

    fixtures = ['eric', 'test_data']

    repo_response_data = {
        'lfs_enabled': True,
        'request_access_enabled': False,
        'approvals_before_merge': 0,
        'forks_count': 12,
        'only_allow_merge_if_all_discussions_are_resolved': False,
        'container_registry_enabled': True,
        'web_url': 'https://gitlab.com/testorga/testrepo',
        'owner': {
            'username': '******',
            'web_url': 'https://gitlab.com/testorga',
            'name': 'Test Orga',
            'state': 'active',
            'avatar_url': 'https://secure.gravatar.com/avatar/test',
            'id': 42,
        },
        'wiki_enabled': True,
        'id': 42,
        'merge_requests_enabled': True,
        'archived': False,
        'snippets_enabled': True,
        'http_url_to_repo': 'https://gitlab.com/testorga/testrepo.git',
        'namespace': {
            'kind': 'user',
            'name': 'Test Orga',
            'parent_id': None,
            'plan': 'early_adopter',
            'path': 'testorga',
            'id': 42,
            'full_path': 'testorga',
        },
        'star_count': 1,
        '_links': {
            'repo_branches': 'http://gitlab.com/api/v4/projects/42/repository/branches',
            'merge_requests': 'http://gitlab.com/api/v4/projects/42/merge_requests',
            'self': 'http://gitlab.com/api/v4/projects/42',
            'labels': 'http://gitlab.com/api/v4/projects/42/labels',
            'members': 'http://gitlab.com/api/v4/projects/42/members',
            'events': 'http://gitlab.com/api/v4/projects/42/events',
            'issues': 'http://gitlab.com/api/v4/projects/42/issues',
        },
        'resolve_outdated_diff_discussions': False,
        'issues_enabled': True,
        'path_with_namespace': 'testorga/testrepo',
        'ci_config_path': None,
        'shared_with_groups': [],
        'description': 'Test Repo',
        'default_branch': 'master',
        'visibility': 'public',
        'ssh_url_to_repo': '[email protected]:testorga/testrepo.git',
        'public_jobs': True,
        'path': 'testrepo',
        'import_status': 'none',
        'only_allow_merge_if_pipeline_succeeds': False,
        'open_issues_count': 0,
        'last_activity_at': '2017-11-28T14:21:17.570Z',
        'name': 'testrepo',
        'printing_merge_request_link_enabled': True,
        'name_with_namespace': 'testorga / testrepo',
        'created_at': '2017-11-27T19:19:30.906Z',
        'shared_runners_enabled': True,
        'creator_id': 389803,
        'avatar_url': None,
        'permissions': {
            'group_access': None,
            'project_access': {
                'notification_level': 3,
                'access_level': 40,
            },
        },
        'tag_list': [],
        'jobs_enabled': True,
    }

    group_response_data = {
        'id': 1,
        'name': 'Test Orga',
        'path': 'testorga',
        'description': 'An interesting group',
        'visibility': 'public',
        'lfs_enabled': True,
        'avatar_url': 'https://secure.gravatar.com/avatar/test',
        'web_url': 'https://gitlab.com/groups/testorga',
        'request_access_enabled': False,
        'full_name': 'Test Orga',
        'full_path': 'testorga',
        'parent_id': None,
    }

    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='testorga', json='')
        self.privacy = self.project.version_privacy_level
        self.service = GitLabService(user=self.user, account=None)

    def get_private_repo_data(self):
        """Manipulate repo response data to get private repo data."""
        data = self.repo_response_data.copy()
        data.update({
            'visibility': 'private',
        })
        return data

    def test_make_project_pass(self):
        with mock.patch('readthedocs.oauth.services.gitlab.GitLabService.is_owned_by') as m:  # yapf: disable
            m.return_value = True
            repo = self.service.create_repository(
                self.repo_response_data, organization=self.org,
                privacy=self.privacy,
            )
        self.assertIsInstance(repo, RemoteRepository)
        self.assertEqual(repo.name, 'testrepo')
        self.assertEqual(repo.full_name, 'testorga / testrepo')
        self.assertEqual(repo.description, 'Test Repo')
        self.assertEqual(
            repo.avatar_url,
            'https://secure.gravatar.com/avatar/test',
        )
        self.assertIn(self.user, repo.users.all())
        self.assertEqual(repo.organization, self.org)
        self.assertEqual(
            repo.clone_url,
            'https://gitlab.com/testorga/testrepo.git',
        )
        self.assertEqual(repo.ssh_url, '[email protected]:testorga/testrepo.git')
        self.assertEqual(repo.html_url, 'https://gitlab.com/testorga/testrepo')
        self.assertTrue(repo.admin)
        self.assertFalse(repo.private)

    def test_make_private_project_fail(self):
        repo = self.service.create_repository(
            self.get_private_repo_data(), organization=self.org,
            privacy=self.privacy,
        )
        self.assertIsNone(repo)

    def test_make_private_project_success(self):
        repo = self.service.create_repository(
            self.get_private_repo_data(), organization=self.org,
            privacy=constants.PRIVATE,
        )
        self.assertIsInstance(repo, RemoteRepository)
        self.assertTrue(repo.private, True)

    def test_make_organization(self):
        org = self.service.create_organization(self.group_response_data)
        self.assertIsInstance(org, RemoteOrganization)
        self.assertEqual(org.slug, 'testorga')
        self.assertEqual(org.name, 'Test Orga')
        self.assertEqual(
            org.avatar_url,
            'https://secure.gravatar.com/avatar/test',
        )
        self.assertEqual(org.url, 'https://gitlab.com/testorga')

    @override_settings(DEFAULT_PRIVACY_LEVEL='private')
    def test_make_private_project(self):
        """
        Test ability to import ``public`` repositories under ``private`` level.
        """
        data = self.repo_response_data.copy()
        data['visibility'] = 'public'
        with mock.patch('readthedocs.oauth.services.gitlab.GitLabService.is_owned_by') as m:  # yapf: disable
            m.return_value = True
            repo = self.service.create_repository(data, organization=self.org)
        self.assertIsNotNone(repo)

    def test_setup_webhook(self):
        success, response = self.service.setup_webhook(self.project)
        self.assertFalse(success)
        self.assertIsNone(response)