Skip to content

Commit

Permalink
init setup ows pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
WouterVisscher committed Jul 6, 2020
1 parent 9f11dac commit d794162
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 65 deletions.
54 changes: 54 additions & 0 deletions pkg/ows/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package ows

import (
"encoding/xml"
"testing"
)

func TestBoundingBoxBuildQueryString(t *testing.T) {
var tests = []struct {
boundingbox BoundingBox
boundingboxstring string
}{
// While 'not' correct this will we checked in the validation step
0: {boundingbox: BoundingBox{}, boundingboxstring: `0.000000,0.000000,0.000000,0.000000`},
1: {boundingbox: BoundingBox{LowerCorner: [2]float64{-180.0, -90.0}, UpperCorner: [2]float64{180.0, 90.0}}, boundingboxstring: `-180.000000,-90.000000,180.000000,90.000000`},
}
for k, a := range tests {
str := a.boundingbox.BuildQueryString()
if str != a.boundingboxstring {
t.Errorf("test: %d, expected: %v+,\n got: %v+", k, a.boundingboxstring, str)
}
}
}

func TestStripDuplicateAttr(t *testing.T) {
var tests = []struct {
attributes []xml.Attr
expected []xml.Attr
}{
0: {attributes: []xml.Attr{{Name: xml.Name{Local: "gml"}, Value: "http://www.opengis.net/gml/3.2"}}, expected: []xml.Attr{{Name: xml.Name{Local: "gml"}, Value: "http://www.opengis.net/gml/3.2"}}},
1: {attributes: []xml.Attr{{Name: xml.Name{Local: "gml"}, Value: "http://www.opengis.net/gml/3.2"}, {Name: xml.Name{Local: "gml"}, Value: "http://www.opengis.net/gml/3.2"}, {Name: xml.Name{Local: "gml"}, Value: "http://www.opengis.net/gml/3.2"}},
expected: []xml.Attr{{Name: xml.Name{Local: "gml"}, Value: "http://www.opengis.net/gml/3.2"}}},
}

for k, a := range tests {
stripped := StripDuplicateAttr(a.attributes)
if len(a.expected) != len(stripped) {
t.Errorf("test: %d, expected: %s,\n got: %s", k, a.expected, stripped)
} else {
c := false
for _, exceptedattr := range a.expected {
for _, result := range stripped {
if exceptedattr == result {
c = true
}
}
if !c {
t.Errorf("test: %d, expected: %s,\n got: %s", k, a.expected, stripped)
}
c = false
}
}
}
}
65 changes: 51 additions & 14 deletions pkg/ows/exception.go
Original file line number Diff line number Diff line change
@@ -1,72 +1,109 @@
package ows

import (
"encoding/xml"
"fmt"
)

const (
version = `1.0.0`
)

// ExceptionReport interface
type ExceptionReport interface {
Report(Exception) []byte
Report([]Exception) []byte
}

// Exception interfact wraps the two variables:
// OWSExceptionReport struct
type OWSExceptionReport struct {
xmlname xml.Name `xml:"ExceptionReport"`
ows string `xml:"xmlns:ows,attr"`
xsi string `xml:"xmlns:xsi,attr"`
schemaLocation string `xml:"xsi:schemaLocation,attr"`
version string `xml:"version,attr"`
language string `xml:"xml:lang,attr"`
Exception []Exception `xml:"Exception"`
}

// Report returns OWSExceptionReport
func (r OWSExceptionReport) Report(errors []Exception) []byte {
r.schemaLocation = `http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd`
r.ows = `http://www.opengis.net/ows/1.1`
r.xsi = `http://www.w3.org/2001/XMLSchema-instance`
r.version = version
r.language = `en`
r.Exception = errors

si, _ := xml.MarshalIndent(r, "", " ")
return append([]byte(xml.Header), si...)
}

// Exception interfact wraps the three variables:
// Error
// Code
// Locator
type Exception interface {
Error() string
Code() string
Locator() string
}

// OWSException grouping the error message variables together
type OWSException struct {
ErrorMessage string `xml:",chardata"`
ExceptionText string `xml:",chardata"`
ExceptionCode string `xml:"exceptionCode,attr"`
LocatorCode string `xml:"locator,attr"`
LocatorCode string `xml:"locator,attr,omitempty"`
}

// Error returns available ErrorMessage
// Error returns available ExceptionText
func (e OWSException) Error() string {
return e.ErrorMessage
return e.ExceptionText
}

// Code returns available ExceptionCode
func (e OWSException) Code() string {
return e.ExceptionCode
}

// Locator returns available ExceptionCode
func (e OWSException) Locator() string {
return e.LocatorCode
}

// OperationNotSupported exception
func OperationNotSupported(message string) OWSException {
return OWSException{
ErrorMessage: message,
ExceptionText: fmt.Sprintf("This service does not know the operation: %s", message),
ExceptionCode: `OperationNotSupported`,
LocatorCode: message,
}
}

// MissingParameterValue exception
func MissingParameterValue(s ...string) OWSException {
if len(s) >= 2 {
return OWSException{ErrorMessage: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue"}
return OWSException{ExceptionText: fmt.Sprintf("%s key got incorrect value: %s", s[0], s[1]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}
}
if len(s) == 1 {
return OWSException{ErrorMessage: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue"}
return OWSException{ExceptionText: fmt.Sprintf("Missing key: %s", s[0]), ExceptionCode: "MissingParameterValue", LocatorCode: s[0]}
}

return OWSException{ErrorMessage: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue"}
return OWSException{ExceptionText: `Could not determine REQUEST`, ExceptionCode: "MissingParameterValue", LocatorCode: "REQUEST"}
}

// InvalidParameterValue exception
func InvalidParameterValue(value, locator string) OWSException {
return OWSException{
ErrorMessage: fmt.Sprintf("%s %s does not exist in this server. Please check the capabilities and reformulate your request", locator, value),
LocatorCode: locator,
ExceptionText: fmt.Sprintf("%s %s does not exist in this server. Please check the capabilities and reformulate your request", locator, value),
LocatorCode: value,
ExceptionCode: `InvalidParameterValue`,
}
}

// VersionNegotiationFailed exception
func VersionNegotiationFailed(version string) OWSException {
return OWSException{
ErrorMessage: fmt.Sprintf("%s is an invalid version number", version),
ExceptionText: fmt.Sprintf("%s is an invalid version number", version),
ExceptionCode: `VersionNegotiationFailed`,
LocatorCode: "VERSION",
}
Expand All @@ -89,7 +126,7 @@ func OptionNotSupported() OWSException {
// NoApplicableCode exception
func NoApplicableCode(message string) OWSException {
return OWSException{
ErrorMessage: message,
ExceptionText: message,
ExceptionCode: `NoApplicableCode`,
}
}
107 changes: 107 additions & 0 deletions pkg/ows/exception_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package ows

import (
"testing"
)

func TestOWSException(t *testing.T) {
var tests = []struct {
exception Exception
exceptionText string
exceptionCode string
locatorCode string
}{
0: {exception: OWSException{ExceptionCode: "", ExceptionText: "", LocatorCode: ""},
exceptionText: "",
exceptionCode: "",
locatorCode: "",
},
1: {exception: OperationNotSupported("GetCoconut"),
exceptionText: "This service does not know the operation: GetCoconut",
exceptionCode: "OperationNotSupported",
locatorCode: "GetCoconut",
},
2: {exception: MissingParameterValue(),
exceptionText: "Could not determine REQUEST",
exceptionCode: "MissingParameterValue",
locatorCode: "REQUEST",
},
3: {exception: MissingParameterValue("VERSION"),
exceptionText: "Missing key: VERSION",
exceptionCode: "MissingParameterValue",
locatorCode: "VERSION",
},
// TODO: ... is this valid
4: {exception: MissingParameterValue("SERVICE", "1.3.0"),
exceptionText: "SERVICE key got incorrect value: 1.3.0",
exceptionCode: "MissingParameterValue",
locatorCode: "SERVICE",
},
5: {exception: InvalidParameterValue("SERVICE", "WKS"),
exceptionText: "WKS SERVICE does not exist in this server. Please check the capabilities and reformulate your request",
exceptionCode: "InvalidParameterValue",
locatorCode: "SERVICE",
},
6: {exception: VersionNegotiationFailed("0.0.0"),
exceptionText: "0.0.0 is an invalid version number",
exceptionCode: "VersionNegotiationFailed",
locatorCode: "VERSION",
},
// TODO: ...
7: {exception: InvalidUpdateSequence(),
exceptionCode: "InvalidUpdateSequence",
},
// TODO: ...
8: {exception: OptionNotSupported(),
exceptionCode: "OptionNotSupported",
},
9: {exception: NoApplicableCode("No other exceptionCode specified by this service"),
exceptionText: "No other exceptionCode specified by this service",
exceptionCode: "NoApplicableCode",
},
}

for k, a := range tests {
if a.exception.Error() != a.exceptionText {
t.Errorf("test: %d, expected: %s\n got: %s", k, a.exceptionText, a.exception.Error())
}
if a.exception.Code() != a.exceptionCode {
t.Errorf("test: %d, expected: %s\n got: %s", k, a.exceptionCode, a.exception.Code())
}
if a.exception.Locator() != a.locatorCode {
t.Errorf("test: %d, expected: %s\n got: %s", k, a.locatorCode, a.exception.Locator())
}
}
}

func TestReport(t *testing.T) {
var tests = []struct {
exceptions []Exception
result []byte
err error
}{
0: {exceptions: []Exception{OWSException{ExceptionCode: "", ExceptionText: "", LocatorCode: ""}},
result: []byte(`<?xml version="1.0" encoding="UTF-8"?>
<OWSExceptionReport>
<Exception exceptionCode=""></Exception>
</OWSExceptionReport>`)},
1: {exceptions: []Exception{
OperationNotSupported(`WKS`),
VersionNegotiationFailed(`0.0.1`),
},
result: []byte(`<?xml version="1.0" encoding="UTF-8"?>
<OWSExceptionReport>
<Exception exceptionCode="OperationNotSupported" locator="WKS">This service does not know the operation: WKS</Exception>
<Exception exceptionCode="VersionNegotiationFailed" locator="VERSION">0.0.1 is an invalid version number</Exception>
</OWSExceptionReport>`)},
}

for k, a := range tests {
report := OWSExceptionReport{}
r := report.Report(a.exceptions)

if string(r) != string(a.result) {
t.Errorf("test: %d, expected: %s\n got: %s", k, r, a.result)
}
}
}
7 changes: 3 additions & 4 deletions pkg/ows/xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ func (xmlattr *XMLAttribute) UnmarshalXML(d *xml.Decoder, start xml.StartElement
*xmlattr = newattributes

for {
token, err := d.Token()
if err != nil {
return err
}
// 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 == start.End() {
Expand Down
29 changes: 22 additions & 7 deletions pkg/ows/xml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,28 @@ package ows

import (
"encoding/xml"
"errors"
"testing"
)

func TestUnMarshalXMLAttribute(t *testing.T) {
var tests = []struct {
xmlraw string
expected XMLAttribute
xmlraw string
expected XMLAttribute
exception error
}{
0: {xmlraw: `<startelement attr="one"/>`, expected: XMLAttribute{xml.Attr{Name: xml.Name{Local: "attr"}, Value: "one"}}},
1: {xmlraw: `<startelement attr="two" attr="three"/>`, expected: XMLAttribute{xml.Attr{Name: xml.Name{Local: "attr"}, Value: "two"}, xml.Attr{Name: xml.Name{Local: "attr"}, Value: "three"}}},
2: {xmlraw: `<startelement b:attr="two" b:item="three"/>`, expected: XMLAttribute{xml.Attr{Name: xml.Name{Space: "b", Local: "attr"}, Value: "two"}, xml.Attr{Name: xml.Name{Space: "b", Local: "item"}, Value: "three"}}},
3: {xmlraw: `<startelement attr="one"`, exception: errors.New("XML syntax error on line 1: unexpected EOF")},
}

for k, a := range tests {
var xmlattr XMLAttribute
if err := xml.Unmarshal([]byte(a.xmlraw), &xmlattr); err != nil {
t.Errorf("test: %d, expected no error,\n got: %s", k, err.Error())
if err.Error() != a.exception.Error() {
t.Errorf("test: %d, expected no error,\n got: %s", k, err.Error())
}
}

if len(a.expected) != len(xmlattr) {
Expand All @@ -44,6 +49,7 @@ func TestUnMarshalXMLBoundingBox(t *testing.T) {
var tests = []struct {
xmlraw string
boundingbox BoundingBox
exception error
}{
// BoundingBox from GetMap schemas.opengis.net/sld/1.1.0/example_getmap.xml example request
0: {xmlraw: `<BoundingBox crs="http://www.opengis.net/gml/srs/epsg.xml#4326">
Expand All @@ -68,14 +74,23 @@ func TestUnMarshalXMLBoundingBox(t *testing.T) {
<ows:UpperCorner/>
</BoundingBox>`,
boundingbox: BoundingBox{Crs: "http://www.opengis.net/gml/srs/epsg.xml#4326", Dimensions: "2"}},
5: {xmlraw: `<BoundingBox crs="http://www.opengis.net/gml/srs/epsg.xml#4326" dimensions="2">
<ows:LowerCorner>Not a coord</ows:LowerCorner>
<ows:UpperCorner/>
corrupt xml"`,
exception: errors.New("XML syntax error on line 4: unexpected EOF")},
}
for k, a := range tests {
var bbox BoundingBox
if err := xml.Unmarshal([]byte(a.xmlraw), &bbox); err != nil {
t.Errorf("test: %d, expected no error,\n got: %s", k, err.Error())
}
if a.boundingbox != bbox {
t.Errorf("test: %d, expected: %v+,\n got: %v+", k, a.boundingbox, bbox)
if err.Error() != a.exception.Error() {
t.Errorf("test: %d, expected no error,\n got: %s", k, err.Error())
}

} else {
if a.boundingbox != bbox {
t.Errorf("test: %d, expected: %v+,\n got: %v+", k, a.boundingbox, bbox)
}
}
}
}
Expand Down
Loading

0 comments on commit d794162

Please sign in to comment.