From ec79c367e4d5bd709065dc19f19b89885c066620 Mon Sep 17 00:00:00 2001 From: damienmulder Date: Mon, 15 Jun 2026 17:06:39 +0200 Subject: [PATCH] Revert and fix linting and add test --- .github/workflows/lint.yml | 23 ++++ .golangci.yml | 131 +++++++++++++++++++ README.md | 2 +- go.mod | 2 +- pkg/utils/xml.go | 19 ++- pkg/wcs201/capabilities.go | 4 +- pkg/wcs201/getcapabilities_request.go | 2 +- pkg/wfs200/capabilities.go | 11 +- pkg/wfs200/crs.go | 2 +- pkg/wfs200/crs_test.go | 14 +- pkg/wfs200/crs_yaml.go | 7 +- pkg/wfs200/describefeaturetype_request.go | 6 +- pkg/wfs200/describefeaturetype_request_pv.go | 16 +-- pkg/wfs200/describefeaturetype_test.go | 2 + pkg/wfs200/exception.go | 1 + pkg/wfs200/exception_codes.go | 10 +- pkg/wfs200/getcapabilities_request.go | 18 +-- pkg/wfs200/getcapabilities_request_pv.go | 12 +- pkg/wfs200/getcapabilities_response.go | 18 +-- pkg/wfs200/getcapabilities_test.go | 1 + pkg/wfs200/getfeature_request.go | 105 ++++++++------- pkg/wfs200/getfeature_request_pv.go | 23 ++-- pkg/wfs200/getfeature_test.go | 11 +- pkg/wms130/boundingbox_xml.go | 2 +- pkg/wms130/boundingbox_yaml.go | 8 +- pkg/wms130/boundingbox_yaml_test.go | 30 ++--- pkg/wms130/capabilities.go | 4 +- pkg/wms130/capabilities_test.go | 96 +++++++++++--- pkg/wms130/common.go | 2 + pkg/wms130/crs.go | 2 +- pkg/wms130/crs_test.go | 6 +- pkg/wms130/crs_yaml.go | 7 +- pkg/wms130/exception.go | 23 ++-- pkg/wms130/exception_codes.go | 120 +++++++++-------- pkg/wms130/exception_test.go | 9 +- pkg/wms130/getcapabilities_request.go | 10 +- pkg/wms130/getcapabilities_request_pv.go | 12 +- pkg/wms130/getcapabilities_test.go | 4 +- pkg/wms130/getfeatureinfo_request.go | 78 +++++------ pkg/wms130/getfeatureinfo_request_pv.go | 79 ++++++----- pkg/wms130/getfeatureinfo_test.go | 10 +- pkg/wms130/getmap_request.go | 27 ++-- pkg/wms130/getmap_request_pv.go | 16 +-- pkg/wms130/getmap_test.go | 19 +-- pkg/wmts100/capabilities.go | 4 +- pkg/wmts100/exception.go | 2 +- pkg/wsc110/boundingbox_xml.go | 2 +- pkg/wsc110/boundingbox_yaml.go | 8 +- pkg/wsc110/boundingbox_yaml_test.go | 30 ++--- pkg/wsc110/crs.go | 2 +- pkg/wsc110/crs_test.go | 14 +- pkg/wsc110/crs_yaml.go | 7 +- pkg/wsc110/exception.go | 1 + pkg/wsc110/exception_codes.go | 13 +- pkg/wsc110/exception_test.go | 1 + pkg/wsc200/exception.go | 3 +- pkg/wsc200/exception_codes.go | 11 +- pkg/wsc200/exception_test.go | 1 + 58 files changed, 680 insertions(+), 423 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .golangci.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..76971f7 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,23 @@ +name: Lint + +on: + push: + pull_request: + +jobs: + lint: + name: Run on Ubuntu + runs-on: ubuntu-latest + steps: + - name: Clone the code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Run linter + uses: golangci/golangci-lint-action@v9 + with: + version: v2.12.1 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..eeb8f1a --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,131 @@ +version: "2" +run: + timeout: 5m + modules-download-mode: readonly + tests: true + +linters: + default: none + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - copyloopvar + - cyclop + - dogsled + - dupl + - durationcheck + - errcheck + - errname + - errorlint + - exhaustive + - exptostd + - fatcontext + - forbidigo + - funlen + - gocheckcompilerdirectives + - goconst + - gocritic + - gomoddirectives + - gomodguard + - goprintffuncname + - gosec + - govet + - ineffassign + - loggercheck + - makezero + - mirror + - misspell + - nakedret + - nestif + - nilerr + - nolintlint + - nosprintfhostport + - perfsprint + - predeclared + - promlinter + - reassign + - revive + - rowserrcheck + - sloglint + - sqlclosecheck + - staticcheck + - tagliatelle + - testableexamples + - tparallel + - unconvert + - unparam + - unused + - usestdlibvars + - usetesting + - wastedassign # finds wasted assignment statements + settings: + revive: + rules: + # default rules + - name: blank-imports + - name: context-as-argument + - name: context-keys-type + - name: dot-imports + - name: empty-block + - name: error-naming + - name: error-return + - name: error-strings + - name: errorf + - name: increment-decrement + - name: indent-error-flow + - name: range + - name: receiver-naming + - name: redefines-builtin-id + - name: superfluous-else + - name: time-naming + - name: unexported-return + - name: unreachable-code + - name: unused-parameter + - name: var-declaration + # enabled or tweaked by us + - name: use-any + cyclop: + max-complexity: 15 + depguard: + rules: + main: + deny: + - pkg: github.com/pkg/errors + desc: Should be replaced by standard lib errors package + forbidigo: + forbid: + - pattern: http\.NotFound.* + - pattern: http\.Error.* + funlen: + lines: 100 + gomoddirectives: + replace-allow-list: + - github.com/abbot/go-http-auth + nestif: + min-complexity: 6 + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - bodyclose + - dogsled + - dupl + - funlen + - gosec + path: _test\.go + - linters: + - cyclop + - goconst + - staticcheck + path: (.+)_test\.go + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/README.md b/README.md index ebed6fb..863fd4c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # ogc-specifications - +[![Lint](https://github.com/PDOK/ogc-specifications/actions/workflows/lint.yml/badge.svg)](https://github.com/PDOK/ogc-specifications/actions/workflows/lint.yml) ![GitHub license](https://img.shields.io/github/license/PDOK/ogc-specifications) [![GitHub release](https://img.shields.io/github/release/PDOK/ogc-specifications.svg)](https://github.com/PDOK/ogc-specifications/releases) diff --git a/go.mod b/go.mod index 15a10a0..0fb84da 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ module github.com/pdok/ogc-specifications -go 1.26 +go 1.26.3 require gopkg.in/yaml.v3 v3.0.1 diff --git a/pkg/utils/xml.go b/pkg/utils/xml.go index 16228e6..6c6cbe4 100644 --- a/pkg/utils/xml.go +++ b/pkg/utils/xml.go @@ -9,13 +9,13 @@ type XMLAttribute []xml.Attr // StripDuplicateAttr removes the duplicate Attributes from a []Attribute func StripDuplicateAttr(attr []xml.Attr) []xml.Attr { - attributemap := make(map[xml.Name]string) + attributeMap := make(map[xml.Name]string) for _, a := range attr { - attributemap[xml.Name{Space: a.Name.Space, Local: a.Name.Local}] = a.Value + attributeMap[xml.Name{Space: a.Name.Space, Local: a.Name.Local}] = a.Value } var strippedAttr []xml.Attr - for k, v := range attributemap { + for k, v := range attributeMap { strippedAttr = append(strippedAttr, xml.Attr{Name: k, Value: v}) } return strippedAttr @@ -23,21 +23,18 @@ func StripDuplicateAttr(attr []xml.Attr) []xml.Attr { // UnmarshalXML func for the XMLAttr struct func (xmlattr *XMLAttribute) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - var newattributes XMLAttribute + var newAttributes XMLAttribute for _, attr := range start.Attr { - switch attr.Name.Local { - default: - newattributes = append(newattributes, xml.Attr{Name: attr.Name, Value: attr.Value}) - } + newAttributes = append(newAttributes, xml.Attr{Name: attr.Name, Value: attr.Value}) } - *xmlattr = newattributes + *xmlattr = newAttributes for { // if it got this far the XML is 'valid' and the xmlattr are set // so we ignore the err token, _ := d.Token() - switch el := token.(type) { - case xml.EndElement: + + if el, ok := token.(xml.EndElement); ok { if el == start.End() { return nil } diff --git a/pkg/wcs201/capabilities.go b/pkg/wcs201/capabilities.go index 50947f9..9459850 100644 --- a/pkg/wcs201/capabilities.go +++ b/pkg/wcs201/capabilities.go @@ -1,12 +1,12 @@ package wcs201 // ParseXML func -func (c *Capabilities) ParseXML(doc []byte) error { +func (c *Capabilities) ParseXML(_ []byte) error { return nil } // ParseYAML func -func (c *Capabilities) ParseYAML(doc []byte) error { +func (c *Capabilities) ParseYAML(_ []byte) error { return nil } diff --git a/pkg/wcs201/getcapabilities_request.go b/pkg/wcs201/getcapabilities_request.go index 449b37b..0e889e1 100644 --- a/pkg/wcs201/getcapabilities_request.go +++ b/pkg/wcs201/getcapabilities_request.go @@ -23,7 +23,7 @@ func (gc *GetCapabilitiesRequest) Type() string { } // Validate validates the GetCapabilities struct -func (gc *GetCapabilitiesRequest) Validate(c Capabilities) []wsc200.Exception { +func (gc *GetCapabilitiesRequest) Validate(_ Capabilities) []wsc200.Exception { return nil } diff --git a/pkg/wfs200/capabilities.go b/pkg/wfs200/capabilities.go index d41cb3d..bcabe19 100644 --- a/pkg/wfs200/capabilities.go +++ b/pkg/wfs200/capabilities.go @@ -2,16 +2,17 @@ package wfs200 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/wsc110" ) // ParseXML func -func (c *Capabilities) ParseXML(doc []byte) error { +func (c *Capabilities) ParseXML(_ []byte) error { return nil } // ParseYAML func -func (c *Capabilities) ParseYAML(doc []byte) error { +func (c *Capabilities) ParseYAML(_ []byte) error { return nil } @@ -164,7 +165,7 @@ type MetadataHref struct { // FilterCapabilities struct for the WFS 2.0.0 type FilterCapabilities struct { Conformance Conformance `xml:"fes:Conformance" yaml:"conformance"` - IDCapabilities IdCapabilities `xml:"fes:Id_Capabilities" yaml:"idCapabilities"` + IDCapabilities IDCapabilities `xml:"fes:Id_Capabilities" yaml:"idCapabilities"` ScalarCapabilities ScalarCapabilities `xml:"fes:Scalar_Capabilities" yaml:"scalarCapabilities"` SpatialCapabilities SpatialCapabilities `xml:"fes:Spatial_Capabilities" yaml:"spatialCapabilities"` // NO TemporalCapabilities!!! @@ -176,8 +177,8 @@ type Conformance struct { Constraint []ValueConstraint `xml:"fes:Constraint" yaml:"constraint"` } -// IdCapabilities struct for the WFS 2.0.0 -type IdCapabilities struct { +// IDCapabilities struct for the WFS 2.0.0 +type IDCapabilities struct { ResourceIdentifier ResourceIdentifier `xml:"fes:ResourceIdentifier" yaml:"resourceIdentifier"` } diff --git a/pkg/wfs200/crs.go b/pkg/wfs200/crs.go index be84ac5..f609d62 100644 --- a/pkg/wfs200/crs.go +++ b/pkg/wfs200/crs.go @@ -11,7 +11,7 @@ const ( // CRS struct with namespace/authority/registry and code type CRS struct { - Namespace string //TODO maybe AuthorityType is a better name...? + Namespace string // TODO maybe AuthorityType is a better name...? Code int } diff --git a/pkg/wfs200/crs_test.go b/pkg/wfs200/crs_test.go index 52f3fa2..b7eed6c 100644 --- a/pkg/wfs200/crs_test.go +++ b/pkg/wfs200/crs_test.go @@ -51,10 +51,8 @@ othercrs: err := yaml.Unmarshal(test.yaml, &ftl) if err != nil { t.Errorf("test: %d, yaml.UnMarshal failed with '%s'\n", k, err) - } else { - if ftl.DefaultCRS.Code != test.expectedcrs.Code || ftl.DefaultCRS.Namespace != test.expectedcrs.Namespace { - t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedcrs, ftl.DefaultCRS) - } + } else if ftl.DefaultCRS.Code != test.expectedcrs.Code || ftl.DefaultCRS.Namespace != test.expectedcrs.Namespace { + t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedcrs, ftl.DefaultCRS) } } } @@ -70,13 +68,11 @@ func TestMarshalYAMLCrs(t *testing.T) { } for k, test := range tests { yamlCRS, err := yaml.Marshal(test.CRS) + if err != nil { t.Errorf("test: %d, yaml.Marshal failed with '%s'\n", k, err) - } else { - stringCRS := string(yamlCRS) - if stringCRS != test.expectedYAML { - t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedYAML, stringCRS) - } + } else if stringCRS := string(yamlCRS); stringCRS != test.expectedYAML { + t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedYAML, stringCRS) } } } diff --git a/pkg/wfs200/crs_yaml.go b/pkg/wfs200/crs_yaml.go index 5033adb..8269c76 100644 --- a/pkg/wfs200/crs_yaml.go +++ b/pkg/wfs200/crs_yaml.go @@ -1,9 +1,7 @@ package wfs200 // UnmarshalYAML CRS -// -//nolint:revive -func (c *CRS) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (c *CRS) UnmarshalYAML(unmarshal func(any) error) error { var s string if err := unmarshal(&s); err != nil { return err @@ -17,7 +15,6 @@ func (c *CRS) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } -//nolint:revive -func (c CRS) MarshalYAML() (interface{}, error) { +func (c CRS) MarshalYAML() (any, error) { return c.String(), nil } diff --git a/pkg/wfs200/describefeaturetype_request.go b/pkg/wfs200/describefeaturetype_request.go index afe806b..d3ef3b9 100644 --- a/pkg/wfs200/describefeaturetype_request.go +++ b/pkg/wfs200/describefeaturetype_request.go @@ -21,7 +21,7 @@ func (d DescribeFeatureTypeRequest) Type() string { } // Validate returns GetCapabilities -func (d DescribeFeatureTypeRequest) Validate(c wsc110.Capabilities) []wsc110.Exception { +func (d DescribeFeatureTypeRequest) Validate(_ wsc110.Capabilities) []wsc110.Exception { return nil } @@ -83,8 +83,8 @@ func (d *DescribeFeatureTypeRequest) parsedescribeFeatureTypeRequestParameterVal d.TypeNames = dpv.typeName - if dpv.outputFormat != nil { - d.OutputFormat = dpv.outputFormat + if dpv.OutputFormat != nil { + d.OutputFormat = dpv.OutputFormat } else { s := gml32 d.OutputFormat = &(s) diff --git a/pkg/wfs200/describefeaturetype_request_pv.go b/pkg/wfs200/describefeaturetype_request_pv.go index 40784c3..2c8b387 100644 --- a/pkg/wfs200/describefeaturetype_request_pv.go +++ b/pkg/wfs200/describefeaturetype_request_pv.go @@ -7,14 +7,15 @@ import ( "github.com/pdok/ogc-specifications/pkg/wsc110" ) +//nolint:govet,staticcheck type describeFeatureTypeRequestParameterValue struct { service string `yaml:"service" json:"service"` baseParameterValueRequest - typeName *string `yaml:"typeName" json:"typeName"` // [0..*] - outputFormat *string `yaml:"outputFormat" json:"outputFormat"` // default: "text/xml; subtype=gml/3.2" + OutputFormat *string `yaml:"outputFormat" json:"outputFormat"` // default: "text/xml; subtype=gml/3.2" } +//nolint:staticcheck func (dpv *describeFeatureTypeRequestParameterValue) parseQueryParameters(query url.Values) []wsc110.Exception { var exceptions []wsc110.Exception for k, v := range query { @@ -33,7 +34,7 @@ func (dpv *describeFeatureTypeRequestParameterValue) parseQueryParameters(query dpv.typeName = &vp case OUTPUTFORMAT: vp := v[0] - dpv.outputFormat = &vp + dpv.OutputFormat = &vp } } } @@ -45,13 +46,12 @@ func (dpv *describeFeatureTypeRequestParameterValue) parseQueryParameters(query return nil } -func (dpv *describeFeatureTypeRequestParameterValue) parseDescribeFeatureTypeRequest(dft DescribeFeatureTypeRequest) []wsc110.Exception { +func (dpv *describeFeatureTypeRequestParameterValue) parseDescribeFeatureTypeRequest(dft DescribeFeatureTypeRequest) { dpv.request = describefeaturetype dpv.version = dft.Version dpv.service = dft.Service dpv.typeName = dft.TypeNames - dpv.outputFormat = dft.OutputFormat - return nil + dpv.OutputFormat = dft.OutputFormat } func (dpv describeFeatureTypeRequestParameterValue) toQueryParameters() url.Values { @@ -62,8 +62,8 @@ func (dpv describeFeatureTypeRequestParameterValue) toQueryParameters() url.Valu if dpv.typeName != nil { querystring[TYPENAME] = []string{*dpv.typeName} } - if dpv.outputFormat != nil { - querystring[OUTPUTFORMAT] = []string{*dpv.outputFormat} + if dpv.OutputFormat != nil { + querystring[OUTPUTFORMAT] = []string{*dpv.OutputFormat} } return querystring } diff --git a/pkg/wfs200/describefeaturetype_test.go b/pkg/wfs200/describefeaturetype_test.go index 29bd9cf..1b97536 100644 --- a/pkg/wfs200/describefeaturetype_test.go +++ b/pkg/wfs200/describefeaturetype_test.go @@ -15,6 +15,7 @@ func TestDescribeFeatureTypeType(t *testing.T) { } } +//nolint:nestif func TestDescribeFeatureTypeParseXML(t *testing.T) { var tests = []struct { body []byte @@ -100,6 +101,7 @@ func TestDescribeFeatureTypeParseXML(t *testing.T) { } } +//nolint:nestif func TestDescribeFeatureTypeParseQueryParameters(t *testing.T) { var tests = []struct { query url.Values diff --git a/pkg/wfs200/exception.go b/pkg/wfs200/exception.go index ecd1337..33b18c6 100644 --- a/pkg/wfs200/exception.go +++ b/pkg/wfs200/exception.go @@ -2,6 +2,7 @@ package wfs200 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/wsc110" ) diff --git a/pkg/wfs200/exception_codes.go b/pkg/wfs200/exception_codes.go index 0094272..193432e 100644 --- a/pkg/wfs200/exception_codes.go +++ b/pkg/wfs200/exception_codes.go @@ -6,6 +6,10 @@ import ( "github.com/pdok/ogc-specifications/pkg/wsc110" ) +const ( + invalidValue = "InvalidValue" +) + // CannotLockAllFeatures exception func CannotLockAllFeatures() wsc110.Exception { return exception{ @@ -45,11 +49,11 @@ func InvalidLockID() wsc110.Exception { func InvalidValue(s ...string) wsc110.Exception { if len(s) == 1 { return exception{ExceptionText: fmt.Sprintf("The parameter: %s, contains a InvalidValue", s[0]), - ExceptionCode: "InvalidValue", + ExceptionCode: invalidValue, LocatorCode: s[0]} } return exception{ - ExceptionCode: "InvalidValue", + ExceptionCode: invalidValue, } } @@ -63,7 +67,7 @@ func LockHasExpired() wsc110.Exception { // OperationParsingFailed exception func OperationParsingFailed(value, locator string) wsc110.Exception { return exception{ - ExceptionText: fmt.Sprintf("Failed to parse the operation, found: %s", value), + ExceptionText: "Failed to parse the operation, found: " + value, LocatorCode: locator, ExceptionCode: "OperationParsingFailed"} } diff --git a/pkg/wfs200/getcapabilities_request.go b/pkg/wfs200/getcapabilities_request.go index e89fbb2..dd19a76 100644 --- a/pkg/wfs200/getcapabilities_request.go +++ b/pkg/wfs200/getcapabilities_request.go @@ -18,22 +18,22 @@ func (g GetCapabilitiesRequest) Type() string { } // Validate returns GetCapabilities -func (g GetCapabilitiesRequest) Validate(c wsc110.Capabilities) []wsc110.Exception { +func (g GetCapabilitiesRequest) Validate(_ wsc110.Capabilities) []wsc110.Exception { var exceptions []wsc110.Exception return exceptions } // ParseXML builds a GetCapabilities object based on a XML document func (g *GetCapabilitiesRequest) ParseXML(doc []byte) []wsc110.Exception { - var xmlattributes utils.XMLAttribute - if err := xml.Unmarshal(doc, &xmlattributes); err != nil { + var xmlAttributes utils.XMLAttribute + if err := xml.Unmarshal(doc, &xmlAttributes); err != nil { return []wsc110.Exception{wsc110.NoApplicableCode("Could not process XML, is it XML?")} } if err := xml.Unmarshal(doc, &g); err != nil { - return []wsc110.Exception{wsc110.OperationNotSupported(err.Error())} //TODO Should be OperationParsingFailed + return []wsc110.Exception{wsc110.OperationNotSupported(err.Error())} // TODO Should be OperationParsingFailed } var n []xml.Attr - for _, a := range xmlattributes { + for _, a := range xmlAttributes { switch strings.ToUpper(a.Name.Local) { case VERSION: case SERVICE: @@ -50,7 +50,7 @@ func (g *GetCapabilitiesRequest) ParseXML(doc []byte) []wsc110.Exception { func (g *GetCapabilitiesRequest) ParseQueryParameters(query url.Values) []wsc110.Exception { if len(query) == 0 { // When there are no query value we know that at least - // the manadorty SERVICE and REQUEST parameter is missing. + // the mandatory SERVICE and REQUEST parameter is missing. exceptions := wsc110.MissingParameterValue(SERVICE).ToExceptions() exceptions = append(exceptions, wsc110.MissingParameterValue(REQUEST)) return exceptions @@ -61,15 +61,15 @@ func (g *GetCapabilitiesRequest) ParseQueryParameters(query url.Values) []wsc110 return exception } - if exception := g.parsegetCapabilitiesRequestParameterValue(gpv); exception != nil { + if exception := g.parseGetCapabilitiesRequestParameterValue(gpv); exception != nil { return exception } return nil } -// parsegetCapabilitiesRequestParameterValue process the simple struct to a complex struct -func (g *GetCapabilitiesRequest) parsegetCapabilitiesRequestParameterValue(gpv getCapabilitiesRequestParameterValue) []wsc110.Exception { +// parseGetCapabilitiesRequestParameterValue process the simple struct to a complex struct +func (g *GetCapabilitiesRequest) parseGetCapabilitiesRequestParameterValue(gpv getCapabilitiesRequestParameterValue) []wsc110.Exception { g.XMLName.Local = gpv.request g.Service = gpv.service g.Version = gpv.version diff --git a/pkg/wfs200/getcapabilities_request_pv.go b/pkg/wfs200/getcapabilities_request_pv.go index 646d205..1ac8376 100644 --- a/pkg/wfs200/getcapabilities_request_pv.go +++ b/pkg/wfs200/getcapabilities_request_pv.go @@ -7,13 +7,15 @@ import ( "github.com/pdok/ogc-specifications/pkg/wsc110" ) -//getCapabilitiesRequestParameterValue struct +// getCapabilitiesRequestParameterValue struct type getCapabilitiesRequestParameterValue struct { service string `yaml:"service,omitempty"` baseParameterValueRequest } // ParseQueryParameters builds a GetCapabilities object based on the available query parameters +// +//nolint:staticcheck func (gpv *getCapabilitiesRequestParameterValue) parseQueryParameters(query url.Values) []wsc110.Exception { var exceptions []wsc110.Exception for k, v := range query { @@ -41,14 +43,14 @@ func (gpv *getCapabilitiesRequestParameterValue) parseQueryParameters(query url. // parseGetCapabilitiesRequest builds a getCapabilitiesRequestParameterValue object based on a GetCapabilities struct // This is a 'dummy' implementation, because for a GetCapabilities request it will always be // Mandatory: REQUEST=GetCapabilities -// SERVICE=WFS +// +// SERVICE=WFS +// // Optional: VERSION=2.0.0 -func (gpv *getCapabilitiesRequestParameterValue) parseGetCapabilitiesRequest(gc GetCapabilitiesRequest) []wsc110.Exception { +func (gpv *getCapabilitiesRequestParameterValue) parseGetCapabilitiesRequest(gc GetCapabilitiesRequest) { gpv.request = getcapabilities gpv.version = gc.Version gpv.service = gc.Service - - return nil } // toQueryParameters builds a url.Values query from a getCapabilitiesRequestParameterValue struct diff --git a/pkg/wfs200/getcapabilities_response.go b/pkg/wfs200/getcapabilities_response.go index e2a993e..e7dfa53 100644 --- a/pkg/wfs200/getcapabilities_response.go +++ b/pkg/wfs200/getcapabilities_response.go @@ -47,15 +47,15 @@ type GetCapabilitiesResponse struct { // Namespaces struct containing the namespaces needed for the XML document type Namespaces struct { - XmlnsGML string `xml:"xmlns:gml,attr" yaml:"gml"` //http://www.opengis.net/gml/3.2 - XmlnsWFS string `xml:"xmlns,attr" yaml:"wfs"` //http://www.opengis.net/wfs/2.0 - XmlnsOWS string `xml:"xmlns:ows,attr" yaml:"common"` //http://www.opengis.net/ows/1.1 - XmlnsXlink string `xml:"xmlns:xlink,attr" yaml:"xlink"` //http://www.w3.org/1999/xlink - XmlnsXSI string `xml:"xmlns:xsi,attr" yaml:"xsi"` //http://www.w3.org/2001/XMLSchema-instance - XmlnsFes string `xml:"xmlns:fes,attr" yaml:"fes"` //http://www.opengis.net/fes/2.0 - XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspireCommon,omitempty"` //http://inspire.ec.europa.eu/schemas/common/1.0 - XmlnsInspireDls string `xml:"xmlns:inspire_dls,attr,omitempty" yaml:"inspireDls,omitempty"` //http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 - XmlnsPrefix string `xml:"xmlns:{{.Prefix}},attr" yaml:"prefix"` //namespace_uri placeholder + XmlnsGML string `xml:"xmlns:gml,attr" yaml:"gml"` // http://www.opengis.net/gml/3.2 + XmlnsWFS string `xml:"xmlns,attr" yaml:"wfs"` // http://www.opengis.net/wfs/2.0 + XmlnsOWS string `xml:"xmlns:ows,attr" yaml:"common"` // http://www.opengis.net/ows/1.1 + XmlnsXlink string `xml:"xmlns:xlink,attr" yaml:"xlink"` // http://www.w3.org/1999/xlink + XmlnsXSI string `xml:"xmlns:xsi,attr" yaml:"xsi"` // http://www.w3.org/2001/XMLSchema-instance + XmlnsFes string `xml:"xmlns:fes,attr" yaml:"fes"` // http://www.opengis.net/fes/2.0 + XmlnsInspireCommon string `xml:"xmlns:inspire_common,attr,omitempty" yaml:"inspireCommon,omitempty"` // http://inspire.ec.europa.eu/schemas/common/1.0 + XmlnsInspireDls string `xml:"xmlns:inspire_dls,attr,omitempty" yaml:"inspireDls,omitempty"` // http://inspire.ec.europa.eu/schemas/inspire_dls/1.0 + XmlnsPrefix string `xml:"xmlns:{{.Prefix}},attr" yaml:"prefix"` // namespace_uri placeholder Version string `xml:"version,attr" yaml:"version"` SchemaLocation string `xml:"xsi:schemaLocation,attr" yaml:"schemaLocation"` } diff --git a/pkg/wfs200/getcapabilities_test.go b/pkg/wfs200/getcapabilities_test.go index a12abd4..8c6026a 100644 --- a/pkg/wfs200/getcapabilities_test.go +++ b/pkg/wfs200/getcapabilities_test.go @@ -15,6 +15,7 @@ func TestGetCapabilitiesType(t *testing.T) { } } +//nolint:nestif func TestGetCapabilitiesParseXML(t *testing.T) { var tests = []struct { body []byte diff --git a/pkg/wfs200/getfeature_request.go b/pkg/wfs200/getfeature_request.go index 33b9889..f987f77 100644 --- a/pkg/wfs200/getfeature_request.go +++ b/pkg/wfs200/getfeature_request.go @@ -54,30 +54,38 @@ func (f GetFeatureRequest) Type() string { } // Validate returns GetFeature -func (f GetFeatureRequest) Validate(c wsc110.Capabilities) []wsc110.Exception { +func (f GetFeatureRequest) Validate(_ wsc110.Capabilities) []wsc110.Exception { - //getfeaturecap := c.(capabilities.Capabilities) + // getfeaturecap := c.(capabilities.Capabilities) return nil } // WFS tables as map[string]bool, where the key (string) is the TOKEN and the bool if its a mandatory (true) or optional (false) attribute -//var table5 = map[string]bool{STARTINDEX: false, COUNT: false, OUTPUTFORMAT: false, RESULTTYPE: false} +// var table5 = map[string]bool{STARTINDEX: false, COUNT: false, OUTPUTFORMAT: false, RESULTTYPE: false} // var table6 = map[string]bool{RESOLVE: false, RESOLVEDEPTH: false, RESOLVETIMEOUT: false} // var table7 = map[string]bool{NAMESPACES: false} //VSPs (<- vendor specific parameters) var table8 = map[string]bool{TYPENAMES: true, ALIASES: false, SRSNAME: false, FILTER: false, FILTERLANGUAGE: false, RESOURCEID: false, BBOX: false, SORTBY: false} -//var table10 = map[string]bool{STOREDQUERYID: true} //storedquery_parameter=value +// var table10 = map[string]bool{STOREDQUERYID: true} //storedquery_parameter=value // ParseXML builds a GetCapabilities object based on a XML document +// +//nolint:staticcheck func (f *GetFeatureRequest) ParseXML(doc []byte) []wsc110.Exception { - var xmlattributes utils.XMLAttribute - if err := xml.Unmarshal(doc, &xmlattributes); err != nil { + var xmlAttributes utils.XMLAttribute + if err := xml.Unmarshal(doc, &xmlAttributes); err != nil { return wsc110.NoApplicableCode("Could not process XML, is it XML?").ToExceptions() } - xml.Unmarshal(doc, &f) //When object can be Unmarshalled -> XMLAttributes, it can be Unmarshalled -> GetFeature + + // When object can be Unmarshalled -> XMLAttributes, it can be Unmarshalled -> GetFeature + // if err := xml.Unmarshal(doc, &f); err != nil { + // return wsc110.NoApplicableCode("Could not process XML, is it XML?").ToExceptions() + // } + _ = xml.Unmarshal(doc, &f) + var n []xml.Attr - for _, a := range xmlattributes { + for _, a := range xmlAttributes { switch strings.ToUpper(a.Name.Local) { case VERSION: case SERVICE: @@ -107,7 +115,7 @@ func (f *GetFeatureRequest) ParseQueryParameters(query url.Values) []wsc110.Exce return exceptions } - if exceptions := f.parsegetFeatureRequestParameterValue(fpv); exceptions != nil { + if exceptions := f.parseGetFeatureRequestParameterValue(fpv); exceptions != nil { return exceptions } return nil @@ -120,7 +128,8 @@ func (f GetFeatureRequest) ToXML() []byte { return append([]byte(xml.Header), si...) } -func (f *GetFeatureRequest) parsegetFeatureRequestParameterValue(fpv getFeatureRequestParameterValue) []wsc110.Exception { +//nolint:staticcheck +func (f *GetFeatureRequest) parseGetFeatureRequestParameterValue(fpv getFeatureRequestParameterValue) []wsc110.Exception { // Base f.XMLName.Local = getfeature @@ -199,6 +208,7 @@ type StandardPresentationParameters struct { StartIndex *int `xml:"startindex,attr,omitempty" yaml:"startIndex"` // default 0 } +//nolint:nestif func (b *StandardPresentationParameters) parseKVPRequest(fpv getFeatureRequestParameterValue) []wsc110.Exception { var exceptions []wsc110.Exception @@ -220,11 +230,11 @@ func (b *StandardPresentationParameters) parseKVPRequest(fpv getFeatureRequestPa } if fpv.startindex != nil { - startindex, err := strconv.Atoi(*fpv.startindex) + startIndex, err := strconv.Atoi(*fpv.startindex) if err != nil { exceptions = append(exceptions, wsc110.MissingParameterValue(STARTINDEX, *fpv.startindex)) } - b.StartIndex = &startindex + b.StartIndex = &startIndex } } @@ -237,7 +247,7 @@ func (b *StandardPresentationParameters) parseKVPRequest(fpv getFeatureRequestPa // StandardResolveParameters struct used by GetFeature // contains the resolve information of a GetFeauter request type StandardResolveParameters struct { - Resolve *string `xml:"Resolve,omitempty" yaml:"resolve"` //can be one of: local, remote, all, none + Resolve *string `xml:"Resolve,omitempty" yaml:"resolve"` // can be one of: local, remote, all, none ResolveDepth *int `xml:"ResolveDepth,omitempty" yaml:"resolveDepth"` ResolveTimeout *int `xml:"ResolveTimeout,omitempty" yaml:"resolveTimeout"` } @@ -260,21 +270,21 @@ func (q *Query) parseKVPRequest(fpv getFeatureRequestParameterValue) []wsc110.Ex q.SrsName = fpv.srsname } - var selectionclause []string + var selectionClause []string if fpv.resourceid != nil { - selectionclause = append(selectionclause, RESOURCEID) + selectionClause = append(selectionClause, RESOURCEID) } if fpv.filter != nil { - selectionclause = append(selectionclause, FILTER) + selectionClause = append(selectionClause, FILTER) } if fpv.bbox != nil { - selectionclause = append(selectionclause, BBOX) + selectionClause = append(selectionClause, BBOX) } - if len(selectionclause) > 1 { - exceptions = append(exceptions, wsc110.NoApplicableCode(fmt.Sprintf(`Only one of the following selectionclauses can be used %s`, strings.Join(selectionclause, `,`)))) - } else if len(selectionclause) == 1 { - switch selectionclause[0] { + if len(selectionClause) > 1 { + exceptions = append(exceptions, wsc110.NoApplicableCode(`Only one of the following selectionclauses can be used `+strings.Join(selectionClause, `,`))) + } else if len(selectionClause) == 1 { + switch selectionClause[0] { case RESOURCEID: f := Filter{} var rids ResourceIDs @@ -300,7 +310,7 @@ func (q *Query) parseKVPRequest(fpv getFeatureRequestParameterValue) []wsc110.Ex // TODO aliases // TODO filterlanguage - //q.SortBy = fpv.sortby + // q.SortBy = fpv.sortby if len(exceptions) > 0 { return exceptions @@ -371,11 +381,11 @@ type Filter struct { func (f Filter) toString() string { si, _ := xml.MarshalIndent(f, "", "") re := regexp.MustCompile(`><.*>`) - return (xml.Header + re.ReplaceAllString(string(si), "/>")) + return xml.Header + re.ReplaceAllString(string(si), "/>") } func (f *Filter) parseKVPRequest(filter string) []wsc110.Exception { - if error := xml.Unmarshal([]byte(filter), &f); error != nil { + if err := xml.Unmarshal([]byte(filter), &f); err != nil { return wsc110.NoApplicableCode(`Filter is not valid XML`).ToExceptions() } return nil @@ -424,14 +434,12 @@ func (r ResourceIDs) toString() string { return strings.Join(rids, ",") } -func (r *ResourceIDs) parseKVPRequest(resourceids string) []wsc110.Exception { +func (r *ResourceIDs) parseKVPRequest(resourceids string) { var rids ResourceIDs for _, resourceid := range strings.Split(resourceids, `,`) { rids = append(rids, ResourceID{Rid: resourceid}) } *r = rids - - return nil } // ResourceID struct for Filter @@ -691,31 +699,30 @@ type GEOBBOX struct { func (gb *GEOBBOX) parseKVPRequest(q string) []wsc110.Exception { regex := regexp.MustCompile(`,`) result := regex.Split(q, -1) - if len(result) == 4 || len(result) == 5 { - var lx, ly, ux, uy float64 - var err error + if len(result) != 4 && len(result) != 5 { + return wsc110.MissingParameterValue(BBOX, q).ToExceptions() + } + var lx, ly, ux, uy float64 + var err error - if lx, err = strconv.ParseFloat(result[0], 64); err != nil { - return InvalidValue(BBOX).ToExceptions() - } - if ly, err = strconv.ParseFloat(result[1], 64); err != nil { - return InvalidValue(BBOX).ToExceptions() - } - if ux, err = strconv.ParseFloat(result[2], 64); err != nil { - return InvalidValue(BBOX).ToExceptions() - } - if uy, err = strconv.ParseFloat(result[3], 64); err != nil { - return InvalidValue(BBOX).ToExceptions() - } + if lx, err = strconv.ParseFloat(result[0], 64); err != nil { + return InvalidValue(BBOX).ToExceptions() + } + if ly, err = strconv.ParseFloat(result[1], 64); err != nil { + return InvalidValue(BBOX).ToExceptions() + } + if ux, err = strconv.ParseFloat(result[2], 64); err != nil { + return InvalidValue(BBOX).ToExceptions() + } + if uy, err = strconv.ParseFloat(result[3], 64); err != nil { + return InvalidValue(BBOX).ToExceptions() + } - gb.Envelope.LowerCorner = wsc110.Position{lx, ly} - gb.Envelope.UpperCorner = wsc110.Position{ux, uy} - if len(result) == 5 { - gb.SrsName = &result[4] - } - } else { - return wsc110.MissingParameterValue(BBOX, q).ToExceptions() + gb.Envelope.LowerCorner = wsc110.Position{lx, ly} + gb.Envelope.UpperCorner = wsc110.Position{ux, uy} + if len(result) == 5 { + gb.SrsName = &result[4] } return nil diff --git a/pkg/wfs200/getfeature_request_pv.go b/pkg/wfs200/getfeature_request_pv.go index 9ef7083..0c71b31 100644 --- a/pkg/wfs200/getfeature_request_pv.go +++ b/pkg/wfs200/getfeature_request_pv.go @@ -46,6 +46,8 @@ type standardResolveParameters struct { // AdhocQueryKeywords struct // NOTE filter, resourceid and bbox are mutually exclusive +// +//nolint:tagliatelle type adhocQueryKeywords struct { // Table 8 typenames string `yaml:"typenames"` @@ -66,6 +68,7 @@ type storedQueryKeywords struct { // storedquery_parameter not implemented } +//nolint:cyclop,nestif,staticcheck func (fpv *getFeatureRequestParameterValue) parseQueryParameters(query url.Values) []wsc110.Exception { var exceptions []wsc110.Exception for k, v := range query { @@ -169,7 +172,8 @@ func (fpv *getFeatureRequestParameterValue) parseQueryParameters(query url.Value return nil } -func (fpv *getFeatureRequestParameterValue) parseGetFeatureRequest(f GetFeatureRequest) []wsc110.Exception { +//nolint:cyclop,funlen,staticcheck +func (fpv *getFeatureRequestParameterValue) parseGetFeatureRequest(f GetFeatureRequest) { fpv.request = getfeature fpv.version = Version @@ -246,13 +250,14 @@ func (fpv *getFeatureRequestParameterValue) parseGetFeatureRequest(f GetFeatureR } if f.Query.Filter != nil { - if f.Query.Filter.ResourceID != nil { + switch { + case f.Query.Filter.ResourceID != nil: s := f.Query.Filter.ResourceID.toString() fpv.resourceid = &(s) - } else if f.Query.Filter.BBOX != nil { + case f.Query.Filter.BBOX != nil: s := f.Query.Filter.BBOX.MarshalText() fpv.bbox = &s - } else { + default: f := f.Query.Filter.toString() fpv.filter = &f } @@ -268,10 +273,9 @@ func (fpv *getFeatureRequestParameterValue) parseGetFeatureRequest(f GetFeatureR // TODO // fpv.storedQueryKeywords.storedqueryid = v[0] - - return nil } +//nolint:cyclop func (fpv getFeatureRequestParameterValue) toQueryParameters() url.Values { query := make(map[string][]string) @@ -327,11 +331,12 @@ func (fpv getFeatureRequestParameterValue) toQueryParameters() url.Values { } // // Projection_clause not implemented - if fpv.filter != nil { + switch { + case fpv.filter != nil: query[FILTER] = []string{*fpv.filter} - } else if fpv.resourceid != nil { + case fpv.resourceid != nil: query[RESOURCEID] = []string{*fpv.resourceid} - } else if fpv.bbox != nil { + case fpv.bbox != nil: query[BBOX] = []string{*fpv.bbox} } diff --git a/pkg/wfs200/getfeature_test.go b/pkg/wfs200/getfeature_test.go index 900fd47..5a773c7 100644 --- a/pkg/wfs200/getfeature_test.go +++ b/pkg/wfs200/getfeature_test.go @@ -80,6 +80,8 @@ func TestGetFeatureToXML(t *testing.T) { // TODO // Merge TestParseBodyGetFeature & TestParseQueryParameters GetFeature comporison into single func, like with WMS GetMap +// +//nolint:nestif func TestGetFeatureParseXML(t *testing.T) { var tests = []struct { body []byte @@ -214,7 +216,7 @@ func TestProcesNamespaces(t *testing.T) { result: []xml.Attr{{Name: xml.Name{Local: "ns1"}, Value: "http://www.someserver.com/ns1"}}}, // Duplicate namespace with the different values 4: {namespace: "xmlns(ns1,http://www.someserver.com/ns1),xmlns(ns1,http://someserver.com/ns2)", - result: []xml.Attr{{Name: xml.Name{Local: "ns1"}, Value: "http://someserver.com/ns2"}}}, //takes the last matched result + result: []xml.Attr{{Name: xml.Name{Local: "ns1"}, Value: "http://someserver.com/ns2"}}}, // takes the last matched result // A namespace with a trailing string outside the xmlns() 5: {namespace: "xmlns(ns1,http://www.someserver.com/ns1),not a correct,namespace query,string", result: []xml.Attr{{Name: xml.Name{Local: "ns1"}, Value: "http://www.someserver.com/ns1"}}}, @@ -319,6 +321,7 @@ func TestGetFeatureParseQueryParameters(t *testing.T) { } } +//nolint:nestif func compareGetFeatureQuery(result, expected GetFeatureRequest, tid int, t *testing.T) { if result.BaseRequest.Service != expected.BaseRequest.Service || result.BaseRequest.Version != expected.BaseRequest.Version { t.Errorf("test: %d, expected: %+v ,\n got: %+v", tid, expected.BaseRequest, result.BaseRequest) @@ -366,10 +369,8 @@ func compareGetFeatureQuery(result, expected GetFeatureRequest, tid int, t *test } if expected.Query.Filter != nil { - if expected.Query.SrsName != nil { - if *expected.Query.SrsName != *result.Query.SrsName { - t.Errorf("test: %d, expected: %+v ,\n got: %+v", tid, *expected.Query.SrsName, *result.Query.SrsName) - } + if expected.Query.SrsName != nil && *expected.Query.SrsName != *result.Query.SrsName { + t.Errorf("test: %d, expected: %+v ,\n got: %+v", tid, *expected.Query.SrsName, *result.Query.SrsName) } if expected.Query.Filter.ResourceID != nil { for _, erid := range *expected.Query.Filter.ResourceID { diff --git a/pkg/wms130/boundingbox_xml.go b/pkg/wms130/boundingbox_xml.go index 62d5570..aae5076 100644 --- a/pkg/wms130/boundingbox_xml.go +++ b/pkg/wms130/boundingbox_xml.go @@ -40,7 +40,7 @@ func (p *Position) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { func getPositionFromString(position string) []float64 { regex := regexp.MustCompile(` `) result := regex.Split(position, -1) - var ps []float64 //slice because length can be 2 or more + var ps []float64 // slice because length can be 2 or more // check if 'strings' are parsable to float64 // if one is not return nothing diff --git a/pkg/wms130/boundingbox_yaml.go b/pkg/wms130/boundingbox_yaml.go index e60b47e..91dee4f 100644 --- a/pkg/wms130/boundingbox_yaml.go +++ b/pkg/wms130/boundingbox_yaml.go @@ -6,9 +6,7 @@ import ( ) // UnmarshalYAML Position -// -//nolint:revive -func (p *Position) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (p *Position) UnmarshalYAML(unmarshal func(any) error) error { var s string if err := unmarshal(&s); err != nil { return err @@ -21,8 +19,6 @@ func (p *Position) UnmarshalYAML(unmarshal func(interface{}) error) error { } // MarshalYAML Position -// -//nolint:revive -func (p Position) MarshalYAML() (interface{}, error) { +func (p Position) MarshalYAML() (any, error) { return fmt.Sprintf("%s %s", strconv.FormatFloat(p[0], 'f', -1, 64), strconv.FormatFloat(p[1], 'f', -1, 64)), nil } diff --git a/pkg/wms130/boundingbox_yaml_test.go b/pkg/wms130/boundingbox_yaml_test.go index 8434698..9aed1ef 100644 --- a/pkg/wms130/boundingbox_yaml_test.go +++ b/pkg/wms130/boundingbox_yaml_test.go @@ -9,44 +9,40 @@ import ( func TestUnmarshalYAMLPosition(t *testing.T) { var tests = []struct { - positionstring []byte - expectedposition Position + positionString []byte + expectedPosition Position }{ - 0: {positionstring: []byte(`2.52712538742158 50.2128625669452`), expectedposition: Position{2.52712538742158, 50.2128625669452}}, - 1: {positionstring: []byte(`7.37402550506231 55.7211602557705`), expectedposition: Position{7.37402550506231, 55.7211602557705}}, - 2: {positionstring: []byte(`7.37402550506231 55.7211602557705 0 1 2 3`), expectedposition: Position{7.37402550506231, 55.7211602557705}}, + 0: {positionString: []byte(`2.52712538742158 50.2128625669452`), expectedPosition: Position{2.52712538742158, 50.2128625669452}}, + 1: {positionString: []byte(`7.37402550506231 55.7211602557705`), expectedPosition: Position{7.37402550506231, 55.7211602557705}}, + 2: {positionString: []byte(`7.37402550506231 55.7211602557705 0 1 2 3`), expectedPosition: Position{7.37402550506231, 55.7211602557705}}, } for k, test := range tests { var pos Position - err := yaml.Unmarshal(test.positionstring, &pos) + err := yaml.Unmarshal(test.positionString, &pos) if err != nil { t.Errorf("test: %d, yaml.UnMarshal failed with '%s'\n", k, err) - } else { - if pos != test.expectedposition { - t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedposition, pos) - } + } else if pos != test.expectedPosition { + t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedPosition, pos) } } } func TestMarshalYAMLPosition(t *testing.T) { var tests = []struct { - positionstring []byte + positionString []byte position Position }{ - 0: {positionstring: []byte("2.52712538742158 50.2128625669452\n"), position: Position{2.52712538742158, 50.2128625669452}}, - 1: {positionstring: []byte("7.37402550506231 55.7211602557705\n"), position: Position{7.37402550506231, 55.7211602557705}}, + 0: {positionString: []byte("2.52712538742158 50.2128625669452\n"), position: Position{2.52712538742158, 50.2128625669452}}, + 1: {positionString: []byte("7.37402550506231 55.7211602557705\n"), position: Position{7.37402550506231, 55.7211602557705}}, } for k, test := range tests { pos, err := yaml.Marshal(test.position) if err != nil { t.Errorf("test: %d, yaml.Marshal failed with '%s'\n", k, err) - } else { - if string(pos) != string(test.positionstring) { - t.Errorf("test: %d, expected: %s,\n got: %s", k, test.positionstring, pos) - } + } else if string(pos) != string(test.positionString) { + t.Errorf("test: %d, expected: %s,\n got: %s", k, test.positionString, pos) } } } diff --git a/pkg/wms130/capabilities.go b/pkg/wms130/capabilities.go index b500819..9a92354 100644 --- a/pkg/wms130/capabilities.go +++ b/pkg/wms130/capabilities.go @@ -66,7 +66,7 @@ type Layer struct { // layer has a full/complete map coverage Opaque *string `xml:"opaque,attr" yaml:"opaque,omitempty"` // no cascaded attr in Layer element, because we don't do cascaded services e.g. wms services "proxying" and/or combining other wms services - //Cascaded *string `xml:"cascaded,attr" yaml:"cascaded"` + // Cascaded *string `xml:"cascaded,attr" yaml:"cascaded"` Name *string `xml:"Name" yaml:"name,omitempty"` Title string `xml:"Title" yaml:"title"` Abstract *string `xml:"Abstract,omitempty" yaml:"abstract,omitempty"` @@ -178,7 +178,7 @@ func (l *Layer) findLayer(layername string) *Layer { } // GetLayer returns the Layer Capabilities from the Capabilities document. -// when the requested Layer is not found a exception is thrown. +// when the requested Layer is not found a Exception is thrown. func (c *Capabilities) GetLayer(layername string) (Layer, Exceptions) { var layer Layer diff --git a/pkg/wms130/capabilities_test.go b/pkg/wms130/capabilities_test.go index 204e3d5..b625573 100644 --- a/pkg/wms130/capabilities_test.go +++ b/pkg/wms130/capabilities_test.go @@ -2,30 +2,40 @@ package wms130 import ( "testing" + + "gopkg.in/yaml.v3" ) var capabilities = Capabilities{ WMSCapabilities: WMSCapabilities{ Layer: []Layer{ - {Name: sp(`depthOneLayerOne`), + {Name: new(`depthOneLayerOne`), Layer: []*Layer{ - {Name: sp(`depthTwoLayerThree`), Style: []*Style{{Name: `StyleOne`}, {Name: `StyleTwo`}}}, - {Name: sp(`depthTwoLayerFour`), + {Name: new(`depthTwoLayerThree`), Style: []*Style{{Name: `StyleOne`}, {Name: `StyleTwo`}}}, + {Name: new(`depthTwoLayerFour`), Layer: []*Layer{ - {Name: sp(`depthThreeLayerSix`)}, - {Name: sp(`depthThreeLayerSeven`), Style: []*Style{{Name: `StyleThree`}}}, + {Name: new(`depthThreeLayerSix`)}, + {Name: new(`depthThreeLayerSeven`), Style: []*Style{{Name: `StyleThree`}}}, }, }, }, }, - {Name: sp(`depthOneLayerTwo`), + {Name: new(`depthOneLayerTwo`), Layer: []*Layer{ - {Name: sp(`depthTwoLayerFive`), Style: []*Style{{Name: `StyleFour`}, {Name: `StyleFive`}}}}, + {Name: new(`depthTwoLayerFive`), Style: []*Style{{Name: `StyleFour`}, {Name: `StyleFive`}}}}, }, }, }, } +var capabilitiesWithException = Capabilities{ + WMSCapabilities: WMSCapabilities{ + Exception: ExceptionType{ + Format: []string{"XML"}, + }, + }, +} + func TestGetLayerNames(t *testing.T) { expected := []string{`depthOneLayerOne`, `depthOneLayerTwo`, `depthTwoLayerThree`, `depthTwoLayerFour`, `depthTwoLayerFive`, `depthThreeLayerSix`, `depthThreeLayerSeven`} @@ -63,26 +73,82 @@ func TestStyleDefined(t *testing.T) { func TestGetLayer(t *testing.T) { var tests = []struct { - layername string + layerName string exception Exceptions }{ - 0: {layername: `depthTwoLayerThree`}, - 1: {layername: `depthThreeLayerSeven`}, - 2: {layername: `unknownLayer`, exception: Exceptions{LayerNotDefined(`unknownLayer`)}}, + 0: {layerName: `depthTwoLayerThree`}, + 1: {layerName: `depthThreeLayerSeven`}, + 2: {layerName: `unknownLayer`, exception: Exceptions{LayerNotDefined(`unknownLayer`)}}, } for k, test := range tests { - layerfound, exception := capabilities.GetLayer(test.layername) + layerFound, exception := capabilities.GetLayer(test.layerName) if exception != nil { if test.exception != nil { if test.exception[0].Code() != exception[0].Code() { - t.Errorf("test: %d, expected: %s \ngot: %v", k, test.layername, capabilities.GetLayerNames()) + t.Errorf("test: %d, expected: %s \ngot: %v", k, test.layerName, capabilities.GetLayerNames()) } } } else { - if *layerfound.Name != test.layername { - t.Errorf("test: %d, expected: %s \ngot: %s", k, capabilities.GetLayerNames(), *layerfound.Name) + if *layerFound.Name != test.layerName { + t.Errorf("test: %d, expected: %s \ngot: %s", k, capabilities.GetLayerNames(), *layerFound.Name) } } } } + +func TestException(t *testing.T) { + + out, err := yaml.Marshal(capabilitiesWithException) + if err != nil { + t.Fatalf("marshal failed: %v", err) + } + + var got map[string]any + if err = yaml.Unmarshal(out, &got); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + wmsRaw, ok := got["wmsCapabilities"] + if !ok { + t.Fatalf("expected 'wmsCapabilities' key") + } + + wms, ok := wmsRaw.(map[string]any) + if !ok { + t.Fatalf("'wmsCapabilities' is not a map, got %T", wmsRaw) + } + + exceptionRaw, ok := wms["exception"] + if !ok { + t.Fatalf("expected 'exception' key to exist") + } + + exception, ok := exceptionRaw.(map[string]any) + if !ok { + t.Fatalf("'exception' is not a map, got %T", exceptionRaw) + } + + formatsRaw, ok := exception["format"] + if !ok { + t.Fatalf("expected 'format' key to exist") + } + + formats, ok := formatsRaw.([]any) + if !ok { + t.Fatalf("'format' is not a slice, got %T", formatsRaw) + } + + if len(formats) != 1 { + t.Fatalf("expected exactly 1 format, got %d", len(formats)) + } + + formatStr, ok := formats[0].(string) + if !ok { + t.Fatalf("format value is not string, got %T", formats[0]) + } + + if formatStr != "XML" { + t.Errorf("expected 'XML', got %s", formatStr) + } +} diff --git a/pkg/wms130/common.go b/pkg/wms130/common.go index 311980c..6bdeec3 100644 --- a/pkg/wms130/common.go +++ b/pkg/wms130/common.go @@ -56,6 +56,8 @@ func (b *BaseRequest) ParseQueryParameters(q url.Values) Exceptions { } // parseBaseParameterValueRequest builds a BaseRequest struct +// +//nolint:unparam func (b *BaseRequest) parseBaseParameterValueRequest(bpv baseParameterValueRequest) Exceptions { // Service is optional, because it's implicit for a GetMap/GetFeatureInfo request b.Service = Service diff --git a/pkg/wms130/crs.go b/pkg/wms130/crs.go index 3ba9d46..3071593 100644 --- a/pkg/wms130/crs.go +++ b/pkg/wms130/crs.go @@ -16,7 +16,7 @@ const ( // CRS struct with namespace/authority/registry and code type CRS struct { - Namespace string //TODO maybe AuthorityType is a better name...? + Namespace string // TODO maybe AuthorityType is a better name...? Code int } diff --git a/pkg/wms130/crs_test.go b/pkg/wms130/crs_test.go index d664c93..19ff4bb 100644 --- a/pkg/wms130/crs_test.go +++ b/pkg/wms130/crs_test.go @@ -31,10 +31,8 @@ othercrs: err := yaml.Unmarshal(test.yaml, &ftl) if err != nil { t.Errorf("test: %d, yaml.UnMarshal failed with '%s'\n", k, err) - } else { - if ftl.DefaultCRS.Code != test.expectedCrs.Code || ftl.DefaultCRS.Namespace != test.expectedCrs.Namespace { - t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedCrs, ftl.DefaultCRS) - } + } else if ftl.DefaultCRS.Code != test.expectedCrs.Code || ftl.DefaultCRS.Namespace != test.expectedCrs.Namespace { + t.Errorf("test: %d, expected: %v+,\n got: %v+", k, test.expectedCrs, ftl.DefaultCRS) } } } diff --git a/pkg/wms130/crs_yaml.go b/pkg/wms130/crs_yaml.go index a16b6b6..b8e2c10 100644 --- a/pkg/wms130/crs_yaml.go +++ b/pkg/wms130/crs_yaml.go @@ -1,9 +1,7 @@ package wms130 // UnmarshalYAML CRS -// -//nolint:revive -func (c *CRS) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (c *CRS) UnmarshalYAML(unmarshal func(any) error) error { var s string if err := unmarshal(&s); err != nil { return err @@ -17,7 +15,6 @@ func (c *CRS) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } -//nolint:revive -func (c CRS) MarshalYAML() (interface{}, error) { +func (c CRS) MarshalYAML() (any, error) { return c.String(), nil } diff --git a/pkg/wms130/exception.go b/pkg/wms130/exception.go index 04f4655..9524c2f 100644 --- a/pkg/wms130/exception.go +++ b/pkg/wms130/exception.go @@ -2,16 +2,19 @@ package wms130 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/common" ) -// exception -type exception struct { +// Exception +// +//nolint:errname +type Exception struct { common.ExceptionDetails } -// Exceptions is a array of the Exception interface -type Exceptions []exception +// Exceptions is an array of the Exception interface +type Exceptions []Exception // ServiceExceptionReport struct type ServiceExceptionReport struct { @@ -24,6 +27,8 @@ type ServiceExceptionReport struct { } // ToReport builds a ServiceExceptionReport from an array of Exceptions +// +//nolint:goconst func (e Exceptions) ToReport() ServiceExceptionReport { r := ServiceExceptionReport{} r.SchemaLocation = `http://www.opengis.net/ogc http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd` @@ -40,22 +45,22 @@ func (r ServiceExceptionReport) ToBytes() []byte { return append([]byte(xml.Header), si...) } -// ToExceptions promotes a single exception to an array of one -func (e exception) ToExceptions() Exceptions { +// ToExceptions promotes a single Exception to an array of one +func (e Exception) ToExceptions() Exceptions { return Exceptions{e} } // Error returns available ExceptionText -func (e exception) Error() string { +func (e Exception) Error() string { return e.ExceptionText } // Code returns available ExceptionCode -func (e exception) Code() string { +func (e Exception) Code() string { return e.ExceptionCode } // Locator returns available ExceptionCode -func (e exception) Locator() string { +func (e Exception) Locator() string { return e.LocatorCode } diff --git a/pkg/wms130/exception_codes.go b/pkg/wms130/exception_codes.go index 23bfdb6..4d472ef 100644 --- a/pkg/wms130/exception_codes.go +++ b/pkg/wms130/exception_codes.go @@ -2,152 +2,160 @@ package wms130 import ( "fmt" + "github.com/pdok/ogc-specifications/pkg/common" ) -// InvalidFormat exception -func InvalidFormat(unknownformat string) exception { - return exception{ExceptionDetails: common.ExceptionDetails{ - ExceptionText: fmt.Sprintf("The format: %s, is a invalid image format", unknownformat), +// InvalidFormat Exception +func InvalidFormat(unknownFormat string) Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ + ExceptionText: fmt.Sprintf("The format: %s, is a invalid image format", unknownFormat), ExceptionCode: `InvalidFormat`, }} } -// InvalidCRS exception -func InvalidCRS(s ...string) exception { +// InvalidCRS Exception +// +//nolint:goconst +func InvalidCRS(s ...string) Exception { if len(s) == 1 { - return exception{ExceptionDetails: common.ExceptionDetails{ - ExceptionText: fmt.Sprintf("CRS is not known by this service: %s", s[0]), + return Exception{ExceptionDetails: common.ExceptionDetails{ + ExceptionText: "CRS is not known by this service: " + s[0], ExceptionCode: `InvalidCRS`, }} } if len(s) == 2 { - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The CRS: %s is not known by the layer: %s", s[0], s[1]), ExceptionCode: `InvalidCRS`, }} } - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidCRS`, }} } -// LayerNotDefined exception -func LayerNotDefined(s ...string) exception { +// LayerNotDefined Exception +// +//nolint:goconst +func LayerNotDefined(s ...string) Exception { if len(s) == 1 { - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The layer: %s is not known by the server", s[0]), ExceptionCode: `LayerNotDefined`, }} } - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `LayerNotDefined`, }} } -// StyleNotDefined exception -func StyleNotDefined(s ...string) exception { +// StyleNotDefined Exception +// +//nolint:goconst +func StyleNotDefined(s ...string) Exception { if len(s) == 2 { - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The style: %s is not known by the server for the layer: %s", s[0], s[1]), ExceptionCode: `StyleNotDefined`, }} } - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: `There is a one-to-one correspondence between the values in the LAYERS parameter and the values in the STYLES parameter. Expecting an empty string for the STYLES like STYLES= or comma-separated list STYLES=,,, or using keyword default STYLES=default,default,...`, ExceptionCode: `StyleNotDefined`, }} } -// LayerNotQueryable exception -func LayerNotQueryable(s ...string) exception { +// LayerNotQueryable Exception +// +//nolint:goconst +func LayerNotQueryable(s ...string) Exception { if len(s) == 1 { - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("Layer: %s, can not be queried", s[0]), ExceptionCode: `LayerNotQueryable`, LocatorCode: s[0], }} } - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `LayerNotQueryable`, }} } -// InvalidPoint exception -// i and j are strings so we can return none integer values in the exception -func InvalidPoint(i, j string) exception { +// InvalidPoint Exception +// i and j are strings so we can return none integer values in the Exception +func InvalidPoint(i, j string) Exception { // TODO provide giving WIDTH and HEIGHT values in Exception response - return exception{ExceptionDetails: common.ExceptionDetails{ + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("The parameters I and J are invalid, given: %s for I and %s for J", i, j), ExceptionCode: `InvalidPoint`, }} } -// CurrentUpdateSequence exception -func CurrentUpdateSequence() exception { - return exception{ExceptionDetails: common.ExceptionDetails{ +// CurrentUpdateSequence Exception +func CurrentUpdateSequence() Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `CurrentUpdateSequence`, }} } -// InvalidUpdateSequence exception -func InvalidUpdateSequence() exception { - return exception{ExceptionDetails: common.ExceptionDetails{ +// InvalidUpdateSequence Exception +func InvalidUpdateSequence() Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidUpdateSequence`, }} } -// MissingDimensionValue exception -func MissingDimensionValue() exception { - return exception{ExceptionDetails: common.ExceptionDetails{ +// MissingDimensionValue Exception +func MissingDimensionValue() Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `MissingDimensionValue`, }} } -// InvalidDimensionValue exception -func InvalidDimensionValue() exception { - return exception{ExceptionDetails: common.ExceptionDetails{ +// InvalidDimensionValue Exception +func InvalidDimensionValue() Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionCode: `InvalidDimensionValue`, }} } -//////////////// -//////////////// - -// MissingParameterValue exception -func MissingParameterValue(s ...string) exception { +// MissingParameterValue Exception +// +//nolint:goconst +func MissingParameterValue(s ...string) Exception { if len(s) >= 2 { - return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} + return Exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } if len(s) == 1 { - return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} + return Exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: "Missing key: " + s[0], ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } - return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}} + return Exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}} } -// InvalidParameterValue exception -func InvalidParameterValue(value, locator string) exception { - return exception{ExceptionDetails: common.ExceptionDetails{ +// InvalidParameterValue Exception +func InvalidParameterValue(value, locator string) Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: fmt.Sprintf("%s contains a invalid value: %s", locator, value), LocatorCode: value, ExceptionCode: `InvalidParameterValue`, }} } -// NoApplicableCode exception -func NoApplicableCode(message string) exception { - return exception{ExceptionDetails: common.ExceptionDetails{ +// NoApplicableCode Exception +func NoApplicableCode(message string) Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ ExceptionText: message, ExceptionCode: `NoApplicableCode`, }} } -// OperationNotSupported exception -func OperationNotSupported(message string) exception { - return exception{ExceptionDetails: common.ExceptionDetails{ - ExceptionText: fmt.Sprintf("This service does not know the operation: %s", message), +// OperationNotSupported Exception +func OperationNotSupported(message string) Exception { + return Exception{ExceptionDetails: common.ExceptionDetails{ + ExceptionText: "This service does not know the operation: " + message, ExceptionCode: `OperationNotSupported`, LocatorCode: message, }} diff --git a/pkg/wms130/exception_test.go b/pkg/wms130/exception_test.go index d35a322..3359c42 100644 --- a/pkg/wms130/exception_test.go +++ b/pkg/wms130/exception_test.go @@ -1,18 +1,19 @@ package wms130 import ( - "github.com/pdok/ogc-specifications/pkg/common" "testing" + + "github.com/pdok/ogc-specifications/pkg/common" ) func TestWFSException(t *testing.T) { var tests = []struct { - exception exception + exception Exception exceptionText string exceptionCode string locatorCode string }{ - 0: {exception: exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}, + 0: {exception: Exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}, exceptionText: "", exceptionCode: "", locatorCode: "", @@ -80,7 +81,7 @@ func TestReport(t *testing.T) { result []byte err error }{ - 0: {exceptions: Exceptions{exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}}, + 0: {exceptions: Exceptions{Exception{ExceptionDetails: common.ExceptionDetails{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}}}, result: []byte(` diff --git a/pkg/wms130/getcapabilities_request.go b/pkg/wms130/getcapabilities_request.go index b5ea330..29d92fb 100644 --- a/pkg/wms130/getcapabilities_request.go +++ b/pkg/wms130/getcapabilities_request.go @@ -16,7 +16,7 @@ type GetCapabilitiesRequest struct { } // Validate returns GetCapabilities -func (g *GetCapabilitiesRequest) Validate(c Capabilities) Exceptions { +func (g *GetCapabilitiesRequest) Validate(_ Capabilities) Exceptions { var exceptions Exceptions return exceptions } @@ -57,15 +57,17 @@ func (g *GetCapabilitiesRequest) ParseQueryParameters(query url.Values) Exceptio return exception } - if exception := g.parsegetCapabilitiesRequestParameterValue(gpv); exception != nil { + if exception := g.parseGetCapabilitiesRequestParameterValue(gpv); exception != nil { return exception } return nil } -// parsegetCapabilitiesRequestParameterValue process the simple struct to a complex struct -func (g *GetCapabilitiesRequest) parsegetCapabilitiesRequestParameterValue(gpv getCapabilitiesRequestParameterValue) Exceptions { +// parseGetCapabilitiesRequestParameterValue process the simple struct to a complex struct +// +//nolint:staticcheck +func (g *GetCapabilitiesRequest) parseGetCapabilitiesRequestParameterValue(gpv getCapabilitiesRequestParameterValue) Exceptions { g.XMLName.Local = gpv.request g.BaseRequest.parseBaseParameterValueRequest(gpv.baseParameterValueRequest) diff --git a/pkg/wms130/getcapabilities_request_pv.go b/pkg/wms130/getcapabilities_request_pv.go index 6741409..6166bbd 100644 --- a/pkg/wms130/getcapabilities_request_pv.go +++ b/pkg/wms130/getcapabilities_request_pv.go @@ -5,7 +5,7 @@ import ( "strings" ) -//getCapabilitiesRequestParameterValue struct +// getCapabilitiesRequestParameterValue struct type getCapabilitiesRequestParameterValue struct { // Table 8 - The Parameters of a GetMap request service string `yaml:"service,omitempty"` @@ -13,6 +13,8 @@ type getCapabilitiesRequestParameterValue struct { } // ParseQueryParameters builds a GetCapabilities object based on the available query parameters +// +//nolint:staticcheck func (gpv *getCapabilitiesRequestParameterValue) parseQueryParameters(query url.Values) Exceptions { var exceptions Exceptions for k, v := range query { @@ -40,14 +42,14 @@ func (gpv *getCapabilitiesRequestParameterValue) parseQueryParameters(query url. // ParseOperationRequest builds a getCapabilitiesRequestParameterValue object based on a GetCapabilities struct // This is a 'dummy' implementation, because for a GetCapabilities request it will always be // Mandatory: REQUEST=GetCapabilities -// SERVICE=WMS +// +// SERVICE=WMS +// // Optional: VERSION=1.3.0 -func (gpv *getCapabilitiesRequestParameterValue) parseGetCapabilitiesRequest(g GetCapabilitiesRequest) Exceptions { +func (gpv *getCapabilitiesRequestParameterValue) parseGetCapabilitiesRequest(g GetCapabilitiesRequest) { gpv.request = getcapabilities gpv.version = g.Version gpv.service = g.Service - - return nil } // toQueryParameters builds a url.Values query from a getCapabilitiesRequestParameterValue struct diff --git a/pkg/wms130/getcapabilities_test.go b/pkg/wms130/getcapabilities_test.go index fef6c71..fd164a2 100644 --- a/pkg/wms130/getcapabilities_test.go +++ b/pkg/wms130/getcapabilities_test.go @@ -6,6 +6,7 @@ import ( "testing" ) +//nolint:nestif func TestGetCapabilitiesParseXML(t *testing.T) { var tests = []struct { body []byte @@ -59,6 +60,7 @@ func TestGetCapabilitiesParseXML(t *testing.T) { } } +//nolint:nestif func TestGetCapabilitiesParseQueryParameters(t *testing.T) { var tests = []struct { query url.Values @@ -95,7 +97,7 @@ func TestGetCapabilitiesParseQueryParameters(t *testing.T) { } } if !found { - t.Errorf("test exception: %d, expected one of: %s ,\n got: %s", k, test.exceptions, exception.Error()) + t.Errorf("test Exception: %d, expected one of: %s ,\n got: %s", k, test.exceptions, exception.Error()) } } } else { diff --git a/pkg/wms130/getfeatureinfo_request.go b/pkg/wms130/getfeatureinfo_request.go index 3631688..fb23394 100644 --- a/pkg/wms130/getfeatureinfo_request.go +++ b/pkg/wms130/getfeatureinfo_request.go @@ -30,7 +30,7 @@ type GetFeatureInfoRequest struct { // // These are the 'minimum' required GetMap parameters // needed in a GetFeatureInfo request - StyledLayerDescriptor StyledLayerDescriptor `xml:"StyledLayerDescriptor" yaml:"styledLayerDescriptor"` //TODO layers is need styles is not! + StyledLayerDescriptor StyledLayerDescriptor `xml:"StyledLayerDescriptor" yaml:"styledLayerDescriptor"` // TODO layers is need styles is not! CRS string `xml:"CRS" yaml:"crs"` BoundingBox BoundingBox `xml:"BoundingBox" yaml:"boundingBox"` // We skip the Output struct, because these are not required parameters @@ -48,11 +48,11 @@ type GetFeatureInfoRequest struct { } // Validate returns GetFeatureInfo -func (i *GetFeatureInfoRequest) Validate(c Capabilities) Exceptions { +func (gfi *GetFeatureInfoRequest) Validate(c Capabilities) Exceptions { var exceptions Exceptions - exceptions = append(exceptions, i.StyledLayerDescriptor.Validate(c)...) - // exceptions = append(exceptions, i.Output.Validate(wmsCapabilities)...) + exceptions = append(exceptions, gfi.StyledLayerDescriptor.Validate(c)...) + // exceptions = append(exceptions, gfi.Output.Validate(wmsCapabilities)...) return exceptions } @@ -61,16 +61,16 @@ func (i *GetFeatureInfoRequest) Validate(c Capabilities) Exceptions { // Note: the XML GetFeatureInfo body that is consumed is a interpretation. // So we use the GetMap, that is a large part of this request, as a base // with the additional GetFeatureInfo parameters. -func (i *GetFeatureInfoRequest) ParseXML(body []byte) Exceptions { - var xmlattributes utils.XMLAttribute - if err := xml.Unmarshal(body, &xmlattributes); err != nil { +func (gfi *GetFeatureInfoRequest) ParseXML(body []byte) Exceptions { + var xmlAttributes utils.XMLAttribute + if err := xml.Unmarshal(body, &xmlAttributes); err != nil { return Exceptions{MissingParameterValue()} } - if err := xml.Unmarshal(body, &i); err != nil { + if err := xml.Unmarshal(body, &gfi); err != nil { return Exceptions{MissingParameterValue("REQUEST")} } var n []xml.Attr - for _, a := range xmlattributes { + for _, a := range xmlAttributes { switch strings.ToUpper(a.Name.Local) { case VERSION: case SERVICE: @@ -79,53 +79,55 @@ func (i *GetFeatureInfoRequest) ParseXML(body []byte) Exceptions { } } - i.Attr = utils.StripDuplicateAttr(n) + gfi.Attr = utils.StripDuplicateAttr(n) return nil } -// parsegetFeatureInfoRequestParameterValue process the simple struct to a complex struct -func (i *GetFeatureInfoRequest) parsegetFeatureInfoRequestParameterValue(ipv getFeatureInfoRequestParameterValue) Exceptions { +// parseGetFeatureInfoRequestParameterValue process the simple struct to a complex struct +// +//nolint:staticcheck +func (gfi *GetFeatureInfoRequest) parseGetFeatureInfoRequestParameterValue(ipv getFeatureInfoRequestParameterValue) Exceptions { var exceptions Exceptions - i.XMLName.Local = getfeatureinfo - i.BaseRequest.parseBaseParameterValueRequest(ipv.baseParameterValueRequest) + gfi.XMLName.Local = getfeatureinfo + gfi.BaseRequest.parseBaseParameterValueRequest(ipv.baseParameterValueRequest) sld, ex := ipv.buildStyledLayerDescriptor() if ex != nil { exceptions = append(exceptions, ex...) } - i.StyledLayerDescriptor = sld + gfi.StyledLayerDescriptor = sld - i.CRS = ipv.crs + gfi.CRS = ipv.crs var bbox BoundingBox if ex := bbox.parseString(ipv.bbox); ex != nil { exceptions = append(exceptions, ex...) } - i.BoundingBox = bbox + gfi.BoundingBox = bbox - i.CRS = ipv.crs + gfi.CRS = ipv.crs w, err := strconv.Atoi(ipv.width) if err != nil { exceptions = append(exceptions, Exceptions{MissingParameterValue(WIDTH, ipv.width)}...) } - i.Size.Width = w + gfi.Size.Width = w h, err := strconv.Atoi(ipv.height) if err != nil { exceptions = append(exceptions, Exceptions{MissingParameterValue(HEIGHT, ipv.height)}...) } - i.Size.Height = h + gfi.Size.Height = h - i.QueryLayers = strings.Split(ipv.querylayers, ",") + gfi.QueryLayers = strings.Split(ipv.querylayers, ",") - if exps := i.parseIJ(ipv.i, ipv.j); exps != nil { + if exps := gfi.parseIJ(ipv.i, ipv.j); exps != nil { exceptions = append(exceptions, exps...) } - i.InfoFormat = ipv.infoformat + gfi.InfoFormat = ipv.infoformat // Optional keys if ipv.featurecount != nil { @@ -134,11 +136,11 @@ func (i *GetFeatureInfoRequest) parsegetFeatureInfoRequestParameterValue(ipv get exceptions = append(exceptions, NoApplicableCode("Unknown FEATURE_COUNT value")) } - i.FeatureCount = &fc + gfi.FeatureCount = &fc } if ipv.exceptions != nil { - i.Exceptions = ipv.exceptions + gfi.Exceptions = ipv.exceptions } if len(exceptions) > 0 { @@ -148,7 +150,7 @@ func (i *GetFeatureInfoRequest) parsegetFeatureInfoRequestParameterValue(ipv get } // ParseQueryParameters builds a GetFeatureInfo object based on the available query parameters -func (i *GetFeatureInfoRequest) ParseQueryParameters(query url.Values) Exceptions { +func (gfi *GetFeatureInfoRequest) ParseQueryParameters(query url.Values) Exceptions { if len(query) == 0 { // When there are no query value we know that at least // the manadorty VERSION and REQUEST parameter is missing. @@ -160,7 +162,7 @@ func (i *GetFeatureInfoRequest) ParseQueryParameters(query url.Values) Exception return exceptions } - if exceptions := i.parsegetFeatureInfoRequestParameterValue(ipv); len(exceptions) != 0 { + if exceptions := gfi.parseGetFeatureInfoRequestParameterValue(ipv); len(exceptions) != 0 { return exceptions } @@ -168,9 +170,9 @@ func (i *GetFeatureInfoRequest) ParseQueryParameters(query url.Values) Exception } // ToQueryParameters builds a new query string that will be proxied -func (i GetFeatureInfoRequest) ToQueryParameters() url.Values { +func (gfi *GetFeatureInfoRequest) ToQueryParameters() url.Values { ipv := getFeatureInfoRequestParameterValue{} - ipv.parseGetFeatureInfoRequest(i) + ipv.parseGetFeatureInfoRequest(*gfi) q := ipv.toQueryParameters() return q @@ -180,24 +182,24 @@ func (i GetFeatureInfoRequest) ToQueryParameters() url.Values { // Note: this GetFeatureInfo XML body is a interpretation and there isn't a // good/real OGC example request. So for now we use the GetMap, that is a large part // of this request, as a base with the additional GetFeatureInfo parameters. -func (i GetFeatureInfoRequest) ToXML() []byte { - si, _ := xml.MarshalIndent(i, "", " ") +func (gfi *GetFeatureInfoRequest) ToXML() []byte { + si, _ := xml.MarshalIndent(gfi, "", " ") re := regexp.MustCompile(`><.*>`) return []byte(xml.Header + re.ReplaceAllString(string(si), "/>")) } -func (i *GetFeatureInfoRequest) parseIJ(I, J string) Exceptions { - ii, err := strconv.Atoi(I) +func (gfi *GetFeatureInfoRequest) parseIJ(i string, j string) Exceptions { + ii, err := strconv.Atoi(i) if err != nil { - return InvalidPoint(I, J).ToExceptions() + return InvalidPoint(i, j).ToExceptions() } - i.I = ii + gfi.I = ii - j, err := strconv.Atoi(J) + jj, err := strconv.Atoi(j) if err != nil { - return InvalidPoint(I, J).ToExceptions() + return InvalidPoint(i, j).ToExceptions() } - i.J = j + gfi.J = jj return nil } diff --git a/pkg/wms130/getfeatureinfo_request_pv.go b/pkg/wms130/getfeatureinfo_request_pv.go index 11de5ae..81f468a 100644 --- a/pkg/wms130/getfeatureinfo_request_pv.go +++ b/pkg/wms130/getfeatureinfo_request_pv.go @@ -17,46 +17,47 @@ type getFeatureInfoRequestParameterValue struct { } // parseQueryParameters builds a getFeatureInfoRequestParameterValue object based on the available query parameters -func (ipv *getFeatureInfoRequestParameterValue) parseQueryParameters(query url.Values) Exceptions { - var exceptions Exceptions +// +//nolint:cyclop,staticcheck,goconst +func (ipv *getFeatureInfoRequestParameterValue) parseQueryParameters(query url.Values) (exceptions Exceptions) { for k, v := range query { if len(v) != 1 { exceptions = append(exceptions, InvalidParameterValue(k, strings.Join(v, ","))) - } else { - switch strings.ToUpper(k) { - case SERVICE: - ipv.service = strings.ToUpper(v[0]) - case VERSION: - ipv.baseParameterValueRequest.version = v[0] - case REQUEST: - ipv.baseParameterValueRequest.request = v[0] - case LAYERS: - ipv.getMapParameterValueMandatory.layers = v[0] - case STYLES: - ipv.getMapParameterValueMandatory.styles = v[0] - case "CRS": - ipv.getMapParameterValueMandatory.crs = v[0] - case BBOX: - ipv.getMapParameterValueMandatory.bbox = v[0] - case WIDTH: - ipv.getMapParameterValueMandatory.width = v[0] - case HEIGHT: - ipv.getMapParameterValueMandatory.height = v[0] - case FORMAT: - ipv.getMapParameterValueMandatory.format = v[0] - case QUERYLAYERS: - ipv.getFeatureInfoParameterValueMandatory.querylayers = v[0] - case INFOFORMAT: - ipv.getFeatureInfoParameterValueMandatory.infoformat = v[0] - case I: - ipv.getFeatureInfoParameterValueMandatory.i = v[0] - case J: - ipv.getFeatureInfoParameterValueMandatory.j = v[0] - case FEATURECOUNT: - ipv.getFeatureInfoParameterValueOptional.featurecount = &(v[0]) - case EXCEPTIONS: - ipv.getFeatureInfoParameterValueOptional.exceptions = &(v[0]) - } + continue + } + switch strings.ToUpper(k) { + case SERVICE: + ipv.service = strings.ToUpper(v[0]) + case VERSION: + ipv.baseParameterValueRequest.version = v[0] + case REQUEST: + ipv.baseParameterValueRequest.request = v[0] + case LAYERS: + ipv.getMapParameterValueMandatory.layers = v[0] + case STYLES: + ipv.getMapParameterValueMandatory.styles = v[0] + case "CRS": + ipv.getMapParameterValueMandatory.crs = v[0] + case BBOX: + ipv.getMapParameterValueMandatory.bbox = v[0] + case WIDTH: + ipv.getMapParameterValueMandatory.width = v[0] + case HEIGHT: + ipv.getMapParameterValueMandatory.height = v[0] + case FORMAT: + ipv.getMapParameterValueMandatory.format = v[0] + case QUERYLAYERS: + ipv.getFeatureInfoParameterValueMandatory.querylayers = v[0] + case INFOFORMAT: + ipv.getFeatureInfoParameterValueMandatory.infoformat = v[0] + case I: + ipv.getFeatureInfoParameterValueMandatory.i = v[0] + case J: + ipv.getFeatureInfoParameterValueMandatory.j = v[0] + case FEATURECOUNT: + ipv.getFeatureInfoParameterValueOptional.featurecount = &(v[0]) + case EXCEPTIONS: + ipv.getFeatureInfoParameterValueOptional.exceptions = &(v[0]) } } @@ -101,7 +102,7 @@ func (ipv getFeatureInfoRequestParameterValue) toQueryParameters() url.Values { } // parseGetFeatureInfoRequest builds a getFeatureInfoRequestParameterValue object based on a GetFeatureInfoRequest struct -func (ipv *getFeatureInfoRequestParameterValue) parseGetFeatureInfoRequest(i GetFeatureInfoRequest) Exceptions { +func (ipv *getFeatureInfoRequestParameterValue) parseGetFeatureInfoRequest(i GetFeatureInfoRequest) { ipv.request = getfeatureinfo ipv.version = Version @@ -126,8 +127,6 @@ func (ipv *getFeatureInfoRequestParameterValue) parseGetFeatureInfoRequest(i Get } ipv.exceptions = i.Exceptions - - return nil } // GetFeatureInfoParameterValueMandatory struct containing the mandatory WMS request Parameter Value diff --git a/pkg/wms130/getfeatureinfo_test.go b/pkg/wms130/getfeatureinfo_test.go index f3c9ecf..db37118 100644 --- a/pkg/wms130/getfeatureinfo_test.go +++ b/pkg/wms130/getfeatureinfo_test.go @@ -2,6 +2,7 @@ package wms130 import ( "encoding/xml" + "errors" "net/url" "strings" "testing" @@ -148,8 +149,8 @@ func TestGetFeatureInfoToXML(t *testing.T) { for k, test := range tests { body := test.gfi.ToXML() - x := strings.Replace(string(body), "\n", ``, -1) - y := strings.Replace(test.result, "\n", ``, -1) + x := strings.ReplaceAll(string(body), "\n", ``) + y := strings.ReplaceAll(test.result, "\n", ``) if x != y { t.Errorf("test: %d, Expected body: \n%s\nbut was not got: \n%s", k, y, x) @@ -157,6 +158,7 @@ func TestGetFeatureInfoToXML(t *testing.T) { } } +//nolint:nestif func TestGetFeatureInfoParseQueryParameters(t *testing.T) { var tests = []struct { query url.Values @@ -233,8 +235,8 @@ func TestGetFeatureInfoParseQueryParameters(t *testing.T) { } else { for _, exception := range exceptions { found := false - for _, testexception := range test.exceptions { - if testexception == exception { + for _, testException := range test.exceptions { + if errors.Is(testException, exception) { found = true } } diff --git a/pkg/wms130/getmap_request.go b/pkg/wms130/getmap_request.go index a8326a9..5096fa5 100644 --- a/pkg/wms130/getmap_request.go +++ b/pkg/wms130/getmap_request.go @@ -80,6 +80,8 @@ func (m *GetMapRequest) ParseQueryParameters(query url.Values) Exceptions { } // parsegetMapRequestParameterValue process the simple struct to a complex struct +// +//nolint:staticcheck func (m *GetMapRequest) parsegetMapRequestParameterValue(mpv getMapRequestParameterValue) Exceptions { m.XMLName.Local = getmap m.BaseRequest.parseBaseParameterValueRequest(mpv.baseParameterValueRequest) @@ -112,12 +114,16 @@ func (m *GetMapRequest) parsegetMapRequestParameterValue(mpv getMapRequestParame } // ParseXML builds a GetMap object based on a XML document +// +//nolint:staticcheck func (m *GetMapRequest) ParseXML(body []byte) Exceptions { var xmlattributes utils.XMLAttribute if err := xml.Unmarshal(body, &xmlattributes); err != nil { return Exceptions{MissingParameterValue()} } - xml.Unmarshal(body, &m) //When object can be Unmarshalled -> XMLAttributes, it can be Unmarshalled -> GetMap + // When object can be Unmarshalled -> XMLAttributes, it can be Unmarshalled -> GetMap + _ = xml.Unmarshal(body, &m) + var n []xml.Attr for _, a := range xmlattributes { switch strings.ToUpper(a.Name.Local) { @@ -163,7 +169,7 @@ func (output *Output) Validate(c Capabilities) Exceptions { exceptions = append(exceptions, NoApplicableCode(fmt.Sprintf("Image size out of range, HEIGHT must be between 1 and %d pixels", c.MaxHeight))) } - for _, format := range c.WMSCapabilities.Request.GetMap.Format { + for _, format := range c.Request.GetMap.Format { found := false if format == output.Format { found = true @@ -296,6 +302,7 @@ type Elevation struct { } `xml:"Interval" yaml:"interval"` } +//nolint:goconst func buildStyledLayerDescriptor(layers, styles []string) (StyledLayerDescriptor, Exceptions) { // Because the LAYERS & STYLES parameters are intertwined we process as follows: // 1. cnt(STYLE) == 0 -> Added LAYERS @@ -307,29 +314,29 @@ func buildStyledLayerDescriptor(layers, styles []string) (StyledLayerDescriptor, // That is because POST xml and GET Parameter Value request handle this 'different' (at least not in the same way...) // When 3 is hit the validation at the Validation step wil resolve this + switch { // 1. - if len(styles) == 0 { + case len(styles) == 0: var sld StyledLayerDescriptor for _, layer := range layers { sld.NamedLayer = append(sld.NamedLayer, NamedLayer{Name: layer}) } sld.Version = "1.1.0" return sld, nil - // 2. - } else if len(layers) == 0 { + // 2. + case len(layers) == 0: // do nothing // will be resolved during validation - - // 3. - } else if len(layers) == len(styles) { + // 3. + case len(layers) == len(styles): var sld StyledLayerDescriptor for k, layer := range layers { sld.NamedLayer = append(sld.NamedLayer, NamedLayer{Name: layer, NamedStyle: &NamedStyle{Name: styles[k]}}) } sld.Version = "1.1.0" return sld, nil - // 4. - } else if len(layers) != len(styles) { + // 4. + case len(layers) != len(styles): return StyledLayerDescriptor{}, StyleNotDefined().ToExceptions() } diff --git a/pkg/wms130/getmap_request_pv.go b/pkg/wms130/getmap_request_pv.go index ef9d71b..0dd8379 100644 --- a/pkg/wms130/getmap_request_pv.go +++ b/pkg/wms130/getmap_request_pv.go @@ -6,7 +6,7 @@ import ( "strings" ) -//getMapRequestParameterValue struct +// getMapRequestParameterValue struct type getMapRequestParameterValue struct { // Table 8 - The Parameters of a GetMap request service string `yaml:"service,omitempty"` @@ -16,6 +16,8 @@ type getMapRequestParameterValue struct { } // parseQueryParameters builds a getMapRequestParameterValue object based on the available query parameters +// +//nolint:cyclop,staticcheck,goconst func (mpv *getMapRequestParameterValue) parseQueryParameters(query url.Values) Exceptions { var exceptions Exceptions params := make(map[string]bool) @@ -47,11 +49,11 @@ func (mpv *getMapRequestParameterValue) parseQueryParameters(query url.Values) E case FORMAT: mpv.getMapParameterValueMandatory.format = v[0] case TRANSPARENT: - mpv.getMapParameterValueOptional.transparent = &(v[0]) + mpv.transparent = &(v[0]) case BGCOLOR: - mpv.getMapParameterValueOptional.bgcolor = &(v[0]) + mpv.bgcolor = &(v[0]) case EXCEPTIONS: - mpv.getMapParameterValueOptional.exceptions = &(v[0]) + mpv.exceptions = &(v[0]) } } } @@ -89,7 +91,7 @@ func (mpv *getMapRequestParameterValue) parseQueryParameters(query url.Values) E } // parseGetMapRequest builds a getMapRequestParameterValue object based on a GetMap struct -func (mpv *getMapRequestParameterValue) parseGetMapRequest(m GetMapRequest) Exceptions { +func (mpv *getMapRequestParameterValue) parseGetMapRequest(m GetMapRequest) { mpv.request = getmap mpv.version = Version @@ -117,8 +119,6 @@ func (mpv *getMapRequestParameterValue) parseGetMapRequest(m GetMapRequest) Exce // mpv.Elevation = m.Elevation mpv.exceptions = m.Exceptions - - return nil } // BuildOutput builds a Output struct from the getMapRequestParameterValue information @@ -137,7 +137,7 @@ func (mpv *getMapRequestParameterValue) buildOutput() (Output, Exceptions) { output.Size = Size{Height: h, Width: w} output.Format = mpv.format if mpv.transparent != nil { - b, err := strconv.ParseBool(*mpv.transparent); + b, err := strconv.ParseBool(*mpv.transparent) if err != nil { return output, InvalidParameterValue(*mpv.transparent, TRANSPARENT).ToExceptions() } diff --git a/pkg/wms130/getmap_test.go b/pkg/wms130/getmap_test.go index a7e290e..97f03ae 100644 --- a/pkg/wms130/getmap_test.go +++ b/pkg/wms130/getmap_test.go @@ -87,7 +87,7 @@ func TestValidateStyledLayerDescriptor(t *testing.T) { } } if !found { - t.Errorf("test exception: %d, expected one of: %s ,\n got: %s", k, test.exceptions, exception.Error()) + t.Errorf("test Exception: %d, expected one of: %s ,\n got: %s", k, test.exceptions, exception.Error()) } } } @@ -98,7 +98,7 @@ func TestGetMapParseXML(t *testing.T) { var tests = []struct { body []byte excepted GetMapRequest - exception exception + exception Exception }{ // GetMap http://schemas.opengis.net/sld/1.1.0/example_getmap.xml example request 0: {body: []byte(`= 2 { return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } if len(s) == 1 { - return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: "Missing key: " + s[0], ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}} @@ -38,9 +41,11 @@ func InvalidParameterValue(value, locator string) Exception { } // VersionNegotiationFailed exception +// +//nolint:goconst func VersionNegotiationFailed(version string) Exception { return exception{ExceptionDetails: common.ExceptionDetails{ - ExceptionText: fmt.Sprintf("%s is an invalid version number", version), + ExceptionText: version + " is an invalid version number", ExceptionCode: `VersionNegotiationFailed`, LocatorCode: "VERSION", }} @@ -54,6 +59,8 @@ func InvalidUpdateSequence() Exception { } // OptionNotSupported exception +// +//nolint:goconst func OptionNotSupported(s ...string) Exception { if len(s) == 1 { return exception{ExceptionDetails: common.ExceptionDetails{ diff --git a/pkg/wsc110/exception_test.go b/pkg/wsc110/exception_test.go index 44c9702..ce756bb 100644 --- a/pkg/wsc110/exception_test.go +++ b/pkg/wsc110/exception_test.go @@ -2,6 +2,7 @@ package wsc110 import ( "github.com/pdok/ogc-specifications/pkg/common" + "testing" ) diff --git a/pkg/wsc200/exception.go b/pkg/wsc200/exception.go index f15b0a4..4e6b396 100644 --- a/pkg/wsc200/exception.go +++ b/pkg/wsc200/exception.go @@ -2,6 +2,7 @@ package wsc200 import ( "encoding/xml" + "github.com/pdok/ogc-specifications/pkg/common" ) @@ -25,7 +26,7 @@ type ExceptionReport struct { Ows string `xml:"xmlns:ows,attr,omitempty" yaml:"ows"` Xsi string `xml:"xmlns:xsi,attr,omitempty" yaml:"xsi"` SchemaLocation string `xml:"xsi:schemaLocation,attr,omitempty" yaml:"schemaLocation"` - Version string `xml:"version,attr" yaml:"version" yaml:"version"` + Version string `xml:"version,attr" yaml:"version"` Language string `xml:"xml:lang,attr,omitempty" yaml:"lang,omitempty"` Exception Exceptions `xml:"ows:Exception" yaml:"exception"` } diff --git a/pkg/wsc200/exception_codes.go b/pkg/wsc200/exception_codes.go index ea53398..6306351 100644 --- a/pkg/wsc200/exception_codes.go +++ b/pkg/wsc200/exception_codes.go @@ -2,25 +2,28 @@ package wsc200 import ( "fmt" + "github.com/pdok/ogc-specifications/pkg/common" ) // OperationNotSupported exception func OperationNotSupported(message string) Exception { return exception{ExceptionDetails: common.ExceptionDetails{ - ExceptionText: fmt.Sprintf("This service does not know the operation: %s", message), + ExceptionText: "This service does not know the operation: " + message, ExceptionCode: `OperationNotSupported`, LocatorCode: message, }} } // MissingParameterValue exception +// +//nolint:goconst func MissingParameterValue(s ...string) Exception { if len(s) >= 2 { return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } if len(s) == 1 { - return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} + return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: "Missing key: " + s[0], ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}} } return exception{ExceptionDetails: common.ExceptionDetails{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}} @@ -36,9 +39,11 @@ func InvalidParameterValue(value, locator string) Exception { } // VersionNegotiationFailed exception +// +//nolint:goconst func VersionNegotiationFailed(version string) Exception { return exception{ExceptionDetails: common.ExceptionDetails{ - ExceptionText: fmt.Sprintf("%s is an invalid version number", version), + ExceptionText: version + " is an invalid version number", ExceptionCode: `VersionNegotiationFailed`, LocatorCode: "VERSION", }} diff --git a/pkg/wsc200/exception_test.go b/pkg/wsc200/exception_test.go index c5f1c8b..be949d1 100644 --- a/pkg/wsc200/exception_test.go +++ b/pkg/wsc200/exception_test.go @@ -2,6 +2,7 @@ package wsc200 import ( "github.com/pdok/ogc-specifications/pkg/common" + "testing" )