diff --git a/Makefile b/Makefile
index e3b7aa3..108cfa3 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ help:
.PHONY: test
test:
go test -v -cover -coverprofile cover.out
- go tool cover -html=cover.out -o cover.html
+ go tool cover -html cover.out -o cover.html
.PHONY: lint
lint:
diff --git a/ci_doc_test.go b/ci_doc_test.go
new file mode 100644
index 0000000..8dd2bd1
--- /dev/null
+++ b/ci_doc_test.go
@@ -0,0 +1,203 @@
+package cos
+
+import (
+ "context"
+ "net/http"
+ "testing"
+)
+
+func TestCIService_CreateDocProcessJobs(t *testing.T) {
+ setup()
+ defer teardown()
+ wantBody := "DocProcess" +
+ "" +
+ "png1-1" +
+ "watermark/1/image/aHR0cDovL3Rlc3QwMDUtMTI1MTcwNDcwOC5jb3MuYXAtY2hvbmdxaW5nLm15cWNsb3VkLmNvbS8xLmpwZw==/gravity/southeast" +
+ "p532fdead78444e649e1a4467c1cd19d3"
+
+ mux.HandleFunc("/doc_jobs", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodPost)
+ testHeader(t, r, "Content-Type", "application/xml")
+ testBody(t, r, wantBody)
+ })
+
+ createJobOpt := &CreateDocProcessJobsOptions{
+ Tag: "DocProcess",
+ Input: &DocProcessJobInput{
+ Object: "1.doc",
+ },
+ Operation: &DocProcessJobOperation{
+ Output: &DocProcessJobOutput{
+ Region: "ap-chongqing",
+ Object: "big/test-${Number}",
+ Bucket: "examplebucket-1250000000",
+ },
+ DocProcess: &DocProcessJobDocProcess{
+ TgtType: "png",
+ StartPage: 1,
+ EndPage: -1,
+ ImageParams: "watermark/1/image/aHR0cDovL3Rlc3QwMDUtMTI1MTcwNDcwOC5jb3MuYXAtY2hvbmdxaW5nLm15cWNsb3VkLmNvbS8xLmpwZw==/gravity/southeast",
+ },
+ },
+ QueueId: "p532fdead78444e649e1a4467c1cd19d3",
+ }
+
+ _, _, err := client.CI.CreateDocProcessJobs(context.Background(), createJobOpt)
+ if err != nil {
+ t.Fatalf("CI.CreateDocProcessJobs returned error: %v", err)
+ }
+}
+
+func TestCIService_DescribeDocProcessJob(t *testing.T) {
+ setup()
+ defer teardown()
+
+ jobID := "d13cfd584cd9011ea820b597ad1785a2f"
+ mux.HandleFunc("/doc_jobs"+"/"+jobID, func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ })
+
+ _, _, err := client.CI.DescribeDocProcessJob(context.Background(), jobID)
+
+ if err != nil {
+ t.Fatalf("CI.DescribeDocProcessJob returned error: %v", err)
+ }
+}
+
+func TestCIService_DescribeDocProcessJobs(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/doc_jobs", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ v := values{
+ "queueId": "QueueID",
+ "tag": "DocProcess",
+ }
+ testFormValues(t, r, v)
+ })
+
+ opt := &DescribeDocProcessJobsOptions{
+ QueueId: "QueueID",
+ Tag: "DocProcess",
+ }
+
+ _, _, err := client.CI.DescribeDocProcessJobs(context.Background(), opt)
+
+ if err != nil {
+ t.Fatalf("CI.DescribeDocProcessJobs returned error: %v", err)
+ }
+}
+
+func TestCIService_DescribeDocProcessQueues(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/docqueue", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ v := values{
+ "pageNumber": "1",
+ "pageSize": "2",
+ "queueIds": "p111a8dd208104ce3b11c78398f658ca8,p4318f85d2aa14c43b1dba6f9b78be9b3,aacb2bb066e9c4478834d4196e76c49d3",
+ }
+ testFormValues(t, r, v)
+ })
+
+ opt := &DescribeDocProcessQueuesOptions{
+ QueueIds: "p111a8dd208104ce3b11c78398f658ca8,p4318f85d2aa14c43b1dba6f9b78be9b3,aacb2bb066e9c4478834d4196e76c49d3",
+ PageNumber: 1,
+ PageSize: 2,
+ }
+
+ _, _, err := client.CI.DescribeDocProcessQueues(context.Background(), opt)
+ if err != nil {
+ t.Fatalf("CI.DescribeDocProcessQueues returned error: %v", err)
+ }
+}
+
+func TestCIService_UpdateDocProcessQueue(t *testing.T) {
+ setup()
+ defer teardown()
+
+ queueID := "p2505d57bdf4c4329804b58a6a5fb1572"
+ wantBody := "markjrzhang4p2505d57bdf4c4329804b58a6a5fb1572" +
+ "Active" +
+ "http://google.com/On" +
+ "UrlTransCodingFinish" +
+ ""
+
+ mux.HandleFunc("/docqueue/"+queueID, func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodPut)
+ testBody(t, r, wantBody)
+ })
+
+ opt := &UpdateDocProcessQueueOptions{
+ Name: "markjrzhang4",
+ QueueID: queueID,
+ State: "Active",
+ NotifyConfig: &DocProcessQueueNotifyConfig{
+ Url: "http://google.com/",
+ State: "On",
+ Type: "Url",
+ Event: "TransCodingFinish",
+ },
+ }
+
+ _, _, err := client.CI.UpdateDocProcessQueue(context.Background(), opt)
+ if err != nil {
+ t.Fatalf("CI.DescribeDocProcessQueues returned error: %v", err)
+ }
+}
+
+func TestCIService_DescribeDocProcessBuckets(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/docbucket", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ v := values{
+ "pageNumber": "1",
+ "pageSize": "2",
+ "regions": "ap-shanghai",
+ }
+ testFormValues(t, r, v)
+ })
+
+ opt := &DescribeDocProcessBucketsOptions{
+ Regions: "ap-shanghai",
+ PageNumber: 1,
+ PageSize: 2,
+ }
+
+ _, _, err := client.CI.DescribeDocProcessBuckets(context.Background(), opt)
+ if err != nil {
+ t.Fatalf("CI.DescribeDocProcessBuckets returned error: %v", err)
+ }
+}
+
+func TestCIService_DocPreview(t *testing.T) {
+ setup()
+ defer teardown()
+
+ name := "sample.pdf"
+ mux.HandleFunc("/"+name, func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ v := values{
+ "ci-process": "doc-preview",
+ "page": "1",
+ "ImageParams": "imageMogr2/thumbnail/!50p|watermark/2/text/5pWw5o2u5LiH6LGh/fill/I0ZGRkZGRg==/fontsize/30/dx/20/dy/20",
+ }
+ testFormValues(t, r, v)
+ })
+
+ opt := &DocPreviewOptions{
+ Page: 1,
+ ImageParams: "imageMogr2/thumbnail/!50p|watermark/2/text/5pWw5o2u5LiH6LGh/fill/I0ZGRkZGRg==/fontsize/30/dx/20/dy/20",
+ }
+
+ _, err := client.CI.DocPreview(context.Background(), name, opt)
+ if err != nil {
+ t.Fatalf("CI.DocPreview returned error: %v", err)
+ }
+}
diff --git a/ci_test.go b/ci_test.go
index 5cc1a82..5324345 100644
--- a/ci_test.go
+++ b/ci_test.go
@@ -198,6 +198,99 @@ func TestCIService_ImageRecognition(t *testing.T) {
}
}
+func TestCIService_PutVideoAuditingJob(t *testing.T) {
+ setup()
+ defer teardown()
+ name := "test.mp4"
+ wantBody := "" +
+ "Porn,Terrorism,Politics,Ads" +
+ "Interval100500.5" +
+ "http://callback.com/call_back_test"
+
+ mux.HandleFunc("/video/auditing", func(writer http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodPost)
+ testHeader(t, r, "Content-Type", "application/xml")
+ testBody(t, r, wantBody)
+ })
+
+ opt := &PutVideoAuditingJobOptions{
+ InputObject: name,
+ Conf: &VideoAuditingJobConf{
+ DetectType: "Porn,Terrorism,Politics,Ads",
+ Snapshot: &PutVideoAuditingJobSnapshot{
+ Mode: "Interval",
+ Count: 100,
+ TimeInterval: 50,
+ Start: 0.5,
+ },
+ Callback: "http://callback.com/call_back_test",
+ },
+ }
+
+ _, _, err := client.CI.PutVideoAuditingJob(context.Background(), opt)
+ if err != nil {
+ t.Fatalf("CI.PutVideoAuditingJob returned error: %v", err)
+ }
+}
+
+func TestCIService_GetVideoAuditingJob(t *testing.T) {
+ setup()
+ defer teardown()
+ jobID := "vab1ca9fc8a3ed11ea834c525400863904"
+
+ mux.HandleFunc("/video/auditing"+"/"+jobID, func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ })
+
+ _, _, err := client.CI.GetVideoAuditingJob(context.Background(), jobID)
+ if err != nil {
+ t.Fatalf("CI.GetVideoAuditingJob returned error: %v", err)
+ }
+}
+
+func TestCIService_PutAudioAuditingJob(t *testing.T) {
+ setup()
+ defer teardown()
+ name := "test.mp4"
+ wantBody := "" +
+ "Porn,Terrorism,Politics,Ads" +
+ "http://callback.com/call_back_test"
+
+ mux.HandleFunc("/audio/auditing", func(writer http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodPost)
+ testHeader(t, r, "Content-Type", "application/xml")
+ testBody(t, r, wantBody)
+ })
+
+ opt := &PutAudioAuditingJobOptions{
+ InputObject: name,
+ Conf: &AudioAuditingJobConf{
+ DetectType: "Porn,Terrorism,Politics,Ads",
+ Callback: "http://callback.com/call_back_test",
+ },
+ }
+
+ _, _, err := client.CI.PutAudioAuditingJob(context.Background(), opt)
+ if err != nil {
+ t.Fatalf("CI.PutAudioAuditingJob returned error: %v", err)
+ }
+}
+
+func TestCIService_GetAudioAuditingJob(t *testing.T) {
+ setup()
+ defer teardown()
+ jobID := "vab1ca9fc8a3ed11ea834c525400863904"
+
+ mux.HandleFunc("/audio/auditing"+"/"+jobID, func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ })
+
+ _, _, err := client.CI.GetAudioAuditingJob(context.Background(), jobID)
+ if err != nil {
+ t.Fatalf("CI.GetAudioAuditingJob returned error: %v", err)
+ }
+}
+
func TestCIService_Put(t *testing.T) {
setup()
defer teardown()
@@ -431,6 +524,121 @@ func TestCIService_PutFromFile(t *testing.T) {
}
}
+func TestCIService_Get(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ vs := values{
+ "imageMogr2/thumbnail/!50p": "",
+ }
+ testFormValues(t, r, vs)
+ })
+
+ _, err := client.CI.Get(context.Background(), "test.jpg", "imageMogr2/thumbnail/!50p", nil)
+ if err != nil {
+ t.Fatalf("CI.Get returned error: %v", err)
+ }
+}
+
+func TestCIService_GetToFile(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ vs := values{
+ "imageMogr2/thumbnail/!50p": "",
+ }
+ testFormValues(t, r, vs)
+ })
+
+ filepath := "test.jpg." + time.Now().Format(time.RFC3339)
+ defer os.Remove(filepath)
+
+ _, err := client.CI.GetToFile(context.Background(), "test.jpg", filepath, "imageMogr2/thumbnail/!50p", nil)
+ if err != nil {
+ t.Fatalf("CI.GetToFile returned error: %v", err)
+ }
+}
+
+func TestCIService_GetQRcode(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ vs := values{
+ "ci-process": "QRcode",
+ "cover": "1",
+ }
+ testFormValues(t, r, vs)
+ })
+
+ _, _, err := client.CI.GetQRcode(context.Background(), "test.jpg", 1, nil)
+ if err != nil {
+ t.Fatalf("CI.GetQRcode returned error: %v", err)
+ }
+}
+
+func TestCIService_GenerateQRcode(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ vs := values{
+ "ci-process": "qrcode-generate",
+ "qrcode-content": "",
+ "mode": "1",
+ "width": "200",
+ }
+ testFormValues(t, r, vs)
+ })
+
+ opt := &GenerateQRcodeOptions{
+ QRcodeContent: "",
+ Mode: 1,
+ Width: 200,
+ }
+
+ _, _, err := client.CI.GenerateQRcode(context.Background(), opt)
+ if err != nil {
+ t.Fatalf("CI.GenerateQRcode returned error: %v", err)
+ }
+}
+
+func TestCIService_GenerateQRcodeToFile(t *testing.T) {
+ setup()
+ defer teardown()
+
+ mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodGet)
+ vs := values{
+ "ci-process": "qrcode-generate",
+ "qrcode-content": "",
+ "mode": "1",
+ "width": "200",
+ }
+ testFormValues(t, r, vs)
+ })
+
+ opt := &GenerateQRcodeOptions{
+ QRcodeContent: "",
+ Mode: 1,
+ Width: 200,
+ }
+
+ filepath := "test.file." + time.Now().Format(time.RFC3339)
+ defer os.Remove(filepath)
+
+ _, _, err := client.CI.GenerateQRcodeToFile(context.Background(), filepath, opt)
+ if err != nil {
+ t.Fatalf("CI.GenerateQRcode returned error: %v", err)
+ }
+}
+
func TestBucketService_GetGuetzli(t *testing.T) {
setup()
defer teardown()
diff --git a/object.go b/object.go
index 5d7fed2..28a1de5 100644
--- a/object.go
+++ b/object.go
@@ -150,7 +150,6 @@ func (s *ObjectService) GetPresignedURL(ctx context.Context, httpMethod, name, a
req.URL.RawQuery = fmt.Sprintf("%s&%s", req.URL.RawQuery, sign)
}
return req.URL, nil
-
}
// ObjectPutHeaderOptions the options of header of the put object
diff --git a/object_test.go b/object_test.go
index 414ff29..cd37452 100644
--- a/object_test.go
+++ b/object_test.go
@@ -6,6 +6,7 @@ import (
"crypto/rand"
"encoding/hex"
"encoding/xml"
+ "errors"
"fmt"
"hash/crc64"
"io"
@@ -100,6 +101,43 @@ func TestObjectService_GetToFile(t *testing.T) {
}
}
+func TestObjectService_GetPresignedURL(t *testing.T) {
+ setup()
+ defer teardown()
+
+ exceptSign := "q-sign-algorithm=sha1&q-ak=QmFzZTY0IGlzIGEgZ*******&q-sign-time=1622702557;1622706157&q-key-time=1622702557;1622706157&q-header-list=&q-url-param-list=&q-signature=0f359fe9d29e7fa0c738ce6c8feaf4ed1e84f287"
+ exceptURL := &url.URL{
+ Scheme: "http",
+ Host: client.Host,
+ Path: "/test.jpg",
+ RawQuery: exceptSign,
+ }
+
+ c := context.Background()
+ name := "test.jpg"
+ ak := "QmFzZTY0IGlzIGEgZ*******"
+ sk := "ZfbOA78asKUYBcXFrJD0a1I*******"
+ startTime := time.Unix(int64(1622702557), 0)
+ endTime := time.Unix(int64(1622706157), 0)
+ opt := presignedURLTestingOptions{
+ authTime: &AuthTime{
+ SignStartTime: startTime,
+ SignEndTime: endTime,
+ KeyStartTime: startTime,
+ KeyEndTime: endTime,
+ },
+ }
+
+ presignedURL, err := client.Object.GetPresignedURL(c, http.MethodPut, name, ak, sk, time.Hour, opt)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if reflect.DeepEqual(exceptURL, presignedURL) {
+ t.Fatalf("Wrong PreSignedURL!")
+ }
+}
+
func TestObjectService_Put(t *testing.T) {
setup()
defer teardown()
@@ -280,6 +318,35 @@ func TestObjectService_Options(t *testing.T) {
}
+func TestObjectService_PostRestore(t *testing.T) {
+ setup()
+ defer teardown()
+ name := "test/hello.txt"
+ wantBody := "3Expedited"
+
+ mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, http.MethodPost)
+ testHeader(t, r, "Content-Type", "application/xml")
+ testHeader(t, r, "Content-Length", "106")
+ //b, _ := ioutil.ReadAll(r.Body)
+ //fmt.Printf("%s", string(b))
+ testBody(t, r, wantBody)
+ })
+
+ opt := &ObjectRestoreOptions{
+ Days: 3,
+ Tier: &CASJobParameters{
+ Tier: "Expedited",
+ },
+ }
+
+ _, err := client.Object.PostRestore(context.Background(), name, opt)
+ if err != nil {
+ t.Fatalf("Object.PostRestore returned error: %v", err)
+ }
+
+}
+
// func TestObjectService_Append(t *testing.T) {
// setup()
// defer teardown()
@@ -384,6 +451,38 @@ func TestObjectService_DeleteMulti(t *testing.T) {
}
+func TestObiectService_Read_and_Close(t *testing.T) {
+ data := make([]byte, 1024*10)
+ rand.Read(data)
+ body := bytes.NewReader(data)
+ r, _ := http.NewRequest(http.MethodGet, "test", body)
+
+ drc := DiscardReadCloser{
+ RC: r.Body,
+ Discard: 10,
+ }
+
+ res := make([]byte, 1024*10)
+ readLen, err := drc.Read(res)
+ if err != nil {
+ t.Fatalf("Object.Read returned %v", err)
+ }
+ if readLen != 10230 {
+ t.Fatalf("Object.Read returned %#v, excepted %#v", readLen, 10230)
+ }
+ if drc.Discard != 0 {
+ t.Fatalf("Object.Read: drc.Discard = %v, excepted %v", drc.Discard, 0)
+ }
+ if !reflect.DeepEqual(res[:10230], data[10:]) {
+ t.Fatalf("Object.Read: Wrong data!")
+ }
+
+ err = drc.Close()
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
func TestObjectService_Copy(t *testing.T) {
setup()
defer teardown()
@@ -396,6 +495,13 @@ func TestObjectService_Copy(t *testing.T) {
`)
})
+ wrongURL := "wrongURL"
+ _, _, err := client.Object.Copy(context.Background(), "test.go.copy", wrongURL, nil)
+ exceptedErr := errors.New(fmt.Sprintf("x-cos-copy-source format error: %s", wrongURL))
+ if !reflect.DeepEqual(err, exceptedErr) {
+ t.Fatalf("Object.Copy returned %#v, excepted %#v", err, exceptedErr)
+ }
+
sourceURL := "test-1253846586.cos.ap-guangzhou.myqcloud.com/test.source"
ref, _, err := client.Object.Copy(context.Background(), "test.go.copy", sourceURL, nil)
if err != nil {