[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
parent 6d5c06272e
commit e001e75aba
2 changed files with 210 additions and 0 deletions

View file

@ -525,6 +525,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 */; };
EDBD68072B625724005DD151 /* LocationServicesDisabledAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = EDBD68062B625724005DD151 /* LocationServicesDisabledAlert.xib */; };
EDBD680B2B62572E005DD151 /* LocationServicesDisabledAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDBD680A2B62572E005DD151 /* LocationServicesDisabledAlert.swift */; };
@ -1492,6 +1493,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>"; };
EDBD68062B625724005DD151 /* LocationServicesDisabledAlert.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LocationServicesDisabledAlert.xib; sourceTree = "<group>"; };
EDBD680A2B62572E005DD151 /* LocationServicesDisabledAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationServicesDisabledAlert.swift; sourceTree = "<group>"; };
@ -2767,6 +2769,7 @@
4B4153B62BF9709100EE4B02 /* Core */ = {
isa = PBXGroup;
children = (
ED9DDF982D6F6D8000645BC8 /* TrackRecorder */,
EDF838AB2C00B9C7007E4E67 /* iCloudTests */,
4B4153B72BF970A000EE4B02 /* TextToSpeech */,
);
@ -3315,6 +3318,14 @@
path = ColorPicker;
sourceTree = "<group>";
};
ED9DDF982D6F6D8000645BC8 /* TrackRecorder */ = {
isa = PBXGroup;
children = (
ED9DDF9B2D6F6DA300645BC8 /* TrackRecordingManagerTests.swift */,
);
path = TrackRecorder;
sourceTree = "<group>";
};
EDC4E3422C5D1BD3009286A2 /* RecentlyDeletedTests */ = {
isa = PBXGroup;
children = (
@ -4911,6 +4922,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) {}
}