fix(zentao): add e2e (#3772)

diff --git a/plugins/zentao/e2e/account_test.go b/plugins/zentao/e2e/account_test.go
new file mode 100644
index 0000000..67ec476
--- /dev/null
+++ b/plugins/zentao/e2e/account_test.go
@@ -0,0 +1,63 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package e2e
+
+import (
+	"github.com/apache/incubator-devlake/models/common"
+	"github.com/apache/incubator-devlake/models/domainlayer/crossdomain"
+	"testing"
+
+	"github.com/apache/incubator-devlake/helpers/e2ehelper"
+	"github.com/apache/incubator-devlake/plugins/zentao/impl"
+	"github.com/apache/incubator-devlake/plugins/zentao/models"
+	"github.com/apache/incubator-devlake/plugins/zentao/tasks"
+)
+
+func TestZentaoAccountDataFlow(t *testing.T) {
+
+	var zentao impl.Zentao
+	dataflowTester := e2ehelper.NewDataFlowTester(t, "zentao", zentao)
+
+	taskData := &tasks.ZentaoTaskData{
+		Options: &tasks.ZentaoOptions{
+			ConnectionId: 1,
+			ProjectId:    1,
+			ProductId:    3,
+			ExecutionId:  1,
+		},
+	}
+
+	// import raw data table
+	dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_zentao_api_accounts.csv",
+		"_raw_zentao_api_accounts")
+
+	// verify extraction
+	dataflowTester.FlushTabler(&models.ZentaoAccount{})
+	dataflowTester.Subtask(tasks.ExtractAccountMeta, taskData)
+	dataflowTester.VerifyTableWithOptions(&models.ZentaoAccount{}, e2ehelper.TableOptions{
+		CSVRelPath:  "./snapshot_tables/_tool_zentao_accounts.csv",
+		IgnoreTypes: []interface{}{common.NoPKModel{}},
+	})
+
+	dataflowTester.FlushTabler(&crossdomain.Account{})
+	dataflowTester.Subtask(tasks.ConvertAccountMeta, taskData)
+	dataflowTester.VerifyTableWithOptions(&crossdomain.Account{}, e2ehelper.TableOptions{
+		CSVRelPath:  "./snapshot_tables/users.csv",
+		IgnoreTypes: []interface{}{common.NoPKModel{}},
+	})
+}
diff --git a/plugins/zentao/e2e/department_test.go b/plugins/zentao/e2e/department_test.go
new file mode 100644
index 0000000..c100da0
--- /dev/null
+++ b/plugins/zentao/e2e/department_test.go
@@ -0,0 +1,63 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package e2e
+
+import (
+	"github.com/apache/incubator-devlake/models/common"
+	"github.com/apache/incubator-devlake/models/domainlayer/crossdomain"
+	"testing"
+
+	"github.com/apache/incubator-devlake/helpers/e2ehelper"
+	"github.com/apache/incubator-devlake/plugins/zentao/impl"
+	"github.com/apache/incubator-devlake/plugins/zentao/models"
+	"github.com/apache/incubator-devlake/plugins/zentao/tasks"
+)
+
+func TestZentaoDepartmentDataFlow(t *testing.T) {
+
+	var zentao impl.Zentao
+	dataflowTester := e2ehelper.NewDataFlowTester(t, "zentao", zentao)
+
+	taskData := &tasks.ZentaoTaskData{
+		Options: &tasks.ZentaoOptions{
+			ConnectionId: 1,
+			ProjectId:    1,
+			ProductId:    3,
+			ExecutionId:  1,
+		},
+	}
+
+	// import raw data table
+	dataflowTester.ImportCsvIntoRawTable("./raw_tables/_raw_zentao_api_departments.csv",
+		"_raw_zentao_api_departments")
+
+	// verify extraction
+	dataflowTester.FlushTabler(&models.ZentaoDepartment{})
+	dataflowTester.Subtask(tasks.ExtractDepartmentMeta, taskData)
+	dataflowTester.VerifyTableWithOptions(&models.ZentaoDepartment{}, e2ehelper.TableOptions{
+		CSVRelPath:  "./snapshot_tables/_tool_zentao_departments.csv",
+		IgnoreTypes: []interface{}{common.NoPKModel{}},
+	})
+
+	dataflowTester.FlushTabler(&crossdomain.Team{})
+	dataflowTester.Subtask(tasks.ConvertDepartmentMeta, taskData)
+	dataflowTester.VerifyTableWithOptions(&crossdomain.Team{}, e2ehelper.TableOptions{
+		CSVRelPath:  "./snapshot_tables/teams.csv",
+		IgnoreTypes: []interface{}{common.NoPKModel{}},
+	})
+}
diff --git a/plugins/zentao/e2e/raw_tables/_raw_zentao_api_accounts.csv b/plugins/zentao/e2e/raw_tables/_raw_zentao_api_accounts.csv
new file mode 100644
index 0000000..0ea9a75
--- /dev/null
+++ b/plugins/zentao/e2e/raw_tables/_raw_zentao_api_accounts.csv
@@ -0,0 +1,11 @@
+id,params,data,url,input,created_at
+31,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":10,""dept"":1,""account"":""testManager"",""realname"":""\u6d4b\u8bd5\u7ecf\u7406"",""role"":""qd"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+32,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":9,""dept"":3,""account"":""tester3"",""realname"":""\u6d4b\u8bd5\u4e19"",""role"":""qa"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+33,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":8,""dept"":3,""account"":""tester2"",""realname"":""\u6d4b\u8bd5\u4e59"",""role"":""qa"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+34,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":7,""dept"":3,""account"":""tester1"",""realname"":""\u6d4b\u8bd5\u7532"",""role"":""qa"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+35,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":6,""dept"":2,""account"":""dev3"",""realname"":""\u5f00\u53d1\u4e19"",""role"":""dev"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+36,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":5,""dept"":2,""account"":""dev2"",""realname"":""\u5f00\u53d1\u4e59"",""role"":""dev"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+37,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":4,""dept"":2,""account"":""dev1"",""realname"":""\u5f00\u53d1\u7532"",""role"":""dev"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+38,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":3,""dept"":6,""account"":""projectManager"",""realname"":""\u9879\u76ee\u7ecf\u7406"",""role"":""pm"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+39,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":2,""dept"":5,""account"":""productManager"",""realname"":""\u4ea7\u54c1\u7ecf\u7406"",""role"":""po"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
+40,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":1,""dept"":0,""account"":""devlake"",""realname"":""devlake"",""role"":"""",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:57.970
diff --git a/plugins/zentao/e2e/raw_tables/_raw_zentao_api_departments.csv b/plugins/zentao/e2e/raw_tables/_raw_zentao_api_departments.csv
new file mode 100644
index 0000000..a4faf38
--- /dev/null
+++ b/plugins/zentao/e2e/raw_tables/_raw_zentao_api_departments.csv
@@ -0,0 +1,11 @@
+id,params,data,url,input,created_at
+31,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":10,""dept"":1,""account"":""testManager"",""realname"":""\u6d4b\u8bd5\u7ecf\u7406"",""role"":""qd"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+32,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":9,""dept"":3,""account"":""tester3"",""realname"":""\u6d4b\u8bd5\u4e19"",""role"":""qa"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+33,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":8,""dept"":3,""account"":""tester2"",""realname"":""\u6d4b\u8bd5\u4e59"",""role"":""qa"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+34,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":7,""dept"":3,""account"":""tester1"",""realname"":""\u6d4b\u8bd5\u7532"",""role"":""qa"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+35,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":6,""dept"":2,""account"":""dev3"",""realname"":""\u5f00\u53d1\u4e19"",""role"":""dev"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+36,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":5,""dept"":2,""account"":""dev2"",""realname"":""\u5f00\u53d1\u4e59"",""role"":""dev"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+37,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":4,""dept"":2,""account"":""dev1"",""realname"":""\u5f00\u53d1\u7532"",""role"":""dev"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+38,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":3,""dept"":6,""account"":""projectManager"",""realname"":""\u9879\u76ee\u7ecf\u7406"",""role"":""pm"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+39,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":2,""dept"":5,""account"":""productManager"",""realname"":""\u4ea7\u54c1\u7ecf\u7406"",""role"":""po"",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
+40,"{""ConnectionId"":1,""ProductId"":1,""ExecutionId"":1,""ProjectId"":3}","{""id"":1,""dept"":0,""account"":""devlake"",""realname"":""devlake"",""role"":"""",""pinyin"":"""",""email"":""""}",http://iwater.red:8000/api.php/v1/users?limit=100&page=1,null,2022-11-21 11:04:58.124
diff --git a/plugins/zentao/e2e/snapshot_tables/_tool_zentao_accounts.csv b/plugins/zentao/e2e/snapshot_tables/_tool_zentao_accounts.csv
new file mode 100644
index 0000000..675868a
--- /dev/null
+++ b/plugins/zentao/e2e/snapshot_tables/_tool_zentao_accounts.csv
@@ -0,0 +1 @@
+connection_id,id,account,avatar,realname,role,dept
diff --git a/plugins/zentao/e2e/snapshot_tables/_tool_zentao_departments.csv b/plugins/zentao/e2e/snapshot_tables/_tool_zentao_departments.csv
new file mode 100644
index 0000000..01aca95
--- /dev/null
+++ b/plugins/zentao/e2e/snapshot_tables/_tool_zentao_departments.csv
@@ -0,0 +1 @@
+connection_id,id,name,parent,path,grade,order_in,position,dept_function,manager,manager_name
diff --git a/plugins/zentao/e2e/snapshot_tables/teams.csv b/plugins/zentao/e2e/snapshot_tables/teams.csv
new file mode 100644
index 0000000..356c60d
--- /dev/null
+++ b/plugins/zentao/e2e/snapshot_tables/teams.csv
@@ -0,0 +1 @@
+id,name,alias,parent_id,sorting_index
diff --git a/plugins/zentao/e2e/snapshot_tables/users.csv b/plugins/zentao/e2e/snapshot_tables/users.csv
new file mode 100644
index 0000000..605226a
--- /dev/null
+++ b/plugins/zentao/e2e/snapshot_tables/users.csv
@@ -0,0 +1 @@
+id,email,full_name,user_name,avatar_url,organization,created_date,status
diff --git a/plugins/zentao/models/archived/account.go b/plugins/zentao/models/archived/account.go
index 105b977..87c2a00 100644
--- a/plugins/zentao/models/archived/account.go
+++ b/plugins/zentao/models/archived/account.go
@@ -23,13 +23,13 @@
 
 type ZentaoAccount struct {
 	archived.NoPKModel
-	ConnectionId uint64  `gorm:"primaryKey;type:BIGINT  NOT NULL"`
-	ID           uint64  `json:"id" gorm:"primaryKey;type:BIGINT  NOT NULL" `
-	Account  string `json:"account" gorm:"type:varchar(100);index"`
-	Avatar   string `json:"avatar" gorm:"type:varchar(255)"`
-	Realname string `json:"realname" gorm:"type:varchar(100);index"`
-	Role string `json:"role" gorm:"type:varchar(100);index"`
-	Dept uint64 `json:"dept" gorm:"type:BIGINT  NOT NULL;index"`
+	ConnectionId uint64 `gorm:"primaryKey;type:BIGINT  NOT NULL"`
+	ID           uint64 `json:"id" gorm:"primaryKey;type:BIGINT  NOT NULL" `
+	Account      string `json:"account" gorm:"type:varchar(100);index"`
+	Avatar       string `json:"avatar" gorm:"type:varchar(255)"`
+	Realname     string `json:"realname" gorm:"type:varchar(100);index"`
+	Role         string `json:"role" gorm:"type:varchar(100);index"`
+	Dept         uint64 `json:"dept" gorm:"type:BIGINT  NOT NULL;index"`
 }
 
 func (ZentaoAccount) TableName() string {
diff --git a/plugins/zentao/models/archived/department.go b/plugins/zentao/models/archived/department.go
index b97fcbb..70beab7 100644
--- a/plugins/zentao/models/archived/department.go
+++ b/plugins/zentao/models/archived/department.go
@@ -26,9 +26,9 @@
 	Parent       int    `json:"parent" gorm:"type:varchar(100)"`
 	Path         string `json:"path" gorm:"type:varchar(100)"`
 	Grade        int    `json:"grade"`
-	Order        int    `json:"order"`
+	OrderIn      int    `json:"order"`
 	Position     string `json:"position" gorm:"type:varchar(100)"`
-	Function     string `json:"function" gorm:"type:varchar(100)"`
+	DeptFunction string `json:"function" gorm:"type:varchar(100)"`
 	Manager      string `json:"manager" gorm:"type:varchar(100)"`
 	ManagerName  string `json:"managerName" gorm:"type:varchar(100)"`
 	archived.NoPKModel
diff --git a/plugins/zentao/models/department.go b/plugins/zentao/models/department.go
index b22344a..036e428 100644
--- a/plugins/zentao/models/department.go
+++ b/plugins/zentao/models/department.go
@@ -28,9 +28,9 @@
 	Parent       uint64 `json:"parent" gorm:"type:varchar(100)"`
 	Path         string `json:"path" gorm:"type:varchar(100)"`
 	Grade        int    `json:"grade"`
-	Order        int    `json:"order"`
+	OrderIn      int    `json:"order"`
 	Position     string `json:"position" gorm:"type:varchar(100)"`
-	Function     string `json:"function" gorm:"type:varchar(100)"`
+	DeptFunction string `json:"function" gorm:"type:varchar(100)"`
 	Manager      string `json:"manager" gorm:"type:varchar(100)"`
 	ManagerName  string `json:"managerName" gorm:"type:varchar(100)"`
 	common.NoPKModel