Skip to content

Commit

Permalink
test(term): add subscribe integration test case
Browse files Browse the repository at this point in the history
  • Loading branch information
ymgyt committed Jun 3, 2024
1 parent ebadb3c commit 8d9a30d
Show file tree
Hide file tree
Showing 20 changed files with 2,660 additions and 42 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions crates/synd_term/src/application/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
application::{Application, Authenticator, Cache, Config},
client::Client,
config::Categories,
interact::Interactor,
terminal::Terminal,
ui::theme::Theme,
};
Expand All @@ -22,6 +23,7 @@ pub struct ApplicationBuilder<
pub(super) theme: Theme,

pub(super) authenticator: Option<Authenticator>,
pub(super) interactor: Option<Interactor>,
}

impl Default for ApplicationBuilder {
Expand All @@ -34,6 +36,7 @@ impl Default for ApplicationBuilder {
config: (),
theme: (),
authenticator: None,
interactor: None,
}
}
}
Expand All @@ -49,6 +52,7 @@ impl<T1, T2, T3, T4, T5> ApplicationBuilder<(), T1, T2, T3, T4, T5> {
config: self.config,
theme: self.theme,
authenticator: self.authenticator,
interactor: self.interactor,
}
}
}
Expand All @@ -64,6 +68,7 @@ impl<T1, T2, T3, T4, T5> ApplicationBuilder<T1, (), T2, T3, T4, T5> {
config: self.config,
theme: self.theme,
authenticator: self.authenticator,
interactor: self.interactor,
}
}
}
Expand All @@ -82,6 +87,7 @@ impl<T1, T2, T3, T4, T5> ApplicationBuilder<T1, T2, (), T3, T4, T5> {
config: self.config,
theme: self.theme,
authenticator: self.authenticator,
interactor: self.interactor,
}
}
}
Expand All @@ -97,6 +103,7 @@ impl<T1, T2, T3, T4, T5> ApplicationBuilder<T1, T2, T3, (), T4, T5> {
config: self.config,
theme: self.theme,
authenticator: self.authenticator,
interactor: self.interactor,
}
}
}
Expand All @@ -112,6 +119,7 @@ impl<T1, T2, T3, T4, T5> ApplicationBuilder<T1, T2, T3, T4, (), T5> {
config,
theme: self.theme,
authenticator: self.authenticator,
interactor: self.interactor,
}
}
}
Expand All @@ -127,6 +135,7 @@ impl<T1, T2, T3, T4, T5> ApplicationBuilder<T1, T2, T3, T4, T5, ()> {
config: self.config,
theme,
authenticator: self.authenticator,
interactor: self.interactor,
}
}
}
Expand All @@ -139,6 +148,14 @@ impl<T1, T2, T3, T4, T5, T6> ApplicationBuilder<T1, T2, T3, T4, T5, T6> {
..self
}
}

#[must_use]
pub fn interactor(self, interactor: Interactor) -> Self {
Self {
interactor: Some(interactor),
..self
}
}
}

impl ApplicationBuilder<Terminal, Client, Categories, Cache, Config, Theme> {
Expand Down
11 changes: 10 additions & 1 deletion crates/synd_term/src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ impl Application {
config,
theme,
authenticator,
interactor,
} = builder;

let key_handlers = {
Expand All @@ -146,7 +147,7 @@ impl Application {
client,
jobs: Jobs::new(),
components: Components::new(),
interactor: Interactor::new(),
interactor: interactor.unwrap_or_else(Interactor::new),
authenticator: authenticator.unwrap_or_else(Authenticator::new),
in_flight: InFlight::new().with_throbber_timer_interval(config.throbber_timer_interval),
cache,
Expand Down Expand Up @@ -1019,4 +1020,12 @@ impl Application {
self.reset_idle_timer();
}
}

pub async fn reload_cache(&mut self) -> anyhow::Result<()> {
match self.restore_credential().await {
Ok(cred) => self.handle_initial_credential(cred),
Err(err) => return Err(err.into()),
}
Ok(())
}
}
15 changes: 12 additions & 3 deletions crates/synd_term/src/interact/integration_interactor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@ use std::ffi::OsStr;

pub type Interactor = TestInteractor;

pub struct TestInteractor;
pub struct TestInteractor {
editor_buffer: String,
}

impl TestInteractor {
pub fn new() -> Self {
Self {}
Self {
editor_buffer: String::new(),
}
}

pub fn with_buffer(mut self, editor_buffer: impl Into<String>) -> Self {
self.editor_buffer = editor_buffer.into();
self
}

#[allow(clippy::unused_self, clippy::needless_pass_by_value)]
Expand All @@ -16,6 +25,6 @@ impl TestInteractor {

#[allow(clippy::unused_self, clippy::needless_pass_by_value)]
pub fn open_editor<S: AsRef<[u8]>>(&self, _initial_content: S) -> String {
String::new()
self.editor_buffer.clone()
}
}
10 changes: 10 additions & 0 deletions crates/synd_term/src/keymap/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,14 @@ macro_rules! key {
crossterm::event::KeyCode::Enter,
))
};
( tab ) => {
crossterm::event::Event::Key(crossterm::event::KeyEvent::from(
crossterm::event::KeyCode::Tab,
))
};
( $char:literal ) => {
crossterm::event::Event::Key(crossterm::event::KeyEvent::from(
crossterm::event::KeyCode::Char($char),
))
};
}
2 changes: 1 addition & 1 deletion crates/synd_term/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![warn(rustdoc::broken_intra_doc_links)]

pub mod application;
pub(crate) mod auth;
pub mod auth;
pub mod cli;
pub mod client;
pub(crate) mod command;
Expand Down
86 changes: 77 additions & 9 deletions crates/synd_term/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,26 @@
mod test {
use std::path::Path;

use serial_test::file_serial;
use synd_term::key;
use tokio_stream::wrappers::UnboundedReceiverStream;

mod helper;
use crate::test::helper::TestCase;

#[tokio::test(flavor = "multi_thread")]
#[file_serial(a)]
async fn happy() -> anyhow::Result<()> {
async fn login() -> anyhow::Result<()> {
helper::init_tracing();

let test_case = TestCase {
oauth_provider_port: 6000,
mock_port: 6000,
synd_api_port: 6001,
kvsd_port: 47379,
terminal_col_row: (120, 30),
device_flow_case: "case1",
cache_dir: helper::temp_dir().into_path(),
..Default::default()
};
let mut application = test_case.init_app().await?;

let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
let mut event_stream = UnboundedReceiverStream::new(rx);
let (tx, mut event_stream) = helper::event_stream();

{
application
Expand All @@ -40,7 +36,7 @@ mod test {

{
// push enter => start auth flow
tx.send(Ok(key!(enter))).unwrap();
tx.send(key!(enter));
application.event_loop_until_idle(&mut event_stream).await;
insta::with_settings!({
description => "show device flow code",
Expand Down Expand Up @@ -107,4 +103,76 @@ mod test {
.assert()
.success();
}

#[tokio::test(flavor = "multi_thread")]
async fn subscribe_then_unsubscribe() -> anyhow::Result<()> {
helper::init_tracing();

let test_case = TestCase {
mock_port: 6010,
synd_api_port: 6011,
kvsd_port: 47389,
terminal_col_row: (120, 30),
interactor_buffer: Some("should rust http://localhost:6010/feed/twir_atom".into()),
..Default::default()
}
.already_logined();

let mut application = test_case.init_app().await?;
let (tx, mut event_stream) = helper::event_stream();

{
// Move tab to feeds
tx.send(key!(tab));
application
.wait_until_jobs_completed(&mut event_stream)
.await;
insta::with_settings!({
description => "after feeds tab move",
},{
insta::assert_debug_snapshot!("subscribe_then_unsubscribe_landing_feeds", application.buffer());
});
}

{
// Subscribe
tx.send(key!('a'));
application
.wait_until_jobs_completed(&mut event_stream)
.await;
insta::with_settings!({
description => "after parsing editor buffer for subscribe",
},{
insta::assert_debug_snapshot!("subscribe_then_unsubscribe_after_editor_parse", application.buffer());
});
}

{
// Unsubscribe popup
tx.send(key!('d'));
application
.wait_until_jobs_completed(&mut event_stream)
.await;
insta::with_settings!({
description => "unsubscribe popup",
},{
insta::assert_debug_snapshot!("subscribe_then_unsubscribe_unsubscribe_popup", application.buffer());
});
}

{
// Select Yes (assuming Yes is selected)
tx.send(key!(enter));
application
.wait_until_jobs_completed(&mut event_stream)
.await;
insta::with_settings!({
description => "after unsubscribe",
},{
insta::assert_debug_snapshot!("subscribe_then_unsubscribe_unsubscribed", application.buffer());
});
}

Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
source: crates/synd_term/tests/integration.rs
description: after parsing editor buffer for subscribe
expression: application.buffer()
---
Buffer {
area: Rect { x: 0, y: 0, width: 120, height: 30 },
content: [
" Syndicationd 󱉯 Entries σ°‘« Feeds ",
" 󰈢 Filter MAY  ",
"  Search ",
" ",
" Updated Feed 1/1 URL Description Req ",
" 2024-05-29  This Week in Rust this-week-in-rust.org SHD▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
" ▐",
"────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────",
" 󰚼 Authors - σ°—€ Src http://localhost:6010/feed/twir_atom ",
" ξ«Έ Generator - σ°ˆ™ Type Atom ",
" ξ­£ Category rust ξ‰— Req SHOULD ",
" ",
" Published Entry Summary ",
" 2024-05-29 This Week in Rust 549 Hello and welcome to another issue of *This Week in Rust*! [Rust][1] ",
" 2024-05-22 This Week in Rust 548 Hello and welcome to another issue of *This Week in Rust*! [Rust][1] ",
" 2024-05-15 This Week in Rust 547 Hello and welcome to another issue of *This Week in Rust*! [Rust][1] ",
" Tab:σ°Ή³ j/k:σ°ΉΉ gg:󱞧 ge:σ±ž₯ h/l:ξ‰— c:ξ­£ /: r:σ°‘“ Ent:󰏌 a:σ°‘« e: d:σ°Ό‘ q: ",
],
styles: [
x: 0, y: 0, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 2, y: 0, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 14, y: 0, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 112, y: 0, fg: Rgb(255, 160, 122), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 119, y: 0, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 2, y: 1, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: DIM,
x: 10, y: 1, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 14, y: 1, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: DIM,
x: 17, y: 1, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 20, y: 1, fg: Rgb(247, 76, 0), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 21, y: 1, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 2, y: 2, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: DIM,
x: 10, y: 2, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 0, y: 4, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD | UNDERLINED,
x: 0, y: 5, fg: Rgb(255, 160, 122), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 119, y: 5, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 0, y: 6, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 2, y: 21, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 11, y: 21, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 49, y: 21, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 56, y: 21, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 2, y: 22, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 13, y: 22, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 49, y: 22, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 56, y: 22, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 2, y: 23, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 12, y: 23, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 49, y: 23, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD,
x: 56, y: 23, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 2, y: 25, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: BOLD | UNDERLINED,
x: 118, y: 25, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 23, y: 29, fg: Rgb(111, 93, 99), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
x: 98, y: 29, fg: Rgb(254, 205, 178), bg: Rgb(43, 41, 45), underline: Reset, modifier: NONE,
]
}
Loading

0 comments on commit 8d9a30d

Please sign in to comment.