package furcadia import ( "errors" "strings" "testing" ) func TestAddFurre(t *testing.T) { testNames := []string{ "Artex", "Albert Quirky", "A|B|C", "#SA", } pounce := NewPounceList() // Success Scenarios ////////////////////////////////////////////////////////////////////////// for _, name := range testNames { // check AddFurre() success furre, err := pounce.AddFurre(name) if err != nil { t.Errorf("AddFurre(%v) failed: %v", name, err) } // check display name if furre.DisplayName != name { t.Errorf("AddFurre(%v).DisplayName == %v (mismatch)", name, furre.DisplayName) } // check shortname expShort := GetShortName(name) furreShort := furre.GetShortName() if furreShort != expShort { t.Errorf("AddFurre(%v).GetShortName() -> %v (expected: %v)", name, furreShort, expShort) } } if len(pounce.Furres) != len(testNames) { t.Errorf("Length inconsistency: len(pounce.Furres)=%v, len(testNames)=%v", len(pounce.Furres), len(testNames)) } // Bad Scenarios ////////////////////////////////////////////////////////////////////////////// // already on record furre, err := pounce.AddFurre("||ARTEX||") if err == nil { t.Errorf("AddFurre(||ARTEX||) unexpectedly succeeded: %v", furre) } // already on record furre, err = pounce.AddFurre("albertquirky") if err == nil { t.Errorf("AddFurre(albertquirky) unexpectedly succeeded: %v", furre) } } func TestDeleteFurre(t *testing.T) { testNames := []string{ "Artex", "Albert Quirky", "A|B|C", "#SA", } // create a pounce list and populate it with names pounce := NewPounceList() for _, name := range testNames { pounce.AddFurre(name) } // delete using a different display name - should work err := pounce.DeleteFurre("ALBERT|QUIRKY") if err != nil { t.Errorf("DeleteFurre(ALBERT|QUIRKY) failed: %v", err) } if len(pounce.Furres) != len(testNames)-1 { t.Errorf("DeleteFurre(ALBERT|QUIRKY) caused invalid furre count: %v (testNames: %v)", len(pounce.Furres), len(testNames)) } // delete for the second time - expect ErrNotFound err = pounce.DeleteFurre("Albert Quirky") if !errors.Is(err, ErrNotFound) { t.Errorf("DeleteFurre(Albert Quirky) for a missing record produced: %v (expected ErrNotFound)", err) } // delete everyone for _, name := range testNames { pounce.DeleteFurre(name) } if len(pounce.Furres) != 0 { t.Errorf("Mass-delete did not empty furre list: %v", pounce.Furres) } } func TestAddDream(t *testing.T) { pounce := NewPounceList() dream, err := pounce.AddDream("Ice Dragon", "Some dream name") if err != nil { t.Errorf("AddDream() failed: %v", err) } // test basic output if dream.Title != "Ice Dragon: Some dream name" { t.Errorf("AddDream(): unexpected title '%v'", dream.Title) } if dream.ShortURL != "icedragon:somedreamname" { t.Errorf("AddDream(): unexpected short url '%v'", dream.ShortURL) } if dream.LastState != StateUnknown { t.Errorf("AddDream(): unexpected initial state '%v'", dream.LastState) } if dream.LastState.IsOnline() { t.Errorf("AddDream(): dream is with unknown state is initially online") } if dream.GetDreamURL() != "furc://icedragon:somedreamname/" { t.Errorf("AddDream(): unexpected URL from GetDreamURL(): '%v'", dream.GetDreamURL()) } // try to add this dream again; make sure it fails d, err := pounce.AddDream("icedragon", "some_dream_name") if !errors.Is(err, ErrExists) { t.Errorf("AddDream(): duplicate add did not produce ErrExists, but %T(%v)", err, err) } if d != dream { t.Errorf("AddDream(): expected existing dream, but got %T(%v)", d, d) } // try to add an analogous dream via dreamurl; make sure it also fails d, err = pounce.AddDreamURL(dream.GetDreamURL()) if !errors.Is(err, ErrExists) { t.Errorf("AddDreamURL(): analogous duplicate add did not produce ErrExists, but %T(%v)", err, err) } if d != dream { t.Errorf("AddDreamURL(): expected existing dream, but got %T(%v)", d, d) } } func TestAddDreamURL(t *testing.T) { const longURL = "furc://a_r_t_e_x:some_dream_name" const normalURL = "furc://artex:somedreamname/" const shortURL = "artex:somedreamname" pounce := NewPounceList() dream, err := pounce.AddDreamURL(longURL) if err != nil { t.Errorf("AddDreamURL() failed: %v", err) } // test basic output if dream.Title != longURL { t.Errorf("AddDreamURL(): unexpected title '%v' (expected '%v')", dream.Title, longURL) } if dream.ShortURL != shortURL { t.Errorf("AddDreamURL(): unexpected dream short url '%v' (expected '%v')", dream.ShortURL, shortURL) } if dream.LastState != StateUnknown { t.Errorf("AddDream(): unexpected initial state '%v'", dream.LastState) } if dream.LastState.IsOnline() { t.Errorf("AddDream(): dream is with unknown state is initially online") } if dream.GetDreamURL() != normalURL { t.Errorf("AddDream(): unexpected URL from GetDreamURL(): '%v' (expected: '%v')", dream.GetDreamURL(), normalURL) } // try to add this dream again; make sure it fails testDup := func(url string) { d, err := pounce.AddDreamURL(url) if !errors.Is(err, ErrExists) { t.Errorf("AddDreamURL(): duplicate add for '%v' did not produce ErrExists, but %T(%v)", url, err, err) } // in case of ErrExists, d is the existing dream object if d != dream { t.Errorf("AddDreamURL(): expected existing dream for '%v', but got %+v", url, d) } } testDup(longURL) testDup(normalURL) // try to add analogous dream via AddDream(); make sure it also fails d, err := pounce.AddDream("Artex", "Some Dream Name") if !errors.Is(err, ErrExists) { t.Errorf("AddDream(): duplicate analogous add did not produce ErrExists, but %T(%v)", err, err) } if d != dream { // in case of ErrExists, d is the existing dream object t.Errorf("AddDream(): expected existing dream, but got %+v", d) } } func TestDeleteDream(t *testing.T) { const uploader = "Ice Dragon" const dreamName = "Some dream name" pounce := NewPounceList() // try deleting a non-existant dream err := pounce.DeleteDream(uploader, dreamName) if !errors.Is(err, ErrNotFound) { t.Errorf("DeleteDream(): expected ErrNotFound for non-existent dream, but got %T(%v)", err, err) } // add the dream _, err = pounce.AddDream(uploader, dreamName) if err != nil { t.Errorf("AddDream() failed: %v", err) } // delete should succeed now err = pounce.DeleteDream(uploader, dreamName) if err != nil { t.Errorf("DeleteDream() unexpectedly failed with %T(%v)", err, err) } // dream is no longer available again err = pounce.DeleteDream(uploader, dreamName) if !errors.Is(err, ErrNotFound) { t.Errorf("DeleteDream(): expected ErrNotFound for deleted dream, but got %T(%v)", err, err) } } func TestDeleteDreamURL(t *testing.T) { const dreamURL = "furc://icedragon:somedreamname" pounce := NewPounceList() // try deleting a non-existant dream err := pounce.DeleteDreamURL(dreamURL) if !errors.Is(err, ErrNotFound) { t.Errorf("DeleteDreamURL(): expected ErrNotFound for non-existent dream, but got %T(%v)", err, err) } // add the dream _, err = pounce.AddDreamURL(dreamURL) if err != nil { t.Errorf("AddDreamURL() failed: %v", err) } // delete should succeed now err = pounce.DeleteDreamURL(dreamURL) if err != nil { t.Errorf("DeleteDreamURL() unexpectedly failed with %T(%v)", err, err) } // dream is no longer available again err = pounce.DeleteDreamURL(dreamURL) if !errors.Is(err, ErrNotFound) { t.Errorf("DeleteDreamURL(): expected ErrNotFound for deleted dream, but got %T(%v)", err, err) } } func TestGetQueryString(t *testing.T) { pounce := NewPounceList() pounce.AddFurre("Artex") pounce.AddFurre("Albert Quirky") pounce.AddFurre("|Test|Alt|666#SA") pounce.AddDream("Allegria", "") pounce.AddDream("FurN", "") pounce.AddDream("Bramblebrook", "Welcome") pounce.AddDreamURL("furc://artex") pounce.AddDreamURL("furc://artex:somename/") query := pounce.GetQueryString() + "&" expectedSubs := []string{ "u[]=artex&", "u[]=albertquirky&", "u[]=testalt666sa&", "d[]=allegria&", "d[]=furn&", "d[]=bramblebrook:welcome&", "d[]=artex&", "d[]=artex:somename&", } unexpectedSubs := []string{ "&&", } nItems := len(strings.Split(query, "&")) if nItems != len(expectedSubs)+1 { t.Errorf("Unexpected number of items (%v) in query: %v", nItems, query) } for _, sub := range expectedSubs { if !strings.Contains(query, sub) { t.Errorf("Missing substring '%v' in query: %v", sub, query) } } for _, sub := range unexpectedSubs { if strings.Contains(query, sub) { t.Errorf("Unexpected substring '%v' in query: %v", sub, query) } } }