mirror of
https://github.com/retailcrm/api-client-go.git
synced 2024-11-22 04:46:03 +03:00
files upload support
This commit is contained in:
parent
ddf8ee7cef
commit
2f06836bd4
262
v5/client.go
262
v5/client.go
@ -1,8 +1,10 @@
|
|||||||
package v5
|
package v5
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -12,6 +14,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-querystring/query"
|
"github.com/google/go-querystring/query"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/retailcrm/api-client-go/errs"
|
"github.com/retailcrm/api-client-go/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -73,23 +76,46 @@ func (c *Client) GetRequest(urlWithParameters string, versioned ...bool) ([]byte
|
|||||||
return res, resp.StatusCode, failure
|
return res, resp.StatusCode, failure
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostRequest implements POST Request
|
// PostRequest implements POST Request with generic body data
|
||||||
func (c *Client) PostRequest(url string, postParams url.Values) ([]byte, int, *errs.Failure) {
|
func (c *Client) PostRequest(uri string, postData interface{}, contType ...string) ([]byte, int, *errs.Failure) {
|
||||||
var res []byte
|
var (
|
||||||
var prefix = "/api/v5"
|
res []byte
|
||||||
|
contentType string
|
||||||
|
reader io.Reader
|
||||||
|
)
|
||||||
|
|
||||||
|
prefix := "/api/v5"
|
||||||
failure := &errs.Failure{}
|
failure := &errs.Failure{}
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s%s", c.URL, prefix, url), strings.NewReader(postParams.Encode()))
|
if len(contType) > 0 {
|
||||||
|
contentType = contType[0]
|
||||||
|
} else {
|
||||||
|
contentType = "application/x-www-form-urlencoded"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch postData.(type) {
|
||||||
|
case url.Values:
|
||||||
|
reader = strings.NewReader(postData.(url.Values).Encode())
|
||||||
|
default:
|
||||||
|
if i, ok := postData.(io.Reader); ok {
|
||||||
|
reader = i
|
||||||
|
} else {
|
||||||
|
failure.SetRuntimeError(errors.New("postData should be url.Values or implement io.Reader"))
|
||||||
|
return []byte{}, 0, failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", fmt.Sprintf("%s%s%s", c.URL, prefix, uri), reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
failure.SetRuntimeError(err)
|
failure.SetRuntimeError(err)
|
||||||
return res, 0, failure
|
return res, 0, failure
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", contentType)
|
||||||
req.Header.Set("X-API-KEY", c.Key)
|
req.Header.Set("X-API-KEY", c.Key)
|
||||||
|
|
||||||
if c.Debug {
|
if c.Debug {
|
||||||
log.Printf("API Request: %s %s %s", url, c.Key, postParams.Encode())
|
log.Printf("API Request: %s %s", uri, c.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.httpClient.Do(req)
|
resp, err := c.httpClient.Do(req)
|
||||||
@ -3941,6 +3967,228 @@ func (c *Client) CostEdit(id int, cost CostRecord, site ...string) (CreateRespon
|
|||||||
return resp, status, nil
|
return resp, status, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Files returns files list
|
||||||
|
//
|
||||||
|
// For more information see https://help.retailcrm.pro/Developers/ApiVersion5#get--api-v5-files
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var client = v5.New("https://demo.url", "09jIJ")
|
||||||
|
//
|
||||||
|
// data, status, err := client.Files(FilesRequest{
|
||||||
|
// Filter: FilesFilter{
|
||||||
|
// Filename: "image.jpeg",
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// if err.Error() != "" {
|
||||||
|
// fmt.Printf("%v", err.RuntimeErr)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if status >= http.StatusBadRequest {
|
||||||
|
// fmt.Printf("%v", err.ApiErr())
|
||||||
|
// }
|
||||||
|
func (c *Client) Files(files FilesRequest) (FilesResponse, int, *errs.Failure) {
|
||||||
|
var resp FilesResponse
|
||||||
|
|
||||||
|
params, _ := query.Values(files)
|
||||||
|
|
||||||
|
data, status, err := c.GetRequest(fmt.Sprintf("/files?%s", params.Encode()))
|
||||||
|
|
||||||
|
if err != nil && err.Error() != "" {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(data, &resp)
|
||||||
|
|
||||||
|
if resp.Success == false {
|
||||||
|
buildErr(data, err)
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileUpload uploads file to retailCRM
|
||||||
|
//
|
||||||
|
// For more information see https://help.retailcrm.pro/Developers/ApiVersion5#get--api-v5-files
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var client = v5.New("https://demo.url", "09jIJ")
|
||||||
|
//
|
||||||
|
// file, err := os.Open("file.jpg")
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Print(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// data, status, err := client.FileUpload(file)
|
||||||
|
//
|
||||||
|
// if err.Error() != "" {
|
||||||
|
// fmt.Printf("%v", err.RuntimeErr)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if status >= http.StatusBadRequest {
|
||||||
|
// fmt.Printf("%v", err.ApiErr())
|
||||||
|
// }
|
||||||
|
func (c *Client) FileUpload(reader io.Reader) (FileUploadResponse, int, *errs.Failure) {
|
||||||
|
var resp FileUploadResponse
|
||||||
|
|
||||||
|
data, status, err := c.PostRequest(fmt.Sprintf("/files/upload?apiKey=%s", c.Key), reader, "application/octet-stream")
|
||||||
|
|
||||||
|
if err != nil && err.Error() != "" {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(data, &resp)
|
||||||
|
|
||||||
|
if resp.Success == false {
|
||||||
|
buildErr(data, err)
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// File returns a file info
|
||||||
|
//
|
||||||
|
// For more information see https://help.retailcrm.pro/Developers/ApiVersion5#get--api-v5-files
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var client = v5.New("https://demo.url", "09jIJ")
|
||||||
|
//
|
||||||
|
// data, status, err := client.File(112)
|
||||||
|
//
|
||||||
|
// if err.Error() != "" {
|
||||||
|
// fmt.Printf("%v", err.RuntimeErr)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if status >= http.StatusBadRequest {
|
||||||
|
// fmt.Printf("%v", err.ApiErr())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if data.Success == true {
|
||||||
|
// fmt.Printf("%v\n", data.File)
|
||||||
|
// }
|
||||||
|
func (c *Client) File(id int) (FileResponse, int, *errs.Failure) {
|
||||||
|
var resp FileResponse
|
||||||
|
|
||||||
|
data, status, err := c.GetRequest(fmt.Sprintf("/files/%d", id))
|
||||||
|
if err.Error() != "" {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(data, &resp)
|
||||||
|
|
||||||
|
if resp.Success == false {
|
||||||
|
buildErr(data, err)
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileDelete removes file from retailCRM
|
||||||
|
//
|
||||||
|
// For more information see https://help.retailcrm.pro/Developers/ApiVersion5#get--api-v5-files
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var client = v5.New("https://demo.url", "09jIJ")
|
||||||
|
//
|
||||||
|
// data, status, err := client.FileDelete(123)
|
||||||
|
//
|
||||||
|
// if err.Error() != "" {
|
||||||
|
// fmt.Printf("%v", err.RuntimeErr)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if status >= http.StatusBadRequest {
|
||||||
|
// fmt.Printf("%v", err.ApiErr())
|
||||||
|
// }
|
||||||
|
func (c *Client) FileDelete(id int) (SuccessfulResponse, int, *errs.Failure) {
|
||||||
|
var resp SuccessfulResponse
|
||||||
|
|
||||||
|
data, status, err := c.PostRequest(fmt.Sprintf("/files/%d/delete", id), strings.NewReader(""))
|
||||||
|
|
||||||
|
if err != nil && err.Error() != "" {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(data, &resp)
|
||||||
|
|
||||||
|
if resp.Success == false {
|
||||||
|
buildErr(data, err)
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileDownload downloads file from retailCRM
|
||||||
|
//
|
||||||
|
// For more information see https://help.retailcrm.pro/Developers/ApiVersion5#get--api-v5-files
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var client = v5.New("https://demo.url", "09jIJ")
|
||||||
|
//
|
||||||
|
// fileData, status, err := client.FileDownload(123)
|
||||||
|
//
|
||||||
|
// if err.Error() != "" {
|
||||||
|
// fmt.Printf("%v", err.RuntimeErr)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if status >= http.StatusBadRequest {
|
||||||
|
// fmt.Printf("%v", err.ApiErr())
|
||||||
|
// }
|
||||||
|
func (c *Client) FileDownload(id int) (io.ReadCloser, int, *errs.Failure) {
|
||||||
|
data, status, err := c.GetRequest(fmt.Sprintf("/files/%d/download", id))
|
||||||
|
if status != http.StatusOK {
|
||||||
|
return nil, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
closer := ioutil.NopCloser(bytes.NewReader(data))
|
||||||
|
return closer, status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileEdit edits file name and relations with orders and customers in retailCRM
|
||||||
|
//
|
||||||
|
// For more information see https://help.retailcrm.pro/Developers/ApiVersion5#get--api-v5-files
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var client = v5.New("https://demo.url", "09jIJ")
|
||||||
|
//
|
||||||
|
// data, status, err := client.FileEdit(123, File{Filename: "image2.jpg"})
|
||||||
|
//
|
||||||
|
// if err.Error() != "" {
|
||||||
|
// fmt.Printf("%v", err.RuntimeErr)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if status >= http.StatusBadRequest {
|
||||||
|
// fmt.Printf("%v", err.ApiErr())
|
||||||
|
// }
|
||||||
|
func (c *Client) FileEdit(id int, file File) (FileResponse, int, *errs.Failure) {
|
||||||
|
var resp FileResponse
|
||||||
|
|
||||||
|
req, _ := json.Marshal(file)
|
||||||
|
data, status, err := c.PostRequest(fmt.Sprintf("/files/%d/edit", id), bytes.NewReader(req))
|
||||||
|
|
||||||
|
if err != nil && err.Error() != "" {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal(data, &resp)
|
||||||
|
|
||||||
|
if resp.Success == false {
|
||||||
|
buildErr(data, err)
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CustomFields returns list of custom fields
|
// CustomFields returns list of custom fields
|
||||||
//
|
//
|
||||||
// For more information see http://www.retailcrm.pro/docs/Developers/ApiVersion5#get--api-v5-custom-fields
|
// For more information see http://www.retailcrm.pro/docs/Developers/ApiVersion5#get--api-v5-custom-fields
|
||||||
|
@ -3,12 +3,14 @@ package v5
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -4750,6 +4752,297 @@ func TestClient_CostsUpload_Fail(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClient_Files(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
fileID := 14925
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Get("/files").
|
||||||
|
MatchParam("filter[ids][]", strconv.Itoa(fileID)).
|
||||||
|
MatchParam("limit", "20").
|
||||||
|
MatchParam("page", "1").
|
||||||
|
Reply(200).
|
||||||
|
BodyString(`{
|
||||||
|
"success": true,
|
||||||
|
"pagination": {
|
||||||
|
"limit": 20,
|
||||||
|
"totalCount": 0,
|
||||||
|
"currentPage": 1,
|
||||||
|
"totalPageCount": 0
|
||||||
|
},
|
||||||
|
"files": []
|
||||||
|
}`)
|
||||||
|
|
||||||
|
_, status, err := c.Files(FilesRequest{
|
||||||
|
Limit: 20,
|
||||||
|
Page: 1,
|
||||||
|
Filter: FilesFilter{
|
||||||
|
Ids: []int{fileID},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if status != 200 {
|
||||||
|
t.Errorf("%v %v", err.Error(), err.ApiError())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_FileUpload(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
file := strings.NewReader(`test file contents`)
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Post("/files/upload").
|
||||||
|
Reply(200).
|
||||||
|
BodyString(`{"success": true, "file": {"id": 1}}`)
|
||||||
|
|
||||||
|
data, status, err := c.FileUpload(file)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Success != true {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.File.ID != 1 {
|
||||||
|
t.Error("invalid file id")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_FileUploadFail(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
file := strings.NewReader(`test file contents`)
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Post("/files/upload").
|
||||||
|
Reply(400).
|
||||||
|
BodyString(`{"success": false, "errorMsg": "error"}`)
|
||||||
|
|
||||||
|
_, status, err := c.FileUpload(file)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusBadRequest {
|
||||||
|
t.Errorf("status should be `%d`, got `%d` instead", http.StatusBadRequest, status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_File(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
invalidFile := 20
|
||||||
|
fileResponse := &FileResponse{
|
||||||
|
Success: true,
|
||||||
|
File: &File{
|
||||||
|
ID: 19,
|
||||||
|
Filename: "image.jpg",
|
||||||
|
Type: "image/jpeg",
|
||||||
|
CreatedAt: time.Now().String(),
|
||||||
|
Size: 10000,
|
||||||
|
Attachment: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
respData, errr := json.Marshal(fileResponse)
|
||||||
|
if errr != nil {
|
||||||
|
t.Errorf("%v", errr.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Get(fmt.Sprintf("/files/%d", fileResponse.File.ID)).
|
||||||
|
Reply(200).
|
||||||
|
BodyString(string(respData))
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Get(fmt.Sprintf("/files/%d", invalidFile)).
|
||||||
|
Reply(404).
|
||||||
|
BodyString(`{"success": false, "errorMsg": "Not Found"}`)
|
||||||
|
|
||||||
|
s, status, err := c.File(fileResponse.File.ID)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Success != true {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.File.ID != fileResponse.File.ID {
|
||||||
|
t.Error("invalid response data")
|
||||||
|
}
|
||||||
|
|
||||||
|
s, status, err = c.File(invalidFile)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusNotFound {
|
||||||
|
t.Errorf("status should be `%d`, got `%d` instead", http.StatusNotFound, status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_FileDelete(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
successful := 19
|
||||||
|
badRequest := 20
|
||||||
|
notFound := 21
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Post(fmt.Sprintf("/files/%d/delete", successful)).
|
||||||
|
Reply(200).
|
||||||
|
BodyString(`{"success": true}`)
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Post(fmt.Sprintf("/files/%d/delete", badRequest)).
|
||||||
|
Reply(400).
|
||||||
|
BodyString(`{"success": false, "errorMsg": "Error"}`)
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Post(fmt.Sprintf("/files/%d/delete", notFound)).
|
||||||
|
Reply(404).
|
||||||
|
BodyString(`{"success": false, "errorMsg": "Not Found"}`)
|
||||||
|
|
||||||
|
data, status, err := c.FileDelete(successful)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Success != true {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
data, status, err = c.FileDelete(badRequest)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusBadRequest {
|
||||||
|
t.Errorf("status should be `%d`, got `%d` instead", http.StatusBadRequest, status)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, status, err = c.FileDelete(notFound)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusNotFound {
|
||||||
|
t.Errorf("status should be `%d`, got `%d` instead", http.StatusNotFound, status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_FileDownload(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
successful := 19
|
||||||
|
fail := 20
|
||||||
|
fileData := "file data"
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Get(fmt.Sprintf("/files/%d/download", successful)).
|
||||||
|
Reply(200).
|
||||||
|
BodyString(fileData)
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Get(fmt.Sprintf("/files/%d/download", fail)).
|
||||||
|
Reply(400).
|
||||||
|
BodyString("")
|
||||||
|
|
||||||
|
data, status, err := c.FileDownload(successful)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchedByte, errr := ioutil.ReadAll(data)
|
||||||
|
if errr != nil {
|
||||||
|
t.Error(errr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fetched := string(fetchedByte)
|
||||||
|
if fetched != fileData {
|
||||||
|
t.Error("file data mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, status, err = c.FileDownload(fail)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusBadRequest {
|
||||||
|
t.Errorf("status should be `%d`, got `%d` instead", http.StatusBadRequest, status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_FileEdit(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
successful := 19
|
||||||
|
fail := 20
|
||||||
|
resp := FileResponse{
|
||||||
|
Success: true,
|
||||||
|
File: &File{Filename: "image.jpg"},
|
||||||
|
}
|
||||||
|
respData, _ := json.Marshal(resp)
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Post(fmt.Sprintf("/files/%d/edit", successful)).
|
||||||
|
Reply(200).
|
||||||
|
BodyString(string(respData))
|
||||||
|
|
||||||
|
gock.New(crmURL).
|
||||||
|
Post(fmt.Sprintf("/files/%d/edit", fail)).
|
||||||
|
Reply(404).
|
||||||
|
BodyString(`{"success": false, "errorMsg": "Not Found"}`)
|
||||||
|
|
||||||
|
data, status, err := c.FileEdit(successful, *resp.File)
|
||||||
|
if err.Error() != "" {
|
||||||
|
t.Errorf("%v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Success != true {
|
||||||
|
t.Errorf("%v", err.ApiError())
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.File.Filename != resp.File.Filename {
|
||||||
|
t.Errorf("filename should be `%s`, got `%s` instead", resp.File.Filename, data.File.Filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, status, err = c.FileEdit(fail, *resp.File)
|
||||||
|
if status != http.StatusNotFound {
|
||||||
|
t.Errorf("status should be `%d`, got `%d` instead", http.StatusNotFound, status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestClient_CustomFields(t *testing.T) {
|
func TestClient_CustomFields(t *testing.T) {
|
||||||
c := client()
|
c := client()
|
||||||
|
|
||||||
|
@ -318,6 +318,23 @@ type CostsFilter struct {
|
|||||||
OrderExternalIds []string `url:"orderIds,omitempty,brackets"`
|
OrderExternalIds []string `url:"orderIds,omitempty,brackets"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilesFilter type
|
||||||
|
type FilesFilter struct {
|
||||||
|
Ids []int `url:"ids,omitempty,brackets"`
|
||||||
|
OrderIds []int `url:"orderIds,omitempty,brackets"`
|
||||||
|
OrderExternalIds []string `url:"orderExternalIds,omitempty,brackets"`
|
||||||
|
CustomerIds []int `url:"customerIds,omitempty,brackets"`
|
||||||
|
CustomerExternalIds []string `url:"customerExternalIds,omitempty,brackets"`
|
||||||
|
CreatedAtFrom string `url:"createdAtFrom,omitempty"`
|
||||||
|
CreatedAtTo string `url:"createdAtTo,omitempty"`
|
||||||
|
SizeFrom int `url:"sizeFrom,omitempty"`
|
||||||
|
SizeTo int `url:"sizeTo,omitempty"`
|
||||||
|
Type []string `url:"type,omitempty,brackets"`
|
||||||
|
Filename string `url:"filename,omitempty"`
|
||||||
|
IsAttached string `url:"isAttached,omitempty"`
|
||||||
|
Sites []string `url:"sites,omitempty,brackets"`
|
||||||
|
}
|
||||||
|
|
||||||
// CustomFieldsFilter type
|
// CustomFieldsFilter type
|
||||||
type CustomFieldsFilter struct {
|
type CustomFieldsFilter struct {
|
||||||
Name string `url:"name,omitempty"`
|
Name string `url:"name,omitempty"`
|
||||||
|
@ -150,6 +150,13 @@ type CostsRequest struct {
|
|||||||
Page int `url:"page,omitempty"`
|
Page int `url:"page,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilesRequest type
|
||||||
|
type FilesRequest struct {
|
||||||
|
Filter FilesFilter `url:"filter,omitempty"`
|
||||||
|
Limit int `url:"limit,omitempty"`
|
||||||
|
Page int `url:"page,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// CustomFieldsRequest type
|
// CustomFieldsRequest type
|
||||||
type CustomFieldsRequest struct {
|
type CustomFieldsRequest struct {
|
||||||
Filter CustomFieldsFilter `url:"filter,omitempty"`
|
Filter CustomFieldsFilter `url:"filter,omitempty"`
|
||||||
|
@ -367,6 +367,25 @@ type CostResponse struct {
|
|||||||
Cost *Cost `json:"cost,omitempty,brackets"`
|
Cost *Cost `json:"cost,omitempty,brackets"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FilesResponse type
|
||||||
|
type FilesResponse struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Pagination *Pagination `json:"pagination,omitempty"`
|
||||||
|
Files []File `json:"files,omitempty,brackets"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileUpload response
|
||||||
|
type FileUploadResponse struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
File *File `json:"file,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileResponse type
|
||||||
|
type FileResponse struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
File *File `json:"file,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// CustomFieldsResponse type
|
// CustomFieldsResponse type
|
||||||
type CustomFieldsResponse struct {
|
type CustomFieldsResponse struct {
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
@ -401,6 +420,6 @@ type CustomFieldResponse struct {
|
|||||||
|
|
||||||
// UnitsResponse type
|
// UnitsResponse type
|
||||||
type UnitsResponse struct {
|
type UnitsResponse struct {
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
Units *[]Unit `json:"units,omitempty,brackets"`
|
Units *[]Unit `json:"units,omitempty,brackets"`
|
||||||
}
|
}
|
||||||
|
16
v5/types.go
16
v5/types.go
@ -923,6 +923,22 @@ type Cost struct {
|
|||||||
Sites []string `json:"sites,omitempty,brackets"`
|
Sites []string `json:"sites,omitempty,brackets"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// File type
|
||||||
|
type File struct {
|
||||||
|
ID int `json:"id,omitempty"`
|
||||||
|
Filename string `json:"filename,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
CreatedAt string `json:"createdAt,omitempty"`
|
||||||
|
Size int `json:"size,omitempty"`
|
||||||
|
Attachment []Attachment `json:"attachment,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attachment type
|
||||||
|
type Attachment struct {
|
||||||
|
Customer *Customer `json:"customer,omitempty"`
|
||||||
|
Order *Order `json:"order,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// CustomFields type
|
// CustomFields type
|
||||||
type CustomFields struct {
|
type CustomFields struct {
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
Loading…
Reference in New Issue
Block a user