1   package org.melati.template.test;
2   
3   import java.util.Properties;
4   
5   import org.melati.Melati;
6   import org.melati.MelatiConfig;
7   import org.melati.PoemContext;
8   import org.melati.poem.AccessPoemException;
9   import org.melati.poem.BaseFieldAttributes;
10  import org.melati.poem.Capability;
11  import org.melati.poem.Column;
12  import org.melati.poem.Field;
13  import org.melati.poem.PoemLocale;
14  import org.melati.poem.PoemThread;
15  import org.melati.util.test.Node;
16  import org.melati.util.test.TreeDatabase;
17  import org.melati.template.AttributeMarkupLanguage;
18  import org.melati.template.HTMLMarkupLanguage;
19  import org.melati.template.MarkupLanguage;
20  import org.melati.template.TemplateContext;
21  import org.melati.template.TemplateEngine;
22  import org.melati.template.TemplateEngineException;
23  import org.melati.util.JSStaticTree;
24  import org.melati.util.MelatiException;
25  import org.melati.util.MelatiStringWriter;
26  import org.melati.util.Tree;
27  
28  import junit.framework.TestCase;
29  
30  
31  /**
32   * An abstract test which is run against most permutations of configuaration.
33   * 
34   * @author timp
35   * @since 14-May-2006
36   */
37  abstract public class MarkupLanguageSpec extends TreeTestCase {
38  
39    protected static MelatiConfig mc = null;
40    protected static TemplateEngine templateEngine = null;
41    protected static MarkupLanguage ml = null;
42    protected static AttributeMarkupLanguage aml = null;
43    protected static Melati m = null;
44  
45    /**
46     * Constructor for PoemTest.
47     * @param arg0
48     */
49    public MarkupLanguageSpec(String arg0) {
50      super(arg0);
51    }
52    /**
53     * Constructor.
54     */
55    public MarkupLanguageSpec() {
56      super();
57    }
58    
59  
60   
61    /**
62     * @see TestCase#setUp()
63     */
64    protected void setUp() throws Exception
65    {
66      super.setUp();
67      melatiConfig();
68      templateEngine = mc.getTemplateEngine();
69      //System.err.println("About to init " + templateEngine.getClass().getName());
70      templateEngine.init(mc);
71      m = new Melati(mc, new MelatiStringWriter());
72      m.setTemplateEngine(templateEngine);
73      m.setPoemContext(new PoemContext());
74      assertNotNull(m.getTemplateEngine());
75      TemplateContext templateContext =
76        templateEngine.getTemplateContext(m);
77      m.setTemplateContext(templateContext);
78    }
79    
80    abstract protected void melatiConfig() throws MelatiException ;
81    
82    
83    
84    /**
85     * Test method for rendered(Exception).
86     * @throws Exception 
87     * 
88     * @see org.melati.template.HTMLAttributeMarkupLanguage#
89     *      rendered(AccessPoemException)
90     */
91    public void testRenderedAccessPoemException() throws Exception {
92      
93      assertEquals("java.lang.Exception",aml.rendered(new Exception()));
94  
95      AccessPoemException ape = new AccessPoemException(
96            getDb().getUserTable().guestUser(), new Capability("Cool"));
97      assertTrue(ml.rendered(ape).indexOf("[Access denied to Melati guest user]") != -1);
98      ape = new AccessPoemException();
99      assertEquals("", aml.rendered(ape));
100     //System.err.println(m.getWriter().toString());
101     assertTrue(m.getWriter().toString().indexOf("[Access denied to [UNRENDERABLE EXCEPTION!]") != -1);
102     ape = new AccessPoemException(
103           getDb().getUserTable().guestUser(), new Capability("Cool"));
104     assertEquals("", aml.rendered(ape));
105       // NB Not at all sure how this value changed 
106       //System.err.println(m.getWriter().toString());
107       //assertTrue(m.getWriter().toString().indexOf("[Access denied to Melati guest user]") != -1);
108     assertTrue(m.getWriter().toString().indexOf("[Access denied to _guest_]") != -1);
109 
110   }
111 
112   /**
113    * Test method for Constructor. 
114    * 
115    * @see org.melati.template.HTMLMarkupLanguage#
116    *   HTMLMarkupLanguage(Melati, TempletLoader, PoemLocale)
117    */
118   public void testHTMLMarkupLanguageMelatiTempletLoaderPoemLocale() {
119 
120   }
121 
122   /**
123    * Test method for Constructor 
124    * @see org.melati.template.HTMLMarkupLanguage#
125    *          HTMLMarkupLanguage(String, HTMLMarkupLanguage)
126    */
127   public void testHTMLMarkupLanguageStringHTMLMarkupLanguage() {
128 
129   }
130 
131   /**
132    * Test method for getAttr().
133    * 
134    * @see org.melati.template.HTMLMarkupLanguage#getAttr()
135    */
136   public void testGetAttr() {
137     assertEquals(aml.getClass(), ml.getAttr().getClass());
138   }
139 
140   /**
141    * Test method for escaped(String).
142    * 
143    * @see org.melati.template.HTMLLikeMarkupLanguage#escaped(String)
144    */
145   public void testEscapedString() throws Exception {
146 
147   }
148   
149   /**
150    * Test entity substitution.
151    * FIXME how to write this so it works on Windows and Linux??
152    */
153   public void testEntitySubstitution() throws Exception { 
154     /*
155     assertEquals("&%£", ml.rendered("&%�"));
156     assertEquals("&%£", aml.rendered("&%�"));
157     */
158   }
159 
160   /**
161    * Test method for escaped(Persistent).
162    * 
163    * @see org.melati.template.HTMLLikeMarkupLanguage#escaped(Persistent)
164    */
165   public void testEscapedPersistent() {
166     assertEquals("Melati guest user",ml.escaped(getDb().getUserTable().getUserObject(0)));
167   }
168 
169   /**
170    * Test method for encoded.
171    * 
172    * @see org.melati.template.HTMLLikeMarkupLanguage#encoded(String)
173    */
174   public void testEncoded() {
175     assertEquals("+", ml.encoded(" "));
176     assertEquals("+", aml.encoded(" "));
177     assertEquals("%26", ml.encoded("&"));
178     assertEquals("%26", aml.encoded("&"));
179   }
180 
181   /**
182    * Test method for rendered(Object).
183    * 
184    * @see org.melati.template.MarkupLanguage#rendered(Object)
185    */
186   public void testRenderedObject() throws Exception {
187     assertEquals("Fredd$", ml.rendered("Fredd$"));
188     // Note velocity seems to leave the line end on
189     assertEquals("[1]", ml.rendered(new Integer("1")).trim());
190     
191     assertEquals("1", ml.getAttr().rendered(new Integer("1")));
192     try { 
193       ml.getAttr().rendered(new Bomber());
194       fail("Should have bombed");
195     } catch (Exception e) {
196       e = null;
197     }
198     
199     try { 
200       ml.rendered(new Bomber());
201       fail("Should have bombed");
202     } catch (Exception e) {
203       e = null;
204     }
205     
206     Node persistent = (Node)getDb().getTable("node").newPersistent();
207     persistent.setName("Mum");
208     persistent.makePersistent();
209     m.setPoemContext(new PoemContext());
210      
211     String renderedPersistent = ml.rendered(persistent);
212     //System.err.println(renderedPersistent);
213     assertEquals("Mum", renderedPersistent);
214 
215   }
216   
217   /**
218    * Test that a syntax error in a templet is handled.
219    */
220   public void testSyntaxErrorInTemplet() throws Exception { 
221     Object templated = new TemplatedWithSyntaxError();
222     try { 
223       ml.rendered(templated);
224       fail("Should have bombed");
225     } catch (TemplateEngineException e) { 
226       e = null;
227     }
228   }
229   
230   /**
231    * Test that a syntax error in a WM templet is handled by Velocity.
232    */
233   public void testSyntaxErrorInWMTemplet() throws Exception { 
234     Object templated = new TemplatedWithWMSyntaxError();
235     try { 
236       System.err.println(ml.rendered(templated));
237       fail("Should have bombed");
238     } catch (TemplateEngineException e) { 
239       e = null;
240     }
241   }
242   
243   /**
244    * Test that we can find a template on the classpath.
245    */
246   public void testTemplateFoundOnClasspath() throws Exception { 
247     Templated templated = new Templated();
248     String rendered = ml.rendered(templated);
249     assertEquals("Hi, this is from a template.", rendered);    
250   }
251   
252   /**
253    * Test that toString is used if no template found.
254    */
255   public void testUntemplatedObjectUsesToString() throws Exception { 
256     
257     String rendered = ml.rendered(new Properties());
258     // Webmacro, incorrectly, puts a newline at front
259     assertEquals("[{}]", rendered.trim());
260   }
261   /**
262    * Test that special templets are found.
263    */
264   public void testSpecialTemplateFound() throws Exception { 
265     Column column = getDb().getGroupMembershipTable().getUserColumn();
266     BaseFieldAttributes fa = new BaseFieldAttributes(column, column.getType());
267     Field field = new Field(getDb().getUserTable().administratorUser().troid(), fa);
268     Object adminUtil = m.getContextUtil("org.melati.admin.AdminUtils");
269     assertTrue(adminUtil instanceof org.melati.admin.AdminUtils);
270     assertTrue(ml.input(field).indexOf("add_rule(\"field_user\",") != -1);
271   }
272 
273   /**
274    * An object which throws an exception when its toString method is called.
275    */
276   class Bomber {
277     /**
278      * Constructor.
279      */
280     public Bomber() {}
281     /** 
282      * Throw exception.
283      */
284     public String toString() {
285       if (true == true) throw new RuntimeException("Bomber bombed.");
286       return "Did not bomb";
287     }
288   }
289   /**
290    * Test method for rendered(String).
291    * 
292    * @see org.melati.template.MarkupLanguage#rendered(String)
293    */
294   public void testRenderedString() throws Exception {
295     assertEquals("Fredd$", ml.rendered("Fredd$"));
296   }
297 
298   /**
299    * Test NPE thrown.
300    */
301   public void testNull() throws Exception {
302     try { 
303       ml.rendered(null);
304       fail("should have bombed");      
305     } catch (NullPointerException e) { 
306       e = null;
307     }
308     
309   }
310   /**
311    * Test method for rendered(String, int).
312    * 
313    * @see org.melati.template.MarkupLanguage#rendered(String, int)
314    */
315   public void testRenderedStringInt() throws Exception {
316       assertEquals("Fre...", ml.rendered("Fredd$", 3));
317   }
318 
319   /**
320    * Test method for rendered(Field).
321    * 
322    * @see org.melati.template.MarkupLanguage#rendered(Field)
323    */
324   public void testRenderedField() throws Exception {
325     Field userName = getDb().getUserTable().getUserObject(0).getField("login");
326     assertEquals("_guest_", ml.rendered(userName));
327   }
328   /**
329    * Test method for rendered(Field, int).
330    * 
331    * @see org.melati.template.MarkupLanguage#rendered(Field, int)
332    */
333   public void testRenderedFieldInt() throws Exception {
334     Field userName = getDb().getUserTable().getUserObject(0).getField("login");
335     assertEquals("_guest_", ml.rendered(userName,3));
336   }
337 
338   /**
339    * Test method for rendered(Field, int, int).
340    * 
341    * @see org.melati.template.MarkupLanguage#rendered(Field, int, int)
342    */
343   public void testRenderedFieldIntInt() throws Exception {
344     Field userName = getDb().getUserTable().getUserObject(0).getField("login");
345     assertEquals("_gu...", ml.rendered(userName,3,3));
346   }
347 
348 
349   /**
350    * Test method for renderedStart(Field).
351    * 
352    * @see org.melati.template.MarkupLanguage#renderedStart(Field)
353    */
354   public void testRenderedStart() throws Exception {
355     Field userName = getDb().getUserTable().getUserObject(0).getField("login");
356     assertEquals("_guest_", ml.renderedStart(userName));
357   }
358 
359   /**
360    * Test method for input(Field).
361    * 
362    * @see org.melati.template.MarkupLanguage#input(Field)
363    */
364   public void testInputField() throws Exception {
365     Field userName = getDb().getUserTable().getUserObject(0).getField("login");
366     assertTrue(ml.input(userName).toLowerCase().indexOf("<input name=\"field_login\"") != -1);
367   }
368   /**
369    * Test method for input(Field) where field to be rendered as a dropdown.
370    * 
371    * @see org.melati.template.MarkupLanguage#input(Field)
372    */
373   public void testInputFieldSelection() throws Exception {
374     //Selection dropdown of references    
375     Field group = getDb().getGroupMembershipTable().getGroupMembershipObject(0).getField("group");
376     //System.err.println(ml.input(group));
377     assertTrue(ml.input(group).indexOf("<select name=\"field_group\"") != -1);
378   }
379   /**
380    * Test method for input(Field) where the renderinfo is selectionWindow.
381    * 
382    * @see org.melati.template.MarkupLanguage#input(Field)
383    */
384   public void testSelectionWindowField() throws Exception {
385     Field owningTable = getDb().getColumnInfoTable().getColumnInfoObject(0).getField("tableinfo");
386     assertTrue(ml.input(owningTable).indexOf("<input type=\"text\" name=\"field_tableinfo_dummy\"") != -1);
387     Field user = getDb().getGroupMembershipTable().getGroupMembershipObject(0).getField("user");
388     assertTrue(ml.input(user).indexOf("<input type=\"text\" name=\"field_user_dummy\"") != -1);
389   }
390 
391   /**
392    * Test access to password field.
393    * FIXME Does not hit the spot.
394    */
395   public void testInputFieldForRestrictedField() throws Exception { 
396     PoemThread.setAccessToken(getDb().getUserTable().guestUser());
397     Field password = getDb().getUserTable().getPasswordColumn().asEmptyField();
398     assertTrue(ml.input(password).toLowerCase().indexOf("name=\"field_password\"") != -1);
399     //System.err.println(ml.rendered(getDb().getUserTable().administratorUser()));
400   }
401   /**
402    * Test method for inputAs(Field, String).
403    * 
404    * @see org.melati.template.MarkupLanguage#inputAs(Field, String)
405    */
406   public void testInputAs() throws Exception {
407     Field userName = getDb().getUserTable().getUserObject(0).getField("login");
408     try {
409       assertTrue(ml.inputAs(userName, "nonExistantTemplateName").toLowerCase().indexOf("<input name=\"field_login\"") != -1);
410       fail("Should have bombed");
411     } catch (Exception e) {
412       e = null;
413     }
414     assertTrue(ml.inputAs(userName, "org.melati.poem.StringPoemType").toLowerCase().indexOf("<input name=\"field_login\"") != -1);
415   }
416 
417   /**
418    * Test method for searchInput(Field, String).
419    * 
420    * @see org.melati.template.MarkupLanguage#searchInput(Field, String)
421    */
422   public void testSearchInput() throws Exception {
423     Field userName = getDb().getUserTable().getUserObject(0).getField("login");
424     assertTrue(ml.searchInput(userName, "None").toLowerCase().indexOf("<input name=\"field_login\"") != -1);
425   }
426 
427 
428   /**
429    * Test method for rendered(Treeable).
430    * 
431    * @see org.melati.template.MarkupLanguage#rendered(Object)
432    */
433   public void testRenderedTreeable() throws Exception {
434     Node parent = (Node)((TreeDatabase)getDb()).getNodeTable().newPersistent();
435     parent.setName("Mum");
436     parent.makePersistent();
437     Node kid1 = (Node)((TreeDatabase)getDb()).getNodeTable().newPersistent();
438     kid1.setName("K1");
439     kid1.setParent(parent);
440     kid1.makePersistent();
441     Node kid2 = (Node)((TreeDatabase)getDb()).getNodeTable().newPersistent();
442     kid2.setName("K2");
443     kid2.setParent(parent);
444     kid2.makePersistent();
445     Tree testTree = new Tree(parent);
446     JSStaticTree tree = new JSStaticTree(testTree, "/melati-static/admin/static");
447     m.setPoemContext(new PoemContext());
448       
449     String renderedTree = ml.rendered(tree);
450     //System.err.println(":" + renderedTree + ":");
451     assertTrue(renderedTree.indexOf("init") != -1);
452    
453   }
454   
455   
456 }