• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / bibdata / da4a9cd5-78f1-4afd-b9b1-022bf0107b90

18 Aug 2025 04:00PM UTC coverage: 92.367% (-0.2%) from 92.556%
da4a9cd5-78f1-4afd-b9b1-022bf0107b90

Pull #2859

circleci

christinach
Move config.tonl in .cargo to be consistent with the hierarchical structure
see https://doc.rust-lang.org/cargo/reference/config.html#hierarchical-structure

Co-authored-by: Jane Sandberg <sandbergja@users.noreply.github.com>
Pull Request #2859: Support format id structure

41 of 57 new or added lines in 6 files covered. (71.93%)

7 existing lines in 2 files now uncovered.

7019 of 7599 relevant lines covered (92.37%)

425.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.32
/lib/bibdata_rs/src/ephemera/born_digital_collection.rs
1
use crate::solr::SolrDocument;
2

3
use super::CatalogClient;
4
use serde::Deserialize;
5

6
#[derive(Deserialize, Debug)]
7
pub struct FoldersResponse {
8
    pub data: Vec<BornDigitalCollection>,
9
}
10

11
#[allow(dead_code)]
12
#[derive(Deserialize, Debug)]
13
pub struct BornDigitalCollection {
14
    id: String,
15
    links: Links,
16
}
17

18
#[allow(dead_code)]
19
#[derive(Deserialize, Debug)]
20
pub struct Links {
21
    #[serde(rename = "self")]
22
    url: String,
23
}
24
pub async fn read_ephemera_folders(
3✔
25
    url: impl Into<String>,
3✔
26
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
3✔
27
    let client = CatalogClient::new(url.into());
3✔
28
    let response = client.get_folder_data().await?;
3✔
29

30
    let ids: Vec<String> = response.data.into_iter().map(|item| item.id).collect();
3✔
31
    Ok(ids)
3✔
32
}
3✔
33

34
pub async fn ephemera_folders_iterator(
3✔
35
    url: &str,
3✔
36
    chunk_size: usize,
3✔
37
) -> Result<Vec<String>, Box<dyn std::error::Error>> {
3✔
38
    let data: Vec<String> = read_ephemera_folders(url).await?;
3✔
39
    let mut result: Vec<String> = Vec::new();
3✔
40
    for chunk in data.chunks(chunk_size) {
6✔
41
        let chunk_vec: Vec<String> = chunk.to_vec().clone();
6✔
42
        let responses = chunk_read_id(chunk_vec, url).await?;
6✔
43
        result.push(responses);
6✔
44
    }
45
    Ok(result)
3✔
46
}
3✔
47

48
pub async fn chunk_read_id(
6✔
49
    ids: Vec<String>,
6✔
50
    url: &str,
6✔
51
) -> Result<String, Box<dyn std::error::Error>> {
6✔
52
    let mut responses = Vec::new();
6✔
53
    for id in ids {
42✔
54
        let client = CatalogClient::new(url.to_owned());
36✔
55
        let response = client.get_item_data(&id).await?;
36✔
56
        responses.push(SolrDocument::from(&response));
36✔
57
    }
58
    Ok(serde_json::to_string(&responses)?)
6✔
59
}
6✔
60

61
#[cfg(test)]
62
mod tests {
63
    use std::path::PathBuf;
64

65
    use crate::{
66
        ephemera::born_digital_collection::{ephemera_folders_iterator, read_ephemera_folders},
67
        testing_support::preserving_envvar_async,
68
    };
69

70
    #[ignore]
71
    #[tokio::test]
72
    async fn test_read_ephemera_folders() {
×
73
        preserving_envvar_async("FIGGY_BORN_DIGITAL_EPHEMERA_URL", || async {
×
74
            let mut server = mockito::Server::new_async().await;
×
75

×
76
            let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
×
77
            d.push("../../spec/fixtures/files/ephemera/ephemera_folders.json");
×
NEW
78
            let path = "/catalog.json?f%5Bephemera_project_ssim%5D%5B%5D=Born+Digital+Monographic+Reports+and+Papers&f%5Bhuman_readable_type_ssim%5D%5B%5D=Ephemera+Folder&f%5Bstate_ssim%5D%5B%5D=complete&per_page=100&q=";
×
79
            // let path = std::env::var("FIGGY_BORN_DIGITAL_EPHEMERA_URL").unwrap();
×
80
            let mock = server
×
81
                .mock("GET", path)
×
82
                .with_status(200)
×
83
                .with_header("content-type", "application/json")
×
84
                .with_body_from_file(d.to_string_lossy().to_string())
×
85
                .create_async()
×
86
                .await;
×
87

×
88
            let result = read_ephemera_folders(server.url()).await.unwrap();
×
89
            assert!(!result.is_empty());
×
90
            assert!(result.contains(
×
91
                &"https://figgy-staging.princeton.edu/catalog/af4a941d-96a4-463e-9043-cfa511e5eddd"
×
92
                    .to_string()
×
93
            ));
×
94

×
95
            mock.assert_async().await;
×
96
        })
×
97
        .await;
×
98
    }
×
99

100
    #[tokio::test]
101
    async fn test_ephemera_folders_iterator() {
1✔
102
        let mut server = mockito::Server::new_async().await;
1✔
103

104
        let mock1 = server
1✔
105
                .mock("GET", "/catalog.json?f%5Bephemera_project_ssim%5D%5B%5D=Born+Digital+Monographic+Reports+and+Papers&f%5Bhuman_readable_type_ssim%5D%5B%5D=Ephemera+Folder&f%5Bstate_ssim%5D%5B%5D=complete&per_page=100&q=")
1✔
106
                .with_status(200)
1✔
107
                .with_header("content-type", "application/json")
1✔
108
                .with_body_from_file("../../spec/fixtures/files/ephemera/ephemera_folders.json")
1✔
109
                .create();
1✔
110

111
        let mock2 = server
1✔
112
            .mock(
1✔
113
                "GET",
1✔
114
                mockito::Matcher::Regex(
1✔
115
                    r"^/catalog/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}.jsonld$"
1✔
116
                        .to_string(),
1✔
117
                ),
1✔
118
            )
1✔
119
            .with_status(200)
1✔
120
            .with_header("content-type", "application/json")
1✔
121
            .with_body_from_file("../../spec/fixtures/files/ephemera/ephemera1.json")
1✔
122
            .expect(12)
1✔
123
            .create();
1✔
124

125
        let chunk_size = 3;
1✔
126

127
        let result = ephemera_folders_iterator(&server.url(), chunk_size)
1✔
128
            .await
1✔
129
            .unwrap();
1✔
130
        assert!(!result.is_empty());
1✔
131

132
        assert_eq!(result.len(), 4);
1✔
133

134
        mock1.assert();
1✔
135
        mock2.assert();
1✔
136
    }
1✔
137
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc