Skip to content

Commit

Permalink
Message model update logic is fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
MikhailGasanov committed Aug 14, 2019
1 parent 3f7daf5 commit 8d3b23c
Show file tree
Hide file tree
Showing 12 changed files with 607 additions and 9 deletions.
36 changes: 36 additions & 0 deletions ChattoAdditions/ChattoAdditions.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@
EA13CAF2229EE8C8009340C5 /* CircleIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA13CAF1229EE8C8009340C5 /* CircleIconView.swift */; };
EA13CAF4229EE985009340C5 /* CircleProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA13CAF3229EE985009340C5 /* CircleProgressView.swift */; };
EA13CAF6229EE9A6009340C5 /* CircleProgressIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA13CAF5229EE9A6009340C5 /* CircleProgressIndicatorView.swift */; };
EA7525502302E94B0069D1AF /* MessageModel+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA75254F2302E94B0069D1AF /* MessageModel+Helpers.swift */; };
EA7525522302FB930069D1AF /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7525512302FB930069D1AF /* TestHelpers.swift */; };
EA7527982302FD790069D1AF /* StubCompoundBubbleViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7527972302FD790069D1AF /* StubCompoundBubbleViewStyle.swift */; };
EA75279A2302FD980069D1AF /* StubMessageCollectionViewCellStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7527992302FD980069D1AF /* StubMessageCollectionViewCellStyle.swift */; };
EA75279C23031FE60069D1AF /* TestableCompoundMessagePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA75279B23031FE60069D1AF /* TestableCompoundMessagePresenter.swift */; };
EAAFBCEB2302BBD3004F553D /* DefaultMessageContentPresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAAFBCEA2302BBD3004F553D /* DefaultMessageContentPresenterTests.swift */; };
EAAFBCED2302D8C8004F553D /* CompoundMessagePresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAAFBCEC2302D8C8004F553D /* CompoundMessagePresenterTests.swift */; };
EAAFBCEF2302DB22004F553D /* FakeViewModelBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAAFBCEE2302DB22004F553D /* FakeViewModelBuilder.swift */; };
EAAFBCF12302DBAF004F553D /* FakeMessageInteractionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAAFBCF02302DBAF004F553D /* FakeMessageInteractionHandler.swift */; };
EAF2678E22BD1524006B3455 /* MessageContentPresenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF2678D22BD1524006B3455 /* MessageContentPresenterProtocol.swift */; };
EAF2679022BD2625006B3455 /* DefaultMessageContentPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF2678F22BD2625006B3455 /* DefaultMessageContentPresenter.swift */; };
F6D04BA71CA46C0200E803FA /* PhotosInputPlaceholderDataProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6D04BA61CA46C0200E803FA /* PhotosInputPlaceholderDataProviderTests.swift */; };
Expand Down Expand Up @@ -245,6 +254,15 @@
EA13CAF1229EE8C8009340C5 /* CircleIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleIconView.swift; sourceTree = "<group>"; };
EA13CAF3229EE985009340C5 /* CircleProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleProgressView.swift; sourceTree = "<group>"; };
EA13CAF5229EE9A6009340C5 /* CircleProgressIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleProgressIndicatorView.swift; sourceTree = "<group>"; };
EA75254F2302E94B0069D1AF /* MessageModel+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageModel+Helpers.swift"; sourceTree = "<group>"; };
EA7525512302FB930069D1AF /* TestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = "<group>"; };
EA7527972302FD790069D1AF /* StubCompoundBubbleViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StubCompoundBubbleViewStyle.swift; sourceTree = "<group>"; };
EA7527992302FD980069D1AF /* StubMessageCollectionViewCellStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StubMessageCollectionViewCellStyle.swift; sourceTree = "<group>"; };
EA75279B23031FE60069D1AF /* TestableCompoundMessagePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableCompoundMessagePresenter.swift; sourceTree = "<group>"; };
EAAFBCEA2302BBD3004F553D /* DefaultMessageContentPresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultMessageContentPresenterTests.swift; sourceTree = "<group>"; };
EAAFBCEC2302D8C8004F553D /* CompoundMessagePresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompoundMessagePresenterTests.swift; sourceTree = "<group>"; };
EAAFBCEE2302DB22004F553D /* FakeViewModelBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeViewModelBuilder.swift; sourceTree = "<group>"; };
EAAFBCF02302DBAF004F553D /* FakeMessageInteractionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeMessageInteractionHandler.swift; sourceTree = "<group>"; };
EAF2678D22BD1524006B3455 /* MessageContentPresenterProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageContentPresenterProtocol.swift; sourceTree = "<group>"; };
EAF2678F22BD2625006B3455 /* DefaultMessageContentPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultMessageContentPresenter.swift; sourceTree = "<group>"; };
F6D04BA61CA46C0200E803FA /* PhotosInputPlaceholderDataProviderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotosInputPlaceholderDataProviderTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -581,6 +599,15 @@
isa = PBXGroup;
children = (
C3EFA6AF1C03607A0063CE22 /* BaseMessagePresenterTests.swift */,
EAAFBCEC2302D8C8004F553D /* CompoundMessagePresenterTests.swift */,
EAAFBCEA2302BBD3004F553D /* DefaultMessageContentPresenterTests.swift */,
EAAFBCF02302DBAF004F553D /* FakeMessageInteractionHandler.swift */,
EAAFBCEE2302DB22004F553D /* FakeViewModelBuilder.swift */,
EA75254F2302E94B0069D1AF /* MessageModel+Helpers.swift */,
EA7527972302FD790069D1AF /* StubCompoundBubbleViewStyle.swift */,
EA7527992302FD980069D1AF /* StubMessageCollectionViewCellStyle.swift */,
EA75279B23031FE60069D1AF /* TestableCompoundMessagePresenter.swift */,
EA7525512302FB930069D1AF /* TestHelpers.swift */,
);
path = BaseMessage;
sourceTree = "<group>";
Expand Down Expand Up @@ -846,15 +873,24 @@
files = (
C3C0CC861BFE49700052747C /* ChatInputItemTests.swift in Sources */,
CDC6100B1FD8268200C2588E /* FakePhotosInputDataProvider.swift in Sources */,
EAAFBCEB2302BBD3004F553D /* DefaultMessageContentPresenterTests.swift in Sources */,
EAAFBCEF2302DB22004F553D /* FakeViewModelBuilder.swift in Sources */,
EA75279A2302FD980069D1AF /* StubMessageCollectionViewCellStyle.swift in Sources */,
55ABA5771FC74F8D00923302 /* ObservableTests.swift in Sources */,
EA7527982302FD790069D1AF /* StubCompoundBubbleViewStyle.swift in Sources */,
C3C0CC881BFE49700052747C /* ChatInputPresenterTests.swift in Sources */,
C3815D001C036B3000DF95CA /* PhotoMessagePresenterBuilderTests.swift in Sources */,
C363C33F1D2405F800599FF5 /* LiveCameraCellPresenterTests.swift in Sources */,
F6D04BA91CA46D5000E803FA /* PhotosInputWithPlaceholdersDataProviderTests.swift in Sources */,
EA75279C23031FE60069D1AF /* TestableCompoundMessagePresenter.swift in Sources */,
EA7525522302FB930069D1AF /* TestHelpers.swift in Sources */,
C35FE3C51C0331CF00D42980 /* TextMessagePresenterTests.swift in Sources */,
55ABA5731FC74E0400923302 /* UIEdgeInets+AdditionsTests.swift in Sources */,
C3C0CC8A1BFE49700052747C /* PhotosChatInputItemTests.swift in Sources */,
EA7525502302E94B0069D1AF /* MessageModel+Helpers.swift in Sources */,
EAAFBCED2302D8C8004F553D /* CompoundMessagePresenterTests.swift in Sources */,
55ABA5691FC7498700923302 /* CGRect+AdditionsTests.swift in Sources */,
EAAFBCF12302DBAF004F553D /* FakeMessageInteractionHandler.swift in Sources */,
C3C0CC8B1BFE49700052747C /* PhotosInputViewItemSizeCalculatorTests.swift in Sources */,
CDE15F43205993FB005D86DD /* PhotosInputCameraPickerTests.swift in Sources */,
F6D04BA71CA46C0200E803FA /* PhotosInputPlaceholderDataProviderTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,23 +86,23 @@ open class CompoundMessagePresenter<ViewModelBuilderT, InteractionHandlerT>
return
}

let isUpdateNeeded = !self.messageModel.hasSameContent(as: newMessageModel)
let isContentChanged = !self.messageModel.hasSameContent(as: newMessageModel)
let isMessageUidChanged = self.messageModel.uid != newMessageModel.uid

self.messageModel = newMessageModel

guard !isUpdateNeeded else {
guard !isContentChanged else {
self.updateContent()
return
}

let isUidUpdateNeeded = self.messageModel.uid != newMessageModel.uid

guard !isUidUpdateNeeded else {
self.updateContentPresenters(with: newMessageModel.uid)
guard !isMessageUidChanged else {
self.updateExistingContentPresenters(with: newMessageModel)
return
}
}

private func updateContent() {
open func updateContent() {
self.contentFactories = self.initialContentFactories.filter { $0.canCreateMessageContent(forModel: self.messageModel) }

self.contentPresenters = self.contentFactories.compactMap {
Expand All @@ -114,7 +114,7 @@ open class CompoundMessagePresenter<ViewModelBuilderT, InteractionHandlerT>
self.menuPresenter = self.contentFactories.lazy.compactMap { $0.createMenuPresenter(forModel: self.messageModel) }.first
}

private func updateContentPresenters(with newMessage: Any) {
open func updateExistingContentPresenters(with newMessage: Any) {
self.contentPresenters.forEach {
$0.updateMessage(newMessage)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ public final class DefaultMessageContentPresenter<MessageType, ViewType: UIView>
public typealias ActionHandler = (_ message: MessageType, _ view: ViewType?) -> Void
public typealias BindingClosure = (_ message: MessageType, _ view: ViewType?) -> Void
public typealias UnbindingClosure = (_ view: ViewType?) -> Void
public typealias MessageUpdateClosure = (_ newMessage: MessageType) -> Void

public init(message: MessageType,
showBorder: Bool,
onBinding: BindingClosure?,
onUnbinding: UnbindingClosure? = nil,
onContentWillBeShown: ActionHandler? = nil,
onContentWasHidden: ActionHandler? = nil,
onContentWasTapped_deprecated: ActionHandler? = nil) {
onContentWasTapped_deprecated: ActionHandler? = nil,
onMessageUpdate: MessageUpdateClosure? = nil) {
self.message = message

self.onBinding = onBinding
Expand All @@ -45,6 +47,8 @@ public final class DefaultMessageContentPresenter<MessageType, ViewType: UIView>
self.onContentWillBeShown = onContentWillBeShown
self.onContentWasHidden = onContentWasHidden
self.onContentWasTapped_deprecated = onContentWasTapped_deprecated

self.onMessageUpdate = onMessageUpdate
}

private var message: MessageType
Expand All @@ -58,6 +62,8 @@ public final class DefaultMessageContentPresenter<MessageType, ViewType: UIView>
private let onContentWasHidden: ActionHandler?
private let onContentWasTapped_deprecated: ActionHandler?

private let onMessageUpdate: MessageUpdateClosure?

// MARK: - MessageContentPresenterProtocol

public weak var delegate: MessageContentPresenterDelegate?
Expand All @@ -83,5 +89,6 @@ public final class DefaultMessageContentPresenter<MessageType, ViewType: UIView>
return
}
self.message = message
self.onMessageUpdate?(self.message)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2015-present Badoo Trading Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

@testable import ChattoAdditions
import XCTest

@available(iOS 11, *)
final class CompoundMessagePresenterTests: XCTestCase {

func test_WhenPresenterIsUpdatedWithTheSameMessage_ThenUpdateContentNotCalled_AndUpdateExistingContentPresentersNotCalled() {
let message = TestHelpers.makeMessage(withId: "123")
let sameMessage = message
let presenter = TestHelpers.makeTestableCompoundMessagePresenter(with: message)

presenter.update(with: sameMessage)

XCTAssertEqual(0, presenter.invokedUpdateContentCount)
XCTAssertEqual(0, presenter.invokedUpdateExistingContentPresentersCount)
}

func test_WhenPresenterIsUpdatedWithMessageWithAnotherContent_ThenUpdateContentCalled_ButUpdateExistingContentPresentersNotCalled() {
let date = Date()
let anotherDate = date.addingTimeInterval(1)
let message = TestHelpers.makeMessage(withId: "123", date: date)
let sameMessageWithAnotherId = TestHelpers.makeMessage(withId: "123", date: anotherDate)
let presenter = TestHelpers.makeTestableCompoundMessagePresenter(with: message)

presenter.update(with: sameMessageWithAnotherId)

XCTAssertEqual(1, presenter.invokedUpdateContentCount)
XCTAssertEqual(0, presenter.invokedUpdateExistingContentPresentersCount)
}

func test_WhenPresenterIsUpdatedWithSameMessageWithAnotherId_ThenUpdateContentNotCalled_ButUpdateExistingContentPresentersCalled() {
let message = TestHelpers.makeMessage(withId: "123")
let sameMessageWithAnotherId = message.makeSameMessage(butAnotherId: "456")
let presenter = TestHelpers.makeTestableCompoundMessagePresenter(with: message)

presenter.update(with: sameMessageWithAnotherId)

XCTAssertEqual(0, presenter.invokedUpdateContentCount)
XCTAssertEqual(1, presenter.invokedUpdateExistingContentPresentersCount)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// The MIT License (MIT)
//
// Copyright (c) 2015-present Badoo Trading Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

@testable import ChattoAdditions
import XCTest

final class DefaultMessageContentPresenterTests: XCTestCase {

func test_WhenPresenterIsUpdatedWithTheSameMessageWithAnotherId_ThenOnMessageUpdateClosureIsCalled_AndItIsCalledWithUpdatedMessage() {
let message = TestHelpers.makeMessage(withId: "123")
let sameMessageWithAnotherId = message.makeSameMessage(butAnotherId: "456")
var isOnMessageUpdateCallsCount = 0
var newMessageOnUpdate: MessageModel!
let presenter = TestHelpers.makeDefaultMessageContentPresenter(with: message, onMessageUpdate: { newMessage in
isOnMessageUpdateCallsCount += 1
newMessageOnUpdate = newMessage
})

presenter.updateMessage(sameMessageWithAnotherId)

XCTAssertEqual(1, isOnMessageUpdateCallsCount)
XCTAssertEqual(sameMessageWithAnotherId.uid, newMessageOnUpdate!.uid)
}
}
Loading

0 comments on commit 8d3b23c

Please sign in to comment.