Skip to main content

rhood_core/endpoints/
documents.rs

1use crate::Result;
2use crate::api::paths;
3use crate::client::RobinhoodClient;
4use crate::models::document::{Document, DocumentType};
5
6impl RobinhoodClient {
7    /// Fetches account documents, optionally filtered by type.
8    ///
9    /// # Errors
10    ///
11    /// Returns an error if the HTTP request fails or the response cannot be
12    /// deserialized.
13    pub async fn get_documents(&self, doc_type: Option<DocumentType>) -> Result<Vec<Document>> {
14        let url = self.api_url(paths::DOCUMENTS);
15        match doc_type {
16            Some(filter) => {
17                let filter_string = filter.to_string();
18                self.get_paginated(&url, &[("type", filter_string.as_str())])
19                    .await
20            }
21            None => self.get_paginated(&url, &[]).await,
22        }
23    }
24}
25
26#[cfg(test)]
27mod tests {
28    use crate::models::document::Document;
29
30    #[test]
31    fn document_deserializes() {
32        let json = r#"{
33            "id": "doc-001",
34            "type": "account_statement",
35            "date": "2026-03-31",
36            "download_url": "https://api.robinhood.com/documents/doc-001/download/",
37            "created_at": "2026-04-01T00:00:00Z"
38        }"#;
39        let doc: Document = serde_json::from_str(json).unwrap();
40        assert_eq!(doc.id.as_deref(), Some("doc-001"));
41        assert_eq!(doc.document_type.as_deref(), Some("account_statement"));
42        assert!(doc.download_url.is_some());
43    }
44
45    #[test]
46    fn document_handles_missing_fields() {
47        let json = r#"{"id": "doc-002"}"#;
48        let doc: Document = serde_json::from_str(json).unwrap();
49        assert_eq!(doc.id.as_deref(), Some("doc-002"));
50        assert!(doc.document_type.is_none());
51        assert!(doc.date.is_none());
52    }
53}