Skip to content
Snippets Groups Projects
Commit be596e5e authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Implement SendImage

parent c17818aa
No related branches found
No related tags found
2 merge requests!124File transfers example,!102Release 1.0.0
...@@ -5,6 +5,14 @@ import XXMessengerClient ...@@ -5,6 +5,14 @@ import XXMessengerClient
import XXModels import XXModels
public struct SendImage { public struct SendImage {
public struct ProgressError: Error, Equatable {
public init(message: String) {
self.message = message
}
public var message: String
}
public typealias OnError = (Error) -> Void public typealias OnError = (Error) -> Void
public typealias Completion = () -> Void public typealias Completion = () -> Void
...@@ -27,8 +35,79 @@ extension SendImage { ...@@ -27,8 +35,79 @@ extension SendImage {
now: @escaping () -> Date now: @escaping () -> Date
) -> SendImage { ) -> SendImage {
SendImage { image, recipientId, onError, completion in SendImage { image, recipientId, onError, completion in
// TODO: implement sending image func updateProgress(transferId: Data, progress: Float) {
completion() do {
if var transfer = try db().fetchFileTransfers(.init(id: [transferId])).first {
transfer.progress = progress
try db().saveFileTransfer(transfer)
}
} catch {
onError(error)
}
}
let file = FileSend(
name: "image.jpg",
type: "image",
preview: nil,
contents: image
)
let params = MessengerSendFile.Params(
file: file,
recipientId: recipientId,
retry: 2,
callbackIntervalMS: 500
)
do {
let date = now()
let myContactId = try messenger.e2e.tryGet().getContact().getId()
let transferId = try messenger.sendFile(params) { info in
switch info {
case .progress(let transferId, let transmitted, let total):
updateProgress(
transferId: transferId,
progress: total > 0 ? Float(transmitted) / Float(total) : 0
)
case .finished(let transferId):
updateProgress(
transferId: transferId,
progress: 1
)
case .failed(_, .error(let error)):
onError(error)
case .failed(_, .progressError(let message)):
onError(ProgressError(message: message))
case .failed(_, .close(let error)):
onError(error)
}
}
try db().saveFileTransfer(XXModels.FileTransfer(
id: transferId,
contactId: myContactId,
name: file.name,
type: file.type,
data: image,
progress: 0,
isIncoming: false,
createdAt: date
))
try db().saveMessage(XXModels.Message(
senderId: myContactId,
recipientId: recipientId,
groupId: nil,
date: date,
status: .sent,
isUnread: false,
text: "",
fileTransferId: transferId
))
} catch {
onError(error)
}
} }
} }
} }
......
...@@ -9,13 +9,46 @@ final class SendImageTests: XCTestCase { ...@@ -9,13 +9,46 @@ final class SendImageTests: XCTestCase {
func testSend() { func testSend() {
let image = "image-data".data(using: .utf8)! let image = "image-data".data(using: .utf8)!
let recipientId = "recipient-id".data(using: .utf8)! let recipientId = "recipient-id".data(using: .utf8)!
let myContactId = "my-contact-id".data(using: .utf8)!
let transferId = "transfer-id".data(using: .utf8)!
let currentDate = Date(timeIntervalSince1970: 123)
var actions: [Action] = [] var actions: [Action] = []
var sendFileCallback: MessengerSendFile.Callback?
let messenger: Messenger = .unimplemented var messenger: Messenger = .unimplemented
let db: DBManagerGetDB = .unimplemented messenger.e2e.get = {
let now: () -> Date = Date.init var e2e: E2E = .unimplemented
let send: SendImage = .live(messenger: messenger, db: db, now: now) e2e.getContact.run = {
var contact: XXClient.Contact = .unimplemented(Data())
contact.getIdFromContact.run = { _ in myContactId }
return contact
}
return e2e
}
messenger.sendFile.run = { params, callback in
actions.append(.didSendFile(params))
sendFileCallback = callback
return transferId
}
var db: DBManagerGetDB = .unimplemented
db.run = {
var db: Database = .unimplemented
db.saveFileTransfer.run = { model in
actions.append(.didSaveFileTransfer(model))
return model
}
db.saveMessage.run = { model in
actions.append(.didSaveMessage(model))
return model
}
db.fetchFileTransfers.run = { query in
actions.append(.didFetchFileTransfers(query))
return [.stub(withProgress: 0)]
}
return db
}
let send: SendImage = .live(messenger: messenger, db: db, now: { currentDate })
actions = [] actions = []
send( send(
...@@ -30,7 +63,77 @@ final class SendImageTests: XCTestCase { ...@@ -30,7 +63,77 @@ final class SendImageTests: XCTestCase {
) )
XCTAssertNoDifference(actions, [ XCTAssertNoDifference(actions, [
.didComplete .didSendFile(.init(
file: .init(
name: "image.jpg",
type: "image",
preview: nil,
contents: image
),
recipientId: recipientId,
retry: 2,
callbackIntervalMS: 500
)),
.didSaveFileTransfer(.init(
id: transferId,
contactId: myContactId,
name: "image.jpg",
type: "image",
data: image,
progress: 0,
isIncoming: false,
createdAt: currentDate
)),
.didSaveMessage(.init(
senderId: myContactId,
recipientId: recipientId,
groupId: nil,
date: currentDate,
status: .sent,
isUnread: false,
text: "",
fileTransferId: transferId
)),
])
actions = []
let sendError = NSError(domain: "send-error", code: 1)
sendFileCallback?(.failed(id: transferId, .error(sendError)))
XCTAssertNoDifference(actions, [
.didFail(sendError),
])
actions = []
let closeError = NSError(domain: "close-error", code: 2)
sendFileCallback?(.failed(id: transferId, .close(closeError)))
XCTAssertNoDifference(actions, [
.didFail(closeError),
])
actions = []
let progressError = "progress-error"
sendFileCallback?(.failed(id: transferId, .progressError(progressError)))
XCTAssertNoDifference(actions, [
.didFail(SendImage.ProgressError(message: progressError) as NSError),
])
actions = []
sendFileCallback?(.progress(id: transferId, transmitted: 1, total: 2))
XCTAssertNoDifference(actions, [
.didFetchFileTransfers(.init(id: [transferId])),
.didSaveFileTransfer(.stub(withProgress: 0.5)),
])
actions = []
sendFileCallback?(.finished(id: transferId))
XCTAssertNoDifference(actions, [
.didFetchFileTransfers(.init(id: [transferId])),
.didSaveFileTransfer(.stub(withProgress: 1)),
]) ])
} }
} }
...@@ -38,4 +141,23 @@ final class SendImageTests: XCTestCase { ...@@ -38,4 +141,23 @@ final class SendImageTests: XCTestCase {
private enum Action: Equatable { private enum Action: Equatable {
case didFail(NSError) case didFail(NSError)
case didComplete case didComplete
case didSendFile(MessengerSendFile.Params)
case didSaveFileTransfer(XXModels.FileTransfer)
case didSaveMessage(XXModels.Message)
case didFetchFileTransfers(XXModels.FileTransfer.Query)
}
private extension XXModels.FileTransfer {
static func stub(withProgress progress: Float) -> XXModels.FileTransfer {
XXModels.FileTransfer(
id: Data(),
contactId: Data(),
name: "",
type: "",
data: nil,
progress: progress,
isIncoming: false,
createdAt: Date(timeIntervalSince1970: 0)
)
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment