Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user account sign up / registration #7

Merged
merged 16 commits into from
Apr 21, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include README.rst
recursive-include warehouse/templates *.html
recursive-include warehouse/templates *.txt
16 changes: 15 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,22 @@ running locally and are configured to not require passwords.
# If you want to use the default development configuration
$ warehouse runserver --settings=configs.dev --configuration=Development

5. Run the tests

Running the tests
-----------------

Warehouse uses pytest to run the test suite. You can run all the tests by using:

.. code:: bash

$ py.test

Unit and functional tests have been marked and you may run either of by using:

..code:: bash

# Run only the unit tests
$ py.test -m unit

# Run only the functional tests
$ py.test -m functional
2 changes: 2 additions & 0 deletions configs/dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Development(Common):
DEBUG = True
TEMPLATE_DEBUG = True

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"


class Testing(Common):

Expand Down
10 changes: 10 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,23 @@
],
extras_require={
"tests": [
"django-webtest",
"pretend",
"pytest",
"pytest-cov",
"pytest-django>=2.3.0",
"webtest",
],
},

packages=find_packages(exclude=["tests"]),
package_data={
"warehouse": [
"templates/*.html",
"templates/*.txt",
],
},
include_package_data=True,

entry_points={
"console_scripts": [
Expand Down
10 changes: 0 additions & 10 deletions tests/accounts/test_forms.py

This file was deleted.

53 changes: 53 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import pytest


def pytest_collection_modifyitems(items):
for item in items:
path, name = item.nodeid.split("::")
if path.startswith("tests/unit/"):
item.keywords["unit"] = pytest.mark.unit
elif path.startswith("tests/functional"):
item.keywords["functional"] = pytest.mark.functional


@pytest.fixture
def webtest(request):
from django.conf import settings
from django.test.utils import override_settings

from django_webtest import DjangoTestApp

middleware = list(settings.MIDDLEWARE_CLASSES)
django_auth_middleware = ("django.contrib.auth.middleware."
"AuthenticationMiddleware")
webtest_auth_middleware = "django_webtest.middleware.WebtestUserMiddleware"
if django_auth_middleware not in settings.MIDDLEWARE_CLASSES:
# There can be a custom AuthenticationMiddleware subclass or
# replacement, we can't compute its index so just put our auth
# middleware to the end.
middleware.append(webtest_auth_middleware)
else:
index = middleware.index(django_auth_middleware)
middleware.insert(index+1, webtest_auth_middleware)

auth_backends = ["django_webtest.backends.WebtestUserBackend"]
auth_backends += list(settings.AUTHENTICATION_BACKENDS)

patched_settings = override_settings(
# We want exceptions to be raised naturally so that
# they are treated like normal exceptions in a
# test case.
DEBUG_PROPAGATE_EXCEPTIONS=True,
# We want to insert the django-webtest middleware
# into our middleware classes so that we can
# auth from a webtest easily.
MIDDLEWARE_CLASSES=middleware,
# We want to insert the django-webtest
# authentication backend so that webtest can
# easily authenticate.
AUTHENTICATION_BACKENDS=auth_backends,
)
patched_settings.enable()
request.addfinalizer(patched_settings.disable)

return DjangoTestApp()
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions tests/functional/accounts/test_signup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import pytest

from django.core.urlresolvers import reverse


@pytest.mark.django_db(transaction=True)
def test_simple_signup(webtest):
form = webtest.get(reverse("accounts.signup")).form
form["username"] = "testuser"
form["email"] = "testuser@example.com"
form["password"] = "test password!"
form["confirm_password"] = "test password!"
response = form.submit()

assert response.status_code == 303
File renamed without changes.
Empty file added tests/unit/accounts/__init__.py
Empty file.
148 changes: 148 additions & 0 deletions tests/unit/accounts/test_adapters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
from pretend import stub
from unittest import mock

import pytest

from warehouse.accounts.adapters import Email, EmailAdapter, User, UserAdapter


def test_useradapter_no_username():
with pytest.raises(ValueError):
UserAdapter().create(None)


def test_useradapter_creates():
created = mock.NonCallableMock()
created.username = "testuser"
created.set_password = mock.Mock()
created.save = mock.Mock()
model = mock.Mock(return_value=created)

adapter = UserAdapter()
adapter.model = model

user = adapter.create("testuser", "testpassword")

assert user.username == "testuser"

assert model.call_count == 1
assert model.call_args == (tuple(), {
"username": "testuser",
"is_staff": False,
"is_superuser": False,
"is_active": True,
"last_login": mock.ANY,
"date_joined": mock.ANY,
})

assert created.set_password.call_count == 1
assert created.set_password.call_args == (("testpassword",), {})

assert created.save.call_count == 1
assert created.save.call_args == (tuple(), {})


@pytest.mark.parametrize(("exists",), [(True,), (False,)])
def test_useradapter_username_exists(exists):
mexists = mock.Mock(return_value=exists)
mfilter = mock.Mock(return_value=stub(exists=mexists))
model = stub(objects=stub(filter=mfilter))

adapter = UserAdapter()
adapter.model = model

uexists = adapter.username_exists("testuser")

assert uexists == exists

assert mfilter.call_count == 1
assert mfilter.call_args == (tuple(), {"username": "testuser"})

assert mexists.call_count == 1
assert mexists.call_args == (tuple(), {})


def test_useradapter_serializer():
adapter = UserAdapter()

user = adapter._serialize(stub(username="testuser"))

assert isinstance(user, User)
assert user == ("testuser",)
assert user.username == "testuser"


@pytest.mark.parametrize(("primary", "verified"), [
(None, None),
(None, True),
(None, False),
(True, True),
(True, False),
(True, None),
(False, True),
(False, False),
(False, None),
])
def test_emailadapter_creates(primary, verified):
user = stub(username="testuser")
user_model_get = mock.Mock(return_value=user)
user_model = stub(objects=stub(get=user_model_get))

created_model_save = mock.Mock()
created_model = stub(
user=user,
email="test@example.com",
primary=primary if primary is not None else False,
verified=verified if verified is not None else False,
save=created_model_save,
)
email_model = mock.Mock(return_value=created_model)

adapter = EmailAdapter(user=user_model)
adapter.model = email_model

kwargs = {}
if primary is not None:
kwargs["primary"] = primary
if verified is not None:
kwargs["verified"] = verified

email = adapter.create("testuser", "test@example.com", **kwargs)

primary = primary if primary is not None else False
verified = verified if verified is not None else False

assert email.user == "testuser"
assert email.email == "test@example.com"

assert user_model_get.call_count == 1
assert user_model_get.call_args == (tuple(), {"username": "testuser"})

assert email_model.call_count == 1
assert email_model.call_args == (tuple(), {
"user": user,
"email": "test@example.com",
"primary": primary,
"verified": verified,
})

assert created_model_save.call_count == 1
assert created_model_save.call_args == (tuple(), {})


def test_emailadapter_serializer():
adapter = EmailAdapter(user=None)

email = adapter._serialize(stub(
user=stub(username="testuser"),
email="test@example.com",
primary=True,
verified=False,
))

assert isinstance(email, Email)
assert email == ("testuser", "test@example.com", True, False)
assert email.user == "testuser"
assert email.email == "test@example.com"
assert email.primary
assert not email.verified
68 changes: 68 additions & 0 deletions tests/unit/accounts/test_forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from unittest import mock
from pretend import stub

import pytest

from django import forms

from warehouse.accounts.forms import SignupForm, UserChangeForm


def test_signup_form_initalizes():
SignupForm()


def test_signup_form_clean_username_valid():
username_exists = mock.Mock(return_value=False)
model = stub(api=stub(username_exists=username_exists))
form = SignupForm({"username": "testuser"})
form.cleaned_data = {"username": "testuser"}
form.model = model

cleaned = form.clean_username()

assert cleaned == "testuser"
assert username_exists.call_count == 1
assert username_exists.call_args == (("testuser",), {})


def test_signup_form_clean_username_invalid():
username_exists = mock.Mock(return_value=True)
model = stub(api=stub(username_exists=username_exists))
form = SignupForm({"username": "testuser"})
form.cleaned_data = {"username": "testuser"}
form.model = model

with pytest.raises(forms.ValidationError):
form.clean_username()

assert username_exists.call_count == 1
assert username_exists.call_args == (("testuser",), {})


def test_signup_form_clean_passwords_valid():
data = {"password": "test password", "confirm_password": "test password"}
form = SignupForm(data)
form.cleaned_data = data

cleaned = form.clean_confirm_password()

assert cleaned == "test password"


def test_signup_form_clean_passwords_invalid():
data = {"password": "test password", "confirm_password": "different!"}
form = SignupForm(data)
form.cleaned_data = data

with pytest.raises(forms.ValidationError):
form.clean_confirm_password()


def test_user_change_form_initalizes():
UserChangeForm()


def test_user_change_form_clean_password():
form = UserChangeForm({"password": "fail"}, initial={"password": "epic"})
assert form.clean_password() == "epic"
File renamed without changes.
30 changes: 30 additions & 0 deletions tests/unit/accounts/test_regards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from pretend import stub
from unittest import mock

from warehouse.accounts.regards import UserCreator


def test_user_creator_basic():
UserCreator()


def test_user_creator():
user_creator = mock.Mock(return_value=stub(username="testuser"))
email_creator = mock.Mock(return_value=stub(email="test@example.com"))
mailer = mock.Mock()

creator = UserCreator(
user_creator=user_creator,
email_creator=email_creator,
mailer=mailer,
)

user = creator("testuser", "test@example.com", "testpassword")

assert user.username == "testuser"

assert user_creator.call_count == 1
assert user_creator.call_args == (("testuser", "testpassword"), {})

assert email_creator.call_count == 1
assert email_creator.call_args == (("testuser", "test@example.com"), {})
Loading