Mock Connector expansion (#437)
Mock Connector data collection is a Messageable item and has been changed to be utilized in other portions of the corso repo.
This commit is contained in:
parent
7e60ec5073
commit
da9a22271d
@ -11,6 +11,14 @@ func FormatTime(t time.Time) string {
|
|||||||
return t.UTC().Format(time.RFC3339Nano)
|
return t.UTC().Format(time.RFC3339Nano)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FormatSimpleDateTime produces standard format for
|
||||||
|
// GraphConnector. Format used on CI testing and default folder
|
||||||
|
// creation during the restore process
|
||||||
|
func FormatSimpleDateTime(t time.Time) string {
|
||||||
|
timeFolderFormat := "02-Jan-2006_15:04:05"
|
||||||
|
return t.UTC().Format(timeFolderFormat)
|
||||||
|
}
|
||||||
|
|
||||||
// ParseTime makes a best attempt to produce a time value from
|
// ParseTime makes a best attempt to produce a time value from
|
||||||
// the provided string. Always returns a UTC timezone value.
|
// the provided string. Always returns a UTC timezone value.
|
||||||
func ParseTime(s string) (time.Time, error) {
|
func ParseTime(s string) (time.Time, error) {
|
||||||
|
|||||||
@ -9,11 +9,10 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/alcionai/corso/internal/connector/exchange"
|
"github.com/alcionai/corso/internal/connector/mockconnector"
|
||||||
"github.com/alcionai/corso/internal/connector/support"
|
"github.com/alcionai/corso/internal/connector/support"
|
||||||
"github.com/alcionai/corso/internal/data"
|
"github.com/alcionai/corso/internal/data"
|
||||||
ctesting "github.com/alcionai/corso/internal/testing"
|
ctesting "github.com/alcionai/corso/internal/testing"
|
||||||
"github.com/alcionai/corso/pkg/backup/details"
|
|
||||||
"github.com/alcionai/corso/pkg/selectors"
|
"github.com/alcionai/corso/pkg/selectors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -73,25 +72,16 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_ExchangeDataColl
|
|||||||
suite.Greater(len(exchangeData.FullPath()), 2)
|
suite.Greater(len(exchangeData.FullPath()), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO add mockdata for this test... Will not pass as is
|
//TestGraphConnector_restoreMessages uses mock data to ensure GraphConnector
|
||||||
|
// is able to restore a messageable item to a Mailbox.
|
||||||
func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_restoreMessages() {
|
func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_restoreMessages() {
|
||||||
user := "TEST_GRAPH_USER" // user.GetId()
|
user := "TEST_GRAPH_USER" // user.GetId()
|
||||||
file := "TEST_GRAPH_FILE" // Test file should be sent or received by the user
|
evs, err := ctesting.GetRequiredEnvVars(user)
|
||||||
evs, err := ctesting.GetRequiredEnvVars(user, file)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
suite.T().Skipf("Environment not configured: %v\n", err)
|
suite.T().Skipf("Environment not configured: %v\n", err)
|
||||||
}
|
}
|
||||||
bytes, err := ctesting.LoadAFile(evs[file]) // TEST_GRAPH_FILE should have a single Message && not present in target inbox
|
mdc := mockconnector.NewMockExchangeCollection([]string{"tenant", evs[user], mailCategory, "Inbox"}, 1)
|
||||||
if err != nil {
|
err = suite.connector.RestoreMessages(context.Background(), []data.Collection{mdc})
|
||||||
suite.T().Skipf("Support file not accessible: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ds := exchange.NewStream("test", bytes, details.ExchangeInfo{})
|
|
||||||
edc := exchange.NewCollection("tenant", []string{"tenantId", evs[user], mailCategory, "Inbox"})
|
|
||||||
|
|
||||||
edc.PopulateCollection(&ds)
|
|
||||||
//edc.FinishPopulation()
|
|
||||||
err = suite.connector.RestoreMessages(context.Background(), []data.Collection{&edc})
|
|
||||||
assert.NoError(suite.T(), err)
|
assert.NoError(suite.T(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/internal/common"
|
||||||
"github.com/alcionai/corso/internal/data"
|
"github.com/alcionai/corso/internal/data"
|
||||||
"github.com/alcionai/corso/pkg/backup/details"
|
"github.com/alcionai/corso/pkg/backup/details"
|
||||||
)
|
)
|
||||||
@ -26,8 +27,8 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewMockExchangeDataCollection creates an data collection that will return the specified number of
|
// NewMockExchangeDataCollection creates an data collection that will return the specified number of
|
||||||
// mock messages when iterated
|
// mock messages when iterated. Exchange type mail
|
||||||
func NewMockExchangeDataCollection(pathRepresentation []string, numMessagesToReturn int) *MockExchangeDataCollection {
|
func NewMockExchangeCollection(pathRepresentation []string, numMessagesToReturn int) *MockExchangeDataCollection {
|
||||||
c := &MockExchangeDataCollection{
|
c := &MockExchangeDataCollection{
|
||||||
fullPath: pathRepresentation,
|
fullPath: pathRepresentation,
|
||||||
messageCount: numMessagesToReturn,
|
messageCount: numMessagesToReturn,
|
||||||
@ -37,7 +38,7 @@ func NewMockExchangeDataCollection(pathRepresentation []string, numMessagesToRet
|
|||||||
|
|
||||||
for i := 0; i < c.messageCount; i++ {
|
for i := 0; i < c.messageCount; i++ {
|
||||||
// We can plug in whatever data we want here (can be an io.Reader to a test data file if needed)
|
// We can plug in whatever data we want here (can be an io.Reader to a test data file if needed)
|
||||||
c.Data = append(c.Data, []byte("test message"))
|
c.Data = append(c.Data, getMockMessageBytes("From: NewMockExchangeCollection"))
|
||||||
c.Names = append(c.Names, uuid.NewString())
|
c.Names = append(c.Names, uuid.NewString())
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
@ -82,3 +83,13 @@ func (med *MockExchangeData) ToReader() io.ReadCloser {
|
|||||||
func (med *MockExchangeData) Info() details.ItemInfo {
|
func (med *MockExchangeData) Info() details.ItemInfo {
|
||||||
return details.ItemInfo{Exchange: &details.ExchangeInfo{Sender: "foo@bar.com", Subject: "Hello world!", Received: time.Now()}}
|
return details.ItemInfo{Exchange: &details.ExchangeInfo{Sender: "foo@bar.com", Subject: "Hello world!", Received: time.Now()}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getMockMessageBytes returns bytes for Messageable item.
|
||||||
|
// Contents verified as working with sample data from kiota-serialization-json-go v0.5.5
|
||||||
|
func getMockMessageBytes(subject string) []byte {
|
||||||
|
|
||||||
|
message := "{\n \"@odata.etag\": \"W/\\\"CQAAABYAAAB8wYc0thTTTYl3RpEYIUq+AAAZ0f0I\\\"\",\n \"id\": \"AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8_7BwB8wYc0thTTTYl3RpEYIUq_AAAAAAEMAAB8wYc0thTTTYl3RpEYIUq_AAAZ3wG3AAA=\",\n \"createdDateTime\": \"2022-04-08T18:08:02Z\",\n \"lastModifiedDateTime\": \"2022-05-17T13:46:55Z\",\n \"changeKey\": \"CQAAABYAAAB8wYc0thTTTYl3RpEYIUq+AAAZ0f0I\",\n \"categories\": [],\n \"receivedDateTime\": \"2022-04-08T18:08:02Z\",\n \"sentDateTime\": \"2022-04-08T18:07:53Z\",\n \"hasAttachments\": false,\n \"internetMessageId\": \"<MWHPR1401MB1952C46D4A46B6398F562B0FA6E99@MWHPR1401MB1952.namprd14.prod.outlook.com>\",\n \"subject\": \"" +
|
||||||
|
subject + " " + common.FormatSimpleDateTime(time.Now()) + " Different\",\n \"bodyPreview\": \"Who is coming to next week's party? I cannot imagine it is July soon\",\n \"importance\": \"normal\",\n \"parentFolderId\": \"AQMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4ADVkZWQwNmNlMTgALgAAAw_9XBStqZdPuOVIalVTz7sBAHzBhzS2FNNNiXdGkRghSr4AAAIBDAAAAA==\",\n \"conversationId\": \"AAQkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOAAQAI7SSzmEPaRJsY-TWIALn1g=\",\n \"conversationIndex\": \"AQHYS3N3jtJLOYQ9pEmxj9NYgAufWA==\",\n \"isDeliveryReceiptRequested\": null,\n \"isReadReceiptRequested\": false,\n \"isRead\": true,\n \"isDraft\": false,\n \"webLink\": \"https://outlook.office365.com/owa/?ItemID=AAMkAGQ1NzViZTdhLTEwMTMtNGJjNi05YWI2LTg4NWRlZDA2Y2UxOABGAAAAAAAPvVwUramXT7jlSGpVU8%2B7BwB8wYc0thTTTYl3RpEYIUq%2BAAAAAAEMAAB8wYc0thTTTYl3RpEYIUq%2BAAAZ3wG3AAA%3D&exvsurl=1&viewmodel=ReadMessageItem\",\n \"inferenceClassification\": \"focused\",\n \"body\": {\n \"contentType\": \"html\",\n \"content\": \"<html><head><meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\"><meta name=\\\"Generator\\\" content=\\\"Microsoft Word 15 (filtered medium)\\\"><style><!--@font-face{font-family:\\\"Cambria Math\\\"}@font-face{font-family:Calibri}p.MsoNormal, li.MsoNormal, div.MsoNormal{margin:0in;font-size:11.0pt;font-family:\\\"Calibri\\\",sans-serif}span.EmailStyle17{font-family:\\\"Calibri\\\",sans-serif;color:windowtext}.MsoChpDefault{font-family:\\\"Calibri\\\",sans-serif}@page WordSection1{margin:1.0in 1.0in 1.0in 1.0in}div.WordSection1{}--></style></head><body lang=\\\"EN-US\\\" link=\\\"#0563C1\\\" vlink=\\\"#954F72\\\" style=\\\"word-wrap:break-word\\\"><div class=\\\"WordSection1\\\"><p class=\\\"MsoNormal\\\">I've been going through with the changing of messages. It shouldn't have the same calls, right? Call Me? </p><p class=\\\"MsoNormal\\\"> </p><p class=\\\"MsoNormal\\\">We want to be able to send multiple messages and we want to be able to respond and do other things that make sense for our users. In this case. Let’s consider a Mailbox</p></div></body></html>\"\n },\n \"sender\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"from\": {\n \"emailAddress\": {\n \"name\": \"Lidia Holloway\",\n \"address\": \"lidiah@8qzvrj.onmicrosoft.com\"\n }\n },\n \"toRecipients\": [\n {\n \"emailAddress\": {\n \"name\": \"Dustin Abbot\",\n \"address\": \"dustina@8qzvrj.onmicrosoft.com\"\n }\n }\n ],\n \"ccRecipients\": [],\n \"bccRecipients\": [],\n \"replyTo\": [],\n \"flag\": {\n \"flagStatus\": \"notFlagged\"\n }\n}\n"
|
||||||
|
|
||||||
|
return []byte(message)
|
||||||
|
}
|
||||||
|
|||||||
@ -1,25 +1,28 @@
|
|||||||
package mockconnector_test
|
package mockconnector_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/alcionai/corso/internal/connector/mockconnector"
|
"github.com/alcionai/corso/internal/connector/mockconnector"
|
||||||
|
"github.com/alcionai/corso/internal/connector/support"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockExchangeDataCollectionSuite struct {
|
type MockExchangeCollectionSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMockExchangeDataCollectionSuite(t *testing.T) {
|
func TestMockExchangeCollectionSuite(t *testing.T) {
|
||||||
suite.Run(t, new(MockExchangeDataCollectionSuite))
|
suite.Run(t, new(MockExchangeCollectionSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *MockExchangeDataCollectionSuite) TestMockExchangeDataCollection() {
|
func (suite *MockExchangeCollectionSuite) TestMockExchangeCollection() {
|
||||||
mdc := mockconnector.NewMockExchangeDataCollection([]string{"foo", "bar"}, 2)
|
mdc := mockconnector.NewMockExchangeCollection([]string{"foo", "bar"}, 2)
|
||||||
|
|
||||||
messagesRead := 0
|
messagesRead := 0
|
||||||
|
|
||||||
@ -30,3 +33,22 @@ func (suite *MockExchangeDataCollectionSuite) TestMockExchangeDataCollection() {
|
|||||||
}
|
}
|
||||||
assert.Equal(suite.T(), 2, messagesRead)
|
assert.Equal(suite.T(), 2, messagesRead)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewExchangeCollectionMail_Hydration tests that mock exchange mail data collection can be used for restoration
|
||||||
|
// functions by verifying no failures on (de)serializing steps using kiota serialization library
|
||||||
|
func (suite *MockExchangeCollectionSuite) TestMockExchangeCollection_NewExchangeCollectionMail_Hydration() {
|
||||||
|
t := suite.T()
|
||||||
|
mdc := mockconnector.NewMockExchangeCollection([]string{"foo", "bar"}, 3)
|
||||||
|
var (
|
||||||
|
byteArray []byte
|
||||||
|
)
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
for stream := range mdc.Items() {
|
||||||
|
_, err := buf.ReadFrom(stream.ToReader())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
byteArray = buf.Bytes()
|
||||||
|
something, err := support.CreateFromBytes(byteArray, models.CreateMessageFromDiscriminatorValue)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, something)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -120,11 +120,11 @@ func (suite *KopiaUnitSuite) TestBuildDirectoryTree() {
|
|||||||
details := &details.Details{}
|
details := &details.Details{}
|
||||||
|
|
||||||
collections := []data.Collection{
|
collections := []data.Collection{
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{tenant, user1, emails},
|
[]string{tenant, user1, emails},
|
||||||
expectedFileCount[user1],
|
expectedFileCount[user1],
|
||||||
),
|
),
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{tenant, user2, emails},
|
[]string{tenant, user2, emails},
|
||||||
expectedFileCount[user2],
|
expectedFileCount[user2],
|
||||||
),
|
),
|
||||||
@ -182,7 +182,7 @@ func (suite *KopiaUnitSuite) TestBuildDirectoryTree_NoAncestorDirs() {
|
|||||||
|
|
||||||
details := &details.Details{}
|
details := &details.Details{}
|
||||||
collections := []data.Collection{
|
collections := []data.Collection{
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{emails},
|
[]string{emails},
|
||||||
expectedFileCount,
|
expectedFileCount,
|
||||||
),
|
),
|
||||||
@ -215,11 +215,11 @@ func (suite *KopiaUnitSuite) TestBuildDirectoryTree_Fails() {
|
|||||||
// - emails
|
// - emails
|
||||||
// - 42 separate files
|
// - 42 separate files
|
||||||
[]data.Collection{
|
[]data.Collection{
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{"user1", "emails"},
|
[]string{"user1", "emails"},
|
||||||
5,
|
5,
|
||||||
),
|
),
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{"user2", "emails"},
|
[]string{"user2", "emails"},
|
||||||
42,
|
42,
|
||||||
),
|
),
|
||||||
@ -228,7 +228,7 @@ func (suite *KopiaUnitSuite) TestBuildDirectoryTree_Fails() {
|
|||||||
{
|
{
|
||||||
"NoCollectionPath",
|
"NoCollectionPath",
|
||||||
[]data.Collection{
|
[]data.Collection{
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
nil,
|
nil,
|
||||||
5,
|
5,
|
||||||
),
|
),
|
||||||
@ -243,11 +243,11 @@ func (suite *KopiaUnitSuite) TestBuildDirectoryTree_Fails() {
|
|||||||
// - 5 separate files
|
// - 5 separate files
|
||||||
// - 42 separate files
|
// - 42 separate files
|
||||||
[]data.Collection{
|
[]data.Collection{
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{"a-tenant", "user1", "emails"},
|
[]string{"a-tenant", "user1", "emails"},
|
||||||
5,
|
5,
|
||||||
),
|
),
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{"a-tenant", "user1"},
|
[]string{"a-tenant", "user1"},
|
||||||
42,
|
42,
|
||||||
),
|
),
|
||||||
@ -402,11 +402,11 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
|
|||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
collections := []data.Collection{
|
collections := []data.Collection{
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{"a-tenant", "user1", "emails"},
|
[]string{"a-tenant", "user1", "emails"},
|
||||||
5,
|
5,
|
||||||
),
|
),
|
||||||
mockconnector.NewMockExchangeDataCollection(
|
mockconnector.NewMockExchangeCollection(
|
||||||
[]string{"a-tenant", "user2", "emails"},
|
[]string{"a-tenant", "user2", "emails"},
|
||||||
42,
|
42,
|
||||||
),
|
),
|
||||||
@ -683,8 +683,8 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestRestoreMultipleItems() {
|
|||||||
tid := uuid.NewString()
|
tid := uuid.NewString()
|
||||||
p1 := []string{tid, "uid", "emails", "fid"}
|
p1 := []string{tid, "uid", "emails", "fid"}
|
||||||
p2 := []string{tid, "uid2", "emails", "fid"}
|
p2 := []string{tid, "uid2", "emails", "fid"}
|
||||||
dc1 := mockconnector.NewMockExchangeDataCollection(p1, 1)
|
dc1 := mockconnector.NewMockExchangeCollection(p1, 1)
|
||||||
dc2 := mockconnector.NewMockExchangeDataCollection(p2, 1)
|
dc2 := mockconnector.NewMockExchangeCollection(p2, 1)
|
||||||
fp1 := append(p1, dc1.Names[0])
|
fp1 := append(p1, dc1.Names[0])
|
||||||
fp2 := append(p2, dc2.Names[0])
|
fp2 := append(p2, dc2.Names[0])
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user