merge: W9 — 文档附件接到 UI 与发送链路(选文件 / 待发芯片 / chat.documents / 分享分流)
This commit is contained in:
commit
ab76798bff
14 files changed
+1668
-65
No files matched your search
@@ -0,0 +1,103 @@
|
||||
package top.yeij.cyrene.ui.chat
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import top.yeij.cyrene.core.error.CyreneError
|
||||
import top.yeij.cyrene.data.api.CyreneException
|
||||
|
||||
/**
|
||||
* 附件上传失败的文案(纯函数)。
|
||||
*
|
||||
* 这里锚的是**每个拒绝码对应的正确动作**:这四个码在用户能做的事上各不相同
|
||||
* (415/413 = 换文件、400 = 少选几个、404 = 重传、401/403 = 重新登录),折成一句
|
||||
* 「附件失败」等于让用户去猜。文案由**服务端**给(含真实上限),客户端**不自己编数字**。
|
||||
*
|
||||
* 另一个锚点是「这是上传这一步失败」:网络类失败必须点明,否则用户看到「无法连接到服务器」
|
||||
* 会以为整条消息没发出去,而实际上文字与附件一起回到了输入框。
|
||||
*/
|
||||
class DocumentUploadFailureTest {
|
||||
|
||||
private fun server(code: String, message: String, status: Int = 400) =
|
||||
CyreneException(CyreneError.Server(code, message, status))
|
||||
|
||||
@Test
|
||||
fun `unsupported media type keeps the server wording instead of inventing one`() {
|
||||
val message = documentUploadFailureMessage(
|
||||
server("unsupported_media_type", "extension not allowed or content is not plain text", 415),
|
||||
)
|
||||
|
||||
assertEquals("extension not allowed or content is not plain text", message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `too large keeps the server limit so the number is the real one`() {
|
||||
val message = documentUploadFailureMessage(
|
||||
server("document_too_large", "file exceeds the 20971520 byte limit", 413),
|
||||
)
|
||||
|
||||
assertEquals("file exceeds the 20971520 byte limit", message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `too many documents keeps the server wording as well`() {
|
||||
val message = documentUploadFailureMessage(server("too_many_documents", "at most 5 documents", 400))
|
||||
|
||||
assertEquals("at most 5 documents", message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a missing document says to send it again`() {
|
||||
val message = documentUploadFailureMessage(server("document_not_found", "document not found", 404))
|
||||
|
||||
assertEquals("document not found", message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `an expired session asks for a re-login, not for another file`() {
|
||||
val message = documentUploadFailureMessage(
|
||||
CyreneException(CyreneError.Unauthorized("unauthorized", "auth: unauthorized")),
|
||||
)
|
||||
|
||||
assertTrue(message, message.contains("重新登录"))
|
||||
assertFalse("鉴权失败不该劝用户换文件", message.contains("换"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a network failure names the step that failed and keeps the reason`() {
|
||||
val message = documentUploadFailureMessage(
|
||||
CyreneException(CyreneError.Local(CyreneError.LocalKind.NoNetwork)),
|
||||
)
|
||||
|
||||
assertEquals("附件上传失败,网络不可用,请检查连接", message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `an unknown server code still carries the server message`() {
|
||||
val message = documentUploadFailureMessage(server("weird_new_code", "something went wrong", 500))
|
||||
|
||||
assertEquals("附件上传失败,something went wrong", message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `a non Cyrene throwable still produces an actionable message`() {
|
||||
assertEquals("附件上传失败,请重试", documentUploadFailureMessage(IllegalStateException("boom")))
|
||||
assertEquals("附件上传失败,请重试", documentUploadFailureMessage(RuntimeException()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `no failure path ever claims the attachment was sent`() {
|
||||
val messages = listOf(
|
||||
documentUploadFailureMessage(server("unsupported_media_type", "x", 415)),
|
||||
documentUploadFailureMessage(server("document_too_large", "x", 413)),
|
||||
documentUploadFailureMessage(server("too_many_documents", "x", 400)),
|
||||
documentUploadFailureMessage(server("document_not_found", "x", 404)),
|
||||
documentUploadFailureMessage(CyreneException(CyreneError.Local(CyreneError.LocalKind.Timeout))),
|
||||
documentUploadFailureMessage(IllegalStateException()),
|
||||
)
|
||||
|
||||
// 文案里绝不能出现「已发送 / 已上传」这类暗示:失败即整轮回滚,附件与正文一起回到输入框。
|
||||
assertTrue(messages.toString(), messages.none { it.contains("已发送") || it.contains("已上传") })
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user