Exemplo n.º 1
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)
Exemplo n.º 2
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)
Exemplo n.º 3
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)
Exemplo n.º 4
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)
Exemplo n.º 5
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')
    @mock_fetch_user_feed
    def test_profile_view(self):
        """A user profile can be viewed"""
        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)
        doc = pq(r.content)

        eq_(profile.user.username,
            doc.find('#profile-head.vcard .nickname').text())
        eq_(profile.fullname,
            doc.find('#profile-head.vcard .fn').text())
        eq_(profile.title,
            doc.find('#profile-head.vcard .title').text())
        eq_(profile.organization,
            doc.find('#profile-head.vcard .org').text())
        eq_(profile.location,
            doc.find('#profile-head.vcard .loc').text())
        eq_('IRC: ' + profile.irc_nickname,
            doc.find('#profile-head.vcard .irc').text())
        eq_(profile.bio,
            doc.find('#profile-head.vcard .bio').text())

        # There should be 15 doc activity items in the page.
        feed_trs = doc.find('#docs-activity table.activity tbody tr')
        eq_(15, feed_trs.length)

        # Check to find all the items expected from the feed
        feed = UserDocsActivityFeed(username="******")
        for idx in range(0, 15):
            item = feed.items[idx]
            item_el = feed_trs.eq(idx)
            eq_(item.current_title, item_el.find('h3').text())
            eq_(item.view_url, item_el.find('h3 a').attr('href'))
            if item.edit_url:
                eq_(item.edit_url,
                    item_el.find('.actions a.edit').attr('href'))
            if item.diff_url:
                eq_(item.diff_url,
                    item_el.find('.actions a.diff').attr('href'))
            if item.history_url:
                eq_(item.history_url,
                    item_el.find('.actions a.history').attr('href'))

    @mock_put_mindtouch_user
    @mock_fetch_user_feed
    def test_bug_698971(self):
        """A non-numeric page number should not cause an error"""
        (user, deki_user, profile) = create_profile()

        url = '%s?page=asdf' % reverse('devmo.views.profile_view',
                                       args=(user.username,))

        try:
            self.client.get(url, follow=True)
        except PageNotAnInteger:
            ok_(False, "Non-numeric page number should not cause an error")

    @mock_put_mindtouch_user
    @mock_fetch_user_feed
    def test_profile_edit(self):
        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)
        doc = pq(r.content)
        eq_(0, doc.find('#profile-head .edit .button').length)

        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_view',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        edit_button = doc.find('#profile-head .edit .button')
        eq_(1, edit_button.length)

        url = edit_button.attr('href')
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        eq_(profile.fullname,
            doc.find('#profile-edit input[name="fullname"]').val())
        eq_(profile.title,
            doc.find('#profile-edit input[name="title"]').val())
        eq_(profile.organization,
            doc.find('#profile-edit input[name="organization"]').val())
        eq_(profile.location,
            doc.find('#profile-edit input[name="location"]').val())
        eq_(profile.irc_nickname,
            doc.find('#profile-edit input[name="irc_nickname"]').val())

        new_attrs = dict(
            email="*****@*****.**",
            fullname="Another Name",
            title="Another title",
            organization="Another org",
        )

        r = self.client.post(url, new_attrs, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('#profile-head').length)
        eq_(new_attrs['fullname'],
            doc.find('#profile-head .main .fn').text())
        eq_(new_attrs['title'],
            doc.find('#profile-head .info .title').text())
        eq_(new_attrs['organization'],
            doc.find('#profile-head .info .org').text())

        profile = UserProfile.objects.get(user__username=user.username)
        eq_(new_attrs['fullname'], profile.fullname)
        eq_(new_attrs['title'], profile.title)
        eq_(new_attrs['organization'], profile.organization)

    @mock_put_mindtouch_user
    @mock_fetch_user_feed
    def test_profile_edit_websites(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_sites = {
            u'website': u'http://example.com/',
            u'twitter': u'http://twitter.com/lmorchard',
            u'github': u'http://github.com/lmorchard',
            u'stackoverflow': u'http://stackoverflow.com/users/lmorchard',
        }

        # Scrape out the existing significant form field values.
        form = dict()
        for fn in ('email', 'fullname', 'title', 'organization', 'location',
                   'irc_nickname', 'bio', 'interests'):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        form['email'] = '*****@*****.**'

        # Fill out the form with websites.
        form.update(dict(('websites_%s' % k, v)
                    for k, v in test_sites.items()))

        # Submit the form, verify redirect to profile detail
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        # Verify the websites are saved in the profile.
        eq_(test_sites, p.websites)

        # Verify the saved websites appear in the editing form
        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        for k, v in test_sites.items():
            eq_(v, doc.find('#profile-edit *[name="websites_%s"]' % k).val())

        # Come up with some bad sites, either invalid URL or bad URL prefix
        bad_sites = {
            u'website': u'HAHAHA WHAT IS A WEBSITE',
            u'twitter': u'http://facebook.com/lmorchard',
            u'stackoverflow': u'http://overqueueblah.com/users/lmorchard',
        }
        form.update(dict(('websites_%s' % k, v)
                    for k, v in bad_sites.items()))

        # Submit the form, verify errors for all of the bad sites
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-edit').length)
        tmpl = '#profile-edit #elsewhere .%s .errorlist'
        for n in ('website', 'twitter', 'stackoverflow'):
            eq_(1, doc.find(tmpl % n).length)

    @mock_put_mindtouch_user
    @mock_fetch_user_feed
    def test_profile_edit_interests(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = ['javascript', 'css', 'canvas', 'html', 'homebrewing']

        form = dict()
        for fn in ('email', 'fullname', 'title', 'organization', 'location',
                'irc_nickname', 'bio', 'interests'):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        form['email'] = '*****@*****.**'

        form['interests'] = ', '.join(test_tags)

        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        result_tags = [t.name.replace('profile:interest:', '')
                for t in p.tags.all_ns('profile:interest:')]
        result_tags.sort()
        test_tags.sort()
        eq_(test_tags, result_tags)

        test_expertise = ['css', 'canvas']
        form['expertise'] = ', '.join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        result_tags = [t.name.replace('profile:expertise:', '')
                for t in p.tags.all_ns('profile:expertise')]
        result_tags.sort()
        test_expertise.sort()
        eq_(test_expertise, result_tags)

        # Now, try some expertise tags not covered in interests
        test_expertise = ['css', 'canvas', 'mobile', 'movies']
        form['expertise'] = ', '.join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('.error #id_expertise').length)

    @mock_put_mindtouch_user
    @mock_fetch_user_feed
    def test_bug_709938_interests(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = [u'science,Technology,paradox,knowledge,modeling,big data,'
                     u'vector,meme,heuristics,harmony,mathesis universalis,'
                     u'symmetry,mathematics,computer graphics,field,chemistry,'
                     u'religion,astronomy,physics,biology,literature,'
                     u'spirituality,Art,Philosophy,Psychology,Business,Music,'
                     u'Computer Science']

        form = dict()
        for fn in ('email', 'fullname', 'title', 'organization', 'location',
                'irc_nickname', 'bio', 'interests'):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        form['email'] = '*****@*****.**'

        form['interests'] = test_tags

        r = self.client.post(url, form, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, doc.find('ul.errorlist li').length)
        assert ('Ensure this value has at most 255 characters'
                in doc.find('ul.errorlist li').text())

    @mock_mindtouch_login
    @mock_get_deki_user
    @mock_put_mindtouch_user
    @mock_fetch_user_feed
    @mock.patch_object(Site.objects, 'get_current')
    def test_profile_edit_language_saves_to_mindtouch(self, get_current):
        get_current.return_value.domain = 'dev.mo.org'

        try:
            user = User.objects.get(username='******')
            user.delete()
        except User.DoesNotExist:
            pass

        # log in as a MindTouch user to create django user & profile
        response = self.client.post(reverse('users.login', locale='en-US'),
                                    {'username': '******',
                                     'password': '******'}, follow=True)
        eq_(200, response.status_code)
        user = User.objects.get(username='******')
        profile = UserProfile.objects.get(user=user)
        ok_(profile)

        # use profile edit to change language
        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code, 'Profile should be found.')
        doc = pq(r.content)

        # Scrape out the existing significant form field values.
        form = dict()
        for fn in ('email', 'fullname', 'title', 'organization', 'location',
                   'locale', 'timezone', 'irc_nickname', 'bio', 'interests'):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()

        # Fill out the form with websites.
        form.update({'locale': 'nl'})
        form.update({'timezone': 'Europe/Amsterdam'})

        # Submit the form, verify redirect to profile detail
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        # Verify locale saved in the profile.
        eq_('nl', p.locale)

        # Verify the saved locale appears in the editing form
        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        ok_('nl', doc.find('#profile-edit select#id_locale option[value="nl"]'
                           '[selected="selected"]'))

        # TODO: Mock this part out...
        """
        r = requests.get(DekiUserBackend.profile_by_id_url % '=testaccount')
        doc = pq(r.content)
        eq_('nl', doc.find('language').text())
        """

    def _break(self, url, r):
        logging.debug("URL  %s" % url)
        logging.debug("STAT %s" % r.status_code)
        logging.debug("HEAD %s" % r.items())
        logging.debug("CONT %s" % r.content)
        ok_(False)
Exemplo n.º 6
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']
Exemplo n.º 7
0
class RegisterTestCase(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_missing_get_deki_user
    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        response = self.client.post(reverse('users.register'), {
            'username': username,
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        assert u.password.startswith('sha256')
        assert not u.is_active
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        key = RegistrationProfile.objects.all()[0].activation_key
        assert mail.outbox[0].body.find('activate/%s' % key) > 0

        # Now try to log in
        u.is_active = True
        u.save()
        response = self.client.post(reverse('users.login'), {
            'username': username,
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)
        eq_('http://testserver/en-US/', response.redirect_chain[0][0])

    @mock_missing_get_deki_user
    @mock_post_mindtouch_user
    @mock_put_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_unicode_password(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        u_str = u'\xe5\xe5\xee\xe9\xf8\xe7\u6709\u52b9'
        response = self.client.post(reverse('users.register', locale='ja'), {
            'username': username,
            'email': '*****@*****.**',
            'password': u_str,
            'password2': u_str
        },
                                    follow=True)
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        u.is_active = True
        u.save()
        assert u.password.startswith('sha256')

        # make sure you can login now
        response = self.client.post(reverse('users.login', locale='ja'), {
            'username': username,
            'password': u_str
        },
                                    follow=True)
        eq_(200, response.status_code)
        eq_('http://testserver/ja/', response.redirect_chain[0][0])

    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user_activation(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        user = RegistrationProfile.objects.create_inactive_user(
            username, 'testpass', '*****@*****.**')
        assert not user.is_active
        key = RegistrationProfile.objects.all()[0].activation_key
        url = reverse('users.activate', args=[key])
        response = self.client.get(url, follow=True)
        eq_(200, response.status_code)
        user = User.objects.get(pk=user.pk)
        assert user.is_active

    @mock_get_deki_user
    def test_duplicate_username(self):
        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_duplicate_mindtouch_username(self):
        if not settings.DEKIWIKI_ENDPOINT:
            # Don't even bother with this test, if there's no MindTouch API
            raise SkipTest()

        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_duplicate_email(self):
        User.objects.create(username='******', email='*****@*****.**').save()
        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_no_match_passwords(self):
        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'bar'
        },
                                    follow=True)
        self.assertContains(response, 'must match')
Exemplo n.º 8
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

    def _get_current_form_field_values(self, doc):
        # Scrape out the existing significant form field values.
        form = dict()
        for fn in ('email', 'fullname', 'title', 'organization', 'location',
                   'irc_nickname', 'bio', 'interests'):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        return form

    @attr('docs_activity')
    def test_profile_view(self):
        """A user profile can be viewed"""
        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)
        doc = pq(r.content)

        eq_(profile.user.username,
            doc.find('#profile-head.vcard .nickname').text())
        eq_(profile.fullname, doc.find('#profile-head.vcard .fn').text())
        eq_(profile.title, doc.find('#profile-head.vcard .title').text())
        eq_(profile.organization, doc.find('#profile-head.vcard .org').text())
        eq_(profile.location, doc.find('#profile-head.vcard .loc').text())
        eq_('IRC: ' + profile.irc_nickname,
            doc.find('#profile-head.vcard .irc').text())
        eq_(profile.bio, doc.find('#profile-head.vcard .bio').text())

    def test_my_profile_view(self):
        u = User.objects.get(username='******')
        self.client.login(username=u.username, password=TESTUSER_PASSWORD)
        resp = self.client.get('/profile/')
        eq_(302, resp.status_code)
        ok_(
            reverse('devmo.views.profile_view', args=(
                u.username, )) in resp['Location'])

    def test_bug_698971(self):
        """A non-numeric page number should not cause an error"""
        (user, profile) = create_profile()

        url = '%s?page=asdf' % reverse('devmo.views.profile_view',
                                       args=(user.username, ))

        try:
            self.client.get(url, follow=True)
        except PageNotAnInteger:
            ok_(False, "Non-numeric page number should not cause an error")

    def test_profile_edit(self):
        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)
        doc = pq(r.content)
        eq_(0, doc.find('#profile-head .edit .button').length)

        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_view', args=(user.username, ))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        edit_button = doc.find('#profile-head .edit #edit-profile')
        eq_(1, edit_button.length)

        url = edit_button.attr('href')
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        eq_(profile.fullname,
            doc.find('#profile-edit input[name="fullname"]').val())
        eq_(profile.title, doc.find('#profile-edit input[name="title"]').val())
        eq_(profile.organization,
            doc.find('#profile-edit input[name="organization"]').val())
        eq_(profile.location,
            doc.find('#profile-edit input[name="location"]').val())
        eq_(profile.irc_nickname,
            doc.find('#profile-edit input[name="irc_nickname"]').val())

        new_attrs = dict(
            email='*****@*****.**',
            fullname="Another Name",
            title="Another title",
            organization="Another org",
        )

        r = self.client.post(url, new_attrs, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('#profile-head').length)
        eq_(new_attrs['fullname'], doc.find('#profile-head .main .fn').text())
        eq_(new_attrs['title'], doc.find('#profile-head .info .title').text())
        eq_(new_attrs['organization'],
            doc.find('#profile-head .info .org').text())

        profile = UserProfile.objects.get(user__username=user.username)
        eq_(new_attrs['fullname'], profile.fullname)
        eq_(new_attrs['title'], profile.title)
        eq_(new_attrs['organization'], profile.organization)

    def test_my_profile_edit(self):
        u = User.objects.get(username='******')
        self.client.login(username=u.username, password=TESTUSER_PASSWORD)
        resp = self.client.get('/profile/edit')
        eq_(302, resp.status_code)
        ok_(
            reverse('devmo.views.profile_edit', args=(
                u.username, )) in resp['Location'])

    def test_profile_edit_beta(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit', args=(user.username, ))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        eq_(None, doc.find('input#id_beta').attr('checked'))

        form = self._get_current_form_field_values(doc)
        form['beta'] = True

        r = self.client.post(url, form, follow=True)

        url = reverse('devmo.views.profile_edit', args=(user.username, ))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        eq_('checked', doc.find('input#id_beta').attr('checked'))

    def test_profile_edit_websites(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit', args=(user.username, ))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_sites = {
            u'website': u'http://example.com/',
            u'twitter': u'http://twitter.com/lmorchard',
            u'github': u'http://github.com/lmorchard',
            u'stackoverflow': u'http://stackoverflow.com/users/lmorchard',
        }

        form = self._get_current_form_field_values(doc)

        # Fill out the form with websites.
        form.update(dict(
            ('websites_%s' % k, v) for k, v in test_sites.items()))

        # Submit the form, verify redirect to profile detail
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        # Verify the websites are saved in the profile.
        eq_(test_sites, p.websites)

        # Verify the saved websites appear in the editing form
        url = reverse('devmo.views.profile_edit', args=(user.username, ))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        for k, v in test_sites.items():
            eq_(v, doc.find('#profile-edit *[name="websites_%s"]' % k).val())

        # Come up with some bad sites, either invalid URL or bad URL prefix
        bad_sites = {
            u'website': u'HAHAHA WHAT IS A WEBSITE',
            u'twitter': u'http://facebook.com/lmorchard',
            u'stackoverflow': u'http://overqueueblah.com/users/lmorchard',
        }
        form.update(dict(('websites_%s' % k, v) for k, v in bad_sites.items()))

        # Submit the form, verify errors for all of the bad sites
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-edit').length)
        tmpl = '#profile-edit #elsewhere .%s .errorlist'
        for n in ('website', 'twitter', 'stackoverflow'):
            eq_(1, doc.find(tmpl % n).length)

    def test_profile_edit_interests(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit', args=(user.username, ))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = ['javascript', 'css', 'canvas', 'html', 'homebrewing']

        form = self._get_current_form_field_values(doc)

        form['interests'] = ', '.join(test_tags)

        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        result_tags = [
            t.name.replace('profile:interest:', '')
            for t in p.tags.all_ns('profile:interest:')
        ]
        result_tags.sort()
        test_tags.sort()
        eq_(test_tags, result_tags)

        test_expertise = ['css', 'canvas']
        form['expertise'] = ', '.join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        result_tags = [
            t.name.replace('profile:expertise:', '')
            for t in p.tags.all_ns('profile:expertise')
        ]
        result_tags.sort()
        test_expertise.sort()
        eq_(test_expertise, result_tags)

        # Now, try some expertise tags not covered in interests
        test_expertise = ['css', 'canvas', 'mobile', 'movies']
        form['expertise'] = ', '.join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('.error #id_expertise').length)

    def test_bug_709938_interests(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit', args=(user.username, ))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = [
            u'science,Technology,paradox,knowledge,modeling,big data,'
            u'vector,meme,heuristics,harmony,mathesis universalis,'
            u'symmetry,mathematics,computer graphics,field,chemistry,'
            u'religion,astronomy,physics,biology,literature,'
            u'spirituality,Art,Philosophy,Psychology,Business,Music,'
            u'Computer Science'
        ]

        form = self._get_current_form_field_values(doc)

        form['interests'] = test_tags

        r = self.client.post(url, form, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, doc.find('ul.errorlist li').length)
        assert ('Ensure this value has at most 255 characters'
                in doc.find('ul.errorlist li').text())

    def test_bug_698126_l10n(self):
        """Test that the form field names are localized"""
        user = User.objects.get(username='******')
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit', args=(user.username, ))
        r = self.client.get(url, follow=True)
        for field in r.context['form'].fields:
            # if label is localized it's a lazy proxy object
            ok_(
                not isinstance(r.context['form'].fields[field].label,
                               basestring), 'Field %s is a string!' % field)

    def _break(self, url, r):
        logging.debug("URL  %s" % url)
        logging.debug("STAT %s" % r.status_code)
        logging.debug("HEAD %s" % r.items())
        logging.debug("CONT %s" % r.content)
        ok_(False)
Exemplo n.º 9
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")
    def test_profile_view(self):
        """A user profile can be viewed"""
        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)
        doc = pq(r.content)

        eq_(profile.user.username, doc.find("#profile-head.vcard .nickname").text())
        eq_(profile.fullname, doc.find("#profile-head.vcard .fn").text())
        eq_(profile.title, doc.find("#profile-head.vcard .title").text())
        eq_(profile.organization, doc.find("#profile-head.vcard .org").text())
        eq_(profile.location, doc.find("#profile-head.vcard .loc").text())
        eq_("IRC: " + profile.irc_nickname, doc.find("#profile-head.vcard .irc").text())
        eq_(profile.bio, doc.find("#profile-head.vcard .bio").text())

    def test_my_profile_view(self):
        u = User.objects.get(username="******")
        self.client.login(username=u.username, password=TESTUSER_PASSWORD)
        resp = self.client.get("/profile/")
        eq_(302, resp.status_code)
        ok_(reverse("devmo.views.profile_view", args=(u.username,)) in resp["Location"])

    def test_bug_698971(self):
        """A non-numeric page number should not cause an error"""
        (user, profile) = create_profile()

        url = "%s?page=asdf" % reverse("devmo.views.profile_view", args=(user.username,))

        try:
            self.client.get(url, follow=True)
        except PageNotAnInteger:
            ok_(False, "Non-numeric page number should not cause an error")

    def test_profile_edit(self):
        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)
        doc = pq(r.content)
        eq_(0, doc.find("#profile-head .edit .button").length)

        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse("devmo.views.profile_view", args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        edit_button = doc.find("#profile-head .edit #edit-profile")
        eq_(1, edit_button.length)

        url = edit_button.attr("href")
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        eq_(profile.fullname, doc.find('#profile-edit input[name="fullname"]').val())
        eq_(profile.title, doc.find('#profile-edit input[name="title"]').val())
        eq_(profile.organization, doc.find('#profile-edit input[name="organization"]').val())
        eq_(profile.location, doc.find('#profile-edit input[name="location"]').val())
        eq_(profile.irc_nickname, doc.find('#profile-edit input[name="irc_nickname"]').val())

        new_attrs = dict(
            email="*****@*****.**", fullname="Another Name", title="Another title", organization="Another org"
        )

        r = self.client.post(url, new_attrs, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find("#profile-head").length)
        eq_(new_attrs["fullname"], doc.find("#profile-head .main .fn").text())
        eq_(new_attrs["title"], doc.find("#profile-head .info .title").text())
        eq_(new_attrs["organization"], doc.find("#profile-head .info .org").text())

        profile = UserProfile.objects.get(user__username=user.username)
        eq_(new_attrs["fullname"], profile.fullname)
        eq_(new_attrs["title"], profile.title)
        eq_(new_attrs["organization"], profile.organization)

    def test_my_profile_edit(self):
        u = User.objects.get(username="******")
        self.client.login(username=u.username, password=TESTUSER_PASSWORD)
        resp = self.client.get("/profile/edit")
        eq_(302, resp.status_code)
        ok_(reverse("devmo.views.profile_edit", args=(u.username,)) in resp["Location"])

    def test_profile_edit_websites(self):
        user = User.objects.get(username="******")
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse("devmo.views.profile_edit", args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_sites = {
            u"website": u"http://example.com/",
            u"twitter": u"http://twitter.com/lmorchard",
            u"github": u"http://github.com/lmorchard",
            u"stackoverflow": u"http://stackoverflow.com/users/lmorchard",
        }

        # Scrape out the existing significant form field values.
        form = dict()
        for fn in ("email", "fullname", "title", "organization", "location", "irc_nickname", "bio", "interests"):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        form["email"] = "*****@*****.**"

        # Fill out the form with websites.
        form.update(dict(("websites_%s" % k, v) for k, v in test_sites.items()))

        # Submit the form, verify redirect to profile detail
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find("#profile-head").length)

        p = UserProfile.objects.get(user=user)

        # Verify the websites are saved in the profile.
        eq_(test_sites, p.websites)

        # Verify the saved websites appear in the editing form
        url = reverse("devmo.views.profile_edit", args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        for k, v in test_sites.items():
            eq_(v, doc.find('#profile-edit *[name="websites_%s"]' % k).val())

        # Come up with some bad sites, either invalid URL or bad URL prefix
        bad_sites = {
            u"website": u"HAHAHA WHAT IS A WEBSITE",
            u"twitter": u"http://facebook.com/lmorchard",
            u"stackoverflow": u"http://overqueueblah.com/users/lmorchard",
        }
        form.update(dict(("websites_%s" % k, v) for k, v in bad_sites.items()))

        # Submit the form, verify errors for all of the bad sites
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find("#profile-edit").length)
        tmpl = "#profile-edit #elsewhere .%s .errorlist"
        for n in ("website", "twitter", "stackoverflow"):
            eq_(1, doc.find(tmpl % n).length)

    def test_profile_edit_interests(self):
        user = User.objects.get(username="******")
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse("devmo.views.profile_edit", args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = ["javascript", "css", "canvas", "html", "homebrewing"]

        form = dict()
        for fn in ("email", "fullname", "title", "organization", "location", "irc_nickname", "bio", "interests"):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        form["email"] = "*****@*****.**"

        form["interests"] = ", ".join(test_tags)

        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find("#profile-head").length)

        p = UserProfile.objects.get(user=user)

        result_tags = [t.name.replace("profile:interest:", "") for t in p.tags.all_ns("profile:interest:")]
        result_tags.sort()
        test_tags.sort()
        eq_(test_tags, result_tags)

        test_expertise = ["css", "canvas"]
        form["expertise"] = ", ".join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find("#profile-head").length)

        p = UserProfile.objects.get(user=user)

        result_tags = [t.name.replace("profile:expertise:", "") for t in p.tags.all_ns("profile:expertise")]
        result_tags.sort()
        test_expertise.sort()
        eq_(test_expertise, result_tags)

        # Now, try some expertise tags not covered in interests
        test_expertise = ["css", "canvas", "mobile", "movies"]
        form["expertise"] = ", ".join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find(".error #id_expertise").length)

    def test_bug_709938_interests(self):
        user = User.objects.get(username="******")
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse("devmo.views.profile_edit", args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = [
            u"science,Technology,paradox,knowledge,modeling,big data,"
            u"vector,meme,heuristics,harmony,mathesis universalis,"
            u"symmetry,mathematics,computer graphics,field,chemistry,"
            u"religion,astronomy,physics,biology,literature,"
            u"spirituality,Art,Philosophy,Psychology,Business,Music,"
            u"Computer Science"
        ]

        form = dict()
        for fn in ("email", "fullname", "title", "organization", "location", "irc_nickname", "bio", "interests"):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        form["email"] = "*****@*****.**"

        form["interests"] = test_tags

        r = self.client.post(url, form, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, doc.find("ul.errorlist li").length)
        assert "Ensure this value has at most 255 characters" in doc.find("ul.errorlist li").text()

    def test_bug_698126_l10n(self):
        """Test that the form field names are localized"""
        user = User.objects.get(username="******")
        self.client.login(username=user.username, password=TESTUSER_PASSWORD)

        url = reverse("devmo.views.profile_edit", args=(user.username,))
        r = self.client.get(url, follow=True)
        for field in r.context["form"].fields:
            # if label is localized it's a lazy proxy object
            ok_(not isinstance(r.context["form"].fields[field].label, basestring), "Field %s is a string!" % field)

    def _break(self, url, r):
        logging.debug("URL  %s" % url)
        logging.debug("STAT %s" % r.status_code)
        logging.debug("HEAD %s" % r.items())
        logging.debug("CONT %s" % r.content)
        ok_(False)
Exemplo n.º 10
0
class UploadImageTestCase(TestCase):
    fixtures = ['users.json', 'questions.json']

    def setUp(self):
        super(UploadImageTestCase, self).setUp()
        self.client = LocalizingClient()
        self.client.login(username='******', password='******')

    def tearDown(self):
        ImageAttachment.objects.all().delete()
        super(UploadImageTestCase, self).tearDown()

    def test_model_invalid(self):
        """Specifying an invalid model returns 400."""
        r = post(self.client, 'upload.up_image_async', {'image': ''},
                 args=['invalid.model', 123])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Model does not exist.', json_r['message'])

    def test_object_notexist(self):
        """Upload nothing returns 404 error and html content."""
        r = post(self.client, 'upload.up_image_async', {'image': ''},
                 args=['questions.Question', 123])

        eq_(404, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Object does not exist.', json_r['message'])

    def test_empty_image(self):
        """Upload nothing returns 400 error and json content."""
        r = post(self.client, 'upload.up_image_async', {'image': ''},
                 args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_('You have not selected an image to upload.',
            json_r['errors']['image'][0])

    def test_upload_image(self):
        """Uploading an image works."""
        with open('apps/upload/tests/media/test.jpg') as f:
            r = post(self.client, 'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        file = json_r['file']
        eq_('test.jpg', file['name'])
        eq_(90, file['width'])
        eq_(120, file['height'])
        name = '098f6b.jpg'
        message = 'Url "%s" does not contain "%s"' % (file['url'], name)
        assert (name in file['url']), message

        eq_(1, ImageAttachment.objects.count())
        image = ImageAttachment.objects.all()[0]
        eq_('pcraciunoiu', image.creator.username)
        eq_(150, image.file.width)
        eq_(200, image.file.height)
        eq_('question', image.content_type.model)
        eq_(1, image.object_id)

    def test_upload_unicode_image(self):
        """Uploading an unicode image works."""
        with open(u'apps/upload/tests/media/123ascii\u6709\u52b9.jpg') as f:
            r = post(self.client, 'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])

    def test_delete_image_logged_out(self):
        """Can't delete an image logged out."""
        # Upload the image first
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        self.client.logout()
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(403, r.status_code)
        assert ImageAttachment.uncached.exists()

    def test_delete_image_no_permission(self):
        """Can't delete an image without permission."""
        u = User.objects.get(username='******')
        assert not u.has_perm('upload.delete_imageattachment')
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        self.client.login(username='******', password='******')
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(403, r.status_code)
        assert ImageAttachment.uncached.exists()

    def test_delete_image_owner(self):
        """Users can delete their own images."""
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        assert not ImageAttachment.uncached.exists()

    def test_delete_image_with_permission(self):
        """Users with permission can delete images."""
        u = User.objects.get(username='******')
        ct = ContentType.objects.get_for_model(ImageAttachment)
        p = Permission.objects.get_or_create(
            codename='delete_imageattachment',
            content_type=ct)[0]
        u.user_permissions.add(p)
        assert u.has_perm('upload.delete_imageattachment')

        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]

        self.client.login(username='******', password='******')
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        assert not ImageAttachment.uncached.exists()

    def test_delete_no_image(self):
        """Trying to delete a non-existent image 404s."""
        r = post(self.client, 'upload.del_image_async', args=[123])
        eq_(404, r.status_code)
        data = json.loads(r.content)
        eq_('error', data['status'])

    def test_invalid_image(self):
        """Make sure invalid files are not accepted as images."""
        with open('apps/upload/__init__.py', 'rb') as f:
            r = post(self.client, 'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_('The submitted file is empty.', json_r['errors']['image'][0])

    def test_invalid_image_extensions(self):
        """Make sure invalid extensions are not accepted as images."""
        with open('apps/upload/tests/media/test_invalid.ext', 'rb') as f:
            r = post(self.client, 'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_('Please upload an image with one of the following extensions: '
            'jpg, jpeg, png, gif.', json_r['errors']['__all__'][0])

    def test_upload_long_filename(self):
        """Uploading an image with a filename that's too long fails."""
        with open('apps/upload/tests/media/a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_yes_.jpg')\
            as f:
            r = post(self.client, 'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_(MSG_IMAGE_LONG % {'length': 251,
                              'max': settings.MAX_FILENAME_LENGTH},
            json_r['errors']['image'][0])
Exemplo n.º 11
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']
Exemplo n.º 12
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())
Exemplo n.º 13
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
        response = 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())
Exemplo n.º 14
0
class RegisterTestCase(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_missing_get_deki_user
    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        response = self.client.post(reverse('users.register'), {
            'username': username,
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        assert u.password.startswith('sha256')
        assert not u.is_active
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        key = RegistrationProfile.objects.all()[0].activation_key
        assert mail.outbox[0].body.find('activate/%s' % key) > 0

        # Now try to log in
        u.is_active = True
        u.save()
        response = self.client.post(reverse('users.login'), {
            'username': username,
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)
        eq_('http://testserver/en-US/', response.redirect_chain[0][0])

    @mock_missing_get_deki_user
    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user_posts_mindtouch_user(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        response = self.client.post(reverse('users.register'), {
            'username': username,
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        assert u.password.startswith('sha256')
        assert not u.is_active
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        key = RegistrationProfile.objects.all()[0].activation_key
        assert mail.outbox[0].body.find('activate/%s' % key) > 0

        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_(username, doc('username').text())

        # Now try to log in
        u.is_active = True
        u.save()
        response = self.client.post(reverse('users.login'), {
            'username': username,
            'password': '******'
        },
                                    follow=True)
        eq_(200, response.status_code)
        eq_('http://testserver/en-US/', response.redirect_chain[0][0])

    @mock_missing_get_deki_user
    @mock_put_mindtouch_user
    @mock_perform_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user_retries_mindtouch_post(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'
        now = time()
        username = '******' % now
        response = self.client.post(reverse('users.register'), {
            'username': username,
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        eq_(200, response.status_code)
        ok_("Please try again later." in response.content)
        self.assertRaises(User.DoesNotExist,
                          User.objects.get,
                          username=username)

    @mock_missing_get_deki_user
    @mock_post_mindtouch_user
    @mock_put_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_unicode_password(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        u_str = u'\xe5\xe5\xee\xe9\xf8\xe7\u6709\u52b9'
        response = self.client.post(reverse('users.register', locale='ja'), {
            'username': username,
            'email': '*****@*****.**',
            'password': u_str,
            'password2': u_str
        },
                                    follow=True)
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        u.is_active = True
        u.save()
        assert u.password.startswith('sha256')

        # make sure you can login now
        response = self.client.post(reverse('users.login', locale='ja'), {
            'username': username,
            'password': u_str
        },
                                    follow=True)
        eq_(200, response.status_code)
        eq_('http://testserver/ja/', response.redirect_chain[0][0])

    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user_activation(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        user = RegistrationProfile.objects.create_inactive_user(
            username, 'testpass', '*****@*****.**')
        assert not user.is_active
        key = RegistrationProfile.objects.all()[0].activation_key
        url = reverse('users.activate', args=[key])
        response = self.client.get(url, follow=True)
        eq_(200, response.status_code)
        user = User.objects.get(pk=user.pk)
        assert user.is_active

    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user_claim_watches(self, get_current):
        """Claim user watches upon activation."""
        old, settings.CELERY_ALWAYS_EAGER = settings.CELERY_ALWAYS_EAGER, True

        get_current.return_value.domain = 'su.mo.com'

        watch(email='*****@*****.**', save=True)

        now = time()
        username = '******' % now
        user = RegistrationProfile.objects.create_inactive_user(
            username, 'testpass', '*****@*****.**')
        key = RegistrationProfile.objects.all()[0].activation_key
        self.client.get(reverse('users.activate', args=[key]), follow=True)

        # Watches are claimed.
        assert user.watch_set.exists()

        settings.CELERY_ALWAYS_EAGER = old

    @mock_get_deki_user
    def test_duplicate_username(self):
        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_duplicate_mindtouch_username(self):
        if not settings.DEKIWIKI_ENDPOINT:
            # Don't even bother with this test, if there's no MindTouch API
            raise SkipTest()

        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_duplicate_email(self):
        User.objects.create(username='******', email='*****@*****.**').save()
        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'foo'
        },
                                    follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_no_match_passwords(self):
        response = self.client.post(reverse('users.register'), {
            'username': '******',
            'email': '*****@*****.**',
            'password': '******',
            'password2': 'bar'
        },
                                    follow=True)
        self.assertContains(response, 'must match')
Exemplo n.º 15
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

    def _get_current_form_field_values(self, doc):
        # Scrape out the existing significant form field values.
        form = dict()
        for fn in ('email', 'fullname', 'title', 'organization', 'location',
                   'irc_nickname', 'bio', 'interests'):
            form[fn] = doc.find('#profile-edit *[name="%s"]' % fn).val()
        return form

    @attr('docs_activity')
    def test_profile_view(self):
        """A user profile can be viewed"""
        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)
        doc = pq(r.content)

        eq_(profile.user.username,
            doc.find('#profile-head.vcard .nickname').text())
        eq_(profile.fullname,
            doc.find('#profile-head.vcard .fn').text())
        eq_(profile.title,
            doc.find('#profile-head.vcard .title').text())
        eq_(profile.organization,
            doc.find('#profile-head.vcard .org').text())
        eq_(profile.location,
            doc.find('#profile-head.vcard .loc').text())
        eq_('IRC: ' + profile.irc_nickname,
            doc.find('#profile-head.vcard .irc').text())
        eq_(profile.bio,
            doc.find('#profile-head.vcard .bio').text())

    def test_my_profile_view(self):
        u = User.objects.get(username='******')
        self.client.login(username=u.username, password=TESTUSER_PASSWORD)
        resp = self.client.get('/profile/')
        eq_(302, resp.status_code)
        ok_(reverse('devmo.views.profile_view', args=(u.username,)) in
            resp['Location'])

    def test_bug_698971(self):
        """A non-numeric page number should not cause an error"""
        (user, profile) = create_profile()

        url = '%s?page=asdf' % reverse('devmo.views.profile_view',
                                       args=(user.username,))

        try:
            self.client.get(url, follow=True)
        except PageNotAnInteger:
            ok_(False, "Non-numeric page number should not cause an error")

    def test_profile_edit(self):
        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)
        doc = pq(r.content)
        eq_(0, doc.find('#profile-head .edit .button').length)

        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_view',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        edit_button = doc.find('#profile-head .edit #edit-profile')
        eq_(1, edit_button.length)

        url = edit_button.attr('href')
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        eq_(profile.fullname,
            doc.find('#profile-edit input[name="fullname"]').val())
        eq_(profile.title,
            doc.find('#profile-edit input[name="title"]').val())
        eq_(profile.organization,
            doc.find('#profile-edit input[name="organization"]').val())
        eq_(profile.location,
            doc.find('#profile-edit input[name="location"]').val())
        eq_(profile.irc_nickname,
            doc.find('#profile-edit input[name="irc_nickname"]').val())

        new_attrs = dict(
            email='*****@*****.**',
            fullname="Another Name",
            title="Another title",
            organization="Another org",
        )

        r = self.client.post(url, new_attrs, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('#profile-head').length)
        eq_(new_attrs['fullname'],
            doc.find('#profile-head .main .fn').text())
        eq_(new_attrs['title'],
            doc.find('#profile-head .info .title').text())
        eq_(new_attrs['organization'],
            doc.find('#profile-head .info .org').text())

        profile = UserProfile.objects.get(user__username=user.username)
        eq_(new_attrs['fullname'], profile.fullname)
        eq_(new_attrs['title'], profile.title)
        eq_(new_attrs['organization'], profile.organization)

    def test_my_profile_edit(self):
        u = User.objects.get(username='******')
        self.client.login(username=u.username, password=TESTUSER_PASSWORD)
        resp = self.client.get('/profile/edit')
        eq_(302, resp.status_code)
        ok_(reverse('devmo.views.profile_edit', args=(u.username,)) in
            resp['Location'])

    def test_profile_edit_beta(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
                          password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        eq_(None, doc.find('input#id_beta').attr('checked'))

        form = self._get_current_form_field_values(doc)
        form['beta'] = True

        r = self.client.post(url, form, follow=True)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        eq_('checked', doc.find('input#id_beta').attr('checked'))

    def test_profile_edit_websites(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_sites = {
            u'website': u'http://example.com/',
            u'twitter': u'http://twitter.com/lmorchard',
            u'github': u'http://github.com/lmorchard',
            u'stackoverflow': u'http://stackoverflow.com/users/lmorchard',
        }

        form = self._get_current_form_field_values(doc)

        # Fill out the form with websites.
        form.update(dict(('websites_%s' % k, v)
                    for k, v in test_sites.items()))

        # Submit the form, verify redirect to profile detail
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        # Verify the websites are saved in the profile.
        eq_(test_sites, p.websites)

        # Verify the saved websites appear in the editing form
        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)
        for k, v in test_sites.items():
            eq_(v, doc.find('#profile-edit *[name="websites_%s"]' % k).val())

        # Come up with some bad sites, either invalid URL or bad URL prefix
        bad_sites = {
            u'website': u'HAHAHA WHAT IS A WEBSITE',
            u'twitter': u'http://facebook.com/lmorchard',
            u'stackoverflow': u'http://overqueueblah.com/users/lmorchard',
        }
        form.update(dict(('websites_%s' % k, v)
                    for k, v in bad_sites.items()))

        # Submit the form, verify errors for all of the bad sites
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-edit').length)
        tmpl = '#profile-edit #elsewhere .%s .errorlist'
        for n in ('website', 'twitter', 'stackoverflow'):
            eq_(1, doc.find(tmpl % n).length)

    def test_profile_edit_interests(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = ['javascript', 'css', 'canvas', 'html', 'homebrewing']

        form = self._get_current_form_field_values(doc)

        form['interests'] = ', '.join(test_tags)

        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)
        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        result_tags = [t.name.replace('profile:interest:', '')
                for t in p.tags.all_ns('profile:interest:')]
        result_tags.sort()
        test_tags.sort()
        eq_(test_tags, result_tags)

        test_expertise = ['css', 'canvas']
        form['expertise'] = ', '.join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('#profile-head').length)

        p = UserProfile.objects.get(user=user)

        result_tags = [t.name.replace('profile:expertise:', '')
                for t in p.tags.all_ns('profile:expertise')]
        result_tags.sort()
        test_expertise.sort()
        eq_(test_expertise, result_tags)

        # Now, try some expertise tags not covered in interests
        test_expertise = ['css', 'canvas', 'mobile', 'movies']
        form['expertise'] = ', '.join(test_expertise)
        r = self.client.post(url, form, follow=True)
        doc = pq(r.content)

        eq_(1, doc.find('.error #id_expertise').length)

    def test_bug_709938_interests(self):
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
                password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
                      args=(user.username,))
        r = self.client.get(url, follow=True)
        doc = pq(r.content)

        test_tags = [u'science,Technology,paradox,knowledge,modeling,big data,'
                     u'vector,meme,heuristics,harmony,mathesis universalis,'
                     u'symmetry,mathematics,computer graphics,field,chemistry,'
                     u'religion,astronomy,physics,biology,literature,'
                     u'spirituality,Art,Philosophy,Psychology,Business,Music,'
                     u'Computer Science']

        form = self._get_current_form_field_values(doc)

        form['interests'] = test_tags

        r = self.client.post(url, form, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, doc.find('ul.errorlist li').length)
        assert ('Ensure this value has at most 255 characters'
                in doc.find('ul.errorlist li').text())


    def test_bug_698126_l10n(self):
        """Test that the form field names are localized"""
        user = User.objects.get(username='******')
        self.client.login(username=user.username,
            password=TESTUSER_PASSWORD)

        url = reverse('devmo.views.profile_edit',
            args=(user.username,))
        r = self.client.get(url, follow=True)
        for field in r.context['form'].fields:
            # if label is localized it's a lazy proxy object
            ok_(not isinstance(
                r.context['form'].fields[field].label, basestring),
                'Field %s is a string!' % field)

    def _break(self, url, r):
        logging.debug("URL  %s" % url)
        logging.debug("STAT %s" % r.status_code)
        logging.debug("HEAD %s" % r.items())
        logging.debug("CONT %s" % r.content)
        ok_(False)
Exemplo n.º 16
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_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']
Exemplo n.º 17
0
class RegisterTestCase(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_missing_get_deki_user
    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, "get_current")
    def test_new_user(self, get_current):
        get_current.return_value.domain = "su.mo.com"
        now = time()
        username = "******" % now
        response = self.client.post(
            reverse("users.register"),
            {"username": username, "email": "*****@*****.**", "password": "******", "password2": "foo"},
            follow=True,
        )
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        assert u.password.startswith("sha256")
        assert not u.is_active
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find("Please confirm your") == 0
        key = RegistrationProfile.objects.all()[0].activation_key
        assert mail.outbox[0].body.find("activate/%s" % key) > 0

        # Now try to log in
        u.is_active = True
        u.save()
        response = self.client.post(reverse("users.login"), {"username": username, "password": "******"}, follow=True)
        eq_(200, response.status_code)
        eq_("http://testserver/en-US/", response.redirect_chain[0][0])

    @mock_missing_get_deki_user
    @mock_post_mindtouch_user
    @mock_put_mindtouch_user
    @mock.patch_object(Site.objects, "get_current")
    def test_unicode_password(self, get_current):
        get_current.return_value.domain = "su.mo.com"
        now = time()
        username = "******" % now
        u_str = u"\xe5\xe5\xee\xe9\xf8\xe7\u6709\u52b9"
        response = self.client.post(
            reverse("users.register", locale="ja"),
            {"username": username, "email": "*****@*****.**", "password": u_str, "password2": u_str},
            follow=True,
        )
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        u.is_active = True
        u.save()
        assert u.password.startswith("sha256")

        # make sure you can login now
        response = self.client.post(
            reverse("users.login", locale="ja"), {"username": username, "password": u_str}, follow=True
        )
        eq_(200, response.status_code)
        eq_("http://testserver/ja/", response.redirect_chain[0][0])

    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, "get_current")
    def test_new_user_activation(self, get_current):
        get_current.return_value.domain = "su.mo.com"
        now = time()
        username = "******" % now
        user = RegistrationProfile.objects.create_inactive_user(username, "testpass", "*****@*****.**")
        assert not user.is_active
        key = RegistrationProfile.objects.all()[0].activation_key
        url = reverse("users.activate", args=[key])
        response = self.client.get(url, follow=True)
        eq_(200, response.status_code)
        user = User.objects.get(pk=user.pk)
        assert user.is_active

    @mock_get_deki_user
    def test_duplicate_username(self):
        response = self.client.post(
            reverse("users.register"),
            {"username": "******", "email": "*****@*****.**", "password": "******", "password2": "foo"},
            follow=True,
        )
        self.assertContains(response, "already exists")

    @mock_get_deki_user
    def test_duplicate_mindtouch_username(self):
        if not settings.DEKIWIKI_ENDPOINT:
            # Don't even bother with this test, if there's no MindTouch API
            raise SkipTest()

        response = self.client.post(
            reverse("users.register"),
            {"username": "******", "email": "*****@*****.**", "password": "******", "password2": "foo"},
            follow=True,
        )
        self.assertContains(response, "already exists")

    @mock_get_deki_user
    def test_duplicate_email(self):
        User.objects.create(username="******", email="*****@*****.**").save()
        response = self.client.post(
            reverse("users.register"),
            {"username": "******", "email": "*****@*****.**", "password": "******", "password2": "foo"},
            follow=True,
        )
        self.assertContains(response, "already exists")

    @mock_get_deki_user
    def test_no_match_passwords(self):
        response = self.client.post(
            reverse("users.register"),
            {"username": "******", "email": "*****@*****.**", "password": "******", "password2": "bar"},
            follow=True,
        )
        self.assertContains(response, "must match")
Exemplo n.º 18
0
class RegisterTestCase(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_missing_get_deki_user
    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        response = self.client.post(reverse('users.register'),
                                    {'username': username,
                                     'email': '*****@*****.**',
                                     'password': '******',
                                     'password2': 'foo'}, follow=True)
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        assert u.password.startswith('sha256')
        assert not u.is_active
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        key = RegistrationProfile.objects.all()[0].activation_key
        assert mail.outbox[0].body.find('activate/%s' % key) > 0

        # Now try to log in
        u.is_active = True
        u.save()
        response = self.client.post(reverse('users.login'),
                                    {'username': username,
                                     'password': '******'}, follow=True)
        eq_(200, response.status_code)
        eq_('http://testserver/en-US/', response.redirect_chain[0][0])

    @mock_missing_get_deki_user
    @mock_post_mindtouch_user
    @mock_put_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_unicode_password(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        u_str = u'\xe5\xe5\xee\xe9\xf8\xe7\u6709\u52b9'
        response = self.client.post(reverse('users.register', locale='ja'),
                                    {'username': username,
                                     'email': '*****@*****.**',
                                     'password': u_str,
                                     'password2': u_str}, follow=True)
        eq_(200, response.status_code)
        u = User.objects.get(username=username)
        u.is_active = True
        u.save()
        assert u.password.startswith('sha256')

        # make sure you can login now
        response = self.client.post(reverse('users.login', locale='ja'),
                                    {'username': username,
                                     'password': u_str}, follow=True)
        eq_(200, response.status_code)
        eq_('http://testserver/ja/', response.redirect_chain[0][0])

    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user_activation(self, get_current):
        get_current.return_value.domain = 'su.mo.com'
        now = time()
        username = '******' % now
        user = RegistrationProfile.objects.create_inactive_user(
            username, 'testpass', '*****@*****.**')
        assert not user.is_active
        key = RegistrationProfile.objects.all()[0].activation_key
        url = reverse('users.activate', args=[key])
        response = self.client.get(url, follow=True)
        eq_(200, response.status_code)
        user = User.objects.get(pk=user.pk)
        assert user.is_active

    @mock_put_mindtouch_user
    @mock_post_mindtouch_user
    @mock.patch_object(Site.objects, 'get_current')
    def test_new_user_claim_watches(self, get_current):
        """Claim user watches upon activation."""
        old, settings.CELERY_ALWAYS_EAGER = settings.CELERY_ALWAYS_EAGER, True

        get_current.return_value.domain = 'su.mo.com'

        watch(email='*****@*****.**', save=True)

        now = time()
        username = '******' % now
        user = RegistrationProfile.objects.create_inactive_user(
            username, 'testpass', '*****@*****.**')
        key = RegistrationProfile.objects.all()[0].activation_key
        self.client.get(reverse('users.activate', args=[key]), follow=True)

        # Watches are claimed.
        assert user.watch_set.exists()

        settings.CELERY_ALWAYS_EAGER = old

    @mock_get_deki_user
    def test_duplicate_username(self):
        response = self.client.post(reverse('users.register'),
                                    {'username': '******',
                                     'email': '*****@*****.**',
                                     'password': '******',
                                     'password2': 'foo'}, follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_duplicate_mindtouch_username(self):
        if not settings.DEKIWIKI_ENDPOINT:
            # Don't even bother with this test, if there's no MindTouch API
            raise SkipTest()

        response = self.client.post(reverse('users.register'),
                                    {'username': '******',
                                     'email': '*****@*****.**',
                                     'password': '******',
                                     'password2': 'foo'}, follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_duplicate_email(self):
        User.objects.create(username='******', email='*****@*****.**').save()
        response = self.client.post(reverse('users.register'),
                                    {'username': '******',
                                     'email': '*****@*****.**',
                                     'password': '******',
                                     'password2': 'foo'}, follow=True)
        self.assertContains(response, 'already exists')

    @mock_get_deki_user
    def test_no_match_passwords(self):
        response = self.client.post(reverse('users.register'),
                                    {'username': '******',
                                     'email': '*****@*****.**',
                                     'password': '******',
                                     'password2': 'bar'}, follow=True)
        self.assertContains(response, 'must match')
Exemplo n.º 19
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_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):
        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())
Exemplo n.º 20
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_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']
Exemplo n.º 21
0
class UploadImageTestCase(TestCase):
    fixtures = ['users.json', 'questions.json']

    def setUp(self):
        super(UploadImageTestCase, self).setUp()
        self.client = LocalizingClient()
        self.client.login(username='******', password='******')

    def tearDown(self):
        ImageAttachment.objects.all().delete()
        super(UploadImageTestCase, self).tearDown()

    def test_model_invalid(self):
        """Specifying an invalid model returns 400."""
        r = post(self.client,
                 'upload.up_image_async', {'image': ''},
                 args=['invalid.model', 123])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Model does not exist.', json_r['message'])

    def test_object_notexist(self):
        """Upload nothing returns 404 error and html content."""
        r = post(self.client,
                 'upload.up_image_async', {'image': ''},
                 args=['questions.Question', 123])

        eq_(404, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Object does not exist.', json_r['message'])

    def test_empty_image(self):
        """Upload nothing returns 400 error and json content."""
        r = post(self.client,
                 'upload.up_image_async', {'image': ''},
                 args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_('You have not selected an image to upload.',
            json_r['errors']['image'][0])

    def test_upload_image(self):
        """Uploading an image works."""
        with open('apps/upload/tests/media/test.jpg') as f:
            r = post(self.client,
                     'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        file = json_r['file']
        eq_('test.jpg', file['name'])
        eq_(90, file['width'])
        eq_(120, file['height'])
        name = '098f6b.jpg'
        message = 'Url "%s" does not contain "%s"' % (file['url'], name)
        assert (name in file['url']), message

        eq_(1, ImageAttachment.objects.count())
        image = ImageAttachment.objects.all()[0]
        eq_('pcraciunoiu', image.creator.username)
        eq_(150, image.file.width)
        eq_(200, image.file.height)
        eq_('question', image.content_type.model)
        eq_(1, image.object_id)

    def test_upload_unicode_image(self):
        """Uploading an unicode image works."""
        with open(u'apps/upload/tests/media/123ascii\u6709\u52b9.jpg') as f:
            r = post(self.client,
                     'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])

    def test_delete_image_logged_out(self):
        """Can't delete an image logged out."""
        # Upload the image first
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        self.client.logout()
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(403, r.status_code)
        assert ImageAttachment.uncached.exists()

    def test_delete_image_no_permission(self):
        """Can't delete an image without permission."""
        u = User.objects.get(username='******')
        assert not u.has_perm('upload.delete_imageattachment')
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        self.client.login(username='******', password='******')
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(403, r.status_code)
        assert ImageAttachment.uncached.exists()

    def test_delete_image_owner(self):
        """Users can delete their own images."""
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        assert not ImageAttachment.uncached.exists()

    def test_delete_image_with_permission(self):
        """Users with permission can delete images."""
        u = User.objects.get(username='******')
        ct = ContentType.objects.get_for_model(ImageAttachment)
        p = Permission.objects.get_or_create(codename='delete_imageattachment',
                                             content_type=ct)[0]
        u.user_permissions.add(p)
        assert u.has_perm('upload.delete_imageattachment')

        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]

        self.client.login(username='******', password='******')
        r = post(self.client, 'upload.del_image_async', args=[im.id])
        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        assert not ImageAttachment.uncached.exists()

    def test_delete_no_image(self):
        """Trying to delete a non-existent image 404s."""
        r = post(self.client, 'upload.del_image_async', args=[123])
        eq_(404, r.status_code)
        data = json.loads(r.content)
        eq_('error', data['status'])

    def test_invalid_image(self):
        """Make sure invalid files are not accepted as images."""
        with open('apps/upload/__init__.py', 'rb') as f:
            r = post(self.client,
                     'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_('The submitted file is empty.', json_r['errors']['image'][0])

    def test_invalid_image_extensions(self):
        """Make sure invalid extensions are not accepted as images."""
        with open('apps/upload/tests/media/test_invalid.ext', 'rb') as f:
            r = post(self.client,
                     'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_(
            'Please upload an image with one of the following extensions: '
            'jpg, jpeg, png, gif.', json_r['errors']['__all__'][0])

    def test_upload_long_filename(self):
        """Uploading an image with a filename that's too long fails."""
        with open('apps/upload/tests/media/a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_worth_'
                  'more_than_250_characters__a_really_long_filename_yes_.jpg')\
            as f:
            r = post(self.client,
                     'upload.up_image_async', {'image': f},
                     args=['questions.Question', 1])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Invalid or no image received.', json_r['message'])
        eq_(
            MSG_IMAGE_LONG % {
                'length': 251,
                'max': settings.MAX_FILENAME_LENGTH
            }, json_r['errors']['image'][0])