Skip to content

Commit

Permalink
Add Duration overload and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MinnDevelopment committed Sep 22, 2024
1 parent 05580ad commit 8c3ad3e
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 1 deletion.
25 changes: 24 additions & 1 deletion src/main/java/net/dv8tion/jda/api/utils/FileUpload.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Base64;
import java.util.function.Supplier;

Expand Down Expand Up @@ -363,6 +364,28 @@ public FileUpload setDescription(@Nullable String description)
return this;
}

/**
* Turns this attachment into a voice message with the provided waveform.
*
* @param mediaType
* The audio type for the attached audio file. Should be {@code audio/ogg} or similar.
* @param waveform
* The waveform of the audio, which is a low frequency sampling up to 256 bytes.
* @param duration
* The actual duration of the audio data.
*
* @throws IllegalArgumentException
* If null is provided or the waveform is not between 1 and 256 bytes long.
*
* @return The same FileUpload instance configured as a voice message attachment
*/
@Nonnull
public FileUpload asVoiceMessage(@Nonnull MediaType mediaType, @Nonnull byte[] waveform, @Nonnull Duration duration)
{
Checks.notNull(duration, "Duration");
return this.asVoiceMessage(mediaType, waveform, duration.toNanos() / 1_000_000_000.0);
}

/**
* Turns this attachment into a voice message with the provided waveform.
*
Expand Down Expand Up @@ -479,7 +502,7 @@ public DataObject toAttachmentData(int index)
DataObject attachment = DataObject.empty()
.put("id", index)
.put("description", description == null ? "" : description)
.put("content_type", mediaType)
.put("content_type", mediaType.toString())
.put("filename", name);
if (waveform != null && durationSeconds > 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import net.dv8tion.jda.api.utils.data.DataObject;
import net.dv8tion.jda.internal.requests.Requester;
import net.dv8tion.jda.internal.utils.EncodingUtil;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import org.jetbrains.annotations.Contract;
import org.mockito.ThrowingConsumer;

Expand Down Expand Up @@ -74,6 +76,21 @@ public RestActionAssertions checkAssertions(@Nonnull ThrowingConsumer<Request<?>
return this;
}

@CheckReturnValue
@Contract("->this")
public RestActionAssertions hasMultipartBody()
{
return checkAssertions(request -> {
RequestBody body = request.getBody();
assertThat(body).isNotNull();
MediaType mediaType = body.contentType();
assertThat(mediaType).isNotNull();

assertThat(mediaType.toString())
.startsWith("multipart/form-data; boundary=");
});
}

@CheckReturnValue
@Contract("_->this")
public RestActionAssertions hasBodyEqualTo(@Nonnull DataObject expected)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,30 @@
import net.dv8tion.jda.api.utils.messages.MessagePollData;
import net.dv8tion.jda.internal.requests.restaction.MessageCreateActionImpl;
import net.dv8tion.jda.test.IntegrationTest;
import okhttp3.MediaType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;

import javax.annotation.Nonnull;
import java.time.Duration;
import java.util.Base64;
import java.util.EnumSet;
import java.util.concurrent.TimeUnit;

import static net.dv8tion.jda.api.requests.Method.POST;
import static net.dv8tion.jda.test.restaction.MessageCreateActionTest.Data.emoji;
import static net.dv8tion.jda.test.restaction.MessageCreateActionTest.Data.pollAnswer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.mockito.Mockito.when;

public class MessageCreateActionTest extends IntegrationTest
{
private static final byte[] voiceMessageAudio = {1, 2, 3};
private static final String voiceMessageMediaType = "audio/ogg";
private static final String voiceMessageFilename = "voice-message.ogg";

private static final String FIXED_CHANNEL_ID = "1234567890";
private static final String FIXED_NONCE = "123456";
private static final String ENDPOINT_URL = "channels/" + FIXED_CHANNEL_ID + "/messages";
Expand Down Expand Up @@ -142,6 +150,49 @@ void testPollOnly()
.whenQueueCalled();
}

@Test
void testSendVoiceMessage()
{
MessageCreateActionImpl action = new MessageCreateActionImpl(channel);

FileUpload file = Data.getVoiceMessageFileUpload(voiceMessageAudio, voiceMessageFilename, voiceMessageMediaType);

assertThat(file.isVoiceMessage()).isTrue();

action.addFiles(file);

assertThatRequestFrom(action)
.hasMultipartBody()
.hasBodyEqualTo(
defaultMessageRequest()
.put("flags", 1 << 13)
.put("attachments", DataArray.empty()
.add(Data.getVoiceMessageAttachmentBody(voiceMessageMediaType, voiceMessageFilename, voiceMessageAudio)))
).whenQueueCalled();
}

@Test
void testSuppressVoiceMessage()
{
MessageCreateActionImpl action = new MessageCreateActionImpl(channel);

FileUpload file = Data.getVoiceMessageFileUpload(voiceMessageAudio, voiceMessageFilename, voiceMessageMediaType);

assertThat(file.isVoiceMessage()).isTrue();

action.addFiles(file);
action.setVoiceMessage(false);

assertThatRequestFrom(action)
.hasMultipartBody()
.hasBodyEqualTo(
defaultMessageRequest()
.put("flags", 0)
.put("attachments", DataArray.empty()
.add(Data.getVoiceMessageAttachmentBody(voiceMessageMediaType, voiceMessageFilename, voiceMessageAudio)))
).whenQueueCalled();
}

@Test
void testFullFromBuilder()
{
Expand Down Expand Up @@ -169,6 +220,23 @@ protected DataObject normalizeRequestBody(@Nonnull DataObject body)

static class Data
{
static FileUpload getVoiceMessageFileUpload(byte[] fakeAudio, String fileName, String audioMediaType)
{
return FileUpload.fromData(fakeAudio, fileName)
.asVoiceMessage(MediaType.parse(audioMediaType), fakeAudio, Duration.ofSeconds(3));
}

static DataObject getVoiceMessageAttachmentBody(String audioMediaType, String fileName, byte[] fakeAudio)
{
return DataObject.empty()
.put("description", "")
.put("content_type", audioMediaType)
.put("duration_secs", 3.0)
.put("filename", fileName)
.put("id", 0)
.put("waveform", new String(Base64.getEncoder().encode(fakeAudio)));
}

static DataObject pollAnswer(long id, String title, DataObject emoji)
{
return DataObject.empty()
Expand Down

0 comments on commit 8c3ad3e

Please sign in to comment.