richfacesjsf-1.2jboss-arquillianseam2

Arquillian tests for an application with Seam 2.2.1 with JSF 1.2 and Richfaces 3.3.3 with managed JBoss 7.2


I am working with legacy code based on:

The app itself is running fine on a Wildfly 9.0.2, with some dependencies such as JSF 1.2 being used instead of the Wildfly 9.0.2 Defaults. The Arquillian configuration is running on a managed JBoss 7.2

Before moving this app to a newer technology stack, I need to write an extensive test Suite. I would like to use Arquillian for this purpose.

I managed to get some things to work already. However, for some tests I need to create an Identity and have Seam recognize me (the test) as a logged in user. This is where I am stuck.

Whatever I try, I get this exception:

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/ISMS_Tool]] (http-/0:0:0:0:0:0:0:0:8180-2) 
JBWEB000211: Session event listener threw exception: 
org.jboss.seam.InstantiationException: Could not instantiate Seam component: 
org.jboss.seam.security.ruleBasedPermissionResolver
at org.jboss.seam.Component.newInstance(Component.java:2170) 
[jboss-seam-2.2.1.Final.jar:2.2.1.Final]
at org.jboss.seam.contexts.Contexts.startup(Contexts.java:304) [jboss-seam-2.2.1.Final.jar:2.2.1.Final]

Caused by: org.jboss.seam.InstantiationException: Could not instantiate Seam component: securityRules
Caused by: java.lang.NullPointerException
at org.drools.base.evaluators.EvaluatorRegistry.addEvaluatorDefinition(EvaluatorRegistry.java:155) [drools-core-5.6.0.Final.jar:5.6.0.Final]

[I am mostly using code from this repository]https://github.com/omidp/seam/tree/master/seam-integration-tests/src/test/java/org/jboss/seam/test/integration/security

The SecurityTest.java is what I'm trying to get to work here.


Solution

  • The following code will solve the problem above. I hope it may be useful for other developers working with legacy applications.

    @RunWith(Arquillian.class)
    @ArquillianSuiteDeployment
    public class seamIntegrationTest  {
    
    private AssetAction assetAction;
    private EntityManager entityManager;
    private User user;
    
    @Deployment
    public static Archive<?> createTestArchive() {
        MavenResolverSystem resolver = Maven.resolver();
        resolver.loadPomFromFile("pom.xml");
        return ShrinkWrap.create(WebArchive.class, "my.war")
                .addPackages(true, "de.abc.ui")
                .addPackages(true, "de.abc")
                .addAsResource("META-INF/test-persistence.xml", "META-INF/persistence.xml")
                .addAsResource("META-INF/jboss-deployment-structure.xml", "META-INF/jboss-deployment-structure.xml")
                .addAsResource("META-INF/jaxws-endpoint-config.xml", "META-INF/jaxws-endpoint-config.xml")
                .addAsResource("META-INF/jboss-webservices.xml", "META-INF/jboss-webservices.xml")
                .addAsResource("de/abc/tool/webservice/handler/ws_security_handler.xml")
                .addAsResource("components.properties")
                .addAsResource("security.drl")
                .addAsResource(EmptyAsset.INSTANCE, "seam.properties")
                .addAsWebInfResource("components.xml")
                .setWebXML("web.xml")
                .addAsLibraries(
                        resolver.loadPomFromFile("pom.xml").importRuntimeAndTestDependencies().resolve().withTransitivity().asFile());
    }
    
    
    
    @Before
    public void setUp() throws Exception {
        MockFacesContext mfc = new MockFacesContext(new MockExternalContext(), new MockApplication());
        UIViewRoot viewRoot = mock(UIViewRoot.class);
        when(viewRoot.findComponent(anyString())).thenReturn(mock(UIForm.class));
        mfc.setViewRoot(viewRoot);
    
        Method m = ReflectionUtils.findMethod(FacesContext.class, "setCurrentInstance", FacesContext.class);
        m.setAccessible(true);
        m.invoke(null, mfc);
    
        Credentials credentials = new Credentials();
        credentials.setUsername("user");
        credentials.setPassword("password");// these should be an existing user in the database
        credentials.setInitialized(true);
    
        Principal principal = new Principal() {
            @Override
            public String getName() {
                return "principalname";
            }
        };
    
        ExtendedIdentity identity = new ExtendedIdentity();
        identity.create();
    
        Field c = ReflectionUtils.findField(ExtendedIdentity.class, "credentials");
        c.setAccessible(true);
        ReflectionUtils.setField(c, identity, credentials);
    
        c = ReflectionUtils.findField(ExtendedIdentity.class, "principal");
        c.setAccessible(true);
        ReflectionUtils.setField(c, identity, principal);
    
        identity.login();
        Contexts.getSessionContext().set(Component.getComponentName(Identity.class), identity);
    
        List<User> users = entityManager.createNamedQuery(User.Q_getUserByUserName)
                .setParameter("username", "password")
                .getResultList();
        if (!users.isEmpty()) {
            user = users.get(0);
            Contexts.getSessionContext().set("loginUser", user);
            for (Role role : user.getRoles()) {
                identity.addRole(role.getRolename());
            }
        }
    
    }
    
    // This is the dialog that can only be accessed when a user is successfully logged in:
    @Test
    public void openCreateNewDialog() throws Exception {
    
        assetAction.setAssetId(126);
        assetAction.setAsset(entityManager.find(Asset.class, 126));
    
        assetAction.openNewChildAssetDialog();
        String result = assetAction.saveNewChildAsset();
    }
    

    }