From 76c60b3e06e21e3cf542aded1e599808d46f85db Mon Sep 17 00:00:00 2001
From: SamYSF <98792230+SamYSF@users.noreply.github.com>
Date: Mon, 13 May 2024 15:42:19 +0800
Subject: [PATCH] fix: cannot import sub-collection of postman (#426)

---
 pkg/generator/importer.go                     | 45 ++++++++++++-------
 pkg/generator/importer_test.go                | 13 ++++++
 .../expected_suite_from_sub_postman.yaml      |  9 ++++
 pkg/generator/testdata/postman-sub.json       | 41 +++++++++++++++++
 4 files changed, 91 insertions(+), 17 deletions(-)
 create mode 100644 pkg/generator/testdata/expected_suite_from_sub_postman.yaml
 create mode 100644 pkg/generator/testdata/postman-sub.json

diff --git a/pkg/generator/importer.go b/pkg/generator/importer.go
index eaf9a70f..65cbe8a5 100644
--- a/pkg/generator/importer.go
+++ b/pkg/generator/importer.go
@@ -52,8 +52,20 @@ type PostmanRequest struct {
 }
 
 type PostmanBody struct {
-	Mode string `json:"mode"`
-	Raw  string `json:"raw"`
+	Mode       string      `json:"mode"`
+	Raw        string      `json:"raw"`
+	FormData   []TypeField `json:"formdata"`
+	URLEncoded []TypeField `json:"urlencoded"`
+	Disabled   bool        `json:"disabled"`
+}
+
+type TypeField struct {
+	Key         string `json:"key"`
+	Value       string `json:"value"`
+	Disabled    bool   `json:"disabled"`
+	Type        string `json:"type"`
+	Description string `json:"description"`
+	Src         string `json:"src"`
 }
 
 type PostmanURL struct {
@@ -110,30 +122,29 @@ func (p *postmanImporter) Convert(data []byte) (suite *testing.TestSuite, err er
 
 	suite = &testing.TestSuite{}
 	suite.Name = postman.Info.Name
-	suite.Items = make([]testing.TestCase, len(postman.Item))
+	if err = p.convertItems(postman.Item, "", suite); err != nil {
+		return
+	}
 
-	for i, item := range postman.Item {
+	return
+}
+
+func (p *postmanImporter) convertItems(items []PostmanItem, prefix string, suite *testing.TestSuite) (err error) {
+	for _, item := range items {
+		itemName := prefix + item.Name
 		if len(item.Item) == 0 {
-			suite.Items[i] = testing.TestCase{
-				Name: item.Name,
+			suite.Items = append(suite.Items, testing.TestCase{
+				Name: itemName,
 				Request: testing.Request{
 					Method: item.Request.Method,
 					API:    item.Request.URL.Raw,
 					Body:   testing.NewRequestBody(item.Request.Body.Raw),
 					Header: item.Request.Header.ToMap(),
 				},
-			}
+			})
 		} else {
-			for _, sub := range item.Item {
-				suite.Items[i] = testing.TestCase{
-					Name: item.Name + " " + sub.Name,
-					Request: testing.Request{
-						Method: sub.Request.Method,
-						API:    sub.Request.URL.Raw,
-						Body:   testing.NewRequestBody(item.Request.Body.Raw),
-						Header: sub.Request.Header.ToMap(),
-					},
-				}
+			if err = p.convertItems(item.Item, itemName+" ", suite); err != nil {
+				return
 			}
 		}
 	}
diff --git a/pkg/generator/importer_test.go b/pkg/generator/importer_test.go
index f4aa4489..60054e15 100644
--- a/pkg/generator/importer_test.go
+++ b/pkg/generator/importer_test.go
@@ -64,6 +64,16 @@ func TestPostmanImport(t *testing.T) {
 		assert.Equal(t, expectedSuiteFromPostman, strings.TrimSpace(result), result)
 	})
 
+	t.Run("sub postman, from file", func(t *testing.T) {
+		suite, err := importer.ConvertFromFile("testdata/postman-sub.json")
+		assert.NoError(t, err)
+
+		var result string
+		result, err = converter.Convert(suite)
+		assert.NoError(t, err)
+		assert.Equal(t, expectedSuiteFromSubPostman, strings.TrimSpace(result), result)
+	})
+
 	t.Run("simple postman, from URl", func(t *testing.T) {
 		defer gock.Off()
 		gock.New(urlFoo).Get("/").Reply(http.StatusOK).BodyString(simplePostman)
@@ -96,3 +106,6 @@ var simplePostman string
 
 //go:embed testdata/expected_suite_from_postman.yaml
 var expectedSuiteFromPostman string
+
+//go:embed testdata/expected_suite_from_sub_postman.yaml
+var expectedSuiteFromSubPostman string
diff --git a/pkg/generator/testdata/expected_suite_from_sub_postman.yaml b/pkg/generator/testdata/expected_suite_from_sub_postman.yaml
new file mode 100644
index 00000000..9a34053c
--- /dev/null
+++ b/pkg/generator/testdata/expected_suite_from_sub_postman.yaml
@@ -0,0 +1,9 @@
+name: Sub
+items:
+    - name: Get Sub Get New Request
+      request:
+        api: http://localhost?key=value
+        method: GET
+        header:
+            key: value
+        body: '{}'
\ No newline at end of file
diff --git a/pkg/generator/testdata/postman-sub.json b/pkg/generator/testdata/postman-sub.json
new file mode 100644
index 00000000..2d8ed5a6
--- /dev/null
+++ b/pkg/generator/testdata/postman-sub.json
@@ -0,0 +1,41 @@
+{
+	"info": {
+		"_postman_id": "84b8940a-009e-4127-b84e-f4d6fd6b9972",
+		"name": "Sub",
+		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
+		"_exporter_id": "19536120"
+	},
+	"item": [
+		{
+			"name": "Get",
+			"item": [
+				{
+					"name": "Sub Get",
+					"item": [
+						{
+							"name": "New Request",
+							"request": {
+								"method": "GET",
+								"header": [
+									{
+										"key": "key",
+										"value": "value",
+										"description": "description",
+										"type": "text"
+									}
+								],
+								"body": {
+									"mode": "raw",
+									"raw": "{}"
+								},
+								"url": {
+									"raw": "http://localhost?key=value"
+								}
+							}
+						}
+					]
+				}
+			]
+		}
+	]
+}
\ No newline at end of file