Implement unsafe icon cache diagnostics (T-611)

This commit is contained in:
ila
2026-07-18 15:18:29 +08:00
parent 6455fec811
commit 320b83d929
22 changed files with 697 additions and 31 deletions
+158
View File
@@ -230,6 +230,164 @@ func TestAppShellRejectsMalformedIconEventAndIgnoresOtherEvents(t *testing.T) {
}
}
func TestAppShellRendersOnlyUnsafeIconCacheDiagnostic(t *testing.T) {
reference := testIconReference("55")
item := application.CatalogListItem{
ID: "app-one",
Name: "One",
Version: "1.0.0",
IconRef: reference,
}
shell := NewAppShell("Test", item)
identity := testIconIdentity(t, "request-unsafe", item.ID, reference, 144)
if err := shell.ExpectIcon(identity); err != nil {
t.Fatal(err)
}
applyTestIconFailure(t, shell, identity, application.IconFailureUnsafe)
shell.model.Select(item.ID)
nodes := adapterContractLayout(shell, adapterContractViewport)
failure := shell.iconFailures[item.ID]
for _, want := range []string{
"图标缓存安全警告",
unsafeIconCacheMessage,
unsafeIconCacheDiagnostic(failure),
} {
if !adapterContractHasSemantic(nodes, want) {
t.Fatalf("unsafe cache detail is missing semantic text %q", want)
}
}
if diagnostic := unsafeIconCacheDiagnostic(failure); strings.Contains(diagnostic, "sha256:") {
t.Fatalf("unsafe cache diagnostic exposed the reference scheme: %q", diagnostic)
}
unavailable := testIconIdentity(t, "request-unavailable", item.ID, reference, 144)
if err := shell.ExpectIcon(unavailable); err != nil {
t.Fatal(err)
}
applyTestIconFailure(t, shell, unavailable, application.IconFailureUnavailable)
nodes = adapterContractLayout(shell, adapterContractViewport)
if adapterContractHasSemantic(nodes, "图标缓存安全警告") {
t.Fatal("ordinary icon failure rendered an unsafe-cache warning")
}
if code, exists := shell.IconFailure(item.ID); !exists ||
code != application.IconFailureUnavailable {
t.Fatalf("IconFailure() = (%q, %t)", code, exists)
}
}
func TestAppShellRetainsUnsafeDiagnosticOnlyForCurrentResource(t *testing.T) {
reference := testIconReference("66")
item := application.CatalogListItem{
ID: "app-one",
Name: "One",
Version: "1.0.0",
IconRef: reference,
}
shell := NewAppShell("Test", item)
first := testIconIdentity(t, "request-first", item.ID, reference, 96)
if err := shell.ExpectIcon(first); err != nil {
t.Fatal(err)
}
firstFailure := applyTestIconFailure(
t,
shell,
first,
application.IconFailureUnsafe,
)
if got := shell.iconFailures[item.ID].Identity; got != first {
t.Fatalf("stored failure identity = %+v, want %+v", got, first)
}
shell.SetItems([]application.CatalogListItem{item})
if code, exists := shell.IconFailure(item.ID); !exists ||
code != application.IconFailureUnsafe {
t.Fatal("same-reference snapshot discarded the unsafe diagnostic")
}
latest := testIconIdentity(t, "request-latest", item.ID, reference, 96)
if err := shell.ExpectIcon(latest); err != nil {
t.Fatal(err)
}
if _, exists := shell.IconFailure(item.ID); exists {
t.Fatal("new request retained the previous unsafe diagnostic")
}
if err := shell.ApplyEvent(firstFailure); err != nil {
t.Fatal(err)
}
if _, exists := shell.IconFailure(item.ID); exists {
t.Fatal("late failure restored a stale diagnostic")
}
ready, err := application.NewIconReadyEvent(
latest,
image.NewNRGBA(image.Rect(0, 0, 16, 16)),
)
if err != nil {
t.Fatal(err)
}
if err := shell.ApplyEvent(ready); err != nil {
t.Fatal(err)
}
if _, exists := shell.IconFailure(item.ID); exists {
t.Fatal("ready event retained an unsafe diagnostic")
}
dpiRequest := testIconIdentity(t, "request-dpi", item.ID, reference, 144)
if err := shell.ExpectIcon(dpiRequest); err != nil {
t.Fatal(err)
}
applyTestIconFailure(t, shell, dpiRequest, application.IconFailureUnsafe)
if got := shell.iconFailures[item.ID].Identity.DPI; got != 144 {
t.Fatalf("stored failure DPI = %d, want 144", got)
}
newReference := testIconReference("77")
changed := item
changed.IconRef = newReference
shell.SetItems([]application.CatalogListItem{changed})
if _, exists := shell.IconFailure(item.ID); exists {
t.Fatal("IconRef change retained the unsafe diagnostic")
}
canceled := testIconIdentity(t, "request-canceled", item.ID, newReference, 96)
if err := shell.ExpectIcon(canceled); err != nil {
t.Fatal(err)
}
if !shell.CancelIconRequest(item.ID, canceled.RequestID) {
t.Fatal("CancelIconRequest() did not cancel the current request")
}
applyTestIconFailure(t, shell, canceled, application.IconFailureUnsafe)
if _, exists := shell.IconFailure(item.ID); exists {
t.Fatal("canceled failure created an unsafe diagnostic")
}
final := testIconIdentity(t, "request-final", item.ID, newReference, 96)
if err := shell.ExpectIcon(final); err != nil {
t.Fatal(err)
}
applyTestIconFailure(t, shell, final, application.IconFailureUnsafe)
shell.SetItems(nil)
if _, exists := shell.IconFailure(item.ID); exists {
t.Fatal("removed app retained the unsafe diagnostic")
}
}
func applyTestIconFailure(
t *testing.T,
shell *AppShell,
identity application.IconEventIdentity,
code application.IconFailureCode,
) application.Event {
t.Helper()
event, err := application.NewIconFailedEvent(identity, code)
if err != nil {
t.Fatal(err)
}
if err := shell.ApplyEvent(event); err != nil {
t.Fatal(err)
}
return event
}
func testIconReference(pair string) string {
return "sha256:" + strings.Repeat(pair, 32)
}