generated from ttipo/project-base
test(frontend): 대용량 파일을 다 올린 뒤 보낸다 — 조각 SHA-256 이 스레드 풀이라 부하에서 늦다
CI / Backend (lint · type-check · test · e2e · build) (pull_request) Failing after 10m31s
CI / Infra (compose · Dockerfile · nginx · 운영 스크립트) (pull_request) Successful in 2m18s
CI / Frontend (lint · type-check · test · build) (pull_request) Successful in 14m21s
CI / 에러 코드 SSOT 동기화 검사 (pull_request) Successful in 11m30s
CI / Backend (lint · type-check · test · e2e · build) (pull_request) Failing after 10m31s
CI / Infra (compose · Dockerfile · nginx · 운영 스크립트) (pull_request) Successful in 2m18s
CI / Frontend (lint · type-check · test · build) (pull_request) Successful in 14m21s
CI / 에러 코드 SSOT 동기화 검사 (pull_request) Successful in 11m30s
쓰기 화면의 두 테스트는 대용량 파일을 고른 뒤 양보(flushPromises) 두 번 만에 다 올렸다고 보았다. 조각의 SHA-256 은 jsdom 이 아니라 Node 의 Web Crypto(libuv 스레드 풀)라, CI 부하에서 그 안에 끝나지 않았다. 다 올리기 전에 누른 [보내기]는 막혀 보내기 요청이 끝내 나가지 않아 payload 가 undefined 였다(2026-11-03 CI — ComposePage.spec.ts 첨부 합계 테스트). - 두 테스트(첨부 합계 · 링크로 보내기)는 대용량 줄이 ready 가 될 때까지 vi.waitFor 로 본다. 첨부 합계 테스트는 보내기 전에 막는 까닭이 없음도 단언한다. - test-utils/timeouts.ts 에 WAIT_FOR_TIMEOUT_MS(15초 — 테스트 한도 20초보다 짧게)를 둔다. - digest 를 늦춘 실험으로 고치기 전에는 깨지고 고친 뒤에는 통과함을 확인했다(실험은 되돌림). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
} from '@/test-utils/mock-api'
|
||||
import { installProseMirrorDom } from '@/test-utils/prosemirror-dom'
|
||||
import { createTestRouter, routeViewProvide } from '@/test-utils/router'
|
||||
import { WAIT_FOR_TIMEOUT_MS } from '@/test-utils/timeouts'
|
||||
import ComposePage from './ComposePage.vue'
|
||||
|
||||
// 쓰기 화면의 대용량 첨부 (11단계 — 디자인 원본 ComposeLargeFiles · 계약 4절 "발송 · 임시 저장과 함께" · "인용 속 링크의 상태")
|
||||
@@ -367,7 +368,14 @@ describe('ComposePage — 대용량 첨부', () => {
|
||||
expect(wrapper.get('#compose-send-why').text()).toBe(SEND_BLOCK_TEXT.uploading('1'))
|
||||
|
||||
releaseChunk()
|
||||
await flushPromises()
|
||||
// 조각을 받으면 끝내기까지 가 ready 가 된다 — 조각을 보내기 전의 SHA-256 은 Node 의 Web Crypto(스레드 풀)라
|
||||
// 부하가 크면 양보 두 번으로는 끝나지 않는다 (ComposePage.spec.ts 의 첨부 합계 테스트와 같은 까닭) — ready 가 될 때까지 본다
|
||||
await vi.waitFor(
|
||||
() => {
|
||||
if (phases(wrapper)[0] !== 'ready') throw new Error('대용량 파일을 올리는 중')
|
||||
},
|
||||
{ timeout: WAIT_FOR_TIMEOUT_MS },
|
||||
)
|
||||
await flushPromises()
|
||||
|
||||
expect(phases(wrapper)).toEqual(['ready'])
|
||||
|
||||
@@ -36,7 +36,7 @@ import {
|
||||
} from '@/test-utils/mock-api'
|
||||
import { editorOf, fileDragEvent, installProseMirrorDom, pasteEvent } from '@/test-utils/prosemirror-dom'
|
||||
import { createTestRouter, routeViewProvide } from '@/test-utils/router'
|
||||
import { LONG_DRAFT_TIMEOUT_MS } from '@/test-utils/timeouts'
|
||||
import { LONG_DRAFT_TIMEOUT_MS, WAIT_FOR_TIMEOUT_MS } from '@/test-utils/timeouts'
|
||||
import ComposePage from './ComposePage.vue'
|
||||
|
||||
const USER = { email: 'ara.kim@arasystem.it.kr', name: '김아라' }
|
||||
@@ -599,7 +599,17 @@ describe('ComposePage', () => {
|
||||
configurable: true,
|
||||
})
|
||||
await picker.trigger('change')
|
||||
await flushPromises()
|
||||
// 도면은 다 올려야(끝내기 응답 뒤 ready) [보내기]가 풀린다 — 그 전에 누른 보내기는 막혀 보내기 요청이 끝내 나가지 않는다.
|
||||
// 조각의 SHA-256 은 Node 의 Web Crypto(스레드 풀)라 부하가 크면 양보 두 번으로는 끝나지 않았다 (2026-11-03 CI) — ready 가 될 때까지 본다
|
||||
await vi.waitFor(
|
||||
() => {
|
||||
const row = wrapper.find('[data-large-upload]')
|
||||
if (!row.exists() || row.attributes('data-phase') !== 'ready') {
|
||||
throw new Error('대용량 파일을 올리는 중')
|
||||
}
|
||||
},
|
||||
{ timeout: WAIT_FOR_TIMEOUT_MS },
|
||||
)
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.findAll('.upload-item').map((item) => item.classes())).toEqual([
|
||||
@@ -612,6 +622,8 @@ describe('ComposePage', () => {
|
||||
)
|
||||
expect(requests.filter((request) => request.url === '/mail-attachments')).toHaveLength(1)
|
||||
expect(useToastStore().toasts).toEqual([])
|
||||
// 다 올렸다 — [보내기]를 막는 까닭이 없다 (아래 보내기는 마이크로태스크로만 이어져 양보 한 번이면 요청이 나간다)
|
||||
expect(wrapper.find('#compose-send-why').exists()).toBe(false)
|
||||
|
||||
const input = wrapper.get('#compose-to')
|
||||
await input.setValue('junho.park@arasystem.it.kr')
|
||||
|
||||
@@ -9,3 +9,11 @@
|
||||
* 전체 한도에 가까워 이 테스트들에만 30초를 준다.
|
||||
*/
|
||||
export const LONG_DRAFT_TIMEOUT_MS = 30_000
|
||||
|
||||
/**
|
||||
* 조건이 될 때까지 다시 보는 기다림(vi.waitFor)의 기한 — 몇 번 양보(flushPromises)해서는 끝난다고 믿을 수 없는 일을 기다린다.
|
||||
* 예: 대용량 파일 조각의 SHA-256 — jsdom 이 아니라 Node 의 Web Crypto 라 스레드 풀에서 돌아, 부하가 크면 양보 두 번 안에 끝나지 않았다
|
||||
* (2026-11-03 CI — 다 올리기 전에 누른 [보내기]는 막혀 보내기 요청이 끝내 나가지 않는다).
|
||||
* 테스트 한도(vitest.config.ts, 20초)보다 짧게 둬, 끝내 되지 않으면 테스트 한도보다 이 기다림이 먼저 까닭(던진 글)을 알린다.
|
||||
*/
|
||||
export const WAIT_FOR_TIMEOUT_MS = 15_000
|
||||
|
||||
Reference in New Issue
Block a user