fix(docker): mail setup 받는 메일 크기 한도 50MiB · 전환 준비 문서 (mailcow 확인 · 서버 B 배포 · 백업 · 큰 메일) #12

Merged
ttipo merged 14 commits from feat/mail-migration-password into main 2026-11-04 07:59:25 +09:00
3 changed files with 31 additions and 3 deletions
Showing only changes of commit 349c312989 - Show all commits
@@ -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'])
+14 -2
View File
@@ -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')
+8
View File
@@ -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