Skip to content
This repository has been archived by the owner on Sep 12, 2024. It is now read-only.

Commit

Permalink
api: create an endpoint to view all scans by image name
Browse files Browse the repository at this point in the history
  • Loading branch information
nettoclaudio committed Jul 26, 2018
1 parent b0d730d commit 03ab97a
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
19 changes: 19 additions & 0 deletions api/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"encoding/base64"
"fmt"
"net/http"
"net/url"
"strings"

"github.com/globalsign/mgo/bson"
"github.com/labstack/echo"
"github.com/tsuru/cst/db"
schd "github.com/tsuru/cst/scan/scheduler"
)

Expand All @@ -26,6 +28,23 @@ type tsuruEvent struct {
EndCustomData string `json:"endcustomdata"`
}

func showScans(ctx echo.Context) error {

image, err := url.PathUnescape(ctx.Param("image"))

if err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}

scans, err := db.GetStorage().GetScansByImage(image)

if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError)
}

return ctx.JSON(http.StatusOK, scans)
}

func createScan(ctx echo.Context) error {
scanRequest, err := loadScanRequestFromContext(ctx)
if err != nil {
Expand Down
120 changes: 120 additions & 0 deletions api/scan_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package api

import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"

"github.com/labstack/echo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tsuru/cst/db"
"github.com/tsuru/cst/scan"
schd "github.com/tsuru/cst/scan/scheduler"
)
Expand Down Expand Up @@ -166,3 +169,120 @@ func TestCreateScan(t *testing.T) {
require.Equal(t, http.StatusCreated, recorder.Code)
})
}

func TestShowScans(t *testing.T) {

t.Run(`When there are no scans for a given image, should return 200 and an empty slice`, func(t *testing.T) {
storage := &db.MockStorage{
MockGetScansByImage: func(image string) ([]scan.Scan, error) {
return []scan.Scan{}, nil
},
}

db.SetStorage(storage)

e := echo.New()

request := httptest.NewRequest(http.MethodGet, "/", strings.NewReader(``))
recorder := httptest.NewRecorder()

context := e.NewContext(request, recorder)

context.SetPath("/v1/container/scan/:image")
context.SetParamNames("image")
context.SetParamValues(url.PathEscape("tsuru/cst:latest"))

err := showScans(context)

require.NoError(t, err)
e.HTTPErrorHandler(err, context)
assert.Equal(t, http.StatusOK, recorder.Code)

assert.JSONEq(t, `[]`, recorder.Body.String())
})

t.Run(`When image param is bad URL encoded, should return 400 status code`, func(t *testing.T) {
e := echo.New()

request := httptest.NewRequest(http.MethodGet, "/", strings.NewReader(``))
recorder := httptest.NewRecorder()

context := e.NewContext(request, recorder)

context.SetPath("/v1/container/scan/:image")
context.SetParamNames("image")
context.SetParamValues("badUrlEncoded%ss")

err := showScans(context)

require.Error(t, err)
e.HTTPErrorHandler(err, context)
assert.Equal(t, http.StatusBadRequest, recorder.Code)
})

t.Run(`When storage returns any error, should return 500 status code`, func(t *testing.T) {
storage := &db.MockStorage{
MockGetScansByImage: func(image string) ([]scan.Scan, error) {
return []scan.Scan{}, errors.New("just another error on storage")
},
}

db.SetStorage(storage)

e := echo.New()

request := httptest.NewRequest(http.MethodGet, "/", strings.NewReader(``))
recorder := httptest.NewRecorder()

context := e.NewContext(request, recorder)

context.SetPath("/v1/container/scan/:image")
context.SetParamNames("image")
context.SetParamValues(url.PathEscape("tsuru/cst:latest"))

err := showScans(context)

require.Error(t, err)
e.HTTPErrorHandler(err, context)
assert.Equal(t, http.StatusInternalServerError, recorder.Code)
})

t.Run(`When storage correctly returns scans, should return 200 status code and scans on body`, func(t *testing.T) {

expectedScans := []scan.Scan{
scan.Scan{
ID: "1",
Image: "tsuru/cst:latest",
},
}

storage := &db.MockStorage{
MockGetScansByImage: func(image string) ([]scan.Scan, error) {
return expectedScans, nil
},
}

db.SetStorage(storage)

e := echo.New()

request := httptest.NewRequest(http.MethodGet, "/", strings.NewReader(``))
recorder := httptest.NewRecorder()

context := e.NewContext(request, recorder)

context.SetPath("/v1/container/scan/:image")
context.SetParamNames("image")
context.SetParamValues(url.PathEscape("tsuru/cst:latest"))

err := showScans(context)

require.NoError(t, err)
e.HTTPErrorHandler(err, context)
assert.Equal(t, http.StatusOK, recorder.Code)

expectedScansJSON, _ := json.Marshal(expectedScans)

assert.JSONEq(t, string(expectedScansJSON), recorder.Body.String())
})
}
1 change: 1 addition & 0 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func (ws *SecureWebServer) Start() error {

v1 := ws.echo.Group("/v1")
v1.POST("/container/scan", createScan)
v1.GET("/container/scan/:image", showScans)

address := fmt.Sprintf(":%d", ws.Port)

Expand Down

0 comments on commit 03ab97a

Please sign in to comment.