Something went wrong. Try again.
My PaaS for hosting multiple elasticsearch clusters in a Kubernetes environment.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323package server_test
import ( "errors" "net/http" "net/http/httptest" "strings" "testing"
"level3.git.onstackit.cloud/LEVEL3/gabriel/src/api" "level3.git.onstackit.cloud/LEVEL3/gabriel/src/search" "level3.git.onstackit.cloud/LEVEL3/gabriel/src/server/mock")
// serviceErr is a *search.ServiceError; writeServiceError keys off this type.func serviceErr(code int, msg string) error { return &search.ServiceError{Code: code, Msg: msg} }
// ── IndexDoc ───────────────────────────────────────────────────────────
func TestIndexDoc_badBody(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodPost, "/v1/search/i/docs", strings.NewReader("x")), "alice") srv.IndexDoc(rec, r, "i")
assertStatus(t, rec, http.StatusBadRequest)}
func TestIndexDoc_emptyText(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(newJSONRequest(t, http.MethodPost, "/v1/search/i/docs", api.DocumentCreateRequest{Text: ""}), "alice") srv.IndexDoc(rec, r, "i")
assertStatus(t, rec, http.StatusBadRequest) if srch.IndexCallCount() != 0 { t.Fatal("search.Index should not be called for empty text") }}
func TestIndexDoc_missingUsername(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := newJSONRequest(t, http.MethodPost, "/v1/search/i/docs", api.DocumentCreateRequest{Text: "hello"}) srv.IndexDoc(rec, r, "i")
assertStatus(t, rec, http.StatusInternalServerError)}
func TestIndexDoc_serviceError(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.IndexReturns(search.IndexedDocument{}, serviceErr(http.StatusNotFound, "not found")) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(newJSONRequest(t, http.MethodPost, "/v1/search/i/docs", api.DocumentCreateRequest{Text: "hello"}), "alice") srv.IndexDoc(rec, r, "i")
assertStatus(t, rec, http.StatusNotFound) assertJSONBody(t, rec, map[string]string{"error": "not found"})}
func TestIndexDoc_genericError(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.IndexReturns(search.IndexedDocument{}, errors.New("boom")) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(newJSONRequest(t, http.MethodPost, "/v1/search/i/docs", api.DocumentCreateRequest{Text: "hello"}), "alice") srv.IndexDoc(rec, r, "i")
// writeServiceError falls through to 500 for non-ServiceError. assertStatus(t, rec, http.StatusInternalServerError) assertJSONBody(t, rec, map[string]string{"error": "internal server error"})}
func TestIndexDoc_success(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.IndexReturns(search.IndexedDocument{ID: "doc-1", Index: "default"}, nil) srv, store := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(newJSONRequest(t, http.MethodPost, "/v1/search/i/docs", api.DocumentCreateRequest{Text: "hello"}), "alice") srv.IndexDoc(rec, r, "i")
assertStatus(t, rec, http.StatusCreated) var got api.DocumentIndexResponse decodeBody(t, rec, &got) if got.DocumentId != "doc-1" || got.Index != "default" { t.Fatalf("got = %+v", got) } _, instanceId, owner, text, index := srch.IndexArgsForCall(0) if instanceId != "i" || owner != "alice" || text != "hello" || index != nil { t.Fatalf("Index args = (%q,%q,%q,%v)", instanceId, owner, text, index) } entries := store.List("i") if len(entries) != 1 || entries[0].Status != api.Success { t.Fatalf("expected Success log, got %+v", entries) }}
func TestIndexDoc_success_withIndex(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.IndexReturns(search.IndexedDocument{ID: "doc-1", Index: "articles"}, nil) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(newJSONRequest(t, http.MethodPost, "/v1/search/i/docs", api.DocumentCreateRequest{Text: "hello", Index: new("articles")}), "alice") srv.IndexDoc(rec, r, "i")
assertStatus(t, rec, http.StatusCreated) _, _, _, _, index := srch.IndexArgsForCall(0) if index == nil || *index != "articles" { t.Fatalf("index = %v, want articles", index) }}
// ── SearchDocs ─────────────────────────────────────────────────────────
func TestSearchDocs_missingUsername(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := httptest.NewRequest(http.MethodGet, "/v1/search/i/docs?q=foo", nil) srv.SearchDocs(rec, r, "i", api.SearchDocsParams{Q: "foo"})
assertStatus(t, rec, http.StatusInternalServerError)}
func TestSearchDocs_serviceError(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.SearchReturns(nil, serviceErr(http.StatusNotFound, "Elasticsearch instance 'i' not found")) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodGet, "/v1/search/i/docs?q=foo", nil), "alice") srv.SearchDocs(rec, r, "i", api.SearchDocsParams{Q: "foo"})
assertStatus(t, rec, http.StatusNotFound) assertJSONBody(t, rec, map[string]string{"error": "Elasticsearch instance 'i' not found"})}
func TestSearchDocs_genericError(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.SearchReturns(nil, errors.New("boom")) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodGet, "/v1/search/i/docs?q=foo", nil), "alice") srv.SearchDocs(rec, r, "i", api.SearchDocsParams{Q: "foo"})
assertStatus(t, rec, http.StatusInternalServerError)}
func TestSearchDocs_success(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} score := 1.5 srch.SearchReturns([]api.Document{ doc("d1", "default", "hello world", &score), doc("d2", "default", "second", nil), }, nil) srv, store := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodGet, "/v1/search/i/docs?q=hello", nil), "alice") srv.SearchDocs(rec, r, "i", api.SearchDocsParams{Q: "hello"})
assertStatus(t, rec, http.StatusOK) var got []api.Document decodeBody(t, rec, &got) if len(got) != 2 || got[0].DocumentId != "d1" || got[0].Score == nil || *got[0].Score != score { t.Fatalf("got = %+v", got) } _, instanceId, owner, params := srch.SearchArgsForCall(0) if instanceId != "i" || owner != "alice" || params.Q != "hello" { t.Fatalf("Search args = (%q,%q,%+v)", instanceId, owner, params) } entries := store.List("i") if len(entries) != 1 || entries[0].Status != api.Success { t.Fatalf("expected Success log, got %+v", entries) }}
// ── DeleteDoc ─────────────────────────────────────────────────────────
func TestDeleteDoc_missingUsername(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := httptest.NewRequest(http.MethodDelete, "/v1/search/i/docs/d1", nil) srv.DeleteDoc(rec, r, "i", "d1", api.DeleteDocParams{Index: "default"})
assertStatus(t, rec, http.StatusInternalServerError)}
func TestDeleteDoc_serviceError_notFound(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.DeleteReturns(serviceErr(http.StatusNotFound, "Document 'd1' not found")) srv, store := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodDelete, "/v1/search/i/docs/d1", nil), "alice") srv.DeleteDoc(rec, r, "i", "d1", api.DeleteDocParams{Index: "default"})
assertStatus(t, rec, http.StatusNotFound) assertJSONBody(t, rec, map[string]string{"error": "Document 'd1' not found"}) entries := store.List("i") if len(entries) != 1 || entries[0].Status != api.Failure { t.Fatalf("expected Failure log, got %+v", entries) }}
func TestDeleteDoc_genericError(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.DeleteReturns(errors.New("boom")) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodDelete, "/v1/search/i/docs/d1", nil), "alice") srv.DeleteDoc(rec, r, "i", "d1", api.DeleteDocParams{Index: "default"})
assertStatus(t, rec, http.StatusInternalServerError)}
func TestDeleteDoc_success(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.DeleteReturns(nil) srv, store := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodDelete, "/v1/search/i/docs/d1", nil), "alice") srv.DeleteDoc(rec, r, "i", "d1", api.DeleteDocParams{Index: "default"})
assertStatus(t, rec, http.StatusNoContent) if rec.Body.Len() != 0 { t.Fatalf("body = %q, want empty", rec.Body.String()) } _, instanceId, owner, docId, params := srch.DeleteArgsForCall(0) if instanceId != "i" || owner != "alice" || docId != "d1" || params.Index != "default" { t.Fatalf("Delete args = (%q,%q,%q,%+v)", instanceId, owner, docId, params) } entries := store.List("i") if len(entries) != 1 || entries[0].Status != api.Success { t.Fatalf("expected Success log, got %+v", entries) }}
// ── ListIndices ───────────────────────────────────────────────────────
func TestListIndices_missingUsername(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := httptest.NewRequest(http.MethodGet, "/v1/search/i/indices", nil) srv.ListIndices(rec, r, "i")
assertStatus(t, rec, http.StatusInternalServerError)}
func TestListIndices_serviceError(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.ListIndicesReturns(nil, serviceErr(http.StatusNotFound, "Elasticsearch instance 'i' not found")) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodGet, "/v1/search/i/indices", nil), "alice") srv.ListIndices(rec, r, "i")
assertStatus(t, rec, http.StatusNotFound)}
func TestListIndices_genericError(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.ListIndicesReturns(nil, errors.New("boom")) srv, _ := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodGet, "/v1/search/i/indices", nil), "alice") srv.ListIndices(rec, r, "i")
assertStatus(t, rec, http.StatusInternalServerError)}
func TestListIndices_success(t *testing.T) { pdb, srch := &mock.FakePagedbService{}, &mock.FakeSearchService{} srch.ListIndicesReturns([]string{"articles", "default"}, nil) srv, store := newTestServer(t, pdb, srch, "")
rec := httptest.NewRecorder() r := simulateSuccessfulLogin(httptest.NewRequest(http.MethodGet, "/v1/search/i/indices", nil), "alice") srv.ListIndices(rec, r, "i")
assertStatus(t, rec, http.StatusOK) var got api.IndexList decodeBody(t, rec, &got) if len(got.Indices) != 2 || got.Indices[0] != "articles" { t.Fatalf("got = %+v", got) } _, instanceId, owner := srch.ListIndicesArgsForCall(0) if instanceId != "i" || owner != "alice" { t.Fatalf("ListIndices args = (%q,%q)", instanceId, owner) } entries := store.List("i") if len(entries) != 1 || entries[0].Status != api.Success { t.Fatalf("expected Success log, got %+v", entries) }}