I'm sending an email from my ASP.NET MVC app using the Spark View Engine based on this example by Andrew Kharlamov.
I've setup a unit test, CanSendEmail, but I need to specify the viewfolder in the config. I found the documentation here and the examples give this:
<spark>
<views>
<add name="{any-unique-name}"
folderType="FileSystem|EmbeddedResource|VirtualPathProvider|Custom"
type="{name, assembly of IViewFolder type}"
constuctor-param-names="values"
subfolder="{optional subfolder to target}"/>
</views>
</spark>
My question is this. Which folderType do I use and do I need any other parameters. My test product is call myProject.Tests and my web project containing the views is called myProject.Web with a Views folder in it.
Do I use FileSystem, VirtualPathProvider ... ?
Edit [14/11/2011]:
Okay I've got this in my app.config in myProject.Tests:
<views>
<add name="web-view-folder"
folderType="VirtualPathProvider"
virtualBaseDir="~/Views"/>
</views>
I still get "View source file not found." when I run my test. I want the test to use the Views in myproject.Web.
My Solution
Based on the blog posts here and here, and with help from @RobertTheGrey and looking at the tests in the Spark source code, I ended up using ViewFolderType.FileSystem. That worked.
Here's the my code under test:
public string RenderEmailWithCustomViewFolder(string sparkViewName, ViewDataDictionary viewData, Dictionary<string, string> viewFolderParameters)
{
var settings = new SparkSettings()
.SetPageBaseType(typeof (SparkView))
.AddViewFolder(ViewFolderType.FileSystem, viewFolderParameters)
.AddAssembly("MvcContrib");
var engine = new SparkViewEngine(settings);
var sparkViewDescriptor = new SparkViewDescriptor().AddTemplate(sparkViewName);
var view = (SparkView)engine.CreateInstance(sparkViewDescriptor);
try
{
// Merge view data
viewData.Keys.ToList().ForEach(x => view.ViewData[x] = viewData[x]);
// Render the view to a text writer
var writer = new StringWriter();
view.RenderView(writer);
return writer.ToString();
}
finally
{
engine.ReleaseInstance(view);
}
}
And here's my test:
[Test]
public void Can_Render_Order_Confirmation_Email_With_Spark_View_Engine()
{
// Arrange
var order = OrderInstanceFactory.CreateTestOrder();
order.ContactEmail = "test@testicle.com";
var emailService = new EmailService();
var viewData = new ViewDataDictionary();
viewData["Order"] = order;
const string viewFolder = @"../../../../app/myProject.Web/Views";
var viewFolderParameters = new Dictionary<string, string> {{"basePath", viewFolder}};
// Act
var emailBody = emailService.RenderEmailWithCustomViewFolder("Email/OrderConfirmation.spark", viewData, viewFolderParameters);
// Assert
Assert.IsNotNull(emailBody);
Assert.IsTrue(emailBody.Contains("test@testicle.com"));
}
My OrderConfirmation.spark template lives in my web products in the Views/Email/.