package main import ( "bytes" "fmt" "net/http" "net/http/httptest" "strings" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gzzn.com/mini/ciimsproxy/internal" ) const ( testErrMsg = `Can not find the event [FLOP-ESTT-ATC-ALL1]` testSendOK = `` testReceiveResp = `<?xml version="1.0" encoding="UTF-8"?><MSG><A>1</A></MSG>` ) func testRouter(t *testing.T, handler http.HandlerFunc) *gin.Engine { t.Helper() gin.SetMode(gin.TestMode) ciims := httptest.NewServer(handler) t.Cleanup(ciims.Close) client, err := internal.NewClient(10) require.NoError(t, err) return newRouter(Config{ServerURL: ciims.URL, Listen: ":0", Timeout: 10, Client: client}) } func performJSON(r http.Handler, method, path, body string) *httptest.ResponseRecorder { req := httptest.NewRequest(method, path, strings.NewReader(body)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() r.ServeHTTP(w, req) return w } func TestPing(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) {}) w := performJSON(r, http.MethodGet, "/ping", "") assert.Equal(t, http.StatusOK, w.Code) assert.JSONEq(t, `{"message":"pong"}`, w.Body.String()) } func TestSendSuccess(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, testSendOK) }) w := performJSON(r, http.MethodPost, "/send", `{"user":"FIMS","pass":"x","event":"E1","msg":""}`) assert.Equal(t, http.StatusOK, w.Code) assert.JSONEq(t, `{"error":""}`, w.Body.String()) } func TestSendSOAPFault(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, testErrMsg) }) w := performJSON(r, http.MethodPost, "/send", `{"user":"FIMS","pass":"x","event":"E1","msg":""}`) assert.Equal(t, http.StatusInternalServerError, w.Code) assert.Contains(t, w.Body.String(), "Can not find the event") } func TestSendMissingRequiredField(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) {}) w := performJSON(r, http.MethodPost, "/send", `{"user":"FIMS","pass":"x","msg":""}`) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestSendOversizedBody(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) {}) body := `{"user":"FIMS","pass":"x","event":"E1","msg":"` + strings.Repeat("a", maxMsgLen) + `"}` req := httptest.NewRequest(http.MethodPost, "/send", bytes.NewBufferString(body)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() r.ServeHTTP(w, req) assert.Equal(t, http.StatusRequestEntityTooLarge, w.Code) } func TestReceiveSuccess(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, testReceiveResp) }) w := performJSON(r, http.MethodPost, "/receive", `{"user":"FIMS","pass":"x","count":2}`) assert.Equal(t, http.StatusOK, w.Code) assert.Contains(t, w.Body.String(), "MSG") } func TestReceiveInvalidCount(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) {}) w := performJSON(r, http.MethodPost, "/receive", `{"user":"FIMS","pass":"x","count":0}`) assert.Equal(t, http.StatusBadRequest, w.Code) w = performJSON(r, http.MethodPost, "/receive", `{"user":"FIMS","pass":"x","count":1001}`) assert.Equal(t, http.StatusBadRequest, w.Code) } func TestReceiveSOAPFault(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, testErrMsg) }) w := performJSON(r, http.MethodPost, "/receive", `{"user":"FIMS","pass":"x","count":2}`) assert.Equal(t, http.StatusInternalServerError, w.Code) assert.Contains(t, w.Body.String(), "Can not find the event") } func TestHTTP500WithSOAPFaultReturnsFaultText(t *testing.T) { r := testRouter(t, func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) fmt.Fprint(w, testErrMsg) }) w := performJSON(r, http.MethodPost, "/send", `{"user":"FIMS","pass":"x","event":"E1","msg":""}`) assert.Equal(t, http.StatusInternalServerError, w.Code) assert.Contains(t, w.Body.String(), "Can not find the event") assert.NotContains(t, w.Body.String(), "ciims returned 500") }