Skip to content

Commit

Permalink
fix(GODT-1605): add test coverage for nil hierarchy delimiter.
Browse files Browse the repository at this point in the history
  • Loading branch information
cuthix committed Oct 10, 2022
1 parent 49c1929 commit 64f8418
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 18 deletions.
4 changes: 4 additions & 0 deletions internal/state/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (

// listSuperiors returns all names superior to the given name, if hierarchies are indicated with the given delimiter.
func listSuperiors(name, delimiter string) []string {
if delimiter == "" {
return nil
}

split := strings.Split(name, delimiter)
if len(split) == 0 {
return nil
Expand Down
66 changes: 48 additions & 18 deletions internal/state/paths_test.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,71 @@
package state

import (
"fmt"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

func TestListSuperiorNames(t *testing.T) {
tests := []struct {
for name, data := range map[string]struct {
name, delimiter string

want []string
want []string
}{
{
"no parents": {
name: "this",
delimiter: "/",
want: []string{},
want: nil,
},
{
"has parents": {
name: "this/is/a/test",
delimiter: "/",
want: []string{"this", "this/is", "this/is/a"},
},
{
name: "/this/is/a/test",
"wrong delimiter": {
name: "this.is.a.test",
delimiter: "/",
want: []string{"/this", "/this/is", "/this/is/a"},
want: nil,
},
"nil delimiter": {
name: "/nil/delimiter.used",
delimiter: "",
want: nil,
},
} {
t.Run(name, func(t *testing.T) {
require.Equal(t, data.want, listSuperiors(data.name, data.delimiter))
})
}
}

for _, tt := range tests {
tt := tt

t.Run(fmt.Sprintf("%#v", tt), func(t *testing.T) {
if res := listSuperiors(tt.name, tt.delimiter); strings.Join(res, "") != strings.Join(tt.want, "") {
t.Errorf("expected result of %v but got %v", tt.want, res)
}
func TestListInferiorNames(t *testing.T) {
for name, data := range map[string]struct {
parent string
delimiter string
names []string
want []string
}{
"no children": {
parent: "this",
delimiter: "/",
names: []string{"one", "two", "three", "this", "a/b", "c/d"},
want: []string{},
},
"has children": {
parent: "this",
delimiter: "/",
names: []string{"a/b", "this/one", "this", "this/two", "this/one/two/three", "c/d"},
want: []string{"this/two", "this/one/two/three", "this/one"},
},
"nil delimiter": {
parent: "this",
delimiter: "",
names: []string{"a/b", "this/one", "this", "this/two", "this/one/two/three", "c/d"},
want: []string{},
},
} {
t.Run(name, func(t *testing.T) {
require.Equal(t, data.want, listInferiors(data.parent, data.delimiter, data.names))
})
}
}
9 changes: 9 additions & 0 deletions internal/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package state

import (
"context"
"errors"
"fmt"
"strings"
"sync/atomic"
Expand Down Expand Up @@ -148,6 +149,14 @@ func (state *State) Examine(ctx context.Context, name string, fn func(*Mailbox)
}

func (state *State) Create(ctx context.Context, name string) error {
if strings.HasPrefix(name, state.delimiter) {
return errors.New("invalid mailbox name: begins with hierarchy separator")
}

if strings.Contains(name, state.delimiter+state.delimiter) {
return errors.New("invalid mailbox name: has adjacent hierarchy separators")
}

mboxesToCreate, err := db.ReadResult(ctx, state.db(), func(ctx context.Context, client *ent.Client) ([]string, error) {
var mboxesToCreate []string
// If the mailbox name is suffixed with the server's hierarchy separator, remove the separator and still create
Expand Down
24 changes: 24 additions & 0 deletions tests/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ func TestCreateWithDifferentHierarchySeparator(t *testing.T) {
})
}

func TestCreateWithNilHierarchySeparator(t *testing.T) {
runOneToOneTestClientWithAuth(t, defaultServerOptions(t, withDelimiter("")), func(client *client.Client, _ *testSession) {
matchMailboxNamesClient(t, client, "", "*", []string{"INBOX"})
require.NoError(t, client.Create("Folder/Bar"))
matchMailboxNamesClient(t, client, "", "*", []string{"INBOX", "Folder/Bar"})
require.NoError(t, client.Create("Folder"))
matchMailboxNamesClient(t, client, "", "*", []string{"INBOX", "Folder", "Folder/Bar"})
})
}

func TestCreatePreviousLevelHierarchyIfNonExisting(t *testing.T) {
runOneToOneTestClientWithAuth(t, defaultServerOptions(t), func(client *client.Client, _ *testSession) {
require.NoError(t, client.Create("Folder/Bar/ZZ"))
Expand Down Expand Up @@ -96,3 +106,17 @@ func TestEnsureNewMailboxWithDeletedNameHasGreaterId(t *testing.T) {

})
}

func TestCreateAdjacentSeparator(t *testing.T) {
runOneToOneTestWithAuth(t, defaultServerOptions(t), func(c *testConnection, _ *testSession) {
c.C(`A001 create foo//bar`)
c.Sx(`^A001 NO .*adjacent hierarchy separators\r\n$`)
})
}

func TestCreateBeginsWithSeparator(t *testing.T) {
runOneToOneTestWithAuth(t, defaultServerOptions(t), func(c *testConnection, _ *testSession) {
c.C(`A001 create /foo`)
c.Sx(`^A001 NO .*begins with hierarchy separator\r\n$`)
})
}
14 changes: 14 additions & 0 deletions tests/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,17 @@ func TestListSpecialUseAttributes(t *testing.T) {
c.OK(`a`)
})
}

func TestListNilDelimiter(t *testing.T) {
runOneToOneTestWithAuth(t, defaultServerOptions(t, withDelimiter("")), func(c *testConnection, s *testSession) {
s.mailboxCreated("user", []string{"INBOX"})
s.mailboxCreated("user", []string{"Folders/Custom"})

c.C(`a list "" "*"`)
c.S(
`* LIST (\Unmarked) NIL "INBOX"`,
`* LIST (\Unmarked) NIL "Folders/Custom"`,
)
c.OK(`a`)
})
}
14 changes: 14 additions & 0 deletions tests/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,17 @@ func TestSelectUTF7(t *testing.T) {
c.C(`A005 LIST "" "*"`).Sxe(`&ZeVnLIqe-`).OK(`A005`)
})
}

func TestSelectWithNilDelimiter(t *testing.T) {
runOneToOneTestWithAuth(t, defaultServerOptions(t, withDelimiter("")), func(c *testConnection, _ *testSession) {
// Test we can create a mailbox with a UTF-7 name.
c.C("a CREATE A").OK("a")
c.C("a CREATE A/B").OK("a")
c.C("a CREATE A/B/C").OK("a")

// Test we can select the mailbox.
c.C("A001 SELECT A").OK("A001")
c.C("A002 SELECT A/B").OK("A002")
c.C("A003 SELECT A/B/C").OK("A003")
})
}

0 comments on commit 64f8418

Please sign in to comment.