package com.atlassian.bitbucket.rest.util;

import com.google.gson.Gson;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doCallRealMethod;

@RunWith(MockitoJUnitRunner.class)
public class JsonStreamingOutputTest {

    private static final String TEST_PROJECT_NAME = "TEST Project";
    private static final String TEST_PROJECT_KEY = "TEST";

    @Mock
    private JsonStreamingOutput streamingOutput;

    @Before
    public void setUp() throws Exception {
        doCallRealMethod().when(streamingOutput).write((OutputStream) any());
        doAnswer(new Answer<Void>() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                final StatefulJsonWriter writer = (StatefulJsonWriter) invocation.getArguments()[0];
                writer.beginObject()
                    .name("name").value(TEST_PROJECT_NAME)
                    .name("key").value(TEST_PROJECT_KEY)
                    .endObject();
                return null;
            }
        }).when(streamingOutput).write((StatefulJsonWriter) any());
    }

    @Test
    public void testWrite() throws Exception {
        final ByteArrayOutputStream os = new ByteArrayOutputStream();
        streamingOutput.write(os);
        Project project = new Gson().fromJson(os.toString("UTF-8"), Project.class);
        assertNotNull(project);
        assertEquals(TEST_PROJECT_NAME, project.name);
        assertEquals(TEST_PROJECT_KEY, project.key);
    }

    public static class Project {
        public String key;
        public String name;
    }
}
