Fix the build.
[castle.git] / MonoRail / Castle.MonoRail.TestSupport / BaseControllerTest.cs
blob8c36c3c0f9a01b75d03674245f7d23b2d09ba8be
1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MonoRail.TestSupport
17 using System;
18 using System.Collections;
19 using System.Collections.Specialized;
20 using System.IO;
21 using Castle.Components.Common.EmailSender;
22 using Castle.MonoRail.Framework;
23 using Castle.MonoRail.Framework.Test;
25 public delegate void ContextInitializer(MockRailsEngineContext context);
27 /// <summary>
28 /// Base class that set ups the necessary infrastructure
29 /// to test controllers without the need
30 /// for an ASP.Net Runtime.
31 /// </summary>
32 ///
33 /// <example>
34 /// The following code is an example of a controller test:
35 ///
36 /// <code lang="cs">
37 /// [TestFixture]
38 /// public class LoginControllerTestCase : BaseControllerTest
39 /// {
40 /// private LoginController controller;
41 ///
42 /// [SetUp]
43 /// public void Init()
44 /// {
45 /// controller = new LoginController();
46 /// PrepareController(controller);
47 /// }
48 ///
49 /// [Test]
50 /// public void Authenticate_Should_Use_The_AuthenticationService()
51 /// {
52 /// // set up a mock authentication service before
53 ///
54 /// controller.Authenticate("username", "my password", false);
55 ///
56 /// Assert.AreEqual(3, controller.PropertyBag.Count);
57 /// Assert.AreEqual("username", controller.PropertyBag["username"]);
58 /// Assert.AreEqual("my password", controller.PropertyBag["password"]);
59 /// Assert.AreEqual(false, controller.PropertyBag["autoLogin"]);
60 /// }
61 /// }
62 /// </code>
63 ///
64 /// <para>
65 /// The following is a more sophisticate test for an action that sends emails.
66 /// </para>
67 ///
68 /// <code lang="cs">
69 /// [Test]
70 /// public void Register_Should_Add_Registration_Using_The_Repository()
71 /// {
72 /// Registration reg = new Registration("John Doe", "johndoe@gmail.com");
73 ///
74 /// using(mockRepository.Record())
75 /// {
76 /// registrationRepositoryMock.Add(reg);
77 /// }
78 ///
79 /// using(mockRepository.Playback())
80 /// {
81 /// controller.Register(reg); // This action sends two emails
82 ///
83 /// Assert.IsTrue(HasRenderedEmailTemplateNamed("emailToManager"));
84 /// Assert.IsTrue(HasRenderedEmailTemplateNamed("emailToParticipant"));
85 ///
86 /// Assert.AreEqual("manager@gmail.com", MessagesSent[0].To);
87 /// Assert.AreEqual("johndoe@gmail.com", MessagesSent[1].To);
88 ///
89 /// Assert.AreEqual("Registration\\Success", controller.SelectedViewName);
90 /// }
91 /// }
92 /// </code>
93 ///
94 /// </example>
95 ///
96 /// <remarks>
97 /// You must invoke <see cref="PrepareController(Controller)"/> -- or a different overload -
98 /// before making invocations to the controller.
99 /// </remarks>
100 public abstract class BaseControllerTest
102 private readonly string domain;
103 private readonly string domainPrefix;
104 private readonly int port;
105 protected string virtualDir = "";
106 private MockRailsEngineContext context;
107 private IMockRequest request;
108 private IMockResponse response;
109 private ITrace trace;
110 private IDictionary cookies;
112 /// <summary>
113 /// Initializes a new instance of the <see cref="BaseControllerTest"/> class.
114 /// </summary>
115 protected BaseControllerTest() : this("app.com", "www", 80)
119 /// <summary>
120 /// Initializes a new instance of the <see cref="BaseControllerTest"/> class.
121 /// </summary>
122 /// <param name="domain">The domain.</param>
123 /// <param name="domainPrefix">The domain prefix.</param>
124 /// <param name="port">The port.</param>
125 protected BaseControllerTest(string domain, string domainPrefix, int port)
127 this.domain = domain;
128 this.domainPrefix = domainPrefix;
129 this.port = port;
132 /// <summary>
133 /// Override to perform any pre-test set up
134 /// </summary>
135 protected virtual void OnSetUp()
139 /// <summary>
140 /// Gets the cookies.
141 /// </summary>
142 /// <value>The cookies.</value>
143 public IDictionary Cookies
145 get { return cookies; }
148 /// <summary>
149 /// Gets the context.
150 /// </summary>
151 /// <value>The context.</value>
152 protected IRailsEngineContext Context
154 get { return context; }
157 /// <summary>
158 /// Gets the request.
159 /// </summary>
160 /// <value>The request.</value>
161 public IMockRequest Request
163 get { return request; }
166 /// <summary>
167 /// Gets the response.
168 /// </summary>
169 /// <value>The response.</value>
170 public IMockResponse Response
172 get { return response; }
175 /// <summary>
176 /// Gets the trace.
177 /// </summary>
178 /// <value>The trace.</value>
179 public ITrace Trace
181 get { return trace; }
184 /// <summary>
185 /// Prepares the controller giving it mock implementations
186 /// of the service it requires to function normally.
187 /// </summary>
188 /// <param name="controller">The controller.</param>
189 protected void PrepareController(Controller controller)
191 PrepareController(controller, InitializeRailsEngineContext);
194 /// <summary>
195 /// Prepares the controller giving it mock implementations
196 /// of the service it requires to function normally.
197 /// </summary>
198 /// <param name="controller">The controller.</param>
199 /// <param name="contextInitializer">The context initializer.</param>
200 protected void PrepareController(Controller controller, ContextInitializer contextInitializer)
202 PrepareController(controller, "", "Controller", "Action", contextInitializer);
205 /// <summary>
206 /// Prepares the controller giving it mock implementations
207 /// of the service it requires to function normally.
208 /// </summary>
209 /// <param name="controller">The controller.</param>
210 /// <param name="controllerName">Name of the controller.</param>
211 /// <param name="actionName">Name of the action.</param>
212 protected void PrepareController(Controller controller, string controllerName, string actionName)
214 PrepareController(controller, "", controllerName, actionName);
217 /// <summary>
218 /// Prepares the controller giving it mock implementations
219 /// of the service it requires to function normally.
220 /// </summary>
221 /// <param name="controller">The controller.</param>
222 /// <param name="areaName">Name of the area (cannot be null).</param>
223 /// <param name="controllerName">Name of the controller.</param>
224 /// <param name="actionName">Name of the action.</param>
225 protected void PrepareController(Controller controller, string areaName, string controllerName, string actionName)
227 PrepareController(controller, areaName, controllerName, actionName, InitializeRailsEngineContext);
230 /// <summary>
231 /// Prepares the controller giving it mock implementations
232 /// of the service it requires to function normally.
233 /// </summary>
234 /// <param name="controller">The controller.</param>
235 /// <param name="areaName">Name of the area (cannot be null).</param>
236 /// <param name="controllerName">Name of the controller.</param>
237 /// <param name="actionName">Name of the action.</param>
238 /// <param name="contextInitializer">The context initializer.</param>
239 protected void PrepareController(Controller controller, string areaName, string controllerName, string actionName, ContextInitializer contextInitializer)
241 if (controller == null)
243 throw new ArgumentNullException("controller", "'controller' cannot be null");
245 if (areaName == null)
247 throw new ArgumentNullException("areaName");
249 if (controllerName == null)
251 throw new ArgumentNullException("controllerName");
253 if (actionName == null)
255 throw new ArgumentNullException("actionName");
257 if( contextInitializer == null) {
258 throw new ArgumentNullException("contextInitializer");
261 cookies = new HybridDictionary(true);
263 BuildRailsContext(areaName, controllerName, actionName, contextInitializer);
264 controller.InitializeFieldsFromServiceProvider(context);
265 controller.InitializeControllerState(areaName, controllerName, actionName);
266 ControllerLifecycleExecutor executor = new ControllerLifecycleExecutor(controller, context);
267 executor.Service(context);
268 executor.InitializeController(controller.AreaName, controller.Name, controller.Action);
271 /// <summary>
272 /// Constructs a mock context.
273 /// </summary>
274 /// <param name="areaName">Name of the area.</param>
275 /// <param name="controllerName">Name of the controller.</param>
276 /// <param name="actionName">Name of the action.</param>
277 protected void BuildRailsContext(string areaName, string controllerName, string actionName)
279 BuildRailsContext(areaName, controllerName, actionName, InitializeRailsEngineContext);
282 /// <summary>
283 /// Constructs a mock context.
284 /// </summary>
285 /// <param name="areaName">Name of the area.</param>
286 /// <param name="controllerName">Name of the controller.</param>
287 /// <param name="actionName">Name of the action.</param>
288 /// <param name="contextInitializer">The context initializer.</param>
289 protected void BuildRailsContext(string areaName, string controllerName, string actionName, ContextInitializer contextInitializer)
291 UrlInfo info = BuildUrlInfo(areaName, controllerName, actionName);
292 request = BuildRequest();
293 response = BuildResponse();
294 trace = BuildTrace();
295 context = BuildRailsEngineContext(request, response, trace, info);
296 contextInitializer(context);
299 /// <summary>
300 /// Builds the request.
301 /// </summary>
302 /// <returns></returns>
303 protected virtual IMockRequest BuildRequest()
305 return new MockRequest(cookies);
308 /// <summary>
309 /// Builds the response.
310 /// </summary>
311 /// <returns></returns>
312 protected virtual IMockResponse BuildResponse()
314 return new MockResponse(cookies);
317 /// <summary>
318 /// Builds the trace.
319 /// </summary>
320 /// <returns></returns>
321 protected virtual ITrace BuildTrace()
323 return new MockTrace();
326 /// <summary>
327 /// Builds the a mock context. You can override this method to
328 /// create a special configured mock context.
329 /// </summary>
330 /// <param name="request">The request.</param>
331 /// <param name="response">The response.</param>
332 /// <param name="trace">The trace.</param>
333 /// <param name="urlInfo">The URL info.</param>
334 /// <returns></returns>
335 protected virtual MockRailsEngineContext BuildRailsEngineContext(IRequest request, IResponse response, ITrace trace,
336 UrlInfo urlInfo)
338 return new MockRailsEngineContext(request, response, trace, urlInfo);
341 /// <summary>
342 /// Builds the URL info that represents the contextual Url.
343 /// </summary>
344 /// <param name="areaName">Name of the area.</param>
345 /// <param name="controllerName">Name of the controller.</param>
346 /// <param name="actionName">Name of the action.</param>
347 /// <returns></returns>
348 protected virtual UrlInfo BuildUrlInfo(string areaName, string controllerName, string actionName)
350 return new UrlInfo(domain, domainPrefix, virtualDir, "http", port,
351 Path.Combine(Path.Combine(areaName, controllerName), actionName),
352 areaName, controllerName, actionName, "rails", null);
355 /// <summary>
356 /// Allows modifying of the engine context created by <see cref="BuildRailsEngineContext"/>
357 /// </summary>
358 /// <param name="mockRailsEngineContext">The engine context to modify</param>
359 protected virtual void InitializeRailsEngineContext(MockRailsEngineContext mockRailsEngineContext)
362 /// <summary>
363 /// Determines whether a specified template was rendered -- to send an email.
364 /// </summary>
365 /// <param name="templateName">Name of the template.</param>
366 /// <returns>
367 /// <c>true</c> if was rendered; otherwise, <c>false</c>.
368 /// </returns>
369 protected bool HasRenderedEmailTemplateNamed(string templateName)
371 MockRailsEngineContext.RenderedEmailTemplate template =
372 context.RenderedEmailTemplates.Find(
373 delegate(MockRailsEngineContext.RenderedEmailTemplate emailTemplate)
375 return templateName.Equals(emailTemplate.Name, StringComparison.OrdinalIgnoreCase);
378 return template != null;
381 /// <summary>
382 /// Gets the fake email messages sent.
383 /// </summary>
384 /// <value>The messages sent.</value>
385 protected Message[] MessagesSent
387 get { return context.MessagesSent.ToArray(); }
390 /// <summary>
391 /// Gets the rendered email templates.
392 /// </summary>
393 /// <value>The rendered email templates.</value>
394 protected MockRailsEngineContext.RenderedEmailTemplate[] RenderedEmailTemplates
396 get { return context.RenderedEmailTemplates.ToArray(); }