// Copyright (c) 2003-present, Jodd Team (http://jodd.org) // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. package jodd.madvoc; import jodd.madvoc.component.ActionMethodParser; import jodd.madvoc.component.ActionsManager; import jodd.madvoc.component.MadvocConfig; import jodd.madvoc.macro.RegExpPathMacros; import jodd.madvoc.fixtures.tst.Boo1Action; import jodd.madvoc.fixtures.tst.Boo2Action; import jodd.madvoc.fixtures.tst.Boo3Action; import jodd.madvoc.fixtures.tst.BooAction; import jodd.madvoc.fixtures.tst2.Boo4Action; import jodd.madvoc.fixtures.tst2.Boo5Action; import jodd.madvoc.fixtures.tst2.ReAction; import org.junit.Test; import static org.junit.Assert.*; public class ActionMethodParserTest extends MadvocTestCase { @Test public void testDefaultMethods() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo"); assertEquals("/boo.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#view"); assertEquals("/boo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#execute"); assertEquals("/boo.html", cfg.actionPath); } @Test public void testMethod() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo"); assertNotNull(cfg); assertEquals(BooAction.class, cfg.actionClass); assertEquals("/boo.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo1"); assertEquals("/boo.xxx.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo2"); assertEquals("/boo.foo2.xxx", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo3"); assertEquals("/boo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo4"); assertEquals("/xxx", cfg.actionPath); assertNull(cfg.actionMethod); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo41"); assertEquals("/xxx", cfg.actionPath); assertEquals("DELETE", cfg.actionMethod); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo5"); assertEquals("/xxx.html", cfg.actionPath); assertEquals("POST", cfg.actionMethod); ActionsManager actionsManager = webapp.getComponent(ActionsManager.class); assertEquals("/xxx.html", actionsManager.lookupPathAlias("dude")); } @Test public void testMethodWithPackage() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo"); assertNotNull(cfg); assertEquals(BooAction.class, cfg.actionClass); assertEquals("/fixtures/tst/boo.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo1"); assertEquals("/fixtures/tst/boo.xxx.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo2"); assertEquals("/fixtures/tst/boo.foo2.xxx", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo3"); assertEquals("/fixtures/tst/boo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo4"); assertEquals("/xxx", cfg.actionPath); assertNull(cfg.actionMethod); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo41"); assertEquals("/xxx", cfg.actionPath); assertEquals("DELETE", cfg.actionMethod); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo5"); assertEquals("/xxx.html", cfg.actionPath); assertEquals("POST", cfg.actionMethod); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo6"); assertEquals("/fixtures/tst/boo.qfoo62.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.BooAction#foo7"); assertEquals("/foo7.html", cfg.actionPath); } @Test public void testClasses() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst.Boo1Action#foo"); assertNotNull(cfg); assertEquals(Boo1Action.class, cfg.actionClass); assertEquals("/boo1.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo"); assertNotNull(cfg); assertEquals(Boo2Action.class, cfg.actionClass); assertEquals("/bbb.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo1"); assertEquals("/bbb.xxx.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo2"); assertEquals("/bbb.foo2.xxx", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo3"); assertEquals("/bbb.html", cfg.actionPath); } @Test public void testClassesWithPackage() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst.Boo1Action#foo"); assertNotNull(cfg); assertEquals(Boo1Action.class, cfg.actionClass); assertEquals("/fixtures/tst/boo1.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo"); assertNotNull(cfg); assertEquals(Boo2Action.class, cfg.actionClass); assertEquals("/fixtures/tst/bbb.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo1"); assertEquals("/fixtures/tst/bbb.xxx.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo2"); assertEquals("/fixtures/tst/bbb.foo2.xxx", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo2Action#foo3"); assertEquals("/fixtures/tst/bbb.html", cfg.actionPath); } @Test public void testClassesWithoutPackage() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst.Boo3Action#foo"); assertNotNull(cfg); assertEquals(Boo3Action.class, cfg.actionClass); assertEquals("/bbb.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo3Action#foo1"); assertEquals("/bbb.xxx.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo3Action#foo2"); assertEquals("/bbb.foo2.xxx", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst.Boo3Action#foo3"); assertEquals("/bbb.html", cfg.actionPath); } @Test public void testPackage() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst2.Boo4Action#foo"); assertNotNull(cfg); assertEquals(Boo4Action.class, cfg.actionClass); assertEquals("/ttt/www.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst2.Boo4Action#foo1"); assertEquals("/ttt/www.xxx.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst2.Boo4Action#foo2"); assertEquals("/ttt/www.foo2.xxx", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst2.Boo4Action#foo3"); assertEquals("/ttt/www.html", cfg.actionPath); } @Test public void testNoPackage() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst2.Boo5Action#foo"); assertNotNull(cfg); assertEquals(Boo5Action.class, cfg.actionClass); assertEquals("/www.foo.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst2.Boo5Action#foo1"); assertEquals("/www.xxx.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst2.Boo5Action#foo2"); assertEquals("/www.foo2.xxx", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst2.Boo5Action#foo3"); assertEquals("/www.html", cfg.actionPath); } @Test public void testEndSlashClassName() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst2.ReAction#hello"); assertNotNull(cfg); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/hello.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst2.ReAction#macro"); assertNotNull(cfg); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/user/${id}/macro.html", cfg.actionPath); } @Test public void testMacros() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionsManager actionsManager = webapp.getComponent(ActionsManager.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); actionsManager.register(ReAction.class, "macro"); ActionConfig cfg = actionsManager.lookup("/re/user/173/macro.html", "GET"); assertNotNull(cfg); ActionConfigSet set = cfg.getActionConfigSet(); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/user/${id}/macro.html", cfg.actionPath); assertEquals(4, set.deep); assertEquals(1, set.actionPathMacros.getMacrosCount()); assertEquals("id", set.actionPathMacros.getNames()[0]); assertNull(set.actionPathMacros.getPatterns()[0]); actionsManager.register(ReAction.class, "macro2"); cfg = actionsManager.lookup("/re/user/image/173/png/macro2.html", "GET"); assertNotNull(cfg); set = cfg.getActionConfigSet(); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/user/image/${id}/${fmt}/macro2.html", cfg.actionPath); assertEquals(6, set.deep); assertEquals(2, set.actionPathMacros.getMacrosCount()); assertEquals("id", set.actionPathMacros.getNames()[0]); assertEquals("fmt", set.actionPathMacros.getNames()[1]); actionsManager.register(ReAction.class, "macro3"); cfg = actionsManager.lookup("/re/users/173/macro3", "POST"); assertNotNull(cfg); set = cfg.getActionConfigSet(); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/users/${id}/macro3", cfg.actionPath); assertEquals("POST", cfg.actionMethod); assertEquals(4, set.deep); assertEquals(1, set.actionPathMacros.getMacrosCount()); assertEquals("id", set.actionPathMacros.getNames()[0]); cfg = actionsManager.lookup("/re/user/index.html", "GET"); assertNull(cfg); cfg = actionsManager.lookup("/re/user/index/reindex/macro.html", "GET"); assertNull(cfg); cfg = actionsManager.lookup("/re/users/173/macro3", "GET"); assertNull(cfg); assertEquals(3, actionsManager.getActionsCount()); } @Test public void testMacrosWildcards() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionsManager actionsManager = webapp.getComponent(ActionsManager.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); actionsManager.register(ReAction.class, "wild1"); actionsManager.register(ReAction.class, "wild2"); ActionConfig cfg = actionsManager.lookup("/re/ild123cat", "GET"); assertNull(cfg); cfg = actionsManager.lookup("/re/wild123cat", "GET"); assertNull(cfg); cfg = actionsManager.lookup("/re/wild123cat.html", "GET"); assertNotNull(cfg); ActionConfigSet set = cfg.getActionConfigSet(); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/wild${id}cat.html", cfg.actionPath); assertEquals(2, set.deep); assertEquals(1, set.actionPathMacros.getMacrosCount()); assertEquals("id", set.actionPathMacros.getNames()[0]); cfg = actionsManager.lookup("/re/wild123dog.html", "GET"); assertNull(cfg); cfg = actionsManager.lookup("/re/wild123dog.html", "POST"); assertNotNull(cfg); set = cfg.getActionConfigSet(); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/wild${id}dog.html", cfg.actionPath); assertEquals("POST", cfg.actionMethod); assertEquals(2, set.deep); assertEquals(1, set.actionPathMacros.getMacrosCount()); assertEquals("id", set.actionPathMacros.getNames()[0]); assertEquals(2, actionsManager.getActionsCount()); } @Test public void testMacrosDups() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionsManager actionsManager = webapp.getComponent(ActionsManager.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); madvocConfig.setPathMacroClass(RegExpPathMacros.class); actionsManager.register(ReAction.class, "duplo1"); actionsManager.register(ReAction.class, "duplo2"); ActionConfig cfg = actionsManager.lookup("/re/duplo/123", "GET"); assertNotNull(cfg); ActionConfigSet set = cfg.getActionConfigSet(); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/duplo/${id:^[0-9]+}", cfg.actionPath); assertEquals(3, set.deep); assertEquals(1, set.actionPathMacros.getMacrosCount()); assertEquals("id", set.actionPathMacros.getNames()[0]); cfg = actionsManager.lookup("/re/duplo/aaa", "GET"); assertNotNull(cfg); set = cfg.getActionConfigSet(); assertEquals(ReAction.class, cfg.actionClass); assertEquals("/re/duplo/${sid}", cfg.actionPath); assertEquals(3, set.deep); assertEquals(1, set.actionPathMacros.getMacrosCount()); assertEquals("sid", set.actionPathMacros.getNames()[0]); assertEquals(2, actionsManager.getActionsCount()); } @Test public void testMarkerClass() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionMethodParser actionMethodParser = webapp.getComponent(ActionMethodParser.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); RootPackages rootPackages = madvocConfig.getRootPackages(); String thisPackageName = this.getClass().getPackage().getName(); assertNull(rootPackages.getPackageActionPath(thisPackageName + ".fixtures.tst3")); ActionConfig cfg = parse(actionMethodParser, "fixtures.tst3.JohnAction#hello"); assertEquals("/root", rootPackages.getPackageActionPath(thisPackageName + ".fixtures.tst3")); assertEquals("/root/john.hello.html", cfg.actionPath); cfg = parse(actionMethodParser, "fixtures.tst3.JimAction#hello"); assertEquals("/my-root/jim.my-hello.html", cfg.actionPath); assertNull(rootPackages.getPackageActionPath(thisPackageName + ".fixtures.tst3.lvl1")); cfg = parse(actionMethodParser, "fixtures.tst3.lvl1.EmaAction#hello"); assertEquals("/root/lvl1/ema.hello.html", cfg.actionPath); assertEquals("/root/lvl1", rootPackages.getPackageActionPath(thisPackageName + ".fixtures.tst3.lvl1")); assertNull(rootPackages.getPackageActionPath(thisPackageName + ".fixtures.tst3.lvl2")); cfg = parse(actionMethodParser, "fixtures.tst3.lvl2.DidyAction#hello"); assertEquals("/gig/didy.hello.html", cfg.actionPath); assertEquals("/gig", rootPackages.getPackageActionPath(thisPackageName + ".fixtures.tst3.lvl2")); } @Test public void testZqq() { WebApplication webapp = new WebApplication(true); webapp.registerMadvocComponents(); ActionsManager actionsManager = webapp.getComponent(ActionsManager.class); MadvocConfig madvocConfig = webapp.getComponent(MadvocConfig.class); madvocConfig.getRootPackages().addRootPackageOf(this.getClass()); actionsManager.register(ReAction.class, "zqq1"); actionsManager.register(ReAction.class, "zqq2"); ActionConfig cfg = actionsManager.lookup("/config/dba.delete_multi", "GET"); assertNotNull(cfg); assertEquals("/${entityName}/dba.delete_multi", cfg.getActionPath()); } }