deep-linking-sample/Apps/Wikipedia/WikipediaUnitTests/Code/TalkPageLocalHandlerTests.swift

286 lines
14 KiB
Swift
Raw Normal View History

import XCTest
import CoreData
@testable import Wikipedia
class TalkPageLocalHandlerTests: XCTestCase {
let urlString1 = "https://en.wikipedia.org/api/rest_v1/page/talk/Username1"
let urlString2 = "https://en.wikipedia.org/api/rest_v1/page/talk/Username2"
let urlString3 = "https://es.wikipedia.org/api/rest_v1/page/talk/Username1"
var tempDataStore: MWKDataStore!
var moc: NSManagedObjectContext!
override func setUp() {
super.setUp()
tempDataStore = MWKDataStore.temporary()
moc = tempDataStore.viewContext
}
override func tearDown() {
tempDataStore.removeFolderAtBasePath()
tempDataStore = nil
super.tearDown()
}
func testCreateFirstTalkPageSavesToDatabase() {
// confirm no talk pages in DB
let fetchRequest: NSFetchRequest<TalkPage> = TalkPage.fetchRequest()
guard let firstResults = try? tempDataStore.viewContext.fetch(fetchRequest) else {
XCTFail("Failure fetching initial talk pages")
return
}
XCTAssertEqual(firstResults.count, 0, "Expected zero existing talk pages at first")
// add network talk page
guard let json = wmf_bundle().wmf_data(fromContentsOfFile: TalkPageTestHelpers.TalkPageJSONType.original.fileName, ofType: "json"),
let talkPage = TalkPageTestHelpers.networkTalkPage(for: urlString1, data: json, revisionId: 1) else {
XCTFail("Failure stubbing out network talk page")
return
}
// create db talk page
guard let dbTalkPage = moc.createTalkPage(with: talkPage) else {
XCTFail("Failure to create db talk page")
return
}
// assert db talk page values
let keyedUrlString = URL(string: urlString1)?.wmf_databaseKey
XCTAssertNotNil(dbTalkPage.key)
XCTAssertEqual(dbTalkPage.key, keyedUrlString, "Unexpected key")
XCTAssertEqual(dbTalkPage.revisionId, 1, "Unexpected revisionId")
XCTAssertEqual(dbTalkPage.topics?.count, 6, "Unexpected topic count")
let topics = dbTalkPage.topics?.allObjects.sorted { ($0 as! TalkPageTopic).sort < ($1 as! TalkPageTopic).sort }
if let introTopic = topics?[0] as? TalkPageTopic {
XCTAssertEqual(introTopic.title, "", "Unexpected topic title")
XCTAssertEqual(introTopic.replies?.count, 1, "Unexpected replies count")
let replies = introTopic.replies?.allObjects.sorted { ($0 as! TalkPageReply).sort < ($1 as! TalkPageReply).sort }
if let firstReply = replies?[0] as? TalkPageReply {
XCTAssertEqual(firstReply.text, "Hello! This is some introduction text on my talk page. L8erz, <a href='./User:TSevener_(WMF)' title='User:TSevener (WMF)'>TSevener (WMF)</a> (<a href='./User_talk:TSevener_(WMF)' title='User talk:TSevener (WMF)'>talk</a>) 20:48, 21 June 2019 (UTC)", "Unexpected replies html")
} else {
XCTFail("Unexpected first reply type")
}
} else {
XCTFail("Unexpected intro topic type")
}
if let firstTopic = topics?[1] as? TalkPageTopic {
XCTAssertEqual(firstTopic.title, "Lets talk about talk pages", "Unexpected topic title")
XCTAssertEqual(firstTopic.replies?.count, 3, "Unexpected topic items count")
let replies = firstTopic.replies?.allObjects.sorted { ($0 as! TalkPageReply).sort < ($1 as! TalkPageReply).sort }
if let firstReply = replies?[0] as? TalkPageReply {
XCTAssertEqual(firstReply.text, "Hello, I am testing a new topic from the <a href='./IOS' title='IOS'>iOS</a> app. It is fun. <a href='./Special:Contributions/47.184.10.84' title='Special:Contributions/47.184.10.84'>47.184.10.84</a> 20:50, 21 June 2019 (UTC)")
XCTAssertEqual(firstReply.depth, 0, "Unexpected reply depth")
} else {
XCTFail("Unexpected first reply type")
}
if let secondReply = replies?[1] as? TalkPageReply {
XCTAssertEqual(secondReply.text, "Hello back! This is a nested reply. <a href='./User:TSevener_(WMF)' title='User:TSevener (WMF)'>TSevener (WMF)</a> (<a href='./User_talk:TSevener_(WMF)' title='User talk:TSevener (WMF)'>talk</a>) 20:51, 21 June 2019 (UTC)")
XCTAssertEqual(secondReply.depth, 1, "Unexpected reply depth")
} else {
XCTFail("Unexpected second reply type")
}
if let thirdReply = replies?[2] as? TalkPageReply {
XCTAssertEqual(thirdReply.text, "Yes I see, I am nested as well. <a href='./Special:Contributions/47.184.10.84' title='Special:Contributions/47.184.10.84'>47.184.10.84</a> 20:52, 21 June 2019 (UTC)")
XCTAssertEqual(thirdReply.depth, 2, "Unexpected reply depth")
} else {
XCTFail("Unexpected third reply type")
}
} else {
XCTFail("Unexpected first topic type")
}
if let secondTopic = topics?[2] as? TalkPageTopic {
XCTAssertEqual(secondTopic.title, "Subtopic time")
XCTAssertEqual(secondTopic.replies?.count, 2, "Unexpected topic items count")
}
if let thirdTopic = topics?[3] as? TalkPageTopic {
XCTAssertEqual(thirdTopic.title, "Sub sub topic")
XCTAssertEqual(thirdTopic.replies?.count, 2, "Unexpected topic items count")
}
if let fourthTopic = topics?[4] as? TalkPageTopic {
XCTAssertEqual(fourthTopic.title, "Topic <a href='./Part' title='Part'>Part</a> Deux")
XCTAssertEqual(fourthTopic.replies?.count, 9, "Unexpected topic items count")
}
if let fifthTopic = topics?[5] as? TalkPageTopic {
XCTAssertEqual(fifthTopic.title, "Topic <a href='./Part' title='Part'>Part</a> Trois")
XCTAssertEqual(fifthTopic.replies?.count, 1, "Unexpected topic items count")
}
// confirm one talk page exists in DB
guard let secondResults = try? tempDataStore.viewContext.fetch(fetchRequest) else {
XCTFail("Failure fetching saved talk pages")
return
}
XCTAssertEqual(secondResults.count, 1, "Expected 1 talk page in DB")
XCTAssertEqual(secondResults.first, dbTalkPage)
}
func testExistingTalkPagePullsFromDB() {
// confirm no talk pages in DB
let fetchRequest: NSFetchRequest<TalkPage> = TalkPage.fetchRequest()
guard let firstResults = try? tempDataStore.viewContext.fetch(fetchRequest) else {
XCTFail("Failure fetching initial talk pages")
return
}
XCTAssertEqual(firstResults.count, 0, "Expected zero existing talk pages at first")
// add network talk page
guard let json = wmf_bundle().wmf_data(fromContentsOfFile: TalkPageTestHelpers.TalkPageJSONType.original.fileName, ofType: "json"),
let talkPage = TalkPageTestHelpers.networkTalkPage(for: urlString1, data: json, revisionId: 1) else {
XCTFail("Failure stubbing out network talk page")
return
}
// create db talk page
guard let dbTalkPage = moc.createTalkPage(with: talkPage) else {
XCTFail("Failure to create db talk page")
return
}
// confirm asking for existing talk page with key pulls same talk page
guard let existingTalkPage = try? moc.talkPage(for: URL(string: urlString1)!) else {
XCTFail("Pull existing talk page fails")
return
}
XCTAssertEqual(existingTalkPage, dbTalkPage, "Unexpected existing talk page value")
// confirm asking for urlString2 pulls nothing
do {
let nonexistantTalkPage = try moc.talkPage(for: URL(string: urlString2)!)
XCTAssertNil(nonexistantTalkPage)
} catch {
XCTFail("Pull existing talk page fails")
}
}
func testUpdateExistingTalkPageUpdatesValues() {
// confirm no talk pages in DB
let fetchRequest: NSFetchRequest<TalkPage> = TalkPage.fetchRequest()
guard let firstResults = try? tempDataStore.viewContext.fetch(fetchRequest) else {
XCTFail("Failure fetching initial talk pages")
return
}
XCTAssertEqual(firstResults.count, 0, "Expected zero existing talk pages at first")
// add network talk page
guard let originalJson = wmf_bundle().wmf_data(fromContentsOfFile: TalkPageTestHelpers.TalkPageJSONType.original.fileName, ofType: "json"),
let talkPage = TalkPageTestHelpers.networkTalkPage(for: urlString1, data: originalJson, revisionId: 1) else {
XCTFail("Failure stubbing out network talk page")
return
}
// create db talk page
guard let dbTalkPage = moc.createTalkPage(with: talkPage) else {
XCTFail("Failure to create db talk page")
return
}
// mark last topic as read to confirm it stays read after updating.
let topics = dbTalkPage.topics?.allObjects.sorted { ($0 as! TalkPageTopic).sort < ($1 as! TalkPageTopic).sort }
if let fifthTopic = topics?[5] as? TalkPageTopic {
fifthTopic.content?.isRead = true
do {
try moc.save()
} catch {
XCTFail("Failure to save isRead flag")
}
}
// get updated talk page payload
guard let updatedJson = wmf_bundle().wmf_data(fromContentsOfFile: TalkPageTestHelpers.TalkPageJSONType.updated.fileName, ofType: "json"),
let updatedTalkPage = TalkPageTestHelpers.networkTalkPage(for: urlString1, data: updatedJson, revisionId: 1) else {
XCTFail("Failure stubbing out network talk page")
return
}
// update local talk page with new talk page
guard let updatedDbTalkPage = moc.updateTalkPage(dbTalkPage, with: updatedTalkPage) else {
XCTFail("Failure updating existing local talk page")
return
}
XCTAssertEqual(updatedDbTalkPage.topics?.count, 3, "Unexpected topic count")
let updatedTopics = updatedDbTalkPage.topics?.allObjects.sorted { ($0 as! TalkPageTopic).sort < ($1 as! TalkPageTopic).sort }
if let introTopic = updatedTopics?[0] as? TalkPageTopic {
XCTAssertEqual(introTopic.title, "", "Unexpected topic title")
XCTAssertEqual(introTopic.replies?.count, 1, "Unexpected replies count")
let replies = introTopic.replies?.allObjects.sorted { ($0 as! TalkPageReply).sort < ($1 as! TalkPageReply).sort }
if let firstReply = replies?[0] as? TalkPageReply {
XCTAssertEqual(firstReply.text, "Hello! This is some introduction text on my talk page. L8erz, <a href='./User:TSevener_(WMF)' title='User:TSevener (WMF)'>TSevener (WMF)</a> (<a href='./User_talk:TSevener_(WMF)' title='User talk:TSevener (WMF)'>talk</a>) 20:48, 21 June 2019 (UTC)", "Unexpected replies html")
} else {
XCTFail("Unexpected first reply type")
}
} else {
XCTFail("Unexpected intro topic type")
}
if let firstTopic = updatedTopics?[1] as? TalkPageTopic {
XCTAssertEqual(firstTopic.title, "Topic <a href='./Part' title='Part'>Part</a> Deux", "Unexpected topic title")
XCTAssertEqual(firstTopic.replies?.count, 11, "Unexpected topic items count")
let replies = firstTopic.replies?.allObjects.sorted { ($0 as! TalkPageReply).sort < ($1 as! TalkPageReply).sort }
if let firstReply = replies?[0] as? TalkPageReply {
XCTAssertEqual(firstReply.text, "Also injecting something in the front because why not. 🤷‍♀️ <a href='./User:TSevener_(WMF)' title='User:TSevener (WMF)'>TSevener (WMF)</a> (<a href='./User_talk:TSevener_(WMF)' title='User talk:TSevener (WMF)'>talk</a>) 21:17, 21 June 2019 (UTC)")
XCTAssertEqual(firstReply.depth, 0, "Unexpected reply depth")
} else {
XCTFail("Unexpected first reply type")
}
if let secondReply = replies?[1] as? TalkPageReply {
XCTAssertEqual(secondReply.text, "Ok try this on for size - can you put a link in a topic title from the iOS app? Only time will tell. <a href='./Special:Contributions/47.184.10.84' title='Special:Contributions/47.184.10.84'>47.184.10.84</a> 20:57, 21 June 2019 (UTC)")
XCTAssertEqual(secondReply.depth, 0, "Unexpected reply depth")
} else {
XCTFail("Unexpected second reply type")
}
if let thirdReply = replies?[2] as? TalkPageReply {
XCTAssertEqual(thirdReply.text, "It certainly seems so. It is good we tested this my friend. <a href='./User:TSevener_(WMF)' title='User:TSevener (WMF)'>TSevener (WMF)</a> (<a href='./User_talk:TSevener_(WMF)' title='User talk:TSevener (WMF)'>talk</a>) 20:58, 21 June 2019 (UTC)")
XCTAssertEqual(thirdReply.depth, 1, "Unexpected reply depth")
} else {
XCTFail("Unexpected third reply type")
}
} else {
XCTFail("Unexpected first topic type")
}
if let secondTopic = updatedTopics?[2] as? TalkPageTopic {
XCTAssertEqual(secondTopic.title, "Topic <a href='./Part' title='Part'>Part</a> Trois")
XCTAssertEqual(secondTopic.replies?.count, 1, "Unexpected topic items count")
XCTAssertTrue(secondTopic.content?.isRead ?? false, "isRead flag flipped back to false after reorder.")
}
// confirm one talk page exists in DB
guard let secondResults = try? tempDataStore.viewContext.fetch(fetchRequest) else {
XCTFail("Failure fetching saved talk pages")
return
}
XCTAssertEqual(secondResults.count, 1, "Expected 1 talk page in DB")
XCTAssertEqual(secondResults.first, dbTalkPage)
}
}