feat: add persistent pull request sort and filter menus
This commit is contained in:
@@ -3836,3 +3836,161 @@ fn async_responses_edit_only_current_bound_working_after_and_refresh_projection(
|
||||
session.editor.execute("diff.close");
|
||||
assert!(session.editor.dirty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn applied_pull_request_preferences_survive_startup_without_config() {
|
||||
use crate::pull_requests::ReviewFilter;
|
||||
let fixture = Fixture::new();
|
||||
let path = fixture.0.join("state/pull_requests.json");
|
||||
let mut session =
|
||||
EditorSession::open_with_preferences_path(None, vec![], None, Some(Ok(path.clone())))
|
||||
.unwrap();
|
||||
assert!(!path.exists());
|
||||
session.editor.execute("pull_requests");
|
||||
// Consume the queued listing so menu input cannot start a forge worker.
|
||||
assert!(session.editor.take_diff_request().is_some());
|
||||
session.handle(Input::Ctrl('f'));
|
||||
session.handle(Input::Char(' '));
|
||||
assert!(!path.exists());
|
||||
session.handle(Input::Escape);
|
||||
assert_eq!(
|
||||
session.editor.pull_request_preferences,
|
||||
crate::pull_requests::Preferences::default()
|
||||
);
|
||||
assert!(!path.exists());
|
||||
session.handle(Input::Ctrl('f'));
|
||||
session.handle(Input::Char(' '));
|
||||
session.handle(Input::Down);
|
||||
session.handle(Input::Char(' '));
|
||||
assert!(!path.exists());
|
||||
session.handle(Input::Enter);
|
||||
assert!(path.exists());
|
||||
assert!(!session.editor.pull_request_preferences_changed);
|
||||
let reopened =
|
||||
EditorSession::open_with_preferences_path(None, vec![], None, Some(Ok(path))).unwrap();
|
||||
assert_eq!(
|
||||
reopened.editor.pull_request_preferences.filters,
|
||||
[ReviewFilter::Other]
|
||||
);
|
||||
assert_eq!(reopened.editor.pull_request_configured, [false, false]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn configured_pull_request_sections_replace_only_their_persisted_section() {
|
||||
use crate::pull_requests::{Direction, Preferences, ReviewFilter, SortField, SortRule};
|
||||
let fixture = Fixture::new();
|
||||
let path = fixture.0.join("state/pull_requests.json");
|
||||
let (store, mut preferences, _) =
|
||||
crate::pull_request_preferences::Store::load(Ok(path.clone()));
|
||||
preferences.filters = vec![ReviewFilter::Other];
|
||||
preferences.sort.insert(
|
||||
SortField::UpdatedAt,
|
||||
SortRule {
|
||||
precedence: Some(1),
|
||||
direction: Direction::Asc,
|
||||
},
|
||||
);
|
||||
store.save(&preferences).unwrap();
|
||||
let bytes = fs::read(&path).unwrap();
|
||||
for (configuration, expected, configured) in [
|
||||
(
|
||||
"config.pull_request_sort = {}",
|
||||
Preferences {
|
||||
sort: Default::default(),
|
||||
filters: preferences.filters.clone(),
|
||||
},
|
||||
[true, false],
|
||||
),
|
||||
(
|
||||
"config.pull_request_filters = []",
|
||||
Preferences {
|
||||
sort: preferences.sort.clone(),
|
||||
filters: vec![],
|
||||
},
|
||||
[false, true],
|
||||
),
|
||||
(
|
||||
"config.pull_request_sort = {created_at: {direction: :asc}}; config.pull_request_filters = nil",
|
||||
Preferences {
|
||||
sort: [(
|
||||
SortField::CreatedAt,
|
||||
SortRule {
|
||||
precedence: None,
|
||||
direction: Direction::Asc,
|
||||
},
|
||||
)]
|
||||
.into(),
|
||||
filters: preferences.filters.clone(),
|
||||
},
|
||||
[true, false],
|
||||
),
|
||||
] {
|
||||
let config = fixture.file(
|
||||
"config.rb",
|
||||
&format!("Vamp.configure {{ |config| {configuration} }}"),
|
||||
);
|
||||
let session = EditorSession::open_with_preferences_path(
|
||||
None,
|
||||
vec![],
|
||||
Some(&config),
|
||||
Some(Ok(path.clone())),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(session.editor.pull_request_preferences, expected);
|
||||
assert_eq!(session.editor.pull_request_configured, configured);
|
||||
assert_eq!(fs::read(&path).unwrap(), bytes);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn corrupt_pull_request_storage_warns_and_apply_remains_session_only() {
|
||||
let fixture = Fixture::new();
|
||||
let path = fixture.file("pull_requests.json", "preserve invalid bytes");
|
||||
let mut session =
|
||||
EditorSession::open_with_preferences_path(None, vec![], None, Some(Ok(path.clone())))
|
||||
.unwrap();
|
||||
assert!(session.editor.message().contains("session-only"));
|
||||
session.editor.execute("pull_requests");
|
||||
assert!(session.editor.take_diff_request().is_some());
|
||||
session.handle(Input::Ctrl('f'));
|
||||
for input in [
|
||||
Input::Char(' '),
|
||||
Input::Down,
|
||||
Input::Char(' '),
|
||||
Input::Down,
|
||||
Input::Char(' '),
|
||||
Input::Enter,
|
||||
] {
|
||||
session.handle(input);
|
||||
}
|
||||
assert!(session.editor.message().contains("preserved"));
|
||||
assert!(session.editor.pull_request_preferences.filters.is_empty());
|
||||
assert_eq!(fs::read_to_string(path).unwrap(), "preserve invalid bytes");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_pull_request_save_keeps_applied_session_preferences_and_reports_failure() {
|
||||
let fixture = Fixture::new();
|
||||
let parent = fixture.0.join("state");
|
||||
let path = parent.join("pull_requests.json");
|
||||
let mut session =
|
||||
EditorSession::open_with_preferences_path(None, vec![], None, Some(Ok(path))).unwrap();
|
||||
fs::write(&parent, "do not replace").unwrap();
|
||||
session.editor.execute("pull_requests");
|
||||
assert!(session.editor.take_diff_request().is_some());
|
||||
session.handle(Input::Ctrl('f'));
|
||||
for input in [
|
||||
Input::Char(' '),
|
||||
Input::Down,
|
||||
Input::Char(' '),
|
||||
Input::Down,
|
||||
Input::Char(' '),
|
||||
Input::Enter,
|
||||
] {
|
||||
session.handle(input);
|
||||
}
|
||||
assert!(session.editor.message().contains("session-only"));
|
||||
assert!(session.editor.pull_request_preferences.filters.is_empty());
|
||||
assert!(!session.editor.pull_request_preferences_changed);
|
||||
assert_eq!(fs::read_to_string(parent).unwrap(), "do not replace");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user