// client/tests/form_tests.rs use rstest::{fixture, rstest}; use std::collections::HashMap; use client::state::pages::form::{FormState, FieldDefinition}; use client::state::pages::canvas_state::CanvasState; #[fixture] fn test_form_state() -> FormState { let fields = vec![ FieldDefinition { display_name: "Company".to_string(), data_key: "firma".to_string(), is_link: false, link_target_table: None, }, FieldDefinition { display_name: "Phone".to_string(), data_key: "telefon".to_string(), is_link: false, link_target_table: None, }, FieldDefinition { display_name: "Email".to_string(), data_key: "email".to_string(), is_link: false, link_target_table: None, }, ]; FormState::new("test_profile".to_string(), "test_table".to_string(), fields) } #[fixture] fn test_form_data() -> HashMap { let mut data = HashMap::new(); data.insert("firma".to_string(), "Test Company".to_string()); data.insert("telefon".to_string(), "+421123456789".to_string()); data.insert("email".to_string(), "test@example.com".to_string()); data } #[rstest] fn test_form_state_creation(test_form_state: FormState) { assert_eq!(test_form_state.profile_name, "test_profile"); assert_eq!(test_form_state.table_name, "test_table"); assert_eq!(test_form_state.fields.len(), 3); assert_eq!(test_form_state.current_field(), 0); assert!(!test_form_state.has_unsaved_changes()); } #[rstest] fn test_form_field_navigation(mut test_form_state: FormState) { // Test initial field assert_eq!(test_form_state.current_field(), 0); // Test navigation to next field test_form_state.set_current_field(1); assert_eq!(test_form_state.current_field(), 1); // Test navigation to last field test_form_state.set_current_field(2); assert_eq!(test_form_state.current_field(), 2); // Test invalid field (should not crash) test_form_state.set_current_field(999); assert_eq!(test_form_state.current_field(), 2); // Should stay at valid field } #[rstest] fn test_form_data_entry(mut test_form_state: FormState) { // Test entering data in first field *test_form_state.get_current_input_mut() = "Test Company".to_string(); test_form_state.set_has_unsaved_changes(true); assert_eq!(test_form_state.get_current_input(), "Test Company"); assert!(test_form_state.has_unsaved_changes()); } #[rstest] fn test_form_field_switching_with_data(mut test_form_state: FormState) { // Enter data in first field *test_form_state.get_current_input_mut() = "Company Name".to_string(); // Switch to second field test_form_state.set_current_field(1); *test_form_state.get_current_input_mut() = "+421123456789".to_string(); // Switch back to first field test_form_state.set_current_field(0); assert_eq!(test_form_state.get_current_input(), "Company Name"); // Switch to second field again test_form_state.set_current_field(1); assert_eq!(test_form_state.get_current_input(), "+421123456789"); } #[rstest] fn test_form_reset_functionality(mut test_form_state: FormState) { // Add some data test_form_state.set_current_field(0); *test_form_state.get_current_input_mut() = "Test Company".to_string(); test_form_state.set_current_field(1); *test_form_state.get_current_input_mut() = "+421123456789".to_string(); test_form_state.set_has_unsaved_changes(true); test_form_state.id = 123; test_form_state.current_position = 5; // Reset the form test_form_state.reset_to_empty(); // Verify reset assert_eq!(test_form_state.id, 0); assert!(!test_form_state.has_unsaved_changes()); assert_eq!(test_form_state.current_field(), 0); // Check all fields are empty for i in 0..test_form_state.fields.len() { test_form_state.set_current_field(i); assert!(test_form_state.get_current_input().is_empty()); } } #[rstest] fn test_form_update_from_response(mut test_form_state: FormState, test_form_data: HashMap) { let position = 3; // Update form with response data test_form_state.update_from_response(&test_form_data, position); // Verify data was loaded assert_eq!(test_form_state.current_position, position); assert!(!test_form_state.has_unsaved_changes()); assert_eq!(test_form_state.current_field(), 0); // Check field values test_form_state.set_current_field(0); assert_eq!(test_form_state.get_current_input(), "Test Company"); test_form_state.set_current_field(1); assert_eq!(test_form_state.get_current_input(), "+421123456789"); test_form_state.set_current_field(2); assert_eq!(test_form_state.get_current_input(), "test@example.com"); } #[rstest] fn test_form_cursor_position(mut test_form_state: FormState) { // Test initial cursor position assert_eq!(test_form_state.current_cursor_pos(), 0); // Add some text *test_form_state.get_current_input_mut() = "Test Company".to_string(); // Test cursor positioning test_form_state.set_current_cursor_pos(5); assert_eq!(test_form_state.current_cursor_pos(), 5); // Test cursor bounds test_form_state.set_current_cursor_pos(999); // Should be clamped to text length assert!(test_form_state.current_cursor_pos() <= "Test Company".len()); } #[rstest] fn test_form_field_display_names(test_form_state: FormState) { let field_names = test_form_state.fields(); assert_eq!(field_names.len(), 3); assert_eq!(field_names[0], "Company"); assert_eq!(field_names[1], "Phone"); assert_eq!(field_names[2], "Email"); } #[rstest] fn test_form_inputs_vector(mut test_form_state: FormState) { // Add data to fields test_form_state.set_current_field(0); *test_form_state.get_current_input_mut() = "Company A".to_string(); test_form_state.set_current_field(1); *test_form_state.get_current_input_mut() = "123456789".to_string(); test_form_state.set_current_field(2); *test_form_state.get_current_input_mut() = "test@test.com".to_string(); // Get inputs vector let inputs = test_form_state.inputs(); assert_eq!(inputs.len(), 3); assert_eq!(inputs[0], "Company A"); assert_eq!(inputs[1], "123456789"); assert_eq!(inputs[2], "test@test.com"); } #[rstest] fn test_form_position_management(mut test_form_state: FormState) { // Test initial position assert_eq!(test_form_state.current_position, 1); assert_eq!(test_form_state.total_count, 0); // Set some values test_form_state.total_count = 10; test_form_state.current_position = 5; assert_eq!(test_form_state.current_position, 5); assert_eq!(test_form_state.total_count, 10); // Test reset affects position test_form_state.reset_to_empty(); assert_eq!(test_form_state.current_position, 11); // total_count + 1 } #[rstest] fn test_form_autocomplete_state(mut test_form_state: FormState) { // Test initial autocomplete state assert!(!test_form_state.autocomplete_active); assert!(test_form_state.autocomplete_suggestions.is_empty()); assert!(test_form_state.selected_suggestion_index.is_none()); // Test deactivating autocomplete test_form_state.autocomplete_active = true; test_form_state.deactivate_autocomplete(); assert!(!test_form_state.autocomplete_active); assert!(test_form_state.autocomplete_suggestions.is_empty()); assert!(test_form_state.selected_suggestion_index.is_none()); assert!(!test_form_state.autocomplete_loading); } #[rstest] fn test_form_empty_data_handling(mut test_form_state: FormState) { let empty_data = HashMap::new(); // Update with empty data test_form_state.update_from_response(&empty_data, 1); // All fields should be empty for i in 0..test_form_state.fields.len() { test_form_state.set_current_field(i); assert!(test_form_state.get_current_input().is_empty()); } } #[rstest] fn test_form_partial_data_handling(mut test_form_state: FormState) { let mut partial_data = HashMap::new(); partial_data.insert("firma".to_string(), "Partial Company".to_string()); // Intentionally missing telefon and email test_form_state.update_from_response(&partial_data, 1); // First field should have data test_form_state.set_current_field(0); assert_eq!(test_form_state.get_current_input(), "Partial Company"); // Other fields should be empty test_form_state.set_current_field(1); assert!(test_form_state.get_current_input().is_empty()); test_form_state.set_current_field(2); assert!(test_form_state.get_current_input().is_empty()); }