/*
* Copyright 2016-2017 the original author or authors.
*
* 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 org.example;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import griffon.inject.BindTo;
import griffon.javafx.test.GriffonTestFXRule;
import griffon.javafx.test.WindowMatchers;
import javafx.scene.control.Button;
import org.example.api.GithubAPI;
import org.example.api.Repository;
import org.junit.FixMethodOrder;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.testfx.service.support.WaitUntilSupport;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Collection;
import java.util.List;
import java.util.stream.IntStream;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static java.util.stream.Collectors.toList;
import static org.testfx.api.FxAssert.verifyThat;
import static org.testfx.matcher.base.NodeMatchers.isEnabled;
import static org.testfx.matcher.control.LabeledMatchers.hasText;
import static org.testfx.matcher.control.ListViewMatchers.hasItems;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ReactiveIntegration2Test {
private static final String ORGANIZATION = "foo";
@Rule
public WireMockRule wireMockRule = new WireMockRule(8080);
@Rule
public GriffonTestFXRule testfx = new GriffonTestFXRule("mainWindow");
@Inject private ObjectMapper objectMapper;
@Test
public void _01_happy_path() {
// given:
List<Repository> repositories = createSampleRepositories();
stubFor(get(urlEqualTo("/orgs/" + ORGANIZATION + "/repos"))
.willReturn(aResponse()
.withFixedDelay(200)
.withStatus(200)
.withHeader("Content-Type", "text/json")
.withBody(repositoriesAsJSON(repositories, objectMapper))));
// when:
testfx.clickOn("#organization")
.eraseText(ORGANIZATION.length())
.write(ORGANIZATION);
// when:
testfx.clickOn("#loadActionTarget");
// wait
Button loadButton = testfx.lookup("#loadActionTarget").query();
new WaitUntilSupport().waitUntil(loadButton, isEnabled(), 10);
// then:
verifyThat("#total", hasText("10"));
verifyThat("#repositories", hasItems(10));
}
@Test
public void _02_cancel_path() throws Exception {
// given:
String nextUrl = "/organizations/1/repos?page=2";
List<Repository> repositories = createSampleRepositories();
stubFor(get(urlEqualTo("/orgs/" + ORGANIZATION + "/repos"))
.willReturn(aResponse()
.withFixedDelay(200)
.withStatus(200)
.withHeader("Content-Type", "text/json")
.withHeader("Link", "<http://localhost:8080" + nextUrl + ">; rel=\"next\"")
.withBody(repositoriesAsJSON(repositories.subList(0, 5), objectMapper))));
stubFor(get(urlEqualTo(nextUrl))
.willReturn(aResponse()
.withFixedDelay(200)
.withStatus(200)
.withHeader("Content-Type", "text/json")
.withBody(repositoriesAsJSON(repositories.subList(5, 10), objectMapper))));
// when:
testfx.clickOn("#organization")
.eraseText(ORGANIZATION.length())
.write(ORGANIZATION);
testfx.clickOn("#loadActionTarget");
testfx.clickOn("#cancelActionTarget");
// wait
Button loadButton = testfx.lookup("#loadActionTarget").query();
new WaitUntilSupport().waitUntil(loadButton, isEnabled(), 2);
// then:
verifyThat("#total", hasText("5"));
verifyThat("#repositories", hasItems(5));
}
@Test
public void _03_failure_path() {
// given:
String nextUrl = "/organizations/1/repos?page=2";
stubFor(get(urlEqualTo("/orgs/" + ORGANIZATION + "/repos"))
.willReturn(aResponse()
.withFixedDelay(200)
.withStatus(200)
.withHeader("Content-Type", "text/json")
.withHeader("Link", "<http://localhost:8080" + nextUrl + ">; rel=\"next\"")
.withBody(repositoriesAsJSON(createSampleRepositories().subList(0, 5), objectMapper))));
stubFor(get(urlEqualTo(nextUrl))
.willReturn(aResponse()
.withFixedDelay(200)
.withStatus(500)
.withStatusMessage("Internal Error")));
// when:
testfx.clickOn("#organization")
.eraseText(ORGANIZATION.length())
.write(ORGANIZATION);
testfx.clickOn("#loadActionTarget");
// then:
new WaitUntilSupport().waitUntil(testfx.window("Error"), WindowMatchers.isShowing(), 5);
}
@BindTo(String.class)
@Named(GithubAPI.GITHUB_API_URL_KEY)
private String githubApiUrl = "http://localhost:8080";
public static List<Repository> createSampleRepositories() {
return IntStream.rangeClosed(1, 10)
.mapToObj(i -> Repository.builder().name("repo" + i).fullName("foo/repo" + i).build())
.collect(toList());
}
public static String repositoriesAsJSON(Collection<Repository> repositories, ObjectMapper objectMapper) {
StringWriter writer = new StringWriter();
try {
objectMapper.writeValue(writer, repositories);
} catch (IOException e) {
throw new IllegalStateException(e);
}
return writer.toString();
}
}