mirror of
https://github.com/google/nomulus
synced 2026-07-22 07:52:22 +00:00
Run Address validation on GSON deserialization too (#3166)
we should run these checks when we deserialize from json objects, not just when we use the builder to construct it. We did something similar for TLD recently.
This commit is contained in:
@@ -155,6 +155,7 @@ public class Address extends ImmutableObject
|
||||
|
||||
@Override
|
||||
public void postProcess() {
|
||||
validateState();
|
||||
if (street == null || street.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -163,6 +164,21 @@ public class Address extends ImmutableObject
|
||||
streetLine3 = street.size() >= 3 ? street.get(2) : null;
|
||||
}
|
||||
|
||||
public void validateState() {
|
||||
checkArgument(
|
||||
street == null || (!street.isEmpty() && street.size() <= 3),
|
||||
"Street address must have [1-3] lines: %s",
|
||||
street);
|
||||
//noinspection ConstantConditions
|
||||
checkArgument(
|
||||
street == null || street.stream().noneMatch(String::isEmpty),
|
||||
"Street address cannot contain empty string: %s",
|
||||
street);
|
||||
checkArgument(
|
||||
countryCode == null || countryCode.length() == 2,
|
||||
"Country code should be a 2 character string");
|
||||
}
|
||||
|
||||
/** A builder for constructing {@link Address}. */
|
||||
public static class Builder<T extends Address> extends Buildable.Builder<T> {
|
||||
|
||||
@@ -172,16 +188,13 @@ public class Address extends ImmutableObject
|
||||
super(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T build() {
|
||||
getInstance().validateState();
|
||||
return super.build();
|
||||
}
|
||||
|
||||
public Builder<T> setStreet(ImmutableList<String> street) {
|
||||
checkArgument(
|
||||
street == null || (!street.isEmpty() && street.size() <= 3),
|
||||
"Street address must have [1-3] lines: %s",
|
||||
street);
|
||||
//noinspection ConstantConditions
|
||||
checkArgument(
|
||||
street.stream().noneMatch(String::isEmpty),
|
||||
"Street address cannot contain empty string: %s",
|
||||
street);
|
||||
getInstance().street = street;
|
||||
getInstance().streetLine1 = street.get(0);
|
||||
getInstance().streetLine2 = street.size() >= 2 ? street.get(1) : null;
|
||||
|
||||
@@ -37,6 +37,14 @@ public class RegistrarAddress extends Address {
|
||||
return new Builder(clone(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateState() {
|
||||
super.validateState();
|
||||
checkNotNull(forceEmptyToNull(getStreet()), "Missing street");
|
||||
checkNotNull(getCity(), "Missing city");
|
||||
checkNotNull(getCountryCode(), "Missing country code");
|
||||
}
|
||||
|
||||
/** Builder for {@link RegistrarAddress}. */
|
||||
public static class Builder extends Address.Builder<RegistrarAddress> {
|
||||
public Builder() {}
|
||||
@@ -44,14 +52,5 @@ public class RegistrarAddress extends Address {
|
||||
private Builder(RegistrarAddress instance) {
|
||||
super(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistrarAddress build() {
|
||||
RegistrarAddress instance = getInstance();
|
||||
checkNotNull(forceEmptyToNull(instance.getStreet()), "Missing street");
|
||||
checkNotNull(instance.getCity(), "Missing city");
|
||||
checkNotNull(instance.getCountryCode(), "Missing country code");
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import google.registry.model.ImmutableObject;
|
||||
import google.registry.model.eppcommon.AddressTest.TestEntity.TestAddress;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions;
|
||||
import google.registry.persistence.transaction.JpaTestExtensions.JpaUnitTestExtension;
|
||||
import google.registry.tools.GsonUtils;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
@@ -124,6 +125,38 @@ class AddressTest {
|
||||
assertAddress(unmarshalledEntity.address, "123 W 14th St", "8th Fl", "Rm 8");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_gsonInstantiation() {
|
||||
String json = "{\"street\":[\"123 W 14th St\",\"8th Fl\"],\"countryCode\":\"US\"}";
|
||||
TestAddress address = GsonUtils.provideGson().fromJson(json, TestAddress.class);
|
||||
assertThat(address.getStreet()).containsExactly("123 W 14th St", "8th Fl");
|
||||
assertThat(address.getCountryCode()).isEqualTo("US");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_tooManyStreetLines() {
|
||||
String json = "{\"street\":[\"123 W 14th St\",\"8th Fl\",\"Rm 8\",\"4th Line\"]}";
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, TestAddress.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_emptyStreetLine() {
|
||||
String json = "{\"street\":[\"123 W 14th St\",\"\"]}";
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, TestAddress.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_invalidCountryCode() {
|
||||
String json = "{\"countryCode\":\"USA\"}";
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, TestAddress.class));
|
||||
}
|
||||
|
||||
private static TestAddress createAddress(String... streetList) {
|
||||
return new TestAddress.Builder()
|
||||
.setStreet(ImmutableList.copyOf(streetList))
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright 2026 The Nomulus Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 google.registry.model.registrar;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import google.registry.tools.GsonUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/** Unit tests for {@link RegistrarAddress}. */
|
||||
class RegistrarAddressTest {
|
||||
|
||||
@Test
|
||||
void testSuccess_gsonInstantiation() {
|
||||
String json = "{\"street\":[\"123 W 14th St\"],\"city\":\"New York\",\"countryCode\":\"US\"}";
|
||||
RegistrarAddress address = GsonUtils.provideGson().fromJson(json, RegistrarAddress.class);
|
||||
assertThat(address.getStreet()).containsExactly("123 W 14th St");
|
||||
assertThat(address.getCity()).isEqualTo("New York");
|
||||
assertThat(address.getCountryCode()).isEqualTo("US");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_missingStreet() {
|
||||
String json = "{\"city\":\"New York\",\"countryCode\":\"US\"}";
|
||||
assertThrows(
|
||||
NullPointerException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, RegistrarAddress.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_missingCity() {
|
||||
String json = "{\"street\":[\"123 W 14th St\"],\"countryCode\":\"US\"}";
|
||||
assertThrows(
|
||||
NullPointerException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, RegistrarAddress.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_missingCountryCode() {
|
||||
String json = "{\"street\":[\"123 W 14th St\"],\"city\":\"New York\"}";
|
||||
assertThrows(
|
||||
NullPointerException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, RegistrarAddress.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_invalidCountryCode() {
|
||||
String json = "{\"street\":[\"123 W 14th St\"],\"city\":\"New York\",\"countryCode\":\"USA\"}";
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, RegistrarAddress.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_gsonInstantiation_tooManyStreetLines() {
|
||||
String json =
|
||||
"{\"street\":[\"1\",\"2\",\"3\",\"4\"],\"city\":\"New York\",\"countryCode\":\"US\"}";
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> GsonUtils.provideGson().fromJson(json, RegistrarAddress.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSuccess_builder() {
|
||||
RegistrarAddress address =
|
||||
new RegistrarAddress.Builder()
|
||||
.setStreet(ImmutableList.of("123 W 14th St"))
|
||||
.setCity("New York")
|
||||
.setCountryCode("US")
|
||||
.build();
|
||||
assertThat(address.getStreet()).containsExactly("123 W 14th St");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFailure_builder_missingStreet() {
|
||||
assertThrows(
|
||||
NullPointerException.class,
|
||||
() -> new RegistrarAddress.Builder().setCity("New York").setCountryCode("US").build());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user