Javier Cicchelli 9bcdaa697b [Setup] Basic project structure (#1)
This PR contains all the work related to setting up this project as required to implement the [Assignment](https://repo.rock-n-code.com/rock-n-code/deep-linking-assignment/wiki/Assignment) on top, as intended.

To summarise this work:
- [x] created a new **Xcode** project;
- [x] cloned the `Wikipedia` app and inserted it into the **Xcode** project;
- [x] created the `Locations` app and also, its `Libraries` package;
- [x] created the `Shared` package to share dependencies between the apps;
- [x] added a `Makefile` file and implemented some **environment** and **help** commands.

Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Reviewed-on: rock-n-code/deep-linking-assignment#1
2023-04-08 18:37:13 +00:00

170 lines
6.9 KiB
Swift

import XCTest
class ReadingListsTests: XCTestCase {
var dataStore: MWKDataStore!
override func setUp() {
super.setUp()
dataStore = MWKDataStore.temporary()
}
override func tearDown() {
super.tearDown()
dataStore.removeFolderAtBasePath()
}
func testListsWithTheSameName() {
let originalName = "pebbles"
let casedName = "pEbBLes"
let diacriticName = "pEbBLés"
do {
let list = try dataStore.readingListsController.createReadingList(named: originalName, description: "Foo")
XCTAssert(list.name == originalName)
} catch let error {
XCTAssert(false, "Should be able to create \(originalName) reading list: \(error)")
}
do {
_ = try dataStore.readingListsController.createReadingList(named: casedName, description: "Foo")
XCTAssert(true, "Should be able to create list with same title and different case")
} catch let error {
XCTAssert(false, "Should not throw an error: \(error) when creating a list with the same title and different case")
}
do {
let list = try dataStore.readingListsController.createReadingList(named: diacriticName, description: "Foo")
XCTAssert(list.name == diacriticName)
} catch let error {
XCTAssert(false, "Should be able to create \(diacriticName) reading list: \(error)")
}
}
func testDeletingExistingReadingLists() {
let readingListNames = ["foo", "bar"]
var readingLists: [ReadingList] = []
do {
readingLists.append(try dataStore.readingListsController.createReadingList(named: readingListNames[0], description: "Foo"))
} catch let error {
XCTAssert(false, "Should be able to create \(readingListNames[0]) reading list: \(error)")
}
do {
readingLists.append(try dataStore.readingListsController.createReadingList(named: readingListNames[1], description: "Foo"))
} catch let error {
XCTAssert(false, "Should be able to create \(readingListNames[1]) reading list: \(error)")
}
do {
try dataStore.readingListsController.delete(readingLists: readingLists)
} catch let error {
XCTAssert(false, "Should be able to delete \(readingListNames) reading lists: \(error)")
}
}
func testDeletingNonexistentReadingLists() {
let readingListNames = ["foo", "bar"]
var readingLists: [ReadingList] = []
do {
readingLists.append(try dataStore.readingListsController.createReadingList(named: readingListNames[0], description: "Foo"))
} catch let error {
XCTAssert(false, "Should be able to create \(readingListNames[0]) reading list: \(error)")
}
do {
try dataStore.readingListsController.delete(readingLists: readingLists)
} catch let error {
XCTAssert(false, "Should attempt to delete \(readingListNames) reading lists: \(error)")
}
}
func testCreatingReadingListWithArticles() {
let readingListName = "foo"
let articleURLs = [URL(string: "//en.wikipedia.org/wiki/Foo")!, URL(string: "//en.wikipedia.org/wiki/Bar")!]
let articles = articleURLs.compactMap { (articleURL) -> WMFArticle? in
return dataStore.fetchOrCreateArticle(with: articleURL)
}
let articleKeys = articles.compactMap { (article) -> String? in
return article.key
}
do {
let readingList = try dataStore.readingListsController.createReadingList(named: readingListName, description: "Foo", with: articles)
XCTAssert(readingList.articleKeys.wmf_containsObjectsInAnyOrderAndMatchesCount(articleKeys))
} catch let error {
XCTAssert(false, "Should be able to add articles to \(readingListName) reading list: \(error)")
}
}
func testAddingArticlesToExistingReadingList() {
let readingListName = "foo"
let articleURLs = [URL(string: "//en.wikipedia.org/wiki/Foo")!, URL(string: "//en.wikipedia.org/wiki/Bar")!]
let otherArticleURLs = [URL(string: "//en.wikipedia.org/wiki/Foo")!, URL(string: "//en.wikipedia.org/wiki/Bar")!, URL(string: "//en.wikipedia.org/wiki/Baz")!]
let articles = articleURLs.compactMap { (articleURL) -> WMFArticle? in
return dataStore.fetchOrCreateArticle(with: articleURL)
}
let otherArticles = otherArticleURLs.compactMap { (articleURL) -> WMFArticle? in
return dataStore.fetchOrCreateArticle(with: articleURL)
}
let otherArticleKeys = otherArticles.compactMap { (article) -> String? in
return article.key
}
do {
let readingList = try dataStore.readingListsController.createReadingList(named: readingListName, description: "Foo", with: articles)
do {
try dataStore.readingListsController.add(articles: otherArticles, to: readingList)
XCTAssert(readingList.articleKeys.wmf_containsObjectsInAnyOrderAndMatchesCount(otherArticleKeys))
} catch let error {
XCTAssert(false, "Should be able to : \(error)")
}
} catch let error {
XCTAssert(false, "Should be able to add articles to \(readingListName) reading list: \(error)")
}
}
func testAddingDuplicateArticlesToExistingReadingList() {
let readingListName = "foo"
let articleURLs = [URL(string: "//en.wikipedia.org/wiki/Foo")!, URL(string: "//en.wikipedia.org/wiki/Foo")!]
let articles = articleURLs.compactMap { (articleURL) -> WMFArticle? in
return dataStore.fetchOrCreateArticle(with: articleURL)
}
let articleKeys = articles.compactMap { (article) -> String? in
return article.key
}
do {
let readingList = try dataStore.readingListsController.createReadingList(named: readingListName, description: "Foo", with: articles)
let existingArticleKeys = readingList.articleKeys
XCTAssert(existingArticleKeys.wmf_containsObjectsInAnyOrder(articleKeys) && existingArticleKeys.count == 1)
} catch let error {
XCTAssert(false, "Should be able to add articles to \(readingListName) reading list: \(error)")
}
}
}
extension Array where Element: Hashable {
func wmf_containsObjectsInAnyOrderAndMatchesCount(_ other: [Element]) -> Bool {
return wmf_containsObjectsInAnyOrder(other) && self.count == other.count
}
func wmf_containsObjectsInAnyOrder(_ other: [Element]) -> Bool {
let selfSet = Set(self)
let otherSet = Set(other)
return otherSet.isSubset(of: selfSet)
}
}