use assinafy::models::{
ArtifactName, AssignmentMethod, DocumentStatus, NotificationMethod, TemplateStatus,
VerificationMethod,
};
use assinafy::resources::{
ApiKeyResponse, ConfirmSignerDataBody, CreateAssignmentBody, CreateAssignmentSigner, LoginBody,
RequestPasswordResetBody, SendTokenBody, SocialLoginBody, TemplateDocumentSigner,
UpdateTagBody, VerifyCodeBody,
};
use assinafy::{Auth, BaseUrl, Client, Envelope};
#[test]
fn base_url_join_appends_trailing_slash() {
let u = BaseUrl::Sandbox.as_url();
assert!(u.as_str().ends_with('/'));
let joined = u.join("accounts/abc/signers").unwrap();
assert_eq!(
joined.as_str(),
"https://sandbox.assinafy.com.br/v1/accounts/abc/signers"
);
}
#[test]
fn base_url_custom_normalises_trailing_slash() {
let u = BaseUrl::custom("https://example.test/api").unwrap();
let joined = u.as_url().join("docs/statuses").unwrap();
assert_eq!(joined.as_str(), "https://example.test/api/docs/statuses");
}
#[test]
fn document_status_round_trips_known_and_unknown() {
let s: DocumentStatus = serde_json::from_str("\"certificated\"").unwrap();
assert_eq!(s, DocumentStatus::Certificated);
let s: DocumentStatus = serde_json::from_str("\"future_status\"").unwrap();
assert_eq!(s, DocumentStatus::Unknown("future_status".to_owned()));
assert_eq!(s.as_str(), "future_status");
}
#[test]
fn template_status_handles_unknown() {
let s: TemplateStatus = serde_json::from_str("\"new-state\"").unwrap();
assert_eq!(s, TemplateStatus::Unknown("new-state".into()));
assert_eq!(s.to_string(), "new-state");
}
#[test]
fn template_status_accepts_capitalized_api_values() {
let s: TemplateStatus = serde_json::from_str("\"Ready\"").unwrap();
assert_eq!(s, TemplateStatus::Ready);
}
#[test]
fn assignment_method_serializes_lowercase() {
let s = serde_json::to_string(&AssignmentMethod::Virtual).unwrap();
assert_eq!(s, "\"virtual\"");
let s = serde_json::to_string(&AssignmentMethod::Collect).unwrap();
assert_eq!(s, "\"collect\"");
}
#[test]
fn verification_and_notification_methods_use_capitalised_strings() {
assert_eq!(VerificationMethod::Email.as_str(), "Email");
assert_eq!(NotificationMethod::Whatsapp.as_str(), "Whatsapp");
let v: VerificationMethod = serde_json::from_str("\"Email\"").unwrap();
assert_eq!(v, VerificationMethod::Email);
}
#[test]
fn artifact_name_round_trip() {
assert_eq!(ArtifactName::from("original"), ArtifactName::Original);
assert_eq!(
ArtifactName::from("custom-thing"),
ArtifactName::Other("custom-thing".into())
);
assert_eq!(ArtifactName::Certificated.as_str(), "certificated");
}
#[test]
fn envelope_decodes_signer_payload() {
let body = r#"{"status":200,"message":"","data":{"resource":"signer","id":"abc","full_name":"Bill","email":"b@e.com","whatsapp_phone_number":null,"has_accepted_terms":false}}"#;
let env: Envelope<assinafy::models::Signer> = serde_json::from_str(body).unwrap();
assert_eq!(env.status, 200);
assert_eq!(env.data.full_name, "Bill");
assert_eq!(env.data.email.as_deref(), Some("b@e.com"));
}
#[test]
fn client_builder_carries_auth_and_base_url() {
let client = Client::builder()
.api_key("k")
.sandbox()
.user_agent("ci/1.0")
.build()
.unwrap();
assert_eq!(
client.base_url().as_str(),
"https://sandbox.assinafy.com.br/v1/"
);
assert!(matches!(client.auth(), Auth::ApiKey(k) if k == "k"));
}
#[test]
fn client_with_auth_swaps_credential() {
let client = Client::builder().api_key("k").build().unwrap();
let bumped = client.with_auth(Auth::Bearer("token".into()));
assert!(matches!(bumped.auth(), Auth::Bearer(t) if t == "token"));
assert!(matches!(client.auth(), Auth::ApiKey(_)));
}
#[test]
fn auth_debug_redacts_credentials() {
let rendered = format!(
"{:?} {:?} {:?} {:?}",
Auth::ApiKey("secret".into()),
Auth::Bearer("token".into()),
Auth::AccessToken("query-token".into()),
Auth::AccessCode("access".into())
);
assert!(!rendered.contains("secret"));
assert!(!rendered.contains("token"));
assert!(!rendered.contains("query-token"));
assert!(!rendered.contains("access"));
assert!(rendered.contains("redacted"));
}
#[test]
fn api_key_response_accepts_missing_key() {
let response: ApiKeyResponse = serde_json::from_str(r#"{"api_key":null}"#).unwrap();
assert_eq!(response.api_key, None);
}
#[test]
fn documented_public_send_token_body_shape() {
let body = serde_json::to_value(SendTokenBody::email("bill@example.com")).unwrap();
assert_eq!(
body,
serde_json::json!({
"recipient": "bill@example.com",
"channel": "email"
})
);
}
#[test]
fn verify_code_body_uses_documented_field_names() {
let body =
serde_json::to_value(VerifyCodeBody::new("123456").access_code("signer-code")).unwrap();
assert_eq!(
body,
serde_json::json!({
"verification-code": "123456",
"signer-access-code": "signer-code"
})
);
}
#[test]
fn assignment_create_body_uses_current_signers_shape() {
let body =
CreateAssignmentBody::new(AssignmentMethod::Virtual, ["s1", "s2"]).copy_receivers(["c1"]);
let json = serde_json::to_value(body).unwrap();
assert_eq!(
json["signers"],
serde_json::json!([{ "id": "s1" }, { "id": "s2" }])
);
assert_eq!(json["copy_receivers"], serde_json::json!(["c1"]));
assert!(json.get("signer_ids").is_none());
assert!(json.get("signerIds").is_none());
}
#[test]
fn assignment_body_can_still_emit_legacy_signer_ids() {
let body = CreateAssignmentBody::from_signers(AssignmentMethod::Virtual, [])
.legacy_signer_ids(["s1", "s2"]);
let json = serde_json::to_value(body).unwrap();
assert_eq!(json["signer_ids"], serde_json::json!(["s1", "s2"]));
assert!(json.get("signers").is_none());
}
#[test]
fn assignment_signer_builder_sets_method_channels_and_step() {
let signer = CreateAssignmentSigner::new("s1")
.verification_method(VerificationMethod::Whatsapp)
.notification_methods(vec![NotificationMethod::Whatsapp])
.step(2);
let json = serde_json::to_value(signer).unwrap();
assert_eq!(
json,
serde_json::json!({
"id": "s1",
"verification_method": "Whatsapp",
"notification_methods": ["Whatsapp"],
"step": 2
})
);
}
#[test]
fn assignment_signer_default_omits_empty_id_for_estimates() {
let json = serde_json::to_value(CreateAssignmentSigner::default()).unwrap();
assert_eq!(json, serde_json::json!({}));
}
#[test]
fn template_document_signer_role_can_be_role_only_for_estimates() {
let json = serde_json::to_value(TemplateDocumentSigner::role("role_123")).unwrap();
assert_eq!(json, serde_json::json!({ "role_id": "role_123" }));
}
#[test]
fn update_tag_body_can_clear_color() {
let json = serde_json::to_value(UpdateTagBody::new().clear_color()).unwrap();
assert_eq!(json, serde_json::json!({ "color": null }));
}
#[test]
fn auth_request_builders_emit_documented_fields() {
assert_eq!(
serde_json::to_value(LoginBody::new("bill@example.com", "secret")).unwrap(),
serde_json::json!({ "email": "bill@example.com", "password": "secret" })
);
assert_eq!(
serde_json::to_value(RequestPasswordResetBody::new("bill@example.com")).unwrap(),
serde_json::json!({ "email": "bill@example.com" })
);
assert_eq!(
serde_json::to_value(SocialLoginBody::google("token", true)).unwrap(),
serde_json::json!({
"provider": "google",
"token": "token",
"has_accepted_terms": true
})
);
}
#[test]
fn signer_confirmation_builder_can_set_all_documented_fields() {
let json = serde_json::to_value(
ConfirmSignerDataBody::new()
.full_name("Bill Murray")
.email("bill@example.com")
.whatsapp("+5548999990000")
.accepted_terms(true)
.verification_code("123456"),
)
.unwrap();
assert_eq!(
json,
serde_json::json!({
"full_name": "Bill Murray",
"email": "bill@example.com",
"whatsapp_phone_number": "+5548999990000",
"has_accepted_terms": true,
"code": "123456"
})
);
}
#[test]
fn public_send_token_supports_whatsapp_channel() {
let body = serde_json::to_value(SendTokenBody::whatsapp("+5548999990000")).unwrap();
assert_eq!(
body,
serde_json::json!({
"recipient": "+5548999990000",
"channel": "whatsapp"
})
);
}
#[test]
fn webhook_dispatch_preserves_resource_discriminator() {
let dispatch: assinafy::models::WebhookDispatch = serde_json::from_value(serde_json::json!({
"resource": "activity_dispatching_history",
"id": "dispatch_1",
"event": "document_ready"
}))
.unwrap();
assert_eq!(
dispatch.resource.as_deref(),
Some("activity_dispatching_history")
);
}
#[test]
fn template_default_document_tag_can_include_color() {
let tag: assinafy::models::TemplateTagRef = serde_json::from_value(serde_json::json!({
"id": "tag_1",
"name": "Contracts",
"color": "ff8800"
}))
.unwrap();
assert_eq!(tag.color.as_deref(), Some("ff8800"));
}