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

test: 업로드 VIP 테스트 코드 작성 #326

Merged
merged 9 commits into from
Dec 13, 2023
60 changes: 60 additions & 0 deletions iOS/Layover/Layover.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,15 @@
FC4975932B03432800D8627F /* Pretendard-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FC49758A2B03432800D8627F /* Pretendard-Bold.ttf */; };
FC4975942B03432800D8627F /* Pretendard-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FC49758B2B03432800D8627F /* Pretendard-Regular.ttf */; };
FC4975992B03439000D8627F /* UIFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4975982B03439000D8627F /* UIFont+.swift */; };
FC4E0C0C2B282AE500152596 /* UploadPostViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C082B282AE500152596 /* UploadPostViewControllerTests.swift */; };
FC4E0C0D2B282AE500152596 /* UploadPostInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C092B282AE500152596 /* UploadPostInteractorTests.swift */; };
FC4E0C0E2B282AE500152596 /* UploadPostWorkerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C0A2B282AE500152596 /* UploadPostWorkerTests.swift */; };
FC4E0C0F2B282AE500152596 /* UploadPostPresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C0B2B282AE500152596 /* UploadPostPresenterTests.swift */; };
FC4E0C112B28595200152596 /* MockUploadPostWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C102B28595200152596 /* MockUploadPostWorker.swift */; };
FC4E0C132B28609C00152596 /* PostBoard.json in Resources */ = {isa = PBXBuildFile; fileRef = FC4E0C122B28609C00152596 /* PostBoard.json */; };
FC4E0C192B28955400152596 /* LocationFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C182B28955400152596 /* LocationFetcher.swift */; };
FC4E0C1D2B28977000152596 /* CurrentLocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C1C2B28977000152596 /* CurrentLocationManager.swift */; };
FC4E0C202B28B4C500152596 /* MockLocationFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4E0C1F2B28B4C500152596 /* MockLocationFetcher.swift */; };
FC5BE11C2B148D160036366D /* EditProfilePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5BE1162B148D160036366D /* EditProfilePresenter.swift */; };
FC5BE11D2B148D160036366D /* EditProfileWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5BE1172B148D160036366D /* EditProfileWorker.swift */; };
FC5BE11E2B148D160036366D /* EditProfileRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5BE1182B148D160036366D /* EditProfileRouter.swift */; };
Expand Down Expand Up @@ -378,6 +387,15 @@
FC49758A2B03432800D8627F /* Pretendard-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Bold.ttf"; sourceTree = "<group>"; };
FC49758B2B03432800D8627F /* Pretendard-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Regular.ttf"; sourceTree = "<group>"; };
FC4975982B03439000D8627F /* UIFont+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+.swift"; sourceTree = "<group>"; };
FC4E0C082B282AE500152596 /* UploadPostViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadPostViewControllerTests.swift; sourceTree = "<group>"; };
FC4E0C092B282AE500152596 /* UploadPostInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadPostInteractorTests.swift; sourceTree = "<group>"; };
FC4E0C0A2B282AE500152596 /* UploadPostWorkerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadPostWorkerTests.swift; sourceTree = "<group>"; };
FC4E0C0B2B282AE500152596 /* UploadPostPresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadPostPresenterTests.swift; sourceTree = "<group>"; };
FC4E0C102B28595200152596 /* MockUploadPostWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUploadPostWorker.swift; sourceTree = "<group>"; };
FC4E0C122B28609C00152596 /* PostBoard.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = PostBoard.json; sourceTree = "<group>"; };
FC4E0C182B28955400152596 /* LocationFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationFetcher.swift; sourceTree = "<group>"; };
FC4E0C1C2B28977000152596 /* CurrentLocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentLocationManager.swift; sourceTree = "<group>"; };
FC4E0C1F2B28B4C500152596 /* MockLocationFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockLocationFetcher.swift; sourceTree = "<group>"; };
FC5BE1162B148D160036366D /* EditProfilePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfilePresenter.swift; sourceTree = "<group>"; };
FC5BE1172B148D160036366D /* EditProfileWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileWorker.swift; sourceTree = "<group>"; };
FC5BE1182B148D160036366D /* EditProfileRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileRouter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -509,6 +527,7 @@
isa = PBXGroup;
children = (
194C21BE2B1DEE5500C62645 /* Home */,
FCF1A02D2B275A0400D961BE /* UploadPost */,
);
path = Scenes;
sourceTree = "<group>";
Expand All @@ -518,6 +537,7 @@
children = (
194C21CE2B1DF63D00C62645 /* MockDatas */,
194C21CA2B1DF37900C62645 /* Workers */,
FC4E0C1E2B28B4AD00152596 /* LocationFetcher */,
);
path = Mocks;
sourceTree = "<group>";
Expand All @@ -526,6 +546,7 @@
isa = PBXGroup;
children = (
194C21CB2B1DF39200C62645 /* MockHomeWorker.swift */,
FC4E0C102B28595200152596 /* MockUploadPostWorker.swift */,
);
path = Workers;
sourceTree = "<group>";
Expand All @@ -535,6 +556,7 @@
children = (
194C21D32B1EEE3700C62645 /* sample.jpeg */,
194C21CF2B1DF65200C62645 /* PostList.json */,
FC4E0C122B28609C00152596 /* PostBoard.json */,
);
path = MockDatas;
sourceTree = "<group>";
Expand Down Expand Up @@ -798,6 +820,23 @@
path = Fonts;
sourceTree = "<group>";
};
FC4E0C172B28954000152596 /* Location */ = {
isa = PBXGroup;
children = (
FC4E0C182B28955400152596 /* LocationFetcher.swift */,
FC4E0C1C2B28977000152596 /* CurrentLocationManager.swift */,
);
path = Location;
sourceTree = "<group>";
};
FC4E0C1E2B28B4AD00152596 /* LocationFetcher */ = {
isa = PBXGroup;
children = (
FC4E0C1F2B28B4C500152596 /* MockLocationFetcher.swift */,
);
path = LocationFetcher;
sourceTree = "<group>";
};
FC5BE1112B148AF00036366D /* Views */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -917,6 +956,7 @@
children = (
1972CCD02B125E8800C3C762 /* UserDefaults */,
19C7AFD42B02583C003B35F2 /* Keychain */,
FC4E0C172B28954000152596 /* Location */,
1901D4A12B18F4BE00617A64 /* System.swift */,
);
path = Services;
Expand Down Expand Up @@ -1035,6 +1075,17 @@
path = SignUpScene;
sourceTree = "<group>";
};
FCF1A02D2B275A0400D961BE /* UploadPost */ = {
isa = PBXGroup;
children = (
FC4E0C082B282AE500152596 /* UploadPostViewControllerTests.swift */,
FC4E0C092B282AE500152596 /* UploadPostInteractorTests.swift */,
FC4E0C0A2B282AE500152596 /* UploadPostWorkerTests.swift */,
FC4E0C0B2B282AE500152596 /* UploadPostPresenterTests.swift */,
);
path = UploadPost;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -1153,6 +1204,7 @@
buildActionMask = 2147483647;
files = (
194C21D02B1DF65200C62645 /* PostList.json in Resources */,
FC4E0C132B28609C00152596 /* PostBoard.json in Resources */,
194C21D42B1EEE3700C62645 /* sample.jpeg in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -1308,7 +1360,9 @@
1915D6E52B1FB82000CE1DD0 /* CheckSignUpDTO.swift in Sources */,
198167A02B20583D0032F563 /* SettingPresenter.swift in Sources */,
198167A42B20583D0032F563 /* SettingInteractor.swift in Sources */,
FC4E0C1D2B28977000152596 /* CurrentLocationManager.swift in Sources */,
83C35E1B2B108C3500D8DD5C /* PlaybackView.swift in Sources */,
FC4E0C192B28955400152596 /* LocationFetcher.swift in Sources */,
835A61A02B068115002F22A5 /* PlaybackModels.swift in Sources */,
FC0E80292B1A0BBB00EF56D6 /* UploadPostInteractor.swift in Sources */,
836C33912B17629400ECAFB0 /* MapRouter.swift in Sources */,
Expand Down Expand Up @@ -1366,10 +1420,16 @@
buildActionMask = 2147483647;
files = (
194C21C42B1DEE6B00C62645 /* HomeInteractorTests.swift in Sources */,
FC4E0C0F2B282AE500152596 /* UploadPostPresenterTests.swift in Sources */,
FC4E0C0C2B282AE500152596 /* UploadPostViewControllerTests.swift in Sources */,
194C21C52B1DEE6B00C62645 /* HomeWorkerTests.swift in Sources */,
194C21C62B1DEE6B00C62645 /* HomePresenterTests.swift in Sources */,
FC4E0C202B28B4C500152596 /* MockLocationFetcher.swift in Sources */,
194C21C32B1DEE6B00C62645 /* HomeViewControllerTests.swift in Sources */,
194C21CC2B1DF39200C62645 /* MockHomeWorker.swift in Sources */,
FC4E0C0E2B282AE500152596 /* UploadPostWorkerTests.swift in Sources */,
FC4E0C112B28595200152596 /* MockUploadPostWorker.swift in Sources */,
FC4E0C0D2B282AE500152596 /* UploadPostInteractorTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ final class UploadPostConfigurator: Configurator {

func configure(_ viewController: ViewController) {
let viewController = viewController
let interactor = UploadPostInteractor()
let interactor = UploadPostInteractor(locationManager: CurrentLocationManager())
anyukyung marked this conversation as resolved.
Show resolved Hide resolved
let presenter = UploadPostPresenter()
let router = UploadPostRouter()
let worker = UploadPostWorker()
Expand Down
71 changes: 28 additions & 43 deletions iOS/Layover/Layover/Scenes/UploadPost/UploadPostInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@ import OSLog
protocol UploadPostBusinessLogic {
func fetchTags()
func editTags(with request: UploadPostModels.EditTags.Request)

@discardableResult
func fetchThumbnailImage() -> Task<Bool, Never>

func fetchThumbnailImage()
func fetchCurrentAddress()
func canUploadPost(request: UploadPostModels.CanUploadPost.Request)

@discardableResult
func uploadPost(request: UploadPostModels.UploadPost.Request) -> Task<Bool, Never>
func uploadPost(request: UploadPostModels.UploadPost.Request)
}

protocol UploadPostDataStore {
Expand All @@ -42,7 +37,7 @@ final class UploadPostInteractor: NSObject, UploadPostBusinessLogic, UploadPostD
var presenter: UploadPostPresentationLogic?

private let fileManager: FileManager
private let locationManager: CLLocationManager
private let locationManager: CurrentLocationManager

// MARK: - Data Store

Expand All @@ -53,7 +48,7 @@ final class UploadPostInteractor: NSObject, UploadPostBusinessLogic, UploadPostD
// MARK: - Object LifeCycle

init(fileManager: FileManager = FileManager.default,
locationManager: CLLocationManager = CLLocationManager()) {
locationManager: CurrentLocationManager = CurrentLocationManager()) {
self.fileManager = fileManager
self.locationManager = locationManager
}
Expand All @@ -69,28 +64,25 @@ final class UploadPostInteractor: NSObject, UploadPostBusinessLogic, UploadPostD
tags = request.tags
}

@discardableResult
func fetchThumbnailImage() -> Task<Bool, Never> {
Task {
guard let videoURL else { return false }
func fetchThumbnailImage() {
guard let videoURL else { return }
let asset = AVAsset(url: videoURL)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
Task {
do {
let image = try await generator.image(at: .zero).image
await MainActor.run {
presenter?.presentThumbnailImage(with: Models.FetchThumbnail.Response(thumbnailImage: image))
}
return true
} catch let error {
os_log(.error, log: .default, "Failed to fetch Thumbnail Image with error: %@", error.localizedDescription)
return false
os_log(.error, log: .data, "Failed to fetch Thumbnail Image with error: %@", error.localizedDescription)
}
}
}

func fetchCurrentAddress() {
guard let location = getCurrentLocation() else { return }
guard let location = locationManager.getCurrentLocation() else { return }
let localeIdentifier = Locale.preferredLanguages.first != nil ? Locale.preferredLanguages[0] : Locale.current.identifier
let locale = Locale(identifier: localeIdentifier)

Expand All @@ -107,7 +99,7 @@ final class UploadPostInteractor: NSObject, UploadPostBusinessLogic, UploadPostD
presenter?.presentCurrentAddress(with: response)
}
} catch {
os_log(.error, log: .default, "Failed to fetch Current Address with error: %@", error.localizedDescription)
os_log(.error, log: .data, "Failed to fetch Current Address with error: %@", error.localizedDescription)
}
}
}
Expand All @@ -117,35 +109,28 @@ final class UploadPostInteractor: NSObject, UploadPostBusinessLogic, UploadPostD
presenter?.presentUploadButton(with: response)
}

@discardableResult
func uploadPost(request: UploadPostModels.UploadPost.Request) -> Task<Bool, Never> {
func uploadPost(request: UploadPostModels.UploadPost.Request) {
guard let worker,
let videoURL,
let isMuted,
let coordinate = locationManager.getCurrentLocation()?.coordinate else { return }
if isMuted {
exportVideoWithoutAudio(at: videoURL)
}
Task {
guard let worker,
let videoURL,
let isMuted,
let coordinate = getCurrentLocation()?.coordinate else { return false }
if isMuted {
exportVideoWithoutAudio(at: videoURL)
}
let response = await worker.uploadPost(with: UploadPost(title: request.title,
content: request.content,
latitude: coordinate.latitude,
longitude: coordinate.longitude,
tag: request.tags,
videoURL: videoURL))
return response
let uploadPostResponse = await worker.uploadPost(with: UploadPost(title: request.title,
content: request.content,
latitude: coordinate.latitude,
longitude: coordinate.longitude,
tag: request.tags,
videoURL: videoURL))
guard let boardID = uploadPostResponse?.id else { return }
let fileType = videoURL.pathExtension
_ = await worker.uploadVideo(with: UploadVideoRequestDTO(boardID: boardID, filetype: fileType),
videoURL: videoURL)
}
}

private func getCurrentLocation() -> CLLocation? {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()

guard let space = locationManager.location?.coordinate else { return nil }
let location = CLLocation(latitude: space.latitude, longitude: space.longitude)
return location
}

private func exportVideoWithoutAudio(at url: URL) {
let composition = AVMutableComposition()
let sourceAsset = AVURLAsset(url: url)
Expand Down
19 changes: 8 additions & 11 deletions iOS/Layover/Layover/Scenes/UploadPost/UploadPostWorker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import UIKit
import OSLog

protocol UploadPostWorkerProtocol {
func uploadPost(with request: UploadPost) async -> Bool
func uploadPost(with request: UploadPost) async -> UploadPostDTO?
func uploadVideo(with request: UploadVideoRequestDTO, videoURL: URL) async -> Bool
}

final class UploadPostWorker: NSObject, UploadPostWorkerProtocol {
Expand All @@ -30,34 +31,30 @@ final class UploadPostWorker: NSObject, UploadPostWorkerProtocol {
self.uploadPostEndPointFactory = uploadPostEndPointFactory
}

func uploadPost(with request: UploadPost) async -> Bool {
func uploadPost(with request: UploadPost) async -> UploadPostDTO? {
let endPoint = uploadPostEndPointFactory.makeUploadPostEndPoint(title: request.title,
content: request.content,
latitude: request.latitude,
longitude: request.longitude,
tag: request.tag)
do {
let response = try await provider.request(with: endPoint)
guard let boardID = response.data?.id else { return false }
let fileType = request.videoURL.pathExtension
let uploadResponse = await uploadVideo(with: UploadVideoRequestDTO(boardID: boardID, filetype: fileType),
videoURL: request.videoURL)
return uploadResponse
return response.data
} catch {
os_log(.error, log: .data, "Failed to fetch posts: %@", error.localizedDescription)
return false
return nil
}
}

private func uploadVideo(with request: UploadVideoRequestDTO, videoURL: URL) async -> Bool {
func uploadVideo(with request: UploadVideoRequestDTO, videoURL: URL) async -> Bool {
let endPoint = uploadPostEndPointFactory.makeUploadVideoEndPoint(boardID: request.boardID,
fileType: request.filetype)
do {
let response = try await provider.request(with: endPoint)
guard let preSignedURLString = response.data?.preSignedURL else { return false }
_ = try await provider.upload(fromFile: videoURL,
to: preSignedURLString,
sessionTaskDelegate: self)
to: preSignedURLString,
sessionTaskDelegate: self)
NotificationCenter.default.post(name: .uploadTaskDidComplete, object: nil)
return true
} catch {
Expand Down
Loading