-
-
Notifications
You must be signed in to change notification settings - Fork 341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(feedback): initial release #4874
base: armcknight/feat(feedback)/final-fixes
Are you sure you want to change the base?
feat(feedback): initial release #4874
Conversation
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## armcknight/feat(feedback)/final-fixes #4874 +/- ##
============================================================================
+ Coverage 9.094% 92.310% +83.215%
============================================================================
Files 350 659 +309
Lines 24970 77407 +52437
Branches 94 28024 +27930
============================================================================
+ Hits 2271 71455 +69184
+ Misses 22699 5853 -16846
- Partials 0 99 +99
... and 637 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
Performance metrics 🚀
|
Revision | Plain | With Sentry | Diff |
---|---|---|---|
f09e892 | 1220.22 ms | 1238.80 ms | 18.57 ms |
38ae188 | 1221.04 ms | 1246.91 ms | 25.87 ms |
cc14e49 | 1209.31 ms | 1231.54 ms | 22.24 ms |
App size
Revision | Plain | With Sentry | Diff |
---|---|---|---|
f09e892 | 22.31 KiB | 820.98 KiB | 798.67 KiB |
38ae188 | 22.31 KiB | 820.94 KiB | 798.63 KiB |
cc14e49 | 22.31 KiB | 821.57 KiB | 799.26 KiB |
Previous results on branch: armcknight/feat(feedback)/initial-release
Startup times
Revision | Plain | With Sentry | Diff |
---|---|---|---|
331f1be | 1197.30 ms | 1229.26 ms | 31.96 ms |
588c9d0 | 1243.65 ms | 1258.61 ms | 14.96 ms |
2b6f0d6 | 1221.55 ms | 1234.17 ms | 12.62 ms |
App size
Revision | Plain | With Sentry | Diff |
---|---|---|---|
331f1be | 22.31 KiB | 821.88 KiB | 799.56 KiB |
588c9d0 | 22.31 KiB | 821.59 KiB | 799.28 KiB |
2b6f0d6 | 22.31 KiB | 821.70 KiB | 799.39 KiB |
4957680
to
e474fea
Compare
e474fea
to
5957494
Compare
func testCaptureFeedback_WithEmptyEventId() { | ||
let sut = fixture.getSut() | ||
XCTAssertTrue(fixture.transportAdapter.sendEventWithTraceStateInvocations.isEmpty) | ||
sut.capture(feedback: fixture.feedback, scope: fixture.scope) | ||
XCTAssertFalse(fixture.transportAdapter.sendEventWithTraceStateInvocations.isEmpty) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@philipphofmann LMK what you think of this test. I debugged and traced execution to something I could check, which turned out to be the transport adapter, so just used that. I do see other test cases using sendEventWithTraceStateInvocations
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's OK to do it like that, and the test should assert some properties of the recorded event. Now it only asserts that there was an event recorded but not that the contents of the event are correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a couple of comments, but other than that LGTM
* submits calling the new method @c SentrySDK.captureFeedback (see | ||
* https://docs.sentry.io/platforms/apple/user-feedback/configuration/). | ||
*/ | ||
@property (nonatomic, copy, nullable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l
: Is there any value in not configuring this in the root options, but instead moving it to something like options.userFeedback.configure { ... }
, implementing the nested options in Swift instead? Similar to the experimental options
@@ -56,7 +56,7 @@ extension SentryFeedback: SentrySerializable { | |||
if let associatedEventId = associatedEventId { | |||
dict["associated_event_id"] = associatedEventId.sentryIdString | |||
} | |||
dict["source"] = source.rawValue | |||
dict["source"] = source.description |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l
: Just want to point out that in most cases it is bad practice to use description
in any serialization, because if the implementation of description
in line 7 is removed, the Swift compiler could still synthesize the CustomStringConvertible
, and it's not guaranteed to match the raw string value (could include information like Optional<String>
)
let sut = SentryFeedback(message: "Test feedback message", name: "Test feedback provider", email: "[email protected]", source: .custom, attachments: [Data()]) | ||
|
||
let serialization = sut.serialize() | ||
XCTAssertEqual(try XCTUnwrap(serialization["message"] as? String), "Test feedback message") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l
: Why the nesting of XCTUnwrap
and XCTAssertEqual
? AFAIK the XCTUnwrap is unnecessary, because we can compare serialization["message"] as? String
directly to Test feedback message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, with a couple of things to improve, but nothing blocking.
@@ -78,6 +78,28 @@ - (IBAction)captureUserFeedback:(id)sender | |||
[SentrySDK captureUserFeedback:userFeedback]; | |||
} | |||
|
|||
- (IBAction)captureNewUserFeedback:(id)sender |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l
: Using V2 instead of new for naming is usually better. What if we have user feedback V3? Are we going to call it newnew then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yeah, we talked about this before with the profiling stuff 🤣 I'll change it to V2
typedef void (^SentryUserFeedbackConfigurationBlock)( | ||
SentryUserFeedbackConfiguration *_Nonnull configuration); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l
: We have all the other typedefs for the callbacks in the options in SentryDefines.h. You could move it there for consistency.
* @note This is unrelated to @c SentrySDK.captureUserFeedback which is the old method of submitting | ||
* user feedback you've already gathered via your own UI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m
: I would write about deprecated instead of old.
* @note This is unrelated to @c SentrySDK.captureUserFeedback which is the old method of submitting | |
* user feedback you've already gathered via your own UI | |
* @note This is unrelated to @c SentrySDK.captureUserFeedback , which is the deprecated method of submitting | |
* user feedback you've already gathered via your own UI |
* (see https://docs.sentry.io/platforms/apple/user-feedback/#user-feedback-api). The new method | ||
* uses either this block to configure and a widget and UI form to gather feedback, or directly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l
:
* (see https://docs.sentry.io/platforms/apple/user-feedback/#user-feedback-api). The new method | |
* uses either this block to configure and a widget and UI form to gather feedback, or directly | |
* (see https://docs.sentry.io/platforms/apple/user-feedback/#user-feedback-api). This method | |
* uses either this block to configure and a widget and UI form to gather feedback, or directly |
assertNothingSent() | ||
} | ||
|
||
@available(*, deprecated, message: "This is only marked as deprecated because assertNothingSent is marked as deprecated, due to it using a deprecated property inside it. When that property usage is removed, this deprecation annotation can go away.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh my god this repetition is very annoying 🤦. We will fix it later.
func testCaptureFeedback_WithEmptyEventId() { | ||
let sut = fixture.getSut() | ||
XCTAssertTrue(fixture.transportAdapter.sendEventWithTraceStateInvocations.isEmpty) | ||
sut.capture(feedback: fixture.feedback, scope: fixture.scope) | ||
XCTAssertFalse(fixture.transportAdapter.sendEventWithTraceStateInvocations.isEmpty) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's OK to do it like that, and the test should assert some properties of the recorded event. Now it only asserts that there was an event recorded but not that the contents of the event are correct.
Publicly exposes the feature. For #4709
TODO: