1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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
.Framework
.Tests
.Helpers
18 using System
.Collections
;
19 using System
.Collections
.Generic
;
20 using System
.Collections
.Specialized
;
21 using System
.Globalization
;
23 using System
.Threading
;
24 using Castle
.DynamicProxy
;
25 using Castle
.MonoRail
.Framework
.Helpers
;
26 using Castle
.MonoRail
.Framework
.Tests
.Controllers
;
28 using NUnit
.Framework
;
31 public class FormHelperTestCase
33 private FormHelper helper
;
34 private Product product
, productProxy
;
35 private SimpleUser user
;
36 private Subscription subscription
;
37 private Month
[] months
;
38 private ProxyGenerator generator
= new ProxyGenerator();
43 CultureInfo en
= CultureInfo
.CreateSpecificCulture("en");
45 Thread
.CurrentThread
.CurrentCulture
= en
;
46 Thread
.CurrentThread
.CurrentUICulture
= en
;
48 helper
= new FormHelper();
50 subscription
= new Subscription();
51 months
= new Month
[] {new Month(1, "January"), new Month(1, "February")}
;
52 product
= new Product("memory card", 10, (decimal) 12.30);
54 productProxy
= (Product
) generator
.CreateClassProxy(typeof(Product
), new StandardInterceptor());
56 productProxy
.Name
= "memory card";
57 productProxy
.Quantity
= 10;
58 productProxy
.Price
= (decimal) 12.30;
60 user
= new SimpleUser();
62 HomeController controller
= new HomeController();
64 controller
.PropertyBag
.Add("product", product
);
65 controller
.PropertyBag
.Add("productproxy", productProxy
);
66 controller
.PropertyBag
.Add("user", user
);
67 controller
.PropertyBag
.Add("roles", new Role
[] { new Role(1, "a"), new Role(2, "b"), new Role(3, "c") }
);
68 controller
.PropertyBag
.Add("sendemail", true);
69 controller
.PropertyBag
.Add("confirmation", "abc");
70 controller
.PropertyBag
.Add("fileaccess", FileAccess
.Read
);
71 controller
.PropertyBag
.Add("subscription", subscription
);
72 controller
.PropertyBag
.Add("months", months
);
74 helper
.SetController(controller
);
78 public void FormTagDoesNotMixUrlParametersWithFormElementParameters()
80 // No solution here. Id is ambiguous
81 // helper.FormTag(DictHelper.Create("noaction=true"));
85 public void OverridingElementId()
87 Assert
.AreEqual("<input type=\"text\" id=\"something\" name=\"product.name\" value=\"memory card\" />",
88 helper
.TextField("product.name", DictHelper
.Create("id=something")));
90 Assert
.AreEqual("<input type=\"password\" id=\"something\" name=\"product.name\" value=\"memory card\" />",
91 helper
.PasswordField("product.name", DictHelper
.Create("id=something")));
93 Assert
.AreEqual("<input type=\"hidden\" id=\"something\" name=\"product.name\" value=\"memory card\" />",
94 helper
.HiddenField("product.name", DictHelper
.Create("id=something")));
96 product
.IsAvailable
= false;
98 Assert
.AreEqual("<input type=\"checkbox\" id=\"something\" name=\"product.isavailable\" value=\"true\" />" +
99 "<input type=\"hidden\" id=\"somethingH\" name=\"product.isavailable\" value=\"false\" />",
100 helper
.CheckboxField("product.isavailable", DictHelper
.Create("id=something")));
102 user
.IsActive
= true;
104 Assert
.AreEqual("<input type=\"radio\" id=\"something\" name=\"user.isactive\" value=\"True\" checked=\"checked\" />",
105 helper
.RadioField("user.isactive", true, DictHelper
.Create("id=something")));
107 Assert
.AreEqual("<label for=\"something\">Name:</label>",
108 helper
.LabelFor("product.name", "Name:", DictHelper
.Create("id=something")));
110 ArrayList list
= new ArrayList();
115 Assert
.AreEqual("<select id=\"something\" name=\"product.category.id\" >" + Environment
.NewLine
+
116 "<option value=\"cat1\">cat1</option>" + Environment
.NewLine
+ "<option value=\"cat2\">cat2</option>" + Environment
.NewLine
+ "</select>",
117 helper
.Select("product.category.id", list
, DictHelper
.Create("id=something")));
121 public void TextField()
123 Assert
.AreEqual("<input type=\"text\" id=\"product_name\" name=\"product.name\" value=\"memory card\" />",
124 helper
.TextField("product.name"));
125 Assert
.AreEqual("<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" />",
126 helper
.TextField("product.quantity"));
130 public void ProxiedComponent()
132 Assert
.AreEqual("<input type=\"text\" id=\"productproxy_name\" name=\"productproxy.name\" value=\"memory card\" />",
133 helper
.TextField("productproxy.name"));
134 Assert
.AreEqual("<input type=\"text\" id=\"productproxy_quantity\" name=\"productproxy.quantity\" value=\"10\" />",
135 helper
.TextField("productproxy.quantity"));
139 public void NumberField()
141 Assert
.AreEqual("<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onKeyPress=\"return monorail_formhelper_numberonly(event, [], []);\" />",
142 helper
.NumberField("product.quantity"));
143 Assert
.AreEqual("<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onKeyPress=\"return monorail_formhelper_numberonly(event, [1], []);\" />",
144 helper
.NumberField("product.quantity", DictHelper
.Create("exceptions=1")));
145 Assert
.AreEqual("<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onKeyPress=\"return monorail_formhelper_numberonly(event, [1,2], []);\" />",
146 helper
.NumberField("product.quantity", DictHelper
.Create("exceptions=1,2")));
150 public void MaskedNumberField()
152 Assert
.AreEqual("<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onKeyPress=\"return monorail_formhelper_numberonly(event, [], []);\" " +
153 "onBlur=\"javascript:void(0);return monorail_formhelper_mask(event,this,'2,5','-');\" onKeyUp=\"javascript:void(0);return monorail_formhelper_mask(event,this,'2,5','-');\" />",
154 helper
.NumberField("product.quantity", DictHelper
.Create("mask=2,5")));
158 public void PasswordField()
160 Assert
.AreEqual("<input type=\"password\" id=\"product_name\" name=\"product.name\" value=\"memory card\" />",
161 helper
.PasswordField("product.name"));
162 Assert
.AreEqual("<input type=\"password\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" />",
163 helper
.PasswordField("product.quantity"));
164 Assert
.AreEqual("<input type=\"password\" id=\"confirmation\" name=\"confirmation\" value=\"abc\" />",
165 helper
.PasswordField("confirmation"));
169 public void TextFieldValue()
171 Assert
.AreEqual("<input type=\"text\" id=\"product_price\" name=\"product.price\" value=\"$12.30\" />",
172 helper
.TextFieldValue("product.price", product
.Price
.ToString("C")));
176 public void TextFieldFormat()
178 Assert
.AreEqual("<input type=\"text\" id=\"product_price\" name=\"product.price\" value=\"$12.30\" />",
179 helper
.TextField("product.price", DictHelper
.Create("textformat=C")));
183 public void HiddenField()
185 Assert
.AreEqual("<input type=\"hidden\" id=\"product_name\" name=\"product.name\" value=\"memory card\" />",
186 helper
.HiddenField("product.name"));
187 Assert
.AreEqual("<input type=\"hidden\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" />",
188 helper
.HiddenField("product.quantity"));
192 public void CheckboxField()
194 product
.IsAvailable
= false;
196 Assert
.AreEqual("<input type=\"checkbox\" id=\"product_isavailable\" name=\"product.isavailable\" value=\"true\" />" +
197 "<input type=\"hidden\" id=\"product_isavailableH\" name=\"product.isavailable\" value=\"false\" />",
198 helper
.CheckboxField("product.isavailable"));
200 product
.IsAvailable
= true;
202 Assert
.AreEqual("<input type=\"checkbox\" id=\"product_isavailable\" name=\"product.isavailable\" value=\"true\" checked=\"checked\" />" +
203 "<input type=\"hidden\" id=\"product_isavailableH\" name=\"product.isavailable\" value=\"false\" />",
204 helper
.CheckboxField("product.isavailable"));
206 Assert
.AreEqual("<input type=\"checkbox\" id=\"sendemail\" name=\"sendemail\" value=\"true\" checked=\"checked\" />" +
207 "<input type=\"hidden\" id=\"sendemailH\" name=\"sendemail\" value=\"false\" />",
208 helper
.CheckboxField("sendemail"));
210 Assert
.AreEqual("<input type=\"checkbox\" id=\"sendemail\" name=\"sendemail\" value=\"true\" checked=\"checked\" />" +
211 "<input type=\"hidden\" id=\"sendemailH\" name=\"sendemail\" value=\"0\" />",
212 helper
.CheckboxField("sendemail", new DictHelper().CreateDict("falseValue=0")));
216 public void RadioField()
218 user
.IsActive
= true;
220 Assert
.AreEqual("<input type=\"radio\" id=\"user_isactive\" name=\"user.isactive\" value=\"True\" checked=\"checked\" />",
221 helper
.RadioField("user.isactive", true));
223 user
.IsActive
= false;
225 Assert
.AreEqual("<input type=\"radio\" id=\"user_isactive\" name=\"user.isactive\" value=\"True\" />",
226 helper
.RadioField("user.isactive", true));
230 public void RadioFieldWithEnums()
232 Assert
.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Read\" checked=\"checked\" />",
233 helper
.RadioField("fileaccess", FileAccess
.Read
));
235 Assert
.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Read\" checked=\"checked\" />",
236 helper
.RadioField("fileaccess", "Read"));
238 Assert
.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Write\" />",
239 helper
.RadioField("fileaccess", FileAccess
.Write
));
241 Assert
.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Write\" />",
242 helper
.RadioField("fileaccess", "Write"));
246 public void LabelFor()
248 Assert
.AreEqual("<label for=\"product_name\">Name:</label>",
249 helper
.LabelFor("product.name", "Name:"));
253 public void LabelForAttributed()
255 IDictionary attrs
= new ListDictionary();
256 attrs
.Add("class", "cssclass");
257 Assert
.AreEqual("<label for=\"product_name\" class=\"cssclass\" >Name:</label>",
258 helper
.LabelFor("product.name", "Name:",attrs
));
261 public void TextFieldWithIndex()
263 Assert
.AreEqual("<input type=\"text\" id=\"roles_0_Id\" name=\"roles[0].Id\" value=\"1\" />",
264 helper
.TextField("roles[0].Id"));
266 Assert
.AreEqual("<input type=\"text\" id=\"roles_1_Name\" name=\"roles[1].Name\" value=\"b\" />",
267 helper
.TextField("roles[1].Name"));
271 public void TextFieldWithNestedIndex()
273 user
.Roles
.Add(new Role(1, "role1"));
274 user
.Roles
.Add(new Role(2, "role2"));
276 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_0_Id\" name=\"user.roles[0].Id\" value=\"1\" />",
277 helper
.TextField("user.roles[0].Id"));
279 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_0_Name\" name=\"user.roles[0].Name\" value=\"role1\" />",
280 helper
.TextField("user.roles[0].Name"));
282 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_1_Name\" name=\"user.roles[1].Name\" value=\"role2\" />",
283 helper
.TextField("user.roles[1].Name"));
287 public void TextFieldWithNestedIndexAndNullValues1()
291 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_0_Id\" name=\"user.roles[0].Id\" value=\"\" />",
292 helper
.TextField("user.roles[0].Id"));
294 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_0_Name\" name=\"user.roles[0].Name\" value=\"\" />",
295 helper
.TextField("user.roles[0].Name"));
297 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_1_Name\" name=\"user.roles[1].Name\" value=\"\" />",
298 helper
.TextField("user.roles[1].Name"));
302 public void TextFieldWithNestedIndexAndNullValues2()
304 user
.Roles
.Add(new Role(1, null));
305 user
.Roles
.Add(new Role(2, null));
307 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_0_Name\" name=\"user.roles[0].Name\" value=\"\" />",
308 helper
.TextField("user.roles[0].Name"));
310 Assert
.AreEqual("<input type=\"text\" id=\"user_roles_1_Name\" name=\"user.roles[1].Name\" value=\"\" />",
311 helper
.TextField("user.roles[1].Name"));
315 public void IndexedValueTextFieldInDotNet2()
317 subscription
.Months4
.Clear();
318 subscription
.Months4
.Add(new Month(1, "Jan"));
319 subscription
.Months4
.Add(new Month(2, "Feb"));
321 Assert
.AreEqual("<input type=\"text\" id=\"subscription_months4_0_id\" name=\"subscription.months4[0].id\" value=\"1\" />",
322 helper
.TextField("subscription.months4[0].id"));
323 Assert
.AreEqual("<input type=\"text\" id=\"subscription_months4_0_name\" name=\"subscription.months4[0].name\" value=\"Jan\" />",
324 helper
.TextField("subscription.months4[0].name"));
327 [Test
, ExpectedException(typeof(RailsException
))]
328 public void InvalidIndex1()
330 helper
.TextField("roles[a].Id");
333 [Test
, ExpectedException(typeof(RailsException
))]
334 public void InvalidIndex2()
336 helper
.TextField("roles[1a].Id");
339 [Test
, ExpectedException(typeof(RailsException
)), Ignore("The behavior for array access has changed")]
340 public void InvalidIndex3()
342 helper
.TextField("roles[10].Id");
346 #region Classes skeletons
353 public Month(int id
, string name
)
368 set { name = value; }
372 public class Subscription
375 IList months2
= new ArrayList();
377 IList
<Month
> months4
= new CustomList
<Month
>();
381 get { return months; }
382 set { months = value; }
387 get { return months2; }
388 set { months2 = value; }
391 public Month
[] Months3
393 get { return months3; }
394 set { months3 = value; }
397 public IList
<Month
> Months4
399 get { return months4; }
400 set { months4 = value; }
407 private int quantity
;
408 private bool isAvailable
;
409 private decimal price
;
410 private ProductCategory category
= new ProductCategory();
416 public Product(string name
, int quantity
, decimal price
)
419 this.quantity
= quantity
;
423 public virtual string Name
426 set { name = value; }
429 public virtual int Quantity
431 get { return quantity; }
432 set { quantity = value; }
435 public virtual decimal Price
437 get { return price; }
438 set { price = value; }
441 public virtual bool IsAvailable
443 get { return isAvailable; }
444 set { isAvailable = value; }
447 public virtual ProductCategory Category
449 get { return category; }
450 set { category = value; }
454 public class ProductCategory
459 public ProductCategory()
463 public ProductCategory(int id
, String name
)
478 set { name = value; }
487 public Role(int id
, string name
)
502 set { name = value; }
505 public override bool Equals(object obj
)
507 Role other
= obj
as Role
;
511 return other
.Id
== Id
;
517 public override int GetHashCode()
522 public override string ToString()
530 private int identification
;
533 public Role2(int id
, string name
)
535 this.identification
= id
;
539 public int Identification
541 get { return identification; }
542 set { identification = value; }
548 set { name = value; }
552 public class SimpleUser
554 public enum RegistrationEnum
563 private ArrayList roles
= new ArrayList();
564 private bool isActive
;
565 private RegistrationEnum registration
= RegistrationEnum
.registered
;
571 public SimpleUser(int id
, bool isActive
)
574 this.isActive
= isActive
;
585 get { return isActive; }
586 set { isActive = value; }
592 set { name = value; }
595 public RegistrationEnum Registration
597 get { return registration; }
598 set { registration = value; }
601 public Role
[] RolesAsArray
603 get { return (Role[]) roles.ToArray(typeof(Role)); }
606 public ArrayList Roles
608 get { return roles; }
609 set { roles = value; }
615 private Month dobMonth
;
617 public Month DobMonth
619 get { return this.dobMonth; }
620 set { this.dobMonth = value; }
624 public class CustomList
<T
> : IList
<T
>
626 private List
<T
> innerList
= new List
<T
>();
628 public int IndexOf(T item
)
630 return innerList
.IndexOf(item
);
633 public void Insert(int index
, T item
)
635 innerList
.Insert(index
, item
);
638 public void RemoveAt(int index
)
640 innerList
.RemoveAt(index
);
643 public T
this[int index
]
645 get { return innerList[index]; }
646 set { innerList[index] = value; }
649 public void Add(T item
)
659 public bool Contains(T item
)
661 return innerList
.Contains(item
);
664 public void CopyTo(T
[] array
, int arrayIndex
)
666 throw new NotImplementedException();
669 public bool Remove(T item
)
671 throw new NotImplementedException();
676 get { return innerList.Count; }
679 public bool IsReadOnly
681 get { throw new NotImplementedException(); }
684 IEnumerator
<T
> IEnumerable
<T
>.GetEnumerator()
686 throw new NotImplementedException();
689 public IEnumerator
GetEnumerator()
691 return innerList
.GetEnumerator();
695 public interface IInterfacedList
698 string Name { get; set;}
701 public class InterfacedClassA
: IInterfacedList
706 public InterfacedClassA(int id
, string name
)
712 #region IInterfacedList Members
729 public class InterfacedClassB
: IInterfacedList
734 public InterfacedClassB(int id
, string name
)
740 #region IInterfacedList Members
751 set { name = value; }
772 public class ClassWithCompositKey
777 public ClassWithCompositKey(int id
, string name
)
786 set { name = value; }