package view import ( "context" "encoding/json" "fmt" "io/ioutil" "local/dndex/config" "local/dndex/storage" "local/dndex/storage/entity" "net/http" "net/http/httptest" "os" "strings" "testing" "time" "github.com/google/uuid" ) func TestJSON(t *testing.T) { if len(os.Getenv("INTEGRATION")) == 0 { t.Logf("skipping because $INTEGRATION unset") return } os.Args = os.Args[:1] t.Logf("config: %+v", config.New()) g := storage.NewGraph() ones := fillDB(t, g) want := ones[len(ones)-1] handler := jsonHandler(g) t.Run("404 on /who", func(t *testing.T) { r := httptest.NewRequest("GET", "/who", strings.NewReader(``)) w := httptest.NewRecorder() handler.ServeHTTP(w, r) if w.Code != http.StatusNotFound { t.Error(w.Code) } }) t.Run("404 on /who/", func(t *testing.T) { r := httptest.NewRequest("GET", "/who/", strings.NewReader(``)) w := httptest.NewRecorder() handler.ServeHTTP(w, r) if w.Code != http.StatusNotFound { t.Error(w.Code) } }) req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost:%d/who/col?id=%s&v", config.New().Port, want.Name), strings.NewReader(``)) if err != nil { t.Fatal(err) } w := httptest.NewRecorder() handler.ServeHTTP(w, req) var v interface{} if b, err := ioutil.ReadAll(w.Body); err != nil { t.Fatalf("failed to read all resp body: %v: %s", err, b) } else if err := json.Unmarshal(b, &v); err != nil { t.Fatalf("err unmarshalling response: %v: %s", err, b) } b, err := json.MarshalIndent(v, "", " ") if err != nil { t.Fatal(err) } var gotOnes map[string]entity.One if err := json.Unmarshal(b, &gotOnes); err != nil { t.Fatal(err) } if len(gotOnes) != 1 { t.Fatal("too many results: ", len(gotOnes)) } var o entity.One for _, v := range gotOnes { o = v } for i := range want.Connections { found := false for j := range o.Connections { if want.Connections[i].Name == o.Connections[j].Name { found = true if want.Connections[i].Relationship != o.Connections[j].Relationship { t.Errorf("connection is wrong: want %+v, got %+v", want.Connections[i], o.Connections[j]) } } } if !found { t.Errorf("didn't find connection %+v in %+v", want.Connections[i], o.Connections) } } if o.Image != want.Image { t.Errorf("wrong image: want %q, got %q", want.Image, o.Image) } if o.Text != want.Text { t.Errorf("wrong text: want %q, got %q", want.Text, o.Text) } if o.Title != want.Title { t.Errorf("wrong title: want %q, got %q", want.Title, o.Title) } if o.Type != want.Type { t.Errorf("wrong type: want %q, got %q", want.Type, o.Type) } if o.Name != want.Name { t.Errorf("wrong name: want %q, got %q", want.Name, o.Name) } t.Logf("\n%s\n", b) } func fillDB(t *testing.T, g storage.Graph) []entity.One { ones := make([]entity.One, 5) for i := range ones { ones[i] = randomOne() if i > 0 { ones[i].Connections[ones[i-1].Name] = entity.One{ Name: ones[i-1].Name, Relationship: ":D", } } } for i := range ones { if err := g.Insert(context.TODO(), "col", ones[i]); err != nil { t.Fatal(err) } if results, err := g.List(context.TODO(), "col", ones[i].Name); err != nil { t.Fatal(err) } else if len(results) != 1 { t.Fatal(len(results)) } else if len(results[0].Connections) != len(ones[i].Connections) { t.Fatal(len(results[0].Connections), len(ones[i].Connections)) } else if len(results[0].Connections) > 0 { for k, v := range results[0].Connections { if k == "" || v.Name == "" { t.Fatalf("name is gone: %q:%+v", k, v) } } } } return ones } func randomOne() entity.One { return entity.One{ Name: "name-" + uuid.New().String()[:5], Type: "type-" + uuid.New().String()[:5], Title: "titl-" + uuid.New().String()[:5], Image: "imge-" + uuid.New().String()[:5], Text: "text-" + uuid.New().String()[:5], Modified: time.Now().UnixNano(), Connections: map[string]entity.One{}, } }