handles single & multiple values for metadata columns (#5121)
handles single & multiple values for metadata columns Similar to `Hyperlink` and `Column` columns, `Metadata` column too is unrecognizable from GRAPH API response. Hence identifying from the field column names. `Metadata` fields are like tags. A `Metadata` fields can be configured to hold multiple values/tags **Original List with `Metadata` column (Department) with single value/tag**:  **Restored List with `Metadata` column with single value/tag**:  **Original List with `Metadata` column (Department) with multiple value/tag**:  **Restored List with `Metadata` column with multiple value/tag**:  #### 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) #5084 #5108 #### Test Plan <!-- How will this be tested prior to merging.--> - [x] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
08d4803ebe
commit
576c9f6b53
@ -62,6 +62,10 @@ const (
|
||||
|
||||
PersonEmailKey = "Email"
|
||||
|
||||
MetadataLabelKey = "Label"
|
||||
MetadataTermGUIDKey = "TermGuid"
|
||||
MetadataWssIDKey = "WssId"
|
||||
|
||||
LinkTitleFieldNamePart = "LinkTitle"
|
||||
ChildCountFieldNamePart = "ChildCount"
|
||||
LookupIDFieldNamePart = "LookupId"
|
||||
|
||||
@ -511,6 +511,10 @@ func retrieveFieldData(orig models.FieldValueSetable, columnNames map[string]*co
|
||||
additionalData[fieldName] = concatenatedHyperlink
|
||||
}
|
||||
|
||||
if metadataField, fieldName, ok := hasMetadataFields(additionalData); ok {
|
||||
additionalData[fieldName] = concatenateMetadataFields(metadataField)
|
||||
}
|
||||
|
||||
fields.SetAdditionalData(additionalData)
|
||||
|
||||
return fields
|
||||
@ -647,6 +651,44 @@ func hasHyperLinkFields(additionalData map[string]any) (map[string]any, string,
|
||||
return nil, "", false
|
||||
}
|
||||
|
||||
func hasMetadataFields(additionalData map[string]any) ([]map[string]any, string, bool) {
|
||||
for fieldName, value := range additionalData {
|
||||
switch valType := reflect.TypeOf(value).Kind(); valType {
|
||||
case reflect.Map:
|
||||
metadataFields, areMetadataFields := getMetadataFields(value)
|
||||
if areMetadataFields {
|
||||
return []map[string]any{metadataFields}, fieldName, true
|
||||
}
|
||||
|
||||
case reflect.Slice:
|
||||
mmdfs := make([]map[string]any, 0)
|
||||
|
||||
multiMetadataFields, ok := value.([]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, mdfs := range multiMetadataFields {
|
||||
metadataFields, areMetadataFields := getMetadataFields(mdfs)
|
||||
if areMetadataFields {
|
||||
mmdfs = append(mmdfs, metadataFields)
|
||||
}
|
||||
}
|
||||
|
||||
if len(mmdfs) > 0 {
|
||||
return mmdfs, fieldName, true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", false
|
||||
}
|
||||
|
||||
func getMetadataFields(metadataFieldvalue any) (map[string]any, bool) {
|
||||
nestedFields, ok := metadataFieldvalue.(map[string]any)
|
||||
return nestedFields, ok && keys.HasKeys(nestedFields, MetadataLabelKey, MetadataTermGUIDKey, MetadataWssIDKey)
|
||||
}
|
||||
|
||||
func concatenateAddressFields(addressFields map[string]any) string {
|
||||
parts := make([]string, 0)
|
||||
|
||||
@ -692,6 +734,23 @@ func concatenateHyperLinkFields(hyperlinkFields map[string]any) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func concatenateMetadataFields(metadataFieldsArr []map[string]any) string {
|
||||
labels := make([]string, 0)
|
||||
|
||||
for _, md := range metadataFieldsArr {
|
||||
mdVal, ok := md[MetadataLabelKey].(*string)
|
||||
if ok {
|
||||
labels = append(labels, ptr.Val(mdVal))
|
||||
}
|
||||
}
|
||||
|
||||
if len(labels) > 0 {
|
||||
return strings.Join(labels, ",")
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func addressKeyToVal(fields map[string]any, key string) string {
|
||||
if v, err := str.AnyValueToString(key, fields); err == nil {
|
||||
return v
|
||||
|
||||
@ -941,6 +941,161 @@ func (suite *ListsUnitSuite) TestSetAdditionalDataByColumnNames() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ListsUnitSuite) TestHasMetadataFields() {
|
||||
t := suite.T()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
additionalData map[string]any
|
||||
expectedFields []map[string]any
|
||||
expectedFieldName string
|
||||
hasMetadataFields bool
|
||||
}{
|
||||
{
|
||||
name: "Single metadata fields, has all keys",
|
||||
additionalData: map[string]any{
|
||||
"MdCol": map[string]any{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
},
|
||||
expectedFields: []map[string]any{
|
||||
{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
},
|
||||
expectedFieldName: "MdCol",
|
||||
hasMetadataFields: true,
|
||||
},
|
||||
{
|
||||
name: "Multiple metadata fields, has all keys",
|
||||
additionalData: map[string]any{
|
||||
"MdCol": []any{
|
||||
map[string]any{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
map[string]any{
|
||||
MetadataLabelKey: ptr.To("Marketing"),
|
||||
MetadataTermGUIDKey: ptr.To("312347ce-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(2),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedFields: []map[string]any{
|
||||
{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
{
|
||||
MetadataLabelKey: ptr.To("Marketing"),
|
||||
MetadataTermGUIDKey: ptr.To("312347ce-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(2),
|
||||
},
|
||||
},
|
||||
expectedFieldName: "MdCol",
|
||||
hasMetadataFields: true,
|
||||
},
|
||||
{
|
||||
name: "Single metadata fields, missing few keys",
|
||||
additionalData: map[string]any{
|
||||
"MdCol": map[string]any{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
},
|
||||
},
|
||||
expectedFields: nil,
|
||||
expectedFieldName: "",
|
||||
hasMetadataFields: false,
|
||||
},
|
||||
{
|
||||
name: "Multiple metadata fields, missing few keys",
|
||||
additionalData: map[string]any{
|
||||
"MdCol": []any{
|
||||
map[string]any{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
map[string]any{
|
||||
MetadataLabelKey: ptr.To("Marketing"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedFields: []map[string]any{
|
||||
{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
},
|
||||
expectedFieldName: "MdCol",
|
||||
hasMetadataFields: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
suite.Run(test.name, func() {
|
||||
nestedFields, fName, isMetadata := hasMetadataFields(test.additionalData)
|
||||
assert.Equal(t, test.expectedFields, nestedFields)
|
||||
assert.Equal(t, test.expectedFieldName, fName)
|
||||
assert.Equal(t, test.hasMetadataFields, isMetadata)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ListsUnitSuite) TestConcatenateMetadataFields() {
|
||||
t := suite.T()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
metadataFields []map[string]any
|
||||
expectedFieldName string
|
||||
expectedResult string
|
||||
hasMetadataFields bool
|
||||
columnNames map[string]any
|
||||
}{
|
||||
{
|
||||
name: "Single metadata fields",
|
||||
metadataFields: []map[string]any{
|
||||
{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
},
|
||||
expectedResult: "Engineering",
|
||||
},
|
||||
{
|
||||
name: "Multiple metadata fields",
|
||||
metadataFields: []map[string]any{
|
||||
{
|
||||
MetadataLabelKey: ptr.To("Engineering"),
|
||||
MetadataTermGUIDKey: ptr.To("6b5d3ce9-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(4),
|
||||
},
|
||||
{
|
||||
MetadataLabelKey: ptr.To("Marketing"),
|
||||
MetadataTermGUIDKey: ptr.To("312347ce-3043-499f-8be6-e92fb57bed96"),
|
||||
MetadataWssIDKey: ptr.To(2),
|
||||
},
|
||||
},
|
||||
expectedResult: "Engineering,Marketing",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
suite.Run(test.name, func() {
|
||||
res := concatenateMetadataFields(test.metadataFields)
|
||||
assert.Equal(t, test.expectedResult, res)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ListsUnitSuite) TestCheckFields() {
|
||||
t := suite.T()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user