diff --git a/CHANGELOG.md b/CHANGELOG.md index 96291f2384..3078664cd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ - Add `sentry_clear_attachments()` to allow clearing all previously added attachments in the global scope. ([#1290](https://github.com/getsentry/sentry-native/pull/1290)) - Compiles also on Xbox One ([#1294](https://github.com/getsentry/sentry-native/pull/1294)) - Provide `sentry_regenerate_trace()` to allow users to set manual trace boundaries. ([#1293](https://github.com/getsentry/sentry-native/pull/1293)) +- Add `sentry_value_new_feedback` and `sentry_capture_feedback` to allow capturing [User Feedback](https://develop.sentry.dev/sdk/data-model/envelope-items/#user-feedback). ([#1304](https://github.com/getsentry/sentry-native/pull/1304)) + - Deprecate `sentry_value_new_user_feedback` and `sentry_capture_user_feedback` in favor of the new API. **Fixes**: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a4372bf2e8..50cf8bc669 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -189,6 +189,7 @@ The example currently supports the following commands: - `capture-with-scope`: Captures an event with a local scope. - `attach-to-scope`: Same as `attachment` but attaches the file to the local scope. - `clear-attachments`: Clears all attachments from the global scope. +- `capture-user-feedback`: Captures a user feedback event. Only on Linux using crashpad: - `crashpad-wait-for-upload`: Couples application shutdown to complete the upload in the `crashpad_handler`. diff --git a/examples/example.c b/examples/example.c index 2bda9a3399..bb4f1cd5ad 100644 --- a/examples/example.c +++ b/examples/example.c @@ -556,14 +556,22 @@ main(int argc, char **argv) sentry_capture_event(event); } if (has_arg(argc, argv, "capture-user-feedback")) { + sentry_value_t user_feedback = sentry_value_new_feedback( + "some-message", "some-email", "some-name", NULL); + + sentry_capture_feedback(user_feedback); + } + if (has_arg(argc, argv, "capture-user-report")) { sentry_value_t event = sentry_value_new_message_event( SENTRY_LEVEL_INFO, "my-logger", "Hello user feedback!"); sentry_uuid_t event_id = sentry_capture_event(event); + SENTRY_SUPPRESS_DEPRECATED sentry_value_t user_feedback = sentry_value_new_user_feedback( &event_id, "some-name", "some-email", "some-comment"); sentry_capture_user_feedback(user_feedback); + SENTRY_RESTORE_DEPRECATED } if (has_arg(argc, argv, "capture-transaction")) { diff --git a/include/sentry.h b/include/sentry.h index b77393fcbd..16d678bcc4 100644 --- a/include/sentry.h +++ b/include/sentry.h @@ -119,6 +119,21 @@ extern "C" { # endif #endif +#if defined(__GNUC__) || defined(__clang__) +# define SENTRY_SUPPRESS_DEPRECATED \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +# define SENTRY_RESTORE_DEPRECATED _Pragma("GCC diagnostic pop") +#elif defined(_MSC_VER) +# define SENTRY_SUPPRESS_DEPRECATED \ + __pragma(warning(push)); \ + __pragma(warning(disable : 4996)) +# define SENTRY_RESTORE_DEPRECATED __pragma(warning(pop)) +#else +# define SENTRY_SUPPRESS_DEPRECATED +# define SENTRY_RESTORE_DEPRECATED +#endif + /* marks a function as experimental api */ #ifndef SENTRY_EXPERIMENTAL_API # define SENTRY_EXPERIMENTAL_API SENTRY_API @@ -2434,25 +2449,48 @@ SENTRY_EXPERIMENTAL_API void sentry_transaction_set_name_n( sentry_transaction_t *transaction, const char *name, size_t name_len); /** - * Creates a new User Feedback with a specific name, email and comments. - * - * See https://develop.sentry.dev/sdk/envelopes/#user-feedback + * Creates a deprecated User Report with a specific name, email and comments. * - * User Feedback has to be associated with a specific event that has been - * sent to Sentry earlier. + * See + * https://develop.sentry.dev/sdk/data-model/envelope-items/#user-report---deprecated */ +SENTRY_DEPRECATED("Use `sentry_value_new_feedback` instead") SENTRY_API sentry_value_t sentry_value_new_user_feedback( const sentry_uuid_t *uuid, const char *name, const char *email, const char *comments); +SENTRY_DEPRECATED("Use `sentry_value_new_feedback_n` instead") SENTRY_API sentry_value_t sentry_value_new_user_feedback_n( const sentry_uuid_t *uuid, const char *name, size_t name_len, const char *email, size_t email_len, const char *comments, size_t comments_len); +/** + * Captures a deprecated User Report and sends it to Sentry. + */ +SENTRY_DEPRECATED("Use `sentry_capture_feedback` instead") +SENTRY_API void sentry_capture_user_feedback(sentry_value_t user_report); + +/** + * Creates a new User Feedback with a specific message (required), and optional + * contact_email, name, message, and associated_event_id. + * + * See https://develop.sentry.dev/sdk/data-model/envelope-items/#user-feedback + * + * User Feedback can be associated with a specific event that has been + * sent to Sentry earlier. + */ +SENTRY_API sentry_value_t sentry_value_new_feedback(const char *message, + const char *contact_email, const char *name, + const sentry_uuid_t *associated_event_id); +SENTRY_API sentry_value_t sentry_value_new_feedback_n(const char *message, + size_t message_len, const char *contact_email, size_t contact_email_len, + const char *name, size_t name_len, + const sentry_uuid_t *associated_event_id); + /** * Captures a manually created User Feedback and sends it to Sentry. */ -SENTRY_API void sentry_capture_user_feedback(sentry_value_t user_feedback); +SENTRY_API void sentry_capture_feedback(sentry_value_t user_feedback); /** * The status of a Span or Transaction. diff --git a/src/sentry_core.c b/src/sentry_core.c index 29ccbbf11f..a76de14628 100644 --- a/src/sentry_core.c +++ b/src/sentry_core.c @@ -658,6 +658,25 @@ sentry__prepare_transaction(const sentry_options_t *options, return NULL; } +static sentry_envelope_t * +prepare_user_report(sentry_value_t user_report) +{ + sentry_envelope_t *envelope = NULL; + + envelope = sentry__envelope_new(); + if (!envelope || !sentry__envelope_add_user_report(envelope, user_report)) { + goto fail; + } + + return envelope; + +fail: + SENTRY_WARN("dropping user report"); + sentry_envelope_free(envelope); + sentry_value_decref(user_report); + return NULL; +} + static sentry_envelope_t * prepare_user_feedback(sentry_value_t user_feedback) { @@ -1335,7 +1354,21 @@ sentry_span_finish_ts(sentry_span_t *opaque_span, uint64_t timestamp) } void -sentry_capture_user_feedback(sentry_value_t user_feedback) +sentry_capture_user_feedback(sentry_value_t user_report) +{ + sentry_envelope_t *envelope = NULL; + + SENTRY_WITH_OPTIONS (options) { + envelope = prepare_user_report(user_report); + if (envelope) { + sentry__capture_envelope(options->transport, envelope); + } + } + sentry_value_decref(user_report); +} + +void +sentry_capture_feedback(sentry_value_t user_feedback) { sentry_envelope_t *envelope = NULL; @@ -1343,9 +1376,10 @@ sentry_capture_user_feedback(sentry_value_t user_feedback) envelope = prepare_user_feedback(user_feedback); if (envelope) { sentry__capture_envelope(options->transport, envelope); + } else { + sentry_value_decref(user_feedback); } } - sentry_value_decref(user_feedback); } int diff --git a/src/sentry_envelope.c b/src/sentry_envelope.c index 1de810d0a8..5702b42f0f 100644 --- a/src/sentry_envelope.c +++ b/src/sentry_envelope.c @@ -297,8 +297,8 @@ sentry__envelope_add_transaction( } sentry_envelope_item_t * -sentry__envelope_add_user_feedback( - sentry_envelope_t *envelope, sentry_value_t user_feedback) +sentry__envelope_add_user_report( + sentry_envelope_t *envelope, sentry_value_t user_report) { sentry_envelope_item_t *item = envelope_add_item(envelope); if (!item) { @@ -310,9 +310,9 @@ sentry__envelope_add_user_feedback( return NULL; } - sentry_value_t event_id = sentry__ensure_event_id(user_feedback, NULL); + sentry_value_t event_id = sentry__ensure_event_id(user_report, NULL); - sentry__jsonwriter_write_value(jw, user_feedback); + sentry__jsonwriter_write_value(jw, user_report); item->payload = sentry__jsonwriter_into_string(jw, &item->payload_len); sentry__envelope_item_set_header( @@ -326,6 +326,30 @@ sentry__envelope_add_user_feedback( return item; } +sentry_envelope_item_t * +sentry__envelope_add_user_feedback( + sentry_envelope_t *envelope, sentry_value_t user_feedback) +{ + sentry_value_t event = sentry_value_new_event(); + sentry_value_t contexts = sentry_value_get_by_key(event, "contexts"); + if (sentry_value_is_null(contexts)) { + contexts = sentry_value_new_object(); + } + sentry_value_set_by_key(contexts, "feedback", user_feedback); + sentry_value_set_by_key(event, "contexts", contexts); + + sentry_envelope_item_t *item = sentry__envelope_add_event(envelope, event); + if (!item) { + sentry_value_decref(event); + return NULL; + } + + sentry__envelope_item_set_header( + item, "type", sentry_value_new_string("feedback")); + + return item; +} + sentry_envelope_item_t * sentry__envelope_add_session( sentry_envelope_t *envelope, const sentry_session_t *session) diff --git a/src/sentry_envelope.h b/src/sentry_envelope.h index 8febb75d58..a41985dce6 100644 --- a/src/sentry_envelope.h +++ b/src/sentry_envelope.h @@ -43,6 +43,12 @@ sentry_envelope_item_t *sentry__envelope_add_event( sentry_envelope_item_t *sentry__envelope_add_transaction( sentry_envelope_t *envelope, sentry_value_t transaction); +/** + * Add a deprecated user report to this envelope. + */ +sentry_envelope_item_t *sentry__envelope_add_user_report( + sentry_envelope_t *envelope, sentry_value_t user_report); + /** * Add a user feedback to this envelope. */ diff --git a/src/sentry_value.c b/src/sentry_value.c index 9e573fe6fd..2ac33c809c 100644 --- a/src/sentry_value.c +++ b/src/sentry_value.c @@ -1350,9 +1350,11 @@ sentry_value_t sentry_value_new_user_feedback(const sentry_uuid_t *uuid, const char *name, const char *email, const char *comments) { + SENTRY_SUPPRESS_DEPRECATED return sentry_value_new_user_feedback_n(uuid, name, sentry__guarded_strlen(name), email, sentry__guarded_strlen(email), comments, sentry__guarded_strlen(comments)); + SENTRY_RESTORE_DEPRECATED } sentry_value_t @@ -1380,6 +1382,42 @@ sentry_value_new_user_feedback_n(const sentry_uuid_t *uuid, const char *name, return rv; } +sentry_value_t +sentry_value_new_feedback(const char *message, const char *contact_email, + const char *name, const sentry_uuid_t *associated_event_id) +{ + return sentry_value_new_feedback_n(message, sentry__guarded_strlen(message), + contact_email, sentry__guarded_strlen(contact_email), name, + sentry__guarded_strlen(name), associated_event_id); +} + +sentry_value_t +sentry_value_new_feedback_n(const char *message, size_t message_len, + const char *contact_email, size_t contact_email_len, const char *name, + size_t name_len, const sentry_uuid_t *associated_event_id) +{ + sentry_value_t rv = sentry_value_new_object(); + + if (message) { + sentry_value_set_by_key( + rv, "message", sentry_value_new_string_n(message, message_len)); + } + if (contact_email) { + sentry_value_set_by_key(rv, "contact_email", + sentry_value_new_string_n(contact_email, contact_email_len)); + } + if (name) { + sentry_value_set_by_key( + rv, "name", sentry_value_new_string_n(name, name_len)); + } + if (associated_event_id) { + sentry_value_set_by_key(rv, "associated_event_id", + sentry__value_new_internal_uuid(associated_event_id)); + } + + return rv; +} + static sentry_value_t sentry__get_or_insert_values_list(sentry_value_t parent, const char *key) { diff --git a/tests/__init__.py b/tests/__init__.py index 6f9bd1a425..255ce8ff32 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -278,7 +278,13 @@ def deserialize_from( headers = json.loads(line) length = headers["length"] payload = f.read(length) - if headers.get("type") in ["event", "session", "transaction", "user_report"]: + if headers.get("type") in [ + "event", + "feedback", + "session", + "transaction", + "user_report", + ]: rv = cls(headers=headers, payload=PayloadRef(json=json.loads(payload))) else: rv = cls(headers=headers, payload=payload) diff --git a/tests/assertions.py b/tests/assertions.py index ef1dbfcee7..8fd340f8ee 100644 --- a/tests/assertions.py +++ b/tests/assertions.py @@ -42,13 +42,25 @@ def assert_session(envelope, extra_assertion=None): def assert_user_feedback(envelope): user_feedback = None for item in envelope: - if item.headers.get("type") == "user_report" and item.payload.json is not None: - user_feedback = item.payload.json + if item.headers.get("type") == "feedback" and item.payload.json is not None: + user_feedback = item.payload.json["contexts"]["feedback"] assert user_feedback is not None assert user_feedback["name"] == "some-name" - assert user_feedback["email"] == "some-email" - assert user_feedback["comments"] == "some-comment" + assert user_feedback["contact_email"] == "some-email" + assert user_feedback["message"] == "some-message" + + +def assert_user_report(envelope): + user_report = None + for item in envelope: + if item.headers.get("type") == "user_report" and item.payload.json is not None: + user_report = item.payload.json + + assert user_report is not None + assert user_report["name"] == "some-name" + assert user_report["email"] == "some-email" + assert user_report["comments"] == "some-comment" def assert_meta( diff --git a/tests/test_integration_http.py b/tests/test_integration_http.py index 809d4506aa..a3b53d72a1 100644 --- a/tests/test_integration_http.py +++ b/tests/test_integration_http.py @@ -30,6 +30,7 @@ assert_inproc_crash, assert_session, assert_user_feedback, + assert_user_report, assert_minidump, assert_breakpad_crash, assert_gzip_content_encoding, @@ -168,6 +169,30 @@ def test_user_feedback_http(cmake, httpserver): env=env, ) + assert len(httpserver.log) == 1 + output = httpserver.log[0][0].get_data() + envelope = Envelope.deserialize(output) + + assert_user_feedback(envelope) + + +def test_user_report_http(cmake, httpserver): + tmp_path = cmake(["sentry_example"], {"SENTRY_BACKEND": "none"}) + + httpserver.expect_request( + "/api/123456/envelope/", + headers={"x-sentry-auth": auth_header}, + ).respond_with_data("OK") + env = dict(os.environ, SENTRY_DSN=make_dsn(httpserver)) + + run( + tmp_path, + "sentry_example", + ["log", "capture-user-report"], + check=True, + env=env, + ) + assert len(httpserver.log) == 2 output = httpserver.log[0][0].get_data() envelope = Envelope.deserialize(output) @@ -177,7 +202,7 @@ def test_user_feedback_http(cmake, httpserver): output = httpserver.log[1][0].get_data() envelope = Envelope.deserialize(output) - assert_user_feedback(envelope) + assert_user_report(envelope) def test_exception_and_session_http(cmake, httpserver): diff --git a/tests/unit/sentry_testsupport.h b/tests/unit/sentry_testsupport.h index e3364f51ac..0fe83d78bd 100644 --- a/tests/unit/sentry_testsupport.h +++ b/tests/unit/sentry_testsupport.h @@ -90,24 +90,11 @@ sentry_dsn_t *Varname = sentry__dsn_new(DSN_URL); \ TEST_ASSERT(!!Varname) -#if defined(__GNUC__) || defined(__clang__) -# define SENTRY_TEST_DEPRECATED(call) \ - do { \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\""); \ - call; \ - _Pragma("GCC diagnostic pop"); \ - } while (0) -#elif defined(_MSC_VER) -# define SENTRY_TEST_DEPRECATED(call) \ - do { \ - __pragma(warning(push)); \ - __pragma(warning(disable : 4996)); \ - call; \ - __pragma(warning(pop)); \ - } while (0) -#else -# define SENTRY_TEST_DEPRECATED(call) call -#endif +#define SENTRY_TEST_DEPRECATED(call) \ + do { \ + SENTRY_SUPPRESS_DEPRECATED \ + call; \ + SENTRY_RESTORE_DEPRECATED \ + } while (0) #endif // SENTRY_TEST_SUPPORT_H_INCLUDED diff --git a/tests/unit/test_envelopes.c b/tests/unit/test_envelopes.c index 2805064158..e7ba20fb87 100644 --- a/tests/unit/test_envelopes.c +++ b/tests/unit/test_envelopes.c @@ -1,4 +1,5 @@ #include "sentry_envelope.h" +#include "sentry_json.h" #include "sentry_path.h" #include "sentry_testsupport.h" #include "sentry_transport.h" @@ -78,16 +79,18 @@ SENTRY_TEST(basic_http_request_preparation_for_transaction) sentry__dsn_decref(dsn); } -SENTRY_TEST(basic_http_request_preparation_for_user_feedback) +SENTRY_TEST(basic_http_request_preparation_for_user_report) { SENTRY_TEST_DSN_NEW_DEFAULT(dsn); sentry_uuid_t event_id = sentry_uuid_from_string("c993afb6-b4ac-48a6-b61b-2558e601d65d"); sentry_envelope_t *envelope = sentry__envelope_new(); - sentry_value_t user_feedback = sentry_value_new_user_feedback( - &event_id, "some-name", "some-email", "some-comment"); - sentry__envelope_add_user_feedback(envelope, user_feedback); + sentry_value_t user_report; + SENTRY_TEST_DEPRECATED( + user_report = sentry_value_new_user_feedback( + &event_id, "some-name", "some-email", "some-comment")); + sentry__envelope_add_user_report(envelope, user_report); sentry_prepared_http_request_t *req = sentry__prepare_http_request(envelope, dsn, NULL, NULL); @@ -103,7 +106,76 @@ SENTRY_TEST(basic_http_request_preparation_for_user_feedback) "\"some-comment\"}"); #endif sentry__prepared_http_request_free(req); - sentry_value_decref(user_feedback); + sentry_value_decref(user_report); + sentry_envelope_free(envelope); + + sentry__dsn_decref(dsn); +} + +SENTRY_TEST(basic_http_request_preparation_for_user_feedback) +{ + SENTRY_TEST_DSN_NEW_DEFAULT(dsn); + + sentry_uuid_t event_id + = sentry_uuid_from_string("c993afb6-b4ac-48a6-b61b-2558e601d65d"); + sentry_envelope_t *envelope = sentry__envelope_new(); + sentry_value_t user_feedback = sentry_value_new_feedback( + "some-message", "some-email", "some-name", &event_id); + sentry__envelope_add_user_feedback(envelope, user_feedback); + + sentry_prepared_http_request_t *req + = sentry__prepare_http_request(envelope, dsn, NULL, NULL); + TEST_CHECK_STRING_EQUAL(req->method, "POST"); + TEST_CHECK_STRING_EQUAL( + req->url, "https://sentry.invalid:443/api/42/envelope/"); +#ifndef SENTRY_TRANSPORT_COMPRESSION + char *line1 = req->body; + char *line1_end = strchr(line1, '\n'); + TEST_CHECK(line1_end != NULL); + line1_end[0] = '\0'; + TEST_CHECK_STRING_EQUAL( + line1, "{\"event_id\":\"4c035723-8638-4c3a-923f-2ab9d08b4018\"}"); + + char *line2 = line1_end + 1; + char *line2_end = strchr(line2, '\n'); + TEST_CHECK(line2_end != NULL); + line2_end[0] = '\0'; + TEST_CHECK_STRING_EQUAL(line2, "{\"type\":\"feedback\",\"length\":269}"); + + char *line3 = line2_end + 1; + sentry_value_t line3_json = sentry__value_from_json(line3, strlen(line3)); + TEST_CHECK(!sentry_value_is_null(line3_json)); + + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key(line3_json, "event_id")), + "4c035723-8638-4c3a-923f-2ab9d08b4018"); + TEST_CHECK(!sentry_value_is_null( + sentry_value_get_by_key(line3_json, "timestamp"))); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key(line3_json, "platform")), + "native"); + + sentry_value_t contexts = sentry_value_get_by_key(line3_json, "contexts"); + TEST_CHECK(!sentry_value_is_null(contexts)); + + sentry_value_t actual = sentry_value_get_by_key(contexts, "feedback"); + TEST_CHECK(!sentry_value_is_null(actual)); + + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key(actual, "message")), + "some-message"); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + actual, "contact_email")), + "some-email"); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key(actual, "name")), + "some-name"); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + actual, "associated_event_id")), + "c993afb6b4ac48a6b61b2558e601d65d"); + sentry_value_decref(line3_json); +#endif + sentry__prepared_http_request_free(req); sentry_envelope_free(envelope); sentry__dsn_decref(dsn); diff --git a/tests/unit/test_value.c b/tests/unit/test_value.c index 00258475d7..46fc893a96 100644 --- a/tests/unit/test_value.c +++ b/tests/unit/test_value.c @@ -814,12 +814,14 @@ SENTRY_TEST(thread_without_name_still_valid) sentry_value_decref(thread); } -SENTRY_TEST(user_feedback_is_valid) +SENTRY_TEST(user_report_is_valid) { sentry_uuid_t event_id = sentry_uuid_from_string("c993afb6-b4ac-48a6-b61b-2558e601d65d"); - sentry_value_t user_feedback = sentry_value_new_user_feedback( - &event_id, "some-name", "some-email", "some-comment"); + sentry_value_t user_feedback; + SENTRY_TEST_DEPRECATED( + user_feedback = sentry_value_new_user_feedback( + &event_id, "some-name", "some-email", "some-comment")); TEST_CHECK(!sentry_value_is_null(user_feedback)); TEST_CHECK_STRING_EQUAL( @@ -839,8 +841,9 @@ SENTRY_TEST(user_feedback_with_null_args) { sentry_uuid_t event_id = sentry_uuid_from_string("c993afb6-b4ac-48a6-b61b-2558e601d65d"); - sentry_value_t user_feedback - = sentry_value_new_user_feedback(&event_id, NULL, NULL, NULL); + sentry_value_t user_feedback; + SENTRY_TEST_DEPRECATED(user_feedback + = sentry_value_new_user_feedback(&event_id, NULL, NULL, NULL)); TEST_CHECK(!sentry_value_is_null(user_feedback)); TEST_CHECK( @@ -852,8 +855,8 @@ SENTRY_TEST(user_feedback_with_null_args) sentry_value_decref(user_feedback); - user_feedback = sentry_value_new_user_feedback( - &event_id, NULL, "some-email", "some-comment"); + SENTRY_TEST_DEPRECATED(user_feedback = sentry_value_new_user_feedback( + &event_id, NULL, "some-email", "some-comment")); TEST_CHECK(!sentry_value_is_null(user_feedback)); TEST_CHECK( @@ -867,8 +870,8 @@ SENTRY_TEST(user_feedback_with_null_args) sentry_value_decref(user_feedback); - user_feedback = sentry_value_new_user_feedback( - &event_id, "some-name", NULL, "some-comment"); + SENTRY_TEST_DEPRECATED(user_feedback = sentry_value_new_user_feedback( + &event_id, "some-name", NULL, "some-comment")); TEST_CHECK(!sentry_value_is_null(user_feedback)); TEST_CHECK_STRING_EQUAL( @@ -882,8 +885,8 @@ SENTRY_TEST(user_feedback_with_null_args) sentry_value_decref(user_feedback); - user_feedback = sentry_value_new_user_feedback( - &event_id, "some-name", "some-email", NULL); + SENTRY_TEST_DEPRECATED(user_feedback = sentry_value_new_user_feedback( + &event_id, "some-name", "some-email", NULL)); TEST_CHECK(!sentry_value_is_null(user_feedback)); @@ -898,3 +901,27 @@ SENTRY_TEST(user_feedback_with_null_args) sentry_value_decref(user_feedback); } + +SENTRY_TEST(user_feedback_is_valid) +{ + sentry_uuid_t event_id + = sentry_uuid_from_string("c993afb6-b4ac-48a6-b61b-2558e601d65d"); + sentry_value_t user_feedback = sentry_value_new_feedback( + "some-message", "some-email", "some-name", &event_id); + + TEST_CHECK(!sentry_value_is_null(user_feedback)); + TEST_CHECK_STRING_EQUAL( + sentry_value_as_string(sentry_value_get_by_key(user_feedback, "name")), + "some-name"); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + user_feedback, "contact_email")), + "some-email"); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + user_feedback, "message")), + "some-message"); + TEST_CHECK_STRING_EQUAL(sentry_value_as_string(sentry_value_get_by_key( + user_feedback, "associated_event_id")), + "c993afb6b4ac48a6b61b2558e601d65d"); + + sentry_value_decref(user_feedback); +} diff --git a/tests/unit/tests.inc b/tests/unit/tests.inc index 4daa747398..7be02a45dd 100644 --- a/tests/unit/tests.inc +++ b/tests/unit/tests.inc @@ -16,6 +16,7 @@ XX(basic_http_request_preparation_for_event_with_attachment) XX(basic_http_request_preparation_for_minidump) XX(basic_http_request_preparation_for_transaction) XX(basic_http_request_preparation_for_user_feedback) +XX(basic_http_request_preparation_for_user_report) XX(basic_spans) XX(basic_tracing_context) XX(basic_transaction) @@ -145,6 +146,7 @@ XX(url_parsing_partial) XX(url_parsing_with_path) XX(user_feedback_is_valid) XX(user_feedback_with_null_args) +XX(user_report_is_valid) XX(uuid_api) XX(uuid_v4) XX(value_bool)