You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@devlake.apache.org by li...@apache.org on 2023/02/16 10:38:02 UTC

[incubator-devlake] branch main updated: fix(plugins): unify test connection response (#4433)

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

likyh 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 86199d74a fix(plugins): unify test connection response (#4433)
86199d74a is described below

commit 86199d74a4ec6bc6928be879ac229776856cf48f
Author: Warren Chen <yi...@merico.dev>
AuthorDate: Thu Feb 16 18:37:56 2023 +0800

    fix(plugins): unify test connection response (#4433)
    
    * fix(plugins): unify test connection response
    
    * fix(generator): modify connection
---
 .../template/plugin/api/connection.go-template     | 84 +++++++++++++---------
 backend/plugins/azure/api/connection.go            | 27 ++++---
 backend/plugins/bitbucket/api/connection.go        | 16 ++++-
 backend/plugins/feishu/api/connection.go           | 18 ++++-
 backend/plugins/gitee/api/connection.go            | 15 +++-
 backend/plugins/jenkins/api/connection.go          | 15 +++-
 backend/plugins/jira/api/connection.go             | 18 ++++-
 backend/plugins/sonarqube/api/connection.go        | 35 +++++----
 backend/plugins/sonarqube/api/remote.go            |  2 +-
 backend/plugins/tapd/api/connection.go             | 14 +++-
 backend/plugins/zentao/api/connection.go           | 28 +++++---
 11 files changed, 193 insertions(+), 79 deletions(-)

diff --git a/backend/generator/template/plugin/api/connection.go-template b/backend/generator/template/plugin/api/connection.go-template
index 3067f57b5..05afe7662 100644
--- a/backend/generator/template/plugin/api/connection.go-template
+++ b/backend/generator/template/plugin/api/connection.go-template
@@ -30,6 +30,14 @@ import (
 )
 
 //TODO Please modify the following code to fit your needs
+// @Summary test {{ .pluginName }} connection
+// @Description Test {{ .pluginName }} Connection. endpoint: "https://dev.{{ .pluginName }}.com/{organization}/
+// @Tags plugins/{{ .pluginName }}
+// @Param body body models.{{ .PluginName }}Conn true "json body"
+// @Success 200  {object} {{ .PluginName }}TestConnResponse "Success"
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /plugins/{{ .pluginName }}/test [POST]
 func TestConnection(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
 	// decode
 	var err errors.Error
@@ -65,19 +73,23 @@ func TestConnection(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, er
 	if res.StatusCode != http.StatusOK {
 		return nil, errors.HttpStatus(res.StatusCode).New(fmt.Sprintf("unexpected status code: %d", res.StatusCode))
 	}
-	return nil, nil
+	body := {{ .PluginName }}TestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
+	// output
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 //TODO Please modify the folowing code to adapt to your plugin
-/*
-POST /plugins/{{ .PluginName }}/connections
-{
-	"name": "{{ .PluginName }} data connection name",
-	"endpoint": "{{ .PluginName }} api endpoint, i.e. https://example.com",
-	"username": "username, usually should be email address",
-	"password": "{{ .PluginName }} api access token"
-}
-*/
+// @Summary create {{ .pluginName }} connection
+// @Description Create {{ .pluginName }} connection
+// @Tags plugins/{{ .pluginName }}
+// @Param body body models.{{ .PluginName }}Connection true "json body"
+// @Success 200  {object} models.{{ .PluginName }}Connection
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /plugins/{{ .pluginName }}/connections [POST]
 func PostConnections(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
 	// update from request and save to database
 	connection := &models.{{ .PluginName }}Connection{}
@@ -90,14 +102,14 @@ func PostConnections(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, e
 
 //TODO Please modify the folowing code to adapt to your plugin
 /*
-PATCH /plugins/{{ .PluginName }}/connections/:connectionId
-{
-	"name": "{{ .PluginName }} data connection name",
-	"endpoint": "{{ .PluginName }} api endpoint, i.e. https://example.com",
-	"username": "username, usually should be email address",
-	"password": "{{ .PluginName }} api access token"
-}
-*/
+// @Summary patch {{ .pluginName }} connection
+// @Description Patch {{ .pluginName }} connection
+// @Tags plugins/{{ .pluginName }}
+// @Param body body models.{{ .PluginName }}Connection true "json body"
+// @Success 200  {object} models.{{ .PluginName }}Connection
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /plugins/{{ .pluginName }}/connections/{connectionId} [PATCH]
 func PatchConnection(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
 	connection := &models.{{ .PluginName }}Connection{}
 	err := connectionHelper.Patch(connection, input)
@@ -107,9 +119,13 @@ func PatchConnection(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, e
 	return &plugin.ApiResourceOutput{Body: connection}, nil
 }
 
-/*
-DELETE /plugins/{{ .PluginName }}/connections/:connectionId
-*/
+// @Summary delete a {{ .pluginName }} connection
+// @Description Delete a {{ .pluginName }} connection
+// @Tags plugins/{{ .pluginName }}
+// @Success 200  {object} models.{{ .PluginName }}Connection
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /plugins/{{ .pluginName }}/connections/{connectionId} [DELETE]
 func DeleteConnection(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
 	connection := &models.{{ .PluginName }}Connection{}
 	err := connectionHelper.First(connection, input.Params)
@@ -120,9 +136,13 @@ func DeleteConnection(input *core.ApiResourceInput) (*plugin.ApiResourceOutput,
 	return &plugin.ApiResourceOutput{Body: connection}, err
 }
 
-/*
-GET /plugins/{{ .PluginName }}/connections
-*/
+// @Summary get all {{ .pluginName }} connections
+// @Description Get all {{ .pluginName }} connections
+// @Tags plugins/{{ .pluginName }}
+// @Success 200  {object} []models.{{ .PluginName }}Connection
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /plugins/{{ .pluginName }}/connections [GET]
 func ListConnections(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
 	var connections []models.{{ .PluginName }}Connection
 	err := connectionHelper.List(&connections)
@@ -133,15 +153,13 @@ func ListConnections(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, e
 }
 
 //TODO Please modify the folowing code to adapt to your plugin
-/*
-GET /plugins/{{ .PluginName }}/connections/:connectionId
-{
-	"name": "{{ .PluginName }} data connection name",
-	"endpoint": "{{ .PluginName }} api endpoint, i.e. https://merico.atlassian.net/rest",
-	"username": "username, usually should be email address",
-	"password": "{{ .PluginName }} api access token"
-}
-*/
+// @Summary get {{ .pluginName }} connection detail
+// @Description Get {{ .pluginName }} connection detail
+// @Tags plugins/{{ .pluginName }}
+// @Success 200  {object} models.{{ .PluginName }}Connection
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /plugins/{{ .pluginName }}/connections/{connectionId} [GET]
 func GetConnection(input *core.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
 	connection := &models.{{ .PluginName }}Connection{}
 	err := connectionHelper.First(connection, input.Params)
diff --git a/backend/plugins/azure/api/connection.go b/backend/plugins/azure/api/connection.go
index 8cba156e8..5662dc65b 100644
--- a/backend/plugins/azure/api/connection.go
+++ b/backend/plugins/azure/api/connection.go
@@ -19,6 +19,7 @@ package api
 
 import (
 	"context"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 
 	"github.com/apache/incubator-devlake/core/errors"
@@ -27,11 +28,16 @@ import (
 	"github.com/apache/incubator-devlake/plugins/azure/models"
 )
 
+type AzureTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.AzureConn
+}
+
 // @Summary test azure connection
 // @Description Test azure Connection. endpoint: "https://dev.azure.com/{organization}/
-// @Tags pluginsazure/
+// @Tags plugins/azure
 // @Param body body models.AzureConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} AzureTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/azure/test [POST]
@@ -55,12 +61,17 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if res.StatusCode != http.StatusOK {
 		return nil, errors.HttpStatus(res.StatusCode).New("unexpected status code while testing connection")
 	}
-	return nil, nil
+	body := AzureTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
+	// output
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create azure connection
 // @Description Create azure connection
-// @Tags pluginsazure/
+// @Tags plugins/azure
 // @Param body body models.AzureConnection true "json body"
 // @Success 200  {object} models.AzureConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
@@ -80,7 +91,7 @@ func PostConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 
 // @Summary patch azure connection
 // @Description Patch azure connection
-// @Tags pluginsazure/
+// @Tags plugins/azure
 // @Param body body models.AzureConnection true "json body"
 // @Success 200  {object} models.AzureConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
@@ -98,7 +109,7 @@ func PatchConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 
 // @Summary delete a azure connection
 // @Description Delete a azure connection
-// @Tags pluginsazure/
+// @Tags plugins/azure
 // @Success 200  {object} models.AzureConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
@@ -115,7 +126,7 @@ func DeleteConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput
 
 // @Summary get all azure connections
 // @Description Get all azure connections
-// @Tags pluginsazure/
+// @Tags plugins/azure
 // @Success 200  {object} []models.AzureConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
@@ -132,7 +143,7 @@ func ListConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 
 // @Summary get azure connection detail
 // @Description Get azure connection detail
-// @Tags pluginsazure/
+// @Tags plugins/azure
 // @Success 200  {object} models.AzureConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
diff --git a/backend/plugins/bitbucket/api/connection.go b/backend/plugins/bitbucket/api/connection.go
index 681c18aa0..b699c133e 100644
--- a/backend/plugins/bitbucket/api/connection.go
+++ b/backend/plugins/bitbucket/api/connection.go
@@ -19,20 +19,25 @@ package api
 
 import (
 	"context"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 
 	"github.com/apache/incubator-devlake/core/errors"
 	plugin "github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 	"github.com/apache/incubator-devlake/plugins/bitbucket/models"
-	_ "github.com/apache/incubator-devlake/server/api/shared"
 )
 
+type BitBucketTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.BitbucketConn
+}
+
 // @Summary test bitbucket connection
 // @Description Test bitbucket Connection
 // @Tags plugins/bitbucket
 // @Param body body models.BitbucketConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} BitBucketTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/bitbucket/test [POST]
@@ -56,7 +61,12 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if res.StatusCode != http.StatusOK {
 		return nil, errors.HttpStatus(res.StatusCode).New("unexpected status code when testing connection")
 	}
-	return nil, nil
+	body := BitBucketTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
+	// output
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create bitbucket connection
diff --git a/backend/plugins/feishu/api/connection.go b/backend/plugins/feishu/api/connection.go
index c9075bc2d..bcf48f3c3 100644
--- a/backend/plugins/feishu/api/connection.go
+++ b/backend/plugins/feishu/api/connection.go
@@ -19,6 +19,7 @@ package api
 
 import (
 	"context"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 
 	"github.com/apache/incubator-devlake/core/errors"
@@ -27,11 +28,16 @@ import (
 	"github.com/apache/incubator-devlake/plugins/feishu/models"
 )
 
+type FeishuTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.FeishuConn
+}
+
 // @Summary test feishu connection
 // @Description Test feishu Connection. endpoint: https://open.feishu.cn/open-apis/
 // @Tags plugins/feishu
 // @Param body body models.FeishuConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} FeishuTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/feishu/test [POST]
@@ -45,8 +51,14 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	// test connection
 	_, err := api.NewApiClientFromConnection(context.TODO(), basicRes, &connection)
 
-	// output
-	return nil, err
+	body := FeishuTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
+	if err != nil {
+		return nil, err
+	}
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create feishu connection
diff --git a/backend/plugins/gitee/api/connection.go b/backend/plugins/gitee/api/connection.go
index 0aa16b4ba..3d9fe0b72 100644
--- a/backend/plugins/gitee/api/connection.go
+++ b/backend/plugins/gitee/api/connection.go
@@ -19,6 +19,7 @@ package api
 
 import (
 	"context"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 
 	"github.com/apache/incubator-devlake/core/errors"
@@ -27,11 +28,16 @@ import (
 	"github.com/apache/incubator-devlake/plugins/gitee/models"
 )
 
+type GiteeTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.GiteeConn
+}
+
 // @Summary test gitee connection
 // @Description Test gitee Connection. endpoint: https://gitee.com/api/v5/
 // @Tags plugins/gitee
 // @Param body body models.GiteeConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} GiteeTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/gitee/test [POST]
@@ -59,7 +65,12 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if res.StatusCode != http.StatusOK {
 		return nil, errors.HttpStatus(res.StatusCode).New("unexpected status code when testing connection")
 	}
-	return nil, nil
+	body := GiteeTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
+	// output
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create gitee connection
diff --git a/backend/plugins/jenkins/api/connection.go b/backend/plugins/jenkins/api/connection.go
index af9128138..f3035ce46 100644
--- a/backend/plugins/jenkins/api/connection.go
+++ b/backend/plugins/jenkins/api/connection.go
@@ -19,6 +19,7 @@ package api
 
 import (
 	"context"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 
 	"github.com/apache/incubator-devlake/core/errors"
@@ -27,11 +28,16 @@ import (
 	"github.com/apache/incubator-devlake/plugins/jenkins/models"
 )
 
+type JenkinsTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.JenkinsConn
+}
+
 // @Summary test jenkins connection
 // @Description Test Jenkins Connection
 // @Tags plugins/jenkins
 // @Param body body models.JenkinsConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} JenkinsTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/jenkins/test [POST]
@@ -56,7 +62,12 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if res.StatusCode != http.StatusOK {
 		return nil, errors.HttpStatus(res.StatusCode).New("unexpected status code when testing connection")
 	}
-	return nil, nil
+	body := JenkinsTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
+	// output
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create jenkins connection
diff --git a/backend/plugins/jira/api/connection.go b/backend/plugins/jira/api/connection.go
index 1554422bc..97a938923 100644
--- a/backend/plugins/jira/api/connection.go
+++ b/backend/plugins/jira/api/connection.go
@@ -20,6 +20,7 @@ package api
 import (
 	"context"
 	"fmt"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 	"net/url"
 	"strings"
@@ -31,11 +32,16 @@ import (
 	"github.com/mitchellh/mapstructure"
 )
 
+type JiraTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.JiraConn
+}
+
 // @Summary test jira connection
 // @Description Test Jira Connection
 // @Tags plugins/jira
 // @Param body body models.JiraConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} JiraTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/jira/test [POST]
@@ -111,8 +117,14 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if res.StatusCode != http.StatusOK {
 		return nil, errors.HttpStatus(res.StatusCode).New(fmt.Sprintf("%s Unexpected [%s] status code: %d %s", getStatusFail, res.Request.URL, res.StatusCode, errMsg))
 	}
-
-	return nil, nil
+	body := JiraTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
+	if err != nil {
+		return nil, err
+	}
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create jira connection
diff --git a/backend/plugins/sonarqube/api/connection.go b/backend/plugins/sonarqube/api/connection.go
index 378bb1f5d..ec81653ac 100644
--- a/backend/plugins/sonarqube/api/connection.go
+++ b/backend/plugins/sonarqube/api/connection.go
@@ -23,23 +23,26 @@ import (
 	"github.com/apache/incubator-devlake/core/plugin"
 	"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
 	"github.com/apache/incubator-devlake/plugins/sonarqube/models"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 )
 
 type validation struct {
 	Valid bool `json:"valid"`
 }
+type SonarqubeTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.SonarqubeConn
+}
 
-/*
-@Summary test sonarqube connection
-@Description Test sonarqube Connection
-@Tags plugins/sonarqube
-@Param body body models.SonarqubeConn true "json body"
-@Success 200  {object} shared.ApiBody "Success"
-@Failure 400  {string} errcode.Error "Bad Request"
-@Failure 500  {string} errcode.Error "Internal Error"
-@Router /plugins/sonarqube/test [POST]
-*/
+// @Summary test sonarqube connection
+// @Description Test sonarqube Connection
+// @Tags plugins/sonarqube
+// @Param body body models.SonarqubeConn true "json body"
+// @Success 200  {object} SonarqubeTestConnResponse "Success"
+// @Failure 400  {string} errcode.Error "Bad Request"
+// @Failure 500  {string} errcode.Error "Internal Error"
+// @Router /plugins/sonarqube/test [POST]
 func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
 	// decode
 	var err errors.Error
@@ -58,15 +61,19 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	}
 	switch res.StatusCode {
 	case 200: // right StatusCode
-		body := &validation{}
-		err = api.UnmarshalResponse(res, body)
+		valid := &validation{}
+		err = api.UnmarshalResponse(res, valid)
+		body := SonarqubeTestConnResponse{}
+		body.Success = true
+		body.Message = "success"
+		body.Connection = &connection
 		if err != nil {
 			return nil, err
 		}
-		if !body.Valid {
+		if !valid.Valid {
 			return nil, errors.Default.New("Authentication failed, please check your access token.")
 		}
-		return &plugin.ApiResourceOutput{Body: true, Status: 200}, nil
+		return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 	case 401: // error secretKey or nonceStr
 		return &plugin.ApiResourceOutput{Body: false, Status: res.StatusCode}, nil
 	default: // unknow what happen , back to user
diff --git a/backend/plugins/sonarqube/api/remote.go b/backend/plugins/sonarqube/api/remote.go
index 3215f9ada..02e8f05a9 100644
--- a/backend/plugins/sonarqube/api/remote.go
+++ b/backend/plugins/sonarqube/api/remote.go
@@ -58,7 +58,7 @@ type PageData struct {
 	Tag     string `json:"tag"`
 }
 
-const SonarqubeRemoteScopesPerPage int = 10
+const SonarqubeRemoteScopesPerPage int = 100
 const TypeProject string = "scope"
 
 // RemoteScopes list all available scope for users
diff --git a/backend/plugins/tapd/api/connection.go b/backend/plugins/tapd/api/connection.go
index e29127ead..321b77144 100644
--- a/backend/plugins/tapd/api/connection.go
+++ b/backend/plugins/tapd/api/connection.go
@@ -20,6 +20,7 @@ package api
 import (
 	"context"
 	"fmt"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 
 	"github.com/apache/incubator-devlake/core/errors"
@@ -28,11 +29,16 @@ import (
 	"github.com/apache/incubator-devlake/plugins/tapd/models"
 )
 
+type TapdTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.TapdConn
+}
+
 // @Summary test tapd connection
 // @Description Test Tapd Connection
 // @Tags plugins/tapd
 // @Param body body models.TapdConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} TapdTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/tapd/test [POST]
@@ -59,8 +65,12 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 	if res.StatusCode != http.StatusOK {
 		return nil, errors.HttpStatus(res.StatusCode).New(fmt.Sprintf("unexpected status code: %d", res.StatusCode))
 	}
+	body := TapdTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
 	// output
-	return nil, nil
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create tapd connection
diff --git a/backend/plugins/zentao/api/connection.go b/backend/plugins/zentao/api/connection.go
index 60a9f2169..52450e3a0 100644
--- a/backend/plugins/zentao/api/connection.go
+++ b/backend/plugins/zentao/api/connection.go
@@ -19,6 +19,7 @@ package api
 
 import (
 	"context"
+	"github.com/apache/incubator-devlake/server/api/shared"
 	"net/http"
 
 	"github.com/apache/incubator-devlake/core/errors"
@@ -27,11 +28,16 @@ import (
 	"github.com/apache/incubator-devlake/plugins/zentao/models"
 )
 
+type ZentaoTestConnResponse struct {
+	shared.ApiBody
+	Connection *models.ZentaoConn
+}
+
 // @Summary test zentao connection
 // @Description Test zentao Connection
 // @Tags plugins/zentao
 // @Param body body models.ZentaoConn true "json body"
-// @Success 200  {object} shared.ApiBody "Success"
+// @Success 200  {object} ZentaoTestConnResponse "Success"
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
 // @Router /plugins/zentao/test [POST]
@@ -45,14 +51,20 @@ func TestConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 
 	// try to create apiClient
 	_, err = helper.NewApiClientFromConnection(context.TODO(), basicRes, &connection)
-
+	if err != nil {
+		return nil, err
+	}
+	body := ZentaoTestConnResponse{}
+	body.Success = true
+	body.Message = "success"
+	body.Connection = &connection
 	// output
-	return nil, err
+	return &plugin.ApiResourceOutput{Body: body, Status: 200}, nil
 }
 
 // @Summary create zentao connection
 // @Description Create zentao connection
-// @Tags plugins/zentao/
+// @Tags plugins/zentao
 // @Param body body models.ZentaoConnection true "json body"
 // @Success 200  {object} models.ZentaoConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
@@ -70,7 +82,7 @@ func PostConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 
 // @Summary patch zentao connection
 // @Description Patch zentao connection
-// @Tags plugins/zentao/
+// @Tags plugins/zentao
 // @Param body body models.ZentaoConnection true "json body"
 // @Success 200  {object} models.ZentaoConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
@@ -87,7 +99,7 @@ func PatchConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 
 // @Summary delete a zentao connection
 // @Description Delete a zentao connection
-// @Tags plugins/zentao/
+// @Tags plugins/zentao
 // @Success 200  {object} models.ZentaoConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
@@ -104,7 +116,7 @@ func DeleteConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput
 
 // @Summary get all zentao connections
 // @Description Get all zentao connections
-// @Tags plugins/zentao/
+// @Tags plugins/zentao
 // @Success 200  {object} []models.ZentaoConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"
@@ -120,7 +132,7 @@ func ListConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
 
 // @Summary get zentao connection detail
 // @Description Get zentao connection detail
-// @Tags plugins/zentao/
+// @Tags plugins/zentao
 // @Success 200  {object} models.ZentaoConnection
 // @Failure 400  {string} errcode.Error "Bad Request"
 // @Failure 500  {string} errcode.Error "Internal Error"