def test_delete_public_snapshot(client: TestClient, session: db.Session, user_token, deck): """Must properly clean up stream entries when deleting a public snapshot""" user, token = user_token snapshot = create_snapshot_for_deck(session, user, deck, is_public=True) assert session.query(Stream).count() == 1 response = client.delete(f"/v2/decks/{snapshot.id}", headers={"Authorization": f"Bearer {token}"}) assert response.status_code == status.HTTP_204_NO_CONTENT assert session.query(Stream).count() == 0 session.refresh(snapshot) assert snapshot.is_deleted == True
def test_delete_latest_public_snapshot(client: TestClient, session: db.Session, user_token, deck): """Must properly revert to older snapshot in stream when deleting a public snapshot""" user, token = user_token snapshot1 = create_snapshot_for_deck(session, user, deck, is_public=True) snapshot2 = create_snapshot_for_deck(session, user, deck, is_public=True) assert session.query(Stream).count() == 1 response = client.delete(f"/v2/decks/{snapshot2.id}", headers={"Authorization": f"Bearer {token}"}) assert response.status_code == status.HTTP_204_NO_CONTENT stream_entry = session.query(Stream).first() assert stream_entry.entity_id == snapshot1.entity_id session.refresh(snapshot2) assert snapshot2.is_deleted == True
def test_reset_password(client: TestClient, session: db.Session): """Password reset must reset the password""" user, _ = utils.create_user_token(session) user.reset_uuid = uuid.uuid4() session.commit() new_password = utils.generate_random_chars(8) original_hash = user.password response = client.post( f"/v2/reset/{user.reset_uuid}", json={"password": new_password, "password_confirm": new_password}, ) assert response.status_code == status.HTTP_200_OK session.refresh(user) assert original_hash != user.password
def test_request_password_reset(client: TestClient, session: db.Session, monkeypatch): """Password reset works properly when emailing the request""" def _always_true(*args, **kwargs): return True # send_email is covered by unit tests, so it's safe to patch the whole function monkeypatch.setattr(api.views.auth, "send_message", _always_true) user, _ = utils.create_user_token(session) assert user.reset_uuid is None response = client.post("/v2/reset", json={"email": user.email}) assert response.status_code == status.HTTP_200_OK session.refresh(user) assert user.reset_uuid is not None
def test_admin_required_normal_user(client: TestClient, session: db.Session): """Non-admins cannot access admin_required dependency paths""" user1, token = utils.create_user_token(session) user2, _ = utils.create_user_token(session) user2.username = "******" session.commit() response = client.patch( f"/v2/players/{user2.badge}", headers={"Authorization": f"Bearer {token}"}, json={"username": "******", "moderation_notes": "Bad name."}, ) assert response.status_code == status.HTTP_403_FORBIDDEN, response.json() session.refresh(user2) assert user2.username == "oldname"
def test_put_deck_update(client: TestClient, session: db.Session, user_token): """Must allow saving a new copy of an existing deck""" user, token = user_token deck = create_deck_for_user(session, user) valid_deck = _valid_deck_dict(session) valid_deck["id"] = deck.id new_title = generate_random_chars(8) assert new_title != deck.title valid_deck["title"] = new_title response = client.put("/v2/decks", json=valid_deck, headers={"Authorization": f"Bearer {token}"}) assert response.status_code == status.HTTP_200_OK session.refresh(deck) assert deck.title == new_title
def test_patch_release(client: TestClient, session: db.Session): """Patching a release to set it public must work""" master_set = Release(name="Master Set") session.add(master_set) session.commit() assert master_set.is_public == False admin, token = create_admin_token(session) response = client.patch( f"/v2/releases/{master_set.stub}", json={"is_public": True}, headers={"Authorization": f"Bearer {token}"}, ) assert response.status_code == status.HTTP_200_OK session.refresh(master_set) assert master_set.is_public == True
def test_ban_user(client: TestClient, session: db.Session): """Admins can ban users""" admin, token = utils.create_admin_token(session) user, _ = utils.create_user_token(session) response = client.patch( f"/v2/players/{user.badge}", headers={"Authorization": f"Bearer {token}"}, json={ "is_banned": True, "moderation_notes": "Bad user." }, ) assert response.status_code == status.HTTP_200_OK, response.json() session.refresh(user) assert user.is_banned == True
def test_patch_user(client: TestClient, session: db.Session): """Patching user must only update the fields that were passed in""" user, token = utils.create_user_token(session) user.description = utils.generate_random_chars(8) original_username = user.username session.commit() new_description = utils.generate_random_chars(4) response = client.patch( "/v2/players/me", json={"description": new_description}, headers={"Authorization": f"Bearer {token}"}, ) assert response.status_code == status.HTTP_200_OK, response.json() session.refresh(user) assert user.username == original_username assert user.description == new_description
def test_user_post_password(client: TestClient, session: db.Session): """Can update own password""" user, current_password = utils.create_user_password(session) user, token = utils.create_user_token(session, user=user) password = utils.generate_random_chars(8) response = client.post( "/v2/players/me/password", json={ "current_password": current_password, "password": password, "password_confirm": password, }, headers={"Authorization": f"Bearer {token}"}, ) assert response.status_code == status.HTTP_200_OK session.refresh(user) assert verify_password(password, user.password) is True
def test_edit_snapshot(client: TestClient, session: db.Session, user1, snapshot1): """Users can edit their own snapshots""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) new_title = "New title" new_description = "New description" response = client.patch( f"/v2/decks/snapshots/{snapshot1.id}", headers={"Authorization": f"Bearer {token}"}, json={"title": new_title, "description": new_description}, ) assert response.status_code == status.HTTP_200_OK session.refresh(snapshot1) assert snapshot1.title == new_title assert snapshot1.description == new_description
def test_request_password_reset_local_debugging( client: TestClient, session: db.Session, monkeypatch ): """Reset UUIDs are properly generated for password reset requests when debugging locally""" def _always_false(*args, **kwargs): return False # send_email is covered by unit tests, so it's safe to patch the whole function monkeypatch.setattr(api.views.auth, "send_message", _always_false) utils.monkeypatch_settings(monkeypatch, {"debug": True}) user, _ = utils.create_user_token(session) assert user.reset_uuid is None response = client.post("/v2/reset", json={"email": user.email}) assert response.status_code == status.HTTP_400_BAD_REQUEST session.refresh(user) assert user.reset_uuid is not None
def test_reset_password_then_login( client: TestClient, session: db.Session, monkeypatch ): """Users must be able to log in after requesting a password reset""" def _always_true(*args, **kwargs): return True # send_email is covered by unit tests, so it's safe to patch the whole function monkeypatch.setattr(api.views.auth, "send_message", _always_true) user, password = utils.create_user_password(session) response = client.post("/v2/reset", json={"email": user.email}) assert response.status_code == status.HTTP_200_OK session.refresh(user) assert user.reset_uuid is not None # And then verify that we can login response = client.post("/v2/token", {"username": user.email, "password": password}) assert response.status_code == status.HTTP_200_OK
def test_edit_snapshot_clear_description( client: TestClient, session: db.Session, user1, snapshot1 ): """Users can pass empty strings to clear descriptions""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) old_title = snapshot1.title new_description = "" response = client.patch( f"/v2/decks/snapshots/{snapshot1.id}", headers={"Authorization": f"Bearer {token}"}, json={"description": new_description}, ) assert response.status_code == status.HTTP_200_OK session.refresh(snapshot1) assert snapshot1.title == old_title assert snapshot1.description is None
def test_edit_snapshot_moderate_description( client: TestClient, session: db.Session, snapshot1 ): """Moderating a description saves the old description""" admin, token = create_admin_token(session) old_description = snapshot1.description new_description = "New description" moderation_notes = "Changed description" response = client.patch( f"/v2/decks/snapshots/{snapshot1.id}", headers={"Authorization": f"Bearer {token}"}, json={"description": new_description, "moderation_notes": moderation_notes}, ) assert response.status_code == status.HTTP_200_OK session.refresh(snapshot1) assert snapshot1.description == new_description assert snapshot1.original_description == old_description assert snapshot1.is_moderated is True assert snapshot1.moderation_notes == moderation_notes
def test_delete_root_deck(client: TestClient, session: db.Session, user_token): """Must delete stream entry and mark all snapshots deleted when deleting root deck""" user, token = user_token deck = create_deck_for_user(session, user) private_snapshot = create_snapshot_for_deck(session, user, deck) public_snapshot = create_snapshot_for_deck(session, user, deck, is_public=True) assert session.query(Stream).count() == 1 response = client.delete(f"/v2/decks/{deck.id}", headers={"Authorization": f"Bearer {token}"}) assert response.status_code == status.HTTP_204_NO_CONTENT assert session.query(Stream).count() == 0 session.refresh(deck) session.refresh(private_snapshot) session.refresh(public_snapshot) assert deck.is_deleted == True assert private_snapshot.is_deleted == True assert public_snapshot.is_deleted == True