package org.appfuse.service.impl;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.net.BindException;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.appfuse.model.User;
import org.appfuse.service.UserManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.subethamail.wiser.Wiser;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:/applicationContext-resources.xml",
"classpath:/applicationContext-dao.xml",
"classpath:/applicationContext-service.xml",
"classpath:/applicationContext-test.xml"
})
public class PasswordTokenManagerTest {
protected transient final Log log = LogFactory.getLog(getClass());
private int smtpPort;
private UserManager userManager;
private PasswordTokenManager passwordTokenManager;
@Autowired
private JavaMailSenderImpl mailSender;
@Autowired
private ApplicationContext applicationContext;
@Autowired
@Qualifier("userManager")
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
@Autowired
@Qualifier("passwordTokenManager")
public void setPasswordTokenManager(PasswordTokenManager passwordTokenManager) {
this.passwordTokenManager = passwordTokenManager;
}
protected Wiser startWiser(int smtpPort) {
Wiser wiser = new Wiser();
wiser.setPort(smtpPort);
try {
wiser.start();
} catch (RuntimeException re) {
if (re.getCause() instanceof BindException) {
int nextPort = smtpPort + 1;
if (nextPort - smtpPort > 10) {
log.error("Exceeded 10 attempts to start SMTP server, aborting...");
throw re;
}
log.error("SMTP port " + smtpPort + " already in use, trying " + nextPort);
return startWiser(nextPort);
}
}
mailSender.setPort(smtpPort);
return wiser;
}
@Before
public void before() throws Exception {
smtpPort = (new Random().nextInt(9999 - 1000) + 1000);
// create new user so conflicts don't occur with other tests
User user = new User("token-test");
user.setPassword("foobar");
user.setFirstName("Token");
user.setLastName("Test");
user.setEmail("token-test@appfuse.org");
userManager.saveUser(user);
}
@After
public void after() {
userManager.removeUser(userManager.getUserByUsername("token-test"));
}
@Test
public void testGenerateRecoveryToken() {
final User user = userManager.getUserByUsername("token-test");
final String token = passwordTokenManager.generateRecoveryToken(user);
assertNotNull(token);
assertTrue(passwordTokenManager.isRecoveryTokenValid(user, token));
}
@Test
public void testConsumeRecoveryToken() throws Exception {
final User user = userManager.getUserByUsername("token-test");
final Integer version = user.getVersion();
final String token = passwordTokenManager.generateRecoveryToken(user);
assertNotNull(token);
assertTrue(passwordTokenManager.isRecoveryTokenValid(user, token));
// start SMTP Server
Wiser wiser = startWiser(smtpPort);
User updated = userManager.updatePassword(user.getUsername(), null, token, "user", "");
wiser.stop();
assertTrue(wiser.getMessages().size() == 1);
assertTrue(updated.getVersion() > version);
assertFalse(passwordTokenManager.isRecoveryTokenValid(updated, token));
}
}