1use crate::commands::{Mob, Setup, TeamMember};
2use crate::repositories::{MobSessionRepo, TeamMemberRepo};
3use crate::Result;
4use clap::{Parser, Subcommand};
5use std::io::Write;
6use std::str;
7
8#[derive(Parser)]
9#[command(
10 author,
11 version,
12 about,
13 long_about,
14 bin_name = "git mob",
15 override_usage = "git mob [COMMAND] [OPTIONS]"
16)]
17#[command(propagate_version = true)]
18struct Cli {
35 #[command(subcommand)]
36 command: Option<Commands>,
37 #[command(flatten)]
38 mob: Mob,
39}
40
41#[derive(Subcommand)]
42enum Commands {
43 Setup(Setup),
45 #[clap(alias = "coauthor")] TeamMember(TeamMember),
51}
52
53pub fn run(
54 team_member_repo: &impl TeamMemberRepo,
55 mob_repo: &impl MobSessionRepo,
56 out: &mut impl Write,
57) -> Result<()> {
58 let cli = Cli::parse();
59 run_inner(&cli, team_member_repo, mob_repo, out)
60}
61
62fn run_inner(
63 cli: &Cli,
64 team_member_repo: &impl TeamMemberRepo,
65 mob_repo: &impl MobSessionRepo,
66 out: &mut impl Write,
67) -> Result<()> {
68 match &cli.command {
69 None => cli.mob.handle(team_member_repo, mob_repo, out)?,
70 Some(Commands::Setup(setup)) => setup.handle(out)?,
71 Some(Commands::TeamMember(team_member)) => team_member.handle(team_member_repo, out)?,
72 }
73 Ok(())
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use crate::repositories::{MockMobSessionRepo, MockTeamMemberRepo};
80 use mockall::predicate;
81
82 #[test]
83 fn test_clear_mob_session() -> Result<()> {
84 let mock_team_member_repo = MockTeamMemberRepo::new();
85 let mut mock_mob_repo = MockMobSessionRepo::new();
86 mock_mob_repo.expect_clear().once().returning(|| Ok(()));
87
88 let cli = Cli {
89 command: None,
90 mob: Mob {
91 with: None,
92 clear: true,
93 list: false,
94 trailers: false,
95 add: None,
96 },
97 };
98
99 let mut out = Vec::new();
100 run_inner(&cli, &mock_team_member_repo, &mock_mob_repo, &mut out)?;
101
102 Ok(())
103 }
104
105 #[test]
106 fn test_delete_team_member() -> Result<()> {
107 let key = "lm";
108 let mut mock_team_member_repo = MockTeamMemberRepo::new();
109 let mock_mob_repo = MockMobSessionRepo::new();
110 mock_team_member_repo
111 .expect_get()
112 .with(predicate::eq(key))
113 .once()
114 .returning(|_| Ok(Some("Leo Messi <leo.messi@example.com>".to_owned())));
115 mock_team_member_repo
116 .expect_remove()
117 .with(predicate::eq(key))
118 .once()
119 .returning(|_| Ok(()));
120
121 let cli = Cli {
122 command: Some(Commands::TeamMember(TeamMember {
123 delete: Some(key.to_owned()),
124 add: None,
125 list: false,
126 })),
127 mob: Mob {
128 with: None,
129 clear: false,
130 list: false,
131 trailers: false,
132 add: None,
133 },
134 };
135
136 let mut out = Vec::new();
137 run_inner(&cli, &mock_team_member_repo, &mock_mob_repo, &mut out)?;
138
139 Ok(())
140 }
141}