From 1a4b44333342b6d24b781825db0b3ffbf63b1d37 Mon Sep 17 00:00:00 2001 From: Michael Mraka Date: Fri, 3 Nov 2023 14:58:58 +0100 Subject: [PATCH 1/3] RHINENG-2420: support filtering in /view{/systems/advisories,/advisories/systems} --- docs/v3/openapi.json | 200 ++++++++++++++++++ .../controllers/systems_advisories_view.go | 166 ++++++++++----- 2 files changed, 316 insertions(+), 50 deletions(-) diff --git a/docs/v3/openapi.json b/docs/v3/openapi.json index 1c8966ea3..07a82ef82 100644 --- a/docs/v3/openapi.json +++ b/docs/v3/openapi.json @@ -5462,6 +5462,103 @@ "summary": "View advisory-system pairs for selected systems and installable advisories", "description": "View advisory-system pairs for selected systems and installable advisories", "operationId": "viewAdvisoriesSystems", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Limit for paging, set -1 to return all", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "in": "query", + "description": "Offset for paging", + "schema": { + "type": "integer" + } + }, + { + "name": "tags", + "in": "query", + "description": "Tag filter", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filter[group_name]", + "in": "query", + "description": "Filter systems by inventory groups", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filter[system_profile][sap_system]", + "in": "query", + "description": "Filter only SAP systems", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][sap_sids]", + "in": "query", + "description": "Filter systems by their SAP SIDs", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filter[system_profile][ansible]", + "in": "query", + "description": "Filter systems by ansible", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][ansible][controller_version]", + "in": "query", + "description": "Filter systems by ansible version", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][mssql]", + "in": "query", + "description": "Filter systems by mssql version", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][mssql][version]", + "in": "query", + "description": "Filter systems by mssql version", + "schema": { + "type": "string" + } + } + ], "requestBody": { "description": "Request body", "content": { @@ -5518,6 +5615,103 @@ "summary": "View system-advisory pairs for selected systems and installable advisories", "description": "View system-advisory pairs for selected systems and installable advisories", "operationId": "viewSystemsAdvisories", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "Limit for paging, set -1 to return all", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "in": "query", + "description": "Offset for paging", + "schema": { + "type": "integer" + } + }, + { + "name": "tags", + "in": "query", + "description": "Tag filter", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filter[group_name]", + "in": "query", + "description": "Filter systems by inventory groups", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filter[system_profile][sap_system]", + "in": "query", + "description": "Filter only SAP systems", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][sap_sids]", + "in": "query", + "description": "Filter systems by their SAP SIDs", + "style": "form", + "explode": true, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filter[system_profile][ansible]", + "in": "query", + "description": "Filter systems by ansible", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][ansible][controller_version]", + "in": "query", + "description": "Filter systems by ansible version", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][mssql]", + "in": "query", + "description": "Filter systems by mssql version", + "schema": { + "type": "string" + } + }, + { + "name": "filter[system_profile][mssql][version]", + "in": "query", + "description": "Filter systems by mssql version", + "schema": { + "type": "string" + } + } + ], "requestBody": { "description": "Request body", "content": { @@ -5643,6 +5837,9 @@ } } }, + "links": { + "$ref": "#/components/schemas/controllers.Links" + }, "meta": { "$ref": "#/components/schemas/controllers.ListMeta" } @@ -7209,6 +7406,9 @@ } } }, + "links": { + "$ref": "#/components/schemas/controllers.Links" + }, "meta": { "$ref": "#/components/schemas/controllers.ListMeta" } diff --git a/manager/controllers/systems_advisories_view.go b/manager/controllers/systems_advisories_view.go index a0230cd0a..e8afbe443 100644 --- a/manager/controllers/systems_advisories_view.go +++ b/manager/controllers/systems_advisories_view.go @@ -21,12 +21,14 @@ type SystemsAdvisoriesRequest struct { } type SystemsAdvisoriesResponse struct { - Data map[SystemID][]AdvisoryName `json:"data"` - Meta ListMeta `json:"meta"` + Data map[SystemID][]AdvisoryName `json:"data"` + Links Links `json:"links"` + Meta ListMeta `json:"meta"` } type AdvisoriesSystemsResponse struct { - Data map[AdvisoryName][]SystemID `json:"data"` - Meta ListMeta `json:"meta"` + Data map[AdvisoryName][]SystemID `json:"data"` + Links Links `json:"links"` + Meta ListMeta `json:"meta"` } type systemsAdvisoriesDBLoad struct { @@ -34,7 +36,34 @@ type systemsAdvisoriesDBLoad struct { AdvisoryID AdvisoryName `query:"am.name" gorm:"column:advisory_id"` } +type systemsAdvisoriesViewSubDBLookup struct { + RhAccountID int `query:"sp.rh_account_id" gorm:"column:rh_account_id"` + ID int64 `query:"sp.id" gorm:"column:id"` + SystemID SystemID `query:"sp.inventory_id" gorm:"column:inventory_id"` +} + +type advisoriesSystemsViewSubDBLookup struct { + ID int64 `query:"am.id" gorm:"column:advisory_id"` + AdvisoryID AdvisoryName `query:"am.name" gorm:"column:advisory_name"` +} + var systemsAdvisoriesSelect = database.MustGetSelect(&systemsAdvisoriesDBLoad{}) +var systemsAdvisoriesViewFields = database.MustGetQueryAttrs(&systemsAdvisoriesViewSubDBLookup{}) +var systemsAdvisoriesViewOpts = ListOpts{ + Fields: systemsAdvisoriesViewFields, + DefaultFilters: nil, + DefaultSort: "inventory_id", + StableSort: "inventory_id", + SearchFields: nil, +} +var advisoriesSystemsViewFields = database.MustGetQueryAttrs(&advisoriesSystemsViewSubDBLookup{}) +var advisoriesSystemsViewOpts = ListOpts{ + Fields: advisoriesSystemsViewFields, + DefaultFilters: nil, + DefaultSort: "advisory_id", + StableSort: "am.id", + SearchFields: nil, +} func totalItems(tx *gorm.DB, cols string) (int, error) { var count int64 @@ -42,27 +71,34 @@ func totalItems(tx *gorm.DB, cols string) (int, error) { return int(count), err } -func systemsAdvisoriesQuery(db *gorm.DB, acc int, groups map[string]string, systems []SystemID, - advisories []AdvisoryName, limit, offset *int, apiver int) (*gorm.DB, int, int, int, error) { +func systemsAdvisoriesQuery(c *gin.Context, db *gorm.DB, acc int, groups map[string]string, + req SystemsAdvisoriesRequest, apiver int) (*gorm.DB, *ListMeta, *Links, error) { + systems := req.Systems + advisories := req.Advisories sysq := database.Systems(db, acc, groups). Distinct("sp.rh_account_id, sp.id, sp.inventory_id"). // we need to join system_advisories to make `limit` work properly // without this join it can happen that we display less items on some pages Joins(`LEFT JOIN system_advisories sa ON sa.system_id = sp.id - AND sa.rh_account_id = sp.rh_account_id AND sa.rh_account_id = ?`, acc). - Order("sp.inventory_id") + AND sa.rh_account_id = sp.rh_account_id AND sa.rh_account_id = ?`, acc) if len(systems) > 0 { - sysq = sysq.Where("sp.inventory_id::text in (?)", systems) + sysq = sysq.Where("sp.inventory_id in (?)", systems) } - total, err := totalItems(sysq, "sp.rh_account_id, sp.id, sp.inventory_id") + filters, err := ParseAllFilters(c, systemsAdvisoriesViewOpts) if err != nil { - return nil, 0, 0, 0, err - } + return nil, nil, nil, err + } // Error handled by method itself - lim, off, err := Paginate(sysq, limit, offset) + sysq, _ = ApplyInventoryFilter(filters, sysq, "sp.inventory_id") + sysq, meta, params, err := ListCommon(sysq, c, filters, systemsAdvisoriesViewOpts) + if err != nil { + return nil, nil, nil, err + } // Error handled by method itself + + total, err := totalItems(sysq, "sp.rh_account_id, sp.id, sp.inventory_id") if err != nil { - return nil, total, lim, off, err + return nil, nil, nil, err } installableOnly := "" @@ -82,31 +118,38 @@ func systemsAdvisoriesQuery(db *gorm.DB, acc int, groups map[string]string, syst } query = query.Order("sp.inventory_id, am.id") - return query, total, lim, off, nil + meta, links, err := UpdateMetaLinks(c, meta, total, nil, params...) + return query, meta, links, err } -func advisoriesSystemsQuery(db *gorm.DB, acc int, groups map[string]string, systems []SystemID, - advisories []AdvisoryName, limit, offset *int, apiver int) (*gorm.DB, int, int, int, error) { +func advisoriesSystemsQuery(c *gin.Context, db *gorm.DB, acc int, groups map[string]string, + req SystemsAdvisoriesRequest, apiver int) (*gorm.DB, *ListMeta, *Links, error) { + systems := req.Systems + advisories := req.Advisories // get all advisories for all systems in the account (with inventory.hosts join) advq := database.Systems(db, acc, groups). Distinct("am.id, am.name"). // we need to join system_advisories to make `limit` work properly // without this join it can happen that we display less items on some pages Joins("JOIN system_advisories sa ON sp.id = sa.system_id AND sa.rh_account_id = ?", acc). - Joins("JOIN advisory_metadata am ON am.id = sa.advisory_id"). - Order("am.name, am.id") + Joins("JOIN advisory_metadata am ON am.id = sa.advisory_id") if len(advisories) > 0 { advq = advq.Where("am.name in (?)", advisories) } - total, err := totalItems(advq, "am.id, am.name") + filters, err := ParseAllFilters(c, advisoriesSystemsViewOpts) if err != nil { - return nil, 0, 0, 0, err - } + return nil, nil, nil, err + } // Error handled by method itself - lim, off, err := Paginate(advq, limit, offset) + advq, meta, params, err := ListCommon(advq, c, filters, advisoriesSystemsViewOpts) + if err != nil { + return nil, nil, nil, err + } // Error handled by method itself + + total, err := totalItems(advq, "am.id, am.name") if err != nil { - return nil, total, lim, off, err + return nil, nil, nil, err } installableOnly := "" @@ -131,49 +174,50 @@ func advisoriesSystemsQuery(db *gorm.DB, acc int, groups map[string]string, syst query = query.Joins(spJoin) } query = query.Order("am.name, sp.inventory_id") - return query, total, lim, off, nil + + meta, links, err := UpdateMetaLinks(c, meta, total, nil, params...) + return query, meta, links, err } -func queryDB(c *gin.Context, endpoint string) ([]systemsAdvisoriesDBLoad, *ListMeta, error) { +func queryDB(c *gin.Context, endpoint string) ([]systemsAdvisoriesDBLoad, *ListMeta, *Links, error) { var req SystemsAdvisoriesRequest var q *gorm.DB var err error - var total int - var limit int - var offset int + var meta *ListMeta + var links *Links if err := c.ShouldBindJSON(&req); err != nil { LogAndRespBadRequest(c, err, fmt.Sprintf("Invalid request body: %s", err.Error())) - return nil, nil, err + return nil, nil, nil, err } acc := c.GetInt(middlewares.KeyAccount) apiver := c.GetInt(middlewares.KeyApiver) groups := c.GetStringMapString(middlewares.KeyInventoryGroups) db := middlewares.DBFromContext(c) + // backward compatibility, put limit/offset from json into querystring + if req.Limit != nil { + c.Request.URL.RawQuery += fmt.Sprintf("&limit=%d", *req.Limit) + } + if req.Offset != nil { + c.Request.URL.RawQuery += fmt.Sprintf("&offset=%d", *req.Offset) + } switch endpoint { case "SystemsAdvisories": - q, total, limit, offset, err = systemsAdvisoriesQuery( - db, acc, groups, req.Systems, req.Advisories, req.Limit, req.Offset, apiver) + q, meta, links, err = systemsAdvisoriesQuery(c, db, acc, groups, req, apiver) case "AdvisoriesSystems": - q, total, limit, offset, err = advisoriesSystemsQuery( - db, acc, groups, req.Systems, req.Advisories, req.Limit, req.Offset, apiver) + q, meta, links, err = advisoriesSystemsQuery(c, db, acc, groups, req, apiver) default: - return nil, nil, fmt.Errorf("unknown endpoint '%s'", endpoint) + return nil, nil, nil, fmt.Errorf("unknown endpoint '%s'", endpoint) } if err != nil { - LogAndRespBadRequest(c, err, err.Error()) - } + return nil, nil, nil, err + } // Error handled by method itself var data []systemsAdvisoriesDBLoad if err := q.Find(&data).Error; err != nil { LogAndRespError(c, err, "Database error") - return nil, nil, err - } - meta := ListMeta{ - Limit: limit, - Offset: offset, - TotalItems: total, + return nil, nil, nil, err } - return data, &meta, nil + return data, meta, links, nil } // @Summary View system-advisory pairs for selected systems and installable advisories @@ -183,19 +227,30 @@ func queryDB(c *gin.Context, endpoint string) ([]systemsAdvisoriesDBLoad, *ListM // @Accept json // @Produce json // @Param body body SystemsAdvisoriesRequest true "Request body" +// @Param limit query int false "Limit for paging, set -1 to return all" +// @Param offset query int false "Offset for paging" +// @Param tags query []string false "Tag filter" +// @Param filter[group_name] query []string false "Filter systems by inventory groups" +// @Param filter[system_profile][sap_system] query string false "Filter only SAP systems" +// @Param filter[system_profile][sap_sids] query []string false "Filter systems by their SAP SIDs" +// @Param filter[system_profile][ansible] query string false "Filter systems by ansible" +// @Param filter[system_profile][ansible][controller_version] query string false "Filter systems by ansible version" +// @Param filter[system_profile][mssql] query string false "Filter systems by mssql version" +// @Param filter[system_profile][mssql][version] query string false "Filter systems by mssql version" // @Success 200 {object} SystemsAdvisoriesResponse // @Failure 400 {object} utils.ErrorResponse // @Failure 500 {object} utils.ErrorResponse // @Router /views/systems/advisories [post] func PostSystemsAdvisories(c *gin.Context) { - data, meta, err := queryDB(c, "SystemsAdvisories") + data, meta, links, err := queryDB(c, "SystemsAdvisories") if err != nil { return } response := SystemsAdvisoriesResponse{ - Data: map[SystemID][]AdvisoryName{}, - Meta: *meta, + Data: map[SystemID][]AdvisoryName{}, + Links: *links, + Meta: *meta, } for _, i := range data { @@ -219,19 +274,30 @@ func PostSystemsAdvisories(c *gin.Context) { // @Accept json // @Produce json // @Param body body SystemsAdvisoriesRequest true "Request body" +// @Param limit query int false "Limit for paging, set -1 to return all" +// @Param offset query int false "Offset for paging" +// @Param tags query []string false "Tag filter" +// @Param filter[group_name] query []string false "Filter systems by inventory groups" +// @Param filter[system_profile][sap_system] query string false "Filter only SAP systems" +// @Param filter[system_profile][sap_sids] query []string false "Filter systems by their SAP SIDs" +// @Param filter[system_profile][ansible] query string false "Filter systems by ansible" +// @Param filter[system_profile][ansible][controller_version] query string false "Filter systems by ansible version" +// @Param filter[system_profile][mssql] query string false "Filter systems by mssql version" +// @Param filter[system_profile][mssql][version] query string false "Filter systems by mssql version" // @Success 200 {object} AdvisoriesSystemsResponse // @Failure 400 {object} utils.ErrorResponse // @Failure 500 {object} utils.ErrorResponse // @Router /views/advisories/systems [post] func PostAdvisoriesSystems(c *gin.Context) { - data, meta, err := queryDB(c, "AdvisoriesSystems") + data, meta, links, err := queryDB(c, "AdvisoriesSystems") if err != nil { return } response := AdvisoriesSystemsResponse{ - Data: map[AdvisoryName][]SystemID{}, - Meta: *meta, + Data: map[AdvisoryName][]SystemID{}, + Links: *links, + Meta: *meta, } for _, i := range data { From 789c2b2ef54790057887e49a24fa914e88ea4a07 Mon Sep 17 00:00:00 2001 From: Michael Mraka Date: Fri, 3 Nov 2023 15:14:44 +0100 Subject: [PATCH 2/3] RHINENG-2420: return data to check instead of passing checker function --- .../systems_advisories_view_test.go | 90 +++++++++---------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/manager/controllers/systems_advisories_view_test.go b/manager/controllers/systems_advisories_view_test.go index ee5892593..184ac3027 100644 --- a/manager/controllers/systems_advisories_view_test.go +++ b/manager/controllers/systems_advisories_view_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/assert" ) -func doTestView(t *testing.T, handler gin.HandlerFunc, limit, offset *int, checker func(w *httptest.ResponseRecorder)) { +func doTestView(t *testing.T, handler gin.HandlerFunc, limit, offset *int) *httptest.ResponseRecorder { core.SetupTest(t) body := SystemsAdvisoriesRequest{ Systems: []SystemID{"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000002"}, @@ -27,86 +27,78 @@ func doTestView(t *testing.T, handler gin.HandlerFunc, limit, offset *int, check } w := CreateRequestRouterWithParams("POST", "/", bytes.NewBuffer(bodyJSON), "", handler, 1, "POST", "/") - checker(w) + return w } func TestSystemsAdvisoriesView(t *testing.T) { - doTestView(t, PostSystemsAdvisories, nil, nil, func(w *httptest.ResponseRecorder) { - var output SystemsAdvisoriesResponse - CheckResponse(t, w, http.StatusOK, &output) - assert.Equal(t, output.Data["00000000-0000-0000-0000-000000000001"][0], AdvisoryName("RH-1")) - assert.Equal(t, output.Data["00000000-0000-0000-0000-000000000001"][1], AdvisoryName("RH-3")) - assert.Equal(t, 0, len(output.Data["00000000-0000-0000-0000-000000000002"])) - }) + w := doTestView(t, PostSystemsAdvisories, nil, nil) + var output SystemsAdvisoriesResponse + CheckResponse(t, w, http.StatusOK, &output) + assert.Equal(t, output.Data["00000000-0000-0000-0000-000000000001"][0], AdvisoryName("RH-1")) + assert.Equal(t, output.Data["00000000-0000-0000-0000-000000000001"][1], AdvisoryName("RH-3")) + assert.Equal(t, 0, len(output.Data["00000000-0000-0000-0000-000000000002"])) } func TestAdvisoriesSystemsView(t *testing.T) { - doTestView(t, PostAdvisoriesSystems, nil, nil, func(w *httptest.ResponseRecorder) { - var output AdvisoriesSystemsResponse - CheckResponse(t, w, http.StatusOK, &output) - assert.Equal(t, output.Data["RH-1"][0], SystemID("00000000-0000-0000-0000-000000000001")) - assert.Equal(t, output.Data["RH-3"][0], SystemID("00000000-0000-0000-0000-000000000001")) - }) + w := doTestView(t, PostAdvisoriesSystems, nil, nil) + var output AdvisoriesSystemsResponse + CheckResponse(t, w, http.StatusOK, &output) + assert.Equal(t, output.Data["RH-1"][0], SystemID("00000000-0000-0000-0000-000000000001")) + assert.Equal(t, output.Data["RH-3"][0], SystemID("00000000-0000-0000-0000-000000000001")) } func TestSystemAdvisoriesViewOffsetLimit(t *testing.T) { limit := 3 offset := 0 - doTestView(t, PostSystemsAdvisories, &limit, &offset, func(w *httptest.ResponseRecorder) { - var output SystemsAdvisoriesResponse - CheckResponse(t, w, http.StatusOK, &output) - assert.Equal(t, 2, len(output.Data)) - _, has := output.Data["00000000-0000-0000-0000-000000000001"] - assert.True(t, has) - }) + w := doTestView(t, PostSystemsAdvisories, &limit, &offset) + var output SystemsAdvisoriesResponse + CheckResponse(t, w, http.StatusOK, &output) + assert.Equal(t, 2, len(output.Data)) + _, has := output.Data["00000000-0000-0000-0000-000000000001"] + assert.True(t, has) } func TestSystemAdvisoriesViewOffsetOverflow(t *testing.T) { limit := 1 offset := 100 - doTestView(t, PostSystemsAdvisories, &limit, &offset, func(w *httptest.ResponseRecorder) { - var errResp utils.ErrorResponse - CheckResponse(t, w, http.StatusBadRequest, &errResp) - assert.Equal(t, InvalidOffsetMsg, errResp.Error) - }) + w := doTestView(t, PostSystemsAdvisories, &limit, &offset) + var errResp utils.ErrorResponse + CheckResponse(t, w, http.StatusBadRequest, &errResp) + assert.Equal(t, InvalidOffsetMsg, errResp.Error) } func TestSystemAdvisoriesViewWrongOffset(t *testing.T) { offset := 1000 - doTestView(t, PostSystemsAdvisories, nil, &offset, func(w *httptest.ResponseRecorder) { - var errResp utils.ErrorResponse - CheckResponse(t, w, http.StatusBadRequest, &errResp) - assert.Equal(t, InvalidOffsetMsg, errResp.Error) - }) + w := doTestView(t, PostSystemsAdvisories, nil, &offset) + var errResp utils.ErrorResponse + CheckResponse(t, w, http.StatusBadRequest, &errResp) + assert.Equal(t, InvalidOffsetMsg, errResp.Error) } func TestAvisorySystemsViewOffsetLimit(t *testing.T) { limit := 3 offset := 0 - doTestView(t, PostAdvisoriesSystems, &limit, &offset, func(w *httptest.ResponseRecorder) { - var output AdvisoriesSystemsResponse - CheckResponse(t, w, http.StatusOK, &output) - assert.Equal(t, 2, len(output.Data)) - _, has := output.Data["RH-1"] - assert.True(t, has) - }) + w := doTestView(t, PostAdvisoriesSystems, &limit, &offset) + var output AdvisoriesSystemsResponse + CheckResponse(t, w, http.StatusOK, &output) + assert.Equal(t, 2, len(output.Data)) + _, has := output.Data["RH-1"] + assert.True(t, has) } func TestAvisorySystemsViewOffsetOverflow(t *testing.T) { limit := 1 offset := 100 - doTestView(t, PostAdvisoriesSystems, &limit, &offset, func(w *httptest.ResponseRecorder) { - var errResp utils.ErrorResponse - CheckResponse(t, w, http.StatusBadRequest, &errResp) - assert.Equal(t, InvalidOffsetMsg, errResp.Error) - }) + w := doTestView(t, PostAdvisoriesSystems, &limit, &offset) + var errResp utils.ErrorResponse + CheckResponse(t, w, http.StatusBadRequest, &errResp) + assert.Equal(t, InvalidOffsetMsg, errResp.Error) } func TestAvisorySystemsViewWrongOffset(t *testing.T) { offset := 1000 - doTestView(t, PostAdvisoriesSystems, nil, &offset, func(w *httptest.ResponseRecorder) { - var errResp utils.ErrorResponse - CheckResponse(t, w, http.StatusBadRequest, &errResp) - assert.Equal(t, InvalidOffsetMsg, errResp.Error) - }) + w := doTestView(t, PostAdvisoriesSystems, nil, &offset) + var errResp utils.ErrorResponse + CheckResponse(t, w, http.StatusBadRequest, &errResp) + assert.Equal(t, InvalidOffsetMsg, errResp.Error) } From c21d328e87c38e9ce821dbf57cfd43c3f4006e24 Mon Sep 17 00:00:00 2001 From: Michael Mraka Date: Mon, 6 Nov 2023 11:44:51 +0100 Subject: [PATCH 3/3] RHINENG-2420: add tests for filters in /view{/systems/advisories,/advisories/systems} --- .../systems_advisories_view_test.go | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/manager/controllers/systems_advisories_view_test.go b/manager/controllers/systems_advisories_view_test.go index 184ac3027..3683b85ec 100644 --- a/manager/controllers/systems_advisories_view_test.go +++ b/manager/controllers/systems_advisories_view_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/assert" ) -func doTestView(t *testing.T, handler gin.HandlerFunc, limit, offset *int) *httptest.ResponseRecorder { +func doTestView(t *testing.T, handler gin.HandlerFunc, url string, limit, offset *int) *httptest.ResponseRecorder { core.SetupTest(t) body := SystemsAdvisoriesRequest{ Systems: []SystemID{"00000000-0000-0000-0000-000000000001", "00000000-0000-0000-0000-000000000002"}, @@ -26,12 +26,12 @@ func doTestView(t *testing.T, handler gin.HandlerFunc, limit, offset *int) *http panic(err) } - w := CreateRequestRouterWithParams("POST", "/", bytes.NewBuffer(bodyJSON), "", handler, 1, "POST", "/") + w := CreateRequestRouterWithParams("POST", url, bytes.NewBuffer(bodyJSON), "", handler, 1, "POST", "/") return w } func TestSystemsAdvisoriesView(t *testing.T) { - w := doTestView(t, PostSystemsAdvisories, nil, nil) + w := doTestView(t, PostSystemsAdvisories, "/", nil, nil) var output SystemsAdvisoriesResponse CheckResponse(t, w, http.StatusOK, &output) assert.Equal(t, output.Data["00000000-0000-0000-0000-000000000001"][0], AdvisoryName("RH-1")) @@ -40,17 +40,32 @@ func TestSystemsAdvisoriesView(t *testing.T) { } func TestAdvisoriesSystemsView(t *testing.T) { - w := doTestView(t, PostAdvisoriesSystems, nil, nil) + w := doTestView(t, PostAdvisoriesSystems, "/", nil, nil) var output AdvisoriesSystemsResponse CheckResponse(t, w, http.StatusOK, &output) assert.Equal(t, output.Data["RH-1"][0], SystemID("00000000-0000-0000-0000-000000000001")) assert.Equal(t, output.Data["RH-3"][0], SystemID("00000000-0000-0000-0000-000000000001")) } +func TestSystemsAdvisoriesViewTags(t *testing.T) { + w := doTestView(t, PostSystemsAdvisories, "/?filter[system_profile][sap_sids]=DEF", nil, nil) + var output SystemsAdvisoriesResponse + CheckResponse(t, w, http.StatusOK, &output) + assert.Equal(t, output.Data["00000000-0000-0000-0000-000000000001"][0], AdvisoryName("RH-1")) + assert.Equal(t, output.Data["00000000-0000-0000-0000-000000000001"][1], AdvisoryName("RH-3")) +} + +func TestAdvisoriesSystemsViewTags(t *testing.T) { + w := doTestView(t, PostAdvisoriesSystems, "/?filter[system_profile][sap_sids]=DEF", nil, nil) + var output AdvisoriesSystemsResponse + CheckResponse(t, w, http.StatusOK, &output) + assert.Equal(t, output.Data["RH-1"][0], SystemID("00000000-0000-0000-0000-000000000001")) + assert.Equal(t, output.Data["RH-3"][0], SystemID("00000000-0000-0000-0000-000000000001")) +} func TestSystemAdvisoriesViewOffsetLimit(t *testing.T) { limit := 3 offset := 0 - w := doTestView(t, PostSystemsAdvisories, &limit, &offset) + w := doTestView(t, PostSystemsAdvisories, "/", &limit, &offset) var output SystemsAdvisoriesResponse CheckResponse(t, w, http.StatusOK, &output) assert.Equal(t, 2, len(output.Data)) @@ -61,7 +76,7 @@ func TestSystemAdvisoriesViewOffsetLimit(t *testing.T) { func TestSystemAdvisoriesViewOffsetOverflow(t *testing.T) { limit := 1 offset := 100 - w := doTestView(t, PostSystemsAdvisories, &limit, &offset) + w := doTestView(t, PostSystemsAdvisories, "/", &limit, &offset) var errResp utils.ErrorResponse CheckResponse(t, w, http.StatusBadRequest, &errResp) assert.Equal(t, InvalidOffsetMsg, errResp.Error) @@ -69,7 +84,7 @@ func TestSystemAdvisoriesViewOffsetOverflow(t *testing.T) { func TestSystemAdvisoriesViewWrongOffset(t *testing.T) { offset := 1000 - w := doTestView(t, PostSystemsAdvisories, nil, &offset) + w := doTestView(t, PostSystemsAdvisories, "/", nil, &offset) var errResp utils.ErrorResponse CheckResponse(t, w, http.StatusBadRequest, &errResp) assert.Equal(t, InvalidOffsetMsg, errResp.Error) @@ -78,7 +93,7 @@ func TestSystemAdvisoriesViewWrongOffset(t *testing.T) { func TestAvisorySystemsViewOffsetLimit(t *testing.T) { limit := 3 offset := 0 - w := doTestView(t, PostAdvisoriesSystems, &limit, &offset) + w := doTestView(t, PostAdvisoriesSystems, "/", &limit, &offset) var output AdvisoriesSystemsResponse CheckResponse(t, w, http.StatusOK, &output) assert.Equal(t, 2, len(output.Data)) @@ -89,7 +104,7 @@ func TestAvisorySystemsViewOffsetLimit(t *testing.T) { func TestAvisorySystemsViewOffsetOverflow(t *testing.T) { limit := 1 offset := 100 - w := doTestView(t, PostAdvisoriesSystems, &limit, &offset) + w := doTestView(t, PostAdvisoriesSystems, "/", &limit, &offset) var errResp utils.ErrorResponse CheckResponse(t, w, http.StatusBadRequest, &errResp) assert.Equal(t, InvalidOffsetMsg, errResp.Error) @@ -97,7 +112,7 @@ func TestAvisorySystemsViewOffsetOverflow(t *testing.T) { func TestAvisorySystemsViewWrongOffset(t *testing.T) { offset := 1000 - w := doTestView(t, PostAdvisoriesSystems, nil, &offset) + w := doTestView(t, PostAdvisoriesSystems, "/", nil, &offset) var errResp utils.ErrorResponse CheckResponse(t, w, http.StatusBadRequest, &errResp) assert.Equal(t, InvalidOffsetMsg, errResp.Error)