Reworked and added test.

This commit is contained in:
Erik C. Thauvin 2019-04-09 15:56:21 -07:00
parent 518703b826
commit bdf0ca3006
2 changed files with 84 additions and 50 deletions

View file

@ -83,43 +83,52 @@ public final class GoogleSearch extends ThreadedModule {
* @param cseKey The Google search results. * @param cseKey The Google search results.
*/ */
@SuppressFBWarnings(value = {"URLCONNECTION_SSRF_FD", "REC_CATCH_EXCEPTION"}) @SuppressFBWarnings(value = {"URLCONNECTION_SSRF_FD", "REC_CATCH_EXCEPTION"})
static ArrayList<Message> searchGoogle(String query, String apiKey, String cseKey) throws ModuleException { static ArrayList<Message> searchGoogle(final String query, final String apiKey, final String cseKey)
final ArrayList<Message> results = new ArrayList<>(); throws ModuleException {
try { if (!Utils.isValidString(apiKey) || !Utils.isValidString(cseKey)) {
final String q = URLEncoder.encode(query, StandardCharsets.UTF_8.toString()); throw new ModuleException(Utils.capitalize(GOOGLE_CMD) + " is disabled. The API keys are missing.");
final URL url =
new URL("https://www.googleapis.com/customsearch/v1?key="
+ apiKey
+ "&cx="
+ cseKey
+ "&q="
+ q
+ "&filter=1&num=5&alt=json");
final URLConnection conn = url.openConnection();
final StringBuilder sb = new StringBuilder();
try (final BufferedReader reader =
new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
final JSONObject json = new JSONObject(sb.toString());
final JSONArray ja = json.getJSONArray("items");
for (int i = 0; i < ja.length(); i++) {
final JSONObject j = ja.getJSONObject(i);
results.add(new NoticeMessage(Utils.unescapeXml(j.getString("title"))));
results.add(new NoticeMessage(j.getString("link")));
}
}
} catch (IOException e) {
throw new ModuleException("searchGoogle(" + query + ')', "An error has occurred searching Google.", e);
} }
return results; if (Utils.isValidString(query)) {
final ArrayList<Message> results = new ArrayList<>();
try {
final String q = URLEncoder.encode(query, StandardCharsets.UTF_8.toString());
final URL url =
new URL("https://www.googleapis.com/customsearch/v1?key="
+ apiKey
+ "&cx="
+ cseKey
+ "&q="
+ q
+ "&filter=1&num=5&alt=json");
final URLConnection conn = url.openConnection();
final StringBuilder sb = new StringBuilder();
try (final BufferedReader reader =
new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
final JSONObject json = new JSONObject(sb.toString());
final JSONArray ja = json.getJSONArray("items");
for (int i = 0; i < ja.length(); i++) {
final JSONObject j = ja.getJSONObject(i);
results.add(new NoticeMessage(Utils.unescapeXml(j.getString("title"))));
results.add(new NoticeMessage(j.getString("link")));
}
}
} catch (IOException e) {
throw new ModuleException("searchGoogle(" + query + ')', "An error has occurred searching Google.", e);
}
return results;
} else {
throw new ModuleException("Invalid query.");
}
} }
/** /**
@ -131,7 +140,7 @@ public final class GoogleSearch extends ThreadedModule {
bot.send(sender, "To search Google:"); bot.send(sender, "To search Google:");
bot.send(sender, bot.helpIndent(bot.getNick() + ": " + GOOGLE_CMD + " <query>")); bot.send(sender, bot.helpIndent(bot.getNick() + ": " + GOOGLE_CMD + " <query>"));
} else { } else {
bot.send(sender, "The Google searching facility is disabled."); bot.send(sender, "The Google search module is disabled.");
} }
} }
@ -139,22 +148,26 @@ public final class GoogleSearch extends ThreadedModule {
* Searches Google. * Searches Google.
*/ */
void run(final Mobibot bot, final String sender, final String query) { void run(final Mobibot bot, final String sender, final String query) {
try { if (Utils.isValidString(query)) {
final ArrayList<Message> results = searchGoogle(query, properties.get(GOOGLE_API_KEY_PROP), try {
properties.get(GOOGLE_CSE_KEY_PROP)); final ArrayList<Message> results = searchGoogle(query, properties.get(GOOGLE_API_KEY_PROP),
properties.get(GOOGLE_CSE_KEY_PROP));
int i = 0; int i = 0;
for (Message msg : results) { for (final Message msg : results) {
if (i % 2 == 0) { if (i % 2 == 0) {
bot.send(sender, Utils.green(TAB_INDENT + msg.getMessage())); bot.send(sender, Utils.green(TAB_INDENT + msg.getMessage()));
} else { } else {
bot.send(sender, msg.getMessage()); bot.send(sender, msg.getMessage());
}
i++;
} }
i++; } catch (ModuleException e) {
bot.getLogger().warn(e.getDebugMessage(), e);
bot.send(sender, e.getMessage());
} }
} catch (ModuleException e) { } else {
bot.getLogger().warn(e.getDebugMessage(), e); helpResponse(bot, sender, query, true);
bot.send(sender, e.getMessage());
} }
} }
} }

View file

@ -45,7 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @created 2019-04-08 * @created 2019-04-08
* @since 1.0 * @since 1.0
*/ */
public class GoogleSearchTest { public class GoogleSearchTest extends LocalProperties {
@Test @Test
public void testGoogleSearchImpl() { public void testGoogleSearchImpl() {
AbstractModuleTest.testAbstractModule(new GoogleSearch()); AbstractModuleTest.testAbstractModule(new GoogleSearch());
@ -63,6 +63,27 @@ public class GoogleSearchTest {
messages = GoogleSearch.searchGoogle("aapl", apiKey, cseKey); messages = GoogleSearch.searchGoogle("aapl", apiKey, cseKey);
assertThat(messages).as("aapl results not empty").isNotEmpty(); assertThat(messages).as("aapl results not empty").isNotEmpty();
assertThat(messages.get(0).getMessage()).as("found apple").containsIgnoringCase("apple"); assertThat(messages.get(0).getMessage()).as("found apple").containsIgnoringCase("apple");
try {
GoogleSearch.searchGoogle("test", "", "apiKey");
} catch (Exception e) {
assertThat(e).as("no API key").isInstanceOf(ModuleException.class);
assertThat(e).as("no API key exception has no cause").hasNoCause();
}
try {
GoogleSearch.searchGoogle("test", "apiKey", "");
} catch (Exception e) {
assertThat(e).as("no CSE API key").isInstanceOf(ModuleException.class);
assertThat(e).as("no CSE API key exception has no cause").hasNoCause();
}
try {
GoogleSearch.searchGoogle("", "apikey", "apiKey");
} catch (Exception e) {
assertThat(e).as("no query").isInstanceOf(ModuleException.class);
assertThat(e).as("no query exception has no cause").hasNoCause();
}
} catch (ModuleException e) { } catch (ModuleException e) {
// Avoid displaying api keys in CI logs. // Avoid displaying api keys in CI logs.
if ("true".equals(System.getenv("CI"))) { if ("true".equals(System.getenv("CI"))) {