diff options
| author | Andrew Godwin | 2022-12-05 19:21:00 -0700 | 
|---|---|---|
| committer | Andrew Godwin | 2022-12-05 19:24:46 -0700 | 
| commit | a31f676b46a4d904954b8b7227dcde779aedca54 (patch) | |
| tree | d00fa3e022ff08f154f431777ba37e2f43127fd6 /tests | |
| parent | da9a3d853eda1173ac8913908d512fb9babbd136 (diff) | |
| download | takahe-a31f676b46a4d904954b8b7227dcde779aedca54.tar.gz takahe-a31f676b46a4d904954b8b7227dcde779aedca54.tar.bz2 takahe-a31f676b46a4d904954b8b7227dcde779aedca54.zip | |
Policy pages and signup tests.
Fixes #113
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/activities/models/test_post.py | 24 | ||||
| -rw-r--r-- | tests/conftest.py | 5 | ||||
| -rw-r--r-- | tests/users/views/test_auth.py | 125 | 
3 files changed, 100 insertions, 54 deletions
| diff --git a/tests/activities/models/test_post.py b/tests/activities/models/test_post.py index 21e7000..00db61b 100644 --- a/tests/activities/models/test_post.py +++ b/tests/activities/models/test_post.py @@ -1,7 +1,4 @@ -import asyncio -  import pytest -from asgiref.sync import async_to_sync  from pytest_httpx import HTTPXMock  from activities.models import Post, PostStates @@ -128,21 +125,8 @@ def test_linkify_mentions_local(identity, remote_identity):      assert post.safe_content_local() == "<p>@test@example.com, welcome!</p>" -async def stator_process_tasks(stator): -    """ -    Guarded wrapper to simply async_to_sync and ensure all stator tasks are -    run to completion without blocking indefinitely. -    """ -    await asyncio.wait_for(stator.fetch_and_process_tasks(), timeout=1) -    for _ in range(100): -        if not stator.tasks: -            break -        stator.remove_completed_tasks() -        await asyncio.sleep(0.01) - -  @pytest.mark.django_db -def test_post_transitions(identity, stator_runner): +def test_post_transitions(identity, stator):      # Create post      post = Post.objects.create( @@ -153,18 +137,18 @@ def test_post_transitions(identity, stator_runner):      )      # Test: | --> new --> fanned_out      assert post.state == str(PostStates.new) -    async_to_sync(stator_process_tasks)(stator_runner) +    stator.run_single_cycle_sync()      post = Post.objects.get(id=post.id)      assert post.state == str(PostStates.fanned_out)      # Test: fanned_out --> (forced) edited --> edited_fanned_out      Post.transition_perform(post, PostStates.edited) -    async_to_sync(stator_process_tasks)(stator_runner) +    stator.run_single_cycle_sync()      post = Post.objects.get(id=post.id)      assert post.state == str(PostStates.edited_fanned_out)      # Test: edited_fanned_out --> (forced) deleted --> deleted_fanned_out      Post.transition_perform(post, PostStates.deleted) -    async_to_sync(stator_process_tasks)(stator_runner) +    stator.run_single_cycle_sync()      post = Post.objects.get(id=post.id)      assert post.state == str(PostStates.deleted_fanned_out) diff --git a/tests/conftest.py b/tests/conftest.py index a3feaca..80622f0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -60,7 +60,10 @@ def config_system(keypair):          system_actor_private_key=keypair["private_key"],          system_actor_public_key=keypair["public_key"],      ) +    Config.__forced__ = True      yield Config.system +    Config.__forced__ = False +    del Config.system  @pytest.fixture @@ -126,7 +129,7 @@ def remote_identity() -> Identity:  @pytest.fixture -def stator_runner(config_system) -> StatorRunner: +def stator(config_system) -> StatorRunner:      """      Return an initialized StatorRunner for tests that need state transitioning      to happen. diff --git a/tests/users/views/test_auth.py b/tests/users/views/test_auth.py index f3a34c0..6dd1010 100644 --- a/tests/users/views/test_auth.py +++ b/tests/users/views/test_auth.py @@ -1,60 +1,119 @@ -from unittest import mock -  import pytest +from django.core import mail +from pytest_django.asserts import assertContains, assertNotContains -from core.models import Config -from users.models import User - - -@pytest.fixture -def config_system(): -    # TODO: Good enough for now, but a better Config mocking system is needed -    result = Config.load_system() -    with mock.patch("core.models.Config.load_system", return_value=result): -        yield result +from users.models import Invite, User  @pytest.mark.django_db  def test_signup_disabled(client, config_system): +    """ +    Tests that disabling signup takes effect +    """      # Signup disabled and no signup text      config_system.signup_allowed = False -    resp = client.get("/auth/signup/") -    assert resp.status_code == 200 -    content = str(resp.content) -    assert "Not accepting new users at this time" in content -    assert "<button>Create</button>" not in content +    response = client.get("/auth/signup/") +    assertContains(response, "Not accepting new users at this time", status_code=200) +    assertNotContains(response, "<button>Create</button>")      # Signup disabled with signup text configured      config_system.signup_text = "Go away!!!!!!" -    resp = client.get("/auth/signup/") -    assert resp.status_code == 200 -    content = str(resp.content) -    assert "Go away!!!!!!" in content +    response = client.get("/auth/signup/") +    assertContains(response, "Go away!!!!!!", status_code=200)      # Ensure direct POST doesn't side step guard -    resp = client.post( +    response = client.post(          "/auth/signup/", data={"email": "test_signup_disabled@example.org"}      ) -    assert resp.status_code == 200 +    assert response.status_code == 200      assert not User.objects.filter(email="test_signup_disabled@example.org").exists()      # Signup enabled      config_system.signup_allowed = True -    resp = client.get("/auth/signup/") -    assert resp.status_code == 200 -    content = str(resp.content) -    assert "Not accepting new users at this time" not in content -    assert "<button>Create</button>" in content +    response = client.get("/auth/signup/") +    assertContains(response, "<button>Create</button>", status_code=200) +    assertNotContains(response, "Not accepting new users at this time")  @pytest.mark.django_db  def test_signup_invite_only(client, config_system): +    """ +    Tests that invite codes work with signup +    """      config_system.signup_allowed = True      config_system.signup_invite_only = True -    resp = client.get("/auth/signup/") -    assert resp.status_code == 200 -    content = str(resp.content) -    assert 'name="invite_code"' in content +    # Try to sign up without an invite code +    response = client.post("/auth/signup/", {"email": "random@example.com"}) +    assertNotContains(response, "Email Sent", status_code=200) + +    # Make an invite code for any email +    invite_any = Invite.create_random() +    response = client.post( +        "/auth/signup/", +        {"email": "random@example.com", "invite_code": invite_any.token}, +    ) +    assertNotContains(response, "not a valid invite") +    assertContains(response, "Email Sent", status_code=200) + +    # Make sure you can't reuse an invite code +    response = client.post( +        "/auth/signup/", +        {"email": "random2@example.com", "invite_code": invite_any.token}, +    ) +    assertNotContains(response, "Email Sent", status_code=200) + +    # Make an invite code for a specific email +    invite_specific = Invite.create_random(email="special@example.com") +    response = client.post( +        "/auth/signup/", +        {"email": "random3@example.com", "invite_code": invite_specific.token}, +    ) +    assertContains(response, "valid invite code for this email", status_code=200) +    assertNotContains(response, "Email Sent") +    response = client.post( +        "/auth/signup/", +        {"email": "special@example.com", "invite_code": invite_specific.token}, +    ) +    assertContains(response, "Email Sent", status_code=200) + + +@pytest.mark.django_db +def test_signup_policy(client, config_system): +    """ +    Tests that you must agree to policies to sign up +    """ +    config_system.signup_allowed = True +    config_system.signup_invite_only = False + +    # Make sure we can sign up when there are no policies +    response = client.post("/auth/signup/", {"email": "random@example.com"}) +    assertContains(response, "Email Sent", status_code=200) + +    # Make sure that's then denied when we have a policy in place +    config_system.policy_rules = "You must love unit tests" +    response = client.post("/auth/signup/", {"email": "random2@example.com"}) +    assertContains(response, "field is required", status_code=200) +    assertNotContains(response, "Email Sent") + + +@pytest.mark.django_db +def test_signup_email(client, config_system, stator): +    """ +    Tests that you can sign up and get an email sent to you +    """ +    config_system.signup_allowed = True +    config_system.signup_invite_only = False + +    # Sign up with a user +    response = client.post("/auth/signup/", {"email": "random@example.com"}) +    assertContains(response, "Email Sent", status_code=200) + +    # Verify that made a user object and a password reset +    user = User.objects.get(email="random@example.com") +    assert user.password_resets.exists() -    # TODO: Actually test this +    # Run Stator and verify it sends the email +    assert len(mail.outbox) == 0 +    stator.run_single_cycle_sync() +    assert len(mail.outbox) == 1 | 
