/* LanguageTool, a natural language style checker
* Copyright (C) 2016 Daniel Naber (http://www.danielnaber.de)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
package org.languagetool.remote;
import org.junit.Ignore;
import org.junit.Test;
import org.languagetool.server.HTTPSServer;
import org.languagetool.server.HTTPSServerConfig;
import org.languagetool.server.HTTPServer;
import org.languagetool.server.HTTPServerConfig;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Collections;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
public class RemoteLanguageToolIntegrationTest {
private static final String serverUrl = "http://" + HTTPServerConfig.DEFAULT_HOST + ":" + HTTPTools.getDefaultPort();
@Test
@Ignore("for interactive use only")
public void testPublicServer() throws MalformedURLException {
RemoteLanguageTool lt = new RemoteLanguageTool(new URL("https://languagetool.org/api"));
RemoteResult matches = lt.check("This is an test.", "en");
System.out.println("matches: " + matches);
}
@Test
public void testClient() throws MalformedURLException {
HTTPServerConfig config = new HTTPServerConfig(HTTPTools.getDefaultPort());
HTTPServer server = new HTTPServer(config);
try {
server.run();
RemoteLanguageTool lt = new RemoteLanguageTool(new URL(serverUrl));
assertThat(lt.check("This is a correct sentence.", "en").getMatches().size(), is(0));
assertThat(lt.check("Sentence wiht a typo not detected.", "en").getMatches().size(), is(0));
assertThat(lt.check("Sentence wiht a typo detected.", "en-US").getMatches().size(), is(1));
assertThat(lt.check("A sentence with a error.", "en").getMatches().size(), is(1));
assertThat(lt.check("Test escape: %", "en").getMatches().size(), is(0));
RemoteResult result1 = lt.check("A sentence with a error, and and another one", "en");
assertThat(result1.getLanguage(), is("English"));
assertThat(result1.getLanguageCode(), is("en"));
assertThat(result1.getRemoteServer().getSoftware(), is("LanguageTool"));
assertNotNull(result1.getRemoteServer().getVersion());
assertThat(result1.getMatches().size(), is(2));
assertThat(result1.getMatches().get(0).getRuleId(), is("EN_A_VS_AN"));
assertThat(result1.getMatches().get(1).getRuleId(), is("ENGLISH_WORD_REPEAT_RULE"));
CheckConfiguration disabledConfig = new CheckConfigurationBuilder("en").disabledRuleIds("EN_A_VS_AN").build();
RemoteResult result2 = lt.check("A sentence with a error, and and another one", disabledConfig);
assertThat(result2.getMatches().size(), is(1));
assertThat(result2.getMatches().get(0).getRuleId(), is("ENGLISH_WORD_REPEAT_RULE"));
CheckConfiguration enabledConfig = new CheckConfigurationBuilder("en").enabledRuleIds("EN_A_VS_AN").build();
RemoteResult result3 = lt.check("A sentence with a error, and and another one", enabledConfig);
assertThat(result3.getMatches().size(), is(2));
CheckConfiguration enabledOnlyConfig = new CheckConfigurationBuilder("en").enabledRuleIds("EN_A_VS_AN").enabledOnly().build();
RemoteResult result4 = lt.check("A sentence with a error, and and another one", enabledOnlyConfig);
assertThat(result4.getMatches().size(), is(1));
assertThat(result4.getMatches().get(0).getRuleId(), is("EN_A_VS_AN"));
CheckConfiguration config1 = new CheckConfigurationBuilder().build();
RemoteResult result5 = lt.check("Ein Satz in Deutsch, mit etwas mehr Text, damit es auch geht.", config1);
assertThat(result5.getLanguage(), is("German (Germany)"));
assertThat(result5.getLanguageCode(), is("de-DE"));
CheckConfiguration config2 = new CheckConfigurationBuilder().build();
RemoteResult result6 = lt.check("x", config2); // too short, fallback will be used
assertThat(result6.getLanguage(), is("English (US)"));
assertThat(result6.getLanguageCode(), is("en-US"));
RemoteResult result7 = lt.check("Das Häuser ist schön.", "de");
assertThat(result7.getMatches().size(), is(1));
assertThat(result7.getMatches().get(0).getRuleId(), is("DE_AGREEMENT"));
try {
System.err.println("=== Testing invalid language code - ignore the following exception: ===");
lt.check("foo", "xy");
fail();
} catch (RuntimeException e) {
assertTrue(e.getMessage().contains("is not a language code known to LanguageTool"));
}
} finally {
server.stop();
}
}
@Test
public void testClientWithHTTPS() throws MalformedURLException, KeyManagementException, NoSuchAlgorithmException {
disableCertChecks();
String keyStore = RemoteLanguageToolIntegrationTest.class.getResource("/org/languagetool/remote/test-keystore.jks").getFile();
HTTPSServerConfig config = new HTTPSServerConfig(HTTPTools.getDefaultPort(), false, new File(keyStore), "mytest");
HTTPSServer server = new HTTPSServer(config, false, "localhost", Collections.singleton("127.0.0.1"));
try {
server.run();
RemoteLanguageTool lt = new RemoteLanguageTool(new URL(serverUrl.replace("http:", "https:")));
assertThat(lt.check("This is a correct sentence.", "en").getMatches().size(), is(0));
} finally {
server.stop();
}
}
private void disableCertChecks() throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustAllCerts = {
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
@Test(expected=RuntimeException.class)
public void testInvalidServer() throws MalformedURLException {
RemoteLanguageTool lt = new RemoteLanguageTool(new URL("http://does-not-exist"));
lt.check("foo", "en");
}
@Test(expected=RuntimeException.class)
public void testWrongProtocol() throws MalformedURLException {
String httpsUrl = "https://" + HTTPServerConfig.DEFAULT_HOST + ":" + HTTPServerConfig.DEFAULT_PORT;
RemoteLanguageTool lt = new RemoteLanguageTool(new URL(httpsUrl));
lt.check("foo", "en");
}
@Test(expected=RuntimeException.class)
public void testInvalidProtocol() throws MalformedURLException {
String httpsUrl = "ftp://" + HTTPServerConfig.DEFAULT_HOST + ":" + HTTPServerConfig.DEFAULT_PORT;
RemoteLanguageTool lt = new RemoteLanguageTool(new URL(httpsUrl));
lt.check("foo", "en");
}
@SuppressWarnings("ResultOfObjectAllocationIgnored")
@Test(expected=MalformedURLException.class)
public void testProtocolTypo() throws MalformedURLException {
String httpsUrl = "htp://" + HTTPServerConfig.DEFAULT_HOST + ":" + HTTPServerConfig.DEFAULT_PORT;
new RemoteLanguageTool(new URL(httpsUrl));
}
}