def test_request_headers_are_removed(self): client = APIClient() client.login(username='******', password='******') project = fixture.get(Project, main_language_project=None) integration = fixture.get( Integration, project=project, integration_type=Integration.GITHUB_WEBHOOK, provider_data='', ) resp = client.post( '/api/v2/webhook/github/{}/'.format(project.slug), {'ref': 'exchange_json'}, format='json', HTTP_X_FORWARDED_FOR='1.2.3.4', HTTP_X_REAL_IP='5.6.7.8', HTTP_X_FOO='bar', ) exchange = HttpExchange.objects.get(integrations=integration) self.assertEqual( exchange.request_headers, { 'Content-Type': 'application/json; charset=None', 'Cookie': '', 'X-Foo': 'bar', }, )
def test_popularity_with_existing_tags(self): tag1 = get(Tag, name='tag1') video1 = get(LeagueVideo, tags=[tag1]) self.assertEqual(tag1.taggit_taggeditem_items.count(), 1) self.assertEqual(video1.popularity, 1)
def test_popularity_with_multiple_tags(self): v = get(LeagueVideo) for num in range(0,10): t = get(Tag, name='tag' + str(num)) v.tags.add(t) self.assertEqual(v.popularity, 10)
def test_subproject_with_translation_with_custom_domain(self): fixture.get( Domain, domain='docs.example.com', canonical=True, cname=True, https=True, project=self.superproject_en, ) url = resolve(self.superproject_en, filename='') self.assertEqual(url, 'http://docs.example.com/en/latest/') url = resolve(self.superproject_es, filename='') self.assertEqual(url, 'http://docs.example.com/es/latest/') # yapf: disable url = resolve(self.subproject_en, filename='') self.assertEqual( url, ('http://docs.example.com/projects/' '{subproject.slug}/en/latest/').format( subproject=self.subproject_en, ), ) url = resolve(self.subproject_es, filename='') self.assertEqual( url, ('http://docs.example.com/projects/' '{subproject.slug}/es/latest/').format( subproject=self.subproject_en, ), )
def setUp(self): self.project = get( Project, main_language_project=None, install_project=False, ) self.version = get(Version, project=self.project)
def setUp(self): self.project = get(Project, documentation_type='mkdocs', name='mkdocs') self.version = get(Version, project=self.project) self.build_env = namedtuple('project', 'version') self.build_env.project = self.project self.build_env.version = self.version
def setUp(self): with mock.patch('readthedocs.projects.models.broadcast'): self.owner = create_user(username='******', password='******') self.tester = create_user(username='******', password='******') self.pip = fixture.get( Project, slug='pip', users=[self.owner], main_language_project=None, ) self.seed = fixture.get( Project, slug='sub', users=[self.owner], main_language_project=None, ) self.subproject = fixture.get( Project, slug='subproject', language='ja', users=[self.owner], main_language_project=None, ) self.translation = fixture.get( Project, slug='trans', language='ja', users=[self.owner], main_language_project=None, ) self.pip.add_subproject(self.subproject, alias='sub') self.pip.translations.add(self.translation)
def test_get_metadata_view(self): node = create_node() get_data = { 'project': node.project.slug, 'version': node.version.slug, 'page': node.page } request = self.request_factory.get('/_get_metadata/', get_data) response = get_metadata(request) response.render() number_of_comments = response.data[node.latest_hash()] # There haven't been any comments yet. self.assertEqual(number_of_comments, 0) # Now we'll make one. get(DocumentComment, node=node, text="Our first comment!") second_request = self.request_factory.get('/_get_metadata/', get_data) second_response = get_metadata(second_request) second_response.render() number_of_comments = second_response.data[node.latest_hash()] # And sure enough - one comment. self.assertEqual(number_of_comments, 1)
def test_exchange_form_request_body(self): client = APIClient() client.login(username='******', password='******') project = fixture.get(Project, main_language_project=None) integration = fixture.get(Integration, project=project, integration_type=Integration.GITHUB_WEBHOOK, provider_data='') resp = client.post( '/api/v2/webhook/github/{0}/'.format(project.slug), 'payload=%7B%22ref%22%3A+%22exchange_form%22%7D', content_type='application/x-www-form-urlencoded', ) exchange = HttpExchange.objects.get(integrations=integration) self.assertEqual( exchange.request_body, '{"ref": "exchange_form"}' ) self.assertEqual( exchange.request_headers, {u'Content-Type': u'application/x-www-form-urlencoded', u'Cookie': u''} ) self.assertEqual( exchange.response_body, ('{{"build_triggered": false, "project": "{0}", "versions": []}}' .format(project.slug)), ) self.assertEqual( exchange.response_headers, {u'Allow': u'POST, OPTIONS', u'Content-Type': u'text/html; charset=utf-8'} )
def test_add_comment_view_with_changed_hash(self): first_hash = "THEoriginalHASH" second_hash = 'ANEWCRAZYHASH' comment_text = "This comment will follow its node despite hash changing." # Create a comment on a node whose latest hash is the first one. node = create_node(hash=first_hash) get(DocumentComment, node=node, text=comment_text) # Now change the node's hash. node.update_hash(second_hash, 'ANEWCRAZYCOMMIT') node_from_orm = DocumentNode.objects.from_hash(version_slug=node.version.slug, page=node.page, node_hash=node.latest_hash(), project_slug=node.project.slug) # It's the same node. self.assertEqual(node, node_from_orm) # Get all the comments with the second hash. query_params = {'node': second_hash, 'document_page': node.page, 'project': node.project.slug, 'version': node.version.slug, } response = self.client.get('/api/v2/comments/', query_params) self.assertEqual(response.data['results'][0]['text'], comment_text)
def test_list_get(self): parent_category = get(Category, parent=None) categories = get(Category, parent=parent_category, n=2) categories.append(parent_category) resp = self.client.get(self.uri, data=self.auth_params) self.assertResponseCode(resp, 200) self.assertResponseMetaList(resp, len(categories))
def test_feature_for_project_is_implicitly_applied(self): project = fixture.get(Project, main_language_project=None) # Explicit feature feature1 = fixture.get(Feature, projects=[project]) # False implicit feature feature2 = fixture.get( Feature, projects=[], add_date=project.pub_date + timedelta(days=1), default_true=False, ) # True implicit feature before add date feature3 = fixture.get( Feature, projects=[], add_date=project.pub_date + timedelta(days=1), default_true=True, ) # True implicit feature after add date feature4 = fixture.get( Feature, projects=[], add_date=project.pub_date - timedelta(days=1), default_true=True, ) self.assertQuerysetEqual( Feature.objects.for_project(project), [repr(feature1), repr(feature3)], ordered=False, )
def test_get_previous_build(self): build_one = get( Build, project=self.project, version=self.version, config={'version': 1}, ) build_two = get( Build, project=self.project, version=self.version, config={'version': 2}, ) build_three = get( Build, project=self.project, version=self.version, config={'version': 3}, success=False, ) self.assertIsNone(build_one.previous) self.assertEqual(build_two.previous, build_one) self.assertEqual(build_three.previous, build_two) self.assertEqual(build_three.previous.previous, build_one)
def test_build_is_stale(self): now = timezone.now() build_one = get( Build, project=self.project, version=self.version, date=now - datetime.timedelta(minutes=8), state='finished' ) build_two = get( Build, project=self.project, version=self.version, date=now - datetime.timedelta(minutes=6), state='triggered' ) build_three = get( Build, project=self.project, version=self.version, date=now - datetime.timedelta(minutes=2), state='triggered' ) self.assertFalse(build_one.is_stale) self.assertTrue(build_two.is_stale) self.assertFalse(build_three.is_stale)
def test_filter_reviews_by_date(self): now = datetime.now() review1 = get(ProductReview) review2 = get(ProductReview) review2.date_created = now - timedelta(days=2) review2.save() review3 = get(ProductReview) review3.date_created = now - timedelta(days=10) review3.save() url = reverse('dashboard:reviews-list') response = self.client.get(url, {'date_from': now - timedelta(days=5)}) self.assertQuerysetContains(response.context['review_list'], [review1, review2]) response = self.client.get(url, {'date_to': now - timedelta(days=5)}) self.assertQuerysetContains(response.context['review_list'], [review3]) response = self.client.get(url, { 'date_from': now - timedelta(days=12), 'date_to': now - timedelta(days=9) }) self.assertQuerysetContains(response.context['review_list'], [review3])
def test_non_persistent_message(self, send_email, render_to_string): render_to_string.return_value = 'Test' class TestNotification(SiteNotification): name = 'foo' success_message = 'Test success message' success_level = INFO_NON_PERSISTENT user = fixture.get(User) # Setting the primary and verified email address of the user email = fixture.get(EmailAddress, user=user, primary=True, verified=True) n = TestNotification(user, True) backend = SiteBackend(request=None) self.assertEqual(PersistentMessage.objects.count(), 0) backend.send(n) # No email is sent for non persistent messages send_email.assert_not_called() self.assertEqual(PersistentMessage.objects.count(), 1) self.assertEqual(PersistentMessage.objects.filter(read=False).count(), 1) self.client.force_login(user) response = self.client.get('/dashboard/') self.assertContains(response, 'Test success message') self.assertEqual(PersistentMessage.objects.count(), 1) self.assertEqual(PersistentMessage.objects.filter(read=True).count(), 1) response = self.client.get('/dashboard/') self.assertNotContains(response, 'Test success message')
def test_plastic_failing_badge(self): get(Build, project=self.project, version=self.version, success=False) res = self.client.get(self.badge_url, {'version': self.version.slug, 'style': 'plastic'}) self.assertContains(res, 'failing') # The plastic badge has slightly more rounding self.assertContains(res, 'rx="4"')
def test_social_passing_badge(self): get(Build, project=self.project, version=self.version, success=True) res = self.client.get(self.badge_url, {'version': self.version.slug, 'style': 'social'}) self.assertContains(res, 'passing') # The social badge (but not the other badges) has this element self.assertContains(res, 'rlink')
def test_user_can_not_add_other_user_project_as_translation(self): # Two users, two projects with different language user_a = User.objects.get(username='******') project_a = get( Project, users=[user_a], language='es', main_language_project=None, ) user_b = User.objects.get(username='******') project_b = get( Project, users=[user_b], language='en', main_language_project=None, ) # User A try to add project B as translation of project A self.client.login(username=user_a.username, password='******') resp = self.client.post( reverse('projects_translations', args=[project_a.slug]), data={'project': project_b.slug}, ) self.assertContains(resp, 'Select a valid choice') self.assertEqual(project_a.translations.count(), 0) project_b.refresh_from_db() self.assertIsNone(project_b.main_language_project)
def test_previous_users_can_list_and_delete_translations_not_owner(self): """Test to make sure that previous users can list and delete projects where they aren't owners.""" user_a = User.objects.get(username='******') project_a = get( Project, users=[user_a], language='es', main_language_project=None, ) user_b = User.objects.get(username='******') project_b = get( Project, users=[user_b], language='en', main_language_project=None, ) project_a.translations.add(project_b) project_a.save() self.client.login(username=user_a.username, password='******') # Project B is listed under user A translations resp = self.client.get( reverse('projects_translations', args=[project_a.slug]), ) self.assertContains(resp, project_b.slug) resp = self.client.post( reverse( 'projects_translations_delete', args=[project_a.slug, project_b.slug], ), follow=True, ) self.assertEqual(resp.status_code, 200) self.assertNotIn(project_b, project_a.translations.all())
def test_filter_reviews_by_status(self): url = reverse('dashboard:reviews-list') user1 = get(User) user2 = get(User) review1 = get(ProductReview, user=user1, status=1) review2 = get(ProductReview, user=user2, status=0) review3 = get(ProductReview, user=user2, status=2) response = self.get(url, params={'status': 0}) self.assertEqual(len(response.context['review_list']), 1) self.assertEqual(response.context['review_list'][0], review2) response = self.get(url, params={'status': 1}) self.assertEqual(len(response.context['review_list']), 1) self.assertEqual(response.context['review_list'][0], review1) response = self.get(url, params={'status': 2}) self.assertEqual(len(response.context['review_list']), 1) self.assertEqual(response.context['review_list'][0], review3) response = self.get(url, params={'status': 3}) reviews = response.context['review_list'] self.assertTrue(review1 in reviews)
def test_filter_reviews_by_date(self): def n_days_ago(days): """ The tests below pass timestamps as GET parameters, but the ProductReviewSearchForm doesn't recognize the timezone notation. """ return timezone.make_naive( now - timedelta(days=days), timezone=timezone.utc) now = timezone.now() review1 = get(ProductReview) review2 = get(ProductReview) review2.date_created = now - timedelta(days=2) review2.save() review3 = get(ProductReview) review3.date_created = now - timedelta(days=10) review3.save() url = reverse('dashboard:reviews-list') response = self.get(url, params={'date_from': n_days_ago(5)}) self.assertQuerysetContains(response.context['review_list'], [review1, review2]) response = self.get(url, params={'date_to': n_days_ago(5)}) self.assertQuerysetContains(response.context['review_list'], [review3]) response = self.get(url, params={ 'date_from': n_days_ago(12), 'date_to': n_days_ago(9), }) self.assertQuerysetContains(response.context['review_list'], [review3])
def testUniqueness(self): try: F = get(EntityField, name="some_field") except: self.assertTrue(False, 'name is unique whatever the entity') with self.assertRaises(BadDataError) or self.assertRaises(IntegrityError): F = get(EntityField, name="some_field", entity=self.instance_of_field.entity)
def testUniqueness(self): try: E = get(Entity, name="foo", description='some_description', fields=5) except: self.assertTrue(False, 'name is unique whatever the project') with self.assertRaises(BadDataError) or self.assertRaises(IntegrityError): E = get(Entity, name="foo", description='some_description', fields=5, project=self.instance_of_entityA.project)
def test_proper_cname_uppercase(self): get(Domain, project=self.pip, domain='pip.random.com') request = self.factory.get(self.url, HTTP_HOST='PIP.RANDOM.COM') self.middleware.process_request(request) self.assertEqual(request.urlconf, self.urlconf_subdomain) self.assertEqual(request.cname, True) self.assertEqual(request.slug, 'pip')
def test_subproject_form_cant_create_sub_sub_project(self): user = fixture.get(User) project = fixture.get(Project, users=[user]) subproject = fixture.get(Project, users=[user]) subsubproject = fixture.get(Project, users=[user]) relation = fixture.get( ProjectRelationship, parent=project, child=subproject ) self.assertQuerysetEqual( Project.objects.for_admin_user(user), [project, subproject, subsubproject], transform=lambda n: n, ) form = ProjectRelationshipForm( {'child': subsubproject.pk}, project=subproject, user=user ) # The subsubproject is valid here, as far as the child check is # concerned, but the parent check should fail. self.assertEqual( [proj_id for (proj_id, __) in form.fields['child'].choices], ['', subsubproject.pk], ) form.full_clean() self.assertEqual(len(form.errors['parent']), 1) self.assertRegexpMatches( form.errors['parent'][0], r'Subproject nesting is not supported' )
def test_email_backend(self, send_email, render_to_string): render_to_string.return_value = 'Test' class TestNotification(Notification): name = 'foo' subject = 'This is {{ foo.id }}' context_object_name = 'foo' level = ERROR build = fixture.get(Build) req = mock.MagicMock() user = fixture.get(User) notify = TestNotification(context_object=build, request=req, user=user) backend = EmailBackend(request=req) backend.send(notify) self.assertEqual(render_to_string.call_count, 1) send_email.assert_has_calls([ mock.call( request=mock.ANY, template='core/email/common.txt', context={'content': 'Test'}, subject=u'This is {}'.format(build.id), template_html='core/email/common.html', recipient=user.email, ) ])
def setUp(self): self.subproject_en = fixture.get( Project, language='en', privacy_level='public', main_language_project=None, ) self.subproject_es = fixture.get( Project, language='es', privacy_level='public', main_language_project=self.subproject_en, ) self.superproject_en = fixture.get( Project, language='en', privacy_level='public', main_language_project=None, ) self.superproject_es = fixture.get( Project, language='es', privacy_level='public', main_language_project=self.superproject_en, ) self.relation = fixture.get( ProjectRelationship, parent=self.superproject_en, child=self.subproject_en, alias=None, ) self.assertIn(self.relation, self.superproject_en.subprojects.all()) self.assertEqual(self.superproject_en.subprojects.count(), 1)
def test_trigger_build_when_version_not_provided_default_version_exist(self, update_docs_task): self.assertFalse(Version.objects.filter(slug='test-default-version').exists()) project_1 = get(Project) version_1 = get(Version, project=project_1, slug='test-default-version', active=True) project_1.default_version = 'test-default-version' project_1.save() default_version = project_1.get_default_version() self.assertEqual(default_version, 'test-default-version') trigger_build(project=project_1) kwargs = { 'version_pk': version_1.pk, 'record': True, 'force': False, 'build_pk': mock.ANY, } update_docs_task.signature.assert_has_calls([ mock.call( args=(project_1.pk,), kwargs=kwargs, options=mock.ANY, immutable=True, ), ])
def test_projects_versions_detail_unique(self): second_project = fixture.get( Project, name='second project', slug='second-project', related_projects=[], main_language_project=None, users=[self.me], versions=[], ) second_version = fixture.get( Version, slug=self.version.slug, verbose_name=self.version.verbose_name, identifier='a1b2c3', project=second_project, active=True, built=True, type='tag', ) self.client.credentials(HTTP_AUTHORIZATION=f'Token {self.token.key}') response = self.client.get( reverse( 'projects-versions-detail', kwargs={ 'parent_lookup_project__slug': self.project.slug, 'version_slug': self.version.slug, }), ) self.assertEqual(response.status_code, 200)
def test_domain_object_missing(self): self.domain = get(Domain, domain='docs.foobar2.com', project=self.pip) request = self.factory.get(self.url, HTTP_HOST='docs.foobar.com') self.process_request_auth_middleware(request) r = self.middleware.process_request(request) self.assertEqual(r.status_code, 404)
def setUp(self): self.user = get(User) self.another_user = get(User) self.project = get( Project, privacy_level=PUBLIC, users=[self.user], main_language_project=None, versions=[], ) self.version_latest = self.project.versions.get(slug=LATEST) self.version = get( Version, privacy_level=PUBLIC, project=self.project, active=True, ) self.version_private = get( Version, privacy_level=PRIVATE, project=self.project, active=True, ) self.another_project = get( Project, privacy_level=PUBLIC, users=[self.another_user], main_language_project=None, versions=[], ) self.another_version_latest = self.another_project.versions.get( slug=LATEST) self.another_version = get( Version, privacy_level=PUBLIC, project=self.another_project, active=True, ) self.another_version_private = get( Version, privacy_level=PRIVATE, project=self.another_project, active=True, ) self.shared_project = get( Project, privacy_level=PUBLIC, users=[self.user, self.another_user], main_language_project=None, versions=[], ) self.shared_version_latest = self.shared_project.versions.get( slug=LATEST) self.shared_version = get( Version, privacy_level=PUBLIC, project=self.shared_project, active=True, ) self.shared_version_private = get( Version, privacy_level=PRIVATE, project=self.shared_project, active=True, ) self.user_versions = { self.version, self.version_latest, self.version_private, self.shared_version, self.shared_version_latest, self.shared_version_private, } self.another_user_versions = { self.another_version_latest, self.another_version, self.another_version_private, self.shared_version, self.shared_version_latest, self.shared_version_private, }
def setUp(self): self.proj = Project.objects.get(slug='read-the-docs') self.redirect = get(Redirect, project=self.proj)
def setUp(self): self.advertiser1 = get(Advertiser, name="Test Advertiser", slug="test-advertiser") self.advertiser2 = get(Advertiser, name="Another Advertiser", slug="another-advertiser") self.publisher1 = get( Publisher, slug="test-publisher", allow_paid_campaigns=True, record_placements=True, ) self.publisher2 = get(Publisher, slug="another-publisher", allow_paid_campaigns=True) self.campaign = get( Campaign, name="Test Campaign", slug="test-campaign", advertiser=self.advertiser1, campaign_type=PAID_CAMPAIGN, ) self.community_campaign = get( Campaign, name="Community Campaign", slug="community-campaign", advertiser=self.advertiser2, campaign_type=COMMUNITY_CAMPAIGN, ) self.house_campaign = get( Campaign, name="House Campaign", slug="house-campaign", advertiser=self.advertiser2, campaign_type=HOUSE_CAMPAIGN, ) self.flight1 = get( Flight, name="Test Flight", slug="test-flight", campaign=self.campaign, live=True, cpc=2.0, sold_clicks=2000, targeting_parameters={ "include_countries": ["US", "CA"], "exclude_countries": ["DE"], "include_keywords": ["python", "test", "awesome"], "include_metro_codes": [205], "include_state_provinces": ["CA", "NY"], }, ) self.flight2 = get( Flight, name="Test Flight 2", slug="test-flight-2", campaign=self.community_campaign, live=False, cpm=1.0, sold_impressions=1000, ) self.flight3 = get( Flight, name="Test Flight 3", slug="test-flight-3", campaign=self.house_campaign, live=False, ) self.ad_type1 = get(AdType, name="Ad Type", has_image=False) self.ad1 = get( Advertisement, name="Test Ad 1", slug="test-ad-1", flight=self.flight1, ad_type=self.ad_type1, image=None, ) # Trigger some impressions so flights will be shown in the date range self.ad1.incr(VIEWS, self.publisher1) self.ad1.incr(VIEWS, self.publisher1) self.ad1.incr(VIEWS, self.publisher1) self.ad1.incr(VIEWS, self.publisher1) self.ad1.incr(CLICKS, self.publisher1) self.password = "******" self.user = get(get_user_model(), email="*****@*****.**", username="******") self.user.set_password(self.password) self.user.save() self.staff_user = get(get_user_model(), is_staff=True, username="******")
def setUp(self): self.user = get(User) self.project = get(Project, users=(self.user, ))
def test_symlink_remove_orphan_symlinks(self): self.domain = get( Domain, project=self.project, domain='woot.com', url='http://woot.com', cname=True, ) self.symlink.symlink_cnames() # Editing the Domain and calling save will symlink the new domain and # leave the old one as orphan. self.domain.domain = 'foobar.com' self.domain.save() filesystem = { 'private_cname_project': { 'foobar.com': {'type': 'link', 'target': 'user_builds/kong'}, 'woot.com': {'type': 'link', 'target': 'user_builds/kong'}, }, 'private_cname_root': { 'foobar.com': {'type': 'link', 'target': 'private_web_root/kong'}, 'woot.com': {'type': 'link', 'target': 'private_web_root/kong'}, }, 'private_web_root': {'kong': {'en': {}}}, 'public_cname_project': { 'foobar.com': {'type': 'link', 'target': 'user_builds/kong'}, 'woot.com': {'type': 'link', 'target': 'user_builds/kong'}, }, 'public_cname_root': { 'foobar.com': {'type': 'link', 'target': 'public_web_root/kong'}, 'woot.com': {'type': 'link', 'target': 'public_web_root/kong'}, }, 'public_web_root': { 'kong': {'en': {'latest': { 'type': 'link', 'target': 'user_builds/kong/rtd-builds/latest', }}}, }, } if self.privacy == 'private': public_root = filesystem['public_web_root'].copy() private_root = filesystem['private_web_root'].copy() filesystem['public_web_root'] = private_root filesystem['private_web_root'] = public_root self.assertFilesystem(filesystem) remove_orphan_symlinks() filesystem = { 'private_cname_project': { 'foobar.com': {'type': 'link', 'target': 'user_builds/kong'}, }, 'private_cname_root': { 'foobar.com': {'type': 'link', 'target': 'private_web_root/kong'}, }, 'private_web_root': {'kong': {'en': {}}}, 'public_cname_project': { 'foobar.com': {'type': 'link', 'target': 'user_builds/kong'}, }, 'public_cname_root': { 'foobar.com': {'type': 'link', 'target': 'public_web_root/kong'}, }, 'public_web_root': { 'kong': {'en': {'latest': { 'type': 'link', 'target': 'user_builds/kong/rtd-builds/latest', }}}, }, } if self.privacy == 'private': public_root = filesystem['public_web_root'].copy() private_root = filesystem['private_web_root'].copy() filesystem['public_web_root'] = private_root filesystem['private_web_root'] = public_root self.assertFilesystem(filesystem)
def setUp(self): self.pip = fixture.get(Project, slug='pip', single_version=True, main_language_project=None)
def test_get_env_vars(self): project = get( Project, slug='project', documentation_type='sphinx', ) get( EnvironmentVariable, name='TOKEN', value='a1b2c3', project=project, ) build = get(Build) version = get(Version, slug='1.8', project=project) task = UpdateDocsTaskStep( project=project, version=version, build={'id': build.pk}, ) # mock this object to make sure that we are NOT in a conda env task.config = mock.Mock(conda=None) env = { 'NO_COLOR': '1', 'READTHEDOCS': 'True', 'READTHEDOCS_VERSION': version.slug, 'READTHEDOCS_PROJECT': project.slug, 'READTHEDOCS_LANGUAGE': project.language, 'BIN_PATH': os.path.join( project.doc_path, 'envs', version.slug, 'bin', ), 'TOKEN': 'a1b2c3', } self.assertEqual(task.get_env_vars(), env) # mock this object to make sure that we are in a conda env task.config = mock.Mock(conda=True) env.update({ 'CONDA_ENVS_PATH': os.path.join(project.doc_path, 'conda'), 'CONDA_DEFAULT_ENV': version.slug, 'BIN_PATH': os.path.join( project.doc_path, 'conda', version.slug, 'bin', ), }) self.assertEqual(task.get_env_vars(), env)
def setUp(self): super().setUp() self.build = get(Build, project=self.pip) self.build_command_result = get(BuildCommandResult, project=self.pip) self.domain = get(Domain, url='http://docs.foobar.com', project=self.pip) self.social_account = get(SocialAccount) self.remote_org = get(RemoteOrganization) self.remote_repo = get(RemoteRepository, organization=self.remote_org) self.integration = get(Integration, project=self.pip, provider_data='') self.default_kwargs = { 'project_slug': self.pip.slug, 'version_slug': self.pip.versions.all()[0].slug, 'format': 'json', 'pk': self.pip.pk, 'task_id': 'Nope', } self.request_data = { 'build-detail': { 'pk': self.build.pk }, 'buildcommandresult-detail': { 'pk': self.build_command_result.pk }, 'version-detail': { 'pk': self.pip.versions.all()[0].pk }, 'domain-detail': { 'pk': self.domain.pk }, 'footer_html': { 'data': { 'project': 'pip', 'version': 'latest', 'page': 'index' } }, 'remoteorganization-detail': { 'pk': self.remote_org.pk }, 'remoterepository-detail': { 'pk': self.remote_repo.pk }, 'remoteaccount-detail': { 'pk': self.social_account.pk }, 'api_webhook': { 'integration_pk': self.integration.pk }, } self.response_data = { 'project-sync-versions': { 'status_code': 403 }, 'project-token': { 'status_code': 403 }, 'emailhook-list': { 'status_code': 403 }, 'emailhook-detail': { 'status_code': 403 }, 'embed': { 'status_code': 400 }, 'docurl': { 'status_code': 400 }, 'cname': { 'status_code': 400 }, 'index_search': { 'status_code': 403 }, 'api_search': { 'status_code': 400 }, 'api_project_search': { 'status_code': 400 }, 'api_section_search': { 'status_code': 400 }, 'api_sync_remote_repositories': { 'status_code': 403 }, 'api_webhook': { 'status_code': 405 }, 'api_webhook_github': { 'status_code': 405 }, 'api_webhook_gitlab': { 'status_code': 405 }, 'api_webhook_bitbucket': { 'status_code': 405 }, 'api_webhook_generic': { 'status_code': 403 }, 'sphinxdomain-detail': { 'status_code': 404 }, 'remoteorganization-detail': { 'status_code': 404 }, 'remoterepository-detail': { 'status_code': 404 }, 'remoteaccount-detail': { 'status_code': 404 }, }
def test_sitemap_xml(self): self.project.versions.update(active=True) private_version = fixture.get( Version, privacy_level=constants.PRIVATE, project=self.project, ) not_translated_public_version = fixture.get( Version, identifier='not-translated-version', verbose_name='not-translated-version', slug='not-translated-version', privacy_level=constants.PUBLIC, project=self.project, active=True) stable_version = fixture.get(Version, identifier='stable', verbose_name='stable', slug='stable', privacy_level=constants.PUBLIC, project=self.project, active=True) # This is a EXTERNAL Version external_version = fixture.get(Version, identifier='pr-version', verbose_name='pr-version', slug='pr-9999', project=self.project, active=True, type=EXTERNAL) # This also creates a Version `latest` Automatically for this project translation = fixture.get( Project, main_language_project=self.project, language='translation-es', privacy_level=constants.PUBLIC, ) translation.versions.update(privacy_level=constants.PUBLIC) # sitemap hreflang should follow correct format. # ref: https://en.wikipedia.org/wiki/Hreflang#Common_Mistakes hreflang_test_translation_project = fixture.get( Project, main_language_project=self.project, language='zh_CN', privacy_level=constants.PUBLIC, ) hreflang_test_translation_project.versions.update( privacy_level=constants.PUBLIC, ) response = self.client.get( reverse('sitemap_xml'), HTTP_HOST='project.readthedocs.io', ) self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'application/xml') for version in self.project.versions(manager=INTERNAL).filter( privacy_level=constants.PUBLIC): self.assertContains( response, self.project.get_docs_url( version_slug=version.slug, lang_slug=self.project.language, ), ) # PRIVATE version should not appear here self.assertNotContains( response, self.project.get_docs_url( version_slug=private_version.slug, lang_slug=self.project.language, ), ) # The `translation` project doesn't have a version named `not-translated-version` # so, the sitemap should not have a doc url for # `not-translated-version` with `translation-es` language. # ie: http://project.readthedocs.io/translation-es/not-translated-version/ self.assertNotContains( response, self.project.get_docs_url( version_slug=not_translated_public_version.slug, lang_slug=translation.language, ), ) # hreflang should use hyphen instead of underscore # in language and country value. (zh_CN should be zh-CN) self.assertContains(response, 'zh-CN') # External Versions should not be in the sitemap_xml. self.assertNotContains( response, self.project.get_docs_url( version_slug=external_version.slug, lang_slug=self.project.language, ), ) # Check if STABLE version has 'priority of 1 and changefreq of weekly. self.assertEqual( response.context['versions'][0]['loc'], self.project.get_docs_url( version_slug=stable_version.slug, lang_slug=self.project.language, ), ) self.assertEqual(response.context['versions'][0]['priority'], 1) self.assertEqual(response.context['versions'][0]['changefreq'], 'weekly') # Check if LATEST version has priority of 0.9 and changefreq of daily. self.assertEqual( response.context['versions'][1]['loc'], self.project.get_docs_url( version_slug='latest', lang_slug=self.project.language, ), ) self.assertEqual(response.context['versions'][1]['priority'], 0.9) self.assertEqual(response.context['versions'][1]['changefreq'], 'daily')
def setUp(self): self.created = make_aware(datetime.datetime(2019, 4, 29, 10, 0, 0)) self.modified = make_aware(datetime.datetime(2019, 4, 29, 12, 0, 0)) self.me = fixture.get( User, date_joined=self.created, username='******', projects=[], ) self.token = fixture.get(Token, key='me', user=self.me) # Defining all the defaults helps to avoid creating ghost / unwanted # objects (like a Project for translations/subprojects) self.project = fixture.get( Project, pub_date=self.created, modified_date=self.modified, description='Project description', repo='https://github.com/rtfd/project', project_url='http://project.com', name='project', slug='project', related_projects=[], main_language_project=None, users=[self.me], versions=[], ) for tag in ('tag', 'project', 'test'): self.project.tags.add(tag) self.redirect = fixture.get( Redirect, create_dt=self.created, update_dt=self.modified, from_url='/docs/', to_url='/documentation/', redirect_type='page', project=self.project, ) self.version = fixture.get( Version, slug='v1.0', verbose_name='v1.0', identifier='a1b2c3', project=self.project, hidden=False, active=True, built=True, type=TAG, ) self.build = fixture.get( Build, date=self.created, type='html', state='finished', error='', success=True, _config={'property': 'test value'}, version=self.version, project=self.project, builder='builder01', commit='a1b2c3', length=60, ) self.other = fixture.get(User, projects=[]) self.others_token = fixture.get(Token, key='other', user=self.other) self.others_project = fixture.get( Project, slug='others-project', related_projects=[], main_language_project=None, users=[self.other], versions=[], ) # Make all non-html true so responses are complete self.project.versions.update( has_pdf=True, has_epub=True, has_htmlzip=True, ) self.client = APIClient()
def setUp(self): self.project = get(Project) self.version = get(Version, verbose_name='master', project=self.project)
def setUp(self): self.project = fixture.get(Project) self.version = fixture.get(Version, project=self.project) self.build = fixture.get(Build, version=self.version)
def setUp(self): self.user = get(User) self.another_user = get(User) self.project = get( Project, privacy_level=PUBLIC, users=[self.user], main_language_project=None, versions=[], ) self.version_public = get( Version, privacy_level=PUBLIC, project=self.project, active=True, slug='version_public' ) self.build_public = get( Build, version=self.version_public, project=self.project, ) self.version_public_external = get( Version, privacy_level=PUBLIC, project=self.project, active=True, type=EXTERNAL, slug='version_public_external' ) self.build_public_external = get( Build, version=self.version_public_external, project=self.project, ) self.version_private = get( Version, privacy_level=PRIVATE, project=self.project, active=True, slug='version_private' ) self.build_private = get( Build, version=self.version_private, project=self.project, ) self.version_private_external = get( Version, privacy_level=PRIVATE, project=self.project, active=True, type=EXTERNAL, slug='version_private_external' ) self.build_private_external = get( Build, version=self.version_private_external, project=self.project, ) self.another_project = get( Project, privacy_level=PUBLIC, users=[self.another_user], main_language_project=None, versions=[], ) self.another_version_public = get( Version, privacy_level=PUBLIC, project=self.another_project, active=True, slug='another_version_public' ) self.another_build_public = get( Build, version=self.another_version_public, project=self.another_project, ) self.another_version_public_external = get( Version, privacy_level=PUBLIC, project=self.another_project, active=True, type=EXTERNAL, slug='another_version_public_external' ) self.another_build_public_external = get( Build, version=self.another_version_public_external, project=self.another_project, ) self.another_version_private = get( Version, privacy_level=PRIVATE, project=self.another_project, active=True, slug='another_version_private' ) self.another_build_private = get( Build, version=self.another_version_private, project=self.another_project, ) self.another_version_private_external = get( Version, privacy_level=PRIVATE, project=self.another_project, active=True, type=EXTERNAL, slug='another_version_private_external' ) self.another_build_private_external = get( Build, version=self.another_version_private_external, project=self.another_project, ) self.shared_project = get( Project, privacy_level=PUBLIC, users=[self.user, self.another_user], main_language_project=None, versions=[], ) self.shared_version_public = get( Version, privacy_level=PUBLIC, project=self.shared_project, active=True, slug='shared_version_public' ) self.shared_build_public = get( Build, version=self.shared_version_public, project=self.shared_project, ) self.shared_version_public_external = get( Version, privacy_level=PUBLIC, project=self.shared_project, active=True, type=EXTERNAL, slug='shared_version_public_external' ) self.shared_build_public_external = get( Build, version=self.shared_version_public_external, project=self.shared_project, ) self.shared_version_private = get( Version, privacy_level=PRIVATE, project=self.shared_project, active=True, slug='shared_version_private' ) self.shared_build_private = get( Build, version=self.shared_version_private, project=self.shared_project, ) self.shared_version_private_external = get( Version, privacy_level=PRIVATE, project=self.shared_project, active=True, type=EXTERNAL, slug='shared_version_private_external' ) self.shared_build_private_external = get( Build, version=self.shared_version_private_external, project=self.shared_project, )
def test_user_cant_delete_other_user_translations(self): user_a = User.objects.get(username='******') project_a = get( Project, users=[user_a], language='es', main_language_project=None, ) project_b = get( Project, users=[user_a], language='en', main_language_project=None, ) project_a.translations.add(project_b) project_a.save() user_b = User.objects.get(username='******') project_c = get( Project, users=[user_b], language='es', main_language_project=None, ) project_d = get( Project, users=[user_b, user_a], language='en', main_language_project=None, ) project_d.translations.add(project_c) project_d.save() # User B tries to delete translation from user A self.client.login(username=user_b.username, password='******') self.assertIn(project_b, project_a.translations.all()) resp = self.client.post( reverse( 'projects_translations_delete', args=[project_a.slug, project_b.slug], ), follow=True, ) self.assertEqual(resp.status_code, 404) self.assertIn(project_b, project_a.translations.all()) # User B tries to delete translation from user A # with a different parent self.client.login(username=user_b.username, password='******') self.assertIn(project_b, project_a.translations.all()) resp = self.client.post( reverse( 'projects_translations_delete', args=[project_d.slug, project_b.slug], ), follow=True, ) self.assertEqual(resp.status_code, 404) self.assertIn(project_b, project_a.translations.all()) # User A tries to delete translation from user A # with a different parent self.client.login(username=user_a.username, password='******') self.assertIn(project_b, project_a.translations.all()) resp = self.client.post( reverse( 'projects_translations_delete', args=[project_b.slug, project_b.slug], ), follow=True, ) self.assertEqual(resp.status_code, 404) self.assertIn(project_b, project_a.translations.all())
def test_send_email_notification(self): fixture.get(EmailHook, project=self.project) send_notifications(self.version.pk, self.build.pk, email=True) self.assertEqual(len(mail.outbox), 1)
def setUp(self): self.user = get(User) self.project = get(Project, users=[self.user]) self.client.force_login(self.user)
def setUp(self): self.project = get(Project)
def test_subclass_is_replaced_on_subclass(self): project = fixture.get(Project, main_language_project=None) integration = Integration.objects.create( project=project, integration_type=Integration.GITHUB_WEBHOOK) integration = Integration.objects.subclass(integration) self.assertIsInstance(integration, GitHubWebhook)
def test_get_theme_name_with_feature_flag(self, checkout_path, run): tmpdir = tempfile.mkdtemp() checkout_path.return_value = tmpdir feature = get( Feature, feature_id=Feature.MKDOCS_THEME_RTD, ) feature.projects.add(self.project) python_env = Virtualenv( version=self.version, build_env=self.build_env, config=None, ) builder = MkdocsHTML( build_env=self.build_env, python_env=python_env, ) self.assertEqual(builder.get_theme_name({}), 'readthedocs') with patch( 'readthedocs.doc_builder.backends.mkdocs.yaml') as mock_yaml: with patch( 'readthedocs.doc_builder.backends.mkdocs.MkdocsHTML.load_yaml_config' ) as mock_load_yaml_config: mock_load_yaml_config.return_value = { 'site_name': self.project.name, 'docs_dir': tmpdir, } builder.append_conf() mock_yaml.safe_dump.assert_called_once_with( { 'site_name': mock.ANY, 'docs_dir': mock.ANY, 'extra_javascript': mock.ANY, 'extra_css': mock.ANY, 'google_analytics': mock.ANY, 'theme': 'readthedocs', }, mock.ANY, ) mock_yaml.reset_mock() config = { 'theme': 'customtheme', } self.assertEqual(builder.get_theme_name(config), 'customtheme') with patch( 'readthedocs.doc_builder.backends.mkdocs.MkdocsHTML.load_yaml_config' ) as mock_load_yaml_config: mock_load_yaml_config.return_value = { 'site_name': self.project.name, 'theme': 'customtheme', 'docs_dir': tmpdir, } builder.append_conf() mock_yaml.safe_dump.assert_called_once_with( { 'site_name': mock.ANY, 'docs_dir': mock.ANY, 'extra_javascript': mock.ANY, 'extra_css': mock.ANY, 'google_analytics': mock.ANY, 'theme': 'customtheme', }, mock.ANY, )
def test_publisher_uplift_report_contents(self): self.client.force_login(self.staff_user) url = reverse("publisher_uplift_report") self.ad2 = get( Advertisement, name="Test Ad 2", slug="test-ad-2", flight=self.flight2, ad_type=self.ad_type1, image=None, ) # Paid get( Offer, advertisement=self.ad1, publisher=self.publisher1, viewed=True, uplifted=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, viewed=True, uplifted=True, ) # Not paid get( Offer, advertisement=self.ad2, publisher=self.publisher1, viewed=True, uplifted=True, ) get( Offer, advertisement=self.ad2, publisher=self.publisher1, viewed=True, uplifted=True, ) get( Offer, advertisement=self.ad2, publisher=self.publisher1, viewed=True, uplifted=True, ) # Update reporting daily_update_uplift() # All reports response = self.client.get(url) self.assertContains(response, '<td class="text-right"><strong>5</strong></td>') # Filter reports response = self.client.get(url, {"campaign_type": "paid"}) self.assertContains(response, '<td class="text-right"><strong>2</strong></td>') self.assertNotContains( response, '<td class="text-right"><strong>3</strong></td>')
def setUp(self): self.project = get(Project) self.version = get(Version, project=self.project)
def test_advertiser_publisher_report_contents(self): get( Offer, advertisement=self.ad1, publisher=self.publisher1, viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher2, viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher2, viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, viewed=True, is_refunded=True, # Won't count ) # Update reporting daily_update_impressions() url = reverse("advertiser_publisher_report", args=[self.advertiser1.slug]) # Anonymous response = self.client.get(url) self.assertEqual(response.status_code, 302) self.assertTrue(response["location"].startswith("/accounts/login/")) self.client.force_login(self.staff_user) # All reports response = self.client.get(url) self.assertContains(response, '<td class="text-right"><strong>3</strong></td>') self.assertContains(response, self.publisher1.name) self.assertContains(response, self.publisher2.name) self.assertNotContains(response, "Belgium") # Filter reports response = self.client.get(url, {"publisher": self.publisher1.slug}) self.assertContains(response, '<td class="text-right"><strong>1</strong></td>') response = self.client.get(url, {"publisher": self.publisher2.slug}) self.assertContains(response, '<td class="text-right"><strong>2</strong></td>') # Verify the export URL is configured self.assertContains(response, "CSV Export") export_url = reverse("advertiser_publisher_report_export", args=[self.advertiser1.slug]) response = self.client.get(export_url) self.assertContains(response, "Total,3")
def test_publisher_keyword_report_contents(self): get( Offer, advertisement=self.ad1, publisher=self.publisher1, keywords=["test"], viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, keywords=["test"], viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, keywords=["test"], viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, keywords=["test"], viewed=True, is_refunded=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, keywords=["awesome"], viewed=True, clicked=True, ) # Update reporting daily_update_keywords() self.client.force_login(self.staff_user) url = reverse("publisher_keyword_report", args=[self.publisher1.slug]) # All reports response = self.client.get(url) self.assertContains(response, '<td class="text-right"><strong>4</strong></td>') self.assertContains(response, "test") # Filter reports response = self.client.get(url, {"keyword": "test"}) self.assertContains(response, '<td class="text-right"><strong>3</strong></td>') self.assertNotContains( response, '<td class="text-right"><strong>2</strong></td>') response = self.client.get(url, {"keyword": "awesome"}) self.assertContains(response, '<td class="text-right"><strong>1</strong></td>') # Invalid country response = self.client.get(url, {"keyword": "foobar"}) self.assertContains(response, '<td class="text-right"><strong>0</strong></td>') # Verify the export URL is configured self.assertContains(response, "CSV Export") export_url = reverse("publisher_keyword_report_export", args=[self.publisher1.slug]) response = self.client.get(export_url, {"keyword": "awesome"}) self.assertContains(response, "Total,1,1")
def setUp(self): self.categories = get(Category, n=4) self.event = get(Event, categories=self.categories) self.user = get(User)
def test_advertiser_geo_report_contents(self): get( Offer, advertisement=self.ad1, publisher=self.publisher1, country="US", viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, country="US", viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, country="US", viewed=True, ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, country="US", viewed=True, is_refunded=True, # Won't count ) get( Offer, advertisement=self.ad1, publisher=self.publisher1, country="FR", viewed=True, clicked=True, ) # Update reporting daily_update_geos() url = reverse("advertiser_geo_report", args=[self.advertiser1.slug]) # Anonymous response = self.client.get(url) self.assertEqual(response.status_code, 302) self.assertTrue(response["location"].startswith("/accounts/login/")) self.client.force_login(self.staff_user) # All reports response = self.client.get(url) self.assertContains(response, '<td class="text-right"><strong>4</strong></td>') self.assertContains(response, "France") self.assertNotContains(response, "Belgium") # Filter reports response = self.client.get(url, {"country": "US"}) self.assertContains(response, '<td class="text-right"><strong>3</strong></td>') self.assertNotContains( response, '<td class="text-right"><strong>2</strong></td>') response = self.client.get(url, {"country": "FR"}) self.assertContains(response, '<td class="text-right"><strong>1</strong></td>') # Invalid country response = self.client.get(url, {"country": "foobar"}) self.assertContains(response, '<td class="text-right"><strong>0</strong></td>') # Verify the export URL is configured self.assertContains(response, "CSV Export") export_url = reverse("advertiser_geo_report_export", args=[self.advertiser1.slug]) response = self.client.get(export_url, {"country": "FR"}) self.assertContains(response, "Total,1")
def setUp(self): self.aggr = get(EventActionAggregate)
def test_feature_for_project_is_explicit_applied(self): project = fixture.get(Project, main_language_project=None) feature = fixture.get(Feature, projects=[project]) self.assertTrue(project.has_feature(feature.feature_id))
def setUp(self): self.user = get(User, username='******', email='*****@*****.**') self.user_two = get(User, username='******', email='*****@*****.**') self.user_three = get(User, username='******', email='*****@*****.**')
def setUp(self): self.promo = get(SupporterPromo, live=True)