Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Sources/Sentry/SentryGeo.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@

@implementation SentryGeo

- (instancetype)initWithDictionary:(NSDictionary *)dictionary
{
if (self = [super init]) {
id city = dictionary[@"city"];
if ([city isKindOfClass:[NSString class]]) {
self.city = city;
}

id countryCode = dictionary[@"country_code"];
if ([countryCode isKindOfClass:[NSString class]]) {
self.countryCode = countryCode;
}

id region = dictionary[@"region"];
if ([region isKindOfClass:[NSString class]]) {
self.region = region;
}
}
return self;
}
Comment thread
antonis marked this conversation as resolved.

- (id)copyWithZone:(nullable NSZone *)zone
{
SentryGeo *copy = [[[self class] allocWithZone:zone] init];
Expand Down
4 changes: 3 additions & 1 deletion Sources/Sentry/SentryUser.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#import "SentryUser.h"
#import "SentryGeo.h"
#import "SentryGeo+Private.h"
#import "SentryInternalDefines.h"
#import "SentrySanitizerUtils.h"

Expand Down Expand Up @@ -33,6 +33,8 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary
self.ipAddress = value;
} else if ([key isEqualToString:@"data"] && isDictionary) {
self.data = value;
} else if ([key isEqualToString:@"geo"] && isDictionary) {
self.geo = [[SentryGeo alloc] initWithDictionary:value];
} else {
unknown[key] = value;
}
Expand Down
16 changes: 16 additions & 0 deletions Sources/Sentry/include/SentryGeo+Private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#if __has_include(<Sentry/SentryGeo.h>)
# import <Sentry/SentryGeo.h>
#else
# import "SentryGeo.h"
#endif

@interface SentryGeo ()

/**
* Initializes a SentryGeo from a dictionary.
* @param dictionary The dictionary containing geo data.
* @return The SentryGeo.
*/
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;

@end
57 changes: 57 additions & 0 deletions Tests/SentryTests/Protocol/SentryGeoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,63 @@ import XCTest

class SentryGeoTests: XCTestCase {

func testInitWithDictionary_AllProperties() throws {
let dict: [String: Any] = [
"city": "San Francisco",
"country_code": "US",
"region": "California"
]
let geo = try XCTUnwrap(Geo(dictionary: dict))

XCTAssertEqual(geo.city, "San Francisco")
XCTAssertEqual(geo.countryCode, "US")
XCTAssertEqual(geo.region, "California")
}

func testInitWithDictionary_PartialProperties() throws {
let geo = try XCTUnwrap(Geo(dictionary: ["city": "Berlin"]))

XCTAssertEqual(geo.city, "Berlin")
XCTAssertNil(geo.countryCode)
XCTAssertNil(geo.region)
}

func testInitWithDictionary_EmptyDict() throws {
let geo = try XCTUnwrap(Geo(dictionary: [:]))

XCTAssertNil(geo.city)
XCTAssertNil(geo.countryCode)
XCTAssertNil(geo.region)
}

func testInitWithDictionary_WrongTypes() throws {
let dict: [String: Any] = [
"city": 123,
"country_code": ["not", "a", "string"],
"region": true
]
let geo = try XCTUnwrap(Geo(dictionary: dict))

XCTAssertNil(geo.city)
XCTAssertNil(geo.countryCode)
XCTAssertNil(geo.region)
}

func testInitWithDictionary_RoundTrip() throws {
let dict: [String: Any] = [
"city": "San Francisco",
"country_code": "US",
"region": "California"
]
let geo = try XCTUnwrap(Geo(dictionary: dict))
let serialized = geo.serialize()

XCTAssertEqual(serialized["city"] as? String, "San Francisco")
XCTAssertEqual(serialized["country_code"] as? String, "US")
XCTAssertEqual(serialized["region"] as? String, "California")
XCTAssertEqual(serialized.count, 3)
}

func testSerializationWithAllProperties() throws {
let geo = try XCTUnwrap(TestData.geo.copy() as? Geo)
let actual = geo.serialize()
Expand Down
29 changes: 28 additions & 1 deletion Tests/SentryTests/Protocol/SentryUserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,44 @@ class SentryUserTests: XCTestCase {
"data": [
"fixture-key": "fixture-value"
],
"geo": [
"city": "San Francisco",
"country_code": "US",
"region": "California"
],
"foo": "bar" // Unknown
]
let user = PrivateSentrySDKOnly.user(with: dict)

XCTAssertEqual(user.userId, "fixture-id")
XCTAssertEqual(user.email, "fixture-email")
XCTAssertEqual(user.username, "fixture-username")
XCTAssertEqual(user.ipAddress, "fixture-ip_address")
XCTAssertEqual(user.data?["fixture-key"] as? String, "fixture-value")
XCTAssertEqual(user.geo?.city, "San Francisco")
XCTAssertEqual(user.geo?.countryCode, "US")
XCTAssertEqual(user.geo?.region, "California")
XCTAssertEqual(user.value(forKey: "unknown") as? NSDictionary, ["foo": "bar"])
}

func testInitWithDictionary_GeoRoundTrip() {
let dict: [AnyHashable: Any] = [
"id": "user-1",
"geo": [
"city": "San Francisco",
"country_code": "US",
"region": "California"
]
]
let user = PrivateSentrySDKOnly.user(with: dict)
let serialized = user.serialize()

let geo = serialized["geo"] as? [String: Any]
XCTAssertEqual(geo?["city"] as? String, "San Francisco")
XCTAssertEqual(geo?["country_code"] as? String, "US")
XCTAssertEqual(geo?["region"] as? String, "California")
XCTAssertNil(serialized["unknown"])
}

func testSerializationWithAllProperties() throws {
let user = try XCTUnwrap(TestData.user.copy() as? User)
Expand Down
1 change: 1 addition & 0 deletions Tests/SentryTests/SentryTests-Bridging-Header.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "SentryDefines.h"
#import "SentryGeo+Private.h"

#import "SentryLaunchProfiling+Tests.h"

Expand Down
Loading