Skip to content

Commit

Permalink
more tests, add validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Bretterklieber committed May 25, 2024
1 parent d39823f commit ccfb2eb
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 99 deletions.
1 change: 0 additions & 1 deletion api/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
// @Produce json
// @Tags location
// @Success 200
// @Failure 404 {object} http.ErrorResponse
// @Router /location [get]
// @Param modem query string false "Modem-Id"
func (a *Api) LocationGet(w http.ResponseWriter, r *http.Request) {
Expand Down
1 change: 0 additions & 1 deletion api/modem.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ func (a *Api) ModemList(w http.ResponseWriter, r *http.Request) {
// @Produce json
// @Tags modem
// @Success 200
// @Failure 404 {object} http.ErrorResponse
// @Router /modem/{id} [get]
// @Param id path string true "Modem-Id"
func (a *Api) ModemDetail(w http.ResponseWriter, r *http.Request) {
Expand Down
15 changes: 11 additions & 4 deletions api/sms.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"encoding/json"
"fmt"
"github.com/go-chi/chi/v5"
"github.com/go-playground/validator/v10"
utils "github.com/mbretter/go-mmcli-svr/http"
"net/http"
"strings"
)

type SmsRequestData struct {
Number string `json:"number" example:"+431234567890"`
Text string `json:"text" example:"Ping"`
Number string `json:"number" example:"+431234567890" validate:"required,e164"`
Text string `json:"text" example:"Ping" validate:"required,max=160"`
}

// SmsCreated {"modem":{"messaging":{"created-sms":"/org/freedesktop/ModemManager1/SMS/0"}}}
Expand All @@ -30,7 +31,6 @@ type SmsCreated struct {
// @Produce json
// @Tags sms
// @Success 200
// @Failure 404 {object} http.ErrorResponse
// @Router /sms/ [get]
// @Router /sms/{id} [get]
// @Param id path string true "SMS-Id"
Expand Down Expand Up @@ -79,6 +79,13 @@ func (a *Api) SmsSend(w http.ResponseWriter, r *http.Request) {
return
}

validate := validator.New()
err = validate.Struct(requestData)
if err != nil {
utils.WriteError(w, r, http.StatusBadRequest, err)
return
}

smsStr := fmt.Sprintf("number='%s',text='%s'", requestData.Number, requestData.Text)
jsonBuf, err := a.backend.ExecModem(modem, "--messaging-create-sms="+smsStr)
if err != nil {
Expand All @@ -89,7 +96,7 @@ func (a *Api) SmsSend(w http.ResponseWriter, r *http.Request) {
var smsCreated SmsCreated
err = json.NewDecoder(bytes.NewReader(jsonBuf)).Decode(&smsCreated)
if err != nil {
utils.WriteError(w, r, http.StatusBadRequest, err)
utils.WriteError(w, r, http.StatusInternalServerError, err)
return
}

Expand Down
123 changes: 120 additions & 3 deletions api/sms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,45 @@ func TestSmsSend(t *testing.T) {
{
"Success",
"",
`{"number":"+436643544125","text":"Ping"}`,
`{"number":"+436641234567","text":"Ping"}`,
http.StatusOK,
`{"message":"successfully sent the SMS"}`,
},
{
"Invalid json",
"",
`{"foo":"+`,
http.StatusBadRequest,
`{"error":"unexpected EOF"}`,
},
{
"Invalid request data",
"",
`{"foo":"+436641234567","xxx":"Ping"}`,
http.StatusBadRequest,
`{"error":"Key: 'SmsRequestData.Number' Error:Field validation for 'Number' failed on the 'required' tag\nKey: 'SmsRequestData.Text' Error:Field validation for 'Text' failed on the 'required' tag"}`,
},
{
"Create SMS failed",
"",
`{"number":"+436641234567","text":"Ping"}`,
http.StatusInternalServerError,
`{"error":"internal server error"}`,
},
{
"Create SMS invalid json",
"",
`{"number":"+436641234567","text":"Ping"}`,
http.StatusInternalServerError,
`{"error":"internal server error"}`,
},
{
"Send SMS failed",
"",
`{"number":"+436641234567","text":"Ping"}`,
http.StatusInternalServerError,
`{"error":"internal server error"}`,
},
}

for _, tt := range tests {
Expand All @@ -173,8 +208,18 @@ func TestSmsSend(t *testing.T) {
r := newRequest(tt.requestBody, tt.modemId, logger)
w := httptest.NewRecorder()

backendMock.EXPECT().ExecModem(tt.modemId, "--messaging-create-sms=number='+436643544125',text='Ping'").Return([]byte(`{"modem":{"messaging":{"created-sms":"/org/freedesktop/ModemManager1/SMS/0"}}}`), nil)
backendMock.EXPECT().Exec("-s", "/org/freedesktop/ModemManager1/SMS/0", "--send").Return([]byte(`successfully sent the SMS`), nil)
if tt.name == "Success" {
backendMock.EXPECT().ExecModem(tt.modemId, "--messaging-create-sms=number='+436641234567',text='Ping'").Return([]byte(`{"modem":{"messaging":{"created-sms":"/org/freedesktop/ModemManager1/SMS/0"}}}`), nil)
backendMock.EXPECT().Exec("-s", "/org/freedesktop/ModemManager1/SMS/0", "--send").Return([]byte(`successfully sent the SMS`), nil)
} else if tt.name == "Create SMS failed" {
backendMock.EXPECT().ExecModem(tt.modemId, "--messaging-create-sms=number='+436641234567',text='Ping'").Return([]byte(`create SMS failed`), errors.New("failed"))
} else if tt.name == "Create SMS invalid json" {
backendMock.EXPECT().ExecModem(tt.modemId, "--messaging-create-sms=number='+436641234567',text='Ping'").Return([]byte(`{"m`), nil)
} else if tt.name == "Send SMS failed" {
backendMock.EXPECT().ExecModem(tt.modemId, "--messaging-create-sms=number='+436641234567',text='Ping'").Return([]byte(`{"modem":{"messaging":{"created-sms":"/org/freedesktop/ModemManager1/SMS/0"}}}`), nil)
backendMock.EXPECT().Exec("-s", "/org/freedesktop/ModemManager1/SMS/0", "--send").Return([]byte(`failed`), errors.New("failed"))
}

api.SmsSend(w, r)
resp := w.Result()
body, _ := io.ReadAll(resp.Body)
Expand All @@ -184,3 +229,75 @@ func TestSmsSend(t *testing.T) {
})
}
}

func TestSmsDelete(t *testing.T) {
newRequest := func(smsId string, modemId string, logger *slog.Logger) *http.Request {
r := httptest.NewRequest("DELETE", "http://127.0.0.1:8743/sms/", nil)

ctx := context.WithValue(r.Context(), "logger", logger)
ctx = context.WithValue(ctx, "modem", modemId)

if len(smsId) > 0 {
routeContext := chi.NewRouteContext()
routeContext.URLParams.Add("id", smsId)
ctx = context.WithValue(ctx, chi.RouteCtxKey, routeContext)
}

return r.WithContext(ctx)
}

tests := []struct {
name string
modemId string
smsId string
expectedStatusCode int
expectedBody string
}{
{
"Success",
"1",
"/org/freedesktop/ModemManager1/SMS/0",
http.StatusOK,
`{"message":"successfully deleted SMS from modem"}`,
},
{
"Invalid SMS id",
"",
"&#'",
http.StatusBadRequest,
`{"error":"invalid ID"}`,
},
{
"Delete failed",
"",
"12",
http.StatusInternalServerError,
`{"error":"internal server error"}`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
api, backendMock := ProvideTestApi(t)

var buff bytes.Buffer
logger := slog.New(slog.NewTextHandler(&buff, nil))

r := newRequest(tt.smsId, tt.modemId, logger)
w := httptest.NewRecorder()

if tt.name == "Success" {
backendMock.EXPECT().ExecModem(tt.modemId, "--messaging-delete-sms="+tt.smsId).Return([]byte("successfully deleted SMS from modem"), nil)
} else if tt.name == "Delete failed" {
backendMock.EXPECT().ExecModem(tt.modemId, "--messaging-delete-sms="+tt.smsId).Return([]byte("failed"), errors.New("failed"))
}

api.SmsDelete(w, r)
resp := w.Result()
body, _ := io.ReadAll(resp.Body)

assert.Equal(t, tt.expectedStatusCode, resp.StatusCode)
assert.Equal(t, tt.expectedBody, strings.Trim(string(body), " \n"))
})
}
}
38 changes: 5 additions & 33 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ const docTemplate = `{
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
}
Expand Down Expand Up @@ -94,12 +88,6 @@ const docTemplate = `{
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
}
Expand Down Expand Up @@ -190,12 +178,6 @@ const docTemplate = `{
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
}
Expand Down Expand Up @@ -230,12 +212,6 @@ const docTemplate = `{
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
},
Expand Down Expand Up @@ -270,25 +246,21 @@ const docTemplate = `{
"definitions": {
"api.SmsRequestData": {
"type": "object",
"required": [
"number",
"text"
],
"properties": {
"number": {
"type": "string",
"example": "+431234567890"
},
"text": {
"type": "string",
"maxLength": 160,
"example": "Ping"
}
}
},
"http.ErrorResponse": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "an error occurred"
}
}
}
},
"securityDefinitions": {
Expand Down
38 changes: 5 additions & 33 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
}
Expand Down Expand Up @@ -87,12 +81,6 @@
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
}
Expand Down Expand Up @@ -183,12 +171,6 @@
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
}
Expand Down Expand Up @@ -223,12 +205,6 @@
"responses": {
"200": {
"description": "OK"
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/http.ErrorResponse"
}
}
}
},
Expand Down Expand Up @@ -263,25 +239,21 @@
"definitions": {
"api.SmsRequestData": {
"type": "object",
"required": [
"number",
"text"
],
"properties": {
"number": {
"type": "string",
"example": "+431234567890"
},
"text": {
"type": "string",
"maxLength": 160,
"example": "Ping"
}
}
},
"http.ErrorResponse": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "an error occurred"
}
}
}
},
"securityDefinitions": {
Expand Down
Loading

0 comments on commit ccfb2eb

Please sign in to comment.