Skip to content

Commit 3faeb3b

Browse files
authored
Merge pull request #147 from icann/andy_dev
Builders and Fixes
2 parents e777428 + eaeb79c commit 3faeb3b

File tree

30 files changed

+886
-162
lines changed

30 files changed

+886
-162
lines changed

icann-rdap-cli/src/rt/results.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ mod tests {
440440
#[test]
441441
fn GIVEN_expected_extension_WHEN_rdap_has_THEN_true() {
442442
// GIVEN
443-
let domain = Domain::builder()
443+
let domain = Domain::response_obj()
444444
.extension(Extension::from("foo0"))
445445
.ldh_name("foo.example.com")
446446
.build();
@@ -456,7 +456,7 @@ mod tests {
456456
#[test]
457457
fn GIVEN_expected_extension_WHEN_rdap_does_not_have_THEN_false() {
458458
// GIVEN
459-
let domain = Domain::builder()
459+
let domain = Domain::response_obj()
460460
.extension(Extension::from("foo0"))
461461
.ldh_name("foo.example.com")
462462
.build();
@@ -472,7 +472,7 @@ mod tests {
472472
#[test]
473473
fn GIVEN_compound_expected_extension_WHEN_rdap_has_THEN_true() {
474474
// GIVEN
475-
let domain = Domain::builder()
475+
let domain = Domain::response_obj()
476476
.extension(Extension::from("foo0"))
477477
.ldh_name("foo.example.com")
478478
.build();

icann-rdap-cli/tests/integration/rdap_test_cmd/url.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ async fn GIVEN_url_WHEN_test_THEN_success() {
1111
test_jig.cmd.env_remove("RDAP_BASE_URL");
1212
let mut tx = test_jig.mem.new_tx().await.expect("new transaction");
1313
tx.add_network(
14-
&Network::builder()
14+
&Network::response_obj()
1515
.cidr("10.0.0.0/24")
1616
.build()
1717
.expect("cidr parsing"),

icann-rdap-client/src/md/table.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ mod tests {
293293
source_host: "",
294294
source_type: SourceType::UncategorizedRegistry,
295295
};
296-
let rdap_response = Rfc9083Error::builder()
296+
let rdap_response = Rfc9083Error::response_obj()
297297
.error_code(500)
298298
.build()
299299
.to_response();
@@ -323,7 +323,7 @@ mod tests {
323323
source_host: "",
324324
source_type: SourceType::UncategorizedRegistry,
325325
};
326-
let rdap_response = Rfc9083Error::builder()
326+
let rdap_response = Rfc9083Error::response_obj()
327327
.error_code(500)
328328
.build()
329329
.to_response();
@@ -354,7 +354,7 @@ mod tests {
354354
source_host: "",
355355
source_type: SourceType::UncategorizedRegistry,
356356
};
357-
let rdap_response = Rfc9083Error::builder()
357+
let rdap_response = Rfc9083Error::response_obj()
358358
.error_code(500)
359359
.build()
360360
.to_response();
@@ -387,7 +387,7 @@ mod tests {
387387
source_host: "",
388388
source_type: SourceType::UncategorizedRegistry,
389389
};
390-
let rdap_response = Rfc9083Error::builder()
390+
let rdap_response = Rfc9083Error::response_obj()
391391
.error_code(500)
392392
.build()
393393
.to_response();
@@ -418,7 +418,7 @@ mod tests {
418418
source_host: "",
419419
source_type: SourceType::UncategorizedRegistry,
420420
};
421-
let rdap_response = Rfc9083Error::builder()
421+
let rdap_response = Rfc9083Error::response_obj()
422422
.error_code(500)
423423
.build()
424424
.to_response();
@@ -455,7 +455,7 @@ mod tests {
455455
source_host: "",
456456
source_type: SourceType::UncategorizedRegistry,
457457
};
458-
let rdap_response = Rfc9083Error::builder()
458+
let rdap_response = Rfc9083Error::response_obj()
459459
.error_code(500)
460460
.build()
461461
.to_response();

icann-rdap-common/README.md

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,6 @@ This library can be compiled for WASM targets.
1919
Usage
2020
-----
2121

22-
Create some RDAP objects:
23-
24-
```rust
25-
// create an entity
26-
use icann_rdap_common::response::Entity;
27-
let holder = Entity::builder().handle("foo-BAR").build();
28-
29-
// create an RDAP domain
30-
use icann_rdap_common::response::Domain;
31-
let domain = Domain::builder().ldh_name("example.com").entity(holder.clone()).build();
32-
33-
// create an IP network
34-
use icann_rdap_common::response::Network;
35-
let net = Network::builder().cidr("10.0.0.0/16").entity(holder.clone()).build().unwrap();
36-
37-
// create a nameserver
38-
use icann_rdap_common::response::Nameserver;
39-
let ns = Nameserver::builder().ldh_name("ns1.example.com").entity(holder.clone()).build().unwrap();
40-
41-
// create an autnum
42-
use icann_rdap_common::response::Autnum;
43-
let autnum = Autnum::builder().autnum_range(700..700).entity(holder).build();
44-
```
45-
4622
Parse RDAP JSON:
4723

4824
```rust
@@ -79,6 +55,56 @@ let rdap: RdapResponse = serde_json::from_str(json).unwrap();
7955
assert!(matches!(rdap, RdapResponse::Network(_)));
8056
```
8157

58+
Create some RDAP objects:
59+
60+
```rust
61+
use icann_rdap_common::prelude::*;
62+
63+
// create a simple entity to be used inside other objects with builder().
64+
let holder = Entity::builder().handle("foo-BAR").build();
65+
66+
// create an RDAP domain response object with response_obj()
67+
let domain = Domain::response_obj()
68+
.ldh_name("example.com")
69+
.extension(ExtensionId::IcannRdapResponseProfile1.as_ref())
70+
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide1.as_ref())
71+
.notice(Notice::builder()
72+
.title("Inaccuracy resport")
73+
.description_entry("Things may be wrong. But it isn't our fault.")
74+
.description_entry("Read the policy for more information.")
75+
.build()
76+
)
77+
.entity(holder.clone())
78+
.build();
79+
80+
// create an IP network to be used as a response with response_obj()
81+
let net = Network::response_obj()
82+
.cidr("10.0.0.0/16")
83+
.entity(holder.clone())
84+
.extension(ExtensionId::NroRdapProfile0.as_ref())
85+
.notice(Notice::builder().title("test").build())
86+
.build()
87+
.unwrap();
88+
89+
// create a nameserver for a response
90+
let ns = Nameserver::response_obj()
91+
.ldh_name("ns1.example.com")
92+
.entity(holder.clone())
93+
.extension(ExtensionId::IcannRdapResponseProfile1.as_ref())
94+
.extension(ExtensionId::IcannRdapTechnicalImplementationGuide1.as_ref())
95+
.notice(Notice::builder().title("Inaccuracy resport").build())
96+
.build()
97+
.unwrap();
98+
99+
// create an autnum for a response
100+
let autnum = Autnum::response_obj()
101+
.autnum_range(700..700)
102+
.entity(holder)
103+
.extension(ExtensionId::NroRdapProfile0.as_ref())
104+
.notice(Notice::builder().title("test").build())
105+
.build();
106+
```
107+
82108
RDAP uses jCard, the JSON version of vCard, to model "contact information"
83109
(e.g. postal addresses, phone numbers, etc...). Because jCard is difficult
84110
to use and there might be other contact models standardized by the IETF,

icann-rdap-common/src/check/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ pub enum Check {
304304
LinkObjectClassHasNoSelf = 206,
305305
#[strum(message = "'href' property not found in Link structure as required by RFC 9083")]
306306
LinkMissingHrefProperty = 207,
307+
#[strum(message = "ambiguous follow because the 'href' may not contain an RDAP URL")]
308+
LinkRelatedNotToRdap = 208,
307309

308310
// Domain Variant 300 - 399
309311
#[strum(message = "empty domain variant is ambiguous")]
@@ -533,6 +535,7 @@ impl Check {
533535
| Self::LinkSelfIsNotRdap => CheckClass::StdWarning,
534536
Self::LinkObjectClassHasNoSelf => CheckClass::SpecificationNote,
535537
Self::LinkMissingHrefProperty => CheckClass::StdError,
538+
Self::LinkRelatedNotToRdap => CheckClass::StdWarning,
536539

537540
Self::VariantEmptyDomain => CheckClass::StdWarning,
538541

icann-rdap-common/src/check/types.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::prelude::has_rdap_path;
2+
13
use {
24
crate::prelude::ObjectCommon,
35
std::{any::TypeId, str::FromStr, sync::LazyLock},
@@ -89,6 +91,12 @@ impl GetChecks for Link {
8991
&& RELATED_AND_SELF_LINK_PARENTS.contains(&params.parent_type)
9092
{
9193
items.push(Check::LinkRelatedIsNotRdap.check_item())
94+
} else if media_type.eq(RDAP_MEDIA_TYPE) {
95+
if let Some(ref href) = self.href {
96+
if !has_rdap_path(href) {
97+
items.push(Check::LinkRelatedNotToRdap.check_item())
98+
}
99+
}
92100
}
93101
} else {
94102
items.push(Check::LinkRelatedHasNoType.check_item())
@@ -359,6 +367,7 @@ mod tests {
359367

360368
use crate::{
361369
check::Checks,
370+
media_types::RDAP_MEDIA_TYPE,
362371
prelude::{ToResponse, VectorStringish},
363372
response::{
364373
domain::Domain,
@@ -508,6 +517,37 @@ mod tests {
508517
.expect("link missing check");
509518
}
510519

520+
#[test]
521+
fn test_object_related_link_with_not_rdap_path() {
522+
// GIVEN
523+
let rdap = Domain::builder()
524+
.ldh_name("example.com")
525+
.link(
526+
Link::builder()
527+
.href("https://foo")
528+
.value("https://foo")
529+
.rel("related")
530+
.media_type(RDAP_MEDIA_TYPE)
531+
.build(),
532+
)
533+
.build()
534+
.to_response();
535+
536+
// WHEN
537+
let checks = rdap.get_checks(CheckParams::for_rdap(&rdap));
538+
539+
// THEN
540+
checks
541+
.sub(crate::check::RdapStructure::Links)
542+
.expect("Links not found")
543+
.sub(crate::check::RdapStructure::Link)
544+
.expect("Link not found")
545+
.items
546+
.iter()
547+
.find(|c| c.check == Check::LinkRelatedNotToRdap)
548+
.expect("link missing check");
549+
}
550+
511551
#[test]
512552
fn test_self_link_with_no_type_property() {
513553
// GIVEN
@@ -613,7 +653,7 @@ mod tests {
613653
/// Issue #59
614654
fn test_nameserver_with_self_link_and_notice() {
615655
// GIVEN
616-
let rdap = Nameserver::builder()
656+
let rdap = Nameserver::response_obj()
617657
.ldh_name("example.com")
618658
.notice(Notice(
619659
NoticeOrRemark::builder()
@@ -921,7 +961,7 @@ mod tests {
921961
links: None,
922962
nr_type: None,
923963
};
924-
let rdap = Domain::builder()
964+
let rdap = Domain::response_obj()
925965
.ldh_name("example.com")
926966
.notice(Notice(notice))
927967
.build()

0 commit comments

Comments
 (0)