package com.atlassian.stash.internal.web.util.captcha;

import com.octo.captcha.Captcha;
import com.octo.captcha.engine.CaptchaEngine;
import com.octo.captcha.service.captchastore.CaptchaStore;
import org.junit.Before;
import org.junit.Test;

import java.util.Locale;

import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;

public class ClusteredManageableImageCaptchaServiceTest {

    private static final String ID = "captcha-id";
    private static final Locale LOCALE = Locale.CANADA;

    private Captcha captcha;
    private ClusteredManageableImageCaptchaService service;
    private CaptchaStore store;

    @Before
    public void setup() {
        CaptchaEngine engine = new StashCaptchaEngine();
        captcha = engine.getNextCaptcha();
        store = mock(CaptchaStore.class);
        when(store.getCaptcha(ID)).thenReturn(captcha);
        when(store.getLocale(ID)).thenReturn(LOCALE);

        service = new ClusteredManageableImageCaptchaService(store, engine, 100, 100, 100);
    }

    @Test
    public void testGetChallengeForExistingChallengedCaptchaRegeneratesCaptcha() {
        captcha.getChallenge(); // sets the 'hasChallengeBeenCalled' flag
        Object challenge = service.getChallengeForID(ID, LOCALE);

        assertNotNull(challenge);
        verify(store, times(2)).storeCaptcha(eq(ID), any(Captcha.class), eq(LOCALE));
    }

    @Test
    public void testGetChallengeForExistingUnchallengedCaptchaStoresCaptchaAgain() {
        Object challenge = service.getChallengeForID(ID, LOCALE);

        assertNotNull(challenge);
        verify(store).storeCaptcha(eq(ID), any(Captcha.class), eq(LOCALE));
    }

    @Test
    public void testGetChallengeGeneratesForUnknown() {
        Object challenge = service.getChallengeForID("unknown", LOCALE);

        assertNotNull(challenge);
        verify(store, times(2)).storeCaptcha(eq("unknown"), any(Captcha.class), eq(LOCALE));
    }
}
