mangadex_api/v5/upload/begin/chapter_id/
post.rs1use derive_builder::Builder;
44use mangadex_api_schema::v5::UploadSessionData;
45use serde::Serialize;
46use uuid::Uuid;
47
48use crate::HttpClientRef;
49
50#[cfg_attr(
56 feature = "deserializable-endpoint",
57 derive(serde::Deserialize, getset::Getters, getset::Setters)
58)]
59#[derive(Debug, Builder, Serialize, Clone)]
60#[serde(rename_all = "camelCase")]
61#[builder(
62 setter(into, strip_option),
63 build_fn(error = "mangadex_api_types::error::BuilderError")
64)]
65pub struct StartEditChapterSession {
66 #[doc(hidden)]
68 #[serde(skip)]
69 #[builder(pattern = "immutable")]
70 #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
71 pub http_client: HttpClientRef,
72
73 #[serde(skip_serializing)]
74 pub chapter_id: Uuid,
75
76 pub version: u32,
77}
78
79endpoint! {
80 POST ("/upload/begin/{}", chapter_id),
81 #[body auth] StartEditChapterSession,
82 #[rate_limited] UploadSessionData,
83 StartEditChapterSessionBuilder
84}
85
86#[cfg(test)]
87mod tests {
88 use serde_json::json;
89 use time::OffsetDateTime;
90 use url::Url;
91 use uuid::Uuid;
92 use wiremock::matchers::{body_json, header, method, path_regex};
93 use wiremock::{Mock, MockServer, ResponseTemplate};
94
95 use crate::v5::AuthTokens;
96 use crate::{HttpClient, MangaDexClient};
97 use mangadex_api_types::{MangaDexDateTime, RelationshipType};
98
99 #[tokio::test]
100 async fn start_edit_chapter_session_fires_a_request_to_base_url() -> anyhow::Result<()> {
101 let mock_server = MockServer::start().await;
102 let http_client: HttpClient = HttpClient::builder()
103 .base_url(Url::parse(&mock_server.uri())?)
104 .auth_tokens(AuthTokens {
105 session: "sessiontoken".to_string(),
106 refresh: "refreshtoken".to_string(),
107 })
108 .build()?;
109 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
110
111 let chapter_id = Uuid::new_v4();
112 let session_id = Uuid::new_v4();
113
114 let datetime = MangaDexDateTime::new(&OffsetDateTime::now_utc());
115
116 let expected_body = json!({
117 "version": 2,
118 });
119 let response_body = json!({
120 "result": "ok",
121 "response": "entity",
122 "data" : {
123 "id": session_id,
124 "type": "upload_session",
125 "attributes": {
126 "isCommitted": false,
127 "isProcessed": false,
128 "isDeleted": false,
129 "version": 2,
130 "createdAt": datetime.to_string(),
131 "updatedAt": datetime.to_string(),
132 },
133 "relationships": []
134 }
135 });
136
137 Mock::given(method("POST"))
138 .and(path_regex("/upload/begin/[0-9a-fA-F-]+"))
139 .and(header("Authorization", "Bearer sessiontoken"))
140 .and(header("Content-Type", "application/json"))
141 .and(body_json(expected_body))
142 .respond_with(
143 ResponseTemplate::new(200)
144 .insert_header("x-ratelimit-retry-after", "1698723860")
145 .insert_header("x-ratelimit-limit", "40")
146 .insert_header("x-ratelimit-remaining", "39")
147 .set_body_json(response_body),
148 )
149 .expect(1)
150 .mount(&mock_server)
151 .await;
152
153 let res = mangadex_client
154 .upload()
155 .begin()
156 .chapter_id(chapter_id)
157 .post()
158 .version(2_u32)
159 .send()
160 .await?;
161
162 let res = &res.data;
163
164 assert_eq!(res.id, session_id);
165 assert_eq!(res.type_, RelationshipType::UploadSession);
166 assert!(!res.attributes.is_committed);
167 assert!(!res.attributes.is_processed);
168 assert!(!res.attributes.is_deleted);
169 assert_eq!(res.attributes.version, 2);
170 assert_eq!(res.attributes.created_at.to_string(), datetime.to_string());
171 assert_eq!(res.attributes.updated_at.to_string(), datetime.to_string());
172
173 Ok(())
174 }
175}