use insta_note_clock::{InstagramClient, SessionData}; use serde_json::json; use wiremock::matchers::{method, path}; use wiremock::{Mock, MockServer, ResponseTemplate}; #[tokio::test] async fn test_create_note_success() { let mock_server = MockServer::start().await; // Mock Instagram endpoint POST /notes/create_note Mock::given(method("POST")) .and(path("/notes/create_note")) .respond_with( ResponseTemplate::new(200).set_body_json(json!({ "status": "ok", "id": "18012345678901234", "text": "🕒 14:30", "created_at": 1727364600 })), ) .expect(1) .mount(&mock_server) .await; let session = SessionData::new( "mock_session_id_123".to_string(), "12345678".to_string(), "mock_csrf_token".to_string(), Some("testuser".to_string()), ); let client = InstagramClient::new(Some(mock_server.uri()), Some(session), 30, false); let resp = client.create_note("🕒 14:30").await.expect("Note creation should succeed"); assert_eq!(resp.status, "ok"); assert_eq!(resp.id.unwrap(), "18012345678901234"); assert_eq!(resp.text.unwrap(), "🕒 14:30"); } #[tokio::test] async fn test_delete_note_success() { let mock_server = MockServer::start().await; // Mock Instagram endpoint POST /notes/delete_note/ Mock::given(method("POST")) .and(path("/notes/delete_note/")) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "status": "ok" }))) .expect(1) .mount(&mock_server) .await; let session = SessionData::new( "mock_session_id_123".to_string(), "12345678".to_string(), "mock_csrf_token".to_string(), None, ); let client = InstagramClient::new(Some(mock_server.uri()), Some(session), 30, false); let result = client.delete_note("18012345678901234").await; assert!(result.is_ok()); } #[tokio::test] async fn test_unauthorized_does_not_retry() { let mock_server = MockServer::start().await; // Mock Instagram endpoint POST /notes/create_note returning 401 Unauthorized Mock::given(method("POST")) .and(path("/notes/create_note")) .respond_with(ResponseTemplate::new(401).set_body_json(json!({ "message": "login_required", "status": "fail" }))) .expect(1) // MUST NOT retry upon 401 .mount(&mock_server) .await; let session = SessionData::new( "invalid_session".to_string(), "12345".to_string(), "token".to_string(), None, ); let client = InstagramClient::new(Some(mock_server.uri()), Some(session), 30, false); let result = client.create_note("🕒 14:30").await; assert!(result.is_err()); let err_msg = result.unwrap_err().to_string(); assert!(err_msg.contains("Authentication failed") || err_msg.contains("401")); } #[tokio::test] async fn test_dry_run_does_not_make_http_calls() { let mock_server = MockServer::start().await; // Ensure 0 calls are made to the mock server in dry-run mode Mock::given(method("POST")) .and(path("/notes/create_note")) .respond_with(ResponseTemplate::new(200)) .expect(0) .mount(&mock_server) .await; let session = SessionData::new( "mock_session_id".to_string(), "123".to_string(), "token".to_string(), None, ); let client = InstagramClient::new(Some(mock_server.uri()), Some(session), 30, true); let resp = client.create_note("🕒 14:30").await.expect("Dry run should succeed"); assert_eq!(resp.status, "ok"); assert_eq!(resp.id.unwrap(), "dry-run-note-id"); }