Wicket Auth/Roles user authentication before testing web Page - java

I have a web app which use Wicket Auth/Roles to login user and assign roles. (http://wicket.apache.org/learn/projects/authroles.html)
You can refer to this example too: http://www.wicket-library.com/wicket-examples-6.0.x/authentication3/
I have many web pages and I want to login in my application before testing my pages.
My test page extends WebAppTestBase.
Here is my code for WebAppTestBase:
public class WebAppTestBase {
protected WicketTester wicketTester;
private MyAuthenticatedWebApplication myAuthenticatedWebApplication = new MyAuthenticatedWebApplication();
#Before
public void setUp() {
wicketTester = new WicketTester(myAuthenticatedWebApplication);
}
#After
public void tearDown() {
wicketTester.destroy();
}
}
So how I could setUp AuthenticatedWebSession to authenticate my user, so I'll be able to test the other page.
Regards,

This might be an old question, but I stumbled upon this myself and found a reasonable solution that might work for you.
It is quite obvious, but it took me a while to realise that this was the way to do it.
public class MyPageTest {
private static WicketTester tester;
public static final String VALID_ADMIN_USERNAME = "admin";
public static final String VALID_ADMIN_PASSWORD = "1234";
#BeforeClass
public static void beforeTesting() {
tester = new WicketTester(new MyTestApplication());
/*
* Setup your AuthenticatedWebSession to be able to resolve any objects
* it might be depening on. In my case this was an AuthChecker instance that
* I get from Guice dependency injection but this might be very different
* for you.
*/
((MyAuthenticatedWebSession)tester.getSession())
.configureAuthChecker(MyTestApplication.testInjector()
.getInstance(AuthChecker.class));
}
#AfterClass
public static void afterTesting() {
tester.destroy();
}
#Test
public void testAdminOptions() {
// You could consider doing this in a separate #Before annotated method.
// This is basically where the magic happens and the user is logged in.
((AuthenticatedWebSession)tester.getSession()).signIn(
VALID_ADMIN_USERNAME,
VALID_ADMIN_PASSWORD);
// When the user is logged in, you can just start from a page that normally
// requires authentication.
tester.startPage(OverviewPage.class);
tester.assertVisible("myPanel");
}
}

Related

A known design pattern for dynamic factory

Does this have a proper name?
public class SomethingFactory {
private final String someParameter;
public SomethingFactory(String someParameter) {
this.someParameter = someParameter;
}
public Something create(String anotherParameter) {
return new Something(someParameter, anotherParameter);
}
}
public class Something {
public final String someParameter;
public final String anotherParameter;
public Something(String someParameter, String anotherParameter) {
this.someParameter = someParameter;
this.anotherParameter = anotherParameter;
}
}
What's different from a regular factory is that you have to specify a parameter at runtime to create() whenever you need to create an object.
That way you can make a singleton factory within Spring context for example, configuring first half of parameters there, and then finish with the rest of parameters at runtime when you call create().
Why I need that in the first place if you're curious:
I used to have regular singleton objects in Spring context and it was fine in thread-per-request applications, but now my whole app is non-blocking and I can't use ThreadLocal to keep stuff throughout entire request processing. For example, to keep info on timings with something like Apache StopWatch.
I needed to find a way to implement a "request scope" in a multithreading, non-blocking environment without having to supply the object representing the scope in every method (that would be silly) of my code.
So I thought let's make every (service) class take this scope object in constructor and let's create those classes on every request, but that goes against the singletons. The singletons we're talking are like, UserService that logs a user in, or a CryptoService that generates digital signatures. They're configured once in Spring, injected wheneven needed and everything's ok. But now I need to create those service classes in every method where they're needed, instead of just referencing an injected singleton instance.
So I thought let's call those singletons "templates" and whenever you need an actual instance you call create() supplying the said scope object. That way every class has the scope object, you just have to keep supplying it into other template service constructors. The full thing would look like this:
public class UserService {
private final Scope scope;
private final Template t;
private UserService(Template t, Scope scope) {
this.t = t;
this.scope = scope;
}
public void login(String username) {
scope.timings.probe("before calling database");
t.database.doSomething(username);
scope.timings.probe("after calling database");
}
public static class Template { /* The singleton configured in Spring */
private Database database;
public void setDatabase(Database database) { /* Injected by Spring */
this.database = database;
}
public UserService create(Scope scope) {
return new UserService(this, scope);
}
}
}
public class LoginHttpHandler { /* Also a Spring singleton */
private UserService.Template userServiceT;
public void setUserServiceT(UserService.Template userServiceT) { /* Injected by Spring */
this.userServiceT = userServiceT;
}
public void handle(HttpContext context) { /* Called on every http request */
userServiceT.create(context.scope).login("billgates");
}
}
In Spring you'd just describe a UserService.Template bean with the appropriate dependencies it needs and then inject that bean whenever a UserService is needed.
I just call that a "template". But like always I feel it's already been done. Does it have any name?
That is almost the example given for Guice's AssistedInject:
public class RealPaymentFactory implements PaymentFactory {
private final Provider<CreditService> creditServiceProvider;
private final Provider<AuthService> authServiceProvider;
#Inject
public RealPaymentFactory(Provider<CreditService> creditServiceProvider, Provider<AuthService> authServiceProvider) {
this.creditServiceProvider = creditServiceProvider;
this.authServiceProvider = authServiceProvider;
}
public Payment create(Date startDate, Money amount) {
return new RealPayment(creditServiceProvider.get(), authServiceProvider.get(), startDate, amount);
}
}
public class RealPayment implements Payment {
public RealPayment(
CreditService creditService, // from the Injector
AuthService authService, // from the Injector
Date startDate, // from the instance's creator
Money amount) // from the instance's creator
{
...
}
}
Assisted injection is used to "create classes that need extra arguments at construction time".
Also, this is similar to partial application, so you could have a PartialUserService that creates a UserService.

Unit testing Amazon SWF child workflows

I have a parent workflow (ParentWorkflow) calling a child workflow (ChildWorkflow) and I'm trying to test out the call.
The parent code looks something like this:
public class ParentWorkflow {
private final ChildWorkflowClientFactory childWorkflowClientFactory =
new ChildWorkflowClientFactoryImpl();
public void runWorkflow() {
new TryCatch() {
#Override
protected void doTry() throws Throwable {
Promise<Void> workflowFinished = childWorkflowClient.childWorkflow(x);
...
}
...
}
}
I want to mock out the
childWorkflowClient.childWorkflow(x)
call, however when I am hooking up the unit test I don't appear to have the option to inject the client factory, the unit test code looks like this:
#Rule
public WorkflowTest workflowTest = new WorkflowTest();
#Mock
private Activities mockActivities;
private ParentWorkflowClientFactory workflowFactory
= new ParentWorkflowClientFactoryImpl();
#Before
public void setUp() throws Exception {
// set up mocks
initMocks(this);
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(ParentWorkflowImpl.class);
workflowTest.addWorkflowImplementationType(ChildWorkflowImpl.class);
I don't appear to be able to pass anything into the workflow implementation classes, is there another way I can mock the child workflow out?
You can test workflow code directly mocking its dependencies without using workflowTest:
/**
* Rule is still needed to initialize asynchronous framework.
*/
#Rule
public WorkflowTest workflowTest = new WorkflowTest();
#Mock
private ActivitiesClient mockActivities;
#Mock
private BWorkflowClientFactory workflowFactory;
#Before
public void setUp() throws Exception {
// set up mocks
initMocks(this);
}
#Test
public void myTest() {
AWorkflowImpl w = new AWorkflowImpl(workflowFactory);
w.execute(); // whatever execute method of the workflow
}
This approach allows testing parts of the workflow encapsulated in other objects instead of the entire workflow.
If for whatever reason (for example you are using other testing framework than JUnit) you don't want to rely on WorkflowTest #Rule asynchronous code can be always executed using AsyncScope:
#Test
public void asyncTest() {
AsyncScope scope = new AsyncScope() {
protected void doAsync() {
// Any asynchronous code
AWorkflowImpl w = new AWorkflowImpl(workflowFactory);
w.execute(); // whatever execute method of the workflow
}
};
scope.eventLoop();
}
EDIT: The below only applies to SpringWorkflowTest; WorkflowTest doesn't have addWorkflowImplementation for some reason.
The correct way to use the WorkflowTest would be to add a mock implementation for the child workflow rather than adding the actual type:
#Rule
public SpringWorkflowTest workflowTest = new SpringWorkflowTest();
#Mock
private Activities mockActivities;
#Mock
private ChildWorkflow childWorkflowMock;
private ParentWorkflowClientFactory workflowFactory
= new ParentWorkflowClientFactoryImpl();
#Before
public void setUp() throws Exception {
// set up mocks
initMocks(this);
workflowTest.addActivitiesImplementation(mockActivities);
workflowTest.addWorkflowImplementationType(ParentWorkflowImpl.class);
workflowTest.addWorkflowImplementation(childWorkflowMock);
...
}
The framework will then call this mock instead of the actual implementation when you use the factory.

Sanitize a database during Arquillian testing

I am currently writing tests for some REST-full Services I wrote. The services I am testing are written in Java and use MongoDb/Morphia. The tests call on the services, some of which in turn write to a test collection. I need to clean up after the tests and delete the data I injected. What is the best way to go about this?
Here is an example of one of my simple services:
package org.haib.myerslab.services;
#Path("/database")
public class DatabaseService {
#Inject
private Datastore ds;
#Path("/genre/")
#POST
#Produces("application/json")
public GenreDTO postFromGenreDTO(#Context UriInfo uri, GenreDTO form) throws ParseException {
Genre myNewGenre = DtoToDomainMapper.gerneFromGenreDTO(form);
myNewGenre.setId(form.getId());
ds.save(myNewGenre);
return new GenreDTO(myNewGenre);
}
}
And here is an example of my Arquillian test:
#RunWith(Arquillian.class)
public class GeneTest {
private static String myId = "myGenreId";
private static String myGenre = "myGenre";
private static String myGenreInfo = "myGenreInfo";
#Deployment
public static WebArchive getDeployment() {
return TestHelper.getDeployment();
}
#Test
#RunAsClient
#InSequence(1)
public void canPostGenre(#ArquillianResource URL baseURL) throws Exception {
GenreDTO newGenre = new GenreDTO();
newGenre.setGenre(myGenre);
newGenre.setGenreInfo(myGenreInfo);
newGenre.setId(myId);
String url = baseURL.toURI().resolve("/database/genre/").toString();
JsonNode rootNode = TestHelper.postUrl(url, newGene);
assertEquals(myGenre, rootNode.get("genre").asText());
assertEquals(myGenreInfo, rootNode.get("genreInfo").asText());
assertEquals(myId, rootNode.get("id").asText());
}
}
Where the getDeployment function looks like this:
public static WebArchive getDeployment() {
File[] depend = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeDependencies().resolve().withTransitivity().asFile();
WebArchive war = ShrinkWrap.create(WebArchive.class).addClass(TestHelper.class)
.addClass(Genre.class).addClass(Application.class).addPackage("org/haib/myerslab")
.addPackage("org/haib/myerslab/database").addPackage("org/haib/myerslab/genre")
.addPackage("org/haib/myerslab/dto").addPackage("org/haib/myerslab/dto/genre")
.addAsLibraries(depend).addAsWebInfResource("jboss-deployment-structure.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml").setWebXML("test-web.xml");
return war;
}
So where I am lost is, what is the best way to Inject the database in an #After, and clear our the Genre Class I posted into it so that my next test doesn't have it there.
How should I do this? Is there another way?
Take a look at nosql-unit. It provides annotations and rules that help you with seeding datasets, comparing expectations and cleaning up MongoDB.
To get your MongoDB into a pristine state before executing a test, you can simply use the following Annotation with the `CLEAN_INSERT´ :
#UsingDataSet(locations="my_data_set.json", loadStrategy=LoadStrategyEnum.CLEAN_INSERT)
public void canPostGenre() { ...}
If you need the behavior around the integration testing lifecycle with MongoDB to be more powerful, you can also roll your own based on the ideas of nosql-unit. Also make sure to check out Junit Rules.

Play Framework 2.2.2 - Java -Testing Controllers With Mock Objects

Is anyone aware of any examples of testing a Java based Play Framework controller by setting mock objects?
I am using Spring in my Play project so all my controller methods are not static.
Testing the tradional way, Play shows my controller as having static methods and I just cant see a way of how I can inject mocks into my object
Result result = callAction(
controllers.routes.ref.LoginController.authenticate(),
fakeRequest().withFormUrlEncodedBody(TestUtils.SUCCESSFUL_LOGIN_MAP)
);
I have a number of services that need to be called in the LoginController and I would like to set those up as mocks
Any help is greatly appreciated
Thanks
Damien
I was looking for the solution of the same problem. So far the best result I was able to achieve is this:
public class MyObjectControllerTest{
private final MyObjectDAO dao = mock(MyObjectDAO.class);
private final MyObjectController controller = new MyObjectController(dao);
public static FakeApplication fakeApplication;
#BeforeClass
public static void startApp() {
fakeApplication = Helpers.fakeApplication();
Helpers.start(fakeApplication);
}
#AfterClass
public static void stopApp() {
Helpers.stop(fakeApplication);
}
#Test(expected = NotFoundException.class)
public void testFailWithUnknownMyObjectKey() throws Throwable {
when(dao.getByKey(any(UUID.class), any(UUID.class), any(Boolean.class))).thenReturn(null);
controller.get(CassandraUUIDs.timeBased());
}
#Test
public void testGetSuccess(){
MyObject deletedObject = MyObjectTestGenerator.generateMyObject();
deletedObject.setDeleted(true);
when(dao.getByKey(any(UUID.class), any(UUID.class), any(Boolean.class))).thenReturn(deletedObject);
try {
Result result = controller.get(CassandraUUIDs.timeBased());
assertThat(status(result)).isEqualTo(Http.Status.GONE);
assertThat(contentType(result)).isEqualTo(Http.MimeTypes.JSON);
assertThat(contentAsString(result)).isEqualTo(ErrorMsg.OBJECT_DELETED.toJson().toString());
} catch (MyObjectsException e) {
e.printStackTrace();
fail("Failed to send MyObject.get request.");
}
}
}
What I do here is instantiate an instance of the controller class and pass mocked DAO instance. Please note that I don't use static controller methods in my code as well.
One issue with this workaround I found so far is that Action (I have custom one) is not working. But Action can (and probably must) be tested separately.

Junit test - com.liferay.portal.kernel.bean.BeanLocatorException: BeanLocator has not been set

public class CustomServiceImplTest extends TestCase{
ApplicationContext ac;
private BeanLocator mockBeanLocator;
#Test
public void testCreateCategory() throws Exception {
CustomService customService = (CustomService) ac.getBean("customService");
customService.CreateCategory();
}
#Before
public void setUp()
{
mockBeanLocator = Mockito.mock(BeanLocator.class);
PortalBeanLocatorUtil.setBeanLocator(mockBeanLocator);
CompanyLocalServiceUtil mockCompanyLocalService = Mockito.mock(CompanyLocalServiceUtil.class);
ac = CustomSpringUtils.loadApplicationContext(new String[] { ""/applicationContext-Services.xml" });
}
}
I am using basic JUnit 4 and created above test class extending TestCase.
The exception I am getting follows :
java.lang.NullPointerException at com.liferay.portal.service.CompanyLocalServiceUtil.getCompanyByWebId(CompanyLocalServiceUtil.java:498)
The following method customService.CreateCategory(); has calls to Lifery util methods such as CompanyLocalServiceUtil.getCompanyByWebId and etc.
Please anyone shed some light on this. I really appreciate any help.
Do I need to provide Liferay DS information in spring config file?? OR
Is there any way I could stub out the data ??
I am trying to test a ADD operation on one of the Liferay entity class -
MBCategoryLocalServiceUtil.addCategory(...)
You have to inject/mock CompanyLocalService class in CompanyLocalServiceUtil. The Liferay way of doing it is:
CompanyLocalService service = ..... // mock;
new CompanyLocalServiceUtil().setService(service);
The setService is an instance method but is assign value to static field. Don't ask me why it is implemented and designed in such way.

Categories