Ejemplo n.º 1
0
class LandingViewsTest(test_utils.TestCase):
    fixtures = ['test_data.json', ]

    def setUp(self):
        self.client = LocalizingClient()

    def test_home(self):
        url = reverse('landing.views.home')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_mozilla(self):
        url = reverse('landing.views.mozilla')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_web(self):
        url = reverse('landing.views.web')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_search(self):
        raise SkipTest('Search test disabled until we switch to kuma wiki')
        url = reverse('landing.views.search')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_promote_buttons(self):
        url = reverse('landing.views.promote_buttons')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 2
0
class DemoListViewsTest(test_utils.TestCase):
    fixtures = ['test_users.json']

    def setUp(self):
        self.user, self.admin_user, self.other_user = make_users()
        self.client = LocalizingClient()

    def test_all_demos_includes_hidden_for_staff(self):
        build_submission(self.user)
        build_hidden_submission(self.user)

        r = self.client.get(reverse('demos_all'))
        count = pq(r.content)('h2.count').text()
        eq_(count, "1 Demo")

        self.client.login(username=self.admin_user.username,
                          password='******')
        r = self.client.get(reverse('demos_all'))
        count = pq(r.content)('h2.count').text()
        eq_(count, "2 Demos")

    @attr('bug882709')
    def test_search_view(self):
        try:
            self.client.get(reverse('demos_search'))
        except:
            self.fail("Search should not ISE.")
Ejemplo n.º 3
0
    def test_kumawiki_waffle_flag(self):

        # Turn off the new wiki for everyone
        self.kumawiki_flag.everyone = False
        self.kumawiki_flag.save()
        
        client = LocalizingClient()

        resp = client.get(reverse('wiki.all_documents'))
        eq_(404, resp.status_code)
        
        resp = client.get(reverse('docs'))
        page = pq(resp.content)
        eq_(0, page.find('#kumawiki_preview').length)

        client.login(username='******', password='******')

        # Turn on the wiki for just superusers, ignore everyone else
        self.kumawiki_flag.superusers = True
        self.kumawiki_flag.everyone = None
        self.kumawiki_flag.save()

        resp = client.get(reverse('wiki.all_documents'))
        eq_(200, resp.status_code)
        
        resp = client.get(reverse('docs'))
        page = pq(resp.content)
        eq_(1, page.find('#kumawiki_preview').length)
Ejemplo n.º 4
0
class LandingViewsTest(test_utils.TestCase):
    fixtures = ["test_data.json"]

    def setUp(self):
        self.client = LocalizingClient()

    def test_home(self):
        url = reverse("landing.views.home")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

        doc = pq(r.content)
        dev_mdc_link = doc.find("a#dev-mdc-link")
        ok_(dev_mdc_link)

    def test_mozilla(self):
        url = reverse("landing.views.mozilla")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_web(self):
        url = reverse("landing.views.web")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_search(self):
        raise SkipTest("Search test disabled until we switch to kuma wiki")
        url = reverse("landing.views.search")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_promote_buttons(self):
        url = reverse("landing.views.promote_buttons")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 5
0
class EventsViewsTest(test_utils.TestCase):
    fixtures = ["devmo_calendar.json"]

    def setUp(self):
        self.client = LocalizingClient()
        devmo_calendar_reload()

    def test_events(self):
        url = reverse("devmo.views.events")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_events_map_flag(self):
        url = reverse("devmo.views.events")

        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_([], doc.find("#map_canvas"))
        ok_("maps.google.com" not in r.content)

        events_map_flag = Flag.objects.create(name="events_map", everyone=True)
        events_map_flag.save()

        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, len(doc.find("#map_canvas")))
        ok_("maps.google.com" in r.content)
Ejemplo n.º 6
0
class HomeTests(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_social_promo(self):
        url = reverse('landing.views.home')

        aurora_promo, social_promo = get_promos(self.client, url)
        ok_(aurora_promo)
        ok_(not social_promo)

        Switch.objects.create(name="social_promo", active=True)

        aurora_promo, social_promo = get_promos(self.client, url)
        ok_(not aurora_promo)
        ok_(social_promo)

    def test_google_analytics(self):
        url = reverse('landing.views.home')

        constance.config.GOOGLE_ANALYTICS_ACCOUNT = ''
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        ok_('var _gaq' not in r.content)

        constance.config.GOOGLE_ANALYTICS_ACCOUNT = 'UA-99999999-9'
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        ok_('var _gaq' in r.content)
Ejemplo n.º 7
0
class EventsViewsTest(test_utils.TestCase):
    fixtures = ['devmo_calendar.json']

    def setUp(self):
        self.client = LocalizingClient()
        devmo_calendar_reload()

    def test_events(self):
        url = reverse('devmo.views.events')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_events_map_flag(self):
        url = reverse('devmo.views.events')

        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_([], doc.find('#map_canvas'))
        ok_("maps.google.com" not in r.content)

        events_map_flag = Flag.objects.create(name='events_map', everyone=True)
        events_map_flag.save()

        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, len(doc.find('#map_canvas')))
        ok_("maps.google.com" in r.content)
Ejemplo n.º 8
0
class AppsViewsTest(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_apps_menu_item(self):
        url = reverse("landing.views.home")
        r = self.client.get(url)
        eq_(200, r.status_code)
        doc = pq(r.content)
        nav_sub_topics = doc.find("ul#nav-sub-topics")
        ok_(nav_sub_topics)
        apps_item = nav_sub_topics.find("li#nav-sub-apps")
        eq_("Apps", apps_item.text())

    def test_apps(self):
        url = reverse("landing.views.apps")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        signup_form = doc.find("form.fm-subscribe")
        eq_(reverse("apps_subscription", locale="en-US"), signup_form.attr("action"))

    @patch("landing.views.basket.subscribe")
    def test_apps_subscription(self, subscribe):
        subscribe.return_value = True
        url = reverse("landing.views.apps_subscription")
        r = self.client.post(url, {"format": "html", "email": "*****@*****.**", "agree": "checked"}, follow=True)
        eq_(200, r.status_code)
        # assert thank you message
        self.assertContains(r, "Thank you")
        eq_(1, subscribe.call_count)

    @patch("landing.views.basket.subscribe")
    def test_apps_subscription_ajax(self, subscribe):
        subscribe.return_value = True
        url = reverse("landing.views.apps_subscription")
        r = self.client.post(
            url,
            {"format": "html", "email": "*****@*****.**", "agree": "checked"},
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        eq_(200, r.status_code)
        # assert thank you message
        self.assertContains(r, "Thank you")
        self.assertNotContains(r, "<html")
        self.assertNotContains(r, "<head>")
        self.assertNotContains(r, "<title>")
        eq_(1, subscribe.call_count)

    @patch("landing.views.basket.subscribe")
    def test_apps_subscription_bad_values(self, subscribe):
        subscribe.return_value = True
        url = reverse("landing.views.apps_subscription")
        r = self.client.post(url, {"format": 1, "email": "nope"})
        eq_(200, r.status_code)
        # assert error
        self.assertContains(r, "Enter a valid e-mail address.")
        self.assertContains(r, "Select a valid choice.")
        self.assertContains(r, "You must agree to the privacy policy.")
Ejemplo n.º 9
0
    def test_json_callback_validation(self):
        """Various json callbacks -- validation"""
        c = LocalizingClient()
        q = 'bookmarks'
        format = 'json'

        callbacks = (
            ('callback', 200),
            ('validCallback', 200),
            ('obj.method', 200),
            ('obj.someMethod', 200),
            ('arr[1]', 200),
            ('arr[12]', 200),
            ("alert('xss');foo", 400),
            ("eval('nastycode')", 400),
            ("someFunc()", 400),
            ('x', 200),
            ('x123', 200),
            ('$', 200),
            ('_func', 200),
            ('"></script><script>alert(\'xss\')</script>', 400),
            ('">', 400),
            ('var x=something;foo', 400),
            ('var x=', 400),
        )

        for callback, status in callbacks:
            response = c.get(reverse('search'), {
                'q': q,
                'format': format,
                'callback': callback,
            })
            eq_(response['Content-Type'], 'application/x-javascript')
            eq_(response.status_code, status)
Ejemplo n.º 10
0
class ProfileViewsTest(TestCase):
    fixtures = ['test_users.json']

    def setUp(self):
        self.old_debug = settings.DEBUG
        settings.DEBUG = True
        self.client = LocalizingClient()
        self.client.logout()

    def tearDown(self):
        settings.DEBUG = self.old_debug

    @attr('docs_activity')
    @attr('bug715923')
    @patch('devmo.models.UserDocsActivityFeed.fetch_user_feed')
    def test_bug715923_feed_parsing_errors(self, fetch_user_feed):
        fetch_user_feed.return_value = """
            THIS IS NOT EVEN XML, SO BROKEN
        """
        try:
            profile = UserProfile.objects.get(user__username='******')
            user = profile.user
            url = reverse('devmo.views.profile_view', args=(user.username, ))
            r = self.client.get(url, follow=True)
            pq(r.content)
        except Exception, e:
            raise e
            ok_(False, "There should be no exception %s" % e)
Ejemplo n.º 11
0
    def test_review_tags(self):
        client = LocalizingClient()
        client.login(username='******', password='******')

        data = new_document_data()
        data.update({'review_tags':['editorial']})
        response = client.post(reverse('wiki.new_document'), data)

        doc = Document.objects.get(slug="a-test-article")

        combos = (
            ([], 0, 0, 0, 0),
            (['technical',], 1, 1, 0, 0),
            (['editorial',], 0, 0, 1, 1),
            (['technical', 'editorial',], 1, 1, 1, 1),
        )

        for tags, a, b, c, d in combos:

            # Edit the page and set the tags for this test
            data.update({ 'form': 'rev', 'review_tags': tags })
            response = client.post(reverse('wiki.edit_document', args=[doc.slug]), data)

            response = client.get(reverse('docs.views.docs'))
            page = pq(response.content)

            # Check for the section itself, and then the doc 
            eq_(a, page('div#review-technical').length)
            eq_(b, page("div#review-technical ul li h4 a:contains('%s')" %
                doc.title).length)
            eq_(c, page('div#review-editorial').length)
            eq_(d, page("div#review-editorial ul li h4 a:contains('%s')" %
                doc.title).length)
Ejemplo n.º 12
0
    def test_raw_section_source(self):
        """The raw source for a document section can be requested"""
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        expected = """
            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>
        """
        response = client.get('%s?section=s2&raw=true' %
                              reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), 
            normalize_html(response.content))
Ejemplo n.º 13
0
    def test_raw_with_editing_links_source(self):
        """The raw source for a document can be requested, with section editing
        links"""
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        expected = """
            <h1 id="s1"><a class="edit-section" data-section-id="s1" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s1" href="/en-US/docs/%(slug)s$edit?section=s1&amp;edit_links=true" title="Edit section">Edit</a>Head 1</h1>
            <p>test</p>
            <p>test</p>
            <h1 id="s2"><a class="edit-section" data-section-id="s2" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s2" href="/en-US/docs/%(slug)s$edit?section=s2&amp;edit_links=true" title="Edit section">Edit</a>Head 2</h1>
            <p>test</p>
            <p>test</p>
            <h1 id="s3"><a class="edit-section" data-section-id="s3" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s3" href="/en-US/docs/%(slug)s$edit?section=s3&amp;edit_links=true" title="Edit section">Edit</a>Head 3</h1>
            <p>test</p>
            <p>test</p>
        """ % {'slug': d.slug}
        response = client.get('%s?raw=true&edit_links=true' %
                              reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), 
            normalize_html(response.content))
Ejemplo n.º 14
0
    def test_raw_with_editing_links_source(self):
        """The raw source for a document can be requested, with section editing
        links"""
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        expected = """
            <h1 id="s1"><a class="edit-section" data-section-id="s1" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s1" href="/en-US/docs/%(slug)s$edit?section=s1&amp;edit_links=true" title="Edit section">Edit</a>Head 1</h1>
            <p>test</p>
            <p>test</p>
            <h1 id="s2"><a class="edit-section" data-section-id="s2" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s2" href="/en-US/docs/%(slug)s$edit?section=s2&amp;edit_links=true" title="Edit section">Edit</a>Head 2</h1>
            <p>test</p>
            <p>test</p>
            <h1 id="s3"><a class="edit-section" data-section-id="s3" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s3" href="/en-US/docs/%(slug)s$edit?section=s3&amp;edit_links=true" title="Edit section">Edit</a>Head 3</h1>
            <p>test</p>
            <p>test</p>
        """ % {
            'slug': d.slug
        }
        response = client.get('%s?raw=true&edit_links=true' %
                              reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), normalize_html(response.content))
Ejemplo n.º 15
0
    def test_raw_section_source(self):
        """The raw source for a document section can be requested"""
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        expected = """
            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>
        """
        response = client.get('%s?section=s2&raw=true' %
                              reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), normalize_html(response.content))
Ejemplo n.º 16
0
    def test_json_callback_validation(self):
        """Various json callbacks -- validation"""
        c = LocalizingClient()
        q = 'bookmarks'
        format = 'json'

        callbacks = (
            ('callback', 200),
            ('validCallback', 200),
            ('obj.method', 200),
            ('obj.someMethod', 200),
            ('arr[1]', 200),
            ('arr[12]', 200),
            ("alert('xss');foo", 400),
            ("eval('nastycode')", 400),
            ("someFunc()", 400),
            ('x', 200),
            ('x123', 200),
            ('$', 200),
            ('_func', 200),
            ('"></script><script>alert(\'xss\')</script>', 400),
            ('">', 400),
            ('var x=something;foo', 400),
            ('var x=', 400),
        )

        for callback, status in callbacks:
            response = c.get(reverse('search'), {
                'q': q,
                'format': format,
                'callback': callback,
            })
            eq_(response['Content-Type'], 'application/x-javascript')
            eq_(response.status_code, status)
Ejemplo n.º 17
0
class ProfileViewsTest(TestCase):
    fixtures = ['test_users.json']

    def setUp(self):
        self.old_debug = settings.DEBUG
        settings.DEBUG = True
        self.client = LocalizingClient()
        self.client.logout()

    def tearDown(self):
        settings.DEBUG = self.old_debug

    @attr('docs_activity')
    @attr('bug715923')
    @patch('devmo.models.UserDocsActivityFeed.fetch_user_feed')
    def test_bug715923_feed_parsing_errors(self, fetch_user_feed):
        fetch_user_feed.return_value = """
            THIS IS NOT EVEN XML, SO BROKEN
        """
        try:
            profile = UserProfile.objects.get(user__username='******')
            user = profile.user
            url = reverse('devmo.views.profile_view',
                          args=(user.username,))
            r = self.client.get(url, follow=True)
            pq(r.content)
        except Exception, e:
            raise e
            ok_(False, "There should be no exception %s" % e)
Ejemplo n.º 18
0
class HomeTests(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_google_analytics(self):
        url = reverse('landing.views.home')

        with override_constance_settings(GOOGLE_ANALYTICS_ACCOUNT='0'):
            r = self.client.get(url, follow=True)
            eq_(200, r.status_code)
            ok_('var _gaq' not in r.content)

        with override_constance_settings(GOOGLE_ANALYTICS_ACCOUNT='UA-99999999-9'):
            r = self.client.get(url, follow=True)
            eq_(200, r.status_code)
            ok_('var _gaq' in r.content)
Ejemplo n.º 19
0
 def test_json_format(self):
     """JSON without callback should return application/json"""
     c = LocalizingClient()
     response = c.get(reverse('search'), {
         'q': 'bookmarks',
         'format': 'json',
     })
     eq_(response['Content-Type'], 'application/json')
Ejemplo n.º 20
0
 def test_json_format(self):
     """JSON without callback should return application/json"""
     c = LocalizingClient()
     response = c.get(reverse('search'), {
         'q': 'bookmarks',
         'format': 'json',
     })
     eq_(response['Content-Type'], 'application/json')
Ejemplo n.º 21
0
def test_breadcrumb():
    """Make sure breadcrumb links start with /."""
    c = LocalizingClient()
    response = c.get(reverse('search'))

    doc = pq(response.content)
    href = doc('.breadcrumbs a')[0]
    eq_('/', href.attrib['href'][0])
Ejemplo n.º 22
0
def test_breadcrumb():
    """Make sure breadcrumb links start with /."""
    c = LocalizingClient()
    response = c.get(reverse('search'))

    doc = pq(response.content)
    href = doc('.breadcrumbs a')[0]
    eq_('/', href.attrib['href'][0])
Ejemplo n.º 23
0
    def test_ban_middleware(self):
        """Ban middleware functions correctly."""
        client = LocalizingClient()
        client.login(username='******', password='******')

        resp = client.get('/')
        self.assertTemplateNotUsed(resp, 'users/user_banned.html')

        admin = User.objects.get(username='******')
        testuser = User.objects.get(username='******')
        ban = UserBan(user=testuser, by=admin,
                      reason='Banned by unit test.',
                      is_active=True)
        ban.save()

        resp = client.get('/')
        self.assertTemplateUsed(resp, 'users/user_banned.html')
Ejemplo n.º 24
0
def test_breadcrumb():
    """Make sure breadcrumb links start with /."""
    c = LocalizingClient()
    response = c.get(reverse("search"))

    doc = pq(response.content)
    href = doc(".breadcrumbs a")[0]
    eq_("/", href.attrib["href"][0])
Ejemplo n.º 25
0
    def test_ban_middleware(self):
        """Ban middleware functions correctly."""
        client = LocalizingClient()
        client.login(username='******', password='******')

        resp = client.get('/')
        self.assertTemplateNotUsed(resp, 'users/user_banned.html')

        admin = User.objects.get(username='******')
        testuser = User.objects.get(username='******')
        ban = UserBan(user=testuser,
                      by=admin,
                      reason='Banned by unit test.',
                      is_active=True)
        ban.save()

        resp = client.get('/')
        self.assertTemplateUsed(resp, 'users/user_banned.html')
Ejemplo n.º 26
0
    def test_ban_permission(self):
        """The ban permission controls access to the ban view."""
        client = LocalizingClient()
        admin = User.objects.get(username="******")
        testuser = User.objects.get(username="******")

        # testuser doesn't have ban permission, can't ban.
        client.login(username="******", password="******")
        ban_url = reverse("users.ban_user", kwargs={"user_id": admin.id})
        resp = client.get(ban_url)
        eq_(302, resp.status_code)
        ok_(settings.LOGIN_URL in resp["Location"])
        client.logout()

        # admin has ban permission, can ban.
        client.login(username="******", password="******")
        ban_url = reverse("users.ban_user", kwargs={"user_id": testuser.id})
        resp = client.get(ban_url)
        eq_(200, resp.status_code)
Ejemplo n.º 27
0
    def test_ban_permission(self):
        """The ban permission controls access to the ban view."""
        client = LocalizingClient()
        admin = User.objects.get(username='******')
        testuser = User.objects.get(username='******')

        # testuser doesn't have ban permission, can't ban.
        client.login(username='******', password='******')
        ban_url = reverse('users.ban_user', kwargs={'user_id': admin.id})
        resp = client.get(ban_url)
        eq_(302, resp.status_code)
        ok_(settings.LOGIN_URL in resp['Location'])
        client.logout()

        # admin has ban permission, can ban.
        client.login(username='******', password='******')
        ban_url = reverse('users.ban_user', kwargs={'user_id': testuser.id})
        resp = client.get(ban_url)
        eq_(200, resp.status_code)
Ejemplo n.º 28
0
    def test_edit_midair_collision(self):
        client = LocalizingClient()
        client.login(username='******', password='******')

        # Post a new document.
        data = new_document_data()
        resp = client.post(reverse('wiki.new_document'), data)
        doc = Document.objects.get(slug=data['slug'])

        # Edit #1 starts...
        resp = client.get(reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id1 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 starts...
        resp = client.get(reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id2 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 submits successfully
        data.update({
            'form': 'rev',
            'content': 'This edit got there first',
            'current_rev': rev_id2
        })
        resp = client.post(reverse('wiki.edit_document', args=[doc.slug]),
                           data)
        eq_(302, resp.status_code)

        # Edit #1 submits, but receives a mid-aired notification
        data.update({
            'form': 'rev',
            'content': 'This edit gets mid-aired',
            'current_rev': rev_id1
        })
        resp = client.post(reverse('wiki.edit_document', args=[doc.slug]),
                           data)
        eq_(200, resp.status_code)

        ok_(
            unicode(MIDAIR_COLLISION).encode('utf-8') in resp.content,
            "Midair collision message should appear")
Ejemplo n.º 29
0
    def test_json_empty_query(self):
        """Empty query returns JSON format"""
        c = LocalizingClient()

        # Test with flags for advanced search or not
        a_types = (0, 1, 2)
        for a in a_types:
            response = c.get(reverse('search'), {
                'format': 'json', 'a': a,
            })
            eq_(response['Content-Type'], 'application/json')
Ejemplo n.º 30
0
class EventsViewsTest(test_utils.TestCase):
    fixtures = ['devmo_calendar.json']

    def setUp(self):
        self.client = LocalizingClient()
        devmo_calendar_reload()

    def test_events(self):
        url = reverse('devmo.views.events')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 31
0
    def test_json_empty_query(self):
        """Empty query returns JSON format"""
        c = LocalizingClient()

        # Test with flags for advanced search or not
        a_types = (0, 1, 2)
        for a in a_types:
            response = c.get(reverse('search'), {
                'format': 'json', 'a': a,
            })
            eq_(response['Content-Type'], 'application/json')
Ejemplo n.º 32
0
class EventsViewsTest(test_utils.TestCase):
    fixtures = ['devmo_calendar.json']

    def setUp(self):
        self.client = LocalizingClient()
        devmo_calendar_reload()

    def test_events(self):
        url = reverse('devmo.views.events')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 33
0
class LandingViewsTest(test_utils.TestCase):
    fixtures = [
        'test_data.json',
    ]

    def setUp(self):
        self.client = LocalizingClient()

    def test_home(self):
        url = reverse('landing.views.home')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

        doc = pq(r.content)
        dev_mdc_link = doc.find('a#dev-mdc-link')
        ok_(dev_mdc_link)

    def test_addons(self):
        url = reverse('landing.views.addons')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_mozilla(self):
        url = reverse('landing.views.mozilla')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_mobile(self):
        url = reverse('landing.views.mobile')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_web(self):
        url = reverse('landing.views.web')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_promote_buttons(self):
        url = reverse('landing.views.promote_buttons')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_discussion(self):
        url = reverse('landing.views.discussion')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_forum_archive(self):
        url = reverse('landing.views.forum_archive')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 34
0
class HomeTests(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_social_promo(self):
        url = reverse('landing.views.home')
        promo = get_promos(self.client, url, '#promo-fosdev')
        ok_(promo)

    def test_google_analytics(self):
        url = reverse('landing.views.home')

        constance.config.GOOGLE_ANALYTICS_ACCOUNT = ''
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        ok_('var _gaq' not in r.content)

        constance.config.GOOGLE_ANALYTICS_ACCOUNT = 'UA-99999999-9'
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        ok_('var _gaq' in r.content)
Ejemplo n.º 35
0
class HomeTests(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_social_promo(self):
        url = reverse("landing.views.home")
        promo = get_promos(self.client, url, "#promo-fosdev")
        ok_(promo)

    def test_google_analytics(self):
        url = reverse("landing.views.home")

        with override_constance_settings(GOOGLE_ANALYTICS_ACCOUNT="0"):
            r = self.client.get(url, follow=True)
            eq_(200, r.status_code)
            ok_("var _gaq" not in r.content)

        with override_constance_settings(GOOGLE_ANALYTICS_ACCOUNT="UA-99999999-9"):
            r = self.client.get(url, follow=True)
            eq_(200, r.status_code)
            ok_("var _gaq" in r.content)
Ejemplo n.º 36
0
class LearnViewsTest(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_learn(self):
        url = reverse("landing.views.learn")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_html(self):
        url = reverse("landing.views.learn_html")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_html5(self):
        url = reverse("landing.views.learn_html5")
        r = self.client.get(url, follow=True)
        eq_(404, r.status_code)
        s = Switch.objects.create(name="html5_landing", active=True)
        s.save()
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        s.delete()

    def test_learn_css(self):
        url = reverse("landing.views.learn_css")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_javascript(self):
        url = reverse("landing.views.learn_javascript")
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 37
0
class LearnViewsTest(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_learn(self):
        url = reverse('landing.views.learn')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_html(self):
        url = reverse('landing.views.learn_html')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_html5(self):
        url = reverse('landing.views.learn_html5')
        r = self.client.get(url, follow=True)
        eq_(404, r.status_code)
        s = Switch.objects.create(name='html5_landing', active=True)
        s.save()
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        s.delete()

    def test_learn_css(self):
        url = reverse('landing.views.learn_css')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_javascript(self):
        url = reverse('landing.views.learn_javascript')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 38
0
class HomeTests(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_social_promo(self):
        url = reverse('landing.views.home')
        promo = get_promos(self.client, url, '#promo-fosdev')
        ok_(promo)

    def test_google_analytics(self):
        url = reverse('landing.views.home')

        with override_constance_settings(GOOGLE_ANALYTICS_ACCOUNT='0'):
            r = self.client.get(url, follow=True)
            eq_(200, r.status_code)
            ok_('var _gaq' not in r.content)

        with override_constance_settings(
                GOOGLE_ANALYTICS_ACCOUNT='UA-99999999-9'):
            r = self.client.get(url, follow=True)
            eq_(200, r.status_code)
            ok_('var _gaq' in r.content)
Ejemplo n.º 39
0
    def test_edit_midair_collision(self):
        client = LocalizingClient()
        client.login(username='******', password='******')

        # Post a new document.
        data = new_document_data()
        resp = client.post(reverse('wiki.new_document'), data)
        doc = Document.objects.get(slug=data['slug'])

        # Edit #1 starts...
        resp = client.get(reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id1 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 starts...
        resp = client.get(reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id2 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 submits successfully
        data.update({
            'form': 'rev',
            'content': 'This edit got there first',
            'current_rev': rev_id2
        })
        resp = client.post(reverse('wiki.edit_document', args=[doc.slug]), data)
        eq_(302, resp.status_code)

        # Edit #1 submits, but receives a mid-aired notification
        data.update({
            'form': 'rev',
            'content': 'This edit gets mid-aired',
            'current_rev': rev_id1
        })
        resp = client.post(reverse('wiki.edit_document', args=[doc.slug]), data)
        eq_(200, resp.status_code)

        ok_(unicode(MIDAIR_COLLISION).encode('utf-8') in resp.content,
            "Midair collision message should appear")
Ejemplo n.º 40
0
class LandingViewsTest(test_utils.TestCase):
    fixtures = ['test_data.json', ]

    def setUp(self):
        self.client = LocalizingClient()

    def test_home(self):
        url = reverse('landing.views.home')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

        doc = pq(r.content)
        dev_mdc_link = doc.find('a#dev-mdc-link')
        ok_(dev_mdc_link)

    def test_addons(self):
        url = reverse('landing.views.addons')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_mozilla(self):
        url = reverse('landing.views.mozilla')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_mobile(self):
        url = reverse('landing.views.mobile')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_web(self):
        url = reverse('landing.views.web')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_promote_buttons(self):
        url = reverse('landing.views.promote_buttons')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_discussion(self):
        url = reverse('landing.views.discussion')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_forum_archive(self):
        url = reverse('landing.views.forum_archive')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 41
0
class LearnViewsTest(test_utils.TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def test_learn(self):
        url = reverse('landing.views.learn')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_html(self):
        url = reverse('landing.views.learn_html')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_css(self):
        url = reverse('landing.views.learn_css')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_javascript(self):
        url = reverse('landing.views.learn_javascript')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 42
0
class FilterTestCase(TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def _tweet_list(self, filter):
        """Return the content of async-fetched tweet list.

        Also, assert the request returns a 200.

        """
        response = self.client.get(reverse('customercare.more_tweets'),
                                   {'filter': filter})
        eq_(response.status_code, 200)
        return response.content
Ejemplo n.º 43
0
class FilterTestCase(TestCase):
    def setUp(self):
        self.client = LocalizingClient()

    def _tweet_list(self, filter):
        """Return the content of async-fetched tweet list.

        Also, assert the request returns a 200.

        """
        response = self.client.get(
            reverse('customercare.more_tweets'),
            {'filter': filter})
        eq_(response.status_code, 200)
        return response.content
Ejemplo n.º 44
0
class LearnViewsTest(test_utils.TestCase):

    def setUp(self):
        self.client = LocalizingClient()

    def test_learn(self):
        url = reverse('landing.views.learn')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_html(self):
        url = reverse('landing.views.learn_html')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_css(self):
        url = reverse('landing.views.learn_css')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_learn_javascript(self):
        url = reverse('landing.views.learn_javascript')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 45
0
    def test_raw_section_edit(self):
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace = """
            <h1 id="s2">Replace</h1>
            <p>replace</p>
        """
        expected = """
            <h1 id="s2">Replace</h1>
            <p>replace</p>
        """
        response = client.post('%s?section=s2&raw=true' %
                               reverse('wiki.edit_document', args=[d.slug]),
                               {"form": "rev",
                                "content": replace},
                               follow=True)
        eq_(normalize_html(expected), 
            normalize_html(response.content))

        expected = """
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Replace</h1>
            <p>replace</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """
        response = client.get('%s?raw=true' %
                               reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), 
            normalize_html(response.content))
Ejemplo n.º 46
0
    def test_raw_section_edit(self):
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace = """
            <h1 id="s2">Replace</h1>
            <p>replace</p>
        """
        expected = """
            <h1 id="s2">Replace</h1>
            <p>replace</p>
        """
        response = client.post('%s?section=s2&raw=true' %
                               reverse('wiki.edit_document', args=[d.slug]), {
                                   "form": "rev",
                                   "content": replace
                               },
                               follow=True)
        eq_(normalize_html(expected), normalize_html(response.content))

        expected = """
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Replace</h1>
            <p>replace</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """
        response = client.get('%s?raw=true' %
                              reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), normalize_html(response.content))
Ejemplo n.º 47
0
def es_search_cmd(query, pages=1, log=log):
    """Simulates a front page search

    .. Note::

       This **doesn't** simulate an advanced search---just a front
       page search.

    """
    from sumo.tests import LocalizingClient
    from sumo.urlresolvers import reverse

    client = LocalizingClient()

    output = []
    output.append('Search for: %s' % query)
    output.append('')

    data = {
        'q': query, 'format': 'json'
        }
    url = reverse('search')

    # The search view shows 10 results at a time. So we hit it few
    # times---once for each page.
    for pageno in range(pages):
        pageno = pageno + 1
        data['page'] = pageno
        resp = client.get(url, data)
        if resp.status_code != 200:
            output.append('ERROR: %s' % resp.content)
            break

        else:
            content = json.loads(resp.content)
            results = content[u'results']

            for mem in results:
                output.append(u'%4d  %5.2f  %-10s  %-20s' % (
                        mem['rank'], mem['score'], mem['type'], mem['title']))

            output.append('')

    for line in output:
        log.info(line.encode('ascii', 'ignore'))
Ejemplo n.º 48
0
class LandingViewsTest(test_utils.TestCase):
    fixtures = [
        'test_data.json',
    ]

    def setUp(self):
        self.client = LocalizingClient()

    def test_home(self):
        url = reverse('landing.views.home')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

        doc = pq(r.content)
        dev_mdc_link = doc.find('a#dev-mdc-link')
        ok_(dev_mdc_link)

    def test_addons(self):
        url = reverse('landing.views.addons')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_mozilla(self):
        url = reverse('landing.views.mozilla')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_mobile(self):
        url = reverse('landing.views.mobile')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_web(self):
        url = reverse('landing.views.web')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_search(self):
        raise SkipTest('Search test disabled until we switch to kuma wiki')
        url = reverse('landing.views.search')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)

    def test_promote_buttons(self):
        url = reverse('landing.views.promote_buttons')
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
Ejemplo n.º 49
0
def test_json_down():
    """When the Sphinx is down, return JSON and 503 status"""
    c = LocalizingClient()

    # Test with flags for advanced search or not
    callbacks = (
        ('', 503, 'application/json'),
        ('validCallback', 503, 'application/x-javascript'),
        # Invalid callback does not search
        ('eval("xss");a', 400, 'application/x-javascript'),
    )
    for callback, status, mimetype in callbacks:
        response = c.get(reverse('search'), {
            'q': 'json down', 'format': 'json',
            'callback': callback,
        })
        eq_(response['Content-Type'], mimetype)
        eq_(response.status_code, status)
Ejemplo n.º 50
0
def test_json_down():
    """When the Sphinx is down, return JSON and 503 status"""
    c = LocalizingClient()

    # Test with flags for advanced search or not
    callbacks = (
        ('', 503, 'application/json'),
        ('validCallback', 503, 'application/x-javascript'),
        # Invalid callback does not search
        ('eval("xss");a', 400, 'application/x-javascript'),
    )
    for callback, status, mimetype in callbacks:
        response = c.get(reverse('search'), {
            'q': 'json down', 'format': 'json',
            'callback': callback,
        })
        eq_(response['Content-Type'], mimetype)
        eq_(response.status_code, status)
Ejemplo n.º 51
0
def es_search_cmd(query, pages=1, log=log):
    """Simulates a front page search

    .. Note::

       This **doesn't** simulate an advanced search---just a front
       page search.

    """
    from sumo.tests import LocalizingClient
    from sumo.urlresolvers import reverse

    client = LocalizingClient()

    output = []
    output.append('Search for: %s' % query)
    output.append('')

    data = {'q': query, 'format': 'json'}
    url = reverse('search')

    # The search view shows 10 results at a time. So we hit it few
    # times---once for each page.
    for pageno in range(pages):
        pageno = pageno + 1
        data['page'] = pageno
        resp = client.get(url, data)
        if resp.status_code != 200:
            output.append('ERROR: %s' % resp.content)
            break

        else:
            content = json.loads(resp.content)
            results = content[u'results']

            for mem in results:
                output.append(
                    u'%4d  %5.2f  %-10s  %-20s' %
                    (mem['rank'], mem['score'], mem['type'], mem['title']))

            output.append('')

    for line in output:
        log.info(line.encode('ascii', 'ignore'))
Ejemplo n.º 52
0
class DemoViewsTest(test_utils.TestCase):
    fixtures = ['test_users.json']

    def setUp(self):
        self.testuser = User.objects.get(username='******')
        self.testuser.set_password(TESTUSER_PASSWORD)
        self.testuser.save()
        self.client = LocalizingClient()

    def test_submit_loggedout(self):
        r = self.client.get(reverse('demos_submit'))
        choices = pq(r.content)('p.choices a[href*="login"]')
        eq_(choices.length, 1)

    @logged_in
    def test_submit_loggedin(self):
        r = self.client.get(reverse('demos_submit'))
        assert pq(r.content)('form#demo-submit')

    @logged_in
    def test_submit_post_invalid(self):
        r = self.client.post(reverse('demos_submit'), data={})
        d = pq(r.content)
        assert d('form#demo-submit')
        assert d('li#field_title ul.errorlist')
        assert d('li#field_summary ul.errorlist')
        assert d('li#field_screenshot_1 ul.errorlist')
        assert d('li#field_demo_package ul.errorlist')
        assert d('li#field_license_name ul.errorlist')
        assert d('li#field_captcha ul.errorlist')
        assert d('li#field_accept_terms ul.errorlist')

    @logged_in
    @disable_captcha
    def test_submit_post_valid(self):

        # Create a valid demo zip file
        zf_fout = StringIO()
        zf = zipfile.ZipFile(zf_fout, 'w')
        zf.writestr('index.html', """<html></html>""")
        zf.close()

        # Create a new file for input
        zf_fin = StringIO(zf_fout.getvalue())
        zf_fin.name = 'demo.zip'

        r = self.client.post(reverse('demos_submit'),
                             data=dict(
                                 title='Test submission',
                                 summary='This is a test demo submission',
                                 description='Some description goes here',
                                 tech_tags=(
                                     'tech:audio',
                                     'tech:video',
                                     'tech:websockets',
                                 ),
                                 screenshot_1=open(SCREENSHOT_PATH),
                                 demo_package=zf_fin,
                                 license_name='gpl',
                                 accept_terms='1',
                             ))

        eq_(302, r.status_code)
        assert 'Location' in r
        assert 'test-submission' in r['Location']

        try:
            obj = Submission.objects.get(slug='test-submission')
            eq_('Test submission', obj.title)
        except Submission.DoesNotExist:
            assert False

        result_tags = [t.name for t in obj.taggit_tags.all_ns('tech:')]
        result_tags.sort()
        eq_(['tech:audio', 'tech:video', 'tech:websockets'], result_tags)

    @logged_in
    def test_edit_invalid(self):
        s = save_valid_submission()
        edit_url = reverse('demos_edit', args=[s.slug])
        r = self.client.post(edit_url, data=dict())
        d = pq(r.content)
        assert d('form#demo-submit')
        assert d('li#field_title ul.errorlist')
        assert d('li#field_summary ul.errorlist')
        assert d('li#field_license_name ul.errorlist')

    @logged_in
    def test_edit_valid(self):
        s = save_valid_submission()
        edit_url = reverse('demos_edit', args=[s.slug])
        r = self.client.post(edit_url,
                             data=dict(
                                 title=s.title,
                                 summary='This is a test demo submission',
                                 description='Some description goes here',
                                 tech_tags=(
                                     'tech:audio',
                                     'tech:video',
                                     'tech:websockets',
                                 ),
                                 license_name='gpl',
                                 accept_terms='1',
                             ))

        eq_(302, r.status_code)
        assert 'Location' in r
        assert 'hello-world' in r['Location']

        try:
            obj = Submission.objects.get(slug='hello-world')
            eq_('This is a test demo submission', obj.summary)
        except Submission.DoesNotExist:
            assert False

    def test_detail(self):
        s = save_valid_submission('hello world')

        url = reverse('demos_detail', args=[s.slug])
        r = self.client.get(url)
        d = pq(r.content)
        eq_(s.title, d('h1.page-title').text())
        edit_link = d('ul.manage a.edit')
        assert not edit_link

    def test_detail_censored(self):
        s = save_valid_submission('hello world')
        s.censored = True
        s.save()

        url = reverse('demos_detail', args=[s.slug])
        r = self.client.get(url)
        d = pq(r.content)
        eq_('Permission Denied', d('h1.page-title').text())

    def test_detail_censored_url(self):
        s = save_valid_submission('hello world')
        s.censored = True
        s.censored_url = "http://developer.mozilla.org"
        s.save()

        url = reverse('demos_detail', args=[s.slug])
        r = self.client.get(url)
        eq_(302, r.status_code)
        eq_("http://developer.mozilla.org", r['Location'])

    @logged_in
    def test_creator_can_edit(self):
        s = save_valid_submission('hello world')

        url = reverse('demos_detail', args=[s.slug])
        r = self.client.get(url)
        d = pq(r.content)
        edit_link = d('ul#demo-manage a.edit')
        assert edit_link
        edit_url = reverse('demos_edit', args=[s.slug], locale='en-US')
        eq_(edit_url, edit_link.attr("href"))

        r = self.client.get(edit_url)
        assert pq(r.content)('form#demo-submit')
        eq_('Save changes',
            pq(r.content)('p.fm-submit button[type="submit"]').text())

    @logged_in
    def test_hidden_field(self):
        s = save_valid_submission('hello world')

        edit_url = reverse('demos_edit', args=[s.slug])
        r = self.client.get(edit_url)
        assert pq(r.content)('input[name="hidden"][type="checkbox"]')

    @logged_in
    def test_derby_field(self):
        s = save_valid_submission('hello world')

        edit_url = reverse('demos_edit', args=[s.slug])
        r = self.client.get(edit_url)
        assert pq(r.content)('fieldset#devderby-submit')

    @logged_in
    def test_edit_no_tags(self):
        s = save_valid_submission('hello world')
        edit_url = reverse('demos_edit', args=[s.slug])
        r = self.client.post(edit_url,
                             data=dict(
                                 title=s.title,
                                 summary='This is a test edit',
                                 description='Some description goes here',
                                 license_name='gpl',
                                 accept_terms='1',
                             ))
        eq_(r.status_code, 302)
        r = self.client.get(edit_url)
        eq_(r.status_code, 200)

    @logged_in
    def test_edit_with_challenge_tag(self):
        s = save_valid_submission('hello world')
        edit_url = reverse('demos_edit', args=[s.slug])
        r = self.client.post(
            edit_url,
            data=dict(
                title=s.title,
                summary='This is a test edit',
                description='Some description goes here',
                tech_tags=('tech:audio', ),
                challenge_tags=parse_tags(
                    constance.config.DEMOS_DEVDERBY_CHALLENGE_CHOICE_TAGS)[0],
                license_name='gpl',
                accept_terms='1',
            ))
        eq_(r.status_code, 302)
        r = self.client.get(edit_url)
        eq_(r.status_code, 200)

    def test_challenge_tag_to_date_parts(self):
        tag = 'challenge:2011:october'
        eq_(challenge_utils.challenge_tag_to_date_parts(tag), (2011, 10))

    def test_challenge_tag_to_end_date(self):
        tag = 'challenge:2011:october'
        eq_(challenge_utils.challenge_tag_to_end_date(tag),
            datetime.date(2011, 10, 31))
        tag = 'challenge:2011:february'
        eq_(challenge_utils.challenge_tag_to_end_date(tag),
            datetime.date(2011, 2, 28))
        tag = 'challenge:2012:february'
        eq_(challenge_utils.challenge_tag_to_end_date(tag),
            datetime.date(2012, 2, 29))

    def test_challenge_closed(self):
        open_tag = 'challenge:%s' % make_challenge_tag()
        closed_dt = datetime.date.today() - datetime.timedelta(days=32)
        closed_tag = 'challenge:%s' % closed_dt.strftime('%Y:%B').lower()
        assert not challenge_utils.challenge_closed([open_tag])
        assert challenge_utils.challenge_closed([closed_tag])

    def test_challenge_closed_model(self):
        s = save_valid_submission('hellow world')
        assert not s.challenge_closed()
        s.taggit_tags.set_ns('challenge:', make_challenge_tag())
        assert not s.challenge_closed()
        closed_dt = datetime.date.today() - datetime.timedelta(days=32)
        s.taggit_tags.set_ns('challenge:', closed_dt.strftime('%Y:%B').lower())
        assert s.challenge_closed()

    def test_derby_before_deadline(self):
        s = save_valid_submission('hello world')
        s.taggit_tags.set_ns('challenge:', make_challenge_tag())
        form = SubmissionEditForm(instance=s)
        assert 'demo_package' in form.fields
        assert 'challenge_tags' in form.fields

    def test_derby_after_deadline(self):
        s = save_valid_submission('hello world')
        closed_dt = datetime.date.today() - datetime.timedelta(days=32)
        s.taggit_tags.set_ns('challenge:', closed_dt.strftime('%Y:%B').lower())
        form = SubmissionEditForm(instance=s)
        assert 'demo_package' not in form.fields
        assert 'challenge_tags' not in form.fields

    @logged_in
    def test_derby_tag_saving(self):
        """
        There's some tricky bits in the handling of editing and saving
        challenge tags; this test just exercises a cycle of edit/save
        a couple times in a row to make sure we don't go foul in
        there.
        
        """
        s = save_valid_submission('hello world')
        closed_dt = datetime.date.today() - datetime.timedelta(days=32)
        s.taggit_tags.set_ns('challenge:', closed_dt.strftime('%Y:%B').lower())
        edit_url = reverse('demos_edit', args=[s.slug])
        r = self.client.get(edit_url)
        eq_(r.status_code, 200)

        r = self.client.post(edit_url,
                             data=dict(
                                 title=s.title,
                                 summary='This is a test demo submission',
                                 description='Some description goes here',
                                 tech_tags=(
                                     'tech:audio',
                                     'tech:video',
                                     'tech:websockets',
                                 ),
                                 license_name='gpl',
                                 accept_terms='1',
                             ))

        eq_(302, r.status_code)
        assert 'Location' in r
        assert s.slug in r['Location']

        r = self.client.get(edit_url)
        eq_(r.status_code, 200)

        r = self.client.post(edit_url,
                             data=dict(
                                 title=s.title,
                                 summary='This is a test demo submission',
                                 description='Some description goes here',
                                 tech_tags=(
                                     'tech:audio',
                                     'tech:video',
                                     'tech:websockets',
                                 ),
                                 license_name='gpl',
                                 accept_terms='1',
                             ))

        eq_(302, r.status_code)
        assert 'Location' in r
        assert s.slug in r['Location']

        r = self.client.get(edit_url)
        eq_(r.status_code, 200)

    @attr('bug702156')
    def test_bug_702156(self):
        """Demo with missing screenshots should not cause exceptions in
        views"""
        # Create the submission...
        s = save_valid_submission('hello world')
        s.taggit_tags.set_ns('tech:', 'javascript')
        s.featured = True
        s.save()

        # Ensure the new screenshot and thumbnail URL code works when there's a
        # screenshot present.
        try:
            r = self.client.get(reverse('demos_all'))
            r = self.client.get(reverse('demos_tag', args=['tech:javascript']))
            r = self.client.get(reverse('demos_detail', args=[s.slug]))
            r = self.client.get(reverse('demos_feed_recent', args=['atom']))
            r = self.client.get(reverse('demos_feed_featured', args=['json']))
        except:
            ok_(False, "No exceptions should have been thrown")

        # Forcibly delete the screenshot - should not be possible from
        # user-facing UI per form validation, but we should at least not throw
        # exceptions.
        s.screenshot_1.storage.delete(s.screenshot_1.name)
        s.screenshot_1 = None
        s.save()

        # Big bucks, no whammies...
        try:
            r = self.client.get(reverse('demos_all'))
            r = self.client.get(reverse('demos_tag', args=['tech:javascript']))
            r = self.client.get(reverse('demos_detail', args=[s.slug]))
            r = self.client.get(reverse('demos_feed_recent', args=['atom']))
            r = self.client.get(reverse('demos_feed_featured', args=['json']))
        except:
            ok_(False, "No exceptions should have been thrown")

    @attr('bug745902')
    def test_long_slug(self):
        """
        A title longer than 50 characters should truncate to a
        50-character slug during (python-level) save, not on DB
        insertion, so that anything that wants the slug to build a URL
        has the value that actually ends up in the DB.
        
        """
        s = save_valid_submission(
            "AudioVisualizer for Alternative Music Notation Systems")
        s.taggit_tags.set_ns('tech:', 'javascript')
        s.save()
        ok_(len(s.slug) == 50)
        r = self.client.get(reverse('demos.views.detail', args=(s.slug, )))
        ok_(r.status_code == 200)

    @attr('bug781823')
    def test_unicode(self):
        """
        Unicode characters in the summary or description doesn't brick the feed.
        
        """
        s = save_valid_submission('ΦOTOS ftw', 'ΦOTOS ΦOTOS ΦOTOS')
        s.featured = 1
        s.save()
        r = self.client.get(reverse('demos_feed_featured', args=['json']))
        ok_(r.status_code == 200)

    def test_make_unique_slug(self):
        """
        Ensure that unique slugs are generated even from titles whose
        first 50 characters are identical.
        
        """
        s = save_valid_submission(
            "This is a really long title whose only purpose in life is to be longer than fifty characters"
        )
        s2 = save_valid_submission(
            "This is a really long title whose only purpose in life is to be longer than fifty characters and not the same as the first title"
        )
        s3 = save_valid_submission(
            "This is a really long title whose only purpose in life is to be longer than fifty characters and not the same as the first or second title"
        )
        ok_(s.slug != s2.slug and s.slug != s3.slug and s2.slug != s3.slug)
Ejemplo n.º 53
0
    def test_review_tags(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        """Review tags can be managed on document revisions"""
        client = LocalizingClient()
        client.login(username='******', password='******')

        # Create a new doc with one review tag
        data = new_document_data()
        data.update({'review_tags': ['technical']})
        response = client.post(reverse('wiki.new_document'), data)

        # Ensure there's now a doc with that expected tag in its newest
        # revision
        doc = Document.objects.get(slug="a-test-article")
        rev = doc.revisions.order_by('-id').all()[0]
        review_tags = [x.name for x in rev.review_tags.all()]
        eq_(['technical'], review_tags)

        # Now, post an update with two tags
        data.update({
            'form': 'rev',
            'review_tags': ['editorial', 'technical'],
        })
        response = client.post(reverse('wiki.edit_document', args=[doc.slug]),
                               data)

        # Ensure the doc's newest revision has both tags.
        doc = Document.objects.get(slug="a-test-article")
        rev = doc.revisions.order_by('-id').all()[0]
        review_tags = [x.name for x in rev.review_tags.all()]
        review_tags.sort()
        eq_(['editorial', 'technical'], review_tags)

        # Now, ensure that warning boxes appear for the review tags.
        response = client.get(reverse('wiki.document', args=[doc.slug]), data)
        page = pq(response.content)
        eq_(1, page.find('.warning.review-technical').length)
        eq_(1, page.find('.warning.review-editorial').length)

        # Ensure the page appears on the listing pages
        response = client.get(reverse('wiki.list_review'))
        eq_(
            1,
            pq(response.content).find("ul.documents li a:contains('%s')" %
                                      doc.title).length)
        response = client.get(
            reverse('wiki.list_review_tag', args=('technical', )))
        eq_(
            1,
            pq(response.content).find("ul.documents li a:contains('%s')" %
                                      doc.title).length)
        response = client.get(
            reverse('wiki.list_review_tag', args=('editorial', )))
        eq_(
            1,
            pq(response.content).find("ul.documents li a:contains('%s')" %
                                      doc.title).length)

        # Also, ensure that the page appears in the proper feeds
        # HACK: Too lazy to parse the XML. Lazy lazy.
        response = client.get(
            reverse('wiki.feeds.list_review', args=('atom', )))
        ok_('<entry><title>%s</title>' % doc.title in response.content)
        response = client.get(
            reverse('wiki.feeds.list_review_tag', args=(
                'atom',
                'technical',
            )))
        ok_('<entry><title>%s</title>' % doc.title in response.content)
        response = client.get(
            reverse('wiki.feeds.list_review_tag', args=(
                'atom',
                'editorial',
            )))
        ok_('<entry><title>%s</title>' % doc.title in response.content)

        # Post an edit that removes one of the tags.
        data.update({
            'form': 'rev',
            'review_tags': [
                'editorial',
            ],
        })
        response = client.post(reverse('wiki.edit_document', args=[doc.slug]),
                               data)

        # Ensure only one of the tags' warning boxes appears, now.
        response = client.get(reverse('wiki.document', args=[doc.slug]), data)
        page = pq(response.content)
        eq_(0, page.find('.warning.review-technical').length)
        eq_(1, page.find('.warning.review-editorial').length)

        # Ensure the page appears on the listing pages
        response = client.get(reverse('wiki.list_review'))
        eq_(
            1,
            pq(response.content).find("ul.documents li a:contains('%s')" %
                                      doc.title).length)
        response = client.get(
            reverse('wiki.list_review_tag', args=('technical', )))
        eq_(
            0,
            pq(response.content).find("ul.documents li a:contains('%s')" %
                                      doc.title).length)
        response = client.get(
            reverse('wiki.list_review_tag', args=('editorial', )))
        eq_(
            1,
            pq(response.content).find("ul.documents li a:contains('%s')" %
                                      doc.title).length)

        # Also, ensure that the page appears in the proper feeds
        # HACK: Too lazy to parse the XML. Lazy lazy.
        response = client.get(
            reverse('wiki.feeds.list_review', args=('atom', )))
        ok_('<entry><title>%s</title>' % doc.title in response.content)
        response = client.get(
            reverse('wiki.feeds.list_review_tag', args=(
                'atom',
                'technical',
            )))
        ok_('<entry><title>%s</title>' % doc.title not in response.content)
        response = client.get(
            reverse('wiki.feeds.list_review_tag', args=(
                'atom',
                'editorial',
            )))
        ok_('<entry><title>%s</title>' % doc.title in response.content)
Ejemplo n.º 54
0
    def test_midair_section_collision(self):
        """If both a revision and the edited section has changed, then a
        section edit is a collision."""
        client = LocalizingClient()
        client.login(username='******', password='******')

        doc, rev = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace_1 = """
            <h1 id="s2">replace</h1>
            <p>replace</p>
        """
        replace_2 = """
            <h1 id="s2">first replace</h1>
            <p>first replace</p>
        """
        data = {'form': 'rev', 'content': rev.content}

        # Edit #1 starts...
        resp = client.get('%s?section=s2' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id1 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 starts...
        resp = client.get('%s?section=s2' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id2 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 submits successfully
        data.update({
            'form': 'rev',
            'content': replace_2,
            'current_rev': rev_id2
        })
        resp = client.post(
            '%s?section=s2&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        eq_(302, resp.status_code)

        # Edit #1 submits, but since it's the same section, there's a collision
        data.update({
            'form': 'rev',
            'content': replace_1,
            'current_rev': rev_id1
        })
        resp = client.post(
            '%s?section=s2&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        # With the raw API, we should get a 409 Conflict on collision.
        eq_(409, resp.status_code)
Ejemplo n.º 55
0
    def test_midair_section_merge(self):
        """If a page was changed while someone was editing, but the changes
        didn't affect the specific section being edited, then ignore the midair
        warning"""
        client = LocalizingClient()
        client.login(username='******', password='******')

        doc, rev = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace_1 = """
            <h1 id="s1">replace</h1>
            <p>replace</p>
        """
        replace_2 = """
            <h1 id="s2">replace</h1>
            <p>replace</p>
        """
        expected = """
            <h1 id="s1">replace</h1>
            <p>replace</p>

            <h1 id="s2">replace</h1>
            <p>replace</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """
        data = {'form': 'rev', 'content': rev.content}

        # Edit #1 starts...
        resp = client.get('%s?section=s1' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id1 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 starts...
        resp = client.get('%s?section=s2' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id2 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 submits successfully
        data.update({
            'form': 'rev',
            'content': replace_2,
            'current_rev': rev_id2
        })
        resp = client.post(
            '%s?section=s2&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        eq_(302, resp.status_code)

        # Edit #1 submits, but since it's a different section, there's no
        # mid-air collision
        data.update({
            'form': 'rev',
            'content': replace_1,
            'current_rev': rev_id1
        })
        resp = client.post(
            '%s?section=s1&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        # No conflict, but we should get a 205 Reset as an indication that the
        # page needs a refresh.
        eq_(205, resp.status_code)

        # Finally, make sure that all the edits landed
        response = client.get('%s?raw=true' %
                              reverse('wiki.document', args=[doc.slug]))
        eq_(normalize_html(expected), normalize_html(response.content))

        # Also, ensure that the revision is slipped into the headers
        eq_(unicode(Document.uncached.get(slug=doc.slug).current_revision.id),
            unicode(response['x-kuma-revision']))
Ejemplo n.º 56
0
class LoginTestCase(TestCase):
    fixtures = ['test_users.json']

    def setUp(self):
        self.old_debug = settings.DEBUG
        settings.DEBUG = True
        self.client = LocalizingClient()
        self.client.logout()

    def tearDown(self):
        settings.DEBUG = self.old_debug

    @mock.patch_object(Site.objects, 'get_current')
    def test_bad_login_fails_both_backends(self, get_current):
        get_current.return_value.domain = 'dev.mo.org'
        self.assertRaises(User.DoesNotExist,
                          User.objects.get,
                          username='******')

        response = self.client.post(reverse('users.login'), {
            'username': '******',
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)
        self.assertContains(response, 'Please enter a correct username and '
                            'password.')

    @mock.patch_object(Site.objects, 'get_current')
    def test_django_login(self, get_current):
        get_current.return_value.domain = 'dev.mo.org'

        response = self.client.post(reverse('users.login'), {
            'username': '******',
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('testuser', doc.find('ul.user-state a:first').text())

    @mock.patch_object(Site.objects, 'get_current')
    def test_django_login_wont_redirect_to_login(self, get_current):
        get_current.return_value.domain = 'dev.mo.org'
        login_uri = reverse('users.login')

        response = self.client.post(login_uri, {
            'username': '******',
            'password': '******',
            'next': login_uri
        },
                                    follow=True)
        eq_(200, response.status_code)
        for redirect_url, code in response.redirect_chain:
            ok_(login_uri not in redirect_url,
                "Found %s in redirect_chain" % login_uri)
        doc = pq(response.content)
        eq_('testuser', doc.find('ul.user-state a:first').text())

    @mock.patch_object(Site.objects, 'get_current')
    def test_logged_in_message(self, get_current):
        get_current.return_value.domain = 'dev.mo.org'
        login_uri = reverse('users.login')

        response = self.client.post(login_uri, {
            'username': '******',
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)
        response = self.client.get(login_uri, follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_("You are already logged in.", doc.find('div#content-main').text())

    @mock.patch_object(Site.objects, 'get_current')
    def test_django_login_redirects_to_next(self, get_current):
        get_current.return_value.domain = 'dev.mo.org'
        login_uri = reverse('users.login')

        response = self.client.post(login_uri, {
            'username': '******',
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)
        response = self.client.get(login_uri, {'next': '/en-US/demos/submit'},
                                   follow=True)
        eq_('http://testserver/en-US/demos/submit',
            response.redirect_chain[0][0])

    @mock.patch('dekicompat.backends.DekiUserBackend.mindtouch_login')
    def test_mindtouch_disabled_login(self, mock_mindtouch_login):
        """When DEKIWIKI_ENDPOINT unavailable, skip MindTouch auth."""
        # HACK: mock has an assert_called_with, but I want something like
        # never_called or call_count. Instead, I have this:
        trap = {'was_called': False}

        def my_mindtouch_login(username, password, force=False):
            trap['was_called'] = True
            return False

        mock_mindtouch_login.side_effect = my_mindtouch_login

        # Try to log in as a MindTouch user, assert that MindTouch auth was
        # never attempted.
        _old = settings.DEKIWIKI_ENDPOINT
        settings.DEKIWIKI_ENDPOINT = False
        self.client.post(reverse('users.login'), {
            'username': '******',
            'password': '******'
        },
                         follow=True)
        settings.DEKIWIKI_ENDPOINT = _old

        ok_(not trap['was_called'])

    @mock_mindtouch_login
    @mock_get_deki_user
    @mock_put_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_mindtouch_creds_create_user_and_profile(self, get_current):
        if not settings.DEKIWIKI_ENDPOINT:
            # Don't even bother with this test, if there's no MindTouch API
            raise SkipTest()

        get_current.return_value.domain = 'dev.mo.org'

        if not getattr(settings, 'DEKIWIKI_MOCK', False):
            # HACK: Ensure that expected user details are in MindTouch when not
            # mocking the API
            mt_email = '*****@*****.**'
            user_xml = MINDTOUCH_USER_XML % dict(username="******",
                                                 email=mt_email,
                                                 fullname="None",
                                                 status="active",
                                                 language="",
                                                 timezone="-08:00",
                                                 role="Contributor")
            DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount',
                                               user_xml=user_xml)
            passwd_url = '%s/@api/deki/users/%s/password?apikey=%s' % (
                settings.DEKIWIKI_ENDPOINT, '=testaccount',
                settings.DEKIWIKI_APIKEY)
            requests.put(passwd_url, data='theplanet')

        self.assertRaises(User.DoesNotExist,
                          User.objects.get,
                          username='******')

        # Try to log in as a MindTouch user
        response = self.client.post(reverse('users.login'), {
            'username': '******',
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)

        # Ensure there are no validation errors
        page = pq(response.content)
        eq_(0,
            page.find('.errorlist').length,
            "There should be no validation errors in login")

        # Login should have auto-created django user
        u = User.objects.get(username='******')
        eq_(True, u.is_active)
        ok_(u.get_profile())

        # Login page should show welcome back
        doc = pq(response.content)
        eq_('testaccount', doc.find('ul.user-state a:first').text())

    @mock.patch_object(Site.objects, 'get_current')
    def test_clean_next_url_request_properties(self, get_current):
        '''_clean_next_url checks POST, GET, and REFERER'''
        get_current.return_value.domain = 'dev.mo.org'

        r = RequestFactory().get('/users/login', {'next': '/demos/submit'},
                                 HTTP_REFERER='referer-trumped-by-get')
        eq_('/demos/submit', _clean_next_url(r))
        r = RequestFactory().post('/users/login', {'next': '/demos/submit'})
        eq_('/demos/submit', _clean_next_url(r))
        r = RequestFactory().get('/users/login', HTTP_REFERER='/demos/submit')
        eq_('/demos/submit', _clean_next_url(r))

    @mock.patch_object(Site.objects, 'get_current')
    def test_clean_next_url_no_self_redirects(self, get_current):
        '''_clean_next_url checks POST, GET, and REFERER'''
        get_current.return_value.domain = 'dev.mo.org'

        for next in [settings.LOGIN_URL, settings.LOGOUT_URL]:
            r = RequestFactory().get('/users/login', {'next': next})
            eq_(None, _clean_next_url(r))

    @mock.patch_object(Site.objects, 'get_current')
    def test_clean_next_url_invalid_next_parameter(self, get_current):
        '''_clean_next_url cleans invalid urls'''
        get_current.return_value.domain = 'dev.mo.org'

        for next in self._invalid_nexts():
            r = RequestFactory().get('/users/login', {'next': next})
            eq_(None, _clean_next_url(r))

    @mock.patch_object(Site.objects, 'get_current')
    def test_login_invalid_next_parameter(self, get_current):
        '''Test with an invalid ?next=http://example.com parameter.'''
        get_current.return_value.domain = 'testserver.com'
        valid_next = reverse('home', locale=settings.LANGUAGE_CODE)

        for invalid_next in self._invalid_nexts():
            # Verify that _valid_ next parameter is set in form hidden field.
            response = self.client.get(
                urlparams(reverse('users.login'), next=invalid_next))
            eq_(200, response.status_code)
            doc = pq(response.content)
            eq_(valid_next, doc('input[name="next"]')[0].attrib['value'])

            # Verify that it gets used on form POST.
            response = self.client.post(
                reverse('users.login'), {
                    'username': '******',
                    'password': '******',
                    'next': invalid_next
                })
            eq_(302, response.status_code)
            eq_('http://testserver' + valid_next, response['location'])
            self.client.logout()

    def _invalid_nexts(self):
        return ['http://foobar.com/evil/', '//goo.gl/y-bad']
Ejemplo n.º 57
0
class BrowserIDTestCase(TestCase):
    fixtures = ['test_users.json']

    def setUp(self):
        # Ensure @ssl_required goes unenforced.
        settings.DEBUG = True
        # Set up some easily-testable redirects.
        settings.LOGIN_REDIRECT_URL = 'SUCCESS'
        settings.LOGIN_REDIRECT_URL_FAILURE = 'FAILURE'
        # BrowserID will squawk if this isn't set
        settings.SITE_URL = 'http://testserver'
        self.client = LocalizingClient()

    def test_invalid_post(self):
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'))
        eq_(302, resp.status_code)
        ok_('FAILURE' in resp['Location'])

    @mock.patch('users.views._verify_browserid')
    def test_invalid_assertion(self, _verify_browserid):
        _verify_browserid.return_value = None

        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'bad data'})
        eq_(302, resp.status_code)
        ok_('FAILURE' in resp['Location'])

    @mock_get_deki_user_by_email
    @mock_put_mindtouch_user
    @mock_mindtouch_login
    @mock.patch('users.views._verify_browserid')
    def test_valid_assertion_with_django_user(self, _verify_browserid):
        _verify_browserid.return_value = {'email': '*****@*****.**'}

        # Posting the fake assertion to browserid_verify should work, with the
        # actual verification method mocked out.
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        eq_(302, resp.status_code)
        ok_('SUCCESS' in resp['Location'])

        # The session should look logged in, now.
        ok_('_auth_user_id' in self.client.session.keys())
        eq_('django_browserid.auth.BrowserIDBackend',
            self.client.session.get('_auth_user_backend', ''))

    @mock_get_deki_user_by_email
    @mock_put_mindtouch_user
    @mock_mindtouch_login
    @mock.patch('users.views._verify_browserid')
    def test_explain_popup(self, _verify_browserid):
        _verify_browserid.return_value = {'email': '*****@*****.**'}
        resp = self.client.get(reverse('home', locale='en-US'))

        # Posting the fake assertion to browserid_verify should work, with the
        # actual verification method mocked out.
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        eq_('1', resp.cookies.get('browserid_explained').value)

        resp = self.client.get(reverse('users.logout'), locale='en-US')

        # even after logout, cookie should prevent the toggle
        resp = self.client.get(reverse('home', locale='en-US'))
        eq_('1', self.client.cookies.get('browserid_explained').value)

    @mock_get_deki_user_by_email
    @mock_put_mindtouch_user
    @mock_mindtouch_login
    @mock.patch('users.views._verify_browserid')
    def test_valid_assertion_with_mindtouch_user(self, _verify_browserid):
        if not settings.DEKIWIKI_ENDPOINT:
            # Don't even bother with this test, if there's no MindTouch API
            raise SkipTest()

        mt_email = '*****@*****.**'
        _verify_browserid.return_value = {'email': mt_email}

        # Probably overkill but let's be sure we're testing the right thing.
        try:
            User.objects.get(email=mt_email)
            ok_(False, "The MindTouch user shouldn't exist in Django yet.")
        except User.DoesNotExist:
            pass

        if not getattr(settings, 'DEKIWIKI_MOCK', False):
            # HACK: Ensure that expected user details are in MindTouch when not
            # mocking the API
            user_xml = MINDTOUCH_USER_XML % dict(username="******",
                                                 email=mt_email,
                                                 fullname="None",
                                                 status="active",
                                                 language="",
                                                 timezone="-08:00",
                                                 role="Contributor")
            DekiUserBackend.put_mindtouch_user(deki_user_id='=testaccount',
                                               user_xml=user_xml)

        deki_user = DekiUserBackend.get_deki_user_by_email(mt_email)
        ok_(deki_user is not None, "The MindTouch user should exist")

        # Posting the fake assertion to browserid_verify should work, with the
        # actual verification method mocked out.
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        eq_(302, resp.status_code)
        ok_('SUCCESS' in resp['Location'])

        # The session should look logged in, now.
        ok_('_auth_user_id' in self.client.session.keys())
        eq_('django_browserid.auth.BrowserIDBackend',
            self.client.session.get('_auth_user_backend', ''))

        # And, after all the above, there should be a Django user now.
        try:
            User.objects.get(email=mt_email)
        except User.DoesNotExist:
            ok_(False, "The MindTouch user should exist in Django now.")

    @attr('current')
    @mock.patch('dekicompat.backends.DekiUserBackend.get_deki_user_by_email')
    @mock.patch('users.views._verify_browserid')
    def test_valid_assertion_with_mt_disabled(self, _verify_browserid,
                                              mock_get_deki_user_by_email):
        """On valid browserid assertion, when Django user is not found, yet
        MindTouch API disabled, there should be no attempt to look the user up
        in MindTouch"""
        mt_email = '*****@*****.**'
        _verify_browserid.return_value = {'email': mt_email}

        # HACK: mock has an assert_called_with, but I want something like
        # never_called or call_count. Instead, I have this:
        trap = {'was_called': False}

        def my_get_deki_user_by_email(email):
            trap['was_called'] = True
            return False

        mock_get_deki_user_by_email.side_effect = my_get_deki_user_by_email

        _old = settings.DEKIWIKI_ENDPOINT
        settings.DEKIWIKI_ENDPOINT = False
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        settings.DEKIWIKI_ENDPOINT = _old

        # This should end up being a redirect to register
        eq_(302, resp.status_code)
        ok_('browserid_register' in resp['Location'])

        ok_(not trap['was_called'])

    @mock_missing_get_deki_user_by_email
    @mock_missing_get_deki_user
    @mock_post_mindtouch_user
    @mock_put_mindtouch_user
    @mock_mindtouch_login
    @mock.patch('users.views._verify_browserid')
    def test_valid_assertion_with_new_account_creation(self,
                                                       _verify_browserid):
        new_username = '******'
        new_email = '*****@*****.**'
        _verify_browserid.return_value = {'email': new_email}

        try:
            user = User.objects.get(email=new_email)
            ok_(False, "User for email should not yet exist")
        except User.DoesNotExist:
            pass

        if not getattr(settings, 'DEKIWIKI_MOCK', False):
            # HACK: When not mocking the MindTouch API, ensure that there's no
            # leftover user with the same name & email as what we want to
            # register
            import random
            rand_num = random.randint(0, 1000000)
            user_xml = MINDTOUCH_USER_XML % dict(username="******" %
                                                 (new_username, rand_num),
                                                 email="%s_%s" %
                                                 (rand_num, new_email),
                                                 fullname="",
                                                 status="inactive",
                                                 language="",
                                                 timezone="-08:00",
                                                 role="Contributor")
            DekiUserBackend.put_mindtouch_user(deki_user_id='=%s' %
                                               new_username,
                                               user_xml=user_xml)

        # Sign in with a verified email, but with no existing account
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        eq_(302, resp.status_code)

        # This should be a redirect to the BrowserID registration page.
        redir_url = resp['Location']
        reg_url = reverse('users.browserid_register', locale='en-US')
        ok_(reg_url in redir_url)

        # And, as part of the redirect, the verified email address should be in
        # our session now.
        ok_(SESSION_VERIFIED_EMAIL in self.client.session.keys())
        verified_email = self.client.session[SESSION_VERIFIED_EMAIL]
        eq_(new_email, verified_email)

        # Grab the redirect, assert that there's a create_user form present
        resp = self.client.get(redir_url)
        page = pq(resp.content)
        form = page.find('form#create_user')
        eq_(1, form.length)

        # There should be no error lists on first load
        eq_(0, page.find('.errorlist').length)

        # Submit the create_user form, with a chosen username
        resp = self.client.post(redir_url, {
            'username': '******',
            'action': 'register'
        })

        # The submission should result in a redirect to the session's redirect
        # value
        eq_(302, resp.status_code)
        redir_url = resp['Location']
        ok_('SUCCESS' in redir_url)

        # The session should look logged in, now.
        ok_('_auth_user_id' in self.client.session.keys())
        eq_('django_browserid.auth.BrowserIDBackend',
            self.client.session.get('_auth_user_backend', ''))

        if settings.DEKIWIKI_ENDPOINT:
            ok_(self.client.cookies.get('authtoken'), 'Should have set '
                'authtoken cookie for '
                'MindTouch')

        # Ensure that the user was created, and with the submitted username and
        # verified email address
        try:
            user = User.objects.get(email=new_email)
            eq_(new_username, user.username)
            eq_(new_email, user.email)
        except User.DoesNotExist:
            ok_(False, "New user should have been created")

    @mock_missing_get_deki_user_by_email
    @mock_post_mindtouch_user
    @mock_put_mindtouch_user
    @mock_mindtouch_login
    @mock_get_deki_user
    @mock.patch('users.views._verify_browserid')
    def test_valid_assertion_with_existing_account_login(
            self, _verify_browserid):
        """ Removed the existing user form: we don't auth the password with
        MindTouch anymore """
        new_email = '*****@*****.**'
        _verify_browserid.return_value = {'email': new_email}

        try:
            User.objects.get(email=new_email)
            ok_(False, "User for email should not yet exist")
        except User.DoesNotExist:
            pass

        # Sign in with a verified email, but with no existing account
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        eq_(302, resp.status_code)

        # This should be a redirect to the BrowserID registration page.
        redir_url = resp['Location']
        reg_url = reverse('users.browserid_register', locale='en-US')
        ok_(reg_url in redir_url)

        # And, as part of the redirect, the verified email address should be in
        # our session now.
        ok_(SESSION_VERIFIED_EMAIL in self.client.session.keys())
        verified_email = self.client.session[SESSION_VERIFIED_EMAIL]
        eq_(new_email, verified_email)

        # Grab the redirect, assert that there's a create_user form present
        resp = self.client.get(redir_url)
        page = pq(resp.content)
        form = page.find('form#existing_user')
        eq_(0, form.length)

    @mock.patch('dekicompat.backends.DekiUserBackend.mindtouch_login')
    @mock.patch('users.views._verify_browserid')
    def test_mindtouch_disabled_redirect_login(self, _verify_browserid,
                                               mock_mindtouch_login):
        """When DEKIWIKI_ENDPOINT unavailable, skip MindTouch auth."""
        _verify_browserid.return_value = {'email': '*****@*****.**'}

        # HACK: mock has an assert_called_with, but I want something like
        # never_called or call_count. Instead, I have this:
        trap = {'was_called': False}

        def my_mindtouch_login(username, password, force=False):
            trap['was_called'] = True
            return False

        mock_mindtouch_login.side_effect = my_mindtouch_login

        _old = settings.DEKIWIKI_ENDPOINT
        settings.DEKIWIKI_ENDPOINT = False
        resp = self.client.post(
            reverse('users.browserid_verify', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        settings.DEKIWIKI_ENDPOINT = _old

        eq_(302, resp.status_code)
        ok_('SUCCESS' in resp['Location'])

        # The session should look logged in, now.
        ok_('_auth_user_id' in self.client.session.keys())
        eq_('django_browserid.auth.BrowserIDBackend',
            self.client.session.get('_auth_user_backend', ''))

        ok_(not trap['was_called'])

    @mock_get_deki_user_by_email
    @mock_put_mindtouch_user
    @mock_mindtouch_login
    @mock.patch('users.views._verify_browserid')
    def test_valid_assertion_changing_email(self, _verify_browserid):
        # just need to be authenticated, not necessarily BrowserID
        self.client.login(username='******', password='******')

        _verify_browserid.return_value = {'email': '*****@*****.**'}

        resp = self.client.post(
            reverse('users.browserid_change_email', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        eq_(302, resp.status_code)
        ok_('profiles/testuser/edit' in resp['Location'])

        resp = self.client.get(
            reverse('devmo_profile_edit', locale='en-US', args=[
                'testuser',
            ]))
        eq_(200, resp.status_code)
        doc = pq(resp.content)
        ok_('*****@*****.**' in doc.find('li#field_email').text())

    @mock_get_deki_user_by_email
    @mock_put_mindtouch_user
    @mock_mindtouch_login
    @mock.patch('users.views._verify_browserid')
    def test_valid_assertion_doesnt_steal_email(self, _verify_browserid):
        # just need to be authenticated, not necessarily BrowserID
        self.client.login(username='******', password='******')

        _verify_browserid.return_value = {'email': '*****@*****.**'}

        # doesn't change email if the new email already belongs to another user
        resp = self.client.post(
            reverse('users.browserid_change_email', locale='en-US'),
            {'assertion': 'PRETENDTHISISVALID'})
        eq_(302, resp.status_code)
        ok_('change_email' in resp['Location'])

        resp = self.client.get(
            reverse('devmo_profile_edit', locale='en-US', args=[
                'testuser',
            ]))
        eq_(200, resp.status_code)
        doc = pq(resp.content)
        ok_('*****@*****.**' in doc.find('li#field_email').text())
Ejemplo n.º 58
0
class ChangeEmailTestCase(TestCase):
    fixtures = ['test_users.json']

    def setUp(self):
        self.client = LocalizingClient()

    @mock.patch_object(Site.objects, 'get_current')
    def test_user_change_email(self, get_current):
        """Send email to change user's email and then change it."""
        get_current.return_value.domain = 'su.mo.com'

        self.client.login(username='******', password='******')
        # Attempt to change email.
        response = self.client.post(reverse('users.change_email'),
                                    {'email': '*****@*****.**'},
                                    follow=True)
        eq_(200, response.status_code)

        # Be notified to click a confirmation link.
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        ec = EmailChange.objects.all()[0]
        assert ec.activation_key in mail.outbox[0].body
        eq_('*****@*****.**', ec.email)

        # Visit confirmation link to change email.
        response = self.client.get(
            reverse('users.confirm_email', args=[ec.activation_key]))
        eq_(200, response.status_code)
        u = User.objects.get(username='******')
        eq_('*****@*****.**', u.email)

    @mock_get_deki_user
    @mock_put_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_user_change_email_updates_mindtouch(self, get_current):
        """Send email to change user's email and then change it."""
        get_current.return_value.domain = 'su.mo.com'

        self.client.login(username='******', password='******')
        # Attempt to change email.
        response = self.client.post(reverse('users.change_email'),
                                    {'email': '*****@*****.**'},
                                    follow=True)
        eq_(200, response.status_code)

        # Be notified to click a confirmation link.
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        ec = EmailChange.objects.all()[0]
        assert ec.activation_key in mail.outbox[0].body
        eq_('*****@*****.**', ec.email)

        # Visit confirmation link to change email.
        response = self.client.get(
            reverse('users.confirm_email', args=[ec.activation_key]))
        eq_(200, response.status_code)
        u = User.objects.get(username='******')
        eq_('*****@*****.**', u.email)

        if not settings.DEKIWIKI_MOCK:
            deki_id = u.get_profile().deki_user_id
            doc = get_deki_user_doc(u)
            eq_(str(deki_id), doc('user').attr('id'))
            eq_('*****@*****.**',
                doc('user').find('email').text())

    def test_user_change_email_same(self):
        """Changing to same email shows validation error."""
        self.client.login(username='******', password='******')
        user = User.objects.get(username='******')
        user.email = '*****@*****.**'
        user.save()
        response = self.client.post(reverse('users.change_email'),
                                    {'email': user.email})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('This is your current email.', doc('ul.errorlist').text())

    def test_user_change_email_duplicate(self):
        """Changing to same email shows validation error."""
        self.client.login(username='******', password='******')
        email = '*****@*****.**'
        response = self.client.post(reverse('users.change_email'),
                                    {'email': email})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('A user with that email address already exists.',
            doc('ul.errorlist').text())

    @mock.patch_object(Site.objects, 'get_current')
    def test_user_confirm_email_duplicate(self, get_current):
        """If we detect a duplicate email when confirming an email change,
        don't change it and notify the user."""
        get_current.return_value.domain = 'su.mo.com'
        self.client.login(username='******', password='******')
        old_email = User.objects.get(username='******').email
        new_email = '*****@*****.**'
        response = self.client.post(reverse('users.change_email'),
                                    {'email': new_email})
        eq_(200, response.status_code)
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        ec = EmailChange.objects.all()[0]

        # Before new email is confirmed, give the same email to a user
        other_user = User.objects.filter(username='******')[0]
        other_user.email = new_email
        other_user.save()

        # Visit confirmation link and verify email wasn't changed.
        response = self.client.get(
            reverse('users.confirm_email', args=[ec.activation_key]))
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('Unable to change email for user testuser', doc('.main h1').text())
        u = User.objects.get(username='******')
        eq_(old_email, u.email)