Skip to content

Commit 0bf0b4f

Browse files
authored
Require EPP validation for complex OT&E stats (#3107)
Previously, if there were no XML bytes somehow, it'd increment a bunch of counts for requirements that shouldn't be incremented. We should only increment these values if we have the data to do so. Note: this doesn't happen and shouldn't happen, so there's no issues currently occurring, but this code is more correct anyway.
1 parent 2ce91e3 commit 0bf0b4f

2 files changed

Lines changed: 112 additions & 70 deletions

File tree

core/src/main/java/google/registry/model/OteStats.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,12 @@ public String getDescription() {
176176
* Check if the {@link HistoryEntry} type matches as well as the {@link EppInput} if supplied.
177177
*/
178178
private boolean matches(HistoryEntry.Type historyType, Optional<EppInput> eppInput) {
179-
if (eppInputFilter.isPresent() && eppInput.isPresent()) {
180-
return typeFilter.test(historyType) && eppInputFilter.get().test(eppInput.get());
181-
} else {
182-
return typeFilter.test(historyType);
179+
if (!typeFilter.test(historyType)) {
180+
return false;
183181
}
182+
return eppInputFilter
183+
.map(filter -> eppInput.isPresent() && filter.test(eppInput.get()))
184+
.orElse(true);
184185
}
185186
}
186187

core/src/test/java/google/registry/model/OteStatsTest.java

Lines changed: 107 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,17 @@
1616

1717
import static com.google.common.truth.Truth.assertThat;
1818
import static google.registry.testing.DatabaseHelper.createTld;
19+
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
20+
import static google.registry.testing.DatabaseHelper.persistPremiumList;
21+
import static google.registry.testing.DatabaseHelper.persistResource;
22+
import static org.joda.money.CurrencyUnit.USD;
1923

2024
import google.registry.model.OteStats.StatType;
25+
import google.registry.model.domain.DomainHistory;
26+
import google.registry.model.reporting.HistoryEntry.Type;
2127
import google.registry.persistence.transaction.JpaTestExtensions;
2228
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
29+
import java.time.Instant;
2330
import org.junit.jupiter.api.BeforeEach;
2431
import org.junit.jupiter.api.Test;
2532
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -60,39 +67,40 @@ void testSuccess_toString() throws Exception {
6067
OteStats stats = OteStats.getFromRegistrar("blobio");
6168
String expected =
6269
"""
63-
contact creates: 0
64-
contact deletes: 0
65-
contact transfer approves: 0
66-
contact transfer cancels: 0
67-
contact transfer rejects: 0
68-
contact transfer requests: 0
69-
contact updates: 0
70-
domain autorenews: 0
71-
domain creates: 5
72-
domain creates ascii: 4
73-
domain creates idn: 1
74-
domain creates start date sunrise: 1
75-
domain creates with claims notice: 1
76-
domain creates with fee: 1
77-
domain creates with sec dns: 1
78-
domain creates without sec dns: 4
79-
domain deletes: 1
80-
domain renews: 0
81-
domain restores: 1
82-
domain transfer approves: 1
83-
domain transfer cancels: 1
84-
domain transfer rejects: 1
85-
domain transfer requests: 1
86-
domain updates: 1
87-
domain updates with sec dns: 1
88-
domain updates without sec dns: 0
89-
host creates: 1
90-
host creates external: 0
91-
host creates subordinate: 1
92-
host deletes: 1
93-
host updates: 1
94-
unclassified flows: 0
95-
TOTAL: 30""";
70+
contact creates: 0
71+
contact deletes: 0
72+
contact transfer approves: 0
73+
contact transfer cancels: 0
74+
contact transfer rejects: 0
75+
contact transfer requests: 0
76+
contact updates: 0
77+
domain autorenews: 0
78+
domain creates: 5
79+
domain creates ascii: 4
80+
domain creates idn: 1
81+
domain creates start date sunrise: 1
82+
domain creates with claims notice: 1
83+
domain creates with fee: 1
84+
domain creates with sec dns: 1
85+
domain creates without sec dns: 4
86+
domain deletes: 1
87+
domain renews: 0
88+
domain restores: 1
89+
domain transfer approves: 1
90+
domain transfer cancels: 1
91+
domain transfer rejects: 1
92+
domain transfer requests: 1
93+
domain updates: 1
94+
domain updates with sec dns: 1
95+
domain updates without sec dns: 0
96+
host creates: 1
97+
host creates external: 0
98+
host creates subordinate: 1
99+
host deletes: 1
100+
host updates: 1
101+
unclassified flows: 0
102+
TOTAL: 30\
103+
""";
96104
assertThat(stats.toString()).isEqualTo(expected);
97105
}
98106

@@ -102,39 +110,72 @@ void testIncomplete_toString() throws Exception {
102110
OteStats stats = OteStats.getFromRegistrar("blobio");
103111
String expected =
104112
"""
105-
contact creates: 0
106-
contact deletes: 0
107-
contact transfer approves: 0
108-
contact transfer cancels: 0
109-
contact transfer rejects: 0
110-
contact transfer requests: 0
111-
contact updates: 0
112-
domain autorenews: 0
113-
domain creates: 4
114-
domain creates ascii: 4
115-
domain creates idn: 0
116-
domain creates start date sunrise: 1
117-
domain creates with claims notice: 1
118-
domain creates with fee: 1
119-
domain creates with sec dns: 1
120-
domain creates without sec dns: 3
121-
domain deletes: 1
122-
domain renews: 0
123-
domain restores: 0
124-
domain transfer approves: 1
125-
domain transfer cancels: 1
126-
domain transfer rejects: 1
127-
domain transfer requests: 1
128-
domain updates: 1
129-
domain updates with sec dns: 1
130-
domain updates without sec dns: 0
131-
host creates: 1
132-
host creates external: 0
133-
host creates subordinate: 1
134-
host deletes: 0
135-
host updates: 10
136-
unclassified flows: 0
137-
TOTAL: 34""";
113+
contact creates: 0
114+
contact deletes: 0
115+
contact transfer approves: 0
116+
contact transfer cancels: 0
117+
contact transfer rejects: 0
118+
contact transfer requests: 0
119+
contact updates: 0
120+
domain autorenews: 0
121+
domain creates: 4
122+
domain creates ascii: 4
123+
domain creates idn: 0
124+
domain creates start date sunrise: 1
125+
domain creates with claims notice: 1
126+
domain creates with fee: 1
127+
domain creates with sec dns: 1
128+
domain creates without sec dns: 3
129+
domain deletes: 1
130+
domain renews: 0
131+
domain restores: 0
132+
domain transfer approves: 1
133+
domain transfer cancels: 1
134+
domain transfer rejects: 1
135+
domain transfer requests: 1
136+
domain updates: 1
137+
domain updates with sec dns: 1
138+
domain updates without sec dns: 0
139+
host creates: 1
140+
host creates external: 0
141+
host creates subordinate: 1
142+
host deletes: 0
143+
host updates: 10
144+
unclassified flows: 0
145+
TOTAL: 34\
146+
""";
138147
assertThat(stats.toString()).isEqualTo(expected);
139148
}
149+
150+
@Test
151+
void testDomainCreateWithoutXmlBytes_doesNotSatisfyComplexRequirements() throws Exception {
152+
persistPremiumList("default_sandbox_list", USD, "sandbox,USD 1000");
153+
OteAccountBuilder.forRegistrarId("blobio").buildAndPersist();
154+
String oteAccount1 = "blobio-1";
155+
Instant now = Instant.parse("2026-06-25T10:00:00Z");
156+
157+
// Persist a DOMAIN_CREATE history entry without XML bytes
158+
persistResource(
159+
new DomainHistory.Builder()
160+
.setDomain(persistActiveDomain("example.tld"))
161+
.setRegistrarId(oteAccount1)
162+
.setType(Type.DOMAIN_CREATE)
163+
.setXmlBytes(null) // explicitly null
164+
.setModificationTime(now)
165+
.build());
166+
167+
OteStats stats = OteStats.getFromRegistrar("blobio");
168+
169+
// It should count towards the basic DOMAIN_CREATES
170+
assertThat(stats.getCount(StatType.DOMAIN_CREATES)).isEqualTo(1);
171+
172+
// It should NOT count towards any stat type that requires EPP input filtering
173+
assertThat(stats.getCount(StatType.DOMAIN_CREATES_ASCII)).isEqualTo(0);
174+
assertThat(stats.getCount(StatType.DOMAIN_CREATES_IDN)).isEqualTo(0);
175+
assertThat(stats.getCount(StatType.DOMAIN_CREATES_START_DATE_SUNRISE)).isEqualTo(0);
176+
assertThat(stats.getCount(StatType.DOMAIN_CREATES_WITH_CLAIMS_NOTICE)).isEqualTo(0);
177+
assertThat(stats.getCount(StatType.DOMAIN_CREATES_WITH_FEE)).isEqualTo(0);
178+
assertThat(stats.getCount(StatType.DOMAIN_CREATES_WITH_SEC_DNS)).isEqualTo(0);
179+
assertThat(stats.getCount(StatType.DOMAIN_CREATES_WITHOUT_SEC_DNS)).isEqualTo(0);
180+
}
140181
}

0 commit comments

Comments
 (0)