import pytest import json from app.models import User, TeamMember, File, DownloadRecord from datetime import datetime, timedelta class TestTeamLeaderManagement: """团队长管理功能测试""" def test_get_team_leaders_admin_only(self, client, auth_headers): """测试只有管理员可以获取团队长列表""" # 普通用户尝试访问 response = client.get('/api/admin/team-leaders', headers=auth_headers['user']) assert response.status_code == 403 # 团队长尝试访问 response = client.get('/api/admin/team-leaders', headers=auth_headers['leader']) assert response.status_code == 403 # 管理员访问 response = client.get('/api/admin/team-leaders', headers=auth_headers['admin']) assert response.status_code == 200 assert 'team_leaders' in response.json assert 'total' in response.json assert 'pages' in response.json def test_set_team_leader_permission(self, client, auth_headers, app): """测试设置团队长权限""" with app.app_context(): # 创建一个普通用户 from app.models import User from werkzeug.security import generate_password_hash test_user = User( username='testuser', email='test@test.com', password_hash=generate_password_hash('test123'), is_admin=False, is_team_leader=False, is_active=True, created_at=datetime.utcnow() ) from app import db db.session.add(test_user) db.session.commit() user_id = test_user.id # 管理员设置团队长权限 response = client.put(f'/api/admin/users/{user_id}/team-leader', headers=auth_headers['admin'], json={'is_team_leader': True}) assert response.status_code == 200 assert response.json['message'] == '团队长权限已设置' # 验证用户已成为团队长 user = User.query.get(user_id) assert user.is_team_leader is True # 取消团队长权限 response = client.put(f'/api/admin/users/{user_id}/team-leader', headers=auth_headers['admin'], json={'is_team_leader': False}) assert response.status_code == 200 assert response.json['message'] == '团队长权限已取消' # 验证权限已取消 user = User.query.get(user_id) assert user.is_team_leader is False def test_add_team_member(self, client, auth_headers, app): """测试添加团队成员""" with app.app_context(): from app.models import User from werkzeug.security import generate_password_hash from app import db # 创建团队成员用户 member_user = User( username='member', email='member@test.com', password_hash=generate_password_hash('member123'), is_admin=False, is_team_leader=False, is_active=True, created_at=datetime.utcnow() ) db.session.add(member_user) db.session.commit() member_id = member_user.id # 获取团队长ID leader = User.query.filter_by(username='leader').first() leader_id = leader.id # 管理员添加团队成员 response = client.post('/api/admin/team-members', headers=auth_headers['admin'], json={'leader_id': leader_id, 'member_id': member_id}) assert response.status_code == 201 assert response.json['message'] == '团队成员添加成功' # 验证团队成员关系已创建 team_member = TeamMember.query.filter_by( leader_id=leader_id, member_id=member_id).first() assert team_member is not None def test_remove_team_member(self, client, auth_headers, app): """测试移除团队成员""" with app.app_context(): from app.models import User from werkzeug.security import generate_password_hash from app import db # 创建团队成员用户 member_user = User( username='member2', email='member2@test.com', password_hash=generate_password_hash('member123'), is_admin=False, is_team_leader=False, is_active=True, created_at=datetime.utcnow() ) db.session.add(member_user) db.session.commit() member_id = member_user.id # 获取团队长ID leader = User.query.filter_by(username='leader').first() leader_id = leader.id # 先添加团队成员 team_member = TeamMember(leader_id=leader_id, member_id=member_id) db.session.add(team_member) db.session.commit() # 管理员移除团队成员 response = client.delete(f'/api/admin/team-members/{member_id}', headers=auth_headers['admin']) assert response.status_code == 200 assert response.json['message'] == '团队成员已移除' # 验证团队成员关系已删除 team_member = TeamMember.query.filter_by( leader_id=leader_id, member_id=member_id).first() assert team_member is None def test_get_users_without_team(self, client, auth_headers): """测试获取没有团队的用户""" response = client.get('/api/admin/users/without-team', headers=auth_headers['admin']) assert response.status_code == 200 assert 'users' in response.json assert 'total' in response.json assert isinstance(response.json['users'], list) class TestTeamLeaderFunctions: """团队长功能测试""" def test_get_team_members_leader_only(self, client, auth_headers): """测试只有团队长可以获取团队成员列表""" # 普通用户尝试访问 response = client.get('/api/team/members', headers=auth_headers['user']) assert response.status_code == 403 # 管理员尝试访问 response = client.get('/api/team/members', headers=auth_headers['admin']) assert response.status_code == 403 # 团队长访问 response = client.get('/api/team/members', headers=auth_headers['leader']) assert response.status_code == 200 assert 'members' in response.json assert 'total' in response.json def test_get_team_statistics_leader_only(self, client, auth_headers): """测试只有团队长可以获取团队统计信息""" # 普通用户尝试访问 response = client.get('/api/team/statistics', headers=auth_headers['user']) assert response.status_code == 403 # 团队长访问 response = client.get('/api/team/statistics', headers=auth_headers['leader']) assert response.status_code == 200 assert 'total_members' in response.json assert 'total_files' in response.json assert 'total_downloads' in response.json def test_update_member_quota_leader_only(self, client, auth_headers, app): """测试只有团队长可以更新成员配额""" with app.app_context(): from app.models import User from werkzeug.security import generate_password_hash from app import db # 创建团队成员 member_user = User( username='teammember', email='teammember@test.com', password_hash=generate_password_hash('member123'), is_admin=False, is_team_leader=False, is_active=True, daily_download_limit=5, created_at=datetime.utcnow() ) db.session.add(member_user) db.session.commit() member_id = member_user.id # 添加团队成员关系 leader = User.query.filter_by(username='leader').first() team_member = TeamMember(leader_id=leader.id, member_id=member_id) db.session.add(team_member) db.session.commit() # 普通用户尝试更新配额 response = client.put(f'/api/team/members/{member_id}/quota', headers=auth_headers['user'], json={'daily_download_limit': 10}) assert response.status_code == 403 # 团队长更新配额 response = client.put(f'/api/team/members/{member_id}/quota', headers=auth_headers['leader'], json={'daily_download_limit': 10}) assert response.status_code == 200 assert response.json['message'] == '成员配额已更新' # 验证配额已更新 member = User.query.get(member_id) assert member.daily_download_limit == 10 def test_toggle_member_status_leader_only(self, client, auth_headers, app): """测试只有团队长可以启用/禁用成员""" with app.app_context(): from app.models import User from werkzeug.security import generate_password_hash from app import db # 创建团队成员 member_user = User( username='teammember2', email='teammember2@test.com', password_hash=generate_password_hash('member123'), is_admin=False, is_team_leader=False, is_active=True, created_at=datetime.utcnow() ) db.session.add(member_user) db.session.commit() member_id = member_user.id # 添加团队成员关系 leader = User.query.filter_by(username='leader').first() team_member = TeamMember(leader_id=leader.id, member_id=member_id) db.session.add(team_member) db.session.commit() # 普通用户尝试禁用成员 response = client.put(f'/api/team/members/{member_id}/status', headers=auth_headers['user'], json={'is_active': False}) assert response.status_code == 403 # 团队长禁用成员 response = client.put(f'/api/team/members/{member_id}/status', headers=auth_headers['leader'], json={'is_active': False}) assert response.status_code == 200 assert response.json['message'] == '成员状态已更新' # 验证成员已被禁用 member = User.query.get(member_id) assert member.is_active is False def test_get_available_categories_leader_only(self, client, auth_headers): """测试只有团队长可以获取可分配分类""" # 普通用户尝试访问 response = client.get('/api/team/available-categories', headers=auth_headers['user']) assert response.status_code == 403 # 团队长访问 response = client.get('/api/team/available-categories', headers=auth_headers['leader']) assert response.status_code == 200 assert 'categories' in response.json assert isinstance(response.json['categories'], list) class TestTeamLeaderValidation: """团队长功能验证测试""" def test_cannot_add_self_as_member(self, client, auth_headers, app): """测试团队长不能添加自己为成员""" with app.app_context(): from app.models import User leader = User.query.filter_by(username='leader').first() leader_id = leader.id # 尝试添加自己为成员 response = client.post('/api/admin/team-members', headers=auth_headers['admin'], json={'leader_id': leader_id, 'member_id': leader_id}) assert response.status_code == 400 assert '不能添加自己为团队成员' in response.json['message'] def test_cannot_add_admin_as_member(self, client, auth_headers, app): """测试不能添加管理员为成员""" with app.app_context(): from app.models import User admin = User.query.filter_by(username='admin').first() admin_id = admin.id leader = User.query.filter_by(username='leader').first() leader_id = leader.id # 尝试添加管理员为成员 response = client.post('/api/admin/team-members', headers=auth_headers['admin'], json={'leader_id': leader_id, 'member_id': admin_id}) assert response.status_code == 400 assert '不能添加管理员为团队成员' in response.json['message'] def test_cannot_add_existing_member(self, client, auth_headers, app): """测试不能重复添加团队成员""" with app.app_context(): from app.models import User from werkzeug.security import generate_password_hash from app import db # 创建团队成员 member_user = User( username='duplicatemember', email='duplicate@test.com', password_hash=generate_password_hash('member123'), is_admin=False, is_team_leader=False, is_active=True, created_at=datetime.utcnow() ) db.session.add(member_user) db.session.commit() member_id = member_user.id # 获取团队长ID leader = User.query.filter_by(username='leader').first() leader_id = leader.id # 第一次添加成功 response = client.post('/api/admin/team-members', headers=auth_headers['admin'], json={'leader_id': leader_id, 'member_id': member_id}) assert response.status_code == 201 # 第二次添加应该失败 response = client.post('/api/admin/team-members', headers=auth_headers['admin'], json={'leader_id': leader_id, 'member_id': member_id}) assert response.status_code == 400 assert '该用户已经是团队成员' in response.json['message'] def test_cannot_update_non_team_member_quota(self, client, auth_headers, app): """测试不能更新非团队成员的配额""" with app.app_context(): from app.models import User from werkzeug.security import generate_password_hash from app import db # 创建非团队成员用户 non_member = User( username='nonmember', email='nonmember@test.com', password_hash=generate_password_hash('member123'), is_admin=False, is_team_leader=False, is_active=True, created_at=datetime.utcnow() ) db.session.add(non_member) db.session.commit() non_member_id = non_member.id # 团队长尝试更新非成员配额 response = client.put(f'/api/team/members/{non_member_id}/quota', headers=auth_headers['leader'], json={'daily_download_limit': 10}) assert response.status_code == 404 assert '该用户不是您的团队成员' in response.json['message']