Skip to content

Commit

Permalink
Implement test server setup flow
Browse files Browse the repository at this point in the history
  • Loading branch information
matzipan committed Nov 1, 2023
1 parent 060ff6a commit 681def9
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 17 deletions.
92 changes: 75 additions & 17 deletions app/src/controllers/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use crate::ui;
use std::cell::RefCell;
use std::rc::Rc;

//@TODO find a better place for this
const TEST_SERVER_EMAIL: &str = "[email protected]";

#[derive(Debug)]
pub enum ApplicationMessage {
Setup {},
Expand Down Expand Up @@ -90,6 +93,23 @@ impl ApplicationMessage {
gmail_refresh_token: response_token.refresh_token,
}
}

pub fn save_identity_message_for_test_server() -> ApplicationMessage {
ApplicationMessage::SaveIdentity {
email_address: TEST_SERVER_EMAIL.to_string(),
full_name: "Full name".to_string(),
account_name: "Test".to_string(),
identity_type: models::IdentityType::Imap,
expires_at: DateTime::<Utc>::MAX_UTC,
imap_server_hostname: "127.0.0.1".to_string(),
imap_server_port: 3993,
imap_password: TEST_SERVER_EMAIL.to_string(),
imap_use_tls: true,
imap_use_starttls: false,
gmail_access_token: String::new(),
gmail_refresh_token: String::new(),
}
}
}

fn send_notification(notifications_email_count: &Rc<RefCell<i32>>, new_messages: Vec<NewMessage>, application_obj: &Application) {
Expand Down Expand Up @@ -132,6 +152,7 @@ mod imp {
pub application_message_sender: RefCell<Option<glib::Sender<ApplicationMessage>>>,
pub store: RefCell<Option<Rc<services::Store>>>,
pub notifications_email_count: Rc<RefCell<i32>>,
pub test_server_enabled: Rc<RefCell<bool>>,
}

#[glib::object_subclass]
Expand All @@ -147,29 +168,27 @@ mod imp {
fn activate(&self) {
debug!("Application activate");

{
let mut application_message;
if self.should_set_up_test_server() {
debug!("Test server setup not found. Configuring");

application_message = ApplicationMessage::save_identity_message_for_test_server();
} else {
let store_borrow = self.store.borrow();
let store = store_borrow.as_ref().expect("Unable to access store");
match store.initialize_database() {
Ok(_) => {
let application_message = match store.is_account_setup_needed() {

application_message = match store.is_account_setup_needed() {
true => ApplicationMessage::Setup {},
false => ApplicationMessage::LoadIdentities { initialize: false },
};
}
}

self.application_message_sender
.borrow()
.as_ref()
.expect("Unable to access application message sender")
.send(application_message)
.expect("Unable to send application message");
}
Err(e) => {
//@TODO show an error dialog
error!("Error encountered when initializing the database: {}", &e);
}
}
}

self.parent_activate();

Expand All @@ -184,16 +203,27 @@ mod imp {
fn startup(&self) {
debug!("Application startup");
self.parent_startup();
let app = self.obj();

// Set icons for shell
gtk::Window::set_default_icon_name(APP_ID);

app.setup_css();
app.setup_gactions();
app.setup_accels();
let obj = self.obj();
obj.setup_css();
obj.setup_gactions();
obj.setup_accels();

self.run();
self.setup_database();
}

fn command_line(&self, command_line: &gio::ApplicationCommandLine) -> glib::ExitCode {
if command_line.options_dict().contains(&"with-test-server") {
debug!("Enabling test server setup");
self.enable_test_server_setup();
}

self.obj().activate();

glib::ExitCode::SUCCESS
}
}

Expand Down Expand Up @@ -569,6 +599,34 @@ mod imp {
});
application_obj.add_action(&action_show_conversation_for_email_id);
}

fn setup_database(&self) {
let store_borrow = self.store.borrow();
let store = store_borrow.as_ref().expect("Unable to access store");

store.initialize_database();
}

fn enable_test_server_setup(&self) {
self.test_server_enabled.replace(true);
}

fn should_set_up_test_server(&self) -> bool {
*self.test_server_enabled.borrow() && !self.is_test_server_set_up_already()
}

fn is_test_server_set_up_already(&self) -> bool {
let store_borrow = self.store.borrow();
let store = store_borrow.as_ref().expect("Unable to access store");

store
.get_bare_identities()
.expect("Unable to fetch identities")
.into_iter()
.filter(|identity| &identity.email_address == TEST_SERVER_EMAIL)
.count()
!= 0
}
}
}

Expand Down
33 changes: 33 additions & 0 deletions docs/application_states.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Application states

The following plantuml diagram shows the different application states and the
different application messages that can be delivered and which state
transitions they can lead to.

As can be seen, application states are not very well defined: once the
application reaches the "Running" state, the state remains largely the same.
But the diagram clarifies well the different startup flows.

```plantuml
@startuml
state "Google Authentication" as google_authentication
state "Welcome Dialog" as welcome_dialog
state "Running" as running
state "Identity saved" as identity_saved
state "Fetching conversation content" as fetching_conversation_contect
[*] --> running : LoadIdentities(initialize: false)
[*] --> identity_saved : SaveIdentity(TestServerAccount)
[*] --> welcome_dialog : Setup
welcome_dialog --> google_authentication : OpenGoogleAuthentication
google_authentication -> identity_saved : SaveIdentity(GmailAccount)
identity_saved -> running : LoadIdentities(initialize: true)
running -> running : ShowFolder(folder)
running -> running : ShowConversation(conversation)
running -> running : NewMessages(...)
running -> running : ShowConversationContainingEmail(...)
running -> fetching_conversation_contect : ShowConversation(...)
fetching_conversation_contect -> running : ConversationContentLoadFinished(conversation)
running --> [*]
@enduml
```

0 comments on commit 681def9

Please sign in to comment.