mirror of
https://github.com/jwdeveloper/TikTokLiveJava.git
synced 2026-02-28 09:19:40 -05:00
Breaking changes:
'Gift': changed from class to enum, so now you can handle
incoming gifts in switch
`Events`
- new:
onGiftComboFinished
- Removed:
onGiftBrodcast
- Rename:
onGiftMessage -> onGift
onRoomPinMessage -> onRoomPin
onRoomMessage -> onRoom
onLinkMessage -> onLink
onBarrageMessage -> onBarrage
onPollMessage -> onPoll
onShopMessage -> onShop
onDetectMessage -> onDetect
`GiftManager`
added:
registerGift
findById
findByName
getGifts
removed:
getActiveGifts
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import io.github.jwdeveloper.tiktok.common.TikTokBaseTest;
|
||||
import io.github.jwdeveloper.tiktok.messages.*;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ParseMessagesTests extends TikTokBaseTest
|
||||
{
|
||||
|
||||
|
||||
@Test
|
||||
public void ShouldParseMessageWebcastLikeMessage() throws InvalidProtocolBufferException {
|
||||
var bytes = getFileBytesUtf("LikeMessage.bin");
|
||||
var message = WebcastLikeMessage.parseFrom(bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ShouldParseMessageWebcastGiftMessage() throws InvalidProtocolBufferException {
|
||||
var bytes = getFileBytesUtf("MessageWebcastGiftMessage.bin");
|
||||
var message = WebcastGiftMessage.parseFrom(bytes);
|
||||
}
|
||||
@Test
|
||||
public void ShouldParseMessageWebcastChatMessage() throws InvalidProtocolBufferException {
|
||||
var bytes = getFileBytesUtf("MessageWebcastChatMessage.bin");
|
||||
var message = WebcastChatMessage.parseFrom(bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ShouldParseMessageWebcastImDeleteMessage() throws InvalidProtocolBufferException {
|
||||
var bytes = getFileBytesUtf("MessageWebcastImDeleteMessage.bin");
|
||||
var message = WebcastImDeleteMessage.parseFrom(bytes);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ShouldParseMessageWebcastSocialMessage() throws InvalidProtocolBufferException {
|
||||
var bytes = getFileBytesUtf("MessageWebcastSocialMessage.bin");
|
||||
var message = WebcastSocialMessage.parseFrom(bytes);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void ShouldParseMessageWebcastMemberMessage() throws InvalidProtocolBufferException {
|
||||
var bytes = getFileBytesUtf("WebcastMemberMessage.bin");
|
||||
var message = WebcastMemberMessage.parseFrom(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package io.github.jwdeveloper.tiktok;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.common.TikTokBaseTest;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokMessageHandlerRegistration;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
public class WebResponseHandlerTests extends TikTokBaseTest {
|
||||
public static TikTokMessageHandlerRegistration sut;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
var mockEventHandler = mock(TikTokEventObserver.class);
|
||||
var mockGiftManager = mock(TikTokGiftManager.class);
|
||||
var mockRoomInfo = mock(TikTokRoomInfo.class);
|
||||
var mockClientSettings = mock(ClientSettings.class);
|
||||
var mockLogger = mock(Logger.class);
|
||||
sut = new TikTokMessageHandlerRegistration(mockEventHandler,mockClientSettings,mockLogger, mockGiftManager, mockRoomInfo);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.common;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.gifts;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.events.objects.Gift;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
|
||||
public class TikTokGiftManagerTest
|
||||
{
|
||||
|
||||
@InjectMocks
|
||||
TikTokGiftManager giftManager;
|
||||
|
||||
@Test
|
||||
void registerGift()
|
||||
{
|
||||
var fakeGift = giftManager.registerGift(123,"Fake gift",123123);
|
||||
var gifts = giftManager.getGifts();
|
||||
var optional = gifts.stream().filter(r -> r == fakeGift).findFirst();
|
||||
Assertions.assertTrue(optional.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findById()
|
||||
{
|
||||
var target = giftManager.registerGift(123,"FAKE",123123);
|
||||
var result = giftManager.findById(target.getId());
|
||||
Assertions.assertEquals(target,result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByName()
|
||||
{
|
||||
var target = giftManager.registerGift(123,"FAKE",123123);
|
||||
var result = giftManager.findByName(target.getName());
|
||||
Assertions.assertEquals(target,result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGifts()
|
||||
{
|
||||
Assertions.assertEquals(Gift.values().length, giftManager.getGifts().size());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,45 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.http;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import org.junit.Test;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.github.jwdeveloper.tiktok.ClientSettings;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveRequestException;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveRoomMeta;
|
||||
import io.github.jwdeveloper.tiktok.mappers.LiveRoomMetaMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Scanner;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class TikTokApiServiceTest {
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class TikTokApiServiceTest
|
||||
{
|
||||
@Mock
|
||||
TikTokHttpClient tiktokHttpClient;
|
||||
|
||||
@Mock
|
||||
Logger logger;
|
||||
|
||||
@Mock
|
||||
ClientSettings clientSettings;
|
||||
|
||||
@InjectMocks
|
||||
TikTokApiService tikTokApiService;
|
||||
|
||||
@Test
|
||||
public void testFetchAvailableGifts() {
|
||||
// Arrange
|
||||
/* var mockApiClient = mock(TikTokHttpApiClient.class);
|
||||
var mockLogger = mock(Logger.class);
|
||||
var clientParams = new HashMap<String,Object>();
|
||||
var tikTokApiService = new TikTokApiService(mockApiClient, mockLogger, clientParams);
|
||||
void updateSessionId_NullSessionId_DoesNotSetSessionId() {
|
||||
when(clientSettings.getSessionId()).thenReturn(null);
|
||||
|
||||
var inputStream = getClass().getClassLoader().getResourceAsStream("gifts.json");
|
||||
String jsonContent;
|
||||
try (var scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name())) {
|
||||
jsonContent = scanner.useDelimiter("\\A").next(); // Read entire content
|
||||
}
|
||||
var json = JsonParser.parseString(jsonContent);
|
||||
var jsonObject = json.getAsJsonObject();
|
||||
tikTokApiService.updateSessionId();
|
||||
|
||||
when(mockApiClient.GetJObjectFromWebcastAPI("gift/list/", clientParams))
|
||||
.thenReturn(jsonObject);
|
||||
|
||||
var gifts = tikTokApiService.fetchAvailableGifts();
|
||||
|
||||
|
||||
assertNotNull(gifts);*/
|
||||
verify(tiktokHttpClient, times(0)).setSessionId(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateSessionId_EmptySessionId_DoesNotSetSessionId() {
|
||||
when(clientSettings.getSessionId()).thenReturn("");
|
||||
|
||||
tikTokApiService.updateSessionId();
|
||||
|
||||
verify(tiktokHttpClient, times(0)).setSessionId(anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateSessionId_ValidSessionId_SetsSessionId() {
|
||||
when(clientSettings.getSessionId()).thenReturn("validSessionId");
|
||||
|
||||
tikTokApiService.updateSessionId();
|
||||
|
||||
verify(tiktokHttpClient, times(1)).setSessionId("validSessionId");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendMessage_EmptySessionId_ThrowsException() {
|
||||
assertThrows(TikTokLiveException.class, () -> {
|
||||
tikTokApiService.sendMessage("some message", "");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendMessage_NullRoomId_ThrowsException() {
|
||||
when(clientSettings.getClientParameters()).thenReturn(new HashMap<>());
|
||||
|
||||
assertThrows(TikTokLiveException.class, () -> {
|
||||
tikTokApiService.sendMessage("some message", "someSessionId");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void fetchRoomId_ValidResponse_ReturnsRoomId() throws Exception {
|
||||
String expectedRoomId = "123456";
|
||||
String htmlResponse = "room_id=" + expectedRoomId ;
|
||||
when(tiktokHttpClient.getLivestreamPage(anyString())).thenReturn(htmlResponse);
|
||||
|
||||
String roomId = tikTokApiService.fetchRoomId("username");
|
||||
|
||||
assertEquals(expectedRoomId, roomId);
|
||||
verify(clientSettings.getClientParameters()).put("room_id", expectedRoomId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fetchRoomId_ExceptionThrown_ThrowsTikTokLiveRequestException() throws Exception {
|
||||
when(tiktokHttpClient.getLivestreamPage(anyString())).thenThrow(new Exception("some exception"));
|
||||
|
||||
assertThrows(TikTokLiveRequestException.class, () -> {
|
||||
tikTokApiService.fetchRoomId("username");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void fetchRoomInfo_ValidResponse_ReturnsLiveRoomMeta() throws Exception {
|
||||
HashMap<String, Object> clientParameters = new HashMap<>();
|
||||
var mockResponse = new JsonObject(); // Assume JsonObject is from the Gson library
|
||||
var expectedLiveRoomMeta = new LiveRoomMeta(); // Assume LiveRoomMeta is a simple POJO
|
||||
|
||||
when(clientSettings.getClientParameters()).thenReturn(clientParameters);
|
||||
when(tiktokHttpClient.getJObjectFromWebcastAPI(anyString(), any())).thenReturn(mockResponse);
|
||||
when(new LiveRoomMetaMapper().mapFrom(mockResponse)).thenReturn(expectedLiveRoomMeta); // Assuming LiveRoomMetaMapper is a simple mapper class
|
||||
|
||||
LiveRoomMeta liveRoomMeta = tikTokApiService.fetchRoomInfo();
|
||||
|
||||
assertEquals(expectedLiveRoomMeta, liveRoomMeta);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fetchRoomInfo_ExceptionThrown_ThrowsTikTokLiveRequestException() throws Exception {
|
||||
when(tiktokHttpClient.getJObjectFromWebcastAPI(anyString(), any())).thenThrow(new Exception("some exception"));
|
||||
|
||||
assertThrows(TikTokLiveRequestException.class, () -> {
|
||||
tikTokApiService.fetchRoomInfo();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2023 jwdeveloper jacekwoln@gmail.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package io.github.jwdeveloper.tiktok.listener;
|
||||
|
||||
import io.github.jwdeveloper.tiktok.annotations.TikTokEventHandler;
|
||||
import io.github.jwdeveloper.tiktok.events.TikTokEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokGiftEvent;
|
||||
import io.github.jwdeveloper.tiktok.events.messages.TikTokJoinEvent;
|
||||
import io.github.jwdeveloper.tiktok.exceptions.TikTokLiveException;
|
||||
import io.github.jwdeveloper.tiktok.handlers.TikTokEventObserver;
|
||||
import io.github.jwdeveloper.tiktok.live.LiveClient;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
class TikTokListenersManagerTest {
|
||||
|
||||
private TikTokEventObserver eventObserver;
|
||||
private TikTokListenersManager tikTokListenersManager;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
eventObserver = Mockito.mock(TikTokEventObserver.class);
|
||||
List<TikTokEventListener> listeners = new ArrayList<>();
|
||||
tikTokListenersManager = new TikTokListenersManager(listeners, eventObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addListener() {
|
||||
TikTokEventListener listener =new TikTokEventListenerTest();
|
||||
tikTokListenersManager.addListener(listener);
|
||||
|
||||
List<TikTokEventListener> listeners = tikTokListenersManager.getListeners();
|
||||
assertEquals(1, listeners.size());
|
||||
assertSame(listener, listeners.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void addListener_alreadyRegistered_throwsException() {
|
||||
TikTokEventListener listener = new TikTokEventListenerTest();
|
||||
tikTokListenersManager.addListener(listener);
|
||||
|
||||
Exception exception = assertThrows(TikTokLiveException.class, () -> {
|
||||
tikTokListenersManager.addListener(listener);
|
||||
});
|
||||
|
||||
assertEquals("Listener " + listener.getClass() + " has already been registered", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeListener() {
|
||||
TikTokEventListener listener = new TikTokEventListenerTest();
|
||||
tikTokListenersManager.addListener(listener);
|
||||
tikTokListenersManager.removeListener(listener);
|
||||
|
||||
List<TikTokEventListener> listeners = tikTokListenersManager.getListeners();
|
||||
assertTrue(listeners.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeListener_notRegistered_doesNotThrow() {
|
||||
TikTokEventListener listener = new TikTokEventListenerTest();
|
||||
assertDoesNotThrow(() -> tikTokListenersManager.removeListener(listener));
|
||||
}
|
||||
|
||||
|
||||
public static class TikTokEventListenerTest implements TikTokEventListener
|
||||
{
|
||||
@TikTokEventHandler
|
||||
public void onJoin(LiveClient client, TikTokJoinEvent joinEvent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onGift(LiveClient client, TikTokGiftEvent giftMessageEvent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@TikTokEventHandler
|
||||
public void onEvent(LiveClient client, TikTokEvent event)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user