142 lines
5.5 KiB
Swift
142 lines
5.5 KiB
Swift
|
@testable import WMF
|
||
|
@testable import Wikipedia
|
||
|
|
||
|
import XCTest
|
||
|
|
||
|
class NotificationsCenterViewModelTests: XCTestCase {
|
||
|
|
||
|
enum TestError: Error {
|
||
|
case failureSettingUpModelController
|
||
|
case failurePullingFixtures
|
||
|
case failureConvertingDataToNotificationsResult
|
||
|
case failurePullingNetworkNotificationModels
|
||
|
case failureSavingNetworkNotificationModelsToDatabase
|
||
|
case failurePullingManagedObjectFromDatabase
|
||
|
case failureConvertingManagedObjectToViewModel
|
||
|
}
|
||
|
|
||
|
var dataFileName: String {
|
||
|
XCTFail("Must override dataFileName.")
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
private var data: Data!
|
||
|
private var networkModels: [RemoteNotificationsAPIController.NotificationsResult.Notification]!
|
||
|
|
||
|
let dataStore = MWKDataStore.temporary()
|
||
|
|
||
|
lazy var languageLinkController = {
|
||
|
dataStore.languageLinkController
|
||
|
}()
|
||
|
lazy var configuration = {
|
||
|
dataStore.configuration
|
||
|
}()
|
||
|
|
||
|
private let modelController: RemoteNotificationsModelController! = try? RemoteNotificationsModelController.temporaryModelController()
|
||
|
|
||
|
override func setUp(completion: @escaping (Error?) -> Void) {
|
||
|
|
||
|
if let gmtTimeZone = TimeZone(abbreviation: "GMT") {
|
||
|
NSTimeZone.default = gmtTimeZone
|
||
|
}
|
||
|
|
||
|
guard modelController != nil else {
|
||
|
completion(TestError.failureSettingUpModelController)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if let data = wmf_bundle().wmf_data(fromContentsOfFile: dataFileName, ofType: "json") {
|
||
|
self.data = data
|
||
|
} else {
|
||
|
completion(TestError.failurePullingFixtures)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
let decoder = JSONDecoder()
|
||
|
let networkResult: RemoteNotificationsAPIController.NotificationsResult
|
||
|
|
||
|
do {
|
||
|
networkResult = try decoder.decode(RemoteNotificationsAPIController.NotificationsResult.self, from: data)
|
||
|
} catch {
|
||
|
completion(TestError.failureConvertingDataToNotificationsResult)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
guard let networkModels = networkResult.query?.notifications?.list,
|
||
|
networkModels.count > 0 else {
|
||
|
completion(TestError.failurePullingNetworkNotificationModels)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
self.networkModels = networkModels
|
||
|
|
||
|
saveNetworkModels(networkModels: networkModels) { result in
|
||
|
|
||
|
switch result {
|
||
|
case .success:
|
||
|
completion(nil)
|
||
|
case .failure:
|
||
|
completion(TestError.failureSavingNetworkNotificationModelsToDatabase)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
override func tearDown(completion: @escaping (Error?) -> Void) {
|
||
|
NSTimeZone.resetSystemTimeZone()
|
||
|
completion(nil)
|
||
|
}
|
||
|
|
||
|
func fetchManagedObject(identifier: String) throws -> RemoteNotification {
|
||
|
|
||
|
let predicate = NSPredicate(format: "id == %@", identifier)
|
||
|
guard let managedObject = try? self.modelController.fetchNotifications(predicate: predicate).first else {
|
||
|
throw TestError.failurePullingManagedObjectFromDatabase
|
||
|
}
|
||
|
return managedObject
|
||
|
}
|
||
|
|
||
|
func detailViewModelFromIdentifier(identifier: String) throws -> NotificationsCenterDetailViewModel {
|
||
|
|
||
|
let notification = try fetchManagedObject(identifier: identifier)
|
||
|
guard let apiIdentifier = notification.wiki,
|
||
|
let project = WikimediaProject(notificationsApiIdentifier: apiIdentifier, languageLinkController: languageLinkController) else {
|
||
|
throw TestError.failureConvertingManagedObjectToViewModel
|
||
|
}
|
||
|
|
||
|
let commonViewModel = NotificationsCenterCommonViewModel(configuration: configuration, notification: notification, project: project)
|
||
|
|
||
|
return NotificationsCenterDetailViewModel(commonViewModel: commonViewModel)
|
||
|
}
|
||
|
|
||
|
private func saveNetworkModels(networkModels: [RemoteNotificationsAPIController.NotificationsResult.Notification], completion: @escaping (Result<Void, Error>) -> Void) {
|
||
|
|
||
|
let backgroundContext = modelController!.newBackgroundContext()
|
||
|
modelController!.createNewNotifications(moc: backgroundContext, notificationsFetchedFromTheServer: Set(networkModels)) { result in
|
||
|
DispatchQueue.main.async {
|
||
|
switch result {
|
||
|
case .success:
|
||
|
completion(.success(()))
|
||
|
|
||
|
case .failure(let error):
|
||
|
completion(.failure(error))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testActions(expectedText: String, expectedURL: URL?, expectedIcon: NotificationsCenterIconType?, expectedDestinationText: String?, actionToTest: NotificationsCenterAction, isMarkAsRead: Bool = false, isNotificationSettings: Bool = false, actionType: NotificationsCenterActionData.LoggingLabel?) throws {
|
||
|
let expectedActionData = NotificationsCenterActionData(text: expectedText, url: expectedURL, iconType: expectedIcon, destinationText: expectedDestinationText, actionType: actionType)
|
||
|
let expectedAction: NotificationsCenterAction
|
||
|
if isMarkAsRead {
|
||
|
expectedAction = NotificationsCenterAction.markAsReadOrUnread(expectedActionData)
|
||
|
} else if isNotificationSettings {
|
||
|
expectedAction = NotificationsCenterAction.notificationSubscriptionSettings(expectedActionData)
|
||
|
} else {
|
||
|
expectedAction = NotificationsCenterAction.custom(expectedActionData)
|
||
|
}
|
||
|
|
||
|
XCTAssertEqual(expectedAction, actionToTest, "Invalid action")
|
||
|
XCTAssertEqual(expectedActionData.actionType?.stringValue, actionToTest.actionData?.actionType?.stringValue)
|
||
|
}
|
||
|
}
|