1616
1717import static com .google .common .truth .Truth .assertThat ;
1818import 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
2024import google .registry .model .OteStats .StatType ;
25+ import google .registry .model .domain .DomainHistory ;
26+ import google .registry .model .reporting .HistoryEntry .Type ;
2127import google .registry .persistence .transaction .JpaTestExtensions ;
2228import google .registry .persistence .transaction .JpaTestExtensions .JpaIntegrationTestExtension ;
29+ import java .time .Instant ;
2330import org .junit .jupiter .api .BeforeEach ;
2431import org .junit .jupiter .api .Test ;
2532import 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