Restore tests for contacts (#989)
## Description Test restoring a single contacts folder and multiple contacts folders. This tests that items from different folders can be restored, but not that items from multiple folders can be backed up (because the restore colocates into a single folder) ## Type of change <!--- Please check the type of change your PR introduces: ---> - [ ] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [x] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🐹 Trivial/Minor ## Issue(s) * #913 merge after * #986 ## Test Plan <!-- How will this be tested prior to merging.--> - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
1a188ce657
commit
0cba7a402c
@ -160,6 +160,90 @@ func checkMessage(
|
|||||||
assert.Equal(t, expected.GetUniqueBody(), got.GetUniqueBody(), "UniqueBody")
|
assert.Equal(t, expected.GetUniqueBody(), got.GetUniqueBody(), "UniqueBody")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkContact(
|
||||||
|
t *testing.T,
|
||||||
|
expected models.Contactable,
|
||||||
|
got models.Contactable,
|
||||||
|
) {
|
||||||
|
emptyOrEqual(t, expected.GetAssistantName(), got.GetAssistantName(), "AssistantName")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetBirthday(), got.GetBirthday(), "Birthday")
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetBusinessAddress(), got.GetBusinessAddress())
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetBusinessHomePage(), got.GetBusinessHomePage(), "BusinessHomePage")
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetBusinessPhones(), got.GetBusinessPhones())
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetCategories(), got.GetCategories())
|
||||||
|
|
||||||
|
// Skip ChangeKey as it's tied to this specific instance of the item.
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetChildren(), got.GetChildren())
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetCompanyName(), got.GetCompanyName(), "CompanyName")
|
||||||
|
|
||||||
|
// Skip CreatedDateTime as it's tied to this specific instance of the item.
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetDepartment(), got.GetDepartment(), "Department")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetDisplayName(), got.GetDisplayName(), "DisplayName")
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetEmailAddresses(), got.GetEmailAddresses())
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetFileAs(), got.GetFileAs(), "FileAs")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetGeneration(), got.GetGeneration(), "Generation")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetGivenName(), got.GetGivenName(), "GivenName")
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetHomeAddress(), got.GetHomeAddress())
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetHomePhones(), got.GetHomePhones())
|
||||||
|
|
||||||
|
// Skip CreatedDateTime as it's tied to this specific instance of the item.
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetImAddresses(), got.GetImAddresses())
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetInitials(), got.GetInitials(), "Initials")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetJobTitle(), got.GetJobTitle(), "JobTitle")
|
||||||
|
|
||||||
|
// Skip CreatedDateTime as it's tied to this specific instance of the item.
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetManager(), got.GetManager(), "Manager")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetMiddleName(), got.GetMiddleName(), "MiddleName")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetMobilePhone(), got.GetMobilePhone(), "MobilePhone")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetNickName(), got.GetNickName(), "NickName")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetOfficeLocation(), got.GetOfficeLocation(), "OfficeLocation")
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetOtherAddress(), got.GetOtherAddress())
|
||||||
|
|
||||||
|
// Skip ParentFolderId as it's tied to this specific instance of the item.
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetPersonalNotes(), got.GetPersonalNotes(), "PersonalNotes")
|
||||||
|
|
||||||
|
assert.Equal(t, expected.GetPhoto(), got.GetPhoto())
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetProfession(), got.GetProfession(), "Profession")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetSpouseName(), got.GetSpouseName(), "SpouseName")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetSurname(), got.GetSurname(), "Surname")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetTitle(), got.GetTitle(), "Title")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetYomiCompanyName(), got.GetYomiCompanyName(), "YomiCompanyName")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetYomiGivenName(), got.GetYomiGivenName(), "YomiGivenName")
|
||||||
|
|
||||||
|
emptyOrEqual(t, expected.GetYomiSurname(), got.GetYomiSurname(), "YomiSurname")
|
||||||
|
}
|
||||||
|
|
||||||
func compareExchangeEmail(
|
func compareExchangeEmail(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
expected map[string][]byte,
|
expected map[string][]byte,
|
||||||
@ -186,6 +270,32 @@ func compareExchangeEmail(
|
|||||||
checkMessage(t, expectedMessage, itemMessage)
|
checkMessage(t, expectedMessage, itemMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compareExchangeContact(
|
||||||
|
t *testing.T,
|
||||||
|
expected map[string][]byte,
|
||||||
|
item data.Stream,
|
||||||
|
) {
|
||||||
|
itemData, err := io.ReadAll(item.ToReader())
|
||||||
|
if !assert.NoError(t, err, "reading collection item: %s", item.UUID()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
itemContact, err := support.CreateContactFromBytes(itemData)
|
||||||
|
if !assert.NoError(t, err, "deserializing backed up contact") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedBytes, ok := expected[*itemContact.GetMiddleName()]
|
||||||
|
if !assert.True(t, ok, "unexpected item with middle name %q", *itemContact.GetMiddleName()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedContact, err := support.CreateContactFromBytes(expectedBytes)
|
||||||
|
assert.NoError(t, err, "deserializing source contact")
|
||||||
|
|
||||||
|
checkContact(t, expectedContact, itemContact)
|
||||||
|
}
|
||||||
|
|
||||||
func compareItem(
|
func compareItem(
|
||||||
t *testing.T,
|
t *testing.T,
|
||||||
expected map[string][]byte,
|
expected map[string][]byte,
|
||||||
@ -198,6 +308,8 @@ func compareItem(
|
|||||||
switch category {
|
switch category {
|
||||||
case path.EmailCategory:
|
case path.EmailCategory:
|
||||||
compareExchangeEmail(t, expected, item)
|
compareExchangeEmail(t, expected, item)
|
||||||
|
case path.ContactsCategory:
|
||||||
|
compareExchangeContact(t, expected, item)
|
||||||
default:
|
default:
|
||||||
assert.FailNowf(t, "unexpected Exchange category: %s", category.String())
|
assert.FailNowf(t, "unexpected Exchange category: %s", category.String())
|
||||||
}
|
}
|
||||||
@ -295,13 +407,17 @@ func collectionsForInfo(
|
|||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
baseExpected := expectedData[baseDestPath.String()]
|
||||||
|
if baseExpected == nil {
|
||||||
expectedData[baseDestPath.String()] = make(map[string][]byte, len(info.items))
|
expectedData[baseDestPath.String()] = make(map[string][]byte, len(info.items))
|
||||||
|
baseExpected = expectedData[baseDestPath.String()]
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < len(info.items); i++ {
|
for i := 0; i < len(info.items); i++ {
|
||||||
c.Names[i] = info.items[i].name
|
c.Names[i] = info.items[i].name
|
||||||
c.Data[i] = info.items[i].data
|
c.Data[i] = info.items[i].data
|
||||||
|
|
||||||
expectedData[baseDestPath.String()][info.items[i].lookupKey] = info.items[i].data
|
baseExpected[info.items[i].lookupKey] = info.items[i].data
|
||||||
}
|
}
|
||||||
|
|
||||||
collections = append(collections, c)
|
collections = append(collections, c)
|
||||||
|
|||||||
@ -367,42 +367,6 @@ func (suite *GraphConnectorIntegrationSuite) TestCreateAndDeleteCalendar() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ashmrtn): Merge this with the below once we get comparison logic for
|
|
||||||
// contacts.
|
|
||||||
func (suite *GraphConnectorIntegrationSuite) TestRestoreContact() {
|
|
||||||
t := suite.T()
|
|
||||||
sel := selectors.NewExchangeRestore()
|
|
||||||
fullpath, err := path.Builder{}.Append("testing").
|
|
||||||
ToDataLayerExchangePathForCategory(
|
|
||||||
suite.connector.tenant,
|
|
||||||
suite.user,
|
|
||||||
path.ContactsCategory,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
|
|
||||||
require.NoError(t, err)
|
|
||||||
aPath, err := path.Builder{}.Append("validator").ToDataLayerExchangePathForCategory(
|
|
||||||
suite.connector.tenant,
|
|
||||||
suite.user,
|
|
||||||
path.ContactsCategory,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
dcs := mockconnector.NewMockContactCollection(fullpath, 3)
|
|
||||||
two := mockconnector.NewMockContactCollection(aPath, 2)
|
|
||||||
collections := []data.Collection{dcs, two}
|
|
||||||
ctx := context.Background()
|
|
||||||
connector := loadConnector(ctx, suite.T())
|
|
||||||
dest := control.DefaultRestoreDestination(common.SimpleDateTimeFormat)
|
|
||||||
err = connector.RestoreDataCollections(ctx, sel.Selector, dest, collections)
|
|
||||||
assert.NoError(suite.T(), err)
|
|
||||||
|
|
||||||
value := connector.AwaitStatus()
|
|
||||||
assert.Equal(t, value.FolderCount, 1)
|
|
||||||
suite.T().Log(value.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *GraphConnectorIntegrationSuite) TestEmptyCollections() {
|
func (suite *GraphConnectorIntegrationSuite) TestEmptyCollections() {
|
||||||
dest := control.DefaultRestoreDestination(common.SimpleDateTimeFormatOneDrive)
|
dest := control.DefaultRestoreDestination(common.SimpleDateTimeFormatOneDrive)
|
||||||
table := []struct {
|
table := []struct {
|
||||||
@ -464,10 +428,12 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() {
|
|||||||
service path.ServiceType
|
service path.ServiceType
|
||||||
collections []colInfo
|
collections []colInfo
|
||||||
backupSelFunc func(dest control.RestoreDestination, backupUser string) selectors.Selector
|
backupSelFunc func(dest control.RestoreDestination, backupUser string) selectors.Selector
|
||||||
|
expectedRestoreFolders int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "MultipleEmailsSingleFolder",
|
name: "MultipleEmailsSingleFolder",
|
||||||
service: path.ExchangeService,
|
service: path.ExchangeService,
|
||||||
|
expectedRestoreFolders: 1,
|
||||||
collections: []colInfo{
|
collections: []colInfo{
|
||||||
{
|
{
|
||||||
pathElements: []string{"Inbox"},
|
pathElements: []string{"Inbox"},
|
||||||
@ -509,6 +475,100 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() {
|
|||||||
[]string{dest.ContainerName},
|
[]string{dest.ContainerName},
|
||||||
))
|
))
|
||||||
|
|
||||||
|
return backupSel.Selector
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MultipleContactsSingleFolder",
|
||||||
|
service: path.ExchangeService,
|
||||||
|
expectedRestoreFolders: 1,
|
||||||
|
collections: []colInfo{
|
||||||
|
{
|
||||||
|
pathElements: []string{"Contacts"},
|
||||||
|
category: path.ContactsCategory,
|
||||||
|
items: []itemInfo{
|
||||||
|
{
|
||||||
|
name: "someencodeditemID",
|
||||||
|
data: mockconnector.GetMockContactBytes("Ghimley"),
|
||||||
|
lookupKey: "Ghimley",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "someencodeditemID2",
|
||||||
|
data: mockconnector.GetMockContactBytes("Irgot"),
|
||||||
|
lookupKey: "Irgot",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "someencodeditemID3",
|
||||||
|
data: mockconnector.GetMockContactBytes("Jannes"),
|
||||||
|
lookupKey: "Jannes",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// TODO(ashmrtn): Generalize this once we know the path transforms that
|
||||||
|
// occur during restore.
|
||||||
|
backupSelFunc: func(dest control.RestoreDestination, backupUser string) selectors.Selector {
|
||||||
|
backupSel := selectors.NewExchangeBackup()
|
||||||
|
backupSel.Include(backupSel.ContactFolders(
|
||||||
|
[]string{backupUser},
|
||||||
|
[]string{dest.ContainerName},
|
||||||
|
))
|
||||||
|
|
||||||
|
return backupSel.Selector
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "MultipleContactsMutlipleFolders",
|
||||||
|
service: path.ExchangeService,
|
||||||
|
expectedRestoreFolders: 1,
|
||||||
|
collections: []colInfo{
|
||||||
|
{
|
||||||
|
pathElements: []string{"Work"},
|
||||||
|
category: path.ContactsCategory,
|
||||||
|
items: []itemInfo{
|
||||||
|
{
|
||||||
|
name: "someencodeditemID",
|
||||||
|
data: mockconnector.GetMockContactBytes("Ghimley"),
|
||||||
|
lookupKey: "Ghimley",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "someencodeditemID2",
|
||||||
|
data: mockconnector.GetMockContactBytes("Irgot"),
|
||||||
|
lookupKey: "Irgot",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "someencodeditemID3",
|
||||||
|
data: mockconnector.GetMockContactBytes("Jannes"),
|
||||||
|
lookupKey: "Jannes",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathElements: []string{"Personal"},
|
||||||
|
category: path.ContactsCategory,
|
||||||
|
items: []itemInfo{
|
||||||
|
{
|
||||||
|
name: "someencodeditemID4",
|
||||||
|
data: mockconnector.GetMockContactBytes("Argon"),
|
||||||
|
lookupKey: "Argon",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "someencodeditemID5",
|
||||||
|
data: mockconnector.GetMockContactBytes("Bernard"),
|
||||||
|
lookupKey: "Bernard",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// TODO(ashmrtn): Generalize this once we know the path transforms that
|
||||||
|
// occur during restore.
|
||||||
|
backupSelFunc: func(dest control.RestoreDestination, backupUser string) selectors.Selector {
|
||||||
|
backupSel := selectors.NewExchangeBackup()
|
||||||
|
backupSel.Include(backupSel.ContactFolders(
|
||||||
|
[]string{backupUser},
|
||||||
|
[]string{dest.ContainerName},
|
||||||
|
))
|
||||||
|
|
||||||
return backupSel.Selector
|
return backupSel.Selector
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -537,7 +597,7 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
status := restoreGC.AwaitStatus()
|
status := restoreGC.AwaitStatus()
|
||||||
assert.Equal(t, len(test.collections), status.FolderCount, "status.FolderCount")
|
assert.Equal(t, test.expectedRestoreFolders, status.FolderCount, "status.FolderCount")
|
||||||
assert.Equal(t, totalItems, status.ObjectCount, "status.ObjectCount")
|
assert.Equal(t, totalItems, status.ObjectCount, "status.ObjectCount")
|
||||||
assert.Equal(t, totalItems, status.Successful, "status.Successful")
|
assert.Equal(t, totalItems, status.Successful, "status.Successful")
|
||||||
|
|
||||||
@ -559,7 +619,7 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() {
|
|||||||
checkCollections(t, totalItems, expectedData, dcs)
|
checkCollections(t, totalItems, expectedData, dcs)
|
||||||
|
|
||||||
status = backupGC.AwaitStatus()
|
status = backupGC.AwaitStatus()
|
||||||
assert.Equal(t, len(test.collections), status.FolderCount, "status.FolderCount")
|
assert.Equal(t, test.expectedRestoreFolders, status.FolderCount, "status.FolderCount")
|
||||||
assert.Equal(t, totalItems, status.ObjectCount, "status.ObjectCount")
|
assert.Equal(t, totalItems, status.ObjectCount, "status.ObjectCount")
|
||||||
assert.Equal(t, totalItems, status.Successful, "status.Successful")
|
assert.Equal(t, totalItems, status.Successful, "status.Successful")
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user