1: /// <summary>
2: /// The test base class for MVC tests. This class does provide some basic helpers for
3: /// testing MVC controllers / filters etc.
4: /// </summary>
5: public class MvcTestBase
6: {
7: /// <summary>
8: /// Creates a new request context that returns a distinct,
9: /// but always the same, session id.
10: /// </summary>
11: /// <returns> The <see cref="Mock"/> object for the
12: /// request context. </returns>
13: public static ActionExecutingContext CreateRequestContext()
14: {
15: var uri = new Uri("http://localhost/test", UriKind.Absolute);
16: var sessionId = Guid.NewGuid().ToString("N");
17: var clientIP = Guid.NewGuid().ToString("N");
18: return CreateRequestContext(uri, sessionId, clientIP);
19: }
20:
21: /// <summary>
22: /// Creates a new request context that returns a distinct, but
23: /// always the same, session id.
24: /// </summary>
25: /// <param name="requestUrl">The URL that should be simulated
26: /// to be requested.</param>
27: /// <returns> The <see cref="Mock"/> object for the
28: /// request context. </returns>
29: public static ActionExecutingContext CreateRequestContext(Uri requestUrl)
30: {
31: var sessionId = Guid.NewGuid().ToString("N");
32: var clientIP = Guid.NewGuid().ToString("N");
33: return CreateRequestContext(requestUrl, sessionId, clientIP);
34: }
35:
36: /// <summary>
37: /// Creates a new request context that returns a distinct,
38: /// but always the same, session id.
39: /// </summary>
40: /// <param name="requestUrl">The URL the request should fake.</param>
41: /// <param name="sessionId"> The session Id for the request. </param>
42: /// <param name="clientIP"> The client IP for the request. </param>
43: /// <returns> The <see cref="Mock"/> object for the request context. </returns>
44: public static ActionExecutingContext CreateRequestContext(Uri requestUrl, string sessionId, string clientIP)
45: {
46: var form = new NameValueCollection();
47: return CreateRequestContext(requestUrl, sessionId, clientIP, form);
48: }
49:
50: /// <summary>
51: /// Creates a new request context that returns a distinct,
52: /// but always the same, session id.
53: /// </summary>
54: /// <param name="requestUrl">The URL the request should fake.</param>
55: /// <param name="sessionId"> The session Id for the request. </param>
56: /// <param name="clientIP"> The client IP for the request. </param>
57: /// <param name="formCollection">The collection of form data items.</param>
58: /// <returns> The <see cref="Mock"/> object for the request context. </returns>
59: public static ActionExecutingContext CreateRequestContext(Uri requestUrl, string sessionId, string clientIP, NameValueCollection formCollection)
60: {
61: return CreateRequestContext(requestUrl, sessionId, clientIP, formCollection, "UserName");
62: }
63:
64: /// <summary>
65: /// Creates a new request context that returns a distinct,
66: /// but always the same, session id.
67: /// </summary>
68: /// <param name="requestUrl">The URL the request should fake.</param>
69: /// <param name="sessionId"> The session Id for the request. </param>
70: /// <param name="clientIP"> The client IP for the request. </param>
71: /// <param name="formCollection">The collection of form data items.</param>
72: /// <param name="userName">The name of the user the identity should contain.</param>
73: /// <returns> The <see cref="Mock"/> object for the request context. </returns>
74: public static ActionExecutingContext CreateRequestContext(Uri requestUrl, string sessionId, string clientIP, NameValueCollection formCollection, string userName)
75: {
76: object values = new
77: {
78: controller = "Home",
79: action = "Index",
80: id = UrlParameter.Optional
81: };
82: var requestContext = RequestContext(requestUrl, sessionId, clientIP, formCollection, values, userName);
83: var routes = RouteCollection(values);
84: var controller = Controller(requestContext, routes);
85: return new ActionExecutingContext { RequestContext = requestContext, Controller = controller, };
86: }
87:
88: /// <summary>
89: /// Creates an initialized <see cref="HtmlHelper"/> object.
90: /// </summary>
91: /// <returns>
92: /// The <see cref="HtmlHelper"/>.
93: /// </returns>
94: public static HtmlHelper CreateHtmlHelper()
95: {
96: var container = new Mock<IViewDataContainer>();
97: var formCollection = new NameValueCollection();
98: var sessionId = Guid.NewGuid().ToString("N");
99: var clientIP = Guid.NewGuid().ToString("N");
100: var uri = new Uri("http://test/");
101: var viewContext = ViewContext(uri, sessionId, clientIP, formCollection);
102: return new HtmlHelper(viewContext, container.Object);
103: }
104:
105: /// <summary>
106: /// Generates a request context.
107: /// </summary>
108: /// <param name="requestUrl"> The request url. </param>
109: /// <param name="sessionId"> The session id. </param>
110: /// <param name="clientIP"> The client IP. </param>
111: /// <param name="formCollection"> The http FORM collection. </param>
112: /// <param name="values"> The values for the route data. </param>
113: /// <param name="username"> The username. </param>
114: /// <returns> The request context"/>. </returns>
115: private static RequestContext RequestContext(Uri requestUrl, string sessionId, string clientIP, NameValueCollection formCollection, object values, string username)
116: {
117: var requestBase = RequestBase(requestUrl, clientIP, formCollection);
118: var httpContext = HttpContext(sessionId, requestBase, username);
119: return RequestContext(httpContext, values);
120: }
121:
122: /// <summary>
123: /// Creates an initialized controller.
124: /// </summary>
125: /// <param name="requestContext"> The request context for the controller. </param>
126: /// <param name="routes"> The routes for the <see cref="UrlHelper"/>. </param>
127: /// <returns> The <see cref="Mock"/>. </returns>
128: private static Controller Controller(RequestContext requestContext, RouteCollection routes)
129: {
130: var urlHelper = new UrlHelper(requestContext, routes);
131: var controller = new Mock<Controller>();
132: controller.Object.Url = urlHelper;
133: RouteTable.Routes.Clear();
134: foreach (var route in routes)
135: { RouteTable.Routes.Add(route); }
136: return controller.Object;
137: }
138:
139: /// <summary>
140: /// Generates a default route collection.
141: /// </summary>
142: /// <param name="values"> The default values. </param>
143: /// <returns> The <see cref="RouteCollection"/>. </returns>
144: private static RouteCollection RouteCollection(object values)
145: {
146: return new RouteCollection
147: {
148: new Route("{controller}/{action}/{id}", new MvcRouteHandler())
149: {
150: Defaults = new RouteValueDictionary(values),
151: Constraints = new RouteValueDictionary((object)null),
152: DataTokens = new RouteValueDictionary(),
153: }
154: };
155: }
156:
157: /// <summary>
158: /// Generates an initialized <see cref="HttpContextBase"/>.
159: /// </summary>
160: /// <param name="sessionId"> The session id. </param>
161: /// <param name="requestBase"> The request base. </param>
162: /// <param name="username"> The username for the identity of the current user. </param>
163: /// <returns> The <see cref="HttpContextBase"/>. </returns>
164: private static HttpContextBase HttpContext(string sessionId, HttpRequestBase requestBase, string username)
165: {
166: var httpContext = new Moq.Mock<HttpContextBase>();
167: httpContext.Setup(x => x.Session).Returns(SessionState(sessionId));
168: httpContext.Setup(x => x.Request).Returns(requestBase);
169: httpContext.Setup(x => x.Response).Returns(Response());
170: httpContext.Setup(x => x.User).Returns(User(username));
171: return httpContext.Object;
172: }
173:
174: /// <summary>
175: /// Creates an initialized <see cref="IPrincipal"/> for a given user name.
176: /// </summary>
177: /// <param name="username"> The username. </param>
178: /// <returns> The <see cref="IPrincipal"/>. </returns>
179: private static IPrincipal User(string username)
180: {
181: var user = new Mock<IPrincipal>();
182: var identity = new Mock<IIdentity>();
183: identity.Setup(x => x.Name).Returns(username);
184: user.Setup(x => x.Identity).Returns(identity.Object);
185: return user.Object;
186: }
187:
188: /// <summary>
189: /// Generates a ready to use <see cref="HttpResponseBase"/> object.
190: /// </summary>
191: /// <returns> The <see cref="Mock"/>. </returns>
192: private static HttpResponseBase Response()
193: {
194: var response = new Mock<HttpResponseBase>();
195: response.Setup(r => r.ApplyAppPathModifier(It.IsAny<string>()))
196: .Returns((string s) => s);
197: return response.Object;
198: }
199:
200: /// <summary>
201: /// Generates an initialized <see cref="HttpSessionStateBase"/>.
202: /// </summary>
203: /// <param name="sessionId"> The session id. </param>
204: /// <returns> The <see cref="HttpSessionStateBase"/>. </returns>
205: private static HttpSessionStateBase SessionState(string sessionId)
206: {
207: var sessionState = new Mock<HttpSessionStateBase>();
208: sessionState.Setup(x => x.SessionID).Returns(sessionId);
209: return sessionState.Object;
210: }
211:
212: /// <summary>
213: /// Generates an initialized <see cref="HttpRequestBase"/>.
214: /// </summary>
215: /// <param name="requestUrl"> The request url. </param>
216: /// <param name="clientIP"> The client IP this request should simulate. </param>
217: /// <param name="formCollection"> The form value collection. </param>
218: /// <returns> The <see cref="HttpRequestBase"/>. </returns>
219: private static HttpRequestBase RequestBase(Uri requestUrl, string clientIP, NameValueCollection formCollection)
220: {
221: var path = requestUrl == null ? string.Empty : requestUrl.AbsolutePath;
222: var requestBase = new Mock<HttpRequestBase>();
223: requestBase.Setup(x => x.ApplicationPath).Returns(path);
224: requestBase.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns("~" + path);
225: requestBase.Setup(x => x.CurrentExecutionFilePath).Returns("/");
226: requestBase.Setup(x => x.CurrentExecutionFilePathExtension).Returns(string.Empty);
227: requestBase.Setup(x => x.Form).Returns(formCollection);
228: requestBase.Setup(x => x.HttpMethod).Returns("GET");
229: requestBase.Setup(x => x.Path).Returns("/");
230: requestBase.Setup(x => x.RawUrl).Returns(path);
231: requestBase.Setup(x => x.RequestType).Returns("GET");
232: requestBase.Setup(x => x.Url).Returns(requestUrl);
233: requestBase.Setup(x => x.UserHostAddress).Returns(clientIP);
234: requestBase.Setup(x => x.UserHostName).Returns(clientIP);
235: return requestBase.Object;
236: }
237:
238: /// <summary>
239: /// Generates an initialized Request Context.
240: /// </summary>
241: /// <param name="httpContext"> The http context. </param>
242: /// <param name="values"> The route values. </param>
243: /// <returns> The Request Context. </returns>
244: private static RequestContext RequestContext(HttpContextBase httpContext, object values)
245: {
246: var requestContext = new Moq.Mock<RequestContext>();
247: requestContext.Setup(x => x.HttpContext).Returns(httpContext);
248: requestContext.Setup(x => x.RouteData).Returns(RouteData(values));
249: return requestContext.Object;
250: }
251:
252: /// <summary>
253: /// Generates an initialized <see cref="RouteData"/>.
254: /// </summary>
255: /// <param name="values"> The values. </param>
256: /// <returns> The <see cref="RouteData"/>. </returns>
257: private static RouteData RouteData(object values)
258: {
259: var routeData = new RouteData
260: {
261: Route = new Route("{controller}/{action}/{id}", new MvcRouteHandler())
262: {
263: Defaults = new RouteValueDictionary(values),
264: Constraints = new RouteValueDictionary((object)null),
265: DataTokens = new RouteValueDictionary()
266: },
267: };
268: routeData.Values.Add("controller", "Home");
269: routeData.Values.Add("action", "Index");
270: return routeData;
271: }
272:
273: /// <summary>
274: /// Generates an initialized <see cref="ViewContext"/>.
275: /// </summary>
276: /// <param name="requestUrl"> The request URL. </param>
277: /// <param name="sessionId"> The session id. </param>
278: /// <param name="clientIP"> The client IP. </param>
279: /// <param name="formCollection"> The form value collection. </param>
280: /// <returns> The <see cref="ViewContext"/>. </returns>
281: private static ViewContext ViewContext(Uri requestUrl, string sessionId, string clientIP, NameValueCollection formCollection)
282: {
283: object values = new
284: {
285: controller = "Home",
286: action = "Index",
287: id = UrlParameter.Optional
288: };
289: var viewContext = new Mock<ViewContext>();
290: var requestContext = RequestContext(requestUrl, sessionId, clientIP, formCollection, values, "userName");
291: var routes = RouteCollection(values);
292: var controller = Controller(requestContext, routes);
293: viewContext.Setup(x => x.Controller).Returns(controller);
294: return viewContext.Object;
295: }
296: }