Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hermanussen/96318e8af0e7eee499dc0bdf27be59ba to your computer and use it in GitHub Desktop.
Save hermanussen/96318e8af0e7eee499dc0bdf27be59ba to your computer and use it in GitHub Desktop.
[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