Skip to content

Commit

Permalink
feat: more granular details on vies faults (#6)
Browse files Browse the repository at this point in the history
### Why?

For different reasons, government databases sometimes can't respond to
whether a `TaxId` is verified or unverified. The `VerificationStatus` is
set to `Unavailable` upon such responses.

However, more granular details should be provided to the client as some
faults/errors are a result of their behaviour or should impact their
behaviour. Examples would be when the client has been blocked or
rate-limited.

### What changed?

- Verification is extended with a `data` HashMap.
- Faults are mapped into data
- Successful responses are mapped into data as well (details like
address etc)
  • Loading branch information
Mollemoll authored May 6, 2024
1 parent 8e3210a commit 10ba4fb
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
36 changes: 25 additions & 11 deletions src/eu_vat/vies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@ impl VIES {

for node in xml.descendants() {
let tag_name = node.tag_name().name();
if tag_name.trim().is_empty() {
continue;
}

if let Some(text) = node.text() {
hash.insert(tag_name.to_string(), text.to_string());
if text == "---" {
hash.insert(tag_name.to_string(), "".to_string());
} else {
hash.insert(tag_name.to_string(), text.to_string());
}
}
}

Expand Down Expand Up @@ -60,19 +68,23 @@ impl Verifier for VIES {
if fault.is_some() {
return Ok(
Verification::new(
VerificationStatus::Unavailable
VerificationStatus::Unavailable,
hash
)
);
} else {
let verification_status = match hash.get("valid")
.expect("Missing valid field in VIES response")
.as_str() {
"true" => VerificationStatus::Verified,
"false" => VerificationStatus::Unverified,
_ => panic!("Invalid value for valid field in VIES response")
};

Ok(
Verification::new(
if hash.get("valid").unwrap() == "true" {
VerificationStatus::Verified
} else if hash.get("valid").unwrap() == "false" {
VerificationStatus::Unverified
} else {
panic!("Unexpected response")
}
verification_status,
hash
)
)
}
Expand All @@ -95,7 +107,7 @@ mod tests {
<requestDate>2021-01-01+01:00</requestDate>
<valid>true</valid>
<name>Test Company</name>
<address>Test Address</address>
<address>---</address>
</checkVat>
</soapenv:Body>
</soapenv:Envelope>
Expand All @@ -108,7 +120,7 @@ mod tests {
assert_eq!(hash.get("requestDate"), Some(&"2021-01-01+01:00".to_string()));
assert_eq!(hash.get("valid"), Some(&"true".to_string()));
assert_eq!(hash.get("name"), Some(&"Test Company".to_string()));
assert_eq!(hash.get("address"), Some(&"Test Address".to_string()));
assert_eq!(hash.get("address"), Some(&"".to_string()));
}

#[test]
Expand Down Expand Up @@ -174,5 +186,7 @@ mod tests {
let verification = verifier.parse_response(response.to_string()).unwrap();

assert_eq!(*verification.status(), VerificationStatus::Unavailable);
assert_eq!(verification.data().get("faultcode"), Some(&"env:Server".to_string()));
assert_eq!(verification.data().get("faultstring"), Some(&"MS_MAX_CONCURRENT_REQ".to_string()));
}
}
20 changes: 17 additions & 3 deletions src/verification.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use chrono::prelude::*;
use crate::tax_id::TaxId;
use crate::errors::VerificationError;
use std::collections::HashMap;

#[derive(Debug, PartialEq)]
pub enum VerificationStatus {
Expand All @@ -13,17 +14,20 @@ pub enum VerificationStatus {
pub struct Verification {
performed_at: DateTime<Local>,
status: VerificationStatus,
data: HashMap<String, String>,
}

impl Verification {
pub fn new(status: VerificationStatus) -> Verification {
pub fn new(status: VerificationStatus, data: HashMap<String, String>) -> Verification {
Verification {
performed_at: Local::now(),
status,
data,
}
}

pub fn status(&self) -> &VerificationStatus { &self.status }
pub fn data(&self) -> &HashMap<String, String> { &self.data }
}

pub trait Verifier {
Expand All @@ -43,7 +47,10 @@ mod tests {

#[test]
fn test_new_verification() {
let verification = Verification::new(VerificationStatus::Verified);
let verification = Verification::new(
VerificationStatus::Verified,
HashMap::new(),
);
assert_eq!(*verification.status(), VerificationStatus::Verified);
assert_eq!(verification.performed_at.date_naive(), Local::now().date_naive());
}
Expand All @@ -56,8 +63,14 @@ mod tests {
}

fn parse_response(&self, response: String) -> Result<Verification, VerificationError> {
let mut hash = HashMap::new();
hash.insert("key".to_string(), "value".to_string());

if response == "test" {
Ok(Verification::new(VerificationStatus::Verified))
Ok(Verification::new(
VerificationStatus::Verified,
hash
))
} else { panic!("Unexpected response") }
}
}
Expand All @@ -69,5 +82,6 @@ mod tests {
let verification = verifier.verify(&tax_id).unwrap();
assert_eq!(*verification.status(), VerificationStatus::Verified);
assert_eq!(verification.performed_at.date_naive(), Local::now().date_naive());
assert_eq!(verification.data().get("key").unwrap(), "value");
}
}

0 comments on commit 10ba4fb

Please sign in to comment.