软件工程结对作业测试代码
模块一:
`
import unittest
import uuid
from enum import Enum
from typing import List, Optional, Dict
Mock classes and exceptions for testing
class Role(Enum):
USER = "USER"
ADMIN = "ADMIN"
class InvalidEmailError(Exception):
pass
class UserAlreadyExistsError(Exception):
pass
class UserNotFoundError(Exception):
pass
class InvalidCredentialsError(Exception):
pass
class PermissionDeniedError(Exception):
pass
class User:
def init(self, user_id: str, username: str, email: str, password_hash: str, role: Role):
self.user_id = user_id
self.username = username
self.email = email
self.password_hash = password_hash
self.role = role
self.is_active = True
@staticmethod
def hash_password(password: str) -> str:
    return f"hashed_{password}"
def verify_password(self, password: str) -> bool:
    return self.password_hash == f"hashed_{password}"
UserManagement class (copied from provided code for completeness)
class UserManagement:
EMAIL_PATTERN = r'[1]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$'
def __init__(self):
    self._users = {}
def _validate_email(self, email: str) -> None:
    import re
    if not re.match(self.EMAIL_PATTERN, email):
        raise InvalidEmailError("Invalid email format")
def register_user(self, username: str, email: str, password: str, role: Role = Role.USER) -> str:
    self._validate_email(email)
    if email in self._users:
        raise UserAlreadyExistsError("Email already registered")
    user_id = str(uuid.uuid4())
    password_hash = User.hash_password(password)
    user = User(user_id=user_id, username=username, email=email, password_hash=password_hash, role=role)
    self._users[email] = user
    return user_id
def login_user(self, email: str, password: str) -> User:
    if email not in self._users:
        raise UserNotFoundError("User not found")
    user = self._users[email]
    if not user.is_active:
        raise InvalidCredentialsError("Account is disabled")
    if not user.verify_password(password):
        raise InvalidCredentialsError("Incorrect password")
    return user
def logout_user(self, email: str) -> None:
    if email not in self._users:
        raise UserNotFoundError("User not found")
def reset_password(self, email: str) -> str:
    if email not in self._users:
        raise UserNotFoundError("User not found")
    reset_token = str(uuid.uuid4())
    return reset_token
def update_password(self, email: str, new_password: str) -> None:
    if email not in self._users:
        raise UserNotFoundError("User not found")
    user = self._users[email]
    user.password_hash = User.hash_password(new_password)
def get_user_info(self, email: str, requesting_user: Optional[User]) -> User:
    if email not in self._users:
        raise UserNotFoundError("User not found")
    user = self._users[email]
    if requesting_user is not None and requesting_user.email != email and requesting_user.role != Role.ADMIN:
        raise PermissionDeniedError("Permission denied")
    return user
def get_user_by_id(self, user_id: str, requesting_user: Optional[User]) -> User:
    for user in self._users.values():
        if user.user_id == user_id:
            if requesting_user is not None and requesting_user.user_id != user_id and requesting_user.role != Role.ADMIN:
                raise PermissionDeniedError("Permission denied")
            return user
    raise UserNotFoundError(f"User {user_id} not found")
def list_users(self, requesting_user: User) -> List[User]:
    if requesting_user.role != Role.ADMIN:
        raise PermissionDeniedError("Permission denied")
    return list(self._users.values())
def disable_user(self, target_email: str, requesting_user: User) -> None:
    if requesting_user.role != Role.ADMIN:
        raise PermissionDeniedError("Permission denied")
    if target_email not in self._users:
        raise UserNotFoundError("User not found")
    self._users[target_email].is_active = False
def is_user_valid(self, user_id: str) -> bool:
    for user in self._users.values():
        if user.user_id == user_id:
            return user.is_active
    return False
def is_admin(self, user_id: str) -> bool:
    for user in self._users.values():
        if user.user_id == user_id and user.is_active:
            return user.role == Role.ADMIN
    return False
def are_users_valid(self, user_ids: List[str]) -> Dict[str, bool]:
    return {user_id: self.is_user_valid(user_id) for user_id in user_ids}
Test cases for boundary condition coverage
class TestUserManagement(unittest.TestCase):
def setUp(self):
self.um = UserManagement()
self.user_id = self.um.register_user("testuser", "test@example.com", "password123", Role.USER)
self.admin_id = self.um.register_user("admin", "admin@example.com", "admin123", Role.ADMIN)
def test_validate_email_valid(self):
    # Valid email formats
    valid_emails = [
        "a@b.co",  # Minimum length domain
        "user@domain.com",  # Standard email
        "user.name@sub.domain.co.uk",  # Complex email with subdomains
        "user+label@domain.com"  # Email with + label
    ]
    for email in valid_emails:
        with self.subTest(email=email):
            self.um._validate_email(email)  # Should not raise exception
def test_validate_email_invalid(self):
    # Invalid email formats
    invalid_emails = [
        "",  # Empty string
        "user@domain",  # Missing top-level domain
        "@domain.com",  # Missing local part
        "user@.com",  # Missing domain
        "user@domain.c",  # Top-level domain too short
        "user@domain..com",  # Double dot
        "user..name@domain.com",  # Double dot in local part
        "user@domain,com",  # Invalid character
        " user@domain.com"  # Leading space
    ]
    for email in invalid_emails:
        with self.subTest(email=email):
            with self.assertRaises(InvalidEmailError):
                self.um._validate_email(email)
def test_register_user_valid(self):
    # Valid registration
    user_id = self.um.register_user("newuser", "newuser@example.com", "pass123")
    self.assertIsNotNone(user_id)
    self.assertTrue(isinstance(user_id, str))
    self.assertIn("newuser@example.com", self.um._users)
def test_register_user_duplicate_email(self):
    # Duplicate email
    with self.assertRaises(UserAlreadyExistsError):
        self.um.register_user("testuser2", "test@example.com", "password123")
def test_register_user_invalid_email(self):
    # Invalid email format
    with self.assertRaises(InvalidEmailError):
        self.um.register_user("testuser2", "invalid.email", "password123")
def test_register_user_empty_inputs(self):
    # Empty username, email, or password
    with self.assertRaises(InvalidEmailError):
        self.um.register_user("", "test2@example.com", "password123")
    with self.assertRaises(InvalidEmailError):
        self.um.register_user("testuser2", "", "password123")
    with self.assertRaises(TypeError):  # Assuming password validation in hash_password
        self.um.register_user("testuser2", "test2@example.com", "")
def test_login_user_success(self):
    # Successful login
    user = self.um.login_user("test@example.com", "password123")
    self.assertEqual(user.email, "test@example.com")
    self.assertEqual(user.username, "testuser")
def test_login_user_not_found(self):
    # Non-existent email
    with self.assertRaises(UserNotFoundError):
        self.um.login_user("nonexistent@example.com", "password123")
def test_login_user_incorrect_password(self):
    # Incorrect password
    with self.assertRaises(InvalidCredentialsError):
        self.um.login_user("test@example.com", "wrongpassword")
def test_login_user_disabled_account(self):
    # Disabled account
    admin = self.um._users["admin@example.com"]
    self.um.disable_user("test@example.com", admin)
    with self.assertRaises(InvalidCredentialsError):
        self.um.login_user("test@example.com", "password123")
def test_logout_user_valid(self):
    # Valid logout
    self.um.logout_user("test@example.com")  # Should not raise exception
def test_logout_user_not_found(self):
    # Non-existent email
    with self.assertRaises(UserNotFoundError):
        self.um.logout_user("nonexistent@example.com")
def test_reset_password_valid(self):
    # Valid reset
    token = self.um.reset_password("test@example.com")
    self.assertIsNotNone(token)
    self.assertTrue(isinstance(token, str))
def test_reset_password_not_found(self):
    # Non-existent email
    with self.assertRaises(UserNotFoundError):
        self.um.reset_password("nonexistent@example.com")
def test_update_password_valid(self):
    # Valid password update
    self.um.update_password("test@example.com", "newpassword123")
    user = self.um.login_user("test@example.com", "newpassword123")
    self.assertEqual(user.email, "test@example.com")
def test_update_password_not_found(self):
    # Non-existent email
    with self.assertRaises(UserNotFoundError):
        self.um.update_password("nonexistent@example.com", "newpassword123")
def test_get_user_info_self(self):
    # User accessing own info
    user = self.um._users["test@example.com"]
    result = self.um.get_user_info("test@example.com", user)
    self.assertEqual(result.email, "test@example.com")
def test_get_user_info_admin(self):
    # Admin accessing user info
    admin = self.um._users["admin@example.com"]
    result = self.um.get_user_info("test@example.com", admin)
    self.assertEqual(result.email, "test@example.com")
def test_get_user_info_unauthorized(self):
    # Non-admin accessing another user's info
    user = self.um._users["test@example.com"]
    with self.assertRaises(PermissionDeniedError):
        self.um.get_user_info("admin@example.com", user)
def test_get_user_info_not_found(self):
    # Non-existent email
    user = self.um._users["test@example.com"]
    with self.assertRaises(UserNotFoundError):
        self.um.get_user_info("nonexistent@example.com", user)
def test_get_user_by_id_self(self):
    # User accessing own info by ID
    user = self.um._users["test@example.com"]
    result = self.um.get_user_by_id(user.user_id, user)
    self.assertEqual(result.user_id, user.user_id)
def test_get_user_by_id_admin(self):
    # Admin accessing user info by ID
    admin = self.um._users["admin@example.com"]
    user = self.um._users["test@example.com"]
    result = self.um.get_user_by_id(user.user_id, admin)
    self.assertEqual(result.user_id, user.user_id)
def test_get_user_by_id_unauthorized(self):
    # Non-admin accessing another user's info by ID
    user = self.um._users["test@example.com"]
    admin = self.um._users["admin@example.com"]
    with self.assertRaises(PermissionDeniedError):
        self.um.get_user_by_id(admin.user_id, user)
def test_get_user_by_id_not_found(self):
    # Non-existent user ID
    user = self.um._users["test@example.com"]
    with self.assertRaises(UserNotFoundError):
        self.um.get_user_by_id("nonexistent-id", user)
def test_list_users_admin(self):
    # Admin listing users
    admin = self.um._users["admin@example.com"]
    users = self.um.list_users(admin)
    self.assertEqual(len(users), 2)
    self.assertTrue(any(u.email == "test@example.com" for u in users))
    self.assertTrue(any(u.email == "admin@example.com" for u in users))
def test_list_users_non_admin(self):
    # Non-admin attempting to list users
    user = self.um._users["test@example.com"]
    with self.assertRaises(PermissionDeniedError):
        self.um.list_users(user)
def test_disable_user_admin(self):
    # Admin disabling user
    admin = self.um._users["admin@example.com"]
    self.um.disable_user("test@example.com", admin)
    self.assertFalse(self.um._users["test@example.com"].is_active)
def test_disable_user_non_admin(self):
    # Non-admin attempting to disable user
    user = self.um._users["test@example.com"]
    with self.assertRaises(PermissionDeniedError):
        self.um.disable_user("admin@example.com", user)
def test_disable_user_not_found(self):
    # Disabling non-existent user
    admin = self.um._users["admin@example.com"]
    with self.assertRaises(UserNotFoundError):
        self.um.disable_user("nonexistent@example.com", admin)
def test_is_user_valid_valid(self):
    # Valid user ID
    user = self.um._users["test@example.com"]
    self.assertTrue(self.um.is_user_valid(user.user_id))
def test_is_user_valid_invalid(self):
    # Non-existent user ID
    self.assertFalse(self.um.is_user_valid("nonexistent-id"))
def test_is_user_valid_disabled(self):
    # Disabled user
    admin = self.um._users["admin@example.com"]
    self.um.disable_user("test@example.com", admin)
    user = self.um._users["test@example.com"]
    self.assertFalse(self.um.is_user_valid(user.user_id))
def test_is_admin_valid(self):
    # Valid admin user
    admin = self.um._users["admin@example.com"]
    self.assertTrue(self.um.is_admin(admin.user_id))
def test_is_admin_non_admin(self):
    # Non-admin user
    user = self.um._users["test@example.com"]
    self.assertFalse(self.um.is_admin(user.user_id))
def test_is_admin_invalid(self):
    # Non-existent user ID
    self.assertFalse(self.um.is_admin("nonexistent-id"))
def test_are_users_valid_mixed(self):
    # Mixed valid, invalid, and disabled users
    admin = self.um._users["admin@example.com"]
    user = self.um._users["test@example.com"]
    self.um.disable_user("test@example.com", admin)
    user_ids = [user.user_id, admin.user_id, "nonexistent-id"]
    result = self.um.are_users_valid(user_ids)
    self.assertEqual(result, {
        user.user_id: False,
        admin.user_id: True,
        "nonexistent-id": False
    })
def test_are_users_valid_empty(self):
    # Empty user ID list
    result = self.um.are_users_valid([])
    self.assertEqual(result, {})
if name == 'main':
unittest.main()
`
模块二:
`
import unittest
from unittest.mock import Mock
import uuid
import datetime
from typing import List, Optional
from enum import Enum
# Import classes from the provided TaskManager code
from task_manager import (
    TaskManager, Task, TaskStatus, TaskPriority,
    InvalidTaskError, InvalidDueDateError, PermissionDeniedError, InvalidUserError,
    MemoryTaskStorage, IUserManager
)
# Mock Role enum for user manager
class Role(Enum):
    USER = "USER"
    ADMIN = "ADMIN"
# Mock User class for testing
class User:
    def __init__(self, user_id: str, role: Role):
        self.user_id = user_id
        self.role = role
# Test cases for boundary condition coverage
class TestTaskManager(unittest.TestCase):
    def setUp(self):
        # Mock IUserManager
        self.user_manager = Mock(spec=IUserManager)
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "admin1"]
        self.user_manager.is_admin.side_effect = lambda user_id: user_id == "admin1"
        # Initialize TaskManager with MemoryTaskStorage
        self.task_manager = TaskManager(self.user_manager, MemoryTaskStorage())
        # Create sample users
        self.user1 = User("user1", Role.USER)
        self.admin1 = User("admin1", Role.ADMIN)
        # Create a future due date
        self.future_date = datetime.datetime.now() + datetime.timedelta(days=1)
        # Create a sample task for testing
        self.task = self.task_manager.create_task(
            title="Sample Task",
            creator_id="user1",
            due_date=self.future_date,
            description="Test description",
            priority=TaskPriority.MEDIUM.value
        )
    def test_create_task_valid(self):
        # Valid task creation with minimal and maximal inputs
        task = self.task_manager.create_task(
            title="Test",
            creator_id="user1",
            due_date=self.future_date,
            description="A" * 1000,  # Long description
            priority=TaskPriority.HIGH.value
        )
        self.assertIsNotNone(task.task_id)
        self.assertEqual(task.title, "Test")
        self.assertEqual(task.creator_id, "user1")
        self.assertEqual(task.priority, TaskPriority.HIGH)
        self.assertEqual(task.status, TaskStatus.TODO)
        self.assertEqual(task.description, "A" * 1000)
        self.assertEqual(task.due_date, self.future_date)
    def test_create_task_empty_title(self):
        # Empty title
        with self.assertRaises(InvalidTaskError):
            self.task_manager.create_task(
                title="",
                creator_id="user1",
                due_date=self.future_date
            )
    def test_create_task_invalid_creator(self):
        # Non-existent creator
        with self.assertRaises(InvalidUserError):
            self.task_manager.create_task(
                title="Test",
                creator_id="nonexistent",
                due_date=self.future_date
            )
    def test_create_task_past_due_date(self):
        # Past due date
        past_date = datetime.datetime.now() - datetime.timedelta(days=1)
        with self.assertRaises(InvalidDueDateError):
            self.task_manager.create_task(
                title="Test",
                creator_id="user1",
                due_date=past_date
            )
    def test_create_task_invalid_priority(self):
        # Invalid priority
        with self.assertRaises(InvalidTaskError):
            self.task_manager.create_task(
                title="Test",
                creator_id="user1",
                due_date=self.future_date,
                priority="invalid"
            )
    def test_update_task_valid_creator(self):
        # Creator updates all fields
        new_due_date = self.future_date + datetime.timedelta(days=1)
        self.task_manager.update_task(
            task_id=self.task.task_id,
            caller_id="user1",
            title="Updated Title",
            description="Updated Description",
            priority=TaskPriority.LOW.value,
            due_date=new_due_date,
            status=TaskStatus.IN_PROGRESS.value
        )
        updated_task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertEqual(updated_task.title, "Updated Title")
        self.assertEqual(updated_task.description, "Updated Description")
        self.assertEqual(updated_task.priority, TaskPriority.LOW)
        self.assertEqual(updated_task.due_date, new_due_date)
        self.assertEqual(updated_task.status, TaskStatus.IN_PROGRESS)
        self.assertIsNotNone(updated_task.updated_at)
    def test_update_task_valid_admin(self):
        # Admin updates all fields
        new_due_date = self.future_date + datetime.timedelta(days=1)
        self.task_manager.update_task(
            task_id=self.task.task_id,
            caller_id="admin1",
            title="Updated Title",
            description="Updated Description",
            priority=TaskPriority.LOW.value,
            due_date=new_due_date,
            status=TaskStatus.IN_PROGRESS.value
        )
        updated_task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertEqual(updated_task.title, "Updated Title")
        self.assertEqual(updated_task.description, "Updated Description")
        self.assertEqual(updated_task.priority, TaskPriority.LOW)
        self.assertEqual(updated_task.due_date, new_due_date)
        self.assertEqual(updated_task.status, TaskStatus.IN_PROGRESS)
    def test_update_task_unauthorized(self):
        # Non-creator, non-admin tries to update
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "user2"]
        self.user_manager.is_admin.side_effect = lambda user_id: False
        with self.assertRaises(PermissionDeniedError):
            self.task_manager.update_task(
                task_id=self.task.task_id,
                caller_id="user2",
                title="Unauthorized Update"
            )
    def test_update_task_nonexistent_task(self):
        # Non-existent task
        with self.assertRaises(InvalidTaskError):
            self.task_manager.update_task(
                task_id="nonexistent",
                caller_id="user1",
                title="Test"
            )
    def test_update_task_empty_title(self):
        # Empty title
        with self.assertRaises(InvalidTaskError):
            self.task_manager.update_task(
                task_id=self.task.task_id,
                caller_id="user1",
                title=""
            )
    def test_update_task_invalid_priority(self):
        # Invalid priority
        with self.assertRaises(InvalidTaskError):
            self.task_manager.update_task(
                task_id=self.task.task_id,
                caller_id="user1",
                priority="invalid"
            )
    def test_update_task_invalid_status(self):
        # Invalid status
        with self.assertRaises(InvalidTaskError):
            self.task_manager.update_task(
                task_id=self.task.task_id,
                caller_id="user1",
                status="invalid"
            )
    def test_update_task_past_due_date(self):
        # Past due date
        past_date = datetime.datetime.now() - datetime.timedelta(days=1)
        with self.assertRaises(InvalidDueDateError):
            self.task_manager.update_task(
                task_id=self.task.task_id,
                caller_id="user1",
                due_date=past_date
            )
    def test_update_task_completed_status(self):
        # Set status to COMPLETED
        self.task_manager.update_task(
            task_id=self.task.task_id,
            caller_id="user1",
            status=TaskStatus.COMPLETED.value
        )
        updated_task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertEqual(updated_task.status, TaskStatus.COMPLETED)
        self.assertIsNotNone(updated_task.completed_at)
    def test_delete_task_valid_creator(self):
        # Creator deletes task
        self.task_manager.delete_task(self.task.task_id, "user1")
        self.assertIsNone(self.task_manager.storage.get_task(self.task.task_id))
    def test_delete_task_valid_admin(self):
        # Admin deletes task
        self.task_manager.delete_task(self.task.task_id, "admin1")
        self.assertIsNone(self.task_manager.storage.get_task(self.task.task_id))
    def test_delete_task_unauthorized(self):
        # Non-creator, non-admin tries to delete
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "user2"]
        self.user_manager.is_admin.side_effect = lambda user_id: False
        with self.assertRaises(PermissionDeniedError):
            self.task_manager.delete_task(self.task.task_id, "user2")
    def test_delete_task_nonexistent(self):
        # Non-existent task
        with self.assertRaises(InvalidTaskError):
            self.task_manager.delete_task("nonexistent", "user1")
    def test_archive_task_valid_creator(self):
        # Creator archives completed task
        self.task_manager.update_task(self.task.task_id, "user1", status=TaskStatus.COMPLETED.value)
        self.task_manager.archive_task(self.task.task_id, "user1")
        task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertTrue(task.archived)
    def test_archive_task_valid_admin(self):
        # Admin archives completed task
        self.task_manager.update_task(self.task.task_id, "admin1", status=TaskStatus.COMPLETED.value)
        self.task_manager.archive_task(self.task.task_id, "admin1")
        task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertTrue(task.archived)
    def test_archive_task_unauthorized(self):
        # Non-creator, non-admin tries to archive
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "user2"]
        self.user_manager.is_admin.side_effect = lambda user_id: False
        self.task_manager.update_task(self.task.task_id, "user1", status=TaskStatus.COMPLETED.value)
        with self.assertRaises(PermissionDeniedError):
            self.task_manager.archive_task(self.task.task_id, "user2")
    def test_archive_task_nonexistent(self):
        # Non-existent task
        with self.assertRaises(InvalidTaskError):
            self.task_manager.archive_task("nonexistent", "user1")
    def test_archive_task_not_completed(self):
        # Task not in COMPLETED status
        with self.assertRaises(InvalidTaskError):
            self.task_manager.archive_task(self.task.task_id, "user1")
    def test_assign_task_valid_creator(self):
        # Creator assigns task to valid users
        self.task_manager.assign_task(self.task.task_id, "user1", ["user1", "admin1"])
        task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertEqual(task.assignees, ["user1", "admin1"])
        self.assertIsNotNone(task.assignment_time)
    def test_assign_task_valid_admin(self):
        # Admin assigns task to valid users
        self.task_manager.assign_task(self.task.task_id, "admin1", ["user1", "admin1"])
        task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertEqual(task.assignees, ["user1", "admin1"])
        self.assertIsNotNone(task.assignment_time)
    def test_assign_task_unauthorized(self):
        # Non-creator, non-admin tries to assign
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "user2"]
        self.user_manager.is_admin.side_effect = lambda user_id: False
        with self.assertRaises(PermissionDeniedError):
            self.task_manager.assign_task(self.task.task_id, "user2", ["user1"])
    def test_assign_task_invalid_user(self):
        # Assign to non-existent user
        with self.assertRaises(InvalidUserError):
            self.task_manager.assign_task(self.task.task_id, "user1", ["nonexistent"])
    def test_assign_task_empty_assignees(self):
        # Empty assignee list
        self.task_manager.assign_task(self.task.task_id, "user1", [])
        task = self.task_manager.storage.get_task(self.task.task_id)
        self.assertEqual(task.assignees, [])
        self.assertIsNotNone(task.assignment_time)
    def test_assign_task_nonexistent_task(self):
        # Non-existent task
        with self.assertRaises(InvalidTaskError):
            self.task_manager.assign_task("nonexistent", "user1", ["user1"])
if __name__ == '__main__':
    unittest.main()
`
模块三
`
import unittest
from unittest.mock import Mock
from datetime import datetime, timedelta
import re
from typing import List, Optional, Dict, Any
# Import classes from task_manager and user_manager
from task_manager import (
    TaskManager, Task, TaskStatus, TaskPriority,
    InvalidTaskError, InvalidUserError, MemoryTaskStorage
)
from user_manager import UserManager, PermissionDeniedError, UserNotFoundError
from task_query_manager import TaskQueryManager
# Mock Role enum for user manager
class Role:
    USER = "USER"
    ADMIN = "ADMIN"
# Mock User class for testing
class User:
    def __init__(self, user_id: str, role: Role):
        self.user_id = user_id
        self.role = role
# Test cases for boundary condition coverage
class TestTaskQueryManager(unittest.TestCase):
    def setUp(self):
        # Mock UserManager
        self.user_manager = Mock(spec=UserManager)
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "user2", "admin1"]
        self.user_manager.is_admin.side_effect = lambda user_id: user_id == "admin1"
        # Mock TaskManager with MemoryTaskStorage
        self.task_manager = TaskManager(self.user_manager, MemoryTaskStorage())
        # Initialize TaskQueryManager
        self.query_manager = TaskQueryManager(self.task_manager, self.user_manager)
        # Create sample users
        self.user1 = User("user1", Role.USER)
        self.user2 = User("user2", Role.USER)
        self.admin1 = User("admin1", Role.ADMIN)
        # Create date references
        self.now = datetime.now()
        self.past_date = self.now - timedelta(days=1)
        self.future_date = self.now + timedelta(days=5)
        # Create sample tasks
        self.task1 = self.task_manager.create_task(
            title="Task 1",
            creator_id="user1",
            due_date=self.future_date,
            description="Description 1",
            priority=TaskPriority.HIGH.value
        )
        self.task2 = self.task_manager.create_task(
            title="Task 2 meeting",
            creator_id="user2",
            due_date=self.past_date,
            description="Description 2",
            priority=TaskPriority.MEDIUM.value
        )
        self.task_manager.assign_task(self.task1.task_id, "user1", ["user1", "user2"])
        self.task_manager.update_task(self.task2.task_id, "user2", status=TaskStatus.COMPLETED.value)
    def test_query_tasks_valid_admin_all_tasks(self):
        # Admin queries all tasks
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            page=1,
            page_size=10,
            sort_by="due_date",
            sort_order="asc"
        )
        self.assertEqual(result["total"], 2)
        self.assertEqual(len(result["tasks"]), 2)
        self.assertEqual(result["tasks"][0]["task_id"], self.task2.task_id)  # Past date first
        self.assertEqual(result["page"], 1)
        self.assertEqual(result["total_pages"], 1)
    def test_query_tasks_valid_user_own_tasks(self):
        # User queries own tasks (creator or assignee)
        result = self.query_manager.query_tasks(
            caller_id="user1",
            page=1,
            page_size=10,
            sort_by="due_date",
            sort_order="asc"
        )
        self.assertEqual(result["total"], 1)
        self.assertEqual(len(result["tasks"]), 1)
        self.assertEqual(result["tasks"][0]["task_id"], self.task1.task_id)
    def test_query_tasks_invalid_caller(self):
        # Invalid caller ID
        with self.assertRaises(InvalidUserError):
            self.query_manager.query_tasks(caller_id="invalid_user")
    def test_query_tasks_invalid_page(self):
        # Negative or zero page
        with self.assertRaises(ValueError):
            self.query_manager.query_tasks(caller_id="admin1", page=0)
        with self.assertRaises(ValueError):
            self.query_manager.query_tasks(caller_id="admin1", page=-1)
    def test_query_tasks_invalid_page_size(self):
        # Negative or zero page_size
        with self.assertRaises(ValueError):
            self.query_manager.query_tasks(caller_id="admin1", page_size=0)
        with self.assertRaises(ValueError):
            self.query_manager.query_tasks(caller_id="admin1", page_size=-1)
    def test_query_tasks_invalid_sort_by(self):
        # Invalid sort_by
        with self.assertRaises(ValueError):
            self.query_manager.query_tasks(caller_id="admin1", sort_by="invalid")
    def test_query_tasks_invalid_sort_order(self):
        # Invalid sort_order
        with self.assertRaises(ValueError):
            self.query_manager.query_tasks(caller_id="admin1", sort_order="invalid")
    def test_query_tasks_invalid_status(self):
        # Invalid status
        with self.assertRaises(InvalidTaskError):
            self.query_manager.query_tasks(caller_id="admin1", status="invalid")
    def test_query_tasks_invalid_priority(self):
        # Invalid priority
        with self.assertRaises(InvalidTaskError):
            self.query_manager.query_tasks(caller_id="admin1", priority="invalid")
    def test_query_tasks_invalid_assignee(self):
        # Invalid assignee ID
        with self.assertRaises(InvalidUserError):
            self.query_manager.query_tasks(caller_id="admin1", assignee_id="invalid_user")
    def test_query_tasks_by_status(self):
        # Filter by status (COMPLETED)
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            status=TaskStatus.COMPLETED.value
        )
        self.assertEqual(result["total"], 1)
        self.assertEqual(result["tasks"][0]["task_id"], self.task2.task_id)
    def test_query_tasks_by_priority(self):
        # Filter by priority (HIGH)
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            priority=TaskPriority.HIGH.value
        )
        self.assertEqual(result["total"], 1)
        self.assertEqual(result["tasks"][0]["task_id"], self.task1.task_id)
    def test_query_tasks_by_assignee(self):
        # Filter by assignee
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            assignee_id="user2"
        )
        self.assertEqual(result["total"], 1)
        self.assertEqual(result["tasks"][0]["task_id"], self.task1.task_id)
    def test_query_tasks_by_due_date_range(self):
        # Filter by due date range
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            due_date_start=self.now,
            due_date_end=self.future_date + timedelta(days=1)
        )
        self.assertEqual(result["total"], 1)
        self.assertEqual(result["tasks"][0]["task_id"], self.task1.task_id)
    def test_query_tasks_by_keyword(self):
        # Filter by keyword in title
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            keyword="meeting"
        )
        self.assertEqual(result["total"], 1)
        self.assertEqual(result["tasks"][0]["task_id"], self.task2.task_id)
    def test_query_tasks_empty_result(self):
        # Filter with no matching tasks
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            keyword="nonexistent"
        )
        self.assertEqual(result["total"], 0)
        self.assertEqual(result["tasks"], [])
        self.assertEqual(result["total_pages"], 0)
        self.assertEqual(result["message"], "No tasks found")
    def test_query_tasks_pagination(self):
        # Pagination with multiple tasks
        for i in range(3, 13):  # Create 10 more tasks
            self.task_manager.create_task(
                title=f"Task {i}",
                creator_id="user1",
                due_date=self.future_date + timedelta(days=i),
                priority=TaskPriority.MEDIUM.value
            )
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            page=2,
            page_size=5,
            sort_by="due_date",
            sort_order="asc"
        )
        self.assertEqual(result["total"], 12)
        self.assertEqual(len(result["tasks"]), 5)
        self.assertEqual(result["page"], 2)
        self.assertEqual(result["total_pages"], 3)
    def test_query_tasks_pagination_last_page(self):
        # Last page with fewer tasks
        for i in range(3, 8):  # Create 5 more tasks
            self.task_manager.create_task(
                title=f"Task {i}",
                creator_id="user1",
                due_date=self.future_date + timedelta(days=i)
            )
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            page=2,
            page_size=5
        )
        self.assertEqual(result["total"], 7)
        self.assertEqual(len(result["tasks"]), 2)
        self.assertEqual(result["total_pages"], 2)
    def test_query_tasks_sort_by_priority_desc(self):
        # Sort by priority descending
        result = self.query_manager.query_tasks(
            caller_id="admin1",
            sort_by="priority",
            sort_order="desc"
        )
        self.assertEqual(result["total"], 2)
        self.assertEqual(result["tasks"][0]["task_id"], self.task1.task_id)  # HIGH first
        self.assertEqual(result["tasks"][1]["task_id"], self.task2.task_id)  # MEDIUM second
    def test_get_task_details_valid_creator(self):
        # Creator accesses task details
        details = self.query_manager.get_task_details(self.task1.task_id, "user1")
        self.assertEqual(details["task_id"], self.task1.task_id)
        self.assertEqual(details["creator_id"], "user1")
    def test_get_task_details_valid_assignee(self):
        # Assignee accesses task details
        details = self.query_manager.get_task_details(self.task1.task_id, "user2")
        self.assertEqual(details["task_id"], self.task1.task_id)
    def test_get_task_details_valid_admin(self):
        # Admin accesses task details
        details = self.query_manager.get_task_details(self.task1.task_id, "admin1")
        self.assertEqual(details["task_id"], self.task1.task_id)
    def test_get_task_details_invalid_caller(self):
        # Invalid caller ID
        with self.assertRaises(InvalidUserError):
            self.query_manager.get_task_details(self.task1.task_id, "invalid_user")
    def test_get_task_details_unauthorized(self):
        # Non-creator, non-assignee, non-admin tries to access
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "user2", "user3"]
        self.user_manager.is_admin.side_effect = lambda user_id: False
        with self.assertRaises(PermissionDeniedError):
            self.query_manager.get_task_details(self.task1.task_id, "user3")
    def test_get_task_details_nonexistent_task(self):
        # Non-existent task
        with self.assertRaises(InvalidTaskError):
            self.query_manager.get_task_details("nonexistent", "admin1")
    def test_count_incomplete_tasks_valid_self(self):
        # User counts own incomplete tasks
        count = self.query_manager.count_incomplete_tasks("user1", "user1")
        self.assertEqual(count, 1)  # task1 is TODO
    def test_count_incomplete_tasks_valid_admin(self):
        # Admin counts user's incomplete tasks
        count = self.query_manager.count_incomplete_tasks("user1", "admin1")
        self.assertEqual(count, 1)
    def test_count_incomplete_tasks_invalid_user(self):
        # Invalid user ID
        with self.assertRaises(InvalidUserError):
            self.query_manager.count_incomplete_tasks("invalid_user", "admin1")
    def test_count_incomplete_tasks_invalid_caller(self):
        # Invalid caller ID
        with self.assertRaises(InvalidUserError):
            self.query_manager.count_incomplete_tasks("user1", "invalid_user")
    def test_count_incomplete_tasks_unauthorized(self):
        # Non-admin, non-self tries to count
        self.user_manager.is_user_valid.side_effect = lambda user_id: user_id in ["user1", "user2"]
        self.user_manager.is_admin.side_effect = lambda user_id: False
        with self.assertRaises(PermissionDeniedError):
            self.query_manager.count_incomplete_tasks("user1", "user2")
    def test_count_incomplete_tasks_no_incomplete(self):
        # User with no incomplete tasks
        self.task_manager.update_task(self.task1.task_id, "user1", status=TaskStatus.COMPLETED.value)
        count = self.query_manager.count_incomplete_tasks("user1", "user1")
        self.assertEqual(count, 0)
if __name__ == '__main__':
    unittest.main()
`
模块四
`
import unittest
from unittest.mock import Mock, patch, AsyncMock
import asyncio
from datetime import datetime, timedelta
from typing import List, Optional, Dict
from notification_service import (
    NotificationService, Notification, NotificationType, Priority, NotificationStatus,
    NotificationSettings, TaskDetails, UserContact
)
# Mock TaskManager and UserManager interfaces
class MockTaskManager:
    def get_task_details(self, task_id: int) -> TaskDetails:
        if task_id == 1:
            return TaskDetails(
                task_id=1,
                title="Test Task",
                assignees=[1, 2],
                creator_id=3,
                deadline=datetime.now() + timedelta(days=1)
            )
        raise ValueError("Task not found")
class MockUserManager:
    def __init__(self):
        self.settings = {
            1: NotificationSettings(user_id=1, receive_task_assigned=True, receive_status_changed=True, receive_deadline_approaching=True),
            2: NotificationSettings(user_id=2, receive_task_assigned=False, receive_status_changed=True, receive_deadline_approaching=True),
            3: NotificationSettings(user_id=3, receive_task_assigned=True, receive_status_changed=False, receive_deadline_approaching=True)
        }
        self.contacts = {
            1: UserContact(user_id=1, email="user1@example.com"),
            2: UserContact(user_id=2, email="user2@example.com"),
            3: UserContact(user_id=3, email="user3@example.com")
        }
    def get_notification_settings(self, user_id: int) -> NotificationSettings:
        if user_id not in self.settings:
            raise ValueError("User not found")
        return self.settings[user_id]
    def update_notification_settings(self, user_id: int, settings: NotificationSettings) -> None:
        if user_id not in self.settings:
            raise ValueError("User not found")
        self.settings[user_id] = settings
    def get_user_contact(self, user_id: int) -> UserContact:
        if user_id not in self.contacts:
            raise ValueError("User not found")
        return self.contacts[user_id]
# Test cases for boundary condition coverage
class TestNotificationService(unittest.TestCase):
    def setUp(self):
        # Mock dependencies
        self.task_manager = MockTaskManager()
        self.user_manager = MockUserManager()
        self.smtp_config = {
            "host": "smtp.example.com",
            "port": 587,
            "user": "test_user",
            "password": "test_password",
            "from_email": "no-reply@taskmanager.com"
        }
        self.service = NotificationService(self.task_manager, self.user_manager, self.smtp_config)
        self.loop = asyncio.get_event_loop()
    @patch('notification_service.smtplib.SMTP')
    def test_handle_task_assigned_valid(self, mock_smtp):
        # Valid task assignment, high priority, email success
        mock_smtp.return_value.__enter__.return_value.login.return_value = None
        mock_smtp.return_value.__enter__.return_value.send_message.return_value = None
        self.service.handle_task_assigned(task_id=1, user_ids=[1, 2])
        self.assertEqual(len(self.service.notifications), 2)
        self.assertEqual(self.service.notifications[0].user_id, 1)
        self.assertEqual(self.service.notifications[0].notification_type, NotificationType.TASK_ASSIGNED)
        self.assertEqual(self.service.notifications[0].priority, Priority.HIGH)
        self.assertEqual(self.service.notifications[0].status, NotificationStatus.SUCCESS)
        self.assertEqual(self.service.notifications[1].user_id, 2)
        self.assertEqual(self.service.notifications[1].status, NotificationStatus.FAILED)
        self.assertEqual(self.service.notifications[1].failure_reason, "用户已关闭此类型通知")
    @patch('notification_service.smtplib.SMTP')
    def test_handle_task_assigned_empty_user_ids(self, mock_smtp):
        # Empty user IDs list
        self.service.handle_task_assigned(task_id=1, user_ids=[])
        self.assertEqual(len(self.service.notifications), 0)
    @patch('notification_service.smtplib.SMTP')
    def test_handle_task_assigned_email_failure(self, mock_smtp):
        # High-priority email failure
        mock_smtp.return_value.__enter__.return_value.login.side_effect = Exception("SMTP error")
        self.service.handle_task_assigned(task_id=1, user_ids=[1])
        self.assertEqual(len(self.service.notifications), 1)
        self.assertEqual(self.service.notifications[0].status, NotificationStatus.FAILED)
        self.assertTrue(self.service.notifications[0].failure_reason.startswith("邮件发送失败"))
    @patch('notification_service.smtplib.SMTP')
    def test_handle_status_changed_valid(self, mock_smtp):
        # Valid status change, low priority, queued
        self.service.handle_status_changed(task_id=1, new_status="completed")
        self.assertEqual(len(self.service.notifications), 3)  # Creator (3) and assignees (1, 2)
        self.assertEqual(self.service.notifications[0].user_id, 1)
        self.assertEqual(self.service.notifications[0].notification_type, NotificationType.STATUS_CHANGED)
        self.assertEqual(self.service.notifications[0].priority, Priority.LOW)
        self.assertEqual(self.service.notifications[0].status, NotificationStatus.SUCCESS)
        self.assertEqual(self.service.notifications[1].user_id, 2)
        self.assertEqual(self.service.notifications[2].user_id, 3)
        self.assertEqual(self.service.notifications[2].status, NotificationStatus.FAILED)
        self.assertEqual(self.service.notifications[2].failure_reason, "用户已关闭此类型通知")
    def test_handle_status_changed_invalid_task(self):
        # Invalid task ID
        self.task_manager.get_task_details = Mock(side_effect=ValueError("Task not found"))
        self.service.handle_status_changed(task_id=999, new_status="completed")
        self.assertEqual(len(self.service.notifications), 0)
    @patch('notification_service.smtplib.SMTP')
    def test_handle_deadline_approaching_valid(self, mock_smtp):
        # Valid deadline approaching, low priority, queued
        deadline = datetime.now() + timedelta(days=1)
        self.service.handle_deadline_approaching(task_id=1, deadline=deadline)
        self.assertEqual(len(self.service.notifications), 3)  # Creator (3) and assignees (1, 2)
        self.assertEqual(self.service.notifications[0].notification_type, NotificationType.DEADLINE_APPROACHING)
        self.assertEqual(self.service.notifications[0].priority, Priority.LOW)
        self.assertEqual(self.service.notifications[0].status, NotificationStatus.SUCCESS)
        self.assertTrue("将于" in self.service.notifications[0].content)
    def test_handle_deadline_approaching_invalid_task(self):
        # Invalid task ID
        self.task_manager.get_task_details = Mock(side_effect=ValueError("Task not found"))
        self.service.handle_deadline_approaching(task_id=999, deadline=datetime.now())
        self.assertEqual(len(self.service.notifications), 0)
    def test_get_notification_history_valid(self):
        # Valid history within 7 days
        self.service.handle_task_assigned(task_id=1, user_ids=[1])
        history = self.service.get_notification_history(user_id=1, days=7)
        self.assertEqual(len(history), 1)
        self.assertEqual(history[0].user_id, 1)
    def test_get_notification_history_no_notifications(self):
        # No notifications for user
        history = self.service.get_notification_history(user_id=1, days=7)
        self.assertEqual(len(history), 0)
    def test_get_notification_history_old_notifications(self):
        # Notifications older than cutoff
        old_notification = Notification(
            notification_id=1,
            task_id=1,
            user_id=1,
            notification_type=NotificationType.TASK_ASSIGNED,
            priority=Priority.HIGH,
            content="Old notification",
            send_time=datetime.now() - timedelta(days=8),
            status=NotificationStatus.SUCCESS
        )
        self.service.notifications.append(old_notification)
        history = self.service.get_notification_history(user_id=1, days=7)
        self.assertEqual(len(history), 0)
    def test_get_notification_history_zero_days(self):
        # Days = 0 (no notifications)
        self.service.handle_task_assigned(task_id=1, user_ids=[1])
        history = self.service.get_notification_history(user_id=1, days=0)
        self.assertEqual(len(history), 0)
    def test_update_notification_settings_valid(self):
        # Valid settings update
        new_settings = NotificationSettings(
            user_id=1,
            receive_task_assigned=False,
            receive_status_changed=False,
            receive_deadline_approaching=False
        )
        self.service.update_notification_settings(user_id=1, settings=new_settings)
        updated_settings = self.user_manager.get_notification_settings(1)
        self.assertFalse(updated_settings.receive_task_assigned)
        self.assertFalse(updated_settings.receive_status_changed)
        self.assertFalse(updated_settings.receive_deadline_approaching)
    def test_update_notification_settings_invalid_user(self):
        # Invalid user ID
        new_settings = NotificationSettings(user_id=999, receive_task_assigned=True)
        with self.assertRaises(ValueError):
            self.service.update_notification_settings(user_id=999, settings=new_settings)
    def test_get_notification_settings_valid(self):
        # Valid settings retrieval
        settings = self.service.get_notification_settings(user_id=1)
        self.assertEqual(settings.user_id, 1)
        self.assertTrue(settings.receive_task_assigned)
        self.assertTrue(settings.receive_status_changed)
        self.assertTrue(settings.receive_deadline_approaching)
    def test_get_notification_settings_invalid_user(self):
        # Invalid user ID
        with self.assertRaises(ValueError):
            self.service.get_notification_settings(user_id=999)
    @patch('notification_service.smtplib.SMTP')
    def test_send_notification_site_message_failure(self, mock_smtp):
        # Site message failure
        with patch.object(self.service, '_send_site_message', return_value=False):
            notification = self.service._send_notification(
                user_id=1,
                task_id=1,
                notification_type=NotificationType.TASK_ASSIGNED,
                priority=Priority.HIGH
            )
            self.assertEqual(notification.status, NotificationStatus.FAILED)
            self.assertEqual(notification.failure_reason, "站内消息发送失败")
    @patch('notification_service.smtplib.SMTP')
    async def test_send_email_async_success(self, mock_smtp):
        # Email success
        mock_smtp.return_value.__enter__.return_value.login.return_value = None
        mock_smtp.return_value.__enter__.return_value.send_message
`
模块五
`
```python
import unittest
from unittest.mock import patch, Mock, mock_open
import sqlite3
from datetime import datetime
import json
import os
from typing import List, Dict
from system_config import SystemConfig, AuditLog, DataBackup, NotificationType, TaskPriority
class TestSystemConfigAuditBackup(unittest.TestCase):
    def setUp(self):
        # Mock SQLite connection and cursor
        self.mock_conn = Mock()
        self.mock_cursor = Mock()
        self.mock_conn.cursor.return_value = self.mock_cursor
        self.mock_conn.__enter__.return_value = self.mock_conn
        self.mock_conn.__exit__.return_value = None
        self.db_path = "task_management.db"
        self.backup_dir = "backups"
        # Patch sqlite3.connect
        self.sqlite_patch = patch('sqlite3.connect', return_value=self.mock_conn)
        self.sqlite_patch.start()
        # Patch os.makedirs
        self.makedirs_patch = patch('os.makedirs')
        self.makedirs_patch.start()
        # Initialize classes
        self.system_config = SystemConfig()
        self.audit_log = AuditLog(self.db_path)
        self.data_backup = DataBackup(self.db_path)
    def tearDown(self):
        # Stop patches
        self.sqlite_patch.stop()
        self.makedirs_patch.stop()
    def test_system_config_init_db_success(self):
        # Successful database initialization
        self.mock_cursor.execute.reset_mock()
        self.system_config._init_db()
        self.mock_cursor.execute.assert_called_once()
        self.assertEqual(self.system_config._db_path, "task_management.db")
    @patch('system_config.logging.error')
    def test_system_config_init_db_failure(self, mock_log_error):
        # Database initialization failure
        self.mock_conn.cursor.side_effect = sqlite3.Error("DB error")
        with self.assertRaises(sqlite3.Error):
            self.system_config._init_db()
        mock_log_error.assert_called_with("Database connection failed: DB error")
    def test_update_notification_type_valid(self):
        # Valid notification types
        for ntype in [NotificationType.EMAIL.value, NotificationType.IN_APP.value, NotificationType.SMS.value]:
            with self.subTest(ntype=ntype):
                result = self.system_config.update_notification_type(ntype)
                self.assertTrue(result)
                self.assertEqual(self.system_config._config["notification_type"], ntype)
    @patch('system_config.logging.warning')
    def test_update_notification_type_invalid(self, mock_log_warning):
        # Invalid notification type
        result = self.system_config.update_notification_type("invalid")
        self.assertFalse(result)
        self.assertEqual(self.system_config._config["notification_type"], NotificationType.IN_APP.value)
        mock_log_warning.assert_called_with("Invalid notification type: invalid")
    def test_update_default_priority_valid(self):
        # Valid priorities
        for priority in [TaskPriority.LOW.value, TaskPriority.MEDIUM.value, TaskPriority.HIGH.value]:
            with self.subTest(priority=priority):
                result = self.system_config.update_default_priority(priority)
                self.assertTrue(result)
                self.assertEqual(self.system_config._config["default_priority"], priority)
    @patch('system_config.logging.warning')
    def test_update_default_priority_invalid(self, mock_log_warning):
        # Invalid priority
        result = self.system_config.update_default_priority("invalid")
        self.assertFalse(result)
        self.assertEqual(self.system_config._config["default_priority"], TaskPriority.MEDIUM.value)
        mock_log_warning.assert_called_with("Invalid priority: invalid")
    def test_add_task_status_valid(self):
        # Valid new status
        result = self.system_config.add_task_status("Blocked")
        self.assertTrue(result)
        self.assertIn("Blocked", self.system_config._config["task_statuses"])
    @patch('system_config.logging.warning')
    def test_add_task_status_empty(self, mock_log_warning):
        # Empty or blank status
        for status in ["", "  "]:
            with self.subTest(status=status):
                result = self.system_config.add_task_status(status)
                self.assertFalse(result)
                self.assertNotIn(status, self.system_config._config["task_statuses"])
                mock_log_warning.assert_called_with("Task status cannot be empty")
    @patch('system_config.logging.warning')
    def test_add_task_status_duplicate(self, mock_log_warning):
        # Duplicate status
        self.system_config._config["task_statuses"] = ["To Do"]
        result = self.system_config.add_task_status("To Do")
        self.assertFalse(result)
        self.assertEqual(self.system_config._config["task_statuses"].count("To Do"), 1)
        mock_log_warning.assert_called_with("Task status 'To Do' already exists")
    def test_get_config(self):
        # Get configuration
        config = self.system_config.get_config()
        expected = {
            "notification_type": NotificationType.IN_APP.value,
            "default_priority": TaskPriority.MEDIUM.value,
            "task_statuses": ["To Do", "In Progress", "Done"]
        }
        self.assertEqual(config, expected)
        # Verify deep copy
        config["task_statuses"].append("Blocked")
        self.assertNotIn("Blocked", self.system_config._config["task_statuses"])
    def test_audit_log_log_action_success(self):
        # Successful log action
        self.mock_cursor.execute.reset_mock()
        self.audit_log.log_action(task_id="task1", action="create", user_id="user1", details="Task created")
        self.mock_cursor.execute.assert_called_once()
        args = self.mock_cursor.execute.call_args[0]
        self.assertEqual(args[0], "INSERT INTO audit_logs (task_id, action, user_id, timestamp, details) VALUES (?, ?, ?, ?, ?)")
        self.assertEqual(args[1][:3], ("task1", "create", "user1"))
    @patch('system_config.logging.error')
    def test_audit_log_log_action_failure(self, mock_log_error):
        # Database failure
        self.mock_cursor.execute.side_effect = sqlite3.Error("DB error")
        self.audit_log.log_action(task_id="task1", action="create", user_id="user1")
        mock_log_error.assert_called_with("Failed to log action: DB error")
    def test_audit_log_get_task_history_success(self):
        # Successful retrieval
        self.mock_cursor.fetchall.return_value = [
            (1, "task1", "create", "user1", "2025-05-30T12:00:00", "Task created"),
            (2, "task1", "update", "user2", "2025-05-30T12:01:00", "Status updated")
        ]
        history = self.audit_log.get_task_history("task1")
        self.assertEqual(len(history), 2)
        self.assertEqual(history[0]["task_id"], "task1")
        self.assertEqual(history[0]["action"], "create")
        self.assertEqual(history[1]["user_id"], "user2")
    def test_audit_log_get_task_history_empty(self):
        # No logs for task
        self.mock_cursor.fetchall.return_value = []
        history = self.audit_log.get_task_history("task1")
        self.assertEqual(history, [])
    @patch('system_config.logging.error')
    def test_audit_log_get_task_history_failure(self, mock_log_error):
        # Database failure
        self.mock_cursor.execute.side_effect = sqlite3.Error("DB error")
        history = self.audit_log.get_task_history("task1")
        self.assertEqual(history, [])
        mock_log_error.assert_called_with("Failed to retrieve task history: DB error")
    @patch('builtins.open', new_callable=mock_open)
    def test_data_backup_success(self, mock_file):
        # Successful backup
        self.mock_cursor.fetchall.return_value = [
            (1, "task1", "create", "user1", "2025-05-30T12:00:00", "Task created")
        ]
        backup_file = self.data_backup.backup()
        self.assertIsNotNone(backup_file)
        self.assertTrue(backup_file.startswith("backups/backup_"))
        self.assertTrue(backup_file.endswith(".json"))
        mock_file.assert_called_once()
        written_data = json.loads(mock_file().write.call_args[0][0])
        self.assertEqual(len(written_data), 1)
        self.assertEqual(written_data[0]["task_id"], "task1")
    @patch('system_config.logging.error')
    def test_data_backup_db_failure(self, mock_log_error):
        # Database failure
        self.mock_cursor.fetchall.side_effect = sqlite3.Error("DB error")
        result = self.data_backup.backup()
        self.assertIsNone(result)
        mock_log_error.assert_called_with("Backup failed: DB error")
    @patch('system_config.logging.error')
    @patch('builtins.open', side_effect=OSError("File error"))
    def test_data_backup_file_failure(self, mock_open, mock_log_error):
        # File system failure
        self.mock_cursor.fetchall.return_value = []
        result = self.data_backup.backup()
        self.assertIsNone(result)
        mock_log_error.assert_called_with("Backup failed: File error")
    @patch('builtins.open', new_callable=mock_open)
    def test_data_restore_success(self, mock_file):
        # Successful restore
        backup_data = [
            {"id": 1, "task_id": "task1", "action": "create", "user_id": "user1", "timestamp": "2025-05-30T12:00:00", "details": "Task created"}
        ]
        mock_file().read.return_value = json.dumps(backup_data)
        self.mock_cursor.execute.reset_mock()
        result = self.data_backup.restore("backups/backup_test.json")
        self.assertTrue(result)
        self.mock_cursor.execute.assert_any_call("DELETE FROM audit_logs")
        self.mock_cursor.execute.assert_any_call(
            "INSERT INTO audit_logs (id, task_id, action, user_id, timestamp, details) VALUES (?, ?, ?, ?, ?, ?)",
            (1, "task1", "create", "user1", "2025-05-30T12:00:00", "Task created")
        )
    @patch('system_config.logging.error')
    @patch('builtins.open', new_callable=mock_open)
    def test_data_restore_invalid_json(self, mock_file, mock_log_error):
        # Invalid JSON in backup file
        mock_file().read.return_value = "invalid json"
        result = self.data_backup.restore("backups/backup_test.json")
        self.assertFalse(result)
        mock_log_error.assert_called_with("Restore failed: Expecting value: line 1 column 1 (char 0)")
    @patch('system_config.logging.error')
    @patch('builtins.open', side_effect=OSError("File not found"))
    def test_data_restore_file_not_found(self, mock_open, mock_log_error):
        # Non-existent backup file
        result = self.data_backup.restore("backups/nonexistent.json")
        self.assertFalse(result)
        mock_log_error.assert_called_with("Restore failed: File not found")
    @patch('system_config.logging.error')
    def test_data_restore_db_failure(self, mock_log_error):
        # Database failure during restore
        self.mock_cursor.execute.side_effect = sqlite3.Error("DB error")
        with patch('builtins.open', mock_open(read_data=json.dumps([]))):
            result = self.data_backup.restore("backups/backup_test.json")
            self.assertFalse(result)
            mock_log_error.assert_called_with("Restore failed: DB error")
if __name__ == '__main__':
    unittest.main()
`
a-zA-Z0-9._%+- ↩︎
                    
                
                
            
        
浙公网安备 33010602011771号