mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-06 17:05:34 +00:00
144 lines
6 KiB
Swift
144 lines
6 KiB
Swift
//
|
|
// HTTPDownloaderTests.swift
|
|
// KeymanEngineTests
|
|
//
|
|
// Created by Joshua Horton on 5/27/20.
|
|
// Copyright © 2020 SIL International. All rights reserved.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import KeymanEngine
|
|
|
|
class HTTPDownloaderTests: XCTestCase {
|
|
var downloader: HTTPDownloader?
|
|
var mockedURLSession: TestUtils.Downloading.URLSessionMock?
|
|
|
|
override func setUp() {
|
|
mockedURLSession = TestUtils.Downloading.URLSessionMock()
|
|
downloader = HTTPDownloader(nil, session: mockedURLSession!)
|
|
}
|
|
|
|
override func tearDownWithError() throws {
|
|
let queueWasCleared = mockedURLSession!.queueIsEmpty
|
|
mockedURLSession = nil
|
|
downloader = nil
|
|
|
|
if !queueWasCleared {
|
|
throw NSError(domain: "Keyman",
|
|
code: 4,
|
|
userInfo: [NSLocalizedDescriptionKey: "A test did not fully utilize its queued mock results!"])
|
|
}
|
|
}
|
|
|
|
func testSingleRequestSuccess() throws {
|
|
// Simple, easy case: our local testing copy of the Khmer Angkor KMP file.
|
|
let mockedResult = TestUtils.Downloading.MockResult(location: TestUtils.Keyboards.khmerAngkorKMP, error: nil)
|
|
mockedURLSession?.queueMockResult(.download(mockedResult))
|
|
|
|
let testDelegate = TestUtils.Downloading.ExpectationDownloaderDelegate()
|
|
downloader!.handler = testDelegate
|
|
|
|
let request = HTTPDownloadRequest(url: TestUtils.Keyboards.khmerAngkorKMP)
|
|
downloader!.addRequest(request)
|
|
testDelegate.expect(method: .RequestStarted, request: request)
|
|
testDelegate.expect(method: .RequestFinished, request: request)
|
|
testDelegate.expect(method: .QueueFinished, queue: downloader!)
|
|
|
|
XCTAssertEqual(downloader!.requestsCount, 1)
|
|
downloader!.run()
|
|
testDelegate.sequentialWait(testCase: self, timeout: 10)
|
|
}
|
|
|
|
func testSingleRequestFailure() throws {
|
|
// A twist on the previous version - the 'download' fails.
|
|
let mockedResult = TestUtils.Downloading.MockResult(location: TestUtils.Keyboards.khmerAngkorKMP, error: TestUtils.mockedError)
|
|
mockedURLSession?.queueMockResult(.download(mockedResult))
|
|
|
|
let testDelegate = TestUtils.Downloading.ExpectationDownloaderDelegate()
|
|
downloader!.handler = testDelegate
|
|
|
|
let request = HTTPDownloadRequest(url: TestUtils.Keyboards.khmerAngkorKMP)
|
|
downloader!.addRequest(request)
|
|
testDelegate.expect(method: .RequestStarted, request: request)
|
|
testDelegate.expect(method: .RequestFailed, request: request)
|
|
testDelegate.expect(method: .QueueFinished, queue: downloader!)
|
|
|
|
XCTAssertEqual(downloader!.requestsCount, 1)
|
|
downloader!.run()
|
|
testDelegate.sequentialWait(testCase: self, timeout: 10)
|
|
}
|
|
|
|
func testSequentialRequests() {
|
|
let mockedResult1 = TestUtils.Downloading.MockResult(location: TestUtils.Keyboards.khmerAngkorKMP, error: nil)
|
|
mockedURLSession?.queueMockResult(.download(mockedResult1))
|
|
|
|
let mockedResult2 = TestUtils.Downloading.MockResult(location:
|
|
TestUtils.LexicalModels.mtntKMP, error: nil)
|
|
mockedURLSession?.queueMockResult(.download(mockedResult2))
|
|
|
|
let testDelegate = TestUtils.Downloading.ExpectationDownloaderDelegate()
|
|
downloader!.handler = testDelegate
|
|
|
|
let request1 = HTTPDownloadRequest(url: TestUtils.Keyboards.khmerAngkorKMP)
|
|
downloader!.addRequest(request1)
|
|
testDelegate.expect(method: .RequestStarted, request: request1)
|
|
testDelegate.expect(method: .RequestFinished, request: request1)
|
|
|
|
let request2 = HTTPDownloadRequest(url: TestUtils.LexicalModels.mtntKMP)
|
|
downloader!.addRequest(request2)
|
|
testDelegate.expect(method: .RequestStarted, request: request2)
|
|
testDelegate.expect(method: .RequestFinished, request: request2)
|
|
testDelegate.expect(method: .QueueFinished, queue: downloader!)
|
|
|
|
XCTAssertEqual(downloader!.requestsCount, 2)
|
|
downloader!.run()
|
|
// This is currently safe, as all downloads are sequential. If we ever
|
|
// enable parallel downloads, this will obviously need to change
|
|
testDelegate.sequentialWait(testCase: self, timeout: 10)
|
|
}
|
|
|
|
func testRequestCancellation() {
|
|
let mockedResult1 = TestUtils.Downloading.MockResult(location: TestUtils.Keyboards.khmerAngkorKMP, error: nil)
|
|
mockedURLSession?.queueMockResult(.download(mockedResult1))
|
|
|
|
// No second mocked result - its call should be cancelled.
|
|
|
|
let testDelegate = TestUtils.Downloading.ExpectationDownloaderDelegate()
|
|
downloader!.handler = testDelegate
|
|
|
|
let request1 = HTTPDownloadRequest(url: TestUtils.Keyboards.khmerAngkorKMP)
|
|
downloader!.addRequest(request1)
|
|
testDelegate.expect(method: .RequestStarted, request: request1)
|
|
|
|
let request2 = HTTPDownloadRequest(url: TestUtils.LexicalModels.mtntKMP)
|
|
downloader!.addRequest(request2)
|
|
testDelegate.expectAbsence(method: .RequestStarted, request: request2)
|
|
testDelegate.expectAbsence(method: .RequestFinished, request: request2)
|
|
testDelegate.expect(method: .QueueCancelled, queue: downloader!)
|
|
testDelegate.expectAbsence(method: .QueueFinished, queue: downloader!)
|
|
|
|
// Placed here for chronological ordering. We expect the request to finish because of
|
|
// our mocking structure, but want to delay its completion long enough for the
|
|
// `cancelAllOperations` call below to complete.
|
|
testDelegate.expect(method: .RequestFinished, request: request1, completion: { response in
|
|
// Force a delay so that our `cancelAllOperations` call has a chance to execute;
|
|
// our mocking structure is otherwise synchronous!
|
|
sleep(1) // in seconds.
|
|
response.expectation.fulfill()
|
|
return false
|
|
})
|
|
|
|
// Ideally, we could add this... but because of how things are currently mocked,
|
|
// it actually does trigger - we have a .RequestFinished processing after .QueueCancelled,
|
|
// which then notes the empty queue.
|
|
//
|
|
// testDelegate.expectAbsence(method: .QueueFinished, queue: downloader!)
|
|
|
|
XCTAssertEqual(downloader!.requestsCount, 2)
|
|
downloader!.run()
|
|
downloader!.cancelAllOperations()
|
|
// This is currently safe, as all downloads are sequential. If we ever
|
|
// enable parallel downloads, this will obviously need to change
|
|
testDelegate.sequentialWait(testCase: self, timeout: 5)
|
|
}
|
|
}
|