diff --git a/src/commands/events/mod.rs b/src/commands/events/mod.rs index c888d96561..3ceea04d13 100644 --- a/src/commands/events/mod.rs +++ b/src/commands/events/mod.rs @@ -24,8 +24,8 @@ pub fn make_command(mut command: Command) -> Command { .about("Manage events on Sentry.") .subcommand_required(true) .arg_required_else_help(true) - .org_arg() - .project_arg(true); + .org_arg_with_id() + .project_arg_with_id(true); each_subcommand!(add_subcommand); command } diff --git a/src/utils/args.rs b/src/utils/args.rs index d017437e5f..b0da470c96 100644 --- a/src/utils/args.rs +++ b/src/utils/args.rs @@ -76,7 +76,9 @@ pub fn get_timestamp(value: &str) -> Result> { pub trait ArgExt: Sized { fn org_arg(self) -> Self; + fn org_arg_with_id(self) -> Self; fn project_arg(self, multiple: bool) -> Self; + fn project_arg_with_id(self, multiple: bool) -> Self; fn release_arg(self) -> Self; fn version_arg(self, global: bool) -> Self; } @@ -94,6 +96,18 @@ impl<'a: 'b, 'b> ArgExt for Command { ) } + fn org_arg_with_id(self) -> Command { + self.arg( + Arg::new("org") + .value_name("ORG") + .long("org") + .short('o') + .value_parser(validate_org) + .global(true) + .help("The organization id or slug."), + ) + } + fn project_arg(self, multiple: bool) -> Command { self.arg( Arg::new("project") @@ -111,6 +125,23 @@ impl<'a: 'b, 'b> ArgExt for Command { ) } + fn project_arg_with_id(self, multiple: bool) -> Command { + self.arg( + Arg::new("project") + .value_name("PROJECT") + .long("project") + .short('p') + .value_parser(validate_project) + .global(true) + .action(if multiple { + ArgAction::Append + } else { + ArgAction::Set + }) + .help("The project id or slug."), + ) + } + fn release_arg(self) -> Command { self.arg( Arg::new("release") diff --git a/tests/integration/_cases/events/events-help.trycmd b/tests/integration/_cases/events/events-help.trycmd index 94b65b182f..bf679e2e5e 100644 --- a/tests/integration/_cases/events/events-help.trycmd +++ b/tests/integration/_cases/events/events-help.trycmd @@ -10,10 +10,10 @@ Commands: help Print this message or the help of the given subcommand(s) Options: - -o, --org The organization slug + -o, --org The organization id or slug. --header Custom headers that should be attached to all requests in key:value format. - -p, --project The project slug. + -p, --project The project id or slug. --auth-token Use the given Sentry auth token. --log-level Set the log output verbosity. [possible values: trace, debug, info, warn, error] diff --git a/tests/integration/_cases/events/events-list-empty-id.trycmd b/tests/integration/_cases/events/events-list-empty-id.trycmd new file mode 100644 index 0000000000..98c0dc0f63 --- /dev/null +++ b/tests/integration/_cases/events/events-list-empty-id.trycmd @@ -0,0 +1,6 @@ +``` +$ sentry-cli events list --org 123 --project 1234 +? success +No events found + +``` diff --git a/tests/integration/_cases/events/events-list-help.trycmd b/tests/integration/_cases/events/events-list-help.trycmd index bd953bf8a6..1ca69eeef1 100644 --- a/tests/integration/_cases/events/events-list-help.trycmd +++ b/tests/integration/_cases/events/events-list-help.trycmd @@ -6,11 +6,11 @@ List all events in your organization. Usage: sentry-cli[EXE] events list [OPTIONS] Options: - -o, --org The organization slug + -o, --org The organization id or slug. -U, --show-user Display the Users column. --header Custom headers that should be attached to all requests in key:value format. - -p, --project The project slug. + -p, --project The project id or slug. -T, --show-tags Display the Tags column. --auth-token Use the given Sentry auth token. --max-rows Maximum number of rows to print. diff --git a/tests/integration/_cases/events/events-list-id.trycmd b/tests/integration/_cases/events/events-list-id.trycmd new file mode 100644 index 0000000000..c2b9328bdd --- /dev/null +++ b/tests/integration/_cases/events/events-list-id.trycmd @@ -0,0 +1,12 @@ +``` +$ sentry-cli events list --org 123 --project 1234 +? success ++--------------------------------------+----------------------+--------------------+ +| Event ID | Date | Title | ++--------------------------------------+----------------------+--------------------+ +| 12345612-3456-1234-5612-345612345612 | 2024-07-10T16:45:57Z | Test Error Title | +| 12345671-2345-6712-3456-712345671234 | 2024-07-11T16:45:57Z | Test Error Title 2 | ++--------------------------------------+----------------------+--------------------+ + +``` + diff --git a/tests/integration/_cases/events/events-list.trycmd b/tests/integration/_cases/events/events-list.trycmd new file mode 100644 index 0000000000..05815f5026 --- /dev/null +++ b/tests/integration/_cases/events/events-list.trycmd @@ -0,0 +1,12 @@ +``` +$ sentry-cli events list +? success ++--------------------------------------+----------------------+--------------------+ +| Event ID | Date | Title | ++--------------------------------------+----------------------+--------------------+ +| 12345612-3456-1234-5612-345612345612 | 2024-07-10T16:45:57Z | Test Error Title | +| 12345671-2345-6712-3456-712345671234 | 2024-07-11T16:45:57Z | Test Error Title 2 | ++--------------------------------------+----------------------+--------------------+ + +``` + diff --git a/tests/integration/_cases/events/events-no-subcommand.trycmd b/tests/integration/_cases/events/events-no-subcommand.trycmd index 05b40a9404..1e204af641 100644 --- a/tests/integration/_cases/events/events-no-subcommand.trycmd +++ b/tests/integration/_cases/events/events-no-subcommand.trycmd @@ -10,10 +10,10 @@ Commands: help Print this message or the help of the given subcommand(s) Options: - -o, --org The organization slug + -o, --org The organization id or slug. --header Custom headers that should be attached to all requests in key:value format. - -p, --project The project slug. + -p, --project The project id or slug. --auth-token Use the given Sentry auth token. --log-level Set the log output verbosity. [possible values: trace, debug, info, warn, error] diff --git a/tests/integration/_responses/events/list-events.json b/tests/integration/_responses/events/list-events.json new file mode 100644 index 0000000000..0dd8329784 --- /dev/null +++ b/tests/integration/_responses/events/list-events.json @@ -0,0 +1,66 @@ +[ + { + "id": "id1", + "event.type": "error", + "groupID": "1234", + "eventID": "12345612345612345612345612345612", + "projectID": "1", + "message": "Test Error Message", + "title": "Test Error Title", + "location": "location.py", + "culprit": "/culprit/", + "user": { + "id": null, + "email": null, + "username": null, + "ip_address": null, + "name": null, + "data": null + }, + "tags": [ + { + "key": "environment", + "value": "[rpf" + }, + { + "key": "handled", + "value": "yes" + }, + { + "key": "level", + "value": "error" + } + ], + "platform": "python", + "dateCreated": "2024-07-10T16:45:57Z", + "crashFile": null + }, + { + "id": "id2", + "event.type": "error", + "groupID": "12345", + "eventID": "12345671234567123456712345671234", + "projectID": "1", + "message": "Test Error Message 2", + "title": "Test Error Title 2", + "location": "location.py", + "culprit": "/culprit/", + "user": { + "id": null, + "email": null, + "username": null, + "ip_address": null, + "name": null, + "data": null + }, + "tags": [ + { + "key": "environment", + "value": "prod" + } + ], + "platform": "python", + "dateCreated": "2024-07-11T16:45:57Z", + "crashFile": null + } +] \ No newline at end of file diff --git a/tests/integration/events/list.rs b/tests/integration/events/list.rs index 56221ed375..891f212212 100644 --- a/tests/integration/events/list.rs +++ b/tests/integration/events/list.rs @@ -17,3 +17,34 @@ fn doesnt_fail_with_empty_response() { ); register_test("events/events-list-empty.trycmd"); } + +#[test] +fn doesnt_fail_with_empty_response_id() { + let _server = mock_endpoint( + EndpointOptions::new("GET", "/api/0/projects/123/1234/events/?cursor=", 200) + .with_response_body("[]"), + ); + register_test("events/events-list-empty-id.trycmd"); +} + +#[test] +fn command_events_list() { + let _server = mock_endpoint( + EndpointOptions::new( + "GET", + "/api/0/projects/wat-org/wat-project/events/?cursor=", + 200, + ) + .with_response_file("events/list-events.json"), + ); + register_test("events/events-list.trycmd"); +} + +#[test] +fn command_events_list_id() { + let _server = mock_endpoint( + EndpointOptions::new("GET", "/api/0/projects/123/1234/events/?cursor=", 200) + .with_response_file("events/list-events.json"), + ); + register_test("events/events-list-id.trycmd"); +}