Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(coredata): make Item optional on SavedItem #690

Merged
merged 3 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,27 @@ class SavedItemViewModel: ReadableViewModel {
}

var components: [ArticleComponent]? {
item.item.article?.components
item.item?.article?.components
}

var textAlignment: Textile.TextAlignment {
item.textAlignment
}

var title: String? {
item.item.title
item.item?.title
}

var authors: [ReadableAuthor]? {
item.item.authors?.compactMap { $0 as? Author }
item.item?.authors?.compactMap { $0 as? Author }
}

var domain: String? {
item.item.domainMetadata?.name ?? item.item.domain ?? item.host
item.item?.domainMetadata?.name ?? item.item?.domain ?? item.host
}

var publishDate: Date? {
item.item.datePublished
item.item?.datePublished
}

var url: URL? {
Expand All @@ -117,7 +117,7 @@ class SavedItemViewModel: ReadableViewModel {
}

func fetchDetailsIfNeeded() {
guard item.item.article == nil else {
guard item.item?.article == nil else {
_events.send(.contentUpdated)
return
}
Expand Down
2 changes: 1 addition & 1 deletion PocketKit/Sources/PocketKit/Home/HomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ extension HomeViewModel {
notificationCenter: notificationCenter
)

if savedItem.item.shouldOpenInWebView {
if let item = savedItem.item, item.shouldOpenInWebView {
selectedReadableType = .webViewSavedItem(viewModel)
} else {
selectedReadableType = .savedItem(viewModel)
Expand Down
8 changes: 4 additions & 4 deletions PocketKit/Sources/PocketKit/Item/Item+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ import Sync

public extension SavedItem {
var textAlignment: TextAlignment {
TextAlignment(language: item.language)
TextAlignment(language: item?.language)
}

var bestURL: URL? {
item.bestURL ?? url
item?.bestURL ?? url
}

var isPending: Bool {
item == nil
}

var shouldOpenInWebView: Bool {
item.shouldOpenInWebView == true
item?.shouldOpenInWebView == true
}

var isSyndicated: Bool {
item.isSyndicated == true
item?.isSyndicated == true
}
}

Expand Down
2 changes: 1 addition & 1 deletion PocketKit/Sources/PocketKit/Listen/ListenViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ListenViewModel: PKTListenDataSource<PKTListDiffable> {
return false
}

return savedItem.item.isArticle
return savedItem.item?.isArticle ?? false
}).compactMap({item in
let v = PKTListenKusariCreate(item.albumID!, PKTListenQueueSectionType.item.rawValue, item, config)
return v
Expand Down
6 changes: 3 additions & 3 deletions PocketKit/Sources/PocketKit/Listen/SavedItem+Listen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ extension SavedItem: PKTListenItem {
}

public var albumLanguage: String? {
self.item.language
self.item?.language
}

public var estimatedAlbumDuration: TimeInterval {
if let wordCount = item.wordCount?.intValue, wordCount > 0 {
if let wordCount = item?.wordCount?.intValue, wordCount > 0 {
let wordsPerMinute = 155
return Double(wordCount/wordsPerMinute * 60).rounded()
}

if let timeToRead = item.timeToRead?.intValue, timeToRead > 0 {
if let timeToRead = item?.timeToRead?.intValue, timeToRead > 0 {
return Double(timeToRead * 60)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ extension SavedItem: ItemsListItem {
}

var domain: String? {
item.domain
item?.domain
}

var topImageURL: URL? {
item.topImageURL
item?.topImageURL
}

var timeToRead: Int? {
item.timeToRead?.intValue
item?.timeToRead?.intValue
}

var displayTitle: String {
item.title ?? item.bestURL.absoluteString
item?.title ?? item?.bestURL.absoluteString ?? url.absoluteString
}

var displayDomain: String? {
item.domainMetadata?.name ?? item.domain ?? host
item?.domainMetadata?.name ?? item?.domain ?? host
}

var displayDetail: String {
Expand All @@ -40,7 +40,7 @@ extension SavedItem: ItemsListItem {
}

var displayAuthors: String? {
let authors: [String]? = item.authors?.compactMap { ($0 as? Author)?.name }
let authors: [String]? = item?.authors?.compactMap { ($0 as? Author)?.name }
return authors?.joined(separator: ", ")
}

Expand All @@ -53,7 +53,7 @@ extension SavedItem: ItemsListItem {
}

var cursor: String? {
item.savedItem?.cursor
item?.savedItem?.cursor
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ extension SavedItemsListViewModel {

switch listOptions.selectedSortOption {
case .longestToRead, .shortestToRead:
sortDescriptorTemp = NSSortDescriptor(keyPath: \SavedItem.item.timeToRead, ascending: (listOptions.selectedSortOption == .shortestToRead))
sortDescriptorTemp = NSSortDescriptor(keyPath: \SavedItem.item?.timeToRead, ascending: (listOptions.selectedSortOption == .shortestToRead))
case .newest, .oldest:

switch self.viewType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension SavedItem {
@NSManaged public var isFavorite: Bool
@NSManaged public var remoteID: String?
@NSManaged public var url: URL
@NSManaged public var item: Item
@NSManaged public var item: Item?
@NSManaged public var savedItemUpdatedNotification: SavedItemUpdatedNotification?
@NSManaged public var tags: NSOrderedSet?
@NSManaged public var unresolvedSavedItem: UnresolvedSavedItem?
Expand Down
12 changes: 6 additions & 6 deletions PocketKit/Sources/Sync/CoreDataSpotlightDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ class CoreDataSpotlightDelegate: NSCoreDataCoreSpotlightDelegate {
let identifier = savedItem.remoteID
let attributeSet = CSSearchableItemAttributeSet(contentType: .content)
attributeSet.identifier = identifier
attributeSet.displayName = savedItem.item.title
attributeSet.publishers = (savedItem.item.authors?.array as? [Author] ?? []).compactMap { $0.name }
attributeSet.thumbnailURL = savedItem.item.topImageURL // TODO: Image cache url..
attributeSet.displayName = savedItem.item?.title
attributeSet.publishers = (savedItem.item?.authors?.array as? [Author] ?? []).compactMap { $0.name }
attributeSet.thumbnailURL = savedItem.item?.topImageURL // TODO: Image cache url..
attributeSet.contentURL = savedItem.url
attributeSet.contentDescription = savedItem.item.excerpt
attributeSet.title = savedItem.item.title
attributeSet.contentCreationDate = savedItem.item.datePublished
attributeSet.contentDescription = savedItem.item?.excerpt
attributeSet.title = savedItem.item?.title
attributeSet.contentCreationDate = savedItem.item?.datePublished

return attributeSet
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22E261" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21754" systemVersion="22E252" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Author" representedClassName="Author" syncable="YES">
<attribute name="id" attributeType="String"/>
<attribute name="name" optional="YES" attributeType="String"/>
Expand Down
2 changes: 1 addition & 1 deletion PocketKit/Sources/Sync/PocketSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ extension PocketSource {

space.delete(savedItem)

if item.recommendation == nil {
if let item = item, item.recommendation == nil {
space.delete(item)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class SavedItemViewModelTests: XCTestCase {
source.stubFetchDetails { _ in }

let savedItem = space.buildSavedItem()
savedItem.item.article = nil
savedItem.item?.article = nil
try space.save()

let viewModel = subject(item: savedItem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class SlateDetailViewModelTests: XCTestCase {

func test_selectCell_whenSelectingRecommendation_recommendationIsReadable_updatesSelectedReadable() throws {
let savedItem = try space.createSavedItem(item: space.buildItem())
let recommendation = space.buildRecommendation(item: savedItem.item)
let recommendation = space.buildRecommendation(item: savedItem.item!)
let slate = try space.createSlate(recommendations: [recommendation])
try space.save()
let viewModel = subject(slate: space.viewObject(with: slate.objectID) as! Slate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class SaveItemOperationTests: XCTestCase {
XCTAssertEqual(performCall?.mutation.input.url, url.absoluteString)

let item = try space.fetchSavedItem(byURL: url)
XCTAssertEqual(savedItem.item.resolvedURL, URL(string: "https://resolved.example.com/item-1")!)
XCTAssertEqual(savedItem.item?.resolvedURL, URL(string: "https://resolved.example.com/item-1")!)
XCTAssertNotNil(item)
}

Expand Down
10 changes: 5 additions & 5 deletions PocketKit/Tests/SyncTests/PocketSourceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class PocketSourceTests: XCTestCase {
}

let savedItem = try space.createSavedItem(item: space.buildItem())
let item = savedItem.item
let item = savedItem.item!
item.recommendation = space.buildRecommendation(item: item)

let remoteItemURL = item.givenURL
Expand All @@ -207,7 +207,7 @@ class PocketSourceTests: XCTestCase {
}

let savedItem = try space.createSavedItem(item: space.buildItem())
let item = savedItem.item
let item = savedItem.item!

let remoteItemURL = item.givenURL

Expand Down Expand Up @@ -354,7 +354,7 @@ class PocketSourceTests: XCTestCase {

let savedItem = savedItems[0]
XCTAssertEqual(savedItem.objectID, seededSavedItem.objectID)
XCTAssertEqual(savedItem.item.objectID, seededItem.objectID)
XCTAssertEqual(savedItem.item?.objectID, seededItem.objectID)
XCTAssertFalse(savedItem.isArchived)
}

Expand Down Expand Up @@ -701,8 +701,8 @@ extension PocketSourceTests {
let savedItem = source.fetchOrCreateSavedItem(with: URL(string: "http://localhost:8080/hello")!, and: itemParts)

XCTAssertEqual(savedItem?.remoteID, "saved-item")
XCTAssertEqual(savedItem?.item.title, "item-title")
XCTAssertEqual(savedItem?.item.bestURL.absoluteString, "http://localhost:8080/hello")
XCTAssertEqual(savedItem?.item?.title, "item-title")
XCTAssertEqual(savedItem?.item?.bestURL.absoluteString, "http://localhost:8080/hello")
}

private func setupLocalSavesSearch(with urlString: String? = nil) throws {
Expand Down
32 changes: 16 additions & 16 deletions PocketKit/Tests/SyncTests/Support/FetchSavesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,33 +104,33 @@ class FetchSavesTests: XCTestCase {
XCTAssertEqual(tags?[0].name, "tag-1")

let item = savedItem.item
XCTAssertEqual(item.remoteID, "item-1")
XCTAssertEqual(item.givenURL, URL(string: "https://given.example.com/item-1")!)
XCTAssertEqual(item.resolvedURL, URL(string: "https://resolved.example.com/item-1")!)
XCTAssertEqual(item.title, "Item 1")
XCTAssertEqual(item.topImageURL, URL(string: "https://example.com/item-1/top-image.jpg")!)
XCTAssertEqual(item.domain, "example.com")
XCTAssertEqual(item.language, "en")
XCTAssertEqual(item.timeToRead, 6)
XCTAssertEqual(item.excerpt, "Cursus Aenean Elit")
XCTAssertEqual(item.datePublished, Date(timeIntervalSinceReferenceDate: 631195261))
XCTAssertEqual(item?.remoteID, "item-1")
XCTAssertEqual(item?.givenURL, URL(string: "https://given.example.com/item-1")!)
XCTAssertEqual(item?.resolvedURL, URL(string: "https://resolved.example.com/item-1")!)
XCTAssertEqual(item?.title, "Item 1")
XCTAssertEqual(item?.topImageURL, URL(string: "https://example.com/item-1/top-image.jpg")!)
XCTAssertEqual(item?.domain, "example.com")
XCTAssertEqual(item?.language, "en")
XCTAssertEqual(item?.timeToRead, 6)
XCTAssertEqual(item?.excerpt, "Cursus Aenean Elit")
XCTAssertEqual(item?.datePublished, Date(timeIntervalSinceReferenceDate: 631195261))

let expected: [ArticleComponent] = Fixture.load(name: "marticle").decode()
XCTAssertEqual(item.article?.components, expected)
XCTAssertEqual(item?.article?.components, expected)

let authors = item.authors?.compactMap { $0 as? Author }
let authors = item?.authors?.compactMap { $0 as? Author }
XCTAssertEqual(authors?[0].id, "author-1")
XCTAssertEqual(authors?[0].name, "Eleanor")
XCTAssertEqual(authors?[0].url, URL(string: "https://example.com/authors/eleanor")!)

let domain = item.domainMetadata
let domain = item?.domainMetadata
XCTAssertEqual(domain?.name, "WIRED")
XCTAssertEqual(domain?.logo, URL(string: "http://example.com/item-1/domain-logo.jpg")!)

let images = item.images?.compactMap { $0 as? Image } ?? []
let images = item?.images?.compactMap { $0 as? Image } ?? []
XCTAssertEqual(images[0].source, URL(string: "http://example.com/item-1/image-1.jpg"))

XCTAssertEqual(item.syndicatedArticle?.itemID, "syndicated-article-item-id")
XCTAssertEqual(item?.syndicatedArticle?.itemID, "syndicated-article-item-id")
}

func test_refresh_whenFetchSucceeds_andResultContainsDuplicateItems_createsSingleItem() async throws {
Expand All @@ -157,7 +157,7 @@ class FetchSavesTests: XCTestCase {
_ = await service.execute(syncTaskId: task.objectID)

let item = try space.fetchSavedItem(byURL: URL(string: "http://example.com/item-1")!)
XCTAssertEqual(item?.item.title, "Updated Item 1")
XCTAssertEqual(item?.item?.title, "Updated Item 1")
}

func test_refresh_whenFetchFails_sendsErrorOverGivenSubject() async throws {
Expand Down