This is an automated email from the ASF dual-hosted git repository.

klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 412f8113a update sprint's url field (#5970)
412f8113a is described below

commit 412f8113a7baf0e0d61c4e99bb70478d7ec04de0
Author: Lynwee <[email protected]>
AuthorDate: Wed Aug 30 19:34:25 2023 +0800

    update sprint's url field (#5970)
    
    * fix(zentao): fix zentao projects's url, add possible prefix
    
    * fix(zentao): fix sprint's url field
    
    * fix(zentao): fix e2e test
    
    * fix(zentao): fix e2e test
    
    * fix(zentao): remove test zentao system's url
    
    * fix(zentao): fix e2e test error
---
 backend/core/runner/basic_res.go                   |  2 +-
 backend/go.mod                                     |  4 --
 backend/go.sum                                     | 11 ------
 backend/plugins/zentao/e2e/account_test.go         | 21 ++++++++++-
 backend/plugins/zentao/e2e/bug_commits_test.go     |  1 +
 backend/plugins/zentao/e2e/bug_test.go             |  1 +
 backend/plugins/zentao/e2e/changelog_test.go       |  7 ++--
 backend/plugins/zentao/e2e/execution_test.go       |  1 +
 .../e2e/snapshot_tables/execution_sprint.csv       |  4 +-
 backend/plugins/zentao/e2e/story_commits_test.go   |  1 +
 backend/plugins/zentao/e2e/story_test.go           |  1 +
 backend/plugins/zentao/e2e/task_commits_test.go    |  1 +
 backend/plugins/zentao/e2e/task_test.go            |  1 +
 .../plugins/zentao/tasks/execution_convertor.go    | 11 +++++-
 backend/plugins/zentao/tasks/project_convertor.go  | 20 +++-------
 backend/plugins/zentao/tasks/shared.go             | 16 ++++++++
 backend/plugins/zentao/tasks/shared_test.go        | 43 ++++++++++++++++++++++
 17 files changed, 108 insertions(+), 38 deletions(-)

diff --git a/backend/core/runner/basic_res.go b/backend/core/runner/basic_res.go
index a4c930ae9..7694d134d 100644
--- a/backend/core/runner/basic_res.go
+++ b/backend/core/runner/basic_res.go
@@ -33,7 +33,7 @@ import (
 var app_lock sync.Mutex
 var app_inited bool
 
-// CreateAppBasicRes returns a application level BasicRes instance based on 
.env/environment variables
+// CreateAppBasicRes returns an application level BasicRes instance based on 
.env/environment variables
 // it is useful because multiple places need BasicRes including `main.go` 
`directrun` and `worker`
 // keep in mind this function can be called only once
 func CreateAppBasicRes() context.BasicRes {
diff --git a/backend/go.mod b/backend/go.mod
index 2e62a878e..46e741447 100644
--- a/backend/go.mod
+++ b/backend/go.mod
@@ -30,7 +30,6 @@ require (
        github.com/swaggo/swag v1.16.1
        github.com/tidwall/gjson v1.14.3
        github.com/viant/afs v1.16.0
-       github.com/x-cray/logrus-prefixed-formatter v0.5.2
        go.temporal.io/api v1.7.1-0.20220223032354-6e6fe738916a
        go.temporal.io/sdk v1.14.0
        golang.org/x/crypto v0.9.0
@@ -91,9 +90,7 @@ require (
        github.com/kr/text v0.2.0 // indirect
        github.com/leodido/go-urn v1.2.4 // indirect
        github.com/mailru/easyjson v0.7.7 // indirect
-       github.com/mattn/go-colorable v0.1.11 // indirect
        github.com/mattn/go-isatty v0.0.19 // indirect
-       github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
        github.com/mitchellh/go-homedir v1.1.0 // indirect
        github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // 
indirect
        github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -118,7 +115,6 @@ require (
        golang.org/x/arch v0.3.0 // indirect
        golang.org/x/net v0.10.0 // indirect
        golang.org/x/sys v0.8.0 // indirect
-       golang.org/x/term v0.8.0 // indirect
        golang.org/x/text v0.9.0 // indirect
        golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
        golang.org/x/tools v0.9.3 // indirect
diff --git a/backend/go.sum b/backend/go.sum
index 922a3a2e8..9312912a2 100644
--- a/backend/go.sum
+++ b/backend/go.sum
@@ -485,7 +485,6 @@ github.com/mattn/go-colorable v0.1.1/go.mod 
h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcncea
 github.com/mattn/go-colorable v0.1.2/go.mod 
h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.6/go.mod 
h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.8/go.mod 
h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.11 
h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
 github.com/mattn/go-colorable v0.1.11/go.mod 
h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 github.com/mattn/go-isatty v0.0.3/go.mod 
h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.5/go.mod 
h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -504,8 +503,6 @@ github.com/mediocregopher/radix/v3 v3.3.0/go.mod 
h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQ
 github.com/mediocregopher/radix/v3 v3.4.2/go.mod 
h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
 github.com/merico-dev/graphql v0.0.0-20221027131946-77460a1fd4cd 
h1:hGQXd4a72JSFIZE+ZVkH5ivE925PGogjob6stgc2too=
 github.com/merico-dev/graphql v0.0.0-20221027131946-77460a1fd4cd/go.mod 
h1:dcDqG8HXVtfEhTCipFMa0Q+RTKTtDKIO2vJt+JVzHEQ=
-github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d 
h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
-github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod 
h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
 github.com/microcosm-cc/bluemonday v1.0.2/go.mod 
h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
 github.com/miekg/dns v1.0.14/go.mod 
h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/mitchellh/cli v1.0.0/go.mod 
h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@@ -535,15 +532,12 @@ github.com/nats-io/nkeys v0.0.2/go.mod 
h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7
 github.com/nats-io/nkeys v0.1.0/go.mod 
h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
 github.com/nats-io/nuid v1.0.1/go.mod 
h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod 
h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
 github.com/nxadm/tail v1.4.4/go.mod 
h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 github.com/onsi/ginkgo v1.6.0/go.mod 
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.3/go.mod 
h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod 
h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
-github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
 github.com/onsi/ginkgo v1.13.0/go.mod 
h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
 github.com/onsi/gomega v1.7.1/go.mod 
h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
 github.com/onsi/gomega v1.10.1/go.mod 
h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/opentracing/opentracing-go v1.1.0/go.mod 
h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/panjf2000/ants/v2 v2.4.6 
h1:drmj9mcygn2gawZ155dRbo+NfXEfAssjZNU1qoIb4gQ=
@@ -671,8 +665,6 @@ github.com/valyala/fasttemplate v1.2.1/go.mod 
h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
 github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod 
h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
 github.com/viant/afs v1.16.0 h1:yb9TQ1gjVVLji9lcXLWaarklqmGWeXTZOwc2fwJevCI=
 github.com/viant/afs v1.16.0/go.mod 
h1:wdiEDffZKJwj1ZSFasy7hHoxLQdSpFZkd3XOWNt1aN0=
-github.com/x-cray/logrus-prefixed-formatter v0.5.2 
h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
-github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod 
h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
 github.com/xanzy/ssh-agent v0.3.0 
h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
 github.com/xanzy/ssh-agent v0.3.0/go.mod 
h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod 
h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -937,7 +929,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9sn
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod 
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod 
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1024,7 +1015,6 @@ golang.org/x/xerrors 
v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 
h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.4.0/go.mod 
h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/api v0.7.0/go.mod 
h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@@ -1156,7 +1146,6 @@ gopkg.in/ini.v1 v1.51.1/go.mod 
h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod 
h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 
h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod 
h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
 gopkg.in/warnings.v0 v0.1.2/go.mod 
h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
diff --git a/backend/plugins/zentao/e2e/account_test.go 
b/backend/plugins/zentao/e2e/account_test.go
index 4204ee713..04ec31a6f 100644
--- a/backend/plugins/zentao/e2e/account_test.go
+++ b/backend/plugins/zentao/e2e/account_test.go
@@ -18,16 +18,32 @@ limitations under the License.
 package e2e
 
 import (
-       "testing"
-
+       gocontext "context"
        "github.com/apache/incubator-devlake/core/models/common"
        
"github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain"
+       "github.com/apache/incubator-devlake/core/runner"
        "github.com/apache/incubator-devlake/helpers/e2ehelper"
+       helper "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
        "github.com/apache/incubator-devlake/plugins/zentao/impl"
        "github.com/apache/incubator-devlake/plugins/zentao/models"
        "github.com/apache/incubator-devlake/plugins/zentao/tasks"
+       "testing"
+       "time"
 )
 
+var basicContext = runner.CreateAppBasicRes()
+
+func getFakeAPIClient() *helper.ApiAsyncClient {
+       client, _ := helper.NewApiClient(gocontext.Background(),
+               "https://zentao.demo.haogs.cn/api.php/v1/";,
+               nil, time.Second*5, "",
+               basicContext,
+       )
+       return &helper.ApiAsyncClient{
+               ApiClient: client,
+       }
+}
+
 func TestZentaoAccountDataFlow(t *testing.T) {
 
        var zentao impl.Zentao
@@ -39,6 +55,7 @@ func TestZentaoAccountDataFlow(t *testing.T) {
                        ProjectId:    3,
                },
                AccountCache: tasks.NewAccountCache(dataflowTester.Dal, 1),
+               ApiClient:    getFakeAPIClient(),
        }
 
        // import raw data table
diff --git a/backend/plugins/zentao/e2e/bug_commits_test.go 
b/backend/plugins/zentao/e2e/bug_commits_test.go
index cc72f1021..0b5ab4b0e 100644
--- a/backend/plugins/zentao/e2e/bug_commits_test.go
+++ b/backend/plugins/zentao/e2e/bug_commits_test.go
@@ -38,6 +38,7 @@ func TestZentaoBugCommitsDataFlow(t *testing.T) {
                        ConnectionId: 1,
                        ProjectId:    22,
                },
+               ApiClient: getFakeAPIClient(),
        }
 
        // import _raw_zentao_api_bug_commits raw data table
diff --git a/backend/plugins/zentao/e2e/bug_test.go 
b/backend/plugins/zentao/e2e/bug_test.go
index c1397d408..cc8f16896 100644
--- a/backend/plugins/zentao/e2e/bug_test.go
+++ b/backend/plugins/zentao/e2e/bug_test.go
@@ -48,6 +48,7 @@ func TestZentaoBugDataFlow(t *testing.T) {
                },
                Bugs:         map[int64]struct{}{},
                AccountCache: tasks.NewAccountCache(dataflowTester.Dal, 1),
+               ApiClient:    getFakeAPIClient(),
        }
 
        // import raw data table
diff --git a/backend/plugins/zentao/e2e/changelog_test.go 
b/backend/plugins/zentao/e2e/changelog_test.go
index bd52b6603..b0d38ed40 100644
--- a/backend/plugins/zentao/e2e/changelog_test.go
+++ b/backend/plugins/zentao/e2e/changelog_test.go
@@ -43,9 +43,10 @@ func TestZentaoDbGetDataFlow(t *testing.T) {
                        ConnectionId: 1,
                        ProjectId:    0,
                },
-               Stories: map[int64]struct{}{},
-               Tasks:   map[int64]struct{}{10: {}, 11: {}, 14: {}},
-               Bugs:    map[int64]struct{}{1: {}, 2: {}, 3: {}, 4: {}},
+               Stories:   map[int64]struct{}{},
+               Tasks:     map[int64]struct{}{10: {}, 11: {}, 14: {}},
+               Bugs:      map[int64]struct{}{1: {}, 2: {}, 3: {}, 4: {}},
+               ApiClient: getFakeAPIClient(),
        }
 
        dataflowTester.ImportCsvIntoTabler("./raw_tables/zt_action.csv", 
models.ZentaoRemoteDbAction{})
diff --git a/backend/plugins/zentao/e2e/execution_test.go 
b/backend/plugins/zentao/e2e/execution_test.go
index 908d2ac5a..8fa7f8658 100644
--- a/backend/plugins/zentao/e2e/execution_test.go
+++ b/backend/plugins/zentao/e2e/execution_test.go
@@ -38,6 +38,7 @@ func TestZentaoExecutionDataFlow(t *testing.T) {
                        ConnectionId: 1,
                        ProjectId:    1,
                },
+               ApiClient: getFakeAPIClient(),
        }
 
        // import raw data table
diff --git a/backend/plugins/zentao/e2e/snapshot_tables/execution_sprint.csv 
b/backend/plugins/zentao/e2e/snapshot_tables/execution_sprint.csv
index 74bb7e65e..32e8e2b1b 100644
--- a/backend/plugins/zentao/e2e/snapshot_tables/execution_sprint.csv
+++ b/backend/plugins/zentao/e2e/snapshot_tables/execution_sprint.csv
@@ -1,3 +1,3 @@
 id,name,url,status,started_date,ended_date,completed_date,original_board_id
-zentao:ZentaoExecution:1:1,企业网站第一期,",7,1,",ACTIVE,,2022-06-01T00:00:00.000+00:00,,zentao:ZentaoProject:1:1
-zentao:ZentaoExecution:1:12,TR5,",1091,12,",CLOSED,2022-07-07T00:00:00.000+00:00,2022-11-03T00:00:00.000+00:00,,zentao:ZentaoProject:1:1
+zentao:ZentaoExecution:1:1,企业网站第一期,https://zentao.demo.haogs.cn/execution-view-1.html,ACTIVE,,2022-06-01T00:00:00.000+00:00,,zentao:ZentaoProject:1:1
+zentao:ZentaoExecution:1:12,TR5,https://zentao.demo.haogs.cn/execution-view-12.html,CLOSED,2022-07-07T00:00:00.000+00:00,2022-11-03T00:00:00.000+00:00,,zentao:ZentaoProject:1:1
diff --git a/backend/plugins/zentao/e2e/story_commits_test.go 
b/backend/plugins/zentao/e2e/story_commits_test.go
index 968c46e11..e3932d426 100644
--- a/backend/plugins/zentao/e2e/story_commits_test.go
+++ b/backend/plugins/zentao/e2e/story_commits_test.go
@@ -38,6 +38,7 @@ func TestZentaoStoryCommitsDataFlow(t *testing.T) {
                        ConnectionId: 1,
                        ProjectId:    1,
                },
+               ApiClient: getFakeAPIClient(),
        }
 
        // import _raw_zentao_api_story_commits raw data table
diff --git a/backend/plugins/zentao/e2e/story_test.go 
b/backend/plugins/zentao/e2e/story_test.go
index c02b8dfcf..baf06e887 100644
--- a/backend/plugins/zentao/e2e/story_test.go
+++ b/backend/plugins/zentao/e2e/story_test.go
@@ -48,6 +48,7 @@ func TestZentaoStoryDataFlow(t *testing.T) {
                },
                Stories:      map[int64]struct{}{},
                AccountCache: tasks.NewAccountCache(dataflowTester.Dal, 1),
+               ApiClient:    getFakeAPIClient(),
        }
 
        // import raw data table
diff --git a/backend/plugins/zentao/e2e/task_commits_test.go 
b/backend/plugins/zentao/e2e/task_commits_test.go
index eb1e79bf5..ff85f961b 100644
--- a/backend/plugins/zentao/e2e/task_commits_test.go
+++ b/backend/plugins/zentao/e2e/task_commits_test.go
@@ -38,6 +38,7 @@ func TestZentaoTaskCommitsDataFlow(t *testing.T) {
                        ConnectionId: 1,
                        ProjectId:    48,
                },
+               ApiClient: getFakeAPIClient(),
        }
 
        // import _raw_zentao_api_task_commits raw data table
diff --git a/backend/plugins/zentao/e2e/task_test.go 
b/backend/plugins/zentao/e2e/task_test.go
index 79f39cdef..1a2fbbe8d 100644
--- a/backend/plugins/zentao/e2e/task_test.go
+++ b/backend/plugins/zentao/e2e/task_test.go
@@ -51,6 +51,7 @@ func TestZentaoTaskDataFlow(t *testing.T) {
                },
                Tasks:        map[int64]struct{}{},
                AccountCache: tasks.NewAccountCache(dataflowTester.Dal, 1),
+               ApiClient:    getFakeAPIClient(),
        }
 
        // import raw data table
diff --git a/backend/plugins/zentao/tasks/execution_convertor.go 
b/backend/plugins/zentao/tasks/execution_convertor.go
index 9324e8eec..e24225c6d 100644
--- a/backend/plugins/zentao/tasks/execution_convertor.go
+++ b/backend/plugins/zentao/tasks/execution_convertor.go
@@ -18,6 +18,7 @@ limitations under the License.
 package tasks
 
 import (
+       "fmt"
        "reflect"
 
        "github.com/apache/incubator-devlake/core/dal"
@@ -43,6 +44,7 @@ var ConvertExecutionMeta = plugin.SubTaskMeta{
 func ConvertExecutions(taskCtx plugin.SubTaskContext) errors.Error {
        data := taskCtx.GetData().(*ZentaoTaskData)
        db := taskCtx.GetDal()
+       logger := taskCtx.GetLogger()
        executionIdGen := didgen.NewDomainIdGenerator(&models.ZentaoExecution{})
        projectIdGen := didgen.NewDomainIdGenerator(&models.ZentaoProject{})
        cursor, err := db.Cursor(
@@ -52,6 +54,12 @@ func ConvertExecutions(taskCtx plugin.SubTaskContext) 
errors.Error {
        if err != nil {
                return err
        }
+
+       homePage, getZentaoHomePageErr := 
getZentaoHomePage(data.ApiClient.GetEndpoint())
+       if getZentaoHomePageErr != nil {
+               logger.Error(getZentaoHomePageErr, "get zentao homepage")
+               return errors.Default.WrapRaw(getZentaoHomePageErr)
+       }
        defer cursor.Close()
        convertor, err := api.NewDataConverter(api.DataConverterArgs{
                InputRowType: reflect.TypeOf(models.ZentaoExecution{}),
@@ -82,13 +90,14 @@ func ConvertExecutions(taskCtx plugin.SubTaskContext) 
errors.Error {
                                        Id: 
executionIdGen.Generate(toolExecution.ConnectionId, toolExecution.Id),
                                },
                                Name:            toolExecution.Name,
-                               Url:             toolExecution.Path,
+                               Url:             
fmt.Sprintf("%s/execution-view-%d.html", homePage, toolExecution.Id),
                                Status:          domainStatus,
                                StartedDate:     
toolExecution.RealBegan.ToNullableTime(),
                                EndedDate:       
toolExecution.PlanEnd.ToNullableTime(),
                                CompletedDate:   
toolExecution.RealEnd.ToNullableTime(),
                                OriginalBoardID: 
projectIdGen.Generate(toolExecution.ConnectionId, data.Options.ProjectId),
                        }
+
                        boardSprint := &ticket.BoardSprint{
                                BoardId:  sprint.OriginalBoardID,
                                SprintId: sprint.Id,
diff --git a/backend/plugins/zentao/tasks/project_convertor.go 
b/backend/plugins/zentao/tasks/project_convertor.go
index 2c392854a..b09ef9405 100644
--- a/backend/plugins/zentao/tasks/project_convertor.go
+++ b/backend/plugins/zentao/tasks/project_convertor.go
@@ -19,9 +19,6 @@ package tasks
 
 import (
        "fmt"
-       "net/url"
-       "reflect"
-
        "github.com/apache/incubator-devlake/core/dal"
        "github.com/apache/incubator-devlake/core/errors"
        "github.com/apache/incubator-devlake/core/models/domainlayer"
@@ -30,6 +27,7 @@ import (
        "github.com/apache/incubator-devlake/core/plugin"
        "github.com/apache/incubator-devlake/helpers/pluginhelper/api"
        "github.com/apache/incubator-devlake/plugins/zentao/models"
+       "reflect"
 )
 
 const RAW_PROJECT_TABLE = "zentao_api_projects"
@@ -57,16 +55,10 @@ func ConvertProjects(taskCtx plugin.SubTaskContext) 
errors.Error {
                return err
        }
        defer cursor.Close()
-       var protocol, host string
-       endpoint := data.ApiClient.ApiClient.GetEndpoint()
-       if endpoint != "" {
-               endpointURL, err := url.Parse(endpoint)
-               if err != nil {
-                       logger.Error(err, "parse: %s", endpoint)
-               } else {
-                       protocol = endpointURL.Scheme
-                       host = endpointURL.Host
-               }
+       homePage, getZentaoHomePageErr := 
getZentaoHomePage(data.ApiClient.GetEndpoint())
+       if getZentaoHomePageErr != nil {
+               logger.Error(getZentaoHomePageErr, "get zentao homepage")
+               return errors.Default.WrapRaw(getZentaoHomePageErr)
        }
        convertor, err := api.NewDataConverter(api.DataConverterArgs{
                InputRowType: reflect.TypeOf(models.ZentaoProject{}),
@@ -87,7 +79,7 @@ func ConvertProjects(taskCtx plugin.SubTaskContext) 
errors.Error {
                                Description: toolProject.Description,
                                CreatedDate: 
toolProject.OpenedDate.ToNullableTime(),
                                Type:        "scrum",
-                               Url:         
fmt.Sprintf("%s://%s/project-index-%d.html", protocol, host, 
data.Options.ProjectId),
+                               Url:         
fmt.Sprintf("%s/project-index-%d.html", homePage, data.Options.ProjectId),
                        }
                        results := make([]interface{}, 0)
                        results = append(results, domainBoard)
diff --git a/backend/plugins/zentao/tasks/shared.go 
b/backend/plugins/zentao/tasks/shared.go
index f02c7f885..158a7709d 100644
--- a/backend/plugins/zentao/tasks/shared.go
+++ b/backend/plugins/zentao/tasks/shared.go
@@ -339,3 +339,19 @@ func extractIdFromLogComment(logCommentType string, 
comment string) ([]string, e
        }
        return ret, nil
 }
+
+// getZentaoHomePage receive endpoint like 
"http://54.158.1.10:30001/api.php/v1/"; and return zentao's homepage like 
"http://54.158.1.10:30001/";
+func getZentaoHomePage(endpoint string) (string, error) {
+       if endpoint == "" {
+               return "", errors.Default.New("empty endpoint")
+       }
+       endpointURL, err := url.Parse(endpoint)
+       if err != nil {
+               return "", err
+       } else {
+               protocol := endpointURL.Scheme
+               host := endpointURL.Host
+               zentaoPath, _, _ := strings.Cut(endpointURL.Path, "/api.php/v1")
+               return fmt.Sprintf("%s://%s%s", protocol, host, zentaoPath), nil
+       }
+}
diff --git a/backend/plugins/zentao/tasks/shared_test.go 
b/backend/plugins/zentao/tasks/shared_test.go
index 3dfc5d8eb..3bec1ca23 100644
--- a/backend/plugins/zentao/tasks/shared_test.go
+++ b/backend/plugins/zentao/tasks/shared_test.go
@@ -152,3 +152,46 @@ func Test_extractIdFromLogComment(t *testing.T) {
                })
        }
 }
+
+func Test_getZentaoWebURL(t *testing.T) {
+       type args struct {
+               endpoint string
+       }
+       tests := []struct {
+               name    string
+               args    args
+               want    string
+               wantErr bool
+       }{
+               {
+                       name:    "without-zentao",
+                       args:    args{endpoint: 
"http://54.158.1.10:30001/api.php/v1/"},
+                       want:    "http://54.158.1.10:30001";,
+                       wantErr: false,
+               },
+               {
+                       name:    "with-zentao",
+                       args:    args{endpoint: 
"http://54.158.1.10:30001/zentao/api.php/v1/"},
+                       want:    "http://54.158.1.10:30001/zentao";,
+                       wantErr: false,
+               },
+               {
+                       name:    "with-others",
+                       args:    args{endpoint: 
"http://54.158.1.10:30001/abc/api.php/v1/"},
+                       want:    "http://54.158.1.10:30001/abc";,
+                       wantErr: false,
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       got, err := getZentaoHomePage(tt.args.endpoint)
+                       if (err != nil) != tt.wantErr {
+                               t.Errorf("getZentaoHomePage() error = %v, 
wantErr %v", err, tt.wantErr)
+                               return
+                       }
+                       if got != tt.want {
+                               t.Errorf("getZentaoHomePage() got = %v, want 
%v", got, tt.want)
+                       }
+               })
+       }
+}

Reply via email to