Skip to content
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: Adds breadcrumb.origin field #4358

Merged
merged 13 commits into from
Sep 26, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Added breadcrumb.origin private field (#4358)
- Custom redact modifier for SwiftUI (#4362)

### Improvements
Expand Down
8 changes: 4 additions & 4 deletions Sources/Sentry/Public/SentryBreadcrumb.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ NS_SWIFT_NAME(Breadcrumb)
/**
* @c NSDate when the breadcrumb happened
*/
@property (nonatomic, strong) NSDate *_Nullable timestamp;
@property (nonatomic, strong, nullable) NSDate *timestamp;

/**
* Type of breadcrumb, can be e.g.: http, empty, user, navigation
* This will be used as icon of the breadcrumb
*/
@property (nonatomic, copy) NSString *_Nullable type;
@property (nonatomic, copy, nullable) NSString *type;

/**
* Message for the breadcrumb
*/
@property (nonatomic, copy) NSString *_Nullable message;
@property (nonatomic, copy, nullable) NSString *message;

/**
* Arbitrary additional data that will be sent with the breadcrumb
*/
@property (nonatomic, strong) NSDictionary<NSString *, id> *_Nullable data;
@property (nonatomic, strong, nullable) NSDictionary<NSString *, id> *data;

/**
* Initializer for @c SentryBreadcrumb
Expand Down
7 changes: 7 additions & 0 deletions Sources/Sentry/SentryBreadcrumb.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "SentryBreadcrumb.h"
#import "SentryBreadcrumb+Private.h"
#import "SentryDateUtils.h"
#import "SentryLevelMapper.h"
#import "SentryNSDictionarySanitize.h"
Expand Down Expand Up @@ -30,6 +31,8 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary
self.category = value;
} else if ([key isEqualToString:@"type"] && isString) {
self.type = value;
} else if ([key isEqualToString:@"origin"] && isString) {
self.origin = value;
} else if ([key isEqualToString:@"message"] && isString) {
self.message = value;
} else if ([key isEqualToString:@"data"] && isDictionary) {
Expand Down Expand Up @@ -69,6 +72,7 @@ - (instancetype)init
[serializedData setValue:sentry_toIso8601String(self.timestamp) forKey:@"timestamp"];
[serializedData setValue:self.category forKey:@"category"];
[serializedData setValue:self.type forKey:@"type"];
[serializedData setValue:self.origin forKey:@"origin"];
[serializedData setValue:self.message forKey:@"message"];
[serializedData setValue:sentry_sanitize(self.data) forKey:@"data"];
NSDictionary<NSString *, id> *unknown = self.unknown;
Expand Down Expand Up @@ -106,6 +110,8 @@ - (BOOL)isEqualToBreadcrumb:(SentryBreadcrumb *)breadcrumb
return NO;
if (self.type != breadcrumb.type && ![self.type isEqualToString:breadcrumb.type])
return NO;
if (self.origin != breadcrumb.origin && ![self.origin isEqualToString:breadcrumb.origin])
return NO;
if (self.message != breadcrumb.message && ![self.message isEqualToString:breadcrumb.message])
return NO;
if (self.data != breadcrumb.data && ![self.data isEqualToDictionary:breadcrumb.data])
Expand All @@ -123,6 +129,7 @@ - (NSUInteger)hash
hash = hash * 23 + [self.category hash];
hash = hash * 23 + [self.timestamp hash];
hash = hash * 23 + [self.type hash];
hash = hash * 23 + [self.origin hash];
hash = hash * 23 + [self.message hash];
hash = hash * 23 + [self.data hash];
hash = hash * 23 + [self.unknown hash];
Expand Down
2 changes: 2 additions & 0 deletions Sources/Sentry/SentryCrashReportConverter.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "SentryCrashReportConverter.h"
#import "SentryBreadcrumb+Private.h"
#import "SentryBreadcrumb.h"
#import "SentryCrashStackCursor.h"
#import "SentryDateUtils.h"
Expand Down Expand Up @@ -170,6 +171,7 @@ - (SentryUser *_Nullable)convertUser
category:storedCrumb[@"category"]];
crumb.message = storedCrumb[@"message"];
crumb.type = storedCrumb[@"type"];
crumb.origin = storedCrumb[@"origin"];
crumb.timestamp = sentry_fromIso8601String(storedCrumb[@"timestamp"]);
crumb.data = storedCrumb[@"data"];
[breadcrumbs addObject:crumb];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

@interface SentryBreadcrumb ()

/**
* Origin of the breadcrumb that is used to identify source of the breadcrumb
* For example hybrid SDKs can identify native breadcrumbs from JS or Flutter
*/
@property (nonatomic, copy, nullable) NSString *origin;

/**
* Initializes a SentryBreadcrumb from a JSON object.
* @param dictionary The dictionary containing breadcrumb data.
* @return The SentryBreadcrumb.
*/
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;
- (instancetype _Nonnull)initWithDictionary:(NSDictionary *_Nonnull)dictionary;
antonis marked this conversation as resolved.
Show resolved Hide resolved
@end
17 changes: 17 additions & 0 deletions Tests/SentryTests/Protocol/SentryBreadcrumbTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class SentryBreadcrumbTests: XCTestCase {

let category = "category"
let type = "user"
let origin = "origin"
let message = "Click something"

init() {
Expand All @@ -18,6 +19,7 @@ class SentryBreadcrumbTests: XCTestCase {
breadcrumb.timestamp = date
breadcrumb.category = category
breadcrumb.type = type
breadcrumb.origin = origin
breadcrumb.message = message
breadcrumb.data = ["some": ["data": "data", "date": date] as [String: Any]]
breadcrumb.setValue(["foo": "bar"], forKey: "unknown")
Expand All @@ -36,6 +38,7 @@ class SentryBreadcrumbTests: XCTestCase {
"timestamp": fixture.dateAs8601String,
"category": fixture.category,
"type": fixture.type,
"origin": fixture.origin,
"message": fixture.message,
"data": ["foo": "bar"],
"foo": "bar" // Unknown
Expand All @@ -46,6 +49,7 @@ class SentryBreadcrumbTests: XCTestCase {
XCTAssertEqual(breadcrumb.timestamp, fixture.date)
XCTAssertEqual(breadcrumb.category, fixture.category)
XCTAssertEqual(breadcrumb.type, fixture.type)
XCTAssertEqual(breadcrumb.origin, fixture.origin)
XCTAssertEqual(breadcrumb.message, fixture.message)
XCTAssertEqual(breadcrumb.data as? [String: String], ["foo": "bar"])
XCTAssertEqual(breadcrumb.value(forKey: "unknown") as? NSDictionary, ["foo": "bar"])
Expand All @@ -68,6 +72,16 @@ class SentryBreadcrumbTests: XCTestCase {
func testIsNotEqualToOtherClass() {
XCTAssertFalse(fixture.breadcrumb.isEqual(1))
}

func testIsNotEqualToNil() {
XCTAssertFalse(fixture.breadcrumb.isEqual(nil))
}

func testIsNotEqualIfOriginDiffers() {
let fixture2 = Fixture()
fixture2.breadcrumb.origin = "origin2"
XCTAssertNotEqual(fixture.breadcrumb, fixture2.breadcrumb)
}

func testIsEqualToOtherInstanceWithSameValues() {
let fixture2 = Fixture()
Expand All @@ -79,6 +93,7 @@ class SentryBreadcrumbTests: XCTestCase {
testIsNotEqual { breadcrumb in breadcrumb.category = "" }
testIsNotEqual { breadcrumb in breadcrumb.timestamp = Date() }
testIsNotEqual { breadcrumb in breadcrumb.type = "" }
testIsNotEqual { breadcrumb in breadcrumb.origin = "" }
testIsNotEqual { breadcrumb in breadcrumb.message = "" }
testIsNotEqual { breadcrumb in breadcrumb.data?.removeAll() }
testIsNotEqual { breadcrumb in breadcrumb.setValue(nil, forKey: "unknown") }
Expand All @@ -99,6 +114,7 @@ class SentryBreadcrumbTests: XCTestCase {
crumb.timestamp = nil
crumb.category = ""
crumb.type = ""
crumb.origin = ""
crumb.message = ""
crumb.data = nil
crumb.setValue(nil, forKey: "unknown")
Expand All @@ -107,6 +123,7 @@ class SentryBreadcrumbTests: XCTestCase {
XCTAssertEqual(fixture.dateAs8601String, actual["timestamp"] as? String)
XCTAssertEqual(fixture.category, actual["category"] as? String)
XCTAssertEqual(fixture.type, actual["type"] as? String)
XCTAssertEqual(fixture.origin, actual["origin"] as? String)
XCTAssertEqual(fixture.message, actual["message"] as? String)
XCTAssertEqual(["some": ["data": "data", "date": fixture.dateAs8601String]], actual["data"] as? Dictionary)
XCTAssertEqual("bar", actual["foo"] as? String)
Expand Down
3 changes: 3 additions & 0 deletions Tests/SentryTests/SentryInterfacesTests.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import <XCTest/XCTest.h>

#import "SentryBreadcrumb+Private.h"
#import "SentryBreadcrumb.h"
#import "SentryDateUtils.h"
#import "SentryEvent.h"
Expand Down Expand Up @@ -378,10 +379,12 @@ - (void)testBreadcrumb
crumb2.type = @"type";
crumb2.timestamp = date;
crumb2.message = @"message";
crumb2.origin = @"origin";
NSDictionary *serialized2 = @{
@"level" : @"info",
@"type" : @"type",
@"message" : @"message",
@"origin" : @"origin",
@"timestamp" : sentry_toIso8601String(date),
@"category" : @"http",
@"data" : @ { @"bla" : @"1" },
Expand Down
1 change: 1 addition & 0 deletions Tests/SentryTests/SentryTests-Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#import "SentryAutoBreadcrumbTrackingIntegration.h"
#import "SentryAutoSessionTrackingIntegration.h"
#import "SentryBooleanSerialization.h"
#import "SentryBreadcrumb+Private.h"
#import "SentryBreadcrumbDelegate.h"
#import "SentryBreadcrumbTracker.h"
#import "SentryByteCountFormatter.h"
Expand Down
2 changes: 2 additions & 0 deletions Tests/SentryTests/SentryTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import "SentryMeta.h"
#import "SentryOptions+HybridSDKs.h"
#import "SentrySDK+Private.h"
#import <SentryBreadcrumb+Private.h>
#import <XCTest/XCTest.h>
@import Sentry;

Expand Down Expand Up @@ -78,6 +79,7 @@ - (void)testSDKBreadCrumbAdd
SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelInfo
category:@"testCategory"];
crumb.type = @"testType";
crumb.origin = @"testOrigin";
crumb.message = @"testMessage";
crumb.data = @{ @"testDataKey" : @"testDataVaue" };

Expand Down
Loading