package com.atlassian.stash.internal.concurrent;

import com.atlassian.bitbucket.concurrent.PullRequestLock;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestRef;
import com.atlassian.bitbucket.repository.Repository;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class ClusterPullRequestLockTest extends AbstractLockTest {

    private PullRequestLock pullRequestLock;
    @Captor
    private ArgumentCaptor<String> lockNameCaptor;

    @Test
    public void testLockNameForIds()  {
        pullRequestLock = new ClusterPullRequestLock(lockService, "pr");

        assertEquals("test", pullRequestLock.withLock(1, 2L, TEST_OP));
        verify(lockService).getLockForName(lockNameCaptor.capture());

        String lockName = lockNameCaptor.getValue();
        assertTrue(lockName.endsWith("pr#1/2"));
    }

    @Test
    public void testLockNameForPullRequest()  {
        PullRequest pr = mock(PullRequest.class);
        Repository repo = mock(Repository.class);
        PullRequestRef toRef = mock(PullRequestRef.class);
        when(pr.getId()).thenReturn(9L);
        when(pr.getToRef()).thenReturn(toRef);
        when(toRef.getRepository()).thenReturn(repo);
        when(repo.getId()).thenReturn(7);
        pullRequestLock = new ClusterPullRequestLock(lockService, "pr");

        assertEquals("test", pullRequestLock.withLock(pr, TEST_OP));
        verify(lockService).getLockForName(lockNameCaptor.capture());

        String lockName = lockNameCaptor.getValue();
        assertTrue(lockName.endsWith("pr#7/9"));
    }
}
