@@ -125,11 +125,11 @@ var successTestCases = []TestCase{
125125 },
126126}
127127
128- const successTestCasesCSV = `Folder,Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params,Step 1,Expected 1,Step 2,Expected 2
129- root, standalone,tc-with-minimal -fields,,false,high,,,,,,,,,,,
130- root, standalone,tc-with-partial-fields,,true,low,,[](http://req1),,"[{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":"" http://file1"",""mimeType"":""text/csv"",""size"":10}, {""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10}]",,,, action-1,,, expected-2
131- root/child, standalone,tc-with-all -fields,legacy-id ,false,high,"tag1,tag2",[req1](http://req1),"[link-1](http://link1),[link-2](http://link2)","[{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10},{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10}]",preconditions,,,action-1,expected-1,action-2,expected-2
132- root/child, standalone," tc-with-special-chars.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;",legacy-id,false,high,"tag1.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;","[req.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;]()","[link-1.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;]( http://link1)", "[{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10}]","preconditions.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;",,,"action.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;","expected.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~; ",,
128+ const successTestCasesCSV = `Folder,Folder Comment, Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params,Step 1,Expected 1,Step 2,Expected 2
129+ root/child,, standalone,tc-with-all -fields,legacy-id ,false,high,"tag1,tag2",[req1](http://req1),"[link-1](http://link1),[link-2](http://link2)","[{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10},{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10}]",preconditions,,,action-1,expected-1,action-2,expected-2
130+ root/child,, standalone," tc-with-special-chars.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;",legacy-id,false,high,"tag1.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;","[req.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;]()","[link-1.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;]( http://link1)","[ {""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10}]","preconditions.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;",,," action.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;"," expected.,<>/@$%""""''*&()[]{}+-[BACKTICK]!~;",,
131+ root,, standalone,tc-with-minimal -fields,,false,high,,,,,,,,,,,
132+ root,, standalone,tc-with-partial-fields,,true,low,,[]( http://req1),, "[{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10},{""fileName"":""file-1.csv"",""id"":""file-id"",""url"":""http://file1"",""mimeType"":""text/csv"",""size"":10}] ",,,,action-1,,,expected-2
133133`
134134
135135var failureTestCases = []TestCase {
@@ -146,12 +146,12 @@ var failureTestCases = []TestCase{
146146 Folder : []string {},
147147 Priority : "high" ,
148148 }, {
149- Title : "folder with empty title " ,
150- Folder : []string {"root/child " },
149+ Title : "folder with empty segment " ,
150+ Folder : []string {"root" , " " },
151151 Priority : "high" ,
152152 }, {
153- Title : "folder title with slash " ,
154- Folder : []string {"root/child " },
153+ Title : "folder segment ending with backslash " ,
154+ Folder : []string {"root\\ " },
155155 Priority : "high" ,
156156 }, {
157157 Title : "wrong priority" ,
@@ -353,12 +353,12 @@ var customFieldSuccessTestCases = []TestCase{
353353 },
354354}
355355
356- const customFieldSuccessTestCasesCSV = `Folder,Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params,Step 1,Expected 1,custom_field_dropdown_test_env,custom_field_dropdown_automation,custom_field_text_notes
357- custom-fields,standalone,tc-with-single-custom-field,,false,medium,,,,,,,,,,"{""value"":""staging"",""isDefault"":false}",,
358- custom-fields,standalone,tc-with-multiple-custom-fields,,false,high,"regression,smoke",,,,,,,Execute test,Test passes,"{""value"":""production"",""isDefault"":false}","{""value"":""Automated"",""isDefault"":false}","{""value"":""This is a test note with special chars: !@#$%^\u0026 *()"",""isDefault"":false}"
359- custom-fields,standalone,tc-with-empty-custom-field-value,,false,low,,,,,,,,,,,,"{""value"":"""",""isDefault"":false}"
360- custom-fields,standalone,tc-with-default-custom-field,,false,medium,,,,,,,,,,,"{""value"":"""",""isDefault"":false}",
361- custom-fields/comprehensive,standalone,tc-with-all-fields-and-custom-fields,CF-001,false,high,"custom,comprehensive",[CF Requirements](http://cf-req),[CF Link](http://cf-link),"[{""fileName"":""cf-test.txt"",""id"":""cf-file-id"",""url"":""http://cf-file"",""mimeType"":""text/plain"",""size"":100}]",Custom field test setup,,,Step 1,Result 1,"{""value"":""development"",""isDefault"":false}","{""value"":""In Progress"",""isDefault"":false}",
356+ const customFieldSuccessTestCasesCSV = `Folder,Folder Comment, Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params,Step 1,Expected 1,custom_field_dropdown_test_env,custom_field_dropdown_automation,custom_field_text_notes
357+ custom-fields,, standalone,tc-with-single-custom-field,,false,medium,,,,,,,,,,"{""value"":""staging"",""isDefault"":false}",,
358+ custom-fields,, standalone,tc-with-multiple-custom-fields,,false,high,"regression,smoke",,,,,,,Execute test,Test passes,"{""value"":""production"",""isDefault"":false}","{""value"":""Automated"",""isDefault"":false}","{""value"":""This is a test note with special chars: !@#$%^& *()"",""isDefault"":false}"
359+ custom-fields,, standalone,tc-with-empty-custom-field-value,,false,low,,,,,,,,,,,,"{""value"":"""",""isDefault"":false}"
360+ custom-fields,, standalone,tc-with-default-custom-field,,false,medium,,,,,,,,,,,"{""value"":"""",""isDefault"":false}",
361+ custom-fields/comprehensive,, standalone,tc-with-all-fields-and-custom-fields,CF-001,false,high,"custom,comprehensive",[CF Requirements](http://cf-req),[CF Link](http://cf-link),"[{""fileName"":""cf-test.txt"",""id"":""cf-file-id"",""url"":""http://cf-file"",""mimeType"":""text/plain"",""size"":100}]",Custom field test setup,,,Step 1,Result 1,"{""value"":""development"",""isDefault"":false}","{""value"":""In Progress"",""isDefault"":false}",
362362`
363363
364364var customFieldFailureTestCases = []TestCase {
@@ -456,3 +456,147 @@ func TestCustomFieldFailureTestCases(t *testing.T) {
456456 })
457457 }
458458}
459+
460+ func TestFolderSlashEscaping (t * testing.T ) {
461+ qasCSV := NewQASphereCSV ()
462+
463+ err := qasCSV .AddTestCase (TestCase {
464+ Title : "tc-in-slash-folder" ,
465+ Folder : []string {"root/parent" , "child/leaf" },
466+ Priority : "high" ,
467+ })
468+ require .NoError (t , err )
469+
470+ csv , err := qasCSV .GenerateCSV ()
471+ require .NoError (t , err )
472+
473+ expected := `Folder,Folder Comment,Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params
474+ root\/parent/child\/leaf,,standalone,tc-in-slash-folder,,false,high,,,,,,,
475+ `
476+ require .Equal (t , expected , csv )
477+ }
478+
479+ func TestFolderSegmentEndingWithBackslash (t * testing.T ) {
480+ qasCSV := NewQASphereCSV ()
481+
482+ err := qasCSV .AddTestCase (TestCase {
483+ Title : "tc-bad-backslash" ,
484+ Folder : []string {"root\\ " },
485+ Priority : "high" ,
486+ })
487+ require .Error (t , err )
488+ require .Contains (t , err .Error (), "must not end with '\\ '" )
489+ }
490+
491+ func TestAddFolderEmpty (t * testing.T ) {
492+ qasCSV := NewQASphereCSV ()
493+
494+ err := qasCSV .AddFolder ([]string {"empty-folder" }, "" )
495+ require .NoError (t , err )
496+
497+ csv , err := qasCSV .GenerateCSV ()
498+ require .NoError (t , err )
499+
500+ expected := `Folder,Folder Comment,Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params
501+ empty-folder,,,,,,,,,,,,,
502+ `
503+ require .Equal (t , expected , csv )
504+ }
505+
506+ func TestAddFolderWithComment (t * testing.T ) {
507+ qasCSV := NewQASphereCSV ()
508+
509+ err := qasCSV .AddFolder ([]string {"commented-folder" }, "This is a folder comment" )
510+ require .NoError (t , err )
511+
512+ csv , err := qasCSV .GenerateCSV ()
513+ require .NoError (t , err )
514+
515+ expected := `Folder,Folder Comment,Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params
516+ commented-folder,This is a folder comment,,,,,,,,,,,,
517+ `
518+ require .Equal (t , expected , csv )
519+ }
520+
521+ func TestAddFolderWithCommentAndTestCases (t * testing.T ) {
522+ qasCSV := NewQASphereCSV ()
523+
524+ err := qasCSV .AddFolder ([]string {"my-folder" }, "Folder description" )
525+ require .NoError (t , err )
526+
527+ err = qasCSV .AddTestCase (TestCase {
528+ Title : "tc-in-commented-folder" ,
529+ Folder : []string {"my-folder" },
530+ Priority : "high" ,
531+ })
532+ require .NoError (t , err )
533+
534+ csv , err := qasCSV .GenerateCSV ()
535+ require .NoError (t , err )
536+
537+ expected := `Folder,Folder Comment,Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params
538+ my-folder,Folder description,,,,,,,,,,,,
539+ my-folder,,standalone,tc-in-commented-folder,,false,high,,,,,,,
540+ `
541+ require .Equal (t , expected , csv )
542+ }
543+
544+ func TestAddFolderValidation (t * testing.T ) {
545+ t .Run ("empty folder path" , func (t * testing.T ) {
546+ qasCSV := NewQASphereCSV ()
547+ err := qasCSV .AddFolder ([]string {}, "comment" )
548+ require .Error (t , err )
549+ require .Contains (t , err .Error (), "folder path must not be empty" )
550+ })
551+
552+ t .Run ("empty folder segment" , func (t * testing.T ) {
553+ qasCSV := NewQASphereCSV ()
554+ err := qasCSV .AddFolder ([]string {"root" , "" }, "comment" )
555+ require .Error (t , err )
556+ require .Contains (t , err .Error (), "folder segment must not be empty" )
557+ })
558+
559+ t .Run ("folder segment ending with backslash" , func (t * testing.T ) {
560+ qasCSV := NewQASphereCSV ()
561+ err := qasCSV .AddFolder ([]string {"root\\ " }, "comment" )
562+ require .Error (t , err )
563+ require .Contains (t , err .Error (), "must not end with '\\ '" )
564+ })
565+
566+ t .Run ("duplicate folder" , func (t * testing.T ) {
567+ qasCSV := NewQASphereCSV ()
568+ err := qasCSV .AddFolder ([]string {"root" }, "comment" )
569+ require .NoError (t , err )
570+ err = qasCSV .AddFolder ([]string {"root" }, "another comment" )
571+ require .Error (t , err )
572+ require .Contains (t , err .Error (), "already exists" )
573+ })
574+
575+ t .Run ("folder already has test cases" , func (t * testing.T ) {
576+ qasCSV := NewQASphereCSV ()
577+ err := qasCSV .AddTestCase (TestCase {
578+ Title : "tc" ,
579+ Folder : []string {"root" },
580+ Priority : "high" ,
581+ })
582+ require .NoError (t , err )
583+ err = qasCSV .AddFolder ([]string {"root" }, "comment" )
584+ require .Error (t , err )
585+ require .Contains (t , err .Error (), "already exists" )
586+ })
587+ }
588+
589+ func TestAddFolderWithSlashInName (t * testing.T ) {
590+ qasCSV := NewQASphereCSV ()
591+
592+ err := qasCSV .AddFolder ([]string {"folder/with/slashes" , "child" }, "slash comment" )
593+ require .NoError (t , err )
594+
595+ csv , err := qasCSV .GenerateCSV ()
596+ require .NoError (t , err )
597+
598+ expected := `Folder,Folder Comment,Type,Name,Legacy ID,Draft,Priority,Tags,Requirements,Links,Files,Preconditions,Parameter Values,Template Suffix Params
599+ folder\/with\/slashes/child,slash comment,,,,,,,,,,,,
600+ `
601+ require .Equal (t , expected , csv )
602+ }
0 commit comments