package main import ( "encoding/json" "net/http" "net/http/httptest" "os" "strings" "testing" "honeyos/internal/store" "honeyos/internal/weather" ) // Ohne eingestellten Ort ist 204 die richtige Antwort: kein Fehler, nur nichts // zu zeigen. Die Leiste lässt das Symbol dann weg, statt etwas zu melden. func TestOhneOrtGibtEsKeinWetter(t *testing.T) { s := newTestServer(t, "") // ohne Anbieter: offener Betrieb, kein Anmelden nötig s.wetter = weather.FakeFuerTest(t, 0, 20) rec := httptest.NewRecorder() s.routes().ServeHTTP(rec, httptest.NewRequest("GET", "/api/weather", nil)) if rec.Code != http.StatusNoContent { t.Fatalf("ohne Ort erwartet 204, bekam %d", rec.Code) } } func TestMitOrtKommtDasWetter(t *testing.T) { s := newTestServer(t, "") s.wetter = weather.FakeFuerTest(t, 3, 8.6) if err := s.store.SetSettings(store.LocalSub, map[string]string{ "weatherCity": "Köln", "weatherLat": "50.938", "weatherLon": "6.96", }); err != nil { t.Fatal(err) } rec := httptest.NewRecorder() s.routes().ServeHTTP(rec, httptest.NewRequest("GET", "/api/weather", nil)) if rec.Code != http.StatusOK { t.Fatalf("erwartet 200, bekam %d: %s", rec.Code, rec.Body) } var w weather.Wetter json.Unmarshal(rec.Body.Bytes(), &w) if w.Ort != "Köln" || w.Glyph != "wolke" { t.Fatalf("falsches Wetter: %+v", w) } } // Ist ein Ort eingestellt und der Dienst fällt aus, ist das etwas anderes als // „nichts eingestellt": Es gibt etwas zu zeigen, es kommt nur gerade nicht. Die // Oberfläche unterscheidet das — 204 verschwindet still, 502 sagt „nicht // erreichbar". Beides als 204 zu melden hiess: Ein Ausfall sah aus wie ein // abgeschaltetes Widget. func TestAusfallIstNichtDasselbeWieNichts(t *testing.T) { s := newTestServer(t, "") s.wetter = weather.KaputtFuerTest(t) if err := s.store.SetSettings(store.LocalSub, map[string]string{ "weatherCity": "Köln", "weatherLat": "50.938", "weatherLon": "6.96", }); err != nil { t.Fatal(err) } rec := httptest.NewRecorder() s.routes().ServeHTTP(rec, httptest.NewRequest("GET", "/api/weather", nil)) if rec.Code != http.StatusBadGateway { t.Fatalf("bei Ausfall erwartet 502, bekam %d", rec.Code) } } // Der Streifen in der Leiste heisst .apps und blendet seine rechten 18 Pixel // mit einer Maske aus. Bekommt ein zweites Element dieselbe Klasse, erbt es die // Maske — die Schublade sah rechts aus, als loese sie sich auf, und in der // Geometrie war nichts zu sehen. Deshalb hier festgenagelt. func TestNurDerStreifenHeisstApps(t *testing.T) { b, err := os.ReadFile("web/honeybar/honeybar.js") if err != nil { t.Fatal(err) } src := string(b) for _, verboten := range []string{`class="menu apps"`, `class="apps menu"`} { if strings.Contains(src, verboten) { t.Errorf("%s: Das Menue erbt damit die Ausblendmaske des App-Streifens", verboten) } } // Genau ein Element darf die Klasse tragen: der Streifen selbst. if n := strings.Count(src, `class="apps"`); n != 1 { t.Errorf(`class="apps" kommt %dx vor, erwartet genau einmal (der Streifen)`, n) } } // Die HoneyBar bringt ihr CSS und ihr Markup in Vorlagenzeichenketten mit. // Ein Backtick in einem Kommentar beendet die Zeichenkette mittendrin — die // Datei ist dann kaputt, und zwar nur in der HoneyBar, nicht auf dem // Schreibtisch. Genau das ist zweimal passiert; deshalb dieser Wächter. func TestHoneyBarOhneBacktickInKommentaren(t *testing.T) { b, err := os.ReadFile("web/honeybar/honeybar.js") if err != nil { t.Fatal(err) } src := string(b) imBlock := false for nr, zeile := range strings.Split(src, "\n") { rest := zeile for { if imBlock { ende := strings.Index(rest, "*/") if ende < 0 { if strings.Contains(rest, "`") { t.Errorf("Zeile %d: Backtick in einem Kommentar — das beendet die Vorlagenzeichenkette:\n %s", nr+1, strings.TrimSpace(zeile)) } break } if strings.Contains(rest[:ende], "`") { t.Errorf("Zeile %d: Backtick in einem Kommentar — das beendet die Vorlagenzeichenkette:\n %s", nr+1, strings.TrimSpace(zeile)) } rest = rest[ende+2:] imBlock = false continue } start := strings.Index(rest, "/*") if start < 0 { break } rest = rest[start+2:] imBlock = true } } }