handles multiple lookup field values (#5112)

handles multiple lookup field values.

**Original `Lookup` list with single value**:
![Lookup-List-Single](https://github.com/alcionai/corso/assets/48874082/6a6b68cf-8fb9-4dfb-985e-702c4d74d3f0)

**Restored `Lookup` list with single value**:
![Restored-Lookup-List](https://github.com/alcionai/corso/assets/48874082/f97ac974-6a3b-4dd2-82c5-9f3596f9adaa)

**Original `Lookup` list with multiple values**:
![Lookup-List-Multi](https://github.com/alcionai/corso/assets/48874082/5f8b1b92-297f-4a66-b0b6-b5007d430690)

**Restored `Lookup` list with multiple values**:
![Restored-Lookup-List-Multi](https://github.com/alcionai/corso/assets/48874082/6c6d79ca-775d-4f50-abee-8090a28f3871)


#### Does this PR need a docs update or release note?

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [x]  No

#### Type of change

<!--- Please check the type of change your PR introduces: --->
- [x] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Issue(s)
#5108 
#5084 

#### Test Plan

<!-- How will this be tested prior to merging.-->
- [x] 💪 Manual
- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Hitesh Pattanayak 2024-01-30 11:19:00 +05:30 committed by GitHub
parent 734fd7239e
commit 08d4803ebe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 134 additions and 4 deletions

View File

@ -23,6 +23,7 @@ type columnDetails struct {
createFieldName string createFieldName string
getFieldName string getFieldName string
isPersonColumn bool isPersonColumn bool
isLookupColumn bool
isMultipleEnabled bool isMultipleEnabled bool
hasDefaultedToText bool hasDefaultedToText bool
} }
@ -420,6 +421,16 @@ func setColumnType(
case orig.GetNumber() != nil: case orig.GetNumber() != nil:
newColumn.SetNumber(orig.GetNumber()) newColumn.SetNumber(orig.GetNumber())
case orig.GetLookup() != nil: case orig.GetLookup() != nil:
colDetails.isLookupColumn = true
isMultipleEnabled := ptr.Val(orig.GetLookup().GetAllowMultipleValues())
colDetails.isMultipleEnabled = isMultipleEnabled
updatedName := colName + LookupIDFieldNamePart
colDetails.createFieldName = updatedName
if !isMultipleEnabled {
colDetails.getFieldName = updatedName
}
newColumn.SetLookup(orig.GetLookup()) newColumn.SetLookup(orig.GetLookup())
case orig.GetThumbnail() != nil: case orig.GetThumbnail() != nil:
newColumn.SetThumbnail(orig.GetThumbnail()) newColumn.SetThumbnail(orig.GetThumbnail())
@ -540,7 +551,8 @@ func populateMultipleValues(val any, filteredData map[string]any, colDetails *co
return return
} }
if !colDetails.isPersonColumn { if !colDetails.isPersonColumn &&
!colDetails.isLookupColumn {
return return
} }
@ -550,11 +562,10 @@ func populateMultipleValues(val any, filteredData map[string]any, colDetails *co
} }
lookupIDs := make([]float64, 0) lookupIDs := make([]float64, 0)
lookupKeys := []string{LookupIDKey, LookupValueKey, PersonEmailKey}
for _, nestedFields := range multiNestedFields { for _, nestedFields := range multiNestedFields {
md, ok := nestedFields.(map[string]any) md, ok := nestedFields.(map[string]any)
if !ok || !keys.HasKeys(md, lookupKeys...) { if !ok || !keys.HasKeys(md, checkFields(colDetails)...) {
continue continue
} }
@ -569,6 +580,17 @@ func populateMultipleValues(val any, filteredData map[string]any, colDetails *co
filteredData[colDetails.createFieldName] = lookupIDs filteredData[colDetails.createFieldName] = lookupIDs
} }
func checkFields(colDetails *columnDetails) []string {
switch {
case colDetails.isLookupColumn:
return []string{LookupIDKey, LookupValueKey}
case colDetails.isPersonColumn:
return []string{LookupIDKey, LookupValueKey, PersonEmailKey}
default:
return []string{}
}
}
// when creating list items with multiple values for a single column // when creating list items with multiple values for a single column
// we let the API know that we are sending a collection. // we let the API know that we are sending a collection.
// Hence this adds an additional field '<columnName>@@odata.type' // Hence this adds an additional field '<columnName>@@odata.type'
@ -587,7 +609,7 @@ func specifyODataType(filteredData map[string]any, colDetails *columnDetails, co
} }
switch { switch {
case colDetails.isPersonColumn: case colDetails.isPersonColumn, colDetails.isLookupColumn:
filteredData[colName+ODataTypeFieldNamePart] = ODataTypeFieldNameIntVal filteredData[colName+ODataTypeFieldNamePart] = ODataTypeFieldNameIntVal
default: default:
filteredData[colName+ODataTypeFieldNamePart] = ODataTypeFieldNameStringVal filteredData[colName+ODataTypeFieldNamePart] = ODataTypeFieldNameStringVal

View File

@ -288,6 +288,41 @@ func (suite *ListsUnitSuite) TestColumnDefinitionable_ColumnType() {
colNames["pg-col"].createFieldName == "pg-colLookupId" colNames["pg-col"].createFieldName == "pg-colLookupId"
}, },
}, },
{
name: "lookup column, single value",
getOrig: func() models.ColumnDefinitionable {
lookupColumn := models.NewLookupColumn()
cd := models.NewColumnDefinition()
cd.SetLookup(lookupColumn)
cd.SetName(ptr.To("refer-col"))
return cd
},
checkFn: func(cd models.ColumnDefinitionable, colNames map[string]*columnDetails) bool {
return cd.GetLookup() != nil &&
colNames["refer-col"].getFieldName == "refer-colLookupId" &&
colNames["refer-col"].createFieldName == "refer-colLookupId"
},
},
{
name: "lookup column, multiple value",
getOrig: func() models.ColumnDefinitionable {
lookupColumn := models.NewLookupColumn()
lookupColumn.SetAllowMultipleValues(ptr.To(true))
cd := models.NewColumnDefinition()
cd.SetLookup(lookupColumn)
cd.SetName(ptr.To("refer-col"))
return cd
},
checkFn: func(cd models.ColumnDefinitionable, colNames map[string]*columnDetails) bool {
return cd.GetLookup() != nil &&
colNames["refer-col"].getFieldName == "refer-col" &&
colNames["refer-col"].createFieldName == "refer-colLookupId"
},
},
{ {
name: "defaulted to text column", name: "defaulted to text column",
getOrig: func() models.ColumnDefinitionable { getOrig: func() models.ColumnDefinitionable {
@ -848,6 +883,51 @@ func (suite *ListsUnitSuite) TestSetAdditionalDataByColumnNames() {
"PersonsLookupId@odata.type": "Collection(Edm.Int32)", "PersonsLookupId@odata.type": "Collection(Edm.Int32)",
}, },
}, },
{
name: "lookup column, single value",
additionalData: map[string]any{
"ReferLookupId": ptr.To(10),
},
colDetails: map[string]*columnDetails{
"Refer": {
isLookupColumn: true,
getFieldName: "ReferLookupId",
createFieldName: "ReferLookupId",
},
},
assertFn: assert.False,
expectedResult: map[string]any{
"ReferLookupId": ptr.To(10),
},
},
{
name: "lookup column, multiple values",
additionalData: map[string]any{
"Refers": []any{
map[string]any{
"LookupId": ptr.To(float64(10)),
"LookupValue": ptr.To("item-1"),
},
map[string]any{
"LookupId": ptr.To(float64(11)),
"LookupValue": ptr.To("item-1"),
},
},
},
colDetails: map[string]*columnDetails{
"Refers": {
isLookupColumn: true,
isMultipleEnabled: true,
getFieldName: "Refers",
createFieldName: "RefersLookupId",
},
},
assertFn: assert.True,
expectedResult: map[string]any{
"RefersLookupId": []float64{10, 11},
"RefersLookupId@odata.type": "Collection(Edm.Int32)",
},
},
} }
for _, test := range tests { for _, test := range tests {
@ -861,6 +941,34 @@ func (suite *ListsUnitSuite) TestSetAdditionalDataByColumnNames() {
} }
} }
func (suite *ListsUnitSuite) TestCheckFields() {
t := suite.T()
tests := []struct {
name string
colDetails *columnDetails
expectedKeys []string
}{
{
name: "lookup column",
colDetails: &columnDetails{isLookupColumn: true},
expectedKeys: []string{LookupIDKey, LookupValueKey},
},
{
name: "person column",
colDetails: &columnDetails{isPersonColumn: true},
expectedKeys: []string{LookupIDKey, LookupValueKey, PersonEmailKey},
},
}
for _, test := range tests {
suite.Run(test.name, func() {
res := checkFields(test.colDetails)
assert.Equal(t, test.expectedKeys, res)
})
}
}
type ListsAPIIntgSuite struct { type ListsAPIIntgSuite struct {
tester.Suite tester.Suite
its intgTesterSetup its intgTesterSetup