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 07107d380 feat(customize): clean up qa_apis and 
qa_test_case_executions when non-incremental import qa_test_cases (#8445)
07107d380 is described below

commit 07107d380632c720792bfa5dadeaa883ba5a989e
Author: NaRro <[email protected]>
AuthorDate: Wed May 21 06:25:33 2025 +0000

    feat(customize): clean up qa_apis and qa_test_case_executions when 
non-incremental import qa_test_cases (#8445)
    
    - Implement new e2e test case for QA data cleanup functionality
    - Add test data files for QA test cases, APIs, and test case executions
    - Update ImportQaTestCases method to delete old data for non-incremental 
imports
    - Verify that API data, test cases, and test case executions are properly 
cleaned up
---
 .../customize/e2e/import_qa_test_cases_test.go     | 148 ++++++++++++++++++++-
 .../e2e/raw_tables/qa_full_test_cases_input.csv    |   7 +
 .../e2e/raw_tables/qa_non_api_test_cases.csv       |   3 +
 backend/plugins/customize/service/service.go       |  12 +-
 4 files changed, 167 insertions(+), 3 deletions(-)

diff --git a/backend/plugins/customize/e2e/import_qa_test_cases_test.go 
b/backend/plugins/customize/e2e/import_qa_test_cases_test.go
index 58d448298..764421e5b 100644
--- a/backend/plugins/customize/e2e/import_qa_test_cases_test.go
+++ b/backend/plugins/customize/e2e/import_qa_test_cases_test.go
@@ -21,6 +21,7 @@ import (
        "os"
        "testing"
 
+       "github.com/apache/incubator-devlake/core/dal"
        
"github.com/apache/incubator-devlake/core/models/domainlayer/crossdomain"
        "github.com/apache/incubator-devlake/core/models/domainlayer/qa"
        "github.com/apache/incubator-devlake/helpers/e2ehelper"
@@ -34,8 +35,9 @@ func TestImportQaTestCasesDataFlow(t *testing.T) {
 
        // Flush the relevant tables
        dataflowTester.FlushTabler(&qa.QaTestCase{})
-       dataflowTester.FlushTabler(&qa.QaProject{})        // qaTestCaseHandler 
also creates/updates QaProject
-       dataflowTester.FlushTabler(&qa.QaApi{})            // qaTestCaseHandler 
also creates/updates QaApi for API test cases
+       dataflowTester.FlushTabler(&qa.QaProject{}) // qaTestCaseHandler also 
creates/updates QaProject
+       dataflowTester.FlushTabler(&qa.QaApi{})     // qaTestCaseHandler also 
creates/updates QaApi for API test cases
+       dataflowTester.FlushTabler(&qa.QaTestCaseExecution{})
        dataflowTester.FlushTabler(&crossdomain.Account{}) // qaTestCaseHandler 
also creates/updates Account for API test cases
 
        // Create a new service instance
@@ -117,3 +119,145 @@ func TestImportQaTestCasesDataFlow(t *testing.T) {
                },
        )
 }
+
+func TestImportQaTestCasesDataCleanup(t *testing.T) {
+       var plugin impl.Customize
+       dataflowTester := e2ehelper.NewDataFlowTester(t, "customize", plugin)
+
+       // Flush all relevant tables
+       dataflowTester.FlushTabler(&qa.QaTestCase{})
+       dataflowTester.FlushTabler(&qa.QaProject{})
+       dataflowTester.FlushTabler(&qa.QaApi{})
+       dataflowTester.FlushTabler(&qa.QaTestCaseExecution{})
+       dataflowTester.FlushTabler(&crossdomain.Account{})
+
+       svc := service.NewService(dataflowTester.Dal)
+
+       qaProjectId := "test-cleanup-project"
+       qaProjectName := "Test Cleanup Project"
+
+       // 1. First import import test cases with API references
+       testCasesFile, err := os.Open("raw_tables/qa_full_test_cases_input.csv")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer testCasesFile.Close()
+
+       err = svc.ImportQaTestCases(qaProjectId, qaProjectName, testCasesFile, 
false)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // import test case executions
+       testCaseExecutionsFile, err := 
os.Open("raw_tables/qa_test_case_executions_input.csv")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer testCaseExecutionsFile.Close()
+
+       err = svc.ImportQaTestCaseExecutions(qaProjectId, 
testCaseExecutionsFile, false)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Then import APIs
+       apisFile, err := os.Open("raw_tables/qa_apis_input.csv")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer apisFile.Close()
+
+       err = svc.ImportQaApis(qaProjectId, apisFile, false)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Verify APIs, test cases and test case executions were imported
+       var initialApiCount int64
+       initialApiCount, err = dataflowTester.Dal.Count(
+               dal.From(&qa.QaApi{}),
+               dal.Where("qa_project_id = ?", qaProjectId),
+       )
+       if err != nil {
+               t.Fatal(err)
+       }
+       if initialApiCount == 0 {
+               t.Error("Expected API data to be imported initially")
+       }
+
+       var initialTestCaseCount int64
+       initialTestCaseCount, err = dataflowTester.Dal.Count(
+               dal.From(&qa.QaTestCase{}),
+               dal.Where("qa_project_id = ?", qaProjectId),
+       )
+       if err != nil {
+               t.Fatal(err)
+       }
+       if initialTestCaseCount == 0 {
+               t.Error("Expected test cases to be imported initially")
+       }
+
+       var initialTestCaseExecutionCount int64
+       initialTestCaseExecutionCount, err = dataflowTester.Dal.Count(
+               dal.From(&qa.QaTestCaseExecution{}),
+               dal.Where("qa_project_id = ?", qaProjectId),
+       )
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       if initialTestCaseExecutionCount == 0 {
+               t.Error("Expected test case executions to be imported 
initially")
+       }
+
+       // 2. Second import non-incremental - test cases
+       nonApiDataFile, err := os.Open("raw_tables/qa_non_api_test_cases.csv")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer nonApiDataFile.Close()
+
+       err = svc.ImportQaTestCases(qaProjectId, qaProjectName, nonApiDataFile, 
false)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       // Verify API data was cleaned up
+       var finalApiCount int64
+       finalApiCount, err = dataflowTester.Dal.Count(
+               dal.From(&qa.QaApi{}),
+               dal.Where("qa_project_id = ?", qaProjectId),
+       )
+       if err != nil {
+               t.Fatal(err)
+       }
+       if finalApiCount != 0 {
+               t.Errorf("Expected API data to be cleaned up, but found %d 
records", finalApiCount)
+       }
+
+       // Verify test case execution data was cleaned up
+       var finalTestCaseExecutionCount int64
+       finalTestCaseExecutionCount, err = dataflowTester.Dal.Count(
+               dal.From(&qa.QaTestCaseExecution{}),
+               dal.Where("qa_project_id = ?", qaProjectId),
+       )
+       if err != nil {
+               t.Fatal(err)
+       }
+       if finalTestCaseExecutionCount != 0 {
+               t.Errorf("Expected test case executions to be cleaned up, but 
found %d records", finalTestCaseExecutionCount)
+       }
+
+       // Verify test case count is correct (should be 2)
+       var finalTestCaseCount int64
+       finalTestCaseCount, err = dataflowTester.Dal.Count(
+               dal.From(&qa.QaTestCase{}),
+               dal.Where("qa_project_id = ?", qaProjectId),
+       )
+       if err != nil {
+               t.Fatal(err)
+       }
+       if finalTestCaseCount != 2 {
+               t.Errorf("Expected 2 test cases after non-incremental import, 
got %d", finalTestCaseCount)
+       }
+}
diff --git 
a/backend/plugins/customize/e2e/raw_tables/qa_full_test_cases_input.csv 
b/backend/plugins/customize/e2e/raw_tables/qa_full_test_cases_input.csv
new file mode 100644
index 000000000..95b607ffc
--- /dev/null
+++ b/backend/plugins/customize/e2e/raw_tables/qa_full_test_cases_input.csv
@@ -0,0 +1,7 @@
+id,name,create_time,creator_name,type,qa_api_id
+tc-1,Full Test Case 1,2023-02-01T10:00:00.000+00:00,user-a,functional,
+tc-2,Full Test Case 2 API,2023-02-02T11:00:00.000+00:00,user-b,api,api-1
+api-1,Test API 1,2023-02-01T10:00:00.000+00:00,user-a,GET,/api/v1/test
+api-2,Test API 2,2023-02-02T11:00:00.000+00:00,user-b,POST,/api/v1/test
+exec-1,tc-1,2023-02-01T10:30:00.000+00:00,2023-02-01T10:35:00.000+00:00,passed,user-a
+exec-2,tc-2,2023-02-02T11:30:00.000+00:00,2023-02-02T11:40:00.000+00:00,failed,user-b
\ No newline at end of file
diff --git a/backend/plugins/customize/e2e/raw_tables/qa_non_api_test_cases.csv 
b/backend/plugins/customize/e2e/raw_tables/qa_non_api_test_cases.csv
new file mode 100644
index 000000000..0e95a5013
--- /dev/null
+++ b/backend/plugins/customize/e2e/raw_tables/qa_non_api_test_cases.csv
@@ -0,0 +1,3 @@
+id,name,create_time,creator_name,type,qa_api_id
+tc-1,Functional Test Case 1,2023-02-01T10:00:00.000+00:00,user-a,functional,
+tc-2,Functional Test Case 2,2023-02-02T11:00:00.000+00:00,user-b,functional,
\ No newline at end of file
diff --git a/backend/plugins/customize/service/service.go 
b/backend/plugins/customize/service/service.go
index 6f6b0d097..22267453f 100644
--- a/backend/plugins/customize/service/service.go
+++ b/backend/plugins/customize/service/service.go
@@ -453,11 +453,21 @@ func (s *Service) qaApiHandler(qaProjectId string) 
func(record map[string]interf
 func (s *Service) ImportQaTestCases(qaProjectId, qaProjectName string, file 
io.ReadCloser, incremental bool) errors.Error {
        if !incremental {
                // delete old data associated with this qaProjectId
+               // delete qa_test_cases
                err := s.dal.Delete(&qa.QaTestCase{}, dal.Where("qa_project_id 
= ?", qaProjectId))
                if err != nil {
                        return errors.Default.Wrap(err, fmt.Sprintf("failed to 
delete old qa_test_cases for qaProjectId %s", qaProjectId))
                }
-               // using ImportQaApis to delete data in qa_apis
+               // delete qa_apis
+               err = s.dal.Delete(&qa.QaApi{}, dal.Where("qa_project_id = ?", 
qaProjectId))
+               if err != nil {
+                       return errors.Default.Wrap(err, fmt.Sprintf("failed to 
delete old qa_apis for qaProjectId %s", qaProjectId))
+               }
+               // delete qa_test_case_executions
+               err = s.dal.Delete(&qa.QaTestCaseExecution{}, 
dal.Where("qa_project_id = ?", qaProjectId))
+               if err != nil {
+                       return errors.Default.Wrap(err, fmt.Sprintf("failed to 
delete old qa_test_case_executions for qaProjectId %s", qaProjectId))
+               }
                // never delete data in qa_projects
        }
        // create or update qa_projects

Reply via email to