This commit is contained in:
Родитель
cd4b4ff451
Коммит
0d394c2a27
|
@ -1,2 +1,4 @@
|
||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
cp -R EmbeddedSocial\ Swift\ File.xctemplate ~/Library/Developer/Xcode/Templates/Custom/
|
destination=$HOME"/Library/Developer/Xcode/Templates/Custom/"
|
||||||
|
mkdir -p $destination
|
||||||
|
cp -R EmbeddedSocial\ Swift\ File.xctemplate $destination
|
||||||
|
|
|
@ -786,6 +786,7 @@
|
||||||
EB45E0D87E3DCF49B5A22162 /* CommentRepliesInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC43B539B5A91FF6D4EAB9B /* CommentRepliesInitializer.swift */; };
|
EB45E0D87E3DCF49B5A22162 /* CommentRepliesInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC43B539B5A91FF6D4EAB9B /* CommentRepliesInitializer.swift */; };
|
||||||
EC75A126A73CC5F294926613 /* CommentRepliesConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C6D69159F11B9D4D3F7000 /* CommentRepliesConfigurator.swift */; };
|
EC75A126A73CC5F294926613 /* CommentRepliesConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74C6D69159F11B9D4D3F7000 /* CommentRepliesConfigurator.swift */; };
|
||||||
ED9BC53643CA7A3E7A3106DC /* CommentCellConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F824A8069868818F477BD /* CommentCellConfigurator.swift */; };
|
ED9BC53643CA7A3E7A3106DC /* CommentCellConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1F824A8069868818F477BD /* CommentCellConfigurator.swift */; };
|
||||||
|
F8ED92AE1F72DF3E0026AC3E /* ActivityPresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8ED92AD1F72DF3E0026AC3E /* ActivityPresenterTests.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -1631,6 +1632,7 @@
|
||||||
E63643937A3B405C1B4E0B49 /* CommentCellInteractorInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CommentCellInteractorInput.swift; sourceTree = "<group>"; };
|
E63643937A3B405C1B4E0B49 /* CommentCellInteractorInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CommentCellInteractorInput.swift; sourceTree = "<group>"; };
|
||||||
EC1ECDB428A92745248FE72C /* CommentCellRouterInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CommentCellRouterInput.swift; sourceTree = "<group>"; };
|
EC1ECDB428A92745248FE72C /* CommentCellRouterInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CommentCellRouterInput.swift; sourceTree = "<group>"; };
|
||||||
F35AC4A39014F4C18D39AA62 /* ActivityRouter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ActivityRouter.swift; sourceTree = "<group>"; };
|
F35AC4A39014F4C18D39AA62 /* ActivityRouter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ActivityRouter.swift; sourceTree = "<group>"; };
|
||||||
|
F8ED92AD1F72DF3E0026AC3E /* ActivityPresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityPresenterTests.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -4338,6 +4340,7 @@
|
||||||
children = (
|
children = (
|
||||||
9CEE0EDD1F6FE3F7008B1104 /* ActivityInteractorTests.swift */,
|
9CEE0EDD1F6FE3F7008B1104 /* ActivityInteractorTests.swift */,
|
||||||
9CCE405C1F72827A003A51D9 /* ActivityTests.swift */,
|
9CCE405C1F72827A003A51D9 /* ActivityTests.swift */,
|
||||||
|
F8ED92AD1F72DF3E0026AC3E /* ActivityPresenterTests.swift */,
|
||||||
);
|
);
|
||||||
path = Activity;
|
path = Activity;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -5765,6 +5768,7 @@
|
||||||
881F7E621F263888003EB37A /* MockKeyValueStorage.swift in Sources */,
|
881F7E621F263888003EB37A /* MockKeyValueStorage.swift in Sources */,
|
||||||
88B94ED11F62C3FA002392F9 /* MockSearchTopicsInteractor.swift in Sources */,
|
88B94ED11F62C3FA002392F9 /* MockSearchTopicsInteractor.swift in Sources */,
|
||||||
9C985E531F505BDF00514F85 /* FeedCacheTests.swift in Sources */,
|
9C985E531F505BDF00514F85 /* FeedCacheTests.swift in Sources */,
|
||||||
|
F8ED92AE1F72DF3E0026AC3E /* ActivityPresenterTests.swift in Sources */,
|
||||||
884C9C341F4C3E940004907F /* UserListPresenterTests.swift in Sources */,
|
884C9C341F4C3E940004907F /* UserListPresenterTests.swift in Sources */,
|
||||||
932898D41F65929F001F3BC2 /* ReportReplyAPITests.swift in Sources */,
|
932898D41F65929F001F3BC2 /* ReportReplyAPITests.swift in Sources */,
|
||||||
9C30243C1F55AB2100675FE9 /* FeedModuleRouterMock.swift in Sources */,
|
9C30243C1F55AB2100675FE9 /* FeedModuleRouterMock.swift in Sources */,
|
||||||
|
|
|
@ -8,19 +8,23 @@ import Foundation
|
||||||
protocol SectionModelType {
|
protocol SectionModelType {
|
||||||
associatedtype Item
|
associatedtype Item
|
||||||
|
|
||||||
var items: [Item] { get }
|
var items: [Item] { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SectionModel<Section, ItemType>: SectionModelType {
|
struct SectionModel<Section, ItemType>: SectionModelType {
|
||||||
typealias Item = ItemType
|
typealias Item = ItemType
|
||||||
|
|
||||||
let model: Section
|
var model: Section
|
||||||
let items: [Item]
|
var items: [Item]
|
||||||
|
|
||||||
init(model: Section, items: [Item]) {
|
init(model: Section, items: [Item]) {
|
||||||
self.model = model
|
self.model = model
|
||||||
self.items = items
|
self.items = items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutating func erase() {
|
||||||
|
items = []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SectionModel: CustomStringConvertible {
|
extension SectionModel: CustomStringConvertible {
|
||||||
|
|
|
@ -91,6 +91,12 @@ struct PendingRequestItem {
|
||||||
var userHandle: String
|
var userHandle: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension PendingRequestItem {
|
||||||
|
static func mock(seed: Int) -> PendingRequestItem {
|
||||||
|
return PendingRequestItem(userName: "username \(seed)", userHandle: "handle \(seed)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
enum Change<T> {
|
enum Change<T> {
|
||||||
|
@ -166,7 +172,7 @@ class ActivityViewModelBuilder {
|
||||||
|
|
||||||
class SectionsConfigurator {
|
class SectionsConfigurator {
|
||||||
|
|
||||||
func build(section: ActivityPresenter.State) -> [ActivityPresenter.Section] {
|
func build(section: ActivityPresenter.State) -> [Section] {
|
||||||
|
|
||||||
switch section {
|
switch section {
|
||||||
case .my:
|
case .my:
|
||||||
|
@ -174,21 +180,22 @@ class SectionsConfigurator {
|
||||||
case .others:
|
case .others:
|
||||||
return others
|
return others
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var my: [ActivityPresenter.Section] {
|
private var my: [Section] {
|
||||||
let sectionHeader = SectionHeader(name: "Section 1", identifier: "")
|
let sectionHeader = SectionHeader(name: "Section 1", identifier: "")
|
||||||
let model = PendingRequestItem(userName: "User", userHandle: "User handle")
|
let model = PendingRequestItem(userName: "User", userHandle: "User handle")
|
||||||
let item = ActivityItem.pendingRequest(model)
|
let item = ActivityItem.pendingRequest(model)
|
||||||
let section = ActivityPresenter.Section(model: sectionHeader, items: [item])
|
let section = Section(model: sectionHeader, items: [item])
|
||||||
return [section]
|
return [section]
|
||||||
}
|
}
|
||||||
|
|
||||||
private var others: [ActivityPresenter.Section] {
|
private var others: [Section] {
|
||||||
let sectionHeader = SectionHeader(name: "Section 2", identifier: "")
|
let sectionHeader = SectionHeader(name: "Section 2", identifier: "")
|
||||||
let model = ActionItem.mock(seed: 0)
|
let model = ActionItem.mock(seed: 0)
|
||||||
let item = ActivityItem.follower(model)
|
let item = ActivityItem.follower(model)
|
||||||
let section = ActivityPresenter.Section(model: sectionHeader, items: [item])
|
let section = Section(model: sectionHeader, items: [item])
|
||||||
return [section]
|
return [section]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,10 @@ protocol ActivityInteractorOutput: class {
|
||||||
|
|
||||||
protocol ActivityInteractorInput {
|
protocol ActivityInteractorInput {
|
||||||
|
|
||||||
|
func loadAll()
|
||||||
|
func loadNextPageFollowingActivities(completion: ((Result<[ActionItem]>) -> Void)?)
|
||||||
|
func loadNextPagePendigRequestItems(completion: ((Result<[PendingRequestItem]>) -> Void)?)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol ActivityService: class {
|
protocol ActivityService: class {
|
||||||
|
@ -190,37 +194,39 @@ extension ActivityInteractor: ActivityInteractorInput {
|
||||||
let pageID = UUID().uuidString
|
let pageID = UUID().uuidString
|
||||||
loadingPages.insert(pageID)
|
loadingPages.insert(pageID)
|
||||||
|
|
||||||
service.loadFollowingActivities(cursor: followersList.cursor,
|
service.loadFollowingActivities(
|
||||||
limit: followersList.limit) { [weak self] (result: Result<FeedResponseActivityView>) in
|
cursor: followersList.cursor,
|
||||||
|
limit: followersList.limit) { [weak self] (result: Result<FeedResponseActivityView>) in
|
||||||
defer {
|
|
||||||
loadingPages.remove(pageID)
|
defer {
|
||||||
}
|
loadingPages.remove(pageID)
|
||||||
|
}
|
||||||
// exit on released or canceled
|
|
||||||
guard let strongSelf = self, strongSelf.loadingPages.contains(pageID) else {
|
// exit on released or canceled
|
||||||
return
|
guard let strongSelf = self, strongSelf.loadingPages.contains(pageID) else {
|
||||||
}
|
return
|
||||||
|
}
|
||||||
// must have data
|
|
||||||
guard let response = result.value else {
|
// must have data
|
||||||
completion?(.failure(ActivityError.noData))
|
guard let response = result.value else {
|
||||||
return
|
completion?(.failure(ActivityError.noData))
|
||||||
}
|
return
|
||||||
|
}
|
||||||
// map data into page
|
|
||||||
guard let page = strongSelf.process(response: response, pageID: pageID) else {
|
// map data into page
|
||||||
completion?(.failure(ActivityError.notParsable))
|
guard let page = strongSelf.process(response: response, pageID: pageID) else {
|
||||||
return
|
completion?(.failure(ActivityError.notParsable))
|
||||||
}
|
return
|
||||||
|
}
|
||||||
strongSelf.followersList.add(page: page)
|
|
||||||
|
strongSelf.followersList.add(page: page)
|
||||||
completion?(.success(page.items))
|
|
||||||
|
completion?(.success(page.items))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remake using generics
|
||||||
func loadNextPagePendigRequestItems(completion: ((Result<[PendingRequestItem]>) -> Void)? = nil) {
|
func loadNextPagePendigRequestItems(completion: ((Result<[PendingRequestItem]>) -> Void)? = nil) {
|
||||||
|
|
||||||
let pageID = UUID().uuidString
|
let pageID = UUID().uuidString
|
||||||
|
|
|
@ -7,14 +7,14 @@ protocol ActivityModuleInput: class {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typealias Section = SectionModel<SectionHeader, ActivityItem>
|
||||||
|
|
||||||
class ActivityPresenter {
|
class ActivityPresenter {
|
||||||
|
|
||||||
typealias Section = SectionModel<SectionHeader, ActivityItem>
|
|
||||||
|
|
||||||
weak var view: ActivityViewInput!
|
weak var view: ActivityViewInput!
|
||||||
var interactor: ActivityInteractorInput!
|
var interactor: ActivityInteractorInput!
|
||||||
var router: ActivityRouterInput!
|
var router: ActivityRouterInput!
|
||||||
|
|
||||||
enum State: Int {
|
enum State: Int {
|
||||||
case my
|
case my
|
||||||
case others
|
case others
|
||||||
|
@ -44,9 +44,9 @@ class ActivityPresenter {
|
||||||
sections[.my] = sectionsConfigurator.build(section: .my)
|
sections[.my] = sectionsConfigurator.build(section: .my)
|
||||||
sections[.others] = sectionsConfigurator.build(section: .others)
|
sections[.others] = sectionsConfigurator.build(section: .others)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func loadNextPage() {
|
fileprivate func loadNextPage() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,13 +59,98 @@ extension ActivityPresenter: ActivityInteractorOutput {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protocol DataSourceProtocol {
|
||||||
|
func loadMore()
|
||||||
|
var section: Section { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataSource: DataSourceProtocol {
|
||||||
|
var interactor: ActivityInteractorInput
|
||||||
|
var section: Section
|
||||||
|
var errorHandler: ((Error) -> Void)?
|
||||||
|
|
||||||
|
func loadMore() { }
|
||||||
|
|
||||||
|
init(interactor: ActivityInteractorInput, section: Section, errorHandler: ((Error) -> Void)? = nil) {
|
||||||
|
self.interactor = interactor
|
||||||
|
self.section = section
|
||||||
|
self.errorHandler = errorHandler
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MyPendingRequests: DataSource {
|
||||||
|
|
||||||
|
override func loadMore() {
|
||||||
|
|
||||||
|
// load pendings
|
||||||
|
interactor.loadNextPagePendigRequestItems { [weak self] (result) in
|
||||||
|
switch result {
|
||||||
|
case let .failure(error):
|
||||||
|
self?.errorHandler?(error)
|
||||||
|
case let .success(models):
|
||||||
|
let items = models.map { ActivityItem.pendingRequest($0) }
|
||||||
|
self?.section.items.append(contentsOf: items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyFollowersActivity: DataSource {
|
||||||
|
|
||||||
|
override func loadMore() {
|
||||||
|
// load activity
|
||||||
|
interactor.loadNextPageFollowingActivities { [weak self] (result) in
|
||||||
|
switch result {
|
||||||
|
case let .failure(error):
|
||||||
|
self?.errorHandler?(error)
|
||||||
|
case let .success(models):
|
||||||
|
let items = models.map { ActivityItem.follower($0) }
|
||||||
|
self?.section.items.append(contentsOf: items)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyFollowingsActivity: DataSource {
|
||||||
|
|
||||||
|
override func loadMore() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extension ActivityPresenter: ActivityViewOutput {
|
extension ActivityPresenter: ActivityViewOutput {
|
||||||
|
|
||||||
func load() {
|
func load() {
|
||||||
|
interactor.loadAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadMore(for section: Int) {
|
func loadMore() {
|
||||||
|
|
||||||
|
interactor.loadNextPageFollowingActivities { (result) in
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case let .success(items):
|
||||||
|
|
||||||
|
// sections[state]
|
||||||
|
break
|
||||||
|
|
||||||
|
case let .failure(error):
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
interactor.loadNextPageFollowingActivities { (result) in
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +171,7 @@ extension ActivityPresenter: ActivityViewOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
func numberOfSections() -> Int {
|
func numberOfSections() -> Int {
|
||||||
return sections.count
|
return sections[state]!.count
|
||||||
}
|
}
|
||||||
|
|
||||||
func numberOfItems(in section: Int) -> Int {
|
func numberOfItems(in section: Int) -> Int {
|
||||||
|
|
|
@ -7,7 +7,8 @@ import UIKit
|
||||||
|
|
||||||
protocol ActivityViewInput: class {
|
protocol ActivityViewInput: class {
|
||||||
func setupInitialState()
|
func setupInitialState()
|
||||||
func registerCell(cell: AnyObject.Type, id: String)
|
func registerCell(cell: UITableViewCell.Type, id: String)
|
||||||
|
func showError(_ error: Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol ActivityViewOutput: class {
|
protocol ActivityViewOutput: class {
|
||||||
|
@ -44,11 +45,15 @@ class ActivityViewController: UIViewController {
|
||||||
|
|
||||||
extension ActivityViewController: ActivityViewInput {
|
extension ActivityViewController: ActivityViewInput {
|
||||||
|
|
||||||
|
func showError(_ error: Error) {
|
||||||
|
Logger.log(error, event: .veryImportant)
|
||||||
|
}
|
||||||
|
|
||||||
func setupInitialState() {
|
func setupInitialState() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerCell(cell: AnyObject.Type, id: String) {
|
func registerCell(cell: UITableViewCell.Type, id: String) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import EmbeddedSocial
|
||||||
|
|
||||||
|
class ActivityInteractorMock: ActivityInteractorInput {
|
||||||
|
|
||||||
|
var followingActivityItemsResult: Result<[ActionItem]>!
|
||||||
|
var pendingRequestsItemsResult: Result<[PendingRequestItem]>!
|
||||||
|
|
||||||
|
func loadAll() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadNextPageFollowingActivities(completion: ((Result<[ActionItem]>) -> Void)? = nil) {
|
||||||
|
completion?(followingActivityItemsResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadNextPagePendigRequestItems(completion: ((Result<[PendingRequestItem]>) -> Void)? = nil) {
|
||||||
|
completion?(pendingRequestsItemsResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActivityPresenterTests: XCTestCase {
|
||||||
|
|
||||||
|
var sut: ActivityPresenter!
|
||||||
|
var interactor : ActivityInteractorMock!
|
||||||
|
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
super.setUp()
|
||||||
|
|
||||||
|
sut = ActivityPresenter()
|
||||||
|
sut.interactor = ActivityInteractorMock()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() {
|
||||||
|
super.tearDown()
|
||||||
|
}
|
||||||
|
|
||||||
|
func test() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
|
||||||
|
let mockItems = Array(1..<5).map { PendingRequestItem.mock(seed: $0) }
|
||||||
|
let result: Result<[PendingRequestItem]> = .success(mockItems)
|
||||||
|
|
||||||
|
let header = SectionHeader(name: "", identifier: "")
|
||||||
|
let section = Section(model: header, items: [])
|
||||||
|
let pendingRequestsDataSource = MyPendingRequests(interactor: interactor,
|
||||||
|
section: section)
|
||||||
|
|
||||||
|
interactor.pendingRequestsItemsResult = result
|
||||||
|
|
||||||
|
pendingRequestsDataSource.loadMore()
|
||||||
|
|
||||||
|
pendingRequestsDataSource.section.items.count
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -87,6 +87,25 @@ class ActivityEntitiesTests: XCTestCase {
|
||||||
waitForExpectations(timeout: 1, handler: nil)
|
waitForExpectations(timeout: 1, handler: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testThatPaggingWorksCorrectly() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
let service = ActivityServiceMock()
|
||||||
|
let followingActivitiesResponse = buildActivitiResponseMock()
|
||||||
|
service.followingActivitiesResponse = .success(followingActivitiesResponse)
|
||||||
|
|
||||||
|
let interactor = ActivityInteractor()
|
||||||
|
interactor.service = service
|
||||||
|
|
||||||
|
let pendingRequests = expectation(description: #file)
|
||||||
|
|
||||||
|
// when
|
||||||
|
|
||||||
|
// interactor.
|
||||||
|
|
||||||
|
// then
|
||||||
|
}
|
||||||
|
|
||||||
func buildActivitiResponseMock() -> FeedResponseActivityView {
|
func buildActivitiResponseMock() -> FeedResponseActivityView {
|
||||||
return FeedResponseActivityView().mockResponse()
|
return FeedResponseActivityView().mockResponse()
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче