package vip.mate.channel.wecom;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import vip.mate.channel.ChannelMessageRouter;
import vip.mate.channel.model.ChannelEntity;
import vip.mate.channel.notification.ApprovalNotificationService;
import vip.mate.channel.wecom.cards.WeComCardDispatcher;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.jupiter.api.Assertions.*;
/**
* Exercises the chunk-content dedup added to
* {@link WeComChannelAdapter#replyStream(String, String, String, boolean, String)}
* (RFC-32 §2.1.3). Without dedup, every token-level update during tool
* argument streaming would emit a fresh frame even when the visible
* content didn't change — flickering the IM client.
*
*
Run pattern: drop {@code sendFrame} into a queue so we can count
* how many frames actually went out for a given content sequence,
* without touching a real WebSocket.
*/
class ReplyStreamDedupTest {
private TestableAdapter adapter;
private LinkedBlockingQueue