Add 57 unit tests across auth (sessions, registration tokens, API tokens, username validation), coffee (roasters, cafes, brews, gear), listing (pagination, sort keys, page calculations), analytics (country stats), images (debug redaction), and entity type (roundtrip serialization).
64 lines
1.5 KiB
Rust
64 lines
1.5 KiB
Rust
use std::fmt;
|
|
|
|
use serde::Deserialize;
|
|
|
|
use crate::domain::entity_type::EntityType;
|
|
|
|
/// An image associated with an entity (roaster, roast, gear, or cafe).
|
|
pub struct EntityImage {
|
|
pub entity_type: EntityType,
|
|
pub entity_id: i64,
|
|
pub content_type: String,
|
|
pub image_data: Vec<u8>,
|
|
pub thumbnail_data: Vec<u8>,
|
|
}
|
|
|
|
/// Wrapper for image data URLs that redacts content in `Debug` output,
|
|
/// allowing payloads to be traced without logging raw base64 image data.
|
|
#[derive(Default, Deserialize)]
|
|
#[serde(transparent)]
|
|
pub struct ImageData(Option<String>);
|
|
|
|
impl ImageData {
|
|
pub fn into_inner(self) -> Option<String> {
|
|
self.0
|
|
}
|
|
|
|
pub fn as_deref(&self) -> Option<&str> {
|
|
self.0.as_deref()
|
|
}
|
|
|
|
pub fn take(&mut self) -> Option<String> {
|
|
self.0.take()
|
|
}
|
|
|
|
pub fn cloned(&self) -> Option<String> {
|
|
self.0.clone()
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for ImageData {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match &self.0 {
|
|
Some(_) => write!(f, "Some(<image>)"),
|
|
None => write!(f, "None"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn image_data_debug_redacts_some() {
|
|
let data: ImageData = serde_json::from_str(r#""data:image/png;base64,abc""#).unwrap();
|
|
assert_eq!(format!("{data:?}"), "Some(<image>)");
|
|
}
|
|
|
|
#[test]
|
|
fn image_data_debug_shows_none() {
|
|
let data = ImageData::default();
|
|
assert_eq!(format!("{data:?}"), "None");
|
|
}
|
|
}
|