I have used code below, has dependencies on IoC still but perhaps it is a start that you can work with.
protected SecurityToken GetMockToken(Guid organizationId, string roleId = null, bool anonymous = false)
{
var roleSystemId = roleId == null ? Guid.Empty : IoC.Resolve<RoleService>().Get(roleId).SystemId;
var personService = IoC.Resolve<PersonService>() as MockPersonService;
personService.SetMockPersonRoles(organizationId, new List<Guid> {roleSystemId});
var userId = anonymous ? Guid.Empty : personService.MockPerson.SystemId;
var identity = new ClaimsIdentity(new List<Claim>
{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", userId.ToString())
}, "MockAuthenticationType");
return new SecurityToken(identity);
}
/// <summary>
/// Registering a custom PersonService in IoC is Required
/// since SecurityToken internally does a resolve on PersonService to get person
/// </summary>
public class MockPersonService : PersonService
{
public Person MockPerson;
public MockPersonService()
{
MockPerson = new Person(Guid.NewGuid())
{
SystemId = Guid.NewGuid(),
Id = "MockPersonId",
OrganizationLinks = new List<PersonToOrganizationLink>()
};
}
public void SetMockPersonRoles(Guid organizationSystemId, List<Guid> roleIds)
{
MockPerson.OrganizationLinks.Clear();
if (organizationSystemId != Guid.Empty)
MockPerson.OrganizationLinks.Add(new PersonToOrganizationLink(organizationSystemId)
{
RoleSystemIds = new HashSet<Guid>(roleIds ?? new List<Guid>())
});
}
public override void Create([NotNull] Person person)
{
throw new NotImplementedException();
}
public override void Delete([NotNull] Person person)
{
throw new NotImplementedException();
}
public override Person Get(Guid systemId)
{
if (systemId.Equals(MockPerson.SystemId))
return MockPerson;
throw new Exception($"PersonId '{systemId}' does not equal mock person id '{MockPerson.SystemId}'");
}
public override Person Get([NotNull] string id)
{
throw new NotImplementedException();
}
public override IEnumerable<Person> Get([NotNull] IEnumerable<Guid> systemIds)
{
throw new NotImplementedException();
}
public override void Update([NotNull] Person person)
{
throw new NotImplementedException();
}
public override IEnumerable<Person> GetByOrganization(Guid organizationSystemId)
{
throw new NotImplementedException();
}
}
Thanks! Good idea making a mockable helper service.
But I found another way!
Instead of injecting SecurityContext to my service under test - I used another, mockable, service I already had injected: ModuleECommerce and used it’s _moduleECommerce.AdminToken where I needed a token.
This is what I ended up implementing to avoid the internal use of IoC in ModuleECommerce and the SecuryToken.
[Service(ServiceType = typeof(OrderUtilities), Lifetime = DependencyLifetime.Singleton)]
public abstract class OrderUtilities
{
public abstract Order GetOrder(string orderAlias);
public abstract OrderCarrier GetOrderCarrier(string orderAlias);
public abstract DeliveryMethodCarrier GetDeliveryMethodCarrier(Guid deliveryMethodID);
public abstract void SetDeliveryStatus(Delivery delivery, short status);
public abstract void AddOrUpdateAdditionalOrderInfo(Order order, string key, string value);
public abstract Country GetCountry(OrderCarrier litiumOrderCarrier);
}
I also use a wrapper class for the ECommerce-module in code that need to be testable. This was an issue with all areas (PIM/Media/CMS/Customers) earlier, but since version 5 Litium has become easier to test and with Litium 8 the new more testable Service-architecture will be implemented in ECommerce also.