diff --git a/openproject.go b/openproject.go index 18f2851..241283a 100644 --- a/openproject.go +++ b/openproject.go @@ -9,14 +9,35 @@ import ( "io/ioutil" "net/http" "net/url" - "reflect" "strings" "time" - "github.com/google/go-querystring/query" "github.com/pkg/errors" ) +// SearchOperator represents Search operators by custom type const +// Doc. https://docs.openproject.org/api/filters/#header-available-filters-1 +type SearchOperator string + +const ( + // Equal operator + Equal SearchOperator = "=" + // Different operator + Different SearchOperator = "<>" + // GreaterThan operator + GreaterThan SearchOperator = ">" + // LowerThan operator + LowerThan SearchOperator = "<" + // SearchString operator + SearchString SearchOperator = "**" + // Like operator + Like SearchOperator = "~" + // GreaterOrEqual operator + GreaterOrEqual SearchOperator = ">=" + // LowerOrEqual operator + LowerOrEqual SearchOperator = "<=" +) + // OPGenericDescription is an structure widely used in several OpenProject API objects type OPGenericDescription struct { Format string `json:"format,omitempty" structs:"format,omitempty"` @@ -97,49 +118,6 @@ func NewClient(httpClient httpClient, baseURL string) (*Client, error) { return c, nil } -// NewRawRequestWithContext creates an API request. -// A relative URL can be provided in urlStr, in which case it is resolved relative to the baseURL of the Client. -// Allows using an optional native io.Reader for sourcing the request body. -func (c *Client) NewRawRequestWithContext(ctx context.Context, method, urlStr string, body io.Reader) (*http.Request, error) { - rel, err := url.Parse(urlStr) - if err != nil { - return nil, err - } - // Relative URLs should be specified without a preceding slash since baseURL will have the trailing slash - rel.Path = strings.TrimLeft(rel.Path, "/") - - u := c.baseURL.ResolveReference(rel) - - req, err := newRequestWithContext(ctx, method, u.String(), body) - if err != nil { - return nil, err - } - - req.Header.Set("Content-Type", "application/json") - - // Set authentication information - if c.Authentication.authType == authTypeSession { - // Set session cookie if there is one - if c.session != nil { - for _, cookie := range c.session.Cookies { - req.AddCookie(cookie) - } - } - } else if c.Authentication.authType == authTypeBasic { - // Set basic auth information - if c.Authentication.username != "" { - req.SetBasicAuth(c.Authentication.username, c.Authentication.password) - } - } - - return req, nil -} - -// NewRawRequest wraps NewRawRequestWithContext using the background context. -func (c *Client) NewRawRequest(method, urlStr string, body io.Reader) (*http.Request, error) { - return c.NewRawRequestWithContext(context.Background(), method, urlStr, body) -} - // NewRequestWithContext creates an API request. // A relative URL can be provided in urlStr, in which case it is resolved relative to the baseURL of the Client. // If specified, the value pointed to by body is JSON encoded and included as the request body. @@ -192,28 +170,6 @@ func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Requ return c.NewRequestWithContext(context.Background(), method, urlStr, body) } -// addOptions adds the parameters in opt as URL query parameters to s. opt -// must be a struct whose fields may contain "url" tags. -func addOptions(s string, opt interface{}) (string, error) { - v := reflect.ValueOf(opt) - if v.Kind() == reflect.Ptr && v.IsNil() { - return s, nil - } - - u, err := url.Parse(s) - if err != nil { - return s, err - } - - qs, err := query.Values(opt) - if err != nil { - return s, err - } - - u.RawQuery = qs.Encode() - return u.String(), nil -} - // NewMultiPartRequestWithContext creates an API request including a multi-part file. // A relative URL can be provided in urlStr, in which case it is resolved relative to the baseURL of the Client. // If specified, the value pointed to by buf is a multipart form. @@ -414,23 +370,6 @@ func cloneRequest(r *http.Request) *http.Request { return r2 } -// Interpret Operator collection and return its string ( Used in searches like GetList(...) ) -func interpretOperator(operator SearchOperator) string { - result := "=" - - switch operator { - case GreaterThan: - result = ">" - case LowerThan: - result = "<" - case Different: - result = "<>" - } - //TODO: Complete list of operators - - return result -} - // getObjectAndClient gets an inputObject (inputObject is an OpenProject object like WorkPackage, WikiPage, Status, etc.) // and return a pointer to its Client from its service and an instance of the object itself func getObjectAndClient(inputObj interface{}) (client *Client, resultObj interface{}) { diff --git a/openproject_test.go b/openproject_test.go index 64feba4..7b94030 100644 --- a/openproject_test.go +++ b/openproject_test.go @@ -160,30 +160,6 @@ func TestClient_NewRequest(t *testing.T) { } } -func TestClient_NewRawRequest(t *testing.T) { - c, err := NewClient(nil, testOpenProjectInstanceURL) - if err != nil { - t.Errorf("An error occurred. Expected nil. Got %+v.", err) - } - - inURL, outURL := "api/v3/workpackages/", testOpenProjectInstanceURL+"api/v3/workpackages/" - - outBody := `{"id":1}` + "\n" - inBody := outBody - req, _ := c.NewRawRequest("GET", inURL, strings.NewReader(outBody)) - - // Test that relative URL was expanded - if got, want := req.URL.String(), outURL; got != want { - t.Errorf("NewRawRequest(%q) URL is %v, want %v", inURL, got, want) - } - - // Test that body was JSON encoded - body, _ := ioutil.ReadAll(req.Body) - if got, want := string(body), outBody; got != want { - t.Errorf("NewRawRequest(%v) Body is %v, want %v", inBody, got, want) - } -} - func testURLParseError(t *testing.T, err error) { if err == nil { t.Errorf("Expected error to be returned") diff --git a/work-package.go b/work-package.go index 9efc8e1..464de51 100644 --- a/work-package.go +++ b/work-package.go @@ -118,29 +118,6 @@ type WPPayload struct { type WPFormLinks struct { } -// SearchOperator represents Search operators by custom type const -// Doc. https://docs.openproject.org/api/filters/#header-available-filters-1 -type SearchOperator int32 - -const ( - // Equal '=' - Equal SearchOperator = 0 - // Different '<>' - Different SearchOperator = 1 - // GreaterThan '>' - GreaterThan SearchOperator = 2 - // LowerThan '<' - LowerThan SearchOperator = 3 - // SearchString '**' - SearchString SearchOperator = 4 - // Like is '~' - Like SearchOperator = 5 - // GreaterOrEqual is'>=' - GreaterOrEqual SearchOperator = 6 - // LowerOrEqual is '<=' - LowerOrEqual SearchOperator = 7 -) - // Constants to represent OpenProject standard GET parameters const paramFilters = "filters" @@ -196,7 +173,7 @@ func (fops *FilterOptions) prepareFilters() url.Values { for _, field := range fops.Fields { s := fmt.Sprintf( "{\"%[1]v\":{\"operator\":\"%[2]v\",\"values\":[\"%[3]v\"]}}", - field.Field, interpretOperator(field.Operator), field.Value) + field.Field, field.Operator, field.Value) filterTemplate += s }