def test_product_specific_ready(self): """Verify product-specific ready for l10n notifications.""" # Add a Firefox OS watcher. ReadyRevisionEvent.notify(UserFactory(), product='firefox-os') # Create a document for Firefox doc = DocumentFactory() doc.products.add(ProductFactory(slug='firefox')) # Mark a revision a ready for L10n. There should be only one email # to the watcher created in setUp. self._mark_as_ready_revision(doc=doc) eq_(1, len(mail.outbox)) _assert_ready_mail(mail.outbox[0]) # Add firefox-os to the document's products. Mark as ready for l10n, # and there should be two new emails. doc.products.add(ProductFactory(slug='firefox-os')) self._mark_as_ready_revision(doc=doc) eq_(3, len(mail.outbox)) _assert_ready_mail(mail.outbox[1]) _assert_ready_mail(mail.outbox[2]) # Add a Firefox watcher, mark as ready for l10n, and there should # be three new emails. ReadyRevisionEvent.notify(UserFactory(), product='firefox') self._mark_as_ready_revision(doc=doc) eq_(6, len(mail.outbox))
def test_product_delete(self): profile = self.user.profile product = ProductFactory() profile.products.add(product) product.delete() self.assertEqual(self.get_doc().product_ids, [])
def test_changing_products(self): """Changing products works as expected.""" r = ApprovedRevisionFactory() d = r.document prod_desktop = ProductFactory(title=u'desktop') prod_mobile = ProductFactory(title=u'mobile') data = new_document_data() data.update({ 'products': [prod_desktop.id, prod_mobile.id], 'title': d.title, 'slug': d.slug, 'form': 'doc' }) self.client.post(reverse('wiki.edit_document', args=[d.slug]), data) eq_( sorted( Document.objects.get(id=d.id).products.values_list('id', flat=True)), sorted([prod.id for prod in [prod_desktop, prod_mobile]])) data.update({'products': [prod_desktop.id], 'form': 'doc'}) self.client.post(reverse('wiki.edit_document', args=[data['slug']]), data) eq_( sorted( Document.objects.get(id=d.id).products.values_list('id', flat=True)), sorted([prod.id for prod in [prod_desktop]]))
def test_product_filter(self): """Test filtering results by product.""" today = date.today() # Create products and associated wiki metrics. p1 = ProductFactory() p2 = ProductFactory() # Create 3 for each product: for i in range(3): for p in [p1, p2]: WikiMetricFactory(date=today - timedelta(days=i), product=p) # Create one more for p2. WikiMetricFactory(date=today - timedelta(days=4), product=p2) # Call and verify the API for product=p1. response = self.client.get( urlparams(reverse('api.wikimetric_list'), format='json', product=p1.slug)) eq_(200, response.status_code) results = json.loads(response.content)['results'] eq_(3, len(results)) # Call and verify the API for product=p1. response = self.client.get( urlparams(reverse('api.wikimetric_list'), format='json', product=p2.slug)) eq_(200, response.status_code) results = json.loads(response.content)['results'] eq_(4, len(results))
def test_filter_by_product(self): desktop = ProductFactory(slug=u'desktop') mobile = ProductFactory(slug=u'mobile') ques = QuestionFactory(title=u'audio', product=desktop) ans = AnswerFactory(question=ques, content=u'volume') AnswerVoteFactory(answer=ans, helpful=True) doc = DocumentFactory(title=u'audio', locale=u'en-US', category=10) doc.products.add(desktop) doc.products.add(mobile) RevisionFactory(document=doc, is_approved=True) self.refresh() # There should be 2 results for desktop and 1 for mobile. response = self.client.get(reverse('search'), { 'q': 'audio', 'format': 'json', 'product': 'desktop' }) eq_(200, response.status_code) content = json.loads(response.content) eq_(content['total'], 2) response = self.client.get(reverse('search'), { 'q': 'audio', 'format': 'json', 'product': 'mobile' }) eq_(200, response.status_code) content = json.loads(response.content) eq_(content['total'], 1)
def test_search_multiple_products(self): p1 = ProductFactory(title='Product One', slug='product-one', display_order=1) p2 = ProductFactory(title='Product Two', slug='product-two', display_order=2) doc1 = DocumentFactory(title='cookies', locale='en-US', category=10, products=[p1, p2]) RevisionFactory(document=doc1, is_approved=True) self.refresh() response = self.client.get( reverse('search.advanced'), { 'a': '1', 'product': ['product-one', 'product-two'], 'q': 'cookies', 'w': '1', }) eq_(200, response.status_code) assert b"We couldn't find any results for" not in response.content assert b'Product One, Product Two' in response.content
def test_search_multiple_products(self): p1 = ProductFactory(title="Product One", slug="product-one", display_order=1) p2 = ProductFactory(title="Product Two", slug="product-two", display_order=2) doc1 = DocumentFactory(title="cookies", locale="en-US", category=10, products=[p1, p2]) RevisionFactory(document=doc1, is_approved=True) self.refresh() response = self.client.get( reverse("search.advanced"), { "a": "1", "product": ["product-one", "product-two"], "q": "cookies", "w": "1", }, ) eq_(200, response.status_code) assert b"We couldn't find any results for" not in response.content assert b"Product One, Product Two" in response.content
def setUp(self): super(TestFacetHelpers, self).setUp() # Create products self.desktop = ProductFactory(slug="firefox") self.mobile = ProductFactory(slug="mobile") # Create topics self.general_d = TopicFactory(product=self.desktop, slug="general") self.bookmarks_d = TopicFactory(product=self.desktop, slug="bookmarks") self.sync_d = TopicFactory(product=self.desktop, slug="sync") self.general_m = TopicFactory(product=self.mobile, slug="general") self.bookmarks_m = TopicFactory(product=self.mobile, slug="bookmarks") self.sync_m = TopicFactory(product=self.mobile, slug="sync") # Set up documents. doc1 = DocumentFactory(products=[self.desktop], topics=[self.general_d, self.bookmarks_d]) doc1_revision = ApprovedRevisionFactory(document=doc1, is_ready_for_localization=True) doc1_localized = DocumentFactory(locale="de", products=[], topics=[], parent=doc1) ApprovedRevisionFactory(document=doc1_localized, based_on=doc1_revision) doc2 = DocumentFactory( products=[self.desktop, self.mobile], topics=[ self.bookmarks_d, self.bookmarks_m, self.sync_d, self.sync_m ], ) ApprovedRevisionFactory(document=doc2) # An archived article shouldn't show up doc3 = DocumentFactory(is_archived=True, products=[self.desktop], topics=[self.general_d, self.bookmarks_d]) ApprovedRevisionFactory(document=doc3) # A template article shouldn't show up either doc4 = TemplateDocumentFactory( products=[self.desktop], topics=[self.general_d, self.bookmarks_d]) ApprovedRevisionFactory(document=doc4) # An article without current revision should be "invisible" # to everything. doc5 = DocumentFactory( products=[self.desktop, self.mobile], topics=[ self.general_d, self.bookmarks_d, self.sync_d, self.general_m, self.bookmarks_m, self.sync_m, ], ) RevisionFactory(is_approved=False, document=doc5)
def test_product_delete(self): RevisionFactory(document=self.document, is_approved=True) product = ProductFactory() self.document.products.add(product) product.delete() self.assertEqual(self.get_doc().product_ids, [])
def test_filter_by_product(self): desktop = ProductFactory(slug="desktop") mobile = ProductFactory(slug="mobile") ques = QuestionFactory(title="audio", product=desktop) ans = AnswerFactory(question=ques, content="volume") AnswerVoteFactory(answer=ans, helpful=True) doc = DocumentFactory(title="audio", locale="en-US", category=10) doc.products.add(desktop) doc.products.add(mobile) RevisionFactory(document=doc, is_approved=True) self.refresh() # There should be 2 results for desktop and 1 for mobile. response = self.client.get( reverse("search"), {"q": "audio", "format": "json", "product": "desktop"} ) eq_(200, response.status_code) content = json.loads(response.content) eq_(content["total"], 2) response = self.client.get( reverse("search"), {"q": "audio", "format": "json", "product": "mobile"} ) eq_(200, response.status_code) content = json.loads(response.content) eq_(content["total"], 1)
def test_changing_products(self): """Changing products works as expected.""" r = ApprovedRevisionFactory() d = r.document prod_desktop = ProductFactory(title="desktop") prod_mobile = ProductFactory(title="mobile") data = new_document_data() data.update({ "products": [prod_desktop.id, prod_mobile.id], "title": d.title, "slug": d.slug, "form": "doc", }) self.client.post(reverse("wiki.edit_document", args=[d.slug]), data) eq_( sorted( Document.objects.get(id=d.id).products.values_list("id", flat=True)), sorted([prod.id for prod in [prod_desktop, prod_mobile]]), ) data.update({"products": [prod_desktop.id], "form": "doc"}) self.client.post(reverse("wiki.edit_document", args=[data["slug"]]), data) eq_( sorted( Document.objects.get(id=d.id).products.values_list("id", flat=True)), sorted([prod.id for prod in [prod_desktop]]), )
def test_filter_product_with_slug(self): p1 = ProductFactory() p2 = ProductFactory() q1 = QuestionFactory(product=p1) QuestionFactory(product=p2) querystring = '?product={0}'.format(p1.slug) res = self.client.get(reverse('question-list') + querystring) eq_(len(res.data['results']), 1) eq_(res.data['results'][0]['id'], q1.id)
def test_filter_product_with_slug(self): p1 = ProductFactory() p2 = ProductFactory() q1 = QuestionFactory(product=p1) QuestionFactory(product=p2) querystring = "?product={0}".format(p1.slug) res = self.client.get(reverse("question-list") + querystring) eq_(len(res.data["results"]), 1) eq_(res.data["results"][0]["id"], q1.id)
def test_home(self): """Verify that home page renders products.""" # Create some topics and products ProductFactory.create_batch(4) # GET the home page and verify the content r = self.client.get(reverse("home"), follow=True) eq_(200, r.status_code) doc = pq(r.content) eq_(4, len(doc("#products-and-services li")))
def test_home(self): """Verify that home page renders products.""" # Create some topics and products ProductFactory.create_batch(4) # GET the home page and verify the content r = self.client.get(reverse('home'), follow=True) eq_(200, r.status_code) doc = pq(r.content) eq_(4, len(doc('#products-and-services li')))
def test_product_filter_works(self): p1 = ProductFactory() p2 = ProductFactory() q1 = self._make_question(product=p1) self._make_question(product=p2) self.refresh() req = self.client.get(reverse('search.suggest'), { 'q': 'emails', 'product': p1.slug }) eq_([q['id'] for q in req.data['questions']], [q1.id])
def test_product_filter_works(self): p1 = ProductFactory() p2 = ProductFactory() q1 = self._make_question(product=p1) self._make_question(product=p2) self.refresh() req = self.client.get(reverse("search.suggest"), { "q": "emails", "product": p1.slug }) eq_([q["id"] for q in req.data["questions"]], [q1.id])
def test_kb_vote(self): """Test vote API call.""" r1 = RevisionFactory(document__locale='en-US') r2 = RevisionFactory(document__locale='es') r3 = RevisionFactory(document__locale='es') for r in [r1, r2, r3]: HelpfulVoteFactory(revision=r) HelpfulVoteFactory(revision=r) HelpfulVoteFactory(revision=r, helpful=True) # Assign 2 documents to Firefox OS and 1 to Firefox firefox_os = ProductFactory(slug='firefox-os') firefox = ProductFactory(slug='firefox') r1.document.products.add(firefox_os) r2.document.products.add(firefox_os) r3.document.products.add(firefox) # All votes should be counted if we don't specify a locale r = self._get_api_result('api.kpi.kb-votes') eq_(r['objects'][0]['kb_helpful'], 3) eq_(r['objects'][0]['kb_votes'], 9) # Only en-US votes: r = self._get_api_result('api.kpi.kb-votes', locale='en-US') eq_(r['objects'][0]['kb_helpful'], 1) eq_(r['objects'][0]['kb_votes'], 3) # Only es votes: r = self._get_api_result('api.kpi.kb-votes', locale='es') eq_(r['objects'][0]['kb_helpful'], 2) eq_(r['objects'][0]['kb_votes'], 6) # Only Firefox OS votes: r = self._get_api_result('api.kpi.kb-votes', product='firefox-os') eq_(r['objects'][0]['kb_helpful'], 2) eq_(r['objects'][0]['kb_votes'], 6) # Only Firefox votes: r = self._get_api_result('api.kpi.kb-votes', product='firefox') eq_(r['objects'][0]['kb_helpful'], 1) eq_(r['objects'][0]['kb_votes'], 3) # Only Firefox OS + es votes: r = self._get_api_result('api.kpi.kb-votes', product='firefox-os', locale='es') eq_(r['objects'][0]['kb_helpful'], 1) eq_(r['objects'][0]['kb_votes'], 3)
def test_search_suggestion_questions_locale(self): """Verifies the right languages show up in search suggestions.""" QuestionLocaleFactory(locale='de') p = ProductFactory(slug=u'firefox') for l in QuestionLocale.objects.all(): p.questions_locales.add(l) TopicFactory(title='Fix problems', slug='fix-problems', product=p) QuestionFactory(title='question cupcakes?', product=p, locale='en-US') QuestionFactory(title='question donuts?', product=p, locale='en-US') QuestionFactory(title='question pies?', product=p, locale='pt-BR') QuestionFactory(title='question pastries?', product=p, locale='de') self.refresh() def sub_test(locale, *titles): url = urlparams(reverse('questions.aaq_step4', args=['desktop', 'fix-problems'], locale=locale), search='question') response = self.client.get(url, follow=True) doc = pq(response.content) eq_msg(len(doc('.result.question')), len(titles), 'Wrong number of results for {0}'.format(locale)) for substr in titles: assert substr in doc('.result.question h3 a').text() sub_test('en-US', 'cupcakes?', 'donuts?') sub_test('pt-BR', 'cupcakes?', 'donuts?', 'pies?') sub_test('de', 'cupcakes?', 'donuts?', 'pastries?')
def setUp(self): super(ActiveContributorsTestCase, self).setUp() start_date = date.today() - timedelta(days=10) self.start_date = start_date before_start = start_date - timedelta(days=1) # Create some revisions to test with. # 3 'en-US' contributors: d = DocumentFactory(locale="en-US") u = UserFactory() self.user = u RevisionFactory(document=d, is_approved=True, reviewer=u) RevisionFactory(document=d, creator=u) self.product = ProductFactory() RevisionFactory(created=start_date, document__products=[self.product]) # Add one that shouldn't count: self.en_us_old = RevisionFactory(document=d, created=before_start) # 4 'es' contributors: d = DocumentFactory(locale="es") RevisionFactory(document=d, is_approved=True, reviewer=u) RevisionFactory(document=d, creator=u, reviewer=UserFactory()) RevisionFactory(document=d, created=start_date) RevisionFactory(document=d) # Add one that shouldn't count: self.es_old = RevisionFactory(document=d, created=before_start)
def test_expected_output(self): p = ProductFactory() t1 = TopicFactory(product=p, visible=True, display_order=1) t2 = TopicFactory(product=p, visible=True, display_order=2) url = reverse('topic-list', kwargs={'product': p.slug}) res = self.client.get(url) eq_(res.status_code, 200) eq_( res.data, { 'count': 2, 'next': None, 'previous': None, 'results': [ { 'title': t1.title, 'slug': t1.slug, }, { 'title': t2.title, 'slug': t2.slug, }, ], })
def test_filter_by_doctype(self): desktop = ProductFactory(slug=u'desktop') ques = QuestionFactory(title=u'audio', product=desktop) ans = AnswerFactory(question=ques, content=u'volume') AnswerVoteFactory(answer=ans, helpful=True) doc = DocumentFactory(title=u'audio', locale=u'en-US', category=10, products=[desktop]) RevisionFactory(document=doc, is_approved=True) doc = DocumentFactory(title=u'audio too', locale=u'en-US', category=10, products=[desktop]) RevisionFactory(document=doc, is_approved=True) self.refresh() # There should be 2 results for kb (w=1) and 1 for questions (w=2). response = self.client.get(reverse('search'), { 'q': 'audio', 'format': 'json', 'w': '1'}) eq_(200, response.status_code) content = json.loads(response.content) eq_(content['total'], 2) response = self.client.get(reverse('search'), { 'q': 'audio', 'format': 'json', 'w': '2'}) eq_(200, response.status_code) content = json.loads(response.content) eq_(content['total'], 1)
def test_data_in_index(self): """Verify the data we are indexing.""" p = ProductFactory() q = QuestionFactory(locale='pt-BR', product=p) a = AnswerFactory(question=q) self.refresh() eq_(AnswerMetricsMappingType.search().count(), 1) data = AnswerMetricsMappingType.search()[0] eq_(data['locale'], q.locale) eq_(data['product'], [p.slug]) eq_(data['creator_id'], a.creator_id) eq_(data['is_solution'], False) eq_(data['by_asker'], False) # Mark as solution and verify q.solution = a q.save() self.refresh() data = AnswerMetricsMappingType.search()[0] eq_(data['is_solution'], True) # Make the answer creator to be the question creator and verify. a.creator = q.creator a.save() self.refresh() data = AnswerMetricsMappingType.search()[0] eq_(data['by_asker'], True)
def test_subtopics(self): """Verifies subtopics appear on document listing page.""" # Create a topic and product. p = ProductFactory() t = TopicFactory(product=p, visible=True) # Create a documents with the topic and product doc = DocumentFactory(products=[p], topics=[t]) ApprovedRevisionFactory(document=doc) self.refresh() # GET the page and verify no subtopics yet. url = reverse("products.documents", args=[p.slug, t.slug]) r = self.client.get(url, follow=True) eq_(200, r.status_code) pqdoc = pq(r.content) eq_(0, len(pqdoc("li.subtopic"))) # Create a subtopic, it still shouldn't show up because no # articles are assigned. subtopic = TopicFactory(parent=t, product=p, visible=True) r = self.client.get(url, follow=True) eq_(200, r.status_code) pqdoc = pq(r.content) eq_(0, len(pqdoc("li.subtopic"))) # Add a document to the subtopic, now it should appear. doc.topics.add(subtopic) self.refresh() r = self.client.get(url, follow=True) eq_(200, r.status_code) pqdoc = pq(r.content) eq_(1, len(pqdoc("li.subtopic")))
def test_include_wiki(self): """This tests whether doing a simple search returns wiki document results. Bug #709202. """ doc = DocumentFactory(title=u'audio', locale=u'en-US', category=10) doc.products.add(ProductFactory(title=u'firefox', slug=u'desktop')) RevisionFactory(document=doc, is_approved=True) self.refresh() # This is the search that you get when you start on the sumo # homepage and do a search from the box with two differences: # first, we do it in json since it's easier to deal with # testing-wise and second, we search for 'audio' since we have # data for that. response = self.client.get(reverse('search'), { 'q': 'audio', 'format': 'json' }) eq_(200, response.status_code) content = json.loads(response.content) eq_(content['total'], 1)
def test_ratelimit(self): """Make sure posting new questions is ratelimited""" data = { "title": "A test question", "content": "I have this question that I hope...", "sites_affected": "http://example.com", "ff_version": "3.6.6", "os": "Intel Mac OS X 10.6", "plugins": "* Shockwave Flash 10.1 r53", "useragent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X " "10.6; en-US; rv:1.9.2.6) Gecko/20100625 " "Firefox/3.6.6", } p = ProductFactory(slug="firefox") locale = QuestionLocale.objects.get(locale=settings.LANGUAGE_CODE) p.questions_locales.add(locale) TopicFactory(slug="fix-problems", product=p) url = urlparams( reverse("questions.aaq_step5", args=["desktop", "fix-problems"]), search="A test question", ) u = UserFactory() self.client.login(username=u.username, password="******") for i in range(0, 5): self.client.post(url, data, follow=True) response = self.client.post(url, data, follow=True) eq_(403, response.status_code)
def setUp(self): super(MobileDocumentTests, self).setUp() rev = ApprovedRevisionFactory() self.doc = rev.document p = ProductFactory() self.doc.products.add(p) self.doc.save()
def test_locale_filter(self): """Only questions for the current locale should be shown on the questions front page for AAQ locales.""" eq_(Question.objects.count(), 0) p = ProductFactory(slug=u"firefox") TopicFactory(title="Fix problems", slug="fix-problems", product=p) QuestionFactory(title="question cupcakes?", product=p, locale="en-US") QuestionFactory(title="question donuts?", product=p, locale="en-US") QuestionFactory(title="question pies?", product=p, locale="pt-BR") QuestionFactory(title="question pastries?", product=p, locale="de") def sub_test(locale, *titles): url = urlparams( reverse("questions.list", args=["all"], locale=locale)) response = self.client.get(url, follow=True) doc = pq(response.content) eq_msg( len(doc("section[id^=question]")), len(titles), "Wrong number of results for {0}".format(locale), ) for substr in titles: assert substr in doc(".questions section .content h2 a").text() # en-US and pt-BR are both in AAQ_LANGUAGES, so should be filtered. sub_test("en-US", "cupcakes?", "donuts?") sub_test("pt-BR", "pies?") # de is not in AAQ_LANGUAGES, so should show en-US, but not pt-BR sub_test("de", "cupcakes?", "donuts?", "pastries?")
def test_bleaching(self): """Tests whether summaries are bleached""" p = ProductFactory(slug=u"firefox") locale = QuestionLocale.objects.get(locale=settings.LANGUAGE_CODE) p.questions_locales.add(locale) TopicFactory(title="Fix problems", slug="fix-problems", product=p) QuestionFactory( product=p, title=u"CupcakesQuestion cupcakes", content=u"cupcakes are best with <unbleached>flour</unbleached>", ) self.refresh() url = urlparams( reverse("questions.aaq_step4", args=["desktop", "fix-problems"]), search="cupcakes", ) response = self.client.get(url, follow=True) eq_(200, response.status_code) assert "CupcakesQuestion" in response.content assert "<unbleached>" not in response.content assert "cupcakes are best with" in response.content
def test_expected_output(self): p = ProductFactory() t1 = TopicFactory(product=p, visible=True, display_order=1) t2 = TopicFactory(product=p, visible=True, display_order=2) url = reverse("topic-list", kwargs={"product": p.slug}) res = self.client.get(url) eq_(res.status_code, 200) eq_( res.data, { "count": 2, "next": None, "previous": None, "results": [ { "title": t1.title, "slug": t1.slug, }, { "title": t2.title, "slug": t2.slug, }, ], }, )
def test_locale_filter(self): """Only questions for the current locale should be shown on the questions front page for AAQ locales.""" eq_(Question.objects.count(), 0) p = ProductFactory(slug=u'firefox') TopicFactory(title='Fix problems', slug='fix-problems', product=p) QuestionFactory(title='question cupcakes?', product=p, locale='en-US') QuestionFactory(title='question donuts?', product=p, locale='en-US') QuestionFactory(title='question pies?', product=p, locale='pt-BR') QuestionFactory(title='question pastries?', product=p, locale='de') def sub_test(locale, *titles): url = urlparams( reverse('questions.list', args=['all'], locale=locale)) response = self.client.get(url, follow=True) doc = pq(response.content) eq_msg(len(doc('section[id^=question]')), len(titles), 'Wrong number of results for {0}'.format(locale)) for substr in titles: assert substr in doc('.questions section .content h2 a').text() # en-US and pt-BR are both in AAQ_LANGUAGES, so should be filtered. sub_test('en-US', 'cupcakes?', 'donuts?') sub_test('pt-BR', 'pies?') # de is not in AAQ_LANGUAGES, so should show en-US, but not pt-BR sub_test('de', 'cupcakes?', 'donuts?', 'pastries?')
def test_get_products(self): """Test the get_products() method.""" en_us = DocumentFactory(products=ProductFactory.create_batch(2)) eq_(2, len(en_us.get_products())) # Localized document inherits parent's topics. DocumentFactory(parent=en_us) eq_(2, len(en_us.get_products()))
def test_absolute_url(self): p = ProductFactory() expected = '/products/{p}'.format(p=p.slug) actual = p.get_absolute_url() eq_(actual, expected)