package com.atlassian.bitbucket.web.conditions;

import com.atlassian.stash.internal.repository.InternalRepository;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.RepositoryCloneLinksRequest;
import com.atlassian.bitbucket.repository.RepositoryService;
import com.atlassian.bitbucket.permission.PermissionService;
import com.atlassian.bitbucket.util.NamedLink;
import com.atlassian.bitbucket.util.SimpleNamedLink;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Collections;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class CanCloneRepositoryConditionTest {

    private Map<String, Object> CONTEXT = Collections.<String, Object>singletonMap(
            "repository", new InternalRepository.Builder().id(1).name("repository").scmId("scm").build());

    @InjectMocks
    private CanCloneRepositoryCondition condition;
    @Mock
    private PermissionService permissionService;
    @Mock
    private RepositoryService repositoryService;

    @Before
    public void setup() {
        NamedLink cloneUrl = new SimpleNamedLink("some-clone-url", "cloneUrl");

        when(permissionService.isRepositoryAccessible(any(Repository.class))).thenReturn(true);
        when(repositoryService.getCloneLinks(any(RepositoryCloneLinksRequest.class))).thenReturn(Collections.singleton(cloneUrl));
    }

    @Test
    public void testNullRepository() {
        assertThat("Should not display if no repository in context",
                condition.shouldDisplay(Collections.<String, Object>emptyMap()), is(false));
    }

    @Test
    public void testRepositoryInaccessible() {
        when(permissionService.isRepositoryAccessible(any(Repository.class))).thenReturn(false);
        assertThat("Should not be able to clone the repository if no clone links are available",
                condition.shouldDisplay(CONTEXT), is(false));
    }

    @Test
    public void testNoCloneUrlsProvided() {
        when(repositoryService.getCloneLinks(any(RepositoryCloneLinksRequest.class))).thenReturn(Collections.<NamedLink>emptySet());
        assertThat("Should not be able to clone the repository if no clone links are available",
                condition.shouldDisplay(CONTEXT), is(false));
    }

    @Test
    public void testCloneUrlsProvided() {
        assertThat("Should be able to clone the repository if clone links are available",
                condition.shouldDisplay(CONTEXT), is(true));
    }
}
