From fbc1eda561087b0f7debb33c4f397b51cbfc9398 Mon Sep 17 00:00:00 2001 From: Blizzard Date: Mon, 5 Oct 2026 20:13:10 +0800 Subject: [PATCH] fix: ignore cancelled pet photo selection --- pets-fe/pages/pet-edit/pet-edit.js | 13 ++++- tests/pet-avatar.test.cjs | 76 ++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 tests/pet-avatar.test.cjs diff --git a/pets-fe/pages/pet-edit/pet-edit.js b/pets-fe/pages/pet-edit/pet-edit.js index 53d3c13..896776c 100644 --- a/pets-fe/pages/pet-edit/pet-edit.js +++ b/pets-fe/pages/pet-edit/pet-edit.js @@ -41,9 +41,18 @@ Page({ this.setData({ gender: e.detail.value }); }, async choose() { + let selection; try { - const r = await wx.chooseMedia({ count: 1, mediaType: ["image"] }); - const file = await upload(r.tempFiles[0].tempFilePath); + selection = await wx.chooseMedia({ count: 1, mediaType: ["image"] }); + } catch (e) { + if (/^chooseMedia:fail cancel\b/i.test((e && e.errMsg) || "")) return; + toast(e); + return; + } + const photo = selection && selection.tempFiles && selection.tempFiles[0]; + if (!photo || !photo.tempFilePath) return; + try { + const file = await upload(photo.tempFilePath); this.setData({ avatar_file_id: file.id, avatar_url: file.url }); } catch (e) { toast(e); diff --git a/tests/pet-avatar.test.cjs b/tests/pet-avatar.test.cjs new file mode 100644 index 0000000..153a67f --- /dev/null +++ b/tests/pet-avatar.test.cjs @@ -0,0 +1,76 @@ +const test = require("node:test"); +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const vm = require("node:vm"); +const path = require("node:path"); + +function screen(chooseMedia, upload) { + let definition; + const errors = []; + vm.runInNewContext( + fs.readFileSync(path.join(__dirname, "../pets-fe/pages/pet-edit/pet-edit.js"), "utf8"), + { + Page: (value) => { definition = value; }, + wx: { chooseMedia }, + require: () => ({ upload, toast: (error) => errors.push(error) }), + }, + ); + return { + ...definition, + data: { ...definition.data, avatar_file_id: "original-id", avatar_url: "original-photo" }, + errors, + setData(changes) { Object.assign(this.data, changes); }, + }; +} + +test("取消选择宠物照片不上传、不提示错误,保留原头像", async () => { + let uploads = 0; + const page = screen( + async () => { throw { errMsg: "chooseMedia:fail cancel" }; }, + async () => { uploads++; }, + ); + await page.choose(); + assert.equal(uploads, 0); + assert.equal(page.errors.length, 0); + assert.equal(page.data.avatar_file_id, "original-id"); + assert.equal(page.data.avatar_url, "original-photo"); +}); + +test("空的照片选择结果不上传", async () => { + const page = screen(async () => ({ tempFiles: [] }), async () => assert.fail("不应上传")); + await page.choose(); + assert.equal(page.errors.length, 0); + assert.equal(page.data.avatar_file_id, "original-id"); +}); + +test("实际选择失败仍提示错误", async () => { + const error = { errMsg: "chooseMedia:fail permission denied" }; + const page = screen(async () => { throw error; }, async () => assert.fail("不应上传")); + await page.choose(); + assert.equal(page.errors[0], error); +}); + +test("实际上传失败仍提示错误并保留原头像", async () => { + const error = new Error("上传失败"); + const page = screen( + async () => ({ tempFiles: [{ tempFilePath: "/tmp/photo.jpg" }] }), + async () => { throw error; }, + ); + await page.choose(); + assert.equal(page.errors[0], error); + assert.equal(page.data.avatar_file_id, "original-id"); +}); + +test("上传成功后更新宠物头像", async () => { + const page = screen( + async () => ({ tempFiles: [{ tempFilePath: "/tmp/photo.jpg" }] }), + async (filePath) => { + assert.equal(filePath, "/tmp/photo.jpg"); + return { id: "new-id", url: "new-photo" }; + }, + ); + await page.choose(); + assert.equal(page.errors.length, 0); + assert.equal(page.data.avatar_file_id, "new-id"); + assert.equal(page.data.avatar_url, "new-photo"); +});