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:
JW
2023-10-03 01:44:34 +02:00
parent 4690a75f20
commit e76703eae6
190 changed files with 25598 additions and 870 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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());
}
}

View File

@@ -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();
});
}
}

View File

@@ -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)
{
}
}
}