package com.ruoyi.app.pay;

import org.junit.jupiter.api.Test;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;

class PaymentCreateGuardServiceTest {

    @Test
    void usesSharedOrderLockWithWatchdogAndReleasesIt() {
        RedissonClient redisson = mock(RedissonClient.class);
        RLock lock = mock(RLock.class);
        when(redisson.getLock("lock:payment:create:DD-1")).thenReturn(lock);
        try {
            when(lock.tryLock(anyLong(), eq(java.util.concurrent.TimeUnit.SECONDS))).thenReturn(true);
        } catch (InterruptedException exception) {
            throw new AssertionError(exception);
        }
        when(lock.isHeldByCurrentThread()).thenReturn(true);
        PaymentCreateGuardService guard = new PaymentCreateGuardService(redisson);

        String result = guard.withLock("DD-1", () -> "done");

        assertEquals("done", result);
        try {
            verify(lock).tryLock(anyLong(), eq(java.util.concurrent.TimeUnit.SECONDS));
        } catch (InterruptedException exception) {
            throw new AssertionError(exception);
        }
        verify(lock).unlock();
    }
}
