[ios] add TrackRecordingManager unit tests

Signed-off-by: Kiryl Kaveryn <kirylkaveryn@gmail.com>
This commit is contained in:
Kiryl Kaveryn
2025-02-26 20:17:55 +04:00
committed by Yannik Bloscheck
parent b79724f248
commit d677112edd
2 changed files with 210 additions and 0 deletions

View File

@@ -511,6 +511,7 @@
ED9857082C4ED02D00694F6C /* MailComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED9857072C4ED02D00694F6C /* MailComposer.swift */; };
ED9966802B94FBC20083CE55 /* ColorPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED99667D2B94FBC20083CE55 /* ColorPicker.swift */; };
ED9DDF882D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED9DDF872D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift */; };
ED9DDF9D2D6F6F7900645BC8 /* TrackRecordingManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED9DDF9B2D6F6DA300645BC8 /* TrackRecordingManagerTests.swift */; };
EDA1EAA42CC7ECAD00DBDCAA /* ElevationProfileFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDA1EAA32CC7ECAD00DBDCAA /* ElevationProfileFormatter.swift */; };
EDB71D8C2D8474A0004A6A7F /* CornerRadius.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDB71D8B2D8474A0004A6A7F /* CornerRadius.swift */; };
EDB71E002D8B0338004A6A7F /* ModalPresentationAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDB71DFF2D8B0338004A6A7F /* ModalPresentationAnimator.swift */; };
@@ -1528,6 +1529,7 @@
ED9857072C4ED02D00694F6C /* MailComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailComposer.swift; sourceTree = "<group>"; };
ED99667D2B94FBC20083CE55 /* ColorPicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPicker.swift; sourceTree = "<group>"; };
ED9DDF872D6F151000645BC8 /* PlacePageTrackRecordingLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlacePageTrackRecordingLayout.swift; sourceTree = "<group>"; };
ED9DDF9B2D6F6DA300645BC8 /* TrackRecordingManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackRecordingManagerTests.swift; sourceTree = "<group>"; };
EDA1EAA32CC7ECAD00DBDCAA /* ElevationProfileFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElevationProfileFormatter.swift; sourceTree = "<group>"; };
EDB71D8B2D8474A0004A6A7F /* CornerRadius.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerRadius.swift; sourceTree = "<group>"; };
EDB71DFF2D8B0338004A6A7F /* ModalPresentationAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalPresentationAnimator.swift; sourceTree = "<group>"; };
@@ -2797,6 +2799,7 @@
4B4153B62BF9709100EE4B02 /* Core */ = {
isa = PBXGroup;
children = (
ED9DDF982D6F6D8000645BC8 /* TrackRecorder */,
EDF838AB2C00B9C7007E4E67 /* iCloudTests */,
4B4153B72BF970A000EE4B02 /* TextToSpeech */,
);
@@ -3344,6 +3347,14 @@
path = ColorPicker;
sourceTree = "<group>";
};
ED9DDF982D6F6D8000645BC8 /* TrackRecorder */ = {
isa = PBXGroup;
children = (
ED9DDF9B2D6F6DA300645BC8 /* TrackRecordingManagerTests.swift */,
);
path = TrackRecorder;
sourceTree = "<group>";
};
EDC4E3422C5D1BD3009286A2 /* RecentlyDeletedTests */ = {
isa = PBXGroup;
children = (
@@ -4923,6 +4934,7 @@
EDF838C32C00B9D6007E4E67 /* UbiquitousDirectoryMonitorDelegateMock.swift in Sources */,
EDF838BE2C00B9D0007E4E67 /* LocalDirectoryMonitorDelegateMock.swift in Sources */,
EDC4E3692C5E6F5B009286A2 /* MockRecentlyDeletedCategoriesManager.swift in Sources */,
ED9DDF9D2D6F6F7900645BC8 /* TrackRecordingManagerTests.swift in Sources */,
EDF838BF2C00B9D0007E4E67 /* SynchronizationStateManagerTests.swift in Sources */,
ED810EC52D566E9B00ECDE2C /* SearchOnMapTests.swift in Sources */,
4B83AE4B2C2E642100B0C3BC /* TTSTesterTest.m in Sources */,

View File

@@ -0,0 +1,198 @@
import XCTest
@testable import Organic_Maps__Debug_
final class TrackRecordingManagerTests: XCTestCase {
private var trackRecordingManager: TrackRecordingManager!
private var mockTrackRecorder: MockTrackRecorder.Type!
private var mockLocationService: MockLocationService.Type!
private var mockActivityManager: MockTrackRecordingActivityManager!
override func setUp() {
super.setUp()
mockTrackRecorder = MockTrackRecorder.self
mockLocationService = MockLocationService.self
mockActivityManager = MockTrackRecordingActivityManager()
trackRecordingManager = TrackRecordingManager(
trackRecorder: mockTrackRecorder,
locationService: mockLocationService,
activityManager: mockActivityManager
)
}
override func tearDown() {
trackRecordingManager = nil
mockTrackRecorder.reset()
mockLocationService.reset()
mockActivityManager = nil
super.tearDown()
}
func test_GivenInitialSetup_WhenLocationEnabled_ThenStateIsInactive() {
mockLocationService.locationIsProhibited = false
mockTrackRecorder.trackRecordingIsEnabled = false
trackRecordingManager.setup()
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
}
func test_GivenInitialSetup_WhenLocationDisabled_ThenShouldHandleErrorAndIncativeState() {
mockLocationService.locationIsProhibited = true
trackRecordingManager.setup()
XCTAssertTrue(mockLocationService.checkLocationStatusCalled)
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
}
func test_GivenStartRecording_WhenLocationEnabled_ThenSuccess() {
mockLocationService.locationIsProhibited = false
mockTrackRecorder.trackRecordingIsEnabled = false
trackRecordingManager.processAction(.start)
XCTAssertTrue(mockTrackRecorder.startTrackRecordingCalled)
XCTAssertTrue(mockActivityManager.startCalled)
XCTAssertTrue(trackRecordingManager.recordingState == .active)
}
func test_GivenStartRecording_WhenLocationDisabled_ThenShouldFail() {
mockLocationService.locationIsProhibited = true
trackRecordingManager.processAction(.start) { result in
switch result {
case .success:
XCTFail("Should not succeed")
case .error(let error):
switch error {
case .locationIsProhibited:
XCTAssertTrue(true)
default:
XCTFail("Unexpected error: \(error)")
}
}
}
XCTAssertFalse(self.mockTrackRecorder.startTrackRecordingCalled)
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
}
func test_GivenStopRecording_WhenLocationEnabled_ThenSuccess() {
mockTrackRecorder.trackRecordingIsEnabled = true
mockTrackRecorder.trackRecordingIsEmpty = false
trackRecordingManager.processAction(.stopAndSave(name: "Test Track")) { result in
switch result {
case .success:
XCTAssertTrue(true)
case .error(let error):
XCTFail("Unexpected error: \(error)")
}
}
XCTAssertTrue(mockTrackRecorder.stopTrackRecordingCalled)
XCTAssertTrue(mockTrackRecorder.saveTrackRecordingCalled)
XCTAssertTrue(mockActivityManager.stopCalled)
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
}
func test_GivenStopRecording_WhenTrackIsEmpty_ThenShouldFail() {
mockTrackRecorder.trackRecordingIsEnabled = true
mockTrackRecorder.trackRecordingIsEmpty = true
trackRecordingManager.processAction(.stopAndSave(name: "Test Track")) { result in
switch result {
case .success:
XCTFail("Should not succeed")
case .error(let error):
switch error {
case .trackIsEmpty:
XCTAssertTrue(true)
default:
XCTFail("Unexpected error: \(error)")
}
}
}
XCTAssertFalse(mockTrackRecorder.saveTrackRecordingCalled)
XCTAssertTrue(trackRecordingManager.recordingState == .inactive)
}
}
// MARK: - Mock Classes
private final class MockTrackRecorder: TrackRecorder {
static var trackRecordingIsEnabled = false
static var trackRecordingIsEmpty = false
static var startTrackRecordingCalled = false
static var stopTrackRecordingCalled = false
static var saveTrackRecordingCalled = false
static func reset() {
trackRecordingIsEnabled = false
trackRecordingIsEmpty = false
startTrackRecordingCalled = false
stopTrackRecordingCalled = false
saveTrackRecordingCalled = false
}
static func isTrackRecordingEnabled() -> Bool {
return trackRecordingIsEnabled
}
static func isTrackRecordingEmpty() -> Bool {
return trackRecordingIsEmpty
}
static func startTrackRecording() {
startTrackRecordingCalled = true
trackRecordingIsEnabled = true
}
static func stopTrackRecording() {
stopTrackRecordingCalled = true
trackRecordingIsEnabled = false
}
static func saveTrackRecording(withName name: String) {
saveTrackRecordingCalled = true
}
static func setTrackRecordingUpdateHandler(_ handler: ((TrackInfo) -> Void)?) {}
static func trackRecordingElevationInfo() -> ElevationProfileData {
ElevationProfileData()
}
}
private final class MockLocationService: LocationService {
static var locationIsProhibited = false
static var checkLocationStatusCalled = false
static func reset() {
locationIsProhibited = false
checkLocationStatusCalled = false
}
static func isLocationProhibited() -> Bool {
return locationIsProhibited
}
static func checkLocationStatus() {
checkLocationStatusCalled = true
}
}
final class MockTrackRecordingActivityManager: TrackRecordingActivityManager {
var startCalled = false
var stopCalled = false
func start(with info: TrackInfo) throws {
startCalled = true
}
func stop() {
stopCalled = true
}
func update(_ info: TrackInfo) {}
}