diff --git a/app/Login.py b/app/Login.py index d82a6d1..efd0ab4 100644 --- a/app/Login.py +++ b/app/Login.py @@ -79,6 +79,8 @@ class UserName: def validate(self): if len(self.username) > 20: return f'{self.username} is too long. The user name cannot exceed 20 characters.' + if len(self.username) == 0: # 用户名必须不为空 + return 'You can`t use an empty user name.' if self.username.startswith('.'): # a user name must not start with a dot return 'Period (.) is not allowed as the first letter in the user name.' if ' ' in self.username: # a user name must not include a whitespace diff --git a/app/templates/signup.html b/app/templates/signup.html index 48cf932..46d9a2e 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -29,8 +29,8 @@ password2 = $("#password2").val().trim(); // 基本表单验证 - if (username === "" || password === "" || password2 === "") { - alert('输入不能为空!'); + if (password === "" || password2 === "") { + alert('输入密码不能为空!'); return false; } if (password.includes(' ') || password2.includes(' ')) { diff --git a/app/test/test_integration_login.py b/app/test/test_integration_login.py new file mode 100644 index 0000000..793c4d7 --- /dev/null +++ b/app/test/test_integration_login.py @@ -0,0 +1,74 @@ +# test_integration_username.py + +import pytest +import sys +import os + +# 获取文件所在目录的上两级目录(EnglishPal) +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) +sys.path.append(project_root) + +from app.Login import add_user, check_username_availability + + +# 模拟数据库行为 +class MockUserDB: + def __init__(self): + self.users = {} + + def insert_user(self, username, password, start_date, expiry_date): + if username in self.users: + return False + self.users[username] = { + 'password': password, + 'start_date': start_date, + 'expiry_date': expiry_date + } + return True + + def get_user_by_username(self, username): + return self.users.get(username) + + +original_insert_user = None +original_get_user_by_username = None + + +@pytest.fixture(autouse=True) +def setup_and_teardown(): + global original_insert_user, original_get_user_by_username + + from app.Login import insert_user as original_iu, get_user_by_username as original_gubu + original_insert_user = original_iu + original_get_user_by_username = original_gubu + + mock_db = MockUserDB() + + def mock_insert_user(**kwargs): + return mock_db.insert_user(**kwargs) + + def mock_get_user_by_username(username): + return mock_db.get_user_by_username(username) + + from app.Login import insert_user, get_user_by_username + insert_user = mock_insert_user + get_user_by_username = mock_get_user_by_username + + yield + + from app.Login import insert_user, get_user_by_username + insert_user = original_insert_user + get_user_by_username = original_get_user_by_username + + +def test_add_user_with_empty_username_fails(): + with pytest.raises(ValueError) as exc_info: + add_user('', 'Password123') + assert "Attribute User.name is required" in str(exc_info.value) + + +def test_add_user_with_valid_username_succeeds(): + result = add_user('validuser', 'Password123') + assert result is None # 如果 add_user 不返回值,则断言无异常即可 + assert check_username_availability('validuser') is False # 用户已存在 + diff --git a/app/test_login.py b/app/test_login.py new file mode 100644 index 0000000..cd8f418 --- /dev/null +++ b/app/test_login.py @@ -0,0 +1,63 @@ +# test_username.py + +import pytest +from app.Login import UserName + + +def test_username_too_long(): + username = 'a' * 21 + result = UserName(username).validate() + assert username in result + assert 'too long' in result + + +def test_username_empty(): + username = '' + result = UserName(username).validate() + assert 'empty user name' in result + + +def test_username_starts_with_dot(): + username = '.startwithdot' + result = UserName(username).validate() + assert 'Period (.) is not allowed' in result + + +def test_username_contains_space(): + username = 'has space' + result = UserName(username).validate() + assert 'Whitespace is not allowed' in result + + +def test_username_contains_invalid_punctuation(): + invalid_chars = ['@', '#', '$', '!', '{', '}', '[', ']'] + for c in invalid_chars: + username = f'bad{c}name' + result = UserName(username).validate() + assert f'{c} is not allowed' in result, f"Failed on char: {c}" + + +def test_username_uses_restricted_word(): + restricted_words = ['signup', 'login', 'logout', 'reset', 'mark', 'back', + 'unfamiliar', 'familiar', 'del', 'admin'] + for word in restricted_words: + result = UserName(word).validate() + assert 'restricted word' in result, f"Failed on word: {word}" + + +def test_username_contains_chinese(): + username = '用户名' + result = UserName(username).validate() + assert 'Chinese characters are not allowed' in result + + +def test_valid_username(): + valid_usernames = [ + 'valid_user', + 'valid.user', + 'user123', + 'A_veryValidName', + ] + for username in valid_usernames: + result = UserName(username).validate() + assert result == 'OK', f"Failed on valid username: {username}" diff --git a/current_branch_commit_messages.txt b/current_branch_commit_messages.txt new file mode 100644 index 0000000..06f4fac Binary files /dev/null and b/current_branch_commit_messages.txt differ