Convert Tell Message Manager to Kotlin.

This commit is contained in:
Erik C. Thauvin 2020-12-04 15:49:25 -08:00
parent 274c711dc2
commit 92e703b68a
10 changed files with 658 additions and 803 deletions

View file

@ -24,6 +24,8 @@
<ID>MagicNumber:Ignore.kt$Ignore$8</ID> <ID>MagicNumber:Ignore.kt$Ignore$8</ID>
<ID>MagicNumber:Modules.kt$Modules$7</ID> <ID>MagicNumber:Modules.kt$Modules$7</ID>
<ID>MagicNumber:Recap.kt$Recap.Companion$10</ID> <ID>MagicNumber:Recap.kt$Recap.Companion$10</ID>
<ID>MagicNumber:Tell.kt$Tell$50</ID>
<ID>MagicNumber:Tell.kt$Tell$7</ID>
<ID>MagicNumber:Twitter.kt$Twitter$1000L</ID> <ID>MagicNumber:Twitter.kt$Twitter$1000L</ID>
<ID>MagicNumber:Twitter.kt$Twitter$60L</ID> <ID>MagicNumber:Twitter.kt$Twitter$60L</ID>
<ID>MagicNumber:Users.kt$Users$8</ID> <ID>MagicNumber:Users.kt$Users$8</ID>
@ -55,6 +57,9 @@
<ID>NestedBlockDepth:Lookup.kt$Lookup$override fun commandResponse( sender: String, cmd: String, args: String, isPrivate: Boolean )</ID> <ID>NestedBlockDepth:Lookup.kt$Lookup$override fun commandResponse( sender: String, cmd: String, args: String, isPrivate: Boolean )</ID>
<ID>NestedBlockDepth:StockQuote.kt$StockQuote$ override fun run(sender: String, cmd: String, args: String, isPrivate: Boolean)</ID> <ID>NestedBlockDepth:StockQuote.kt$StockQuote$ override fun run(sender: String, cmd: String, args: String, isPrivate: Boolean)</ID>
<ID>NestedBlockDepth:StockQuote.kt$StockQuote.Companion$ @JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List&lt;Message&gt;</ID> <ID>NestedBlockDepth:StockQuote.kt$StockQuote.Companion$ @JvmStatic @Throws(ModuleException::class) fun getQuote(symbol: String, apiKey: String?): List&lt;Message&gt;</ID>
<ID>NestedBlockDepth:Tell.kt$Tell$ @JvmOverloads fun send(nickname: String, isMessage: Boolean = false)</ID>
<ID>NestedBlockDepth:Tell.kt$Tell$// Delete message. private fun deleteMessage(sender: String, args: String, isOp: Boolean, isPrivate: Boolean)</ID>
<ID>NestedBlockDepth:TellMessagesMgr.kt$TellMessagesMgr.Companion$ fun save(file: String, messages: List&lt;TellMessage?&gt;?, logger: Logger)</ID>
<ID>NestedBlockDepth:Weather2.kt$Weather2$ override fun run(sender: String, cmd: String, args: String, isPrivate: Boolean)</ID> <ID>NestedBlockDepth:Weather2.kt$Weather2$ override fun run(sender: String, cmd: String, args: String, isPrivate: Boolean)</ID>
<ID>NestedBlockDepth:Weather2.kt$Weather2.Companion$ @JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List&lt;Message&gt;</ID> <ID>NestedBlockDepth:Weather2.kt$Weather2.Companion$ @JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List&lt;Message&gt;</ID>
<ID>NestedBlockDepth:WorldTime.kt$WorldTime$override fun commandResponse( sender: String, cmd: String, args: String, isPrivate: Boolean )</ID> <ID>NestedBlockDepth:WorldTime.kt$WorldTime$override fun commandResponse( sender: String, cmd: String, args: String, isPrivate: Boolean )</ID>
@ -66,6 +71,7 @@
<ID>TooGenericExceptionCaught:FeedReader.kt$FeedReader$e: Exception</ID> <ID>TooGenericExceptionCaught:FeedReader.kt$FeedReader$e: Exception</ID>
<ID>TooGenericExceptionCaught:StockQuote.kt$StockQuote.Companion$e: NullPointerException</ID> <ID>TooGenericExceptionCaught:StockQuote.kt$StockQuote.Companion$e: NullPointerException</ID>
<ID>TooGenericExceptionCaught:Weather2.kt$Weather2.Companion$e: NullPointerException</ID> <ID>TooGenericExceptionCaught:Weather2.kt$Weather2.Companion$e: NullPointerException</ID>
<ID>TooManyFunctions:Tell.kt$Tell : AbstractCommand</ID>
<ID>TooManyFunctions:Utils.kt$Utils$Companion</ID> <ID>TooManyFunctions:Utils.kt$Utils$Companion</ID>
</CurrentIssues> </CurrentIssues>
</SmellBaseline> </SmellBaseline>

View file

@ -298,8 +298,12 @@ class Utils private constructor() {
* Returns the specified date formatted as `yyyy-MM-dd HH:mm`. * Returns the specified date formatted as `yyyy-MM-dd HH:mm`.
*/ */
@JvmStatic @JvmStatic
fun utcDateTime(date: LocalDateTime): String { fun utcDateTime(date: LocalDateTime?): String {
return date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) return if (date != null) {
date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
} else {
""
}
} }
} }
} }

View file

@ -1,393 +0,0 @@
/*
* Tell.java
*
* Copyright (c) 2004-2020, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell;
import net.thauvin.erik.mobibot.Mobibot;
import net.thauvin.erik.mobibot.Utils;
import net.thauvin.erik.mobibot.commands.AbstractCommand;
import net.thauvin.erik.mobibot.commands.links.View;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The <code>Tell</code> command.
*
* @author <a href="https://erik.thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2016-07-02
* @since 1.0
*/
public class Tell extends AbstractCommand {
/**
* Max days property.
*/
public static final String MAX_DAYS_PROP = "tell-max-days";
/**
* Max size proeprty.
*/
public static final String MAX_SIZE_PROP = "tell-max-size";
/**
* The tell command.
*/
public static final String TELL_CMD = "tell";
// Arrow
private static final String ARROW = " --> ";
// Serialized object file extension
private static final String SER_EXT = ".ser";
// All keyword
private static final String TELL_ALL_KEYWORD = "all";
//T he delete command.
private static final String TELL_DEL_KEYWORD = "del";
// Messages queue
private final List<TellMessage> messages = new CopyOnWriteArrayList<>();
// Serialized object file
private final String serializedObject;
// Maximum number of days to keep messages
private int maxDays = 7;
// Message maximum queue size
private int maxSize = 50;
/**
* Creates a new instance.
*
* @param bot The bot.
*/
public Tell(final Mobibot bot) {
super(bot);
initProperties(MAX_DAYS_PROP, MAX_SIZE_PROP);
// Load the message queue
serializedObject = bot.getLogsDir() + bot.getName() + SER_EXT;
messages.addAll(TellMessagesMgr.load(serializedObject, bot.getLogger()));
if (clean()) {
save();
}
}
/**
* Cleans the messages queue.
*
* @return <code>true</code> if the queue was cleaned.
*/
@SuppressWarnings("WeakerAccess")
final boolean clean() {
if (getBot().getLogger().isDebugEnabled()) {
getBot().getLogger().debug("Cleaning the messages.");
}
return TellMessagesMgr.clean(messages, maxDays);
}
// Delete message.
private void deleteMessage(final String sender, final String args, final boolean isOp, final boolean isPrivate) {
final String[] split = args.split(" ");
if (split.length == 2) {
final String id = split[1];
boolean deleted = false;
if (TELL_ALL_KEYWORD.equalsIgnoreCase(id)) {
for (final TellMessage message : messages) {
if (message.getSender().equalsIgnoreCase(sender) && message.isReceived()) {
messages.remove(message);
deleted = true;
}
}
if (deleted) {
save();
getBot().send(sender, "Delivered messages have been deleted.", isPrivate);
} else {
getBot().send(sender, "No delivered messages were found.", isPrivate);
}
} else {
boolean found = false;
for (final TellMessage message : messages) {
found = message.isMatchId(id);
if (found && (message.getSender().equalsIgnoreCase(sender) || getBot().isOp(sender))) {
messages.remove(message);
save();
getBot().send(sender, "Your message was deleted from the queue.", isPrivate);
deleted = true;
break;
}
}
if (!deleted) {
if (found) {
getBot().send(sender, "Only messages that you sent can be deleted.", isPrivate);
} else {
getBot().send(sender, "The specified message [ID " + id + "] could not be found.", isPrivate);
}
}
}
} else {
helpResponse(args, sender, isOp, isPrivate);
}
}
@NotNull
@Override
public String getName() {
return TELL_CMD;
}
@NotNull
@Override
public List<String> getHelp() {
return List.of("To send a message to someone when they join the channel:",
Utils.helpIndent("%c " + TELL_CMD + " <nick> <message>"),
"To view queued and sent messages:",
Utils.helpIndent("%c " + TELL_CMD + ' ' + View.VIEW_CMD),
"Messages are kept for " + Utils.bold(maxDays)
+ Utils.plural(maxDays, " day.", " days."));
}
@Override
public boolean isOp() {
return false;
}
@Override
public boolean isPublic() {
return isEnabled();
}
@Override
public boolean isVisible() {
return isEnabled();
}
@Override
public void commandResponse(@NotNull final String sender,
@NotNull final String login,
@NotNull final String args,
final boolean isOp,
final boolean isPrivate) {
if (isEnabled()) {
if (StringUtils.isBlank(args)) {
helpResponse(args, sender, isOp, isPrivate);
} else if (args.startsWith(View.VIEW_CMD)) {
if (getBot().isOp(sender) && (View.VIEW_CMD + ' ' + TELL_ALL_KEYWORD).equals(args)) {
viewAll(sender, isPrivate);
} else {
viewMessages(sender, isPrivate);
}
} else if (args.startsWith(TELL_DEL_KEYWORD + ' ')) {
deleteMessage(sender, args, isOp, isPrivate);
} else {
newMessage(sender, args, isOp, isPrivate);
}
if (clean()) {
save();
}
}
}
@Override
public boolean isEnabled() {
return maxSize > 0 && maxDays > 0;
}
@Override
public void setProperty(@NotNull final String key, @NotNull final String value) {
super.setProperty(key, value);
if (MAX_DAYS_PROP.equals(key)) {
this.maxDays = Utils.getIntProperty(value, maxDays);
} else if (MAX_SIZE_PROP.equals(key)) {
this.maxSize = Utils.getIntProperty(value, maxSize);
}
}
// New message.
private void newMessage(final String sender, final String args, final boolean isOp, final boolean isPrivate) {
final String[] split = args.split(" ", 2);
if (split.length == 2 && (StringUtils.isNotBlank(split[1]) && split[1].contains(" "))) {
if (messages.size() < maxSize) {
final TellMessage message = new TellMessage(sender, split[0], split[1].trim());
messages.add(message);
save();
getBot().send(sender, "Message [ID " + message.getId() + "] was queued for "
+ Utils.bold(message.getRecipient()), isPrivate);
} else {
getBot().send(sender, "Sorry, the messages queue is currently full.", isPrivate);
}
} else {
helpResponse(args, sender, isOp, isPrivate);
}
}
/**
* Saves the messages queue.
*/
@SuppressWarnings("WeakerAccess")
final void save() {
TellMessagesMgr.save(serializedObject, messages, getBot().getLogger());
}
/**
* Checks and sends messages.
*
* @param nickname The user's nickname.
* @param isMessage The message flag.
*/
public void send(final String nickname, final boolean isMessage) {
if (isEnabled() && !nickname.equals(getBot().getNick())) {
messages.stream().filter(message -> message.isMatch(nickname)).forEach(message -> {
if (message.getRecipient().equalsIgnoreCase(nickname) && !message.isReceived()) {
if (message.getSender().equals(nickname)) {
if (!isMessage) {
getBot().send(nickname, Utils.bold("You") + " wanted me to remind you: "
+ Utils.reverseColor(message.getMessage()),
true);
message.setIsReceived();
message.setIsNotified();
save();
}
} else {
getBot().send(nickname, message.getSender() + " wanted me to tell you: "
+ Utils.reverseColor(message.getMessage()),
true);
message.setIsReceived();
save();
}
} else if (message.getSender().equalsIgnoreCase(nickname) && message.isReceived()
&& !message.isNotified()) {
getBot().send(nickname,
"Your message "
+ Utils.reverseColor("[ID " + message.getId() + ']') + " was sent to "
+ Utils.bold(message.getRecipient()) + " on "
+ Utils.utcDateTime(message.getReceived()),
true);
message.setIsNotified();
save();
}
});
}
}
/**
* Checks and sends messages.
*
* @param nickname The user's nickname.
*/
public void send(final String nickname) {
send(nickname, false);
}
/**
* Returns the messages queue size.
*
* @return The size.
*/
public int size() {
return messages.size();
}
// View all messages.
private void viewAll(final String sender, final boolean isPrivate) {
if (!messages.isEmpty()) {
for (final TellMessage message : messages) {
getBot().send(sender, Utils.bold(message.getSender()) + ARROW + Utils.bold(message.getRecipient())
+ " [ID: " + message.getId() + ", "
+ (message.isReceived() ? "DELIVERED" : "QUEUED") + ']',
isPrivate);
}
} else {
getBot().send(sender, "There are no messages in the queue.", isPrivate);
}
}
// View messages.
private void viewMessages(final String sender, final boolean isPrivate) {
boolean hasMessage = false;
for (final TellMessage message : messages) {
if (message.isMatch(sender)) {
if (!hasMessage) {
hasMessage = true;
getBot().send(sender, "Here are your messages: ", isPrivate);
}
if (message.isReceived()) {
getBot().send(sender,
Utils.bold(message.getSender()) + ARROW + Utils.bold(message.getRecipient())
+ " [" + Utils.utcDateTime(message.getReceived()) + ", ID: "
+ Utils.bold(message.getId()) + ", DELIVERED]",
isPrivate);
} else {
getBot().send(sender,
Utils.bold(message.getSender()) + ARROW + Utils.bold(message.getRecipient())
+ " [" + Utils.utcDateTime(message.getQueued()) + ", ID: "
+ Utils.bold(message.getId()) + ", QUEUED]",
isPrivate);
}
getBot().send(sender, Utils.helpIndent(message.getMessage()), isPrivate);
}
}
if (!hasMessage) {
getBot().send(sender, "You have no messages in the queue.", isPrivate);
} else {
getBot().send(sender, "To delete one or all delivered messages:", isPrivate);
getBot().send(sender,
Utils.helpIndent(Utils.helpFormat(
"%c " + TELL_CMD + ' ' + TELL_DEL_KEYWORD + " <id|" + TELL_ALL_KEYWORD + '>',
getBot().getNick(),
isPrivate)),
isPrivate);
getBot().send(sender,
"Messages are kept for " + Utils.bold(maxDays)
+ Utils.plural(maxDays, " day.", " days."), isPrivate);
}
}
}

View file

@ -0,0 +1,362 @@
/*
* Tell.kt
*
* Copyright (c) 2004-2020, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell
import net.thauvin.erik.mobibot.Mobibot
import net.thauvin.erik.mobibot.Utils.Companion.bold
import net.thauvin.erik.mobibot.Utils.Companion.getIntProperty
import net.thauvin.erik.mobibot.Utils.Companion.helpFormat
import net.thauvin.erik.mobibot.Utils.Companion.helpIndent
import net.thauvin.erik.mobibot.Utils.Companion.plural
import net.thauvin.erik.mobibot.Utils.Companion.reverseColor
import net.thauvin.erik.mobibot.Utils.Companion.utcDateTime
import net.thauvin.erik.mobibot.commands.AbstractCommand
import net.thauvin.erik.mobibot.commands.links.View
import org.apache.commons.lang3.StringUtils
import java.util.concurrent.CopyOnWriteArrayList
/**
* The `Tell` command.
*/
class Tell(bot: Mobibot) : AbstractCommand(bot) {
// Messages queue
private val messages: MutableList<TellMessage> = CopyOnWriteArrayList()
// Serialized object file
private val serializedObject: String
// Maximum number of days to keep messages
private var maxDays = 7
// Message maximum queue size
private var maxSize = 50
/**
* Cleans the messages queue.
*/
private fun clean(): Boolean {
if (bot.logger.isDebugEnabled) {
bot.logger.debug("Cleaning the messages.")
}
return TellMessagesMgr.clean(messages, maxDays)
}
// Delete message.
private fun deleteMessage(sender: String, args: String, isOp: Boolean, isPrivate: Boolean) {
val split = args.split(" ").toTypedArray()
if (split.size == 2) {
val id = split[1]
var deleted = false
if (TELL_ALL_KEYWORD.equals(id, ignoreCase = true)) {
for (message in messages) {
if (message.sender.equals(sender, ignoreCase = true) && message.isReceived) {
messages.remove(message)
deleted = true
}
}
if (deleted) {
save()
bot.send(sender, "Delivered messages have been deleted.", isPrivate)
} else {
bot.send(sender, "No delivered messages were found.", isPrivate)
}
} else {
var found = false
for (message in messages) {
found = message.isMatchId(id)
if (found && (message.sender.equals(sender, ignoreCase = true) || bot.isOp(sender))) {
messages.remove(message)
save()
bot.send(sender, "Your message was deleted from the queue.", isPrivate)
deleted = true
break
}
}
if (!deleted) {
if (found) {
bot.send(sender, "Only messages that you sent can be deleted.", isPrivate)
} else {
bot.send(sender, "The specified message [ID $id] could not be found.", isPrivate)
}
}
}
} else {
helpResponse(args, sender, isOp, isPrivate)
}
}
/**
* The tell command.
*/
override val name = "tell"
override val help: List<String>
get() = listOf(
"To send a message to someone when they join the channel:",
helpIndent("%c $name <nick> <message>"),
"To view queued and sent messages:",
helpIndent("%c $name ${View.VIEW_CMD}"),
"Messages are kept for " + bold(maxDays)
+ plural(maxDays.toLong(), " day.", " days.")
)
override val isOp: Boolean
get() = false
override val isPublic: Boolean
get() = isEnabled()
override val isVisible: Boolean
get() = isEnabled()
override fun commandResponse(
sender: String,
login: String,
args: String,
isOp: Boolean,
isPrivate: Boolean
) {
if (isEnabled()) {
if (StringUtils.isBlank(args)) {
helpResponse(args, sender, isOp, isPrivate)
} else if (args.startsWith(View.VIEW_CMD)) {
if (bot.isOp(sender) && "${View.VIEW_CMD} $TELL_ALL_KEYWORD" == args) {
viewAll(sender, isPrivate)
} else {
viewMessages(sender, isPrivate)
}
} else if (args.startsWith("$TELL_DEL_KEYWORD ")) {
deleteMessage(sender, args, isOp, isPrivate)
} else {
newMessage(sender, args, isOp, isPrivate)
}
if (clean()) {
save()
}
}
}
override fun isEnabled(): Boolean {
return maxSize > 0 && maxDays > 0
}
override fun setProperty(key: String, value: String) {
super.setProperty(key, value)
if (MAX_DAYS_PROP == key) {
maxDays = getIntProperty(value, maxDays)
} else if (MAX_SIZE_PROP == key) {
maxSize = getIntProperty(value, maxSize)
}
}
// New message.
private fun newMessage(sender: String, args: String, isOp: Boolean, isPrivate: Boolean) {
val split = args.split(" ".toRegex(), 2).toTypedArray()
if (split.size == 2 && StringUtils.isNotBlank(split[1]) && split[1].contains(" ")) {
if (messages.size < maxSize) {
val message = TellMessage(sender, split[0], split[1].trim())
messages.add(message)
save()
bot.send(sender, "Message [ID ${message.id}] was queued for ${bold(message.recipient)}", isPrivate
)
} else {
bot.send(sender, "Sorry, the messages queue is currently full.", isPrivate)
}
} else {
helpResponse(args, sender, isOp, isPrivate)
}
}
/**
* Saves the messages queue.
*/
private fun save() {
TellMessagesMgr.save(serializedObject, messages, bot.logger)
}
/**
* Checks and sends messages.
*/
@JvmOverloads
fun send(nickname: String, isMessage: Boolean = false) {
if (isEnabled() && nickname != bot.nick) {
messages.stream().filter { message: TellMessage -> message.isMatch(nickname) }
.forEach { message: TellMessage ->
if (message.recipient.equals(nickname, ignoreCase = true) && !message.isReceived) {
if (message.sender == nickname) {
if (!isMessage) {
bot.send(
nickname,
"${bold("You")} wanted me to remind you: ${reverseColor(message.message)}",
true
)
message.isReceived = true
message.isNotified = true
save()
}
} else {
bot.send(
nickname,
"${message.sender} wanted me to tell you: ${reverseColor(message.message)}",
true
)
message.isReceived = true
save()
}
} else if (message.sender.equals(nickname, ignoreCase = true) && message.isReceived
&& !message.isNotified
) {
bot.send(
nickname,
"Your message ${reverseColor("[ID " + message.id + ']')} was sent to " +
"${bold(message.recipient)} on ${utcDateTime(message.receptionDate)}",
true
)
message.isNotified = true
save()
}
}
}
}
/**
* Returns the messages queue size.
*
* @return The size.
*/
fun size(): Int {
return messages.size
}
// View all messages.
private fun viewAll(sender: String, isPrivate: Boolean) {
if (messages.isNotEmpty()) {
for (message in messages) {
bot.send(
sender, bold(message.sender) + ARROW + bold(message.recipient)
+ " [ID: " + message.id + ", "
+ (if (message.isReceived) "DELIVERED" else "QUEUED") + ']',
isPrivate
)
}
} else {
bot.send(sender, "There are no messages in the queue.", isPrivate)
}
}
// View messages.
private fun viewMessages(sender: String, isPrivate: Boolean) {
var hasMessage = false
for (message in messages) {
if (message.isMatch(sender)) {
if (!hasMessage) {
hasMessage = true
bot.send(sender, "Here are your messages: ", isPrivate)
}
if (message.isReceived) {
bot.send(
sender,
bold(message.sender) + ARROW + bold(message.recipient)
+ " [" + utcDateTime(message.receptionDate) + ", ID: "
+ bold(message.id) + ", DELIVERED]",
isPrivate
)
} else {
bot.send(
sender,
bold(message.sender) + ARROW + bold(message.recipient)
+ " [" + utcDateTime(message.queued) + ", ID: "
+ bold(message.id) + ", QUEUED]",
isPrivate
)
}
bot.send(sender, helpIndent(message.message), isPrivate)
}
}
if (!hasMessage) {
bot.send(sender, "You have no messages in the queue.", isPrivate)
} else {
bot.send(sender, "To delete one or all delivered messages:", isPrivate)
bot.send(
sender,
helpIndent(
helpFormat(
"%c $name $TELL_DEL_KEYWORD <id|$TELL_ALL_KEYWORD>",
bot.nick,
isPrivate
)
),
isPrivate
)
bot.send(
sender,
"Messages are kept for ${bold(maxDays)}${plural(maxDays.toLong(), " day.", " days.")}",
isPrivate
)
}
}
companion object {
/**
* Max days property.
*/
const val MAX_DAYS_PROP = "tell-max-days"
/**
* Max size proeprty.
*/
const val MAX_SIZE_PROP = "tell-max-size"
// Arrow
private const val ARROW = " --> "
// Serialized object file extension
private const val SER_EXT = ".ser"
// All keyword
private const val TELL_ALL_KEYWORD = "all"
//T he delete command.
private const val TELL_DEL_KEYWORD = "del"
}
/**
* Creates a new instance.
*/
init {
initProperties(MAX_DAYS_PROP, MAX_SIZE_PROP)
// Load the message queue
serializedObject = bot.logsDir + bot.name + SER_EXT
messages.addAll(TellMessagesMgr.load(serializedObject, bot.logger))
if (clean()) {
save()
}
}
}

View file

@ -1,195 +0,0 @@
/*
* TellMessage.java
*
* Copyright (c) 2004-2019, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell;
import java.io.Serializable;
import java.time.Clock;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* The <code>TellMessage</code> class.
*
* @author <a href="https://erik.thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2014-04-24
* @since 1.0
*/
@SuppressWarnings("PMD.DataClass")
public class TellMessage implements Serializable {
private static final long serialVersionUID = 2L;
private final String id;
private final String message;
private final LocalDateTime queued;
private final String recipient;
private final String sender;
private boolean isNotified;
private boolean isReceived;
private LocalDateTime received;
/**
* Create a new message.
*
* @param sender The sender's nick.
* @param recipient The recipient's nick.
* @param message The message.
*/
TellMessage(final String sender, final String recipient, final String message) {
this.sender = sender;
this.recipient = recipient;
this.message = message;
this.queued = LocalDateTime.now(Clock.systemUTC());
this.id = this.queued.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
}
/**
* Returns the message id.
*
* @return The message id.
*/
public String getId() {
return id;
}
/**
* Returns the message text.
*
* @return The text of the message.
*/
public String getMessage() {
return message;
}
/**
* Returns the queued date/time.
*
* @return <code>true</code> if the message is queued.
*/
LocalDateTime getQueued() {
return queued;
}
/**
* Returns the state of the received flag.
*
* @return <code>true</code> if the message has been received.
*/
public LocalDateTime getReceived() {
return received;
}
/**
* Returns the message's recipient.
*
* @return The recipient of the message.
*/
String getRecipient() {
return recipient;
}
/**
* Returns the message's sender.
*
* @return The sender of the message.
*/
public String getSender() {
return sender;
}
/**
* Matches the message sender or recipient.
*
* @param nick The nickname to match with.
* @return <code>true</code> if the nickname matches.
*/
boolean isMatch(final String nick) {
return (sender.equalsIgnoreCase(nick) || recipient.equalsIgnoreCase(nick));
}
/**
* Match the message ID.
*
* @param id The ID to match with.
* @return <code>true</code> if the id matches.
*/
boolean isMatchId(final String id) {
return this.id.equals(id);
}
/**
* Returns the notification flag state.
*
* @return <code>true</code> if the sender has been notified.
*/
boolean isNotified() {
return isNotified;
}
/**
* Returns the received flag state.
*
* @return <code>true</code> if the message was received.
*/
public boolean isReceived() {
return isReceived;
}
/**
* Sets the notified flag.
*/
void setIsNotified() {
isNotified = true;
}
/**
* Sets the received flag.
*/
void setIsReceived() {
received = LocalDateTime.now(Clock.systemUTC());
isReceived = true;
}
@Override
public String toString() {
return "TellMessage{"
+ "id='" + id + '\''
+ ", isNotified=" + isNotified
+ ", isReceived=" + isReceived
+ ", message='" + message + '\''
+ ", queued=" + queued
+ ", received=" + received
+ ", recipient='" + recipient + '\''
+ ", sender='" + sender + '\''
+ '}';
}
}

View file

@ -0,0 +1,112 @@
/*
* TellMessage.kt
*
* Copyright (c) 2004-2019, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell
import java.io.Serializable
import java.time.Clock
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
/**
* The `TellMessage` class.
*/
class TellMessage internal constructor(
/**
* Returns the message's sender.
*/
val sender: String,
/**
* Returns the message's recipient.
*/
val recipient: String,
/**
* Returns the message text.
*/
val message: String
) : Serializable {
/**
* Returns the queued date/time.
*/
var queued: LocalDateTime = LocalDateTime.now(Clock.systemUTC())
/**
* Returns the message id.
*/
var id: String = queued.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
/**
* Returns {@code true) if a notification was send.
*/
var isNotified = false
/**
* Returns {@code true) if the message was received.
*/
var isReceived = false
set(value) {
if (value) {
receptionDate = LocalDateTime.now(Clock.systemUTC())
}
field = value
}
/**
* Return the message creating date.
*/
var receptionDate: LocalDateTime = LocalDateTime.MIN
/**
* Matches the message sender or recipient.
*/
fun isMatch(nick: String?): Boolean {
return sender.equals(nick, ignoreCase = true) || recipient.equals(nick, ignoreCase = true)
}
/**
* Match the message ID.
*/
fun isMatchId(id: String): Boolean {
return this.id == id
}
override fun toString(): String {
return ("TellMessage{id='$id', isNotified=$isNotified, isReceived=$isReceived, message='$message', " +
"queued=$queued, received=$receptionDate, recipient='$recipient', sender='$sender'}")
}
companion object {
private const val serialVersionUID = 2L
}
}

View file

@ -1,132 +0,0 @@
/*
* TellMessagesMgr.java
*
* Copyright (c) 2004-2020, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.logging.log4j.Logger;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Clock;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* The Tell Messages Manager.
*
* @author <a href="https://erik.thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2014-04-26
* @since 1.0
*/
final class TellMessagesMgr {
/**
* Disables the default constructor.
*
* @throws UnsupportedOperationException If the constructor is called.
*/
private TellMessagesMgr() {
throw new UnsupportedOperationException("Illegal constructor call.");
}
/**
* Cleans the messages queue.
*
* @param tellMessages The messages list.
* @param tellMaxDays The maximum number of days to keep messages for.
* @return <code>True</code> if the queue was cleaned.
*/
static boolean clean(final List<TellMessage> tellMessages, final int tellMaxDays) {
final LocalDateTime today = LocalDateTime.now(Clock.systemUTC());
return tellMessages.removeIf(o -> o.getQueued().plusDays(tellMaxDays).isBefore(today));
}
/**
* Loads the messages.
*
* @param file The serialized objects file.
* @param logger The logger.
* @return The {@link TellMessage} array.
*/
@SuppressWarnings("unchecked")
@SuppressFBWarnings("OBJECT_DESERIALIZATION")
public static List<TellMessage> load(final String file, final Logger logger) {
try {
try (final ObjectInput input = new ObjectInputStream(
new BufferedInputStream(Files.newInputStream(Paths.get(file))))) {
if (logger.isDebugEnabled()) {
logger.debug("Loading the messages.");
}
return ((List<TellMessage>) input.readObject());
}
} catch (FileNotFoundException ignore) {
// Do nothing
} catch (IOException | ClassNotFoundException e) {
logger.error("An error occurred loading the messages queue.", e);
}
return new ArrayList<>();
}
/**
* Saves the messages.
*
* @param file The serialized objects file.
* @param messages The {@link TellMessage} array.
* @param logger The logger.
*/
public static void save(final String file, final List<TellMessage> messages, final Logger logger) {
try {
try (final BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get(file)))) {
try (final ObjectOutput output = new ObjectOutputStream(bos)) {
if (logger.isDebugEnabled()) {
logger.debug("Saving the messages.");
}
output.writeObject(messages);
}
}
} catch (IOException e) {
logger.error("Unable to save messages queue.", e);
}
}
}

View file

@ -0,0 +1,104 @@
/*
* TellMessagesMgr.kt
*
* Copyright (c) 2004-2020, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell
import org.apache.logging.log4j.Logger
import java.time.LocalDateTime
import java.io.ObjectInputStream
import java.io.BufferedInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.lang.ClassNotFoundException
import java.io.BufferedOutputStream
import java.io.ObjectOutputStream
import java.nio.file.Files
import java.nio.file.Paths
import java.time.Clock
import java.util.ArrayList
/**
* The Tell Messages Manager.
*/
internal class TellMessagesMgr private constructor() {
companion object {
/**
* Cleans the messages queue.
*/
fun clean(tellMessages: MutableList<TellMessage>, tellMaxDays: Int): Boolean {
val today = LocalDateTime.now(Clock.systemUTC())
return tellMessages.removeIf { o: TellMessage -> o.queued.plusDays(tellMaxDays.toLong()).isBefore(today) }
}
/**
* Loads the messages.
*/
fun load(file: String, logger: Logger): List<TellMessage> {
try {
ObjectInputStream(
BufferedInputStream(Files.newInputStream(Paths.get(file)))
).use { input ->
if (logger.isDebugEnabled) {
logger.debug("Loading the messages.")
}
@Suppress("UNCHECKED_CAST")
return input.readObject() as List<TellMessage>
}
} catch (ignore: FileNotFoundException) {
// Do nothing
} catch (e: IOException) {
logger.error("An IO error occurred loading the messages queue.", e)
} catch (e: ClassNotFoundException) {
logger.error("An error occurred loading the messages queue.", e)
}
return ArrayList()
}
/**
* Saves the messages.
*/
fun save(file: String, messages: List<TellMessage?>?, logger: Logger) {
try {
BufferedOutputStream(Files.newOutputStream(Paths.get(file))).use { bos ->
ObjectOutputStream(bos).use { output ->
if (logger.isDebugEnabled) {
logger.debug("Saving the messages.")
}
output.writeObject(messages)
}
}
} catch (e: IOException) {
logger.error("Unable to save messages queue.", e)
}
}
}
}

View file

@ -1,81 +0,0 @@
/*
* TellMessageTest.java
*
* Copyright (c) 2004-2020, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell;
import org.testng.annotations.Test;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.Temporal;
import static org.assertj.core.api.Assertions.assertThat;
/**
* The <code>TellMessageTest</code> class.
*
* @author <a href="https://erik.thauvin.net/" target="_blank">Erik C. Thauvin</a>
* @created 2019-07-29
* @since 1.0
*/
public class TellMessageTest {
private boolean isValidDate(final Temporal date) {
return Duration.between(date, LocalDateTime.now()).toMinutes() < 1;
}
@Test
void testTellMessage() {
final String message = "Test message.";
final String recipient = "recipient";
final String sender = "sender";
final TellMessage tellMessage = new TellMessage(sender, recipient, message);
assertThat(tellMessage.getSender()).as(sender).isEqualTo(sender);
assertThat(tellMessage.getRecipient()).as(recipient).isEqualTo(recipient);
assertThat(tellMessage.getMessage()).as(message).isEqualTo(message);
assertThat(isValidDate(tellMessage.getQueued())).as("queued is valid date/time").isTrue();
assertThat(tellMessage.isMatch(sender)).as("match sender").isTrue();
assertThat(tellMessage.isMatch(recipient)).as("match recipient").isTrue();
assertThat(tellMessage.isMatch("foo")).as("foo is no match").isFalse();
assertThat(tellMessage.isMatchId(tellMessage.getId())).as("is match ID").isTrue();
tellMessage.setIsReceived();
assertThat(tellMessage.isReceived()).as("is received").isTrue();
assertThat(isValidDate(tellMessage.getReceived())).as("received is valid date/time").isTrue();
tellMessage.setIsNotified();
assertThat(tellMessage.isNotified()).as("is notified").isTrue();
}
}

View file

@ -0,0 +1,68 @@
/*
* TellMessageTest.kt
*
* Copyright (c) 2004-2020, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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 net.thauvin.erik.mobibot.commands.tell
import java.time.temporal.Temporal
import java.time.LocalDateTime
import org.assertj.core.api.Assertions
import org.testng.annotations.Test
import java.time.Duration
/**
* The `TellMessageTest` class.
*/
class TellMessageTest {
private fun isValidDate(date: Temporal): Boolean {
return Duration.between(date, LocalDateTime.now()).toMinutes() < 1
}
@Test
fun testTellMessage() {
val message = "Test message."
val recipient = "recipient"
val sender = "sender"
val tellMessage = TellMessage(sender, recipient, message)
Assertions.assertThat(tellMessage.sender).`as`(sender).isEqualTo(sender)
Assertions.assertThat(tellMessage.recipient).`as`(recipient).isEqualTo(recipient)
Assertions.assertThat(tellMessage.message).`as`(message).isEqualTo(message)
Assertions.assertThat(isValidDate(tellMessage.queued)).`as`("queued is valid date/time").isTrue
Assertions.assertThat(tellMessage.isMatch(sender)).`as`("match sender").isTrue
Assertions.assertThat(tellMessage.isMatch(recipient)).`as`("match recipient").isTrue
Assertions.assertThat(tellMessage.isMatch("foo")).`as`("foo is no match").isFalse
Assertions.assertThat(tellMessage.isMatchId(tellMessage.id)).`as`("is match ID").isTrue
tellMessage.isReceived = true
Assertions.assertThat(tellMessage.isReceived).`as`("is received").isTrue
Assertions.assertThat(isValidDate(tellMessage.receptionDate)).`as`("received is valid date/time").isTrue
tellMessage.isNotified = true
Assertions.assertThat(tellMessage.isNotified).`as`("is notified").isTrue
}
}