完成上传下载连接,公告管理与详情页面,求种区页面,轮播图折扣显示,修改部分bug
Change-Id: I86fc294e32911cb3426a8b16f90aca371f975c11
diff --git a/src/api/personal.test.js b/src/api/personal.test.js
new file mode 100644
index 0000000..3a929e8
--- /dev/null
+++ b/src/api/personal.test.js
@@ -0,0 +1,354 @@
+// src/api/__tests__/personal.test.js
+import {
+ getUserInfo,
+ formatFileSize,
+ getDownloadQuota,
+ getDownloadProgress,
+ getUserTorrents,
+ deleteTorrent,
+ generateInviteCode,
+ getUserInviteCodes,
+ exchangeUpload,
+ updatePassword
+} from './personal';
+import { api } from './auth';
+
+// 模拟整个 auth 模块
+jest.mock('./auth');
+
+describe('Personal API', () => {
+ beforeEach(() => {
+ // 在每个测试前重置模拟
+ jest.clearAllMocks();
+ });
+
+ describe('getUserInfo', () => {
+ it('should return formatted user info when API call succeeds', async () => {
+ const mockUserData = {
+ username: 'testuser',
+ level: 3,
+ registTime: '2023-01-01T00:00:00Z',
+ magicPoints: 100,
+ upload: 1024,
+ download: 512,
+ shareRate: 2.0
+ };
+
+ api.get.mockResolvedValue({
+ data: {
+ code: 200,
+ data: mockUserData,
+ message: 'success'
+ }
+ });
+
+ const result = await getUserInfo();
+
+ expect(api.get).toHaveBeenCalledWith('/user/userInfo');
+ expect(result).toEqual({
+ username: 'testuser',
+ level: 3,
+ registTime: '2023-01-01',
+ magicPoints: 100,
+ upload: 1024,
+ download: 512,
+ shareRate: '2.00'
+ });
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.get.mockResolvedValue({
+ data: {
+ code: 500,
+ message: 'Internal server error'
+ }
+ });
+
+ await expect(getUserInfo()).rejects.toThrow('Internal server error');
+ });
+ });
+
+ describe('formatFileSize', () => {
+ it('should format bytes correctly', () => {
+ expect(formatFileSize(500)).toBe('500 B');
+ expect(formatFileSize(1024)).toBe('1.00 KB');
+ expect(formatFileSize(2048)).toBe('2.00 KB');
+ expect(formatFileSize(1024 * 1024)).toBe('1.00 MB');
+ expect(formatFileSize(1024 * 1024 * 2.5)).toBe('2.50 MB');
+ expect(formatFileSize(1024 * 1024 * 1024)).toBe('1.00 GB');
+ expect(formatFileSize(1024 * 1024 * 1024 * 3.7)).toBe('3.70 GB');
+ });
+ });
+
+ describe('getDownloadQuota', () => {
+ it('should return download quota data when API call succeeds', async () => {
+ const mockData = {
+ total: 1073741824, // 1GB in bytes
+ used: 536870912, // 512MB
+ remaining: 536870912
+ };
+
+ api.get.mockResolvedValue({
+ data: {
+ code: 200,
+ data: mockData,
+ message: 'success'
+ }
+ });
+
+ const result = await getDownloadQuota();
+
+ expect(api.get).toHaveBeenCalledWith('/user/allowDownload');
+ expect(result).toEqual(mockData);
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.get.mockResolvedValue({
+ data: {
+ code: 403,
+ message: 'Forbidden'
+ }
+ });
+
+ await expect(getDownloadQuota()).rejects.toThrow('Forbidden');
+ });
+ });
+
+ describe('getDownloadProgress', () => {
+ it('should return download progress when API call succeeds', async () => {
+ const mockProgresses = [
+ { id: 1, name: 'file1', progress: 50 },
+ { id: 2, name: 'file2', progress: 75 }
+ ];
+
+ api.get.mockResolvedValue({
+ data: {
+ code: 200,
+ data: { progresses: mockProgresses },
+ message: 'success'
+ }
+ });
+
+ const result = await getDownloadProgress();
+
+ expect(api.get).toHaveBeenCalledWith('/torrent/getProgress');
+ expect(result).toEqual(mockProgresses);
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.get.mockResolvedValue({
+ data: {
+ code: 404,
+ message: 'Not found'
+ }
+ });
+
+ await expect(getDownloadProgress()).rejects.toThrow('Not found');
+ });
+ });
+
+ describe('getUserTorrents', () => {
+ it('should return user torrents with pagination when API call succeeds', async () => {
+ const mockResponse = {
+ records: [
+ {
+ torrent: { id: 1, name: 'torrent1', size: 1024 },
+ downloadCount: 10,
+ formattedSize: '1 KB'
+ }
+ ],
+ total: 1
+ };
+
+ api.get.mockResolvedValue({
+ data: {
+ code: 200,
+ data: mockResponse,
+ message: 'success'
+ }
+ });
+
+ const result = await getUserTorrents(1, 5);
+
+ expect(api.get).toHaveBeenCalledWith('/torrent/get/torrentMyself', {
+ params: { page: 1, size: 5 }
+ });
+ expect(result).toEqual({
+ records: [
+ {
+ id: 1,
+ name: 'torrent1',
+ size: 1024,
+ downloadCount: 10,
+ formattedSize: '1 KB'
+ }
+ ],
+ total: 1
+ });
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.get.mockResolvedValue({
+ data: {
+ code: 500,
+ message: 'Server error'
+ }
+ });
+
+ await expect(getUserTorrents()).rejects.toThrow('Server error');
+ });
+ });
+
+ describe('deleteTorrent', () => {
+ it('should successfully delete torrent when API call succeeds', async () => {
+ const mockResponse = {
+ code: 200,
+ message: 'Deleted successfully'
+ };
+
+ api.delete.mockResolvedValue({
+ data: mockResponse
+ });
+
+ const result = await deleteTorrent(123);
+
+ expect(api.delete).toHaveBeenCalledWith('/torrent/deleteTorrent/123');
+ expect(result).toEqual(mockResponse);
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.delete.mockResolvedValue({
+ data: {
+ code: 404,
+ message: 'Torrent not found'
+ }
+ });
+
+ await expect(deleteTorrent(123)).rejects.toThrow('Torrent not found');
+ });
+ });
+
+ describe('generateInviteCode', () => {
+ it('should return generated invite code when API call succeeds', async () => {
+ const mockCode = 'ABCD-EFGH-IJKL';
+
+ api.post.mockResolvedValue({
+ data: {
+ code: 200,
+ data: { inviteCode: mockCode },
+ message: 'success'
+ }
+ });
+
+ const result = await generateInviteCode();
+
+ expect(api.post).toHaveBeenCalledWith('/invitecode/generate');
+ expect(result).toBe(mockCode);
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.post.mockResolvedValue({
+ data: {
+ code: 403,
+ message: 'Permission denied'
+ }
+ });
+
+ await expect(generateInviteCode()).rejects.toThrow('Permission denied');
+ });
+ });
+
+ describe('getUserInviteCodes', () => {
+ it('should return user invite codes when API call succeeds', async () => {
+ const mockCodes = ['CODE1', 'CODE2'];
+
+ api.get.mockResolvedValue({
+ data: {
+ code: 200,
+ data: { inviteCode: mockCodes },
+ message: 'success'
+ }
+ });
+
+ const result = await getUserInviteCodes();
+
+ expect(api.get).toHaveBeenCalledWith('/invitecode/userInviteCode');
+ expect(result).toEqual(mockCodes);
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.get.mockResolvedValue({
+ data: {
+ code: 500,
+ message: 'Server error'
+ }
+ });
+
+ await expect(getUserInviteCodes()).rejects.toThrow('Server error');
+ });
+ });
+
+ describe('exchangeUpload', () => {
+ it('should successfully exchange magic points for upload when API call succeeds', async () => {
+ const mockResponse = {
+ code: 200,
+ message: 'Exchange successful'
+ };
+
+ api.post.mockResolvedValue({
+ data: mockResponse
+ });
+
+ const result = await exchangeUpload(100);
+
+ expect(api.post).toHaveBeenCalledWith('/user/exchangeUpload', {
+ magicPoint: 100
+ });
+ expect(result).toEqual(mockResponse);
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.post.mockResolvedValue({
+ data: {
+ code: 400,
+ message: 'Not enough points'
+ }
+ });
+
+ await expect(exchangeUpload(100)).rejects.toThrow('Not enough points');
+ });
+ });
+
+ describe('updatePassword', () => {
+ it('should successfully update password when API call succeeds', async () => {
+ const mockResponse = {
+ code: 200,
+ message: 'Password updated'
+ };
+
+ api.put.mockResolvedValue({
+ data: mockResponse
+ });
+
+ const result = await updatePassword('oldPass', 'newPass');
+
+ expect(api.put).toHaveBeenCalledWith('/user/password', {
+ oldPassword: 'oldPass',
+ newPassword: 'newPass'
+ });
+ expect(result).toEqual(mockResponse);
+ });
+
+ it('should throw error when API call fails', async () => {
+ api.put.mockResolvedValue({
+ data: {
+ code: 401,
+ message: 'Invalid old password'
+ }
+ });
+
+ await expect(updatePassword('wrongPass', 'newPass'))
+ .rejects.toThrow('Invalid old password');
+ });
+ });
+});
\ No newline at end of file