/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.config.webapp.mvc;

import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.web.servlet.MvcResult;

import com.scytl.products.ov.config.commands.api.ConfigurationService;

/**
 * Test the controller with a mock verification card ID generator.
 * 
 * @see ConfigurationEngineControllerShould
 */

public class ConfigurationEngineControllerTest extends ConfigurationEngineControllerTestBase {
    @Autowired
    ConfigurationService configurationService;

    @Test
    public void precomputeManyItems() throws Exception {
        final int itemCount = 1_000;
        when(
            configurationService.createVerificationCardIdStream(ELECTION_EVENT_ID, VERIFICATION_CARD_SET_ID, itemCount))
                .thenReturn(createMockVerificationCardStream(itemCount));

        MvcResult result = runPrecomputeTest(itemCount);

        // Ensure that the right amount of items is generated.
        String expectedContent = createMockVerificationCardStream(itemCount).collect(
            Collectors.joining(ConfigurationEngineController.SEPARATOR)) + ConfigurationEngineController.SEPARATOR;
        assertThat(result.getResponse().getContentAsString(), equalTo(expectedContent));
    }

    /**
     * Create a stream of predictable values to simulate the output of the
     * ConfigurationService stream of verification card IDs.
     *
     * @param itemCount
     *            how many verification card IDs to produce
     * @return a stream with fake, predictable verification card IDs
     */
    private Stream<String> createMockVerificationCardStream(int itemCount) {
        return IntStream.range(0, itemCount).mapToObj(String::valueOf);
    }

    @Configuration
    @Import(ConfigurationEngineControllerTestBase.TestConfig.class)
    static class TestConfig {
        @Bean
        ConfigurationService configurationService() {
            return mock(ConfigurationService.class);
        }
    }
}
