Created
January 22, 2018 20:08
-
-
Save hermanussen/96318e8af0e7eee499dc0bdf27be59ba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Test(Description = "Checks if all Glass mapper template and field IDs can be found in serialized data")] | |
public void ShouldAllTemplatesAndFieldsBeFoundInSerializedData( | |
[Values( | |
typeof(SomeType), // From assembly MyProject | |
)] | |
Type typeFromAssembyUnderTest) | |
{ | |
Assembly assemblyUnderTest = Assembly.GetAssembly(typeFromAssembyUnderTest); | |
// Find all templates and fields that need to be checked in the serialized data | |
List<ID> sitecoreTypes = GetAllTemplateIds(assemblyUnderTest.GetTypes()); | |
List<KeyValuePair<ID,ID[]>> sitecoreFields = GetAllSitecoreFieldsFromAssembly(assemblyUnderTest); | |
Console.WriteLine( | |
"Now checking {0} template ids and {1} fields (from assembly: {2}) in serialized data", | |
sitecoreTypes.Count, | |
sitecoreFields.Count, | |
assemblyUnderTest.GetName().Name); | |
using (var db = new Db()) | |
{ | |
// Find all the templates and deserialize them into the FakeDb | |
List<DsDbTemplate> templates = sitecoreTypes.Select(t => new DsDbTemplate(t)).ToList(); | |
foreach (DsDbTemplate template in templates) | |
{ | |
db.Add(template); | |
} | |
// Iterate all the templates and check if they are correctly deserialized and are actual templates | |
foreach (ID sitecoreType in sitecoreTypes) | |
{ | |
Item item = db.GetItem(sitecoreType); | |
// check if the template was actually deserialized | |
item.Should().NotBeNull(); | |
item.TemplateID.ShouldBeEquivalentTo(TemplateIDs.Template); | |
item.Paths.FullPath.Should().StartWith("/sitecore/templates/"); | |
} | |
// Iterate all the fields and check if they are correctly deserialized and valid for the deserialized templates | |
foreach (var sitecoreField in sitecoreFields) | |
{ | |
// Check if the field is valid on the template(s) for the class that references it | |
templates | |
.Where(t => sitecoreField.Value.Contains(t.ID)) | |
.Any(t => t.Fields.Any(f => f.ID == sitecoreField.Key)) | |
.Should() | |
.BeTrue( | |
"Field with ID {0} should be available on any of the templates with ID's {1}", | |
sitecoreField.Key, | |
string.Join(", ", sitecoreField.Value.Select(v => v.ToString()))); | |
} | |
} | |
} | |
/// <summary> | |
/// Find all template IDs that are defined on all of the types that are passed. | |
/// </summary> | |
/// <param name="types"></param> | |
/// <returns></returns> | |
private static List<ID> GetAllTemplateIds(IEnumerable<Type> types) | |
{ | |
return (from t in types | |
let attributes = t.GetCustomAttributes<SitecoreTypeAttribute>(true) | |
where attributes != null && attributes.Any() | |
select attributes) | |
.SelectMany(a => a) | |
.Where(a => a.TemplateId != null) | |
.Select(a => ID.Parse(a.TemplateId)) | |
.ToList(); | |
} | |
/// <summary> | |
/// Finds all fields marked with the SitecoreFieldAttribute in the whole assembly. | |
/// Returns a list of pairs where the key is the field ID and the value is an array of template IDs that the field might belong to. | |
/// </summary> | |
/// <param name="assembly"></param> | |
/// <returns></returns> | |
private static List<KeyValuePair<ID, ID[]>> GetAllSitecoreFieldsFromAssembly(Assembly assembly) | |
{ | |
return assembly.GetTypes().SelectMany(t => t.GetProperties()) | |
.Where(p => p.IsDefined(typeof (SitecoreFieldAttribute), true)) | |
.Select(p => new | |
{ | |
Type = p.ReflectedType, | |
Attr = p.GetCustomAttribute<SitecoreFieldAttribute>(true) | |
}) | |
.Where(a => a.Attr.FieldId != null) | |
.Select(a => new KeyValuePair<ID, ID[]>( | |
ID.Parse(a.Attr.FieldId), | |
GetAllTemplateIdsIncludingFromBaseTypes(a.Type).ToArray())) | |
.ToList(); | |
} | |
/// <summary> | |
/// Finds all of the template IDs that are declared on the type or any base class or interface that it implements. | |
/// </summary> | |
/// <param name="type"></param> | |
/// <returns></returns> | |
private static List<ID> GetAllTemplateIdsIncludingFromBaseTypes(Type type) | |
{ | |
return GetAllTemplateIds(GetBaseTypes(type).Distinct().Concat(new[] {type})); | |
} | |
/// <summary> | |
/// Finds all of the base types and interfaces of a type. | |
/// </summary> | |
/// <param name="type"></param> | |
/// <returns></returns> | |
private static IEnumerable<Type> GetBaseTypes(Type type) | |
{ | |
if (type.BaseType == null) return type.GetInterfaces(); | |
return Enumerable.Repeat(type.BaseType, 1) | |
.Concat(type.GetInterfaces()) | |
.Concat(type.GetInterfaces().SelectMany<Type, Type>(GetBaseTypes)) | |
.Concat(GetBaseTypes(type.BaseType)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment