// Copyright 2024 Matthew Rich . All rights reserved. package main import ( _ "fmt" "context" "testing" "net/http" "net/http/httptest" _ "net/url" _ "io" "github.com/stretchr/testify/assert" "encoding/json" _ "encoding/base64" "strings" "tagger/httptest/stream" "github.com/gin-contrib/sse" "tagger/tests/mocks" "tagger/internal/models" "encoding/base64" ) func TestRouter(t *testing.T) { app := NewApp(nil) assert.NotNil(t, app) } func TestPingRoute(t *testing.T) { app := NewApp(nil) w := httptest.NewRecorder() req, _ := http.NewRequest("GET", app.BasePath() + "/ping", nil) app.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) assert.Equal(t, "pong", w.Body.String()) } func TestTagsRoute(t *testing.T) { expected := []string { "search-engine", "evil", "done-that" } var results []string m := &mocks.MockDataConnector { InjectTags: func(context.Context) ([]string) { return expected }, } app := NewApp(m) w := httptest.NewRecorder() req, _ := http.NewRequest("GET", app.BasePath() + "/tags", nil) req.Header.Set("Content-Type", "application/json") app.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) json.NewDecoder(w.Body).Decode(&results) assert.Equal(t, len(expected), len(results)) for i,v := range(results) { assert.Equal(t, expected[i], v) } } func TestTagsStreamRoute(t *testing.T) { expected := []string { "search-engine", "evil", "done-that" } //var results []string m := &mocks.MockDataConnector { InjectTags: func(context.Context) ([]string) { return expected }, } app := NewApp(m) w := stream.NewRecorder() req, _ := http.NewRequest("GET", app.BasePath() + "/tags", nil) req.Header.Set("Content-Type", "text/event-stream") go app.ServeHTTP(w, req) for !w.Flushed {} w.Close() assert.Equal(t, 200, w.Code) events, _ := sse.Decode(w.Body) assert.Equal(t, len(expected), len(events)) for i,v := range(events) { assert.Equal(t, expected[i], v.Data) } } func TestTagRoute(t *testing.T) { expected := []string { "https://www.google.com", "https://www.bing.com" } var result models.Tag m := &mocks.MockDataConnector { InjectQuery: func(context.Context, []string) ([]string, error) { return expected, nil }, } app := NewApp(m) w := httptest.NewRecorder() req, _ := http.NewRequest("GET", app.BasePath() + "/tags/search-engine", nil) app.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) json.NewDecoder(w.Body).Decode(&result) assert.Equal(t, len(expected), len(result.Resources)) assert.Equal(t, expected, result.Resources) } func TestTagStream(t *testing.T) { app := NewApp(nil) w := stream.NewRecorder() req, _ := http.NewRequest("GET", app.BasePath() + "/tags", nil) req.Header.Set("Content-Type", "text/event-stream") go app.ServeHTTP(w, req) w.Close() assert.Equal(t, 200, w.Code) } func TestTagPost(t *testing.T) { expected := []string { "https://www.google.com", "https://www.bing.com", "https://www.yahoo.com" } var result models.Tag m := &mocks.MockDataConnector { InjectQuery: func(context.Context, []string) ([]string, error) { return expected, nil }, } app := NewApp(m) w := httptest.NewRecorder() jsonReader := strings.NewReader(`{ "resource": "https://www.yahoo.com" }`) reqPost, _ := http.NewRequest("PUT", app.BasePath() + "/tags/search-engine", jsonReader) wget := httptest.NewRecorder() reqGet, _ := http.NewRequest("GET", app.BasePath() + "/tags/search-engine", nil) app.ServeHTTP(w, reqPost) assert.Equal(t, 200, w.Code) app.ServeHTTP(wget, reqGet) assert.Equal(t, 200, wget.Code) json.NewDecoder(wget.Body).Decode(&result) assert.Contains(t, result.Resources, "https://www.yahoo.com") } func TestTagUpdate(t *testing.T) { expected := []string { "https://www.google.com", "https://www.bing.com", "https://www.yahoo.com" } var result models.Tag m := &mocks.MockDataConnector { InjectQuery: func(context.Context, []string) ([]string, error) { return expected, nil }, InjectAddTag: func(context.Context, string, string) (error) { return nil }, } app := NewApp(m) w := httptest.NewRecorder() jsonReader := strings.NewReader(`{ "name": "search-engine", "resources": [ "https://www.yahoo.com" ] }`) reqPost, _ := http.NewRequest("POST", app.BasePath() + "/tags", jsonReader) wget := httptest.NewRecorder() reqGet, _ := http.NewRequest("GET", app.BasePath() + "/tags/search-engine", nil) app.ServeHTTP(w, reqPost) assert.Equal(t, 200, w.Code) app.ServeHTTP(wget, reqGet) assert.Equal(t, 200, wget.Code) json.NewDecoder(wget.Body).Decode(&result) assert.Contains(t, result.Resources, "https://www.yahoo.com") } func TestTagAddResource(t *testing.T) { expected := []string { "https://www.google.com", "https://www.bing.com", "https://www.yahoo.com" } var result models.Tag m := &mocks.MockDataConnector { InjectQuery: func(context.Context, []string) ([]string, error) { return expected, nil }, InjectAddTag: func(context.Context, string, string) (error) { return nil }, } app := NewApp(m) w := httptest.NewRecorder() jsonReader := strings.NewReader(`{ "resource": "https://www.yahoo.com" }`) reqPost, _ := http.NewRequest("POST", app.BasePath() + "/tags/search-engine", jsonReader) wget := httptest.NewRecorder() reqGet, _ := http.NewRequest("GET", app.BasePath() + "/tags/search-engine", nil) app.ServeHTTP(w, reqPost) assert.Equal(t, 200, w.Code) app.ServeHTTP(wget, reqGet) assert.Equal(t, 200, wget.Code) json.NewDecoder(wget.Body).Decode(&result) assert.Contains(t, result.Resources, "https://www.yahoo.com") } func TestGetResourceTags(t *testing.T) { m := &mocks.MockDataConnector { InjectTags: func(context.Context) ([]string) { return []string{ "search-engine", "news" } }, InjectResourceHasTag: func(ctx context.Context, res string, tag string) bool { if(tag == "search-engine") { return true } else { return false } }, } app := NewApp(m) w := httptest.NewRecorder() reqGet, _ := http.NewRequest("GET", app.BasePath() + "/resources/" + base64.StdEncoding.EncodeToString([]byte("https://www.yahoo.com")), nil) reqGet.Header.Set("Content-Type", "application/json") app.ServeHTTP(w, reqGet) assert.Equal(t, 200, w.Code) result, e := models.NewResourceFromJson(w.Body) assert.Equal(t, nil, e) assert.Contains(t, result.Tags, "search-engine") }