Implement unsafe icon cache diagnostics (T-611)
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user