Skip to content

Commit d7231c5

Browse files
callumbwhyteAndyButland
authored andcommitted
Preserve existing Examine FieldDefinitionCollection if it already exists (#20931)
* Preserve existing Examine FieldDefinitionCollection if it already exists (#20267) * Fix missing bracket * Minor tidy/addition of comments; addition of unit tests. --------- Co-authored-by: Andy Butland <abutland73@gmail.com> (cherry picked from commit 908974c)
1 parent aed7505 commit d7231c5

File tree

3 files changed

+104
-4
lines changed

3 files changed

+104
-4
lines changed

src/Umbraco.Examine.Lucene/DependencyInjection/ConfigureIndexOptions.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010
namespace Umbraco.Cms.Infrastructure.Examine.DependencyInjection;
1111

1212
/// <summary>
13-
/// Configures the index options to construct the Examine indexes
13+
/// Configures the index options to construct the Examine indexes.
1414
/// </summary>
1515
public sealed class ConfigureIndexOptions : IConfigureNamedOptions<LuceneDirectoryIndexOptions>
1616
{
1717
private readonly IndexCreatorSettings _settings;
1818
private readonly IUmbracoIndexConfig _umbracoIndexConfig;
1919
private readonly IDeliveryApiContentIndexFieldDefinitionBuilder _deliveryApiContentIndexFieldDefinitionBuilder;
2020

21+
/// <summary>
22+
/// Initializes a new instance of the <see cref="ConfigureIndexOptions"/> class.
23+
/// </summary>
2124
public ConfigureIndexOptions(
2225
IUmbracoIndexConfig umbracoIndexConfig,
2326
IOptions<IndexCreatorSettings> settings,
@@ -28,24 +31,27 @@ public ConfigureIndexOptions(
2831
_deliveryApiContentIndexFieldDefinitionBuilder = deliveryApiContentIndexFieldDefinitionBuilder;
2932
}
3033

34+
/// <inheritdoc/>
3135
public void Configure(string? name, LuceneDirectoryIndexOptions options)
3236
{
37+
// When creating FieldDefinitions with Umbraco defaults, pass in any already defined to avoid overwriting
38+
// those added via a package or custom code.
3339
switch (name)
3440
{
3541
case Constants.UmbracoIndexes.InternalIndexName:
3642
options.Analyzer = new CultureInvariantWhitespaceAnalyzer();
3743
options.Validator = _umbracoIndexConfig.GetContentValueSetValidator();
38-
options.FieldDefinitions = new UmbracoFieldDefinitionCollection();
44+
options.FieldDefinitions = new UmbracoFieldDefinitionCollection(options.FieldDefinitions);
3945
break;
4046
case Constants.UmbracoIndexes.ExternalIndexName:
4147
options.Analyzer = new StandardAnalyzer(LuceneInfo.CurrentVersion);
4248
options.Validator = _umbracoIndexConfig.GetPublishedContentValueSetValidator();
43-
options.FieldDefinitions = new UmbracoFieldDefinitionCollection();
49+
options.FieldDefinitions = new UmbracoFieldDefinitionCollection(options.FieldDefinitions);
4450
break;
4551
case Constants.UmbracoIndexes.MembersIndexName:
4652
options.Analyzer = new CultureInvariantWhitespaceAnalyzer();
4753
options.Validator = _umbracoIndexConfig.GetMemberValueSetValidator();
48-
options.FieldDefinitions = new UmbracoFieldDefinitionCollection();
54+
options.FieldDefinitions = new UmbracoFieldDefinitionCollection(options.FieldDefinitions);
4955
break;
5056
case Constants.UmbracoIndexes.DeliveryApiContentIndexName:
5157
options.Analyzer = new StandardAnalyzer(LuceneInfo.CurrentVersion);
@@ -64,6 +70,7 @@ public void Configure(string? name, LuceneDirectoryIndexOptions options)
6470
}
6571
}
6672

73+
/// <inheritdoc/>
6774
public void Configure(LuceneDirectoryIndexOptions options)
6875
=> throw new NotImplementedException("This is never called and is just part of the interface");
6976
}

src/Umbraco.Infrastructure/Examine/UmbracoFieldDefinitionCollection.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,29 @@ public class UmbracoFieldDefinitionCollection : FieldDefinitionCollection
3030
new(UmbracoExamineFieldNames.VariesByCultureFieldName, FieldDefinitionTypes.Raw),
3131
};
3232

33+
/// <summary>
34+
/// Initializes a new instance of the <see cref="UmbracoFieldDefinitionCollection"/> class containing
35+
/// the default Umbraco field definitions.
36+
/// </summary>
3337
public UmbracoFieldDefinitionCollection()
3438
: base(UmbracoIndexFieldDefinitions)
3539
{
3640
}
3741

42+
/// <summary>
43+
/// Initializes a new instance of the <see cref="UmbracoFieldDefinitionCollection"/> class containing the containing
44+
/// the default Umbraco field definitions, augmented or overridden by the provided definitions.
45+
/// </summary>
46+
/// <param name="definitions">Existing collection of field definitions.</param>
47+
public UmbracoFieldDefinitionCollection(FieldDefinitionCollection definitions)
48+
: base(UmbracoIndexFieldDefinitions)
49+
{
50+
foreach (FieldDefinition definition in definitions)
51+
{
52+
AddOrUpdate(definition);
53+
}
54+
}
55+
3856
/// <summary>
3957
/// Overridden to dynamically add field definitions for culture variations
4058
/// </summary>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using Examine;
2+
using NUnit.Framework;
3+
using Umbraco.Cms.Infrastructure.Examine;
4+
5+
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Examine;
6+
7+
[TestFixture]
8+
internal class UmbracoFieldDefinitionCollectionTests
9+
{
10+
[Test]
11+
public void Create_Contains_Expected_Fields()
12+
{
13+
var collection = new UmbracoFieldDefinitionCollection();
14+
AssertDefaultField(collection);
15+
}
16+
17+
[Test]
18+
public void Create_New_Contains_Expected_Fields()
19+
{
20+
var collection = new UmbracoFieldDefinitionCollection();
21+
collection.AddOrUpdate(new FieldDefinition("customField", "string"));
22+
var collectionCount = collection.Count;
23+
24+
collection = new UmbracoFieldDefinitionCollection();
25+
Assert.AreEqual(collectionCount - 1, collection.Count);
26+
AssertDefaultField(collection);
27+
AssertCustomField(collection, expectExists: false);
28+
}
29+
30+
[Test]
31+
public void Create_With_Existing_Contains_Expected_Fields()
32+
{
33+
var collection = new UmbracoFieldDefinitionCollection();
34+
collection.AddOrUpdate(new FieldDefinition("customField", "string"));
35+
var collectionCount = collection.Count;
36+
37+
collection = new UmbracoFieldDefinitionCollection(collection);
38+
Assert.AreEqual(collectionCount, collection.Count);
39+
AssertDefaultField(collection);
40+
AssertCustomField(collection, expectExists: true);
41+
}
42+
43+
[Test]
44+
public void Create_With_Existing_Retains_Override_Of_DefaultField()
45+
{
46+
var collection = new UmbracoFieldDefinitionCollection();
47+
collection.AddOrUpdate(new FieldDefinition("parentID", "string"));
48+
49+
collection = new UmbracoFieldDefinitionCollection(collection);
50+
AssertDefaultField(collection, "string");
51+
}
52+
53+
private static void AssertDefaultField(UmbracoFieldDefinitionCollection collection, string expectedType = "int")
54+
{
55+
var field = collection.SingleOrDefault(x => x.Name == "parentID");
56+
Assert.IsNotNull(field);
57+
Assert.AreEqual("parentID", field.Name);
58+
Assert.AreEqual(expectedType, field.Type);
59+
}
60+
61+
private static void AssertCustomField(UmbracoFieldDefinitionCollection collection, bool expectExists)
62+
{
63+
var field = collection.SingleOrDefault(x => x.Name == "customField");
64+
if (expectExists is false)
65+
{
66+
Assert.IsNull(field.Name);
67+
Assert.IsNull(field.Type);
68+
return;
69+
}
70+
71+
Assert.IsNotNull(field);
72+
Assert.AreEqual("customField", field.Name);
73+
Assert.AreEqual("string", field.Type);
74+
}
75+
}

0 commit comments

Comments
 (0)