teamBackgroundFile.spec.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import {
  2. ACCEPT,
  3. formatFileSize,
  4. validateBackgroundFile,
  5. validateEnterpriseWebsite
  6. } from '@/utils/teamBackgroundFile'
  7. import request from '@/utils/request2'
  8. import {
  9. completePublicUpload,
  10. createTeamBackgroundSession,
  11. disableTeamBackgroundFile,
  12. downloadTeamBackgroundFile,
  13. getPublicUploadSession,
  14. listTeamBackgroundFiles,
  15. uploadPublicTeamBackgroundFile,
  16. uploadTeamBackgroundFile,
  17. verifyPublicUploadCode
  18. } from '@/api/teamBackgroundFile'
  19. jest.mock('@/utils/request2', () => jest.fn())
  20. class TestFormData {
  21. constructor() {
  22. this.entries = []
  23. }
  24. append(name, value) {
  25. this.entries.push([name, value])
  26. }
  27. }
  28. global.FormData = TestFormData
  29. beforeEach(() => {
  30. request.mockReset()
  31. })
  32. test('accepts all approved extensions case-insensitively', () => {
  33. for (const ext of ['pdf','doc','docx','xls','xlsx','ppt','pptx','txt','md','csv']) {
  34. expect(validateBackgroundFile({ name: `file.${ext.toUpperCase()}`, size: 1 })).toBe('')
  35. }
  36. })
  37. test('rejects archives, 50MB overflow and names over 255 chars', () => {
  38. expect(validateBackgroundFile({ name: 'file.zip', size: 1 })).toContain('文件类型')
  39. expect(validateBackgroundFile({ name: 'file.pdf', size: 50 * 1024 * 1024 + 1 })).toContain('50MB')
  40. expect(validateBackgroundFile({ name: `${'a'.repeat(252)}.pdf`, size: 1 })).toContain('255')
  41. })
  42. test('accepts a filename containing exactly 255 characters', () => {
  43. const name = `${'a'.repeat(251)}.pdf`
  44. expect(name).toHaveLength(255)
  45. expect(validateBackgroundFile({ name, size: 1 })).toBe('')
  46. })
  47. test('accepts a file containing exactly 50MiB', () => {
  48. expect(validateBackgroundFile({ name: 'file.pdf', size: 50 * 1024 * 1024 })).toBe('')
  49. })
  50. test('rejects missing, unnamed and zero-size files', () => {
  51. expect(validateBackgroundFile()).toBe('请选择非空文件')
  52. expect(validateBackgroundFile({ name: '', size: 1 })).toBe('请选择非空文件')
  53. expect(validateBackgroundFile({ name: 'empty.pdf', size: 0 })).toBe('请选择非空文件')
  54. })
  55. test('exports the exact file-picker accept list', () => {
  56. expect(ACCEPT).toBe('.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.md,.csv')
  57. })
  58. test('formats byte counts across byte, KB and MB thresholds', () => {
  59. expect(formatFileSize(0)).toBe('0 B')
  60. expect(formatFileSize(1)).toBe('1 B')
  61. expect(formatFileSize(1023)).toBe('1023 B')
  62. expect(formatFileSize(1024)).toBe('1 KB')
  63. expect(formatFileSize(1536)).toBe('1.5 KB')
  64. expect(formatFileSize(1024 * 1024)).toBe('1 MB')
  65. expect(formatFileSize(1.5 * 1024 * 1024)).toBe('1.5 MB')
  66. })
  67. test('enforces the backend enterprise website 500-character boundary', () => {
  68. const website = length => `https://example.com/${'a'.repeat(length - 20)}`
  69. expect(validateEnterpriseWebsite(website(499))).toBe('')
  70. expect(validateEnterpriseWebsite(website(500))).toBe('')
  71. expect(validateEnterpriseWebsite(website(501))).toContain('500')
  72. })
  73. test('uses backend-controlled authenticated file routes', () => {
  74. listTeamBackgroundFiles(7)
  75. createTeamBackgroundSession(7)
  76. disableTeamBackgroundFile(7, 12)
  77. downloadTeamBackgroundFile(7, 12)
  78. expect(request.mock.calls).toEqual([
  79. [{ url: '/core/userteam/7/background-files', method: 'get' }],
  80. [{ url: '/core/userteam/7/background-upload-session', method: 'post' }],
  81. [{ url: '/core/userteam/7/background-files/12', method: 'delete' }],
  82. [{ url: '/core/userteam/7/background-files/12/download', method: 'get', responseType: 'blob' }]
  83. ])
  84. })
  85. test('uploads authenticated files without client-supplied identity fields', () => {
  86. const file = { name: 'brief.pdf' }
  87. uploadTeamBackgroundFile(7, file)
  88. const config = request.mock.calls[0][0]
  89. expect(config).toEqual({
  90. url: '/core/userteam/7/background-files',
  91. method: 'post',
  92. data: expect.any(TestFormData)
  93. })
  94. expect(config.data.entries).toEqual([['file', file]])
  95. })
  96. test('uses fixed public routes and sends only server-issued credentials', () => {
  97. const file = { name: 'brief.pdf' }
  98. const onProgress = jest.fn()
  99. getPublicUploadSession('session-token')
  100. verifyPublicUploadCode('123456')
  101. completePublicUpload('upload-token')
  102. uploadPublicTeamBackgroundFile('upload-token', file, onProgress)
  103. const uploadData = request.mock.calls[3][0].data
  104. expect(request.mock.calls).toEqual([
  105. [{ url: '/public/team-background-upload/session', method: 'get', params: { token: 'session-token' } }],
  106. [{ url: '/public/team-background-upload/verify', method: 'post', data: { code: '123456' } }],
  107. [{ url: '/public/team-background-upload/complete', method: 'post', headers: { 'X-Upload-Token': 'upload-token' } }],
  108. [{
  109. url: '/public/team-background-upload/files',
  110. method: 'post',
  111. data: uploadData,
  112. headers: { 'X-Upload-Token': 'upload-token' },
  113. onUploadProgress: onProgress
  114. }]
  115. ])
  116. expect(uploadData).toEqual(expect.any(TestFormData))
  117. expect(uploadData.entries).toEqual([['file', file]])
  118. })