Skip to content

Commit

Permalink
add dynamic vt field (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
tikidunpon authored Jan 12, 2022
1 parent efc1ec3 commit 857eed6
Show file tree
Hide file tree
Showing 17 changed files with 640 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .spm-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0
2.1.0
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@
| KarteInAppMessaging | アプリ内メッセージ機能を提供します。 | 2.10.1 |
| KarteRemoteNotification | プッシュ通知の受信および効果測定機能を提供します。 | 2.6.0 |
| KarteVariables | 設定値配信機能を提供します。 | 2.3.0 |
| KarteVisualTracking | ビジュアルトラッキング機能を提供します。 | 2.6.0 |
| KarteVisualTracking | ビジュアルトラッキング機能を提供します。 | 2.7.0 |
| KarteCrashReporting | クラッシュイベントのトラッキング機能を提供します。 | 2.4.0 |
| KarteUtilities | KarteCore モジュール等が利用するUtility機能を提供します。通常直接参照する必要はありません。 | 3.6.0 |

# Releases - 2022.1.12

### VisualTracking 2.7.0
** 🎉 FEATURE**
- 動的なフィールドの付与に対応しました。
- 動的フィールドについては[こちら](https://support.karte.io/post/7JbUVotDwZMvl6h3HL9Zt7#6-0)を参考ください。

# Releases - 2021.11.25
### Core 2.19.0
** 🎉 FEATURE**
Expand Down
16 changes: 14 additions & 2 deletions Karte.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,10 @@
683762F9252F201D00E690CE /* SelectorDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 683762F8252F201D00E690CE /* SelectorDetector.swift */; };
6837631B252FDAE200E690CE /* SelectorDetectorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6837631A252FDAE200E690CE /* SelectorDetectorMock.swift */; };
684F02062417640900AF4AC0 /* SafeTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 684F02052417640900AF4AC0 /* SafeTimer.swift */; };
6857834427478B4D00A1AE58 /* DefinitionsRequestForDynamicFieldSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6857834327478B4D00A1AE58 /* DefinitionsRequestForDynamicFieldSpec.swift */; };
6857834627478B7000A1AE58 /* success_vt_definitions_with_dynamic_fields.json in Resources */ = {isa = PBXBuildFile; fileRef = 6857834527478B7000A1AE58 /* success_vt_definitions_with_dynamic_fields.json */; };
68751C272583692D00C6306A /* CrashReporter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68751C0E258368FF00C6306A /* CrashReporter.xcframework */; };
688AB96D274DF02C001C01B5 /* DynamicField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 688AB96C274DF02C001C01B5 /* DynamicField.swift */; };
6898FEC725D3CCA500D0839A /* EventFilterError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6898FEC625D3CCA500D0839A /* EventFilterError.swift */; };
68B40CBA25D2F2870081B1AE /* UnretryableEventFilterRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68B40CB925D2F2870081B1AE /* UnretryableEventFilterRule.swift */; };
68BBBCD524BB5156009A1CE0 /* IAMProcessSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68BBBCD424BB5156009A1CE0 /* IAMProcessSpec.swift */; };
Expand Down Expand Up @@ -905,8 +908,11 @@
683762F8252F201D00E690CE /* SelectorDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorDetector.swift; sourceTree = "<group>"; };
6837631A252FDAE200E690CE /* SelectorDetectorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorDetectorMock.swift; sourceTree = "<group>"; };
684F02052417640900AF4AC0 /* SafeTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafeTimer.swift; sourceTree = "<group>"; };
6857834327478B4D00A1AE58 /* DefinitionsRequestForDynamicFieldSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefinitionsRequestForDynamicFieldSpec.swift; sourceTree = "<group>"; };
6857834527478B7000A1AE58 /* success_vt_definitions_with_dynamic_fields.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = success_vt_definitions_with_dynamic_fields.json; sourceTree = "<group>"; };
68597A44239A324F00607D73 /* InspectorSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorSpec.swift; sourceTree = "<group>"; };
68751C0E258368FF00C6306A /* CrashReporter.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = CrashReporter.xcframework; path = KarteCrashReporting/PLCrashReporter/CrashReporter.xcframework; sourceTree = "<group>"; };
688AB96C274DF02C001C01B5 /* DynamicField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicField.swift; sourceTree = "<group>"; };
6898FEC625D3CCA500D0839A /* EventFilterError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventFilterError.swift; sourceTree = "<group>"; };
68B40CB925D2F2870081B1AE /* UnretryableEventFilterRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnretryableEventFilterRule.swift; sourceTree = "<group>"; };
68BBBCD424BB5156009A1CE0 /* IAMProcessSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAMProcessSpec.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1817,6 +1823,7 @@
0C8976EB237FECFF00098CD8 /* LogicalOperator.swift */,
0C8976EF237FFD5200098CD8 /* ComparisonOperator.swift */,
369C2FDF256B9E6D00ED5948 /* DefinitionsRequest.swift */,
688AB96C274DF02C001C01B5 /* DynamicField.swift */,
);
path = Definition;
sourceTree = "<group>";
Expand Down Expand Up @@ -1862,6 +1869,7 @@
0CC648C4238D5559009EB5DF /* success_vt_1.json */,
0CC648C5238D5559009EB5DF /* success_vt_2.json */,
363F260D2582AE60007E6E4B /* success_vt_definitions.json */,
6857834527478B7000A1AE58 /* success_vt_definitions_with_dynamic_fields.json */,
);
path = Stub;
sourceTree = "<group>";
Expand All @@ -1883,6 +1891,7 @@
0CC648BF238CF97C009EB5DF /* IntegrationTests */ = {
isa = PBXGroup;
children = (
6857834327478B4D00A1AE58 /* DefinitionsRequestForDynamicFieldSpec.swift */,
0CA6D437238E14D800583E5C /* DefinitionLoadSpec.swift */,
0CA6D435238E13D300583E5C /* DefinitionMatchSpec.swift */,
0CA6D441238EC5AD00583E5C /* TracerTests.swift */,
Expand Down Expand Up @@ -2582,6 +2591,7 @@
0CC648C7238D5559009EB5DF /* success_vt_2.json in Resources */,
0CF44AFB242E451000CA7F3A /* success_variables_3.json in Resources */,
363F26172582B028007E6E4B /* success_vt_definitions.json in Resources */,
6857834627478B7000A1AE58 /* success_vt_definitions_with_dynamic_fields.json in Resources */,
36EFDED5271BF26700C60666 /* failure_invalid_request.json in Resources */,
36EFDEDF271BF26B00C60666 /* failure_server_error.json in Resources */,
0CC648BB238CD4AA009EB5DF /* success_empty.json in Resources */,
Expand Down Expand Up @@ -2938,6 +2948,7 @@
0C8976C5237EDD4D00098CD8 /* Account.swift in Sources */,
0C8976F823801DC200098CD8 /* PairingClient.swift in Sources */,
0C8976CB237EE78D00098CD8 /* UIViewController+VisualTracking.swift in Sources */,
688AB96D274DF02C001C01B5 /* DynamicField.swift in Sources */,
369C2FE0256B9E6D00ED5948 /* DefinitionsRequest.swift in Sources */,
0C8976CE237EE78D00098CD8 /* UINavigationController+VisualTracking.swift in Sources */,
0C8976EC237FECFF00098CD8 /* LogicalOperator.swift in Sources */,
Expand Down Expand Up @@ -3052,6 +3063,7 @@
0C83931D240838320014C2BF /* TracerTests.swift in Sources */,
0C8392F42407CCE60014C2BF /* ConfigurationTests.swift in Sources */,
0C839310240831630014C2BF /* SetupSpec.swift in Sources */,
6857834427478B4D00A1AE58 /* DefinitionsRequestForDynamicFieldSpec.swift in Sources */,
36EFDEC0271ABDE200C60666 /* TodaySupplierMock.swift in Sources */,
0C839305240822A40014C2BF /* EventSpec.swift in Sources */,
0CFD001524ECCA5800598C8C /* CommandBundlerProxySpec.swift in Sources */,
Expand Down Expand Up @@ -3622,7 +3634,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 2.6.0;
MARKETING_VERSION = 2.7.0;
PRODUCT_BUNDLE_IDENTIFIER = io.karte.KarteVisualTracking;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand Down Expand Up @@ -3653,7 +3665,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 2.6.0;
MARKETING_VERSION = 2.7.0;
PRODUCT_BUNDLE_IDENTIFIER = io.karte.KarteVisualTracking;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//
// Copyright 2020 PLAID, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Quick
import Nimble
import Mockingjay
import KarteUtilities
@testable import KarteCore
@testable import KarteVisualTracking

class DefinitionsRequestForDynamicFieldSpec: QuickSpec {

override func spec() {
var configuration: KarteCore.Configuration!
var builder: Builder!

beforeSuite {
configuration = Configuration { (configuration) in
configuration.isSendInitializationEventEnabled = false
}
builder = StubBuilder(spec: self, resource: .vt_definitions_with_dynamic_fields).build()
}

describe("a definition get") {
var request: URLRequest!
beforeEach {
let exp = self.expectation(description: "Wait for get definitions.")
let stub = self.stub(uri("/v0/native/auto-track/definitions"), {(r) -> (Response) in
request = r
return builder(request)
})

KarteApp.setup(appKey: APP_KEY, configuration: configuration)
VisualTrackingManager.shared.tracker?.refreshDefinitions{
exp.fulfill()
}

self.wait(for: [exp], timeout: 10)
self.removeStub(stub)
}

describe("its request") {
it("has `X-KARTE-Auto-Track-OS` header") {
expect(request.allHTTPHeaderFields?.keys.contains("X-KARTE-Auto-Track-OS")).to(beTrue())
}

it("`X-KARTE-Auto-Track-OS` header value is `iOS`") {
expect(request.allHTTPHeaderFields?["X-KARTE-Auto-Track-OS"]).to(equal("iOS"))
}

it("has `X-KARTE-Auto-Track-If-Modified-Since` header") {
expect(request.allHTTPHeaderFields?.keys.contains("X-KARTE-Auto-Track-If-Modified-Since")).to(beTrue())
}

it("`has X-KARTE-Auto-Track-If-Modified-Since` header that value is `0`") {
expect(request.allHTTPHeaderFields?["X-KARTE-Auto-Track-If-Modified-Since"]).to(equal("0"))
}
}

describe("its definitions") {
var definitions: AutoTrackDefinition?
beforeEach {
definitions = VisualTrackingManager.shared.tracker?.definitions
}

it("is not nil") {
expect(definitions).toNot(beNil())
}

it("only has valid trigger") {
expect(definitions?.definitions?.first?.triggers.count).to(equal(4))
}

it("only has valid conditions") {
if case let .and(c) = definitions?.definitions?.first?.triggers.first?.condition {
expect(c.count).to(equal(2))
} else {
fail()
}
}
}
describe("its definitions with dynamic fields") {
var definitions: AutoTrackDefinition?
var window: UIWindow!
var view1: UIView!
var view2: UIView!
var view3: UIView!
var label: UILabel!

beforeEach {
window = UIWindow()
view1 = UIView()
view2 = UIView()
view3 = UIView()
label = UILabel()
label.text = "test"
view1.addSubview(view2)
view1.addSubview(view3)
view1.addSubview(label)
window.addSubview(view1)
}
beforeEach {
definitions = VisualTrackingManager.shared.tracker?.definitions
}
it("returns valid dynamic fields") {
let dynamicFieldsCount = definitions?.definitions?.first?.triggers.first?.dynamicFields?.count
expect(dynamicFieldsCount).to(equal(4))
}

it("returns valid dynamic values") {
let dynamicValues = definitions?.definitions?.first?.triggers.first?.dynamicValues(window: window)
expect(dynamicValues?.count).to(equal(4))
expect(dynamicValues! as? [String: String]).to(equal(["foo":"test","bar":"test","baz":"test","has_unknown_key":"test"]))
}

it("returns invalid dynamic values") {
let dynamicValues = definitions?.definitions?.first?.triggers[1].dynamicValues(window: window)
expect(dynamicValues).to(beNil())
}

it("returns invalid dynamic values") {
let dynamicValues = definitions?.definitions?.first?.triggers[2].dynamicValues(window: window)
expect(dynamicValues).to(beNil())
}

it("returns invalid dynamic values") {
let dynamicValues = definitions?.definitions?.first?.triggers[3].dynamicValues(window: window)
expect(dynamicValues).to(beNil())
}
}
}
}
}
48 changes: 45 additions & 3 deletions KarteTests/KarteVisualTrackingTests/UnitTests/ActionSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class ActionSpec: QuickSpec {
"dummy_action",
view: button,
viewController: viewController,
targetText: "dummy_target_text"
targetText: "dummy_target_text",
actionId: UIKitAction.actionId(view: button)
)
}

Expand Down Expand Up @@ -84,7 +85,8 @@ class ActionSpec: QuickSpec {
"dummy_action",
view: button0,
viewController: viewController,
targetText: "dummy_target_text"
targetText: "dummy_target_text",
actionId: UIKitAction.actionId(view: button0)
)
expect(action!.actionId!).to(equal("UIButton0UIView0UIView"))
}
Expand All @@ -93,7 +95,8 @@ class ActionSpec: QuickSpec {
"dummy_action",
view: button1,
viewController: viewController,
targetText: "dummy_target_text"
targetText: "dummy_target_text",
actionId: UIKitAction.actionId(view: button1)
)
expect(action!.actionId!).to(equal("UIButton1UIView0UIView"))
}
Expand Down Expand Up @@ -158,6 +161,45 @@ class ActionSpec: QuickSpec {
}
}
}
describe("its viewPathIndices") {
context("when passing nil") {
it("returns empty array") {
let actual = UIKitAction.viewPathIndices(actionId: nil)
expect(actual).to(equal([]))
}
}
context("when passing empty string") {
it("returns empty array") {
let actual = UIKitAction.viewPathIndices(actionId: "")
expect(actual).to(equal([]))
}
}
context("when passing UIView") {
it("returns empty array") {
let actual = UIKitAction.viewPathIndices(actionId: "UIView")
expect(actual).to(equal([]))
}
}
context("when passing UIView0") {
it("returns array with 0") {
let actual = UIKitAction.viewPathIndices(actionId: "UIView0")
expect(actual).to(equal([0]))
}
}
context("when passing complexView") {
it("returns array with 0,0,0,0,0,0,0,11") {
let actual = UIKitAction.viewPathIndices(actionId: "UIView11UITableView0UIView0UIViewControllerWrapperView0UINavigationTransitionView0UILayoutContainerView0UIDropShadowView0UITransitionView0SimpleUIWindow")
expect(actual).toNot(beNil())
expect(actual).to(equal([0,0,0,0,0,0,0,11]))
}
}
context("when passing UIView999UIView2000UIView3000") {
it("returns array with 3000,2000,999") {
let actual = UIKitAction.viewPathIndices(actionId: "UIView999UIView2000UIView3000")
expect(actual).to(equal([3000,2000,999]))
}
}
}
}
}
}
Loading

0 comments on commit 857eed6

Please sign in to comment.