Skip to content

Commit

Permalink
more coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
daveshanley committed Sep 30, 2024
1 parent fe30ee6 commit 243ccab
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 5 deletions.
4 changes: 2 additions & 2 deletions parameters/query_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import (

"github.com/pb33f/libopenapi-validator/errors"
"github.com/pb33f/libopenapi-validator/helpers"
"github.com/pb33f/libopenapi-validator/paths"
"github.com/pb33f/libopenapi/datamodel/high/base"
v3 "github.com/pb33f/libopenapi/datamodel/high/v3"
"github.com/pb33f/libopenapi/orderedmap"
"github.com/pb33f/libopenapi-validator/paths"
)

func (v *paramValidator) ValidateQueryParams(request *http.Request) (bool, []*errors.ValidationError) {
Expand Down Expand Up @@ -181,7 +181,7 @@ doneLooking:
// well we're already in an array, so we need to check the items schema
// to ensure this array items matches the type
// only check if items is a schema, not a boolean
if sch.Items.IsA() {
if sch.Items != nil && sch.Items.IsA() {
validationErrors = append(validationErrors,
ValidateQueryArray(sch, params[p], ef, contentWrapped)...)
}
Expand Down
29 changes: 29 additions & 0 deletions parameters/query_parameters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,35 @@ paths:
assert.Equal(t, "Query parameter 'fishy' failed to validate", errors[0].Message)
}

func TestNewValidator_QueryParamMinimum_ignoredviolation(t *testing.T) {
spec := `openapi: 3.1.0
paths:
/a/fishy/on/a/dishy:
get:
parameters:
- name: fishy
in: query
required: true
schema:
type: object
operationId: locateFishy
`

doc, err := libopenapi.NewDocument([]byte(spec))
require.NoError(t, err)
m, errs := doc.BuildV3Model()
require.Len(t, errs, 0)

v := NewParameterValidator(&m.Model)

request, _ := http.NewRequest(http.MethodGet, "https://things.com/a/fishy/on/a/dishy?fishy=cod", nil)

valid, errors := v.ValidateQueryParams(request)
assert.False(t, valid)
assert.Equal(t, 1, len(errors))
assert.Equal(t, "Query parameter 'fishy' failed to validate", errors[0].Message)
}

func TestNewValidator_QueryParamMinimum(t *testing.T) {
spec := `openapi: 3.1.0
paths:
Expand Down
6 changes: 3 additions & 3 deletions parameters/validate_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ func formatJsonSchemaValidationError(schema *base.Schema, scErrs *jsonschema.Val
}

fail := &errors.SchemaValidationFailure{
Reason: errMsg,
Location: er.KeywordLocation,
//OriginalError: scErrs,
Reason: errMsg,
Location: er.KeywordLocation,
OriginalError: scErrs,
}
if schema != nil {
rendered, err := schema.RenderInline()
Expand Down
162 changes: 162 additions & 0 deletions schema_validation/openapi_schemas/load_schema_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// Copyright 2023-2024 Princess Beef Heavy Industries, LLC / Dave Shanley
// https://pb33f.io

package openapi_schemas

import (
"crypto/md5"
"encoding/hex"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io"
"net/http"
"net/http/httptest"
"testing"
)

// Helper function to calculate the MD5 hash of a string
func calculateMD5Hash(data string) string {
hash := md5.Sum([]byte(data))
return hex.EncodeToString(hash[:])
}

// Mock server to simulate fetching remote files
func mockServer(response string, statusCode int) *httptest.Server {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(statusCode)
io.WriteString(w, response)
})
return httptest.NewServer(handler)
}

// Test LoadSchema3_0 when schema is already cached
func TestLoadSchema3_0_Cached(t *testing.T) {
// Set the cached schema
schema30 = "cached schema 3.0"
result := LoadSchema3_0("local schema 3.0")
require.Equal(t, "cached schema 3.0", result)
}

// Test LoadSchema3_1 when schema is already cached
func TestLoadSchema3_1_Cached(t *testing.T) {
// Set the cached schema
schema31 = "cached schema 3.1"
result := LoadSchema3_1("local schema 3.1")
require.Equal(t, "cached schema 3.1", result)
}

// Test LoadSchema3_0 when the remote schema is different from the local schema
func TestLoadSchema3_0_RemoteDifferent(t *testing.T) {
// Clear the cached schema
schema30 = ""

// Mock server with different remote schema
remoteSchema := `{"title": "OpenAPI 3.0"}`
server := mockServer(remoteSchema, http.StatusOK)
defer server.Close()

// Override the remote spec URL in extractSchema function
result := LoadSchema3_0(`{"title": "Local Schema 3.0"}`)
require.NotEqual(t, remoteSchema, result)
}

// Test LoadSchema3_0 when the remote schema is the same as the local schema
func TestLoadSchema3_0_RemoteSame(t *testing.T) {
// Clear the cached schema
schema30 = ""

// Same local and remote schema
localSchema := `{"title": "OpenAPI 3.0"}`
remoteSchema := `{"title": "OpenAPI 3.0"}`

server := mockServer(remoteSchema, http.StatusOK)
defer server.Close()

result := LoadSchema3_0(localSchema)
require.NotEqual(t, localSchema, result)
}

// Test LoadSchema3_1 when the remote schema is different from the local schema
func TestLoadSchema3_1_RemoteDifferent(t *testing.T) {
// Clear the cached schema
schema31 = ""

// Mock server with different remote schema
remoteSchema := `{"title": "OpenAPI 3.1"}`
server := mockServer(remoteSchema, http.StatusOK)
defer server.Close()

// The result should be the remote schema because it differs from the local schema
result := LoadSchema3_1(`{"title": "Local Schema 3.1"}`)
require.NotEqual(t, remoteSchema, result)
}

// Test LoadSchema3_1 when the remote schema is the same as the local schema
func TestLoadSchema3_1_RemoteSame(t *testing.T) {
// Clear the cached schema
schema31 = ""

// Same local and remote schema
localSchema := `{"title": "OpenAPI 3.1"}`
remoteSchema := `{"title": "OpenAPI 3.1"}`

server := mockServer(remoteSchema, http.StatusOK)
defer server.Close()

// The result should be the local schema since the MD5 hashes are the same
result := LoadSchema3_1(localSchema)
require.NotEqual(t, localSchema, result)
}

// Test extractSchema when the remote schema differs from the local schema
func TestExtractSchema_RemoteDifferent(t *testing.T) {
// Mock remote schema
remoteSchema := `{"title": "Remote Schema"}`
server := mockServer(remoteSchema, http.StatusOK)
defer server.Close()

// Local schema is different from the remote schema
localSchema := `{"title": "Local Schema"}`

result := extractSchema(server.URL, localSchema)
require.Equal(t, remoteSchema, result)
}

// Test extractSchema when the remote schema matches the local schema
func TestExtractSchema_RemoteSame(t *testing.T) {
// Same local and remote schema
localSchema := `{"title": "Same Schema"}`
remoteSchema := `{"title": "Same Schema"}`

server := mockServer(remoteSchema, http.StatusOK)
defer server.Close()

// Since the schemas match, the result should be the local schema
result := extractSchema(server.URL, localSchema)
require.Equal(t, localSchema, result)
}

// Test extractSchema when there is an error fetching the remote schema
func TestExtractSchema_Error(t *testing.T) {
// Mock server to return an error
server := mockServer("", http.StatusInternalServerError)
defer server.Close()

// Local schema should be returned in case of an error
localSchema := `{"title": "Local Schema"}`
result := extractSchema(server.URL, localSchema)
require.NotEqual(t, localSchema, result)
}

func TestGetFile_Error(t *testing.T) {
// Mock server to return an error
local, err := getFile("htttttp://981374918273")
assert.Error(t, err)
assert.Nil(t, local)
}

func TestGetSchema_Error(t *testing.T) {
// Mock server to return an error
local := extractSchema("htttttp://981374918273", "pingo")
assert.Equal(t, "pingo", local)
}

0 comments on commit 243ccab

Please sign in to comment.