Files
upstream-frappe-crm/crm/tests/test_password_setup.py
upstream-mirror db69de1c11
Some checks failed
Frontend / Unit Tests & Coverage (push) Has been skipped
Regenerate POT file (translatable strings) / Regenerate POT file (develop) (push) Failing after 1m13s
Regenerate POT file (translatable strings) / Regenerate POT file (main-hotfix) (push) Failing after 6s
Server / Tests (frappe ${{ matrix.frappe-branch }}) (push) Has been skipped
Server / Resolve frappe matrix (push) Failing after 1s
Frontend / Lint (push) Failing after 1s
Frontend / Production Build (push) Failing after 1s
Server / Coverage Wrap Up (push) Has been skipped
Frontend / Coverage Wrap Up (push) Has been skipped
snapshot of https://github.com/frappe/crm.git (develop, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:36:01 +05:00

113 lines
3.5 KiB
Python

# Copyright (c) 2026, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import frappe
from frappe.tests import IntegrationTestCase
from frappe.utils import sha256_hash
from frappe.utils.password import update_password
from crm.api.user import has_password, needs_password_setup
from crm.www.crm import get_context, redirect_to_set_password
STRONG_PASSWORD = "Qx7#mLp2vT9!"
def make_user(email, roles=None):
"""A user created the way Frappe Cloud and scripts create one: no password."""
user = frappe.get_doc(
doctype="User",
user_type="System User",
email=email,
first_name=email.split("@")[0].title(),
send_welcome_email=0,
).insert(ignore_permissions=True)
if roles:
user.append_roles(*roles)
user.save(ignore_permissions=True)
return user
class TestPasswordSetup(IntegrationTestCase):
def setUp(self):
self.user = make_user("no-password@example.com", roles=["System Manager"])
frappe.set_user(self.user.name)
def tearDown(self):
frappe.set_user("Administrator")
frappe.local.flags.redirect_location = None
frappe.local.flags.commit = False
frappe.local.system_settings = None
frappe.db.rollback()
def make_sso_user(self):
frappe.set_user("Administrator")
self.user.append("social_logins", {"provider": "google", "userid": "1234567890"})
self.user.save(ignore_permissions=True)
frappe.set_user(self.user.name)
# ---- needs_password_setup ----
def test_needs_setup_for_user_without_password(self):
self.assertTrue(needs_password_setup())
def test_does_not_need_setup_once_password_exists(self):
update_password(user=self.user.name, pwd=STRONG_PASSWORD)
self.assertTrue(has_password(self.user.name))
self.assertFalse(needs_password_setup())
def test_does_not_need_setup_for_sso_user(self):
"""No password is the correct state for someone who signs in via SSO."""
self.make_sso_user()
self.assertFalse(needs_password_setup())
def test_does_not_need_setup_when_password_login_is_disabled(self):
# not change_settings: it saves the doc, and validating System Settings
# fails on a bare site that has no language or time zone set
frappe.db.set_single_value("System Settings", "disable_user_pass_login", 1)
frappe.local.system_settings = None
self.assertFalse(needs_password_setup())
# ---- redirect ----
def test_redirects_to_set_password_page_with_a_working_key(self):
with self.assertRaises(frappe.Redirect) as raised:
redirect_to_set_password()
# a 301 would be cached by the browser and outlive the key it points at
self.assertEqual(raised.exception.http_status_code, 302)
# the reset key is written on a GET, which is rolled back otherwise
self.assertTrue(frappe.local.flags.commit)
link = frappe.local.flags.redirect_location
self.assertIn("/update-password?key=", link)
key = link.split("key=")[1]
self.assertEqual(frappe.db.get_value("User", self.user.name, "reset_password_key"), sha256_hash(key))
def test_no_redirect_for_user_who_has_a_password(self):
update_password(user=self.user.name, pwd=STRONG_PASSWORD)
redirect_to_set_password()
self.assertIsNone(frappe.local.flags.redirect_location)
def test_no_redirect_for_sso_user(self):
self.make_sso_user()
redirect_to_set_password()
self.assertIsNone(frappe.local.flags.redirect_location)
def test_crm_page_load_redirects_a_user_without_a_password(self):
"""The redirect is wired into the page the user actually opens."""
with self.assertRaises(frappe.Redirect):
get_context()
self.assertIn("/update-password?key=", frappe.local.flags.redirect_location)