diff --git a/community/lms/web_form/profile/profile.js b/community/lms/web_form/profile/profile.js index 027cef49..286ed9b5 100644 --- a/community/lms/web_form/profile/profile.js +++ b/community/lms/web_form/profile/profile.js @@ -1,7 +1,14 @@ frappe.ready(function () { + frappe.web_form.after_load = () => { if (!frappe.utils.get_url_arg("name")) { window.location.href = `/edit-profile?name=${frappe.session.user}`; } } + + frappe.web_form.after_save = () => { + setTimeout(() => { + window.location.href = `/${frappe.web_form.get_value(["username"])}`; + }) + } }) diff --git a/community/lms/web_form/profile/profile.json b/community/lms/web_form/profile/profile.json index 4c3fcc7d..3ba731a9 100644 --- a/community/lms/web_form/profile/profile.json +++ b/community/lms/web_form/profile/profile.json @@ -11,6 +11,7 @@ "apply_document_permissions": 0, "breadcrumbs": "", "button_label": "Save", + "client_script": "", "creation": "2021-06-30 13:48:13.682851", "custom_css": "[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}", "doc_type": "User", @@ -20,7 +21,7 @@ "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2021-07-14 17:15:15.424855", + "modified": "2021-08-06 14:40:39.013776", "modified_by": "Administrator", "module": "LMS", "name": "profile", @@ -72,6 +73,18 @@ "reqd": 0, "show_in_filter": 0 }, + { + "allow_read_on_all_link_options": 0, + "fieldname": "username", + "fieldtype": "Data", + "hidden": 0, + "label": "Username", + "max_length": 0, + "max_value": 0, + "read_only": 0, + "reqd": 0, + "show_in_filter": 0 + }, { "allow_read_on_all_link_options": 0, "description": "Get your globally recognized avatar from Gravatar.com", diff --git a/community/overrides/test_user.py b/community/overrides/test_user.py new file mode 100644 index 00000000..cb6ce268 --- /dev/null +++ b/community/overrides/test_user.py @@ -0,0 +1,54 @@ +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt + +# import frappe +import unittest +import frappe + +class TestCustomUser(unittest.TestCase): + + def test_with_basic_username(self): + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test_with_basic_username@example.com", + "first_name": "Username" + }).insert() + self.assertEqual(new_user.username, "username") + + def test_without_username(self): + """ The user in this test has the same first name as the user of the test test_with_basic_username. + In such cases frappe makes the username of the second user empty. + The condition in community app should override this and save a username. """ + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test-without-username@example.com", + "first_name": "Username" + }).insert() + self.assertTrue(new_user.username) + + def test_with_illegal_characters(self): + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test_with_illegal_characters@example.com", + "first_name": "Username$$" + }).insert() + self.assertEqual(new_user.username[:8], "username") + + def test_with_hyphen_at_end(self): + new_user = frappe.get_doc({ + "doctype": "User", + "email": "test_with_hyphen_at_end@example.com", + "first_name": "Username---" + }).insert() + length = len(new_user.username) + self.assertNotEqual(new_user.username[length-1], "-") + + @classmethod + def tearDownClass(cls) -> None: + users = [ + "test_with_basic_username@example.com", + "test-without-username@example.com", + "test_with_illegal_characters@example.com", + "test_with_hyphen_at_end@example.com" + ] + frappe.db.delete("User", {"name": ["in", users]}) diff --git a/community/overrides/user.py b/community/overrides/user.py index bcb1496a..0a85e44c 100644 --- a/community/overrides/user.py +++ b/community/overrides/user.py @@ -2,9 +2,50 @@ import frappe from frappe.core.doctype.user.user import User from frappe.utils import cint import hashlib +import random +import re +from frappe import _ class CustomUser(User): + def validate(self): + super(CustomUser, self).validate() + self.validate_username_characters() + + def validate_username_characters(self): + if self.is_new(): + + if self.username.find(" "): + self.username.replace(" ", "") + + if not re.match("^[A-Za-z0-9_]*$", self.username): + self.username = self.remove_illegal_characters() + + if not self.username: + self.username = self.get_username_from_first_name() + + if self.username_exists(): + self.username = self.remove_illegal_characters() + str(random.randint(0, 99)) + + else: + if not re.match("^[A-Za-z0-9_-]*$", self.username): + frappe.throw(_("Username can only contain alphabets, numbers, hyphen and underscore.")) + + if self.username[0] == "-" or self.username[len(self.username) - 1] == "-": + frappe.throw(_("First and Last character of username cannot be Hyphen(-).")) + + def get_username_from_first_name(self): + return frappe.scrub(self.first_name) + str(random.randint(0, 99)) + + def remove_illegal_characters(self): + username = ''.join([c for c in self.username if c.isalnum() or c in ['-', '_']]) + while username[0] == "-" or username[len(username) - 1] == "-": + if username[0] == "-": + username = username[1:] + if username[len(username) - 1]: + username = username[:1] + return username + def get_authored_courses(self) -> int: """Returns the number of courses authored by this user. """