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 := "DocProcess1.doc" + + "ap-chongqingexamplebucket-1250000000" + + "big/test-${Number}" + + "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 := "test.mp4" + + "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 := "test.mp4" + + "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 {