Есть набор тестов, которые выполняют различные оплаты.
Подтверждение оплаты происходит с помощью одноразового пароля. Пароль отправляется на тестовый телефон, откуда форвардится на емеил.
Тест, доходит до момента подтверждения оплаты и вызывает метод, который подключается к почте и ждет/ищет необходимое письмо с кодом подтверждения.
Время в течение которого может прийти код подтверждения от 5-10 секунд до 1-2 минут.
Я написал метод, который работает с почтой. Но! он мне очень сильно не нравится, написан откровенно топорно. Проблема в том, что не хватает умений и знаний как правильно написать, чтобы он работал стабильно.
Основные проблемы НЕстабильности 2:
- Если код смс задерживается и приходит дольше чем ~30 сек, метод работы с gmail находится в этот момент в while цикле ожидания нового письма, но, отваливается с ошибкой gmail connection failure, через 30-35 сек.
- Если запускать тесты скопом, то часто происходит ситуация, что 1ый тест отработал успешно, запустился второй тест. 2ой тест доходит до лисенера почты и тут приходит письмо не с кодом, а с отчетом успешной оплаты по первому тесту, метод видит письмо, не находит в нем нужную фразу и отваливается.
Код лисенера почты под катом. Объясните пожалуйста, как написать стабильный лисенер для почты ?
public class GmailImap {
private final String email_id = "";
private final String email_pass = "";
private String digitCode;
public String getDigitCode() {
Properties properties = new Properties();
properties.put("mail.store.protocol", "imaps");
properties.put("mail.imaps.host", "imap.gmail.com");
properties.put("mail.imaps.port", "993");
properties.put("mail.imap.connectiontimeout", "120000");
properties.put("mail.imap.timeout", "120000");
try {
// Connect to gmail and get store and inbox
Session session = Session.getDefaultInstance(properties, null);
Store store = session.getStore("imaps");
System.out.println("Connection initiated...");
store.connect(email_id, email_pass);
System.out.println("Connection is ready...");
Folder inbox = store.getFolder("inbox");
inbox.open(Folder.READ_WRITE);
// Make unseen flag for inbox mails
Flags seen = new Flags(Flags.Flag.SEEN);
FlagTerm unseenFlagTerm = new FlagTerm(seen, false);
Message[] unseenMessages = inbox.search(unseenFlagTerm);
// Delete all prev unseen mails
int messageCount = unseenMessages.length;
System.out.println("crap messages: " + messageCount);
for (int i = 0; i < messageCount; i++) {
Message msg = unseenMessages[i];
inbox.setFlags(new Message[]{msg}, new Flags(Flags.Flag.DELETED), true);
}
unseenMessages = inbox.search(unseenFlagTerm);
messageCount = unseenMessages.length;
System.out.println("new messages: " + messageCount);
// Wait for mail
Long startTime = System.currentTimeMillis();
do {
inbox = store.getFolder("inbox");
inbox.open(Folder.READ_WRITE);
unseenMessages = inbox.search(unseenFlagTerm);
messageCount = unseenMessages.length;
System.out.println((System.currentTimeMillis() - startTime));
} while ((messageCount == 0) && ((System.currentTimeMillis() - startTime) < 120000));
unseenMessages = inbox.search(unseenFlagTerm);
messageCount = unseenMessages.length;
System.out.println(messageCount);
String messageContent;
unseenMessages = inbox.search(unseenFlagTerm);
messageContent = unseenMessages[0].getContent().toString();
System.out.println(messageContent);
// get company digitCode
if (messageContent.contains("condition_1") {
Pattern p = Pattern.compile("\\d{6}");
Matcher m = p.matcher(messageContent);
while (m.find()) {
System.out.println(m.group());
digitCode = m.group();
}
}
// get external digitCode
if (messageContent.contains("condition_2")) {
Pattern p = Pattern.compile("\\d{5}");
Matcher m = p.matcher(messageContent);
while (m.find()) {
System.out.println(m.group());
digitCode = m.group();
}
}
inbox.setFlags(new Message[]{unseenMessages[0]}, new Flags(Flags.Flag.DELETED), true);
inbox.close(true);
store.close();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
return digitCode;
}
}