108 lines
3.5 KiB
Python
108 lines
3.5 KiB
Python
import pytest
|
|
from passlib.hash import sha512_crypt
|
|
|
|
from dpdapi.models import Domain, User
|
|
|
|
FIELDS = {"id", "created", "updated", "email", "domain"}
|
|
|
|
|
|
@pytest.fixture
|
|
def user(domain):
|
|
return User.objects.create(email="Jane@Example.com", password="x", domain=domain)
|
|
|
|
|
|
def test_list(api, user):
|
|
res = api.get("/api/users/")
|
|
assert res.status_code == 200
|
|
assert res.json() == [res.json()[0]]
|
|
assert set(res.json()[0]) == FIELDS
|
|
assert res.json()[0]["email"] == "jane@example.com"
|
|
assert res.json()[0]["domain"] == user.domain_id
|
|
|
|
|
|
def test_retrieve(api, user):
|
|
res = api.get(f"/api/users/{user.pk}/")
|
|
assert res.status_code == 200
|
|
assert set(res.json()) == FIELDS
|
|
assert str(user) == "jane@example.com"
|
|
|
|
|
|
def test_retrieve_missing(api, db):
|
|
assert api.get("/api/users/999/").status_code == 404
|
|
|
|
|
|
def test_create_hashes_password(api, domain):
|
|
data = {"email": "New@Example.com", "password": "hunter2", "domain": domain.pk}
|
|
res = api.post("/api/users/", data, content_type="application/json")
|
|
assert res.status_code == 201
|
|
assert set(res.json()) == FIELDS
|
|
assert res.json()["email"] == "new@example.com"
|
|
stored = User.objects.get().password
|
|
assert stored.startswith("$6$")
|
|
assert sha512_crypt.verify("hunter2", stored)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"data",
|
|
[
|
|
{"password": "p"},
|
|
{"email": "nope", "password": "p"},
|
|
{"email": "jane@example.com", "password": "p"},
|
|
{"email": "a@example.com"},
|
|
{"email": "a@example.com", "password": "p", "domain": 999},
|
|
],
|
|
)
|
|
def test_create_invalid(api, user, data):
|
|
data.setdefault("domain", user.domain_id)
|
|
res = api.post("/api/users/", data, content_type="application/json")
|
|
assert res.status_code == 400
|
|
assert User.objects.count() == 1
|
|
|
|
|
|
def test_update_hashes_password(api, user):
|
|
other = Domain.objects.create(name="other.org")
|
|
data = {"email": "jane@other.org", "password": "new-secret", "domain": other.pk}
|
|
res = api.put(f"/api/users/{user.pk}/", data, content_type="application/json")
|
|
assert res.status_code == 200
|
|
assert res.json()["email"] == "jane@other.org"
|
|
assert res.json()["domain"] == other.pk
|
|
user.refresh_from_db()
|
|
assert sha512_crypt.verify("new-secret", user.password)
|
|
|
|
|
|
def test_update_invalid(api, user):
|
|
res = api.put(f"/api/users/{user.pk}/", {"email": "x@example.com"}, content_type="application/json")
|
|
assert res.status_code == 400
|
|
|
|
|
|
def test_partial_update_keeps_password(api, user):
|
|
res = api.patch(f"/api/users/{user.pk}/", {"email": "J@example.com"}, content_type="application/json")
|
|
assert res.status_code == 200
|
|
assert res.json()["email"] == "j@example.com"
|
|
user.refresh_from_db()
|
|
assert user.password == "x"
|
|
|
|
|
|
def test_partial_update_hashes_password(api, user):
|
|
res = api.patch(f"/api/users/{user.pk}/", {"password": "p2"}, content_type="application/json")
|
|
assert res.status_code == 200
|
|
user.refresh_from_db()
|
|
assert sha512_crypt.verify("p2", user.password)
|
|
|
|
|
|
@pytest.mark.parametrize("field", ["email", "password", "domain"])
|
|
def test_partial_update_null(api, user, field):
|
|
res = api.patch(f"/api/users/{user.pk}/", {field: None}, content_type="application/json")
|
|
assert res.status_code == 400
|
|
assert field in str(res.json())
|
|
|
|
|
|
def test_delete(api, user):
|
|
assert api.delete(f"/api/users/{user.pk}/").status_code == 204
|
|
assert not User.objects.exists()
|
|
|
|
|
|
def test_deleting_domain_cascades(api, user):
|
|
assert api.delete(f"/api/domains/{user.domain_id}/").status_code == 204
|
|
assert not User.objects.exists()
|