diff --git a/CLAUDE.md b/CLAUDE.md
index 683f270..22c8c84 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -84,6 +84,7 @@ Test doubles are in `src/test/java/com/smartystreets/api/mocks/`:
- US Street Address (`us_street/`)
- US ZIP Code (`us_zipcode/`)
- US Reverse Geo (`us_reverse_geo/`)
+- US Autocomplete (`us_autocomplete/`)
- US Autocomplete Pro (`us_autocomplete_pro/`)
- US Extract (`us_extract/`)
- US Enrichment (`us_enrichment/`)
diff --git a/Makefile b/Makefile
index 6949a88..5b68535 100644
--- a/Makefile
+++ b/Makefile
@@ -38,6 +38,9 @@ international_street_api:
international_postal_code_api:
mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.InternationalPostalCodeExample"
+us_autocomplete_api:
+ mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsAutocompleteExample"
+
us_autocomplete_pro_api:
mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsAutocompleteProExample"
@@ -68,6 +71,6 @@ us_street_iana_timezone_api:
us_zipcode_api:
mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsZipCodeSingleLookupExample" && mvn exec:java $(EXEC_OPTS) -Dexec.mainClass="examples.UsZipCodeMultipleLookupsExample"
-examples: international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api
+examples: international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_zipcode_api
-.PHONY: clean test integration-test compile publish examples international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_street_match_strategy_api us_street_iana_timezone_api us_zipcode_api
\ No newline at end of file
+.PHONY: clean test integration-test compile publish examples international_autocomplete_api international_street_api international_postal_code_api us_autocomplete_api us_autocomplete_pro_api us_enrichment_api us_enrichment_business_api us_enrichment_etag_api us_extract_api us_reverse_geo_api us_street_api us_street_match_strategy_api us_street_iana_timezone_api us_zipcode_api
\ No newline at end of file
diff --git a/src/main/java/com/smartystreets/api/ClientBuilder.java b/src/main/java/com/smartystreets/api/ClientBuilder.java
index 98bff31..6468ef1 100644
--- a/src/main/java/com/smartystreets/api/ClientBuilder.java
+++ b/src/main/java/com/smartystreets/api/ClientBuilder.java
@@ -18,6 +18,7 @@ public class ClientBuilder {
private final static String INTERNATIONAL_STREET_API_URL = "https://international-street.api.smarty.com/verify";
private final static String INTERNATIONAL_AUTOCOMPLETE_API_URL = "https://international-autocomplete.api.smarty.com/v2/lookup";
private final static String US_AUTOCOMPLETE_API_PRO_URL = "https://us-autocomplete-pro.api.smarty.com/lookup";
+ private final static String US_AUTOCOMPLETE_API_URL = "https://us-autocomplete.api.smarty.com/v2/lookup";
private final static String US_EXTRACT_API_URL = "https://us-extract.api.smarty.com/";
private final static String US_STREET_API_URL = "https://us-street.api.smarty.com/street-address";
private final static String US_ZIP_CODE_API_URL = "https://us-zipcode.api.smarty.com/lookup";
@@ -236,6 +237,11 @@ public com.smartystreets.api.us_autocomplete_pro.Client buildUsAutocompleteProAp
return new com.smartystreets.api.us_autocomplete_pro.Client(this.buildSender(), this.serializer);
}
+ public com.smartystreets.api.us_autocomplete.Client buildUsAutocompleteApiClient() {
+ this.ensureURLPrefixNotNull(US_AUTOCOMPLETE_API_URL);
+ return new com.smartystreets.api.us_autocomplete.Client(this.buildSender(), this.serializer);
+ }
+
public com.smartystreets.api.us_extract.Client buildUsExtractApiClient() {
this.ensureURLPrefixNotNull(US_EXTRACT_API_URL);
return new com.smartystreets.api.us_extract.Client(this.buildSender(), this.serializer);
diff --git a/src/main/java/com/smartystreets/api/us_autocomplete/Client.java b/src/main/java/com/smartystreets/api/us_autocomplete/Client.java
new file mode 100644
index 0000000..6b0dcff
--- /dev/null
+++ b/src/main/java/com/smartystreets/api/us_autocomplete/Client.java
@@ -0,0 +1,92 @@
+package com.smartystreets.api.us_autocomplete;
+
+
+import com.smartystreets.api.*;
+import com.smartystreets.api.exceptions.SmartyException;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * This client sends lookups to the SmartyStreets US Autocomplete API,
+ * and attaches the results to the appropriate Lookup objects.
+ */
+public class Client implements Closeable {
+ private final Sender sender;
+ private final Serializer serializer;
+
+ public Client(Sender sender, Serializer serializer) {
+ this.sender = sender;
+ this.serializer = serializer;
+ }
+
+ public Suggestion[] send(Lookup lookup) throws SmartyException, IOException, InterruptedException {
+ if (lookup == null || lookup.getSearch() == null || lookup.getSearch().length() == 0)
+ throw new SmartyException("Send() must be passed a Lookup with the search field set.");
+
+ Request request = this.buildRequest(lookup);
+
+ Response response = this.sender.send(request);
+
+ Result result = this.serializer.deserialize(response.getPayload(), Result.class);
+ Suggestion[] suggestions = result.getSuggestions();
+ lookup.setResult(suggestions);
+
+ return suggestions;
+ }
+
+ private Request buildRequest(Lookup lookup) {
+ Request request = new Request();
+
+ request.putParameter("search", lookup.getSearch());
+ request.putParameter("max_results", lookup.getMaxSuggestionsStringIfSet());
+ request.putParameter("include_only_cities", this.buildString(lookup.getCityFilter()));
+ request.putParameter("include_only_states", this.buildString(lookup.getStateFilter()));
+ request.putParameter("include_only_zip_codes", this.buildString(lookup.getZipcodeFilter()));
+ request.putParameter("exclude_states", this.buildString(lookup.getExcludeStates()));
+ request.putParameter("prefer_cities", this.buildString(lookup.getPreferCity()));
+ request.putParameter("prefer_states", this.buildString(lookup.getPreferState()));
+ request.putParameter("prefer_zip_codes", this.buildString(lookup.getPreferZipcode()));
+ request.putParameter("prefer_ratio", lookup.getPreferRatioStringIfSet());
+ if (lookup.getGeolocateType() != null) {
+ request.putParameter("prefer_geolocation", lookup.getGeolocateType().getName());
+ }
+ request.putParameter("selected", lookup.getSelected());
+ request.putParameter("exclude", this.buildString(lookup.getExclude(), ","));
+ if (lookup.getSource() != null) {
+ request.putParameter("source", lookup.getSource().getName());
+ }
+
+ return request;
+ }
+
+ private String buildString(List list) {
+ return buildStringFromList(list, ";");
+ }
+
+ private String buildString(List list, String separator) {
+ return buildStringFromList(list, separator);
+ }
+
+ private String buildStringFromList(List list, String separator) {
+ if (list.isEmpty())
+ return null;
+
+ String filterList = "";
+
+ for (String item : list) {
+ filterList += (item + separator);
+ }
+
+ if (filterList.endsWith(separator))
+ filterList = filterList.substring(0, filterList.length()-1);
+
+ return filterList;
+ }
+
+ @Override
+ public void close() throws IOException {
+ this.sender.close();
+ }
+}
diff --git a/src/main/java/com/smartystreets/api/us_autocomplete/Lookup.java b/src/main/java/com/smartystreets/api/us_autocomplete/Lookup.java
new file mode 100644
index 0000000..87d620c
--- /dev/null
+++ b/src/main/java/com/smartystreets/api/us_autocomplete/Lookup.java
@@ -0,0 +1,216 @@
+package com.smartystreets.api.us_autocomplete;
+
+import com.smartystreets.api.GeolocateType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * In addition to holding all of the input data for this lookup, this class also
+ * will contain the result of the lookup after it comes back from the API.
+ * @see "https://www.smarty.com/docs/apis/us-autocomplete-v2/reference#http-request-input-fields"
+ */
+public class Lookup {
+ final int PREFER_RATIO_DEFAULT = 100;
+ final int MAX_RESULTS_DEFAULT = 10;
+
+ //region [ Fields ]
+
+ private Suggestion[] result;
+ private String search;
+ private int maxResults;
+ private List cityFilter;
+ private List stateFilter;
+ private List zipcodeFilter;
+ private List excludeStates;
+ private List preferCity;
+ private List preferState;
+ private List preferZipcode;
+ private int preferRatio;
+ private GeolocateType preferGeolocation;
+ private String selected;
+ private List exclude;
+ private Source source;
+
+ //endregion
+
+ //region [ Constructors ]
+
+ /**
+ * If you use this constructor, don't forget to set the search. It is required.
+ */
+ public Lookup() {
+ this.maxResults = this.MAX_RESULTS_DEFAULT;
+ this.preferGeolocation = GeolocateType.CITY;
+ this.cityFilter = new ArrayList<>();
+ this.stateFilter = new ArrayList<>();
+ this.zipcodeFilter = new ArrayList<>();
+ this.excludeStates = new ArrayList<>();
+ this.preferCity = new ArrayList<>();
+ this.preferState = new ArrayList<>();
+ this.preferZipcode = new ArrayList<>();
+ this.exclude = new ArrayList<>();
+ this.preferRatio = this.PREFER_RATIO_DEFAULT;
+ }
+
+ /**
+ * @param search The beginning of an address
+ */
+ public Lookup(String search) {
+ this();
+ this.search = search;
+ }
+
+ //endregion
+
+ //region [ Getters ]
+
+ public Suggestion[] getResult() {
+ return this.result;
+ }
+
+ public Suggestion getResult(int index) {
+ return this.result[index];
+ }
+
+ public String getSearch() {
+ return this.search;
+ }
+
+ public String getSelected() { return this.selected; }
+
+ public List getExclude() { return this.exclude; }
+
+ public Source getSource() { return this.source; }
+
+ public List getCityFilter() {
+ return this.cityFilter;
+ }
+
+ public List getStateFilter() {
+ return this.stateFilter;
+ }
+
+ public List getZipcodeFilter() {
+ return this.zipcodeFilter;
+ }
+
+ public List getExcludeStates() {
+ return this.excludeStates;
+ }
+
+ public List getPreferCity() {
+ return this.preferCity;
+ }
+
+ public List getPreferState() { return this.preferState; }
+
+ public List getPreferZipcode() { return this.preferZipcode; }
+
+ public int getPreferRatio() {
+ return this.preferRatio;
+ }
+
+ String getPreferRatioStringIfSet() {
+ if (this.preferRatio == this.PREFER_RATIO_DEFAULT)
+ return null;
+ return Integer.toString(this.preferRatio);
+ }
+
+ public GeolocateType getGeolocateType() {
+ return preferGeolocation;
+ }
+
+ public int getMaxResults() {
+ return maxResults;
+ }
+
+ String getMaxSuggestionsStringIfSet() {
+ if (this.maxResults == this.MAX_RESULTS_DEFAULT)
+ return null;
+ return Integer.toString(this.maxResults);
+ }
+
+ //endregion
+
+ //region [ Setters ]
+
+ public void setResult(Suggestion[] result) {
+ this.result = result;
+ }
+
+ public void setSearch(String search) {
+ this.search = search;
+ }
+
+ public void setSelected(String selected) { this.selected = selected; }
+
+ public void setExclude(List exclude) { this.exclude = exclude; }
+
+ public void addExclude(String item) { this.exclude.add(item); }
+
+ public void setSource(Source source) { this.source = source; }
+
+ public void setCityFilter(List cityFilter) {
+ this.cityFilter = cityFilter;
+ }
+
+ public void setStateFilter(List stateFilter) {
+ this.stateFilter = stateFilter;
+ }
+
+ public void setZipcodeFilter(List zipcodeFilter) { this.zipcodeFilter = zipcodeFilter; }
+
+ public void setExcludeStates(List excludeStates) { this.excludeStates = excludeStates; }
+
+ public void setPreferCity(List cities) {
+ this.preferCity = cities;
+ }
+
+ public void setPreferState(List states) { this.preferState = states; }
+
+ public void setPreferZipcode(List zipcodes) { this.preferZipcode = zipcodes; }
+
+ /***
+ * Sets the percentage of suggestions that are to be from preferred cities/states.
+ * @param preferRatio An integer value, range [0, 100]. Default is 100.
+ */
+ public void setPreferRatio(int preferRatio) {
+ this.preferRatio = preferRatio;
+ }
+
+ public void setGeolocateType(GeolocateType geolocateType) {
+ this.preferGeolocation = geolocateType;
+ }
+
+ /***
+ * Sets the maximum number of suggestions to return.
+ * @param maxResults A positive integer range [1, 10]. Default is 10.
+ * @throws IllegalArgumentException
+ */
+ public void setMaxResults(int maxResults) throws IllegalArgumentException{
+ if (maxResults > 0 && maxResults <= this.MAX_RESULTS_DEFAULT) {
+ this.maxResults = maxResults;
+ } else {
+ throw new IllegalArgumentException("Max results must be a positive integer no larger than 10.");
+ }
+ }
+
+ public void addCityFilter(String city) {
+ this.cityFilter.add(city);
+ }
+
+ public void addStateFilter(String stateAbbreviation) {
+ this.stateFilter.add(stateAbbreviation);
+ }
+
+ public void addPreferCity(String city) {
+ this.preferCity.add(city);
+ }
+
+ public void addPreferState(String state) { this.preferState.add(state); }
+
+ public void addPreferZipcode(String zipcode) { this.preferZipcode.add(zipcode); }
+
+ //endregion
+}
diff --git a/src/main/java/com/smartystreets/api/us_autocomplete/Result.java b/src/main/java/com/smartystreets/api/us_autocomplete/Result.java
new file mode 100644
index 0000000..1f895a6
--- /dev/null
+++ b/src/main/java/com/smartystreets/api/us_autocomplete/Result.java
@@ -0,0 +1,16 @@
+package com.smartystreets.api.us_autocomplete;
+
+
+import java.io.Serializable;
+
+public class Result implements Serializable {
+ private Suggestion[] suggestions;
+
+ public Suggestion[] getSuggestions() {
+ return this.suggestions;
+ }
+
+ public Suggestion getSuggestion(int index) {
+ return this.suggestions[index];
+ }
+}
diff --git a/src/main/java/com/smartystreets/api/us_autocomplete/Source.java b/src/main/java/com/smartystreets/api/us_autocomplete/Source.java
new file mode 100644
index 0000000..5035d32
--- /dev/null
+++ b/src/main/java/com/smartystreets/api/us_autocomplete/Source.java
@@ -0,0 +1,15 @@
+package com.smartystreets.api.us_autocomplete;
+
+public enum Source {
+ ALL("all"), POSTAL("postal");
+
+ private final String name;
+
+ Source(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/com/smartystreets/api/us_autocomplete/Suggestion.java b/src/main/java/com/smartystreets/api/us_autocomplete/Suggestion.java
new file mode 100644
index 0000000..04d374c
--- /dev/null
+++ b/src/main/java/com/smartystreets/api/us_autocomplete/Suggestion.java
@@ -0,0 +1,59 @@
+package com.smartystreets.api.us_autocomplete;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+/**
+ * @see "https://www.smarty.com/docs/apis/us-autocomplete-v2/reference#http-response-status"
+ */
+public class Suggestion implements Serializable {
+ //region [ Fields ]
+
+ private String smartyKey;
+ private String entryId;
+ private String streetLine;
+ private String secondary;
+ private String city;
+ private String state;
+ private String zipcode;
+ private Integer entries;
+ private String source;
+
+ //endregion
+
+ //region [ Getters ]
+
+ @JsonProperty("smarty_key")
+ public String getSmartyKey() {
+ return smartyKey;
+ }
+
+ @JsonProperty("entry_id")
+ public String getEntryId() {
+ return entryId;
+ }
+
+ @JsonProperty("street_line")
+ public String getStreetLine() {
+ return streetLine;
+ }
+
+ public String getSecondary() { return secondary; }
+
+ public String getCity() {
+ return city;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public String getZipcode() { return zipcode; }
+
+ public Integer getEntries() { return entries; }
+
+ public String getSource() { return source; }
+
+ //endregion
+}
diff --git a/src/main/java/com/smartystreets/api/us_autocomplete_pro/Lookup.java b/src/main/java/com/smartystreets/api/us_autocomplete_pro/Lookup.java
index cbd22d3..bcdd5cc 100644
--- a/src/main/java/com/smartystreets/api/us_autocomplete_pro/Lookup.java
+++ b/src/main/java/com/smartystreets/api/us_autocomplete_pro/Lookup.java
@@ -165,7 +165,7 @@ public void setPreferCity(List cities) {
/***
* Sets the percentage of suggestions that are to be from preferred cities/states.
- * @param preferRatio An integer value, range [0, 100]. Default is 33.
+ * @param preferRatio An integer value, range [0, 100]. Default is 100.
* @see "https://smartystreets.com/docs/cloud/us-autocomplete-pro-api#preference"
*/
public void setPreferRatio(int preferRatio) {
diff --git a/src/main/java/com/smartystreets/api/us_autocomplete_pro/Suggestion.java b/src/main/java/com/smartystreets/api/us_autocomplete_pro/Suggestion.java
index 763c4e2..ce76666 100644
--- a/src/main/java/com/smartystreets/api/us_autocomplete_pro/Suggestion.java
+++ b/src/main/java/com/smartystreets/api/us_autocomplete_pro/Suggestion.java
@@ -17,7 +17,7 @@ public class Suggestion implements Serializable {
private String zipcode;
private Integer entries;
- //region [ Fields ]
+ //endregion
//region [ Getters ]
diff --git a/src/main/java/examples/UsAutocompleteExample.java b/src/main/java/examples/UsAutocompleteExample.java
new file mode 100644
index 0000000..315fae3
--- /dev/null
+++ b/src/main/java/examples/UsAutocompleteExample.java
@@ -0,0 +1,79 @@
+package examples;
+
+import com.smartystreets.api.BasicAuthCredentials;
+import com.smartystreets.api.exceptions.SmartyException;
+import com.smartystreets.api.us_autocomplete.*;
+import com.smartystreets.api.ClientBuilder;
+
+import java.io.IOException;
+
+// This example is for US Autocomplete (V2). It has the same name as a previous product
+// which has been deprecated since 2022, which we refer to as US Autocomplete Basic.
+// If you are still using US Autocomplete Basic, this SDK will not work.
+public class UsAutocompleteExample {
+ public static void main(String[] args) {
+ // We recommend storing your authentication credentials in environment variables.
+ // for client-side requests (browser/mobile), use this code:
+ // SharedCredentials credentials = new SharedCredentials(System.getenv("SMARTY_AUTH_WEB"), System.getenv("SMARTY_AUTH_REFERER"));
+ BasicAuthCredentials credentials = new BasicAuthCredentials(System.getenv("SMARTY_AUTH_ID"), System.getenv("SMARTY_AUTH_TOKEN"));
+
+ try (Client client = new ClientBuilder(credentials).buildUsAutocompleteApiClient()) {
+ Lookup lookup = new Lookup("1042 W Center");
+ lookup.setMaxResults(5);
+
+ client.send(lookup);
+
+ System.out.println("*** Result with no filter ***");
+ System.out.println();
+ printResult(lookup);
+
+ // Documentation for input fields can be found at:
+ // https://www.smarty.com/docs/apis/us-autocomplete-v2/reference#http-request-input-fields
+
+ lookup.addCityFilter("Denver,Aurora,CO");
+ lookup.addCityFilter("Orem,UT");
+ lookup.addPreferState("CO");
+ lookup.setPreferRatio(33);
+ lookup.setSource(Source.ALL);
+
+ client.send(lookup); // The client will also return the suggestions directly
+
+ System.out.println();
+ System.out.println("*** Result with some filters ***");
+ printResult(lookup);
+
+ // Expand the secondaries of a result that has an entry_id by passing it back as the selected address.
+ String entryId = null;
+ for (Suggestion suggestion : lookup.getResult()) {
+ if (suggestion.getEntryId() != null && suggestion.getEntryId().length() > 0)
+ entryId = suggestion.getEntryId();
+ }
+
+ if (entryId != null) {
+ lookup.setSelected(entryId);
+ client.send(lookup);
+
+ System.out.println();
+ System.out.println("*** Secondaries ***");
+ printResult(lookup);
+ }
+ } catch (SmartyException | IOException | InterruptedException ex) {
+ System.out.println(ex.getMessage());
+ ex.printStackTrace();
+ }
+ }
+
+ private static void printResult(Lookup lookup) {
+ for (Suggestion suggestion : lookup.getResult()) {
+ System.out.print(suggestion.getStreetLine());
+ System.out.print(" ");
+ System.out.print(suggestion.getSecondary());
+ System.out.print(" ");
+ System.out.print(suggestion.getCity());
+ System.out.print(", ");
+ System.out.print(suggestion.getState());
+ System.out.print(", ");
+ System.out.println(suggestion.getZipcode());
+ }
+ }
+}
diff --git a/src/test/java/com/smartystreets/api/us_autocomplete/ClientTest.java b/src/test/java/com/smartystreets/api/us_autocomplete/ClientTest.java
new file mode 100644
index 0000000..16fb299
--- /dev/null
+++ b/src/test/java/com/smartystreets/api/us_autocomplete/ClientTest.java
@@ -0,0 +1,140 @@
+package com.smartystreets.api.us_autocomplete;
+
+import com.smartystreets.api.GeolocateType;
+import com.smartystreets.api.Response;
+import com.smartystreets.api.URLPrefixSender;
+import com.smartystreets.api.mocks.FakeDeserializer;
+import com.smartystreets.api.mocks.FakeSerializer;
+import com.smartystreets.api.mocks.MockSender;
+import com.smartystreets.api.mocks.RequestCapturingSender;
+import org.junit.Test;
+import java.util.List;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+public class ClientTest {
+ //region [ Single Lookup ]
+
+ @Test
+ public void testSendingSingleSearchOnlyLookup() throws Exception {
+ RequestCapturingSender capturingSender = new RequestCapturingSender();
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", capturingSender);
+ FakeSerializer serializer = new FakeSerializer(new Result());
+ Client client = new Client(sender, serializer);
+
+ client.send(new Lookup("1"));
+
+ assertEquals("http://localhost/?search=1&prefer_geolocation=city", capturingSender.getRequest().getUrl());
+ }
+
+ @Test
+ public void testSendingSingleFullyPopulatedLookup() throws Exception {
+ RequestCapturingSender capturingSender = new RequestCapturingSender();
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", capturingSender);
+ FakeSerializer serializer = new FakeSerializer(new Result());
+ Client client = new Client(sender, serializer);
+ String expectedURL = "http://localhost/?search=1&max_results=2&include_only_cities=3&include_only_states=4&prefer_ratio=60&prefer_geolocation=city&selected=5&exclude=6";
+ Lookup lookup = new Lookup();
+ lookup.setSearch("1");
+ lookup.setMaxResults(2);
+ lookup.addCityFilter("3");
+ lookup.addStateFilter("4");
+ lookup.setPreferRatio(60);
+ lookup.setGeolocateType(GeolocateType.CITY);
+ lookup.setSelected("5");
+ lookup.addExclude("6");
+
+ client.send(lookup);
+
+ assertEquals(expectedURL, capturingSender.getRequest().getUrl());
+ }
+
+ @Test
+ public void testSendingLookupWithSourceAll() throws Exception {
+ RequestCapturingSender capturingSender = new RequestCapturingSender();
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", capturingSender);
+ FakeSerializer serializer = new FakeSerializer(new Result());
+ Client client = new Client(sender, serializer);
+ Lookup lookup = new Lookup("1");
+ lookup.setSource(Source.ALL);
+
+ client.send(lookup);
+
+ assertEquals("http://localhost/?search=1&prefer_geolocation=city&source=all", capturingSender.getRequest().getUrl());
+ }
+
+ @Test
+ public void testSendingLookupWithSourcePostal() throws Exception {
+ RequestCapturingSender capturingSender = new RequestCapturingSender();
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", capturingSender);
+ FakeSerializer serializer = new FakeSerializer(new Result());
+ Client client = new Client(sender, serializer);
+ Lookup lookup = new Lookup("1");
+ lookup.setSource(Source.POSTAL);
+
+ client.send(lookup);
+
+ assertEquals("http://localhost/?search=1&prefer_geolocation=city&source=postal", capturingSender.getRequest().getUrl());
+ }
+
+ @Test
+ public void testSendingLookupWithNoSourceOmitsParameter() throws Exception {
+ RequestCapturingSender capturingSender = new RequestCapturingSender();
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", capturingSender);
+ FakeSerializer serializer = new FakeSerializer(new Result());
+ Client client = new Client(sender, serializer);
+
+ client.send(new Lookup("1"));
+
+ assertEquals("http://localhost/?search=1&prefer_geolocation=city", capturingSender.getRequest().getUrl());
+ }
+
+ @Test
+ public void testSendingExclude() throws Exception {
+ RequestCapturingSender capturingSender = new RequestCapturingSender();
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", capturingSender);
+ FakeSerializer serializer = new FakeSerializer(new Result());
+ Client client = new Client(sender, serializer);
+ Lookup lookup = new Lookup("1");
+ lookup.setExclude(List.of("excludedAddress", "excludedAddress2"));
+
+ client.send(lookup);
+
+ assertEquals("http://localhost/?search=1&prefer_geolocation=city&exclude=excludedAddress%2CexcludedAddress2", capturingSender.getRequest().getUrl());
+ }
+
+ //endregion
+
+ //region [ Response Handling ]
+
+ @Test
+ public void testDeserializeCalledWithResponseBody() throws Exception {
+ Response response = new Response(0, "Hello, World!".getBytes());
+ MockSender mockSender = new MockSender(response);
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", mockSender);
+ FakeDeserializer deserializer = new FakeDeserializer(new Result());
+ Client client = new Client(sender, deserializer);
+
+ client.send(new Lookup("1"));
+
+ assertEquals(response.getPayload(), deserializer.getPayload());
+ }
+
+ @Test
+ public void testResultCorrectlyAssignedToCorrespondingLookup() throws Exception {
+ Lookup lookup = new Lookup("1");
+ Result expectedResult = new Result();
+
+ MockSender mockSender = new MockSender(new Response(0, "{[]}".getBytes()));
+ URLPrefixSender sender = new URLPrefixSender("http://localhost/", mockSender);
+ FakeDeserializer deserializer = new FakeDeserializer(expectedResult);
+ Client client = new Client(sender, deserializer);
+
+ client.send(lookup);
+
+ assertArrayEquals(expectedResult.getSuggestions(), lookup.getResult());
+ }
+
+ //endregion
+}
diff --git a/src/test/java/com/smartystreets/api/us_autocomplete/SuggestionTest.java b/src/test/java/com/smartystreets/api/us_autocomplete/SuggestionTest.java
new file mode 100644
index 0000000..adebcf7
--- /dev/null
+++ b/src/test/java/com/smartystreets/api/us_autocomplete/SuggestionTest.java
@@ -0,0 +1,28 @@
+package com.smartystreets.api.us_autocomplete;
+
+
+import com.smartystreets.api.SmartySerializer;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class SuggestionTest {
+ private final SmartySerializer smartySerializer = new SmartySerializer();
+ private static final String responsePayload = "{\"suggestions\":[{\"smarty_key\":\"1\",\"entry_id\":\"2\",\"street_line\":\"3\",\"city\":\"4\",\"state\":\"5\",\"source\":\"6\"}]}";
+
+ @Test
+ public void testAllFieldGetFilledInCorrectly() throws IOException {
+ Result result = smartySerializer.deserialize(responsePayload.getBytes(), Result.class);
+
+ assertNotNull(result.getSuggestions()[0]);
+ assertEquals("1", result.getSuggestion(0).getSmartyKey());
+ assertEquals("2", result.getSuggestion(0).getEntryId());
+ assertEquals("3", result.getSuggestion(0).getStreetLine());
+ assertEquals("4", result.getSuggestion(0).getCity());
+ assertEquals("5", result.getSuggestion(0).getState());
+ assertEquals("6", result.getSuggestion(0).getSource());
+ }
+}