/*
 * Copyright (c) 2013 ITOCHU Techno-Solutions Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jp.co.ctc_g.jse.csv.showcase.presentation.resources;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.File;

import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import jp.co.ctc_g.jfw.test.unit.FileInitailize;
import jp.co.ctc_g.jse.core.csv.DownloadFile;
import jp.co.ctc_g.jse.core.rest.jersey.config.JerseyConfigs;
import jp.co.ctc_g.jse.csv.showcase.business.service.UserProfileService;

import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;
import org.hamcrest.CoreMatchers;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mockito;

public class UserProfileResourceTest extends JerseyTest {

    public static UserProfileService mock = Mockito.mock(UserProfileService.class);

    @Rule
    public FileInitailize file = new FileInitailize(UserProfileResourceTest.class);
    
    public class MockBinder extends AbstractBinder {
        @Override
        protected void configure() {
            bind(mock).to(UserProfileService.class);
        }
    }

    @Override
    protected Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);
        return new ResourceConfig().register(UserProfileResource.class)
            .register(new MockBinder())
            .register(JacksonFeature.class)
            .register(MultiPartFeature.class)
            .registerClasses(JerseyConfigs.getExcpetionMappers());
    }

    @Override
    protected void configureClient(ClientConfig config) {
        config.register(JacksonFeature.class)
        .register(MultiPartFeature.class);
    }

    @Test
    public void ファイルアップロードのAPIを実行できる() throws Exception {
        File f = file.copy("test.csv", "temp.csv");
        FormDataBodyPart filePart = new FileDataBodyPart("file", f);
        FormDataMultiPart multipart = new FormDataMultiPart();
        multipart.bodyPart(filePart);
        Response response = target("profile").request().post(Entity.entity(multipart, multipart.getMediaType()));
        String entity = response.readEntity(String.class);
        assertThat(response, CoreMatchers.notNullValue());
        assertThat(response.getStatus(), is(200));
        assertThat(entity, is("success"));
    }

    @Test
    public void ファイルダウンロードのAPIを実行できる() throws Exception {
        File newFile = file.copy("test.csv", "temp.csv");
        DownloadFile f = new DownloadFile(newFile.toURI().getPath());
        when(mock.print()).thenReturn(f);
        Response response = target("profile").request().accept(MediaType.APPLICATION_OCTET_STREAM).get();
        verify(mock).print();
        assertThat(response, notNullValue());
        assertThat(response.getStatus(), is(200));
        String readEntity = response.readEntity(String.class);
        assertThat(readEntity, is(file.load("test.csv")));
    }
}
