From c7598d5fc53ffd175313b5f87d6c3265c90407d1 Mon Sep 17 00:00:00 2001 From: loinsir Date: Wed, 13 Dec 2023 22:15:21 +0900 Subject: [PATCH 1/4] =?UTF-8?q?:white=5Fcheck=5Fmark:=20EditProfileInterac?= =?UTF-8?q?torTests=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS/Layover/Layover.xcodeproj/project.pbxproj | 24 +- .../EditProfile/EditProfileInteractor.swift | 2 + .../EditProfile/EditProfileWorker.swift | 19 -- .../EditProfileInteractorTests.swift | 302 ++++++++++++++++++ .../EditProfilePresenterTests.swift | 62 ++++ .../EditProfileViewControllerTests.swift | 84 +++++ 6 files changed, 470 insertions(+), 23 deletions(-) delete mode 100644 iOS/Layover/Layover/Scenes/EditProfile/EditProfileWorker.swift create mode 100644 iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift create mode 100644 iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift create mode 100644 iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift diff --git a/iOS/Layover/Layover.xcodeproj/project.pbxproj b/iOS/Layover/Layover.xcodeproj/project.pbxproj index 2010426..15c92eb 100644 --- a/iOS/Layover/Layover.xcodeproj/project.pbxproj +++ b/iOS/Layover/Layover.xcodeproj/project.pbxproj @@ -108,6 +108,9 @@ 19AE48182B28C2B700DD4612 /* SettingInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE48142B28C2B700DD4612 /* SettingInteractorTests.swift */; }; 19AE481A2B28C2B700DD4612 /* SettingPresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE48162B28C2B700DD4612 /* SettingPresenterTests.swift */; }; 19AE481C2B28C53800DD4612 /* MockSettingWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE481B2B28C53800DD4612 /* MockSettingWorker.swift */; }; + 19AE48222B29D03D00DD4612 /* EditProfileViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE481E2B29D03D00DD4612 /* EditProfileViewControllerTests.swift */; }; + 19AE48232B29D03D00DD4612 /* EditProfileInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE481F2B29D03D00DD4612 /* EditProfileInteractorTests.swift */; }; + 19AE48252B29D03D00DD4612 /* EditProfilePresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE48212B29D03D00DD4612 /* EditProfilePresenterTests.swift */; }; 19C7AFCE2B02410F003B35F2 /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19C7AFCD2B02410F003B35F2 /* AuthManager.swift */; }; 19C7AFD62B02584D003B35F2 /* KeychainStored.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19C7AFD52B02584D003B35F2 /* KeychainStored.swift */; }; 19E79AC02B0A85D0009EA9ED /* LoopingPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E79ABF2B0A85D0009EA9ED /* LoopingPlayerView.swift */; }; @@ -189,7 +192,6 @@ FC4975942B03432800D8627F /* Pretendard-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = FC49758B2B03432800D8627F /* Pretendard-Regular.ttf */; }; FC4975992B03439000D8627F /* UIFont+.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4975982B03439000D8627F /* UIFont+.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 */; }; FC5BE11F2B148D160036366D /* EditProfileModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5BE1192B148D160036366D /* EditProfileModels.swift */; }; FC5BE1202B148D170036366D /* EditProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC5BE11A2B148D160036366D /* EditProfileViewController.swift */; }; @@ -349,6 +351,9 @@ 19AE48142B28C2B700DD4612 /* SettingInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingInteractorTests.swift; sourceTree = ""; }; 19AE48162B28C2B700DD4612 /* SettingPresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingPresenterTests.swift; sourceTree = ""; }; 19AE481B2B28C53800DD4612 /* MockSettingWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSettingWorker.swift; sourceTree = ""; }; + 19AE481E2B29D03D00DD4612 /* EditProfileViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileViewControllerTests.swift; sourceTree = ""; }; + 19AE481F2B29D03D00DD4612 /* EditProfileInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileInteractorTests.swift; sourceTree = ""; }; + 19AE48212B29D03D00DD4612 /* EditProfilePresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfilePresenterTests.swift; sourceTree = ""; }; 19C7AFCD2B02410F003B35F2 /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthManager.swift; sourceTree = ""; }; 19C7AFD52B02584D003B35F2 /* KeychainStored.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainStored.swift; sourceTree = ""; }; 19E79ABF2B0A85D0009EA9ED /* LoopingPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoopingPlayerView.swift; sourceTree = ""; }; @@ -433,7 +438,6 @@ FC49758B2B03432800D8627F /* Pretendard-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Regular.ttf"; sourceTree = ""; }; FC4975982B03439000D8627F /* UIFont+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+.swift"; sourceTree = ""; }; FC5BE1162B148D160036366D /* EditProfilePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfilePresenter.swift; sourceTree = ""; }; - FC5BE1172B148D160036366D /* EditProfileWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileWorker.swift; sourceTree = ""; }; FC5BE1182B148D160036366D /* EditProfileRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileRouter.swift; sourceTree = ""; }; FC5BE1192B148D160036366D /* EditProfileModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileModels.swift; sourceTree = ""; }; FC5BE11A2B148D160036366D /* EditProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileViewController.swift; sourceTree = ""; }; @@ -591,6 +595,7 @@ 194C21C72B1DF09B00C62645 /* Scenes */ = { isa = PBXGroup; children = ( + 19AE481D2B29D02700DD4612 /* EditProfile */, 19AE48122B28C2A800DD4612 /* Setting */, 192513632B26F7BB001533FA /* TagPlayList */, 1925137B2B277CC4001533FA /* Profile */, @@ -742,6 +747,16 @@ path = Setting; sourceTree = ""; }; + 19AE481D2B29D02700DD4612 /* EditProfile */ = { + isa = PBXGroup; + children = ( + 19AE481E2B29D03D00DD4612 /* EditProfileViewControllerTests.swift */, + 19AE481F2B29D03D00DD4612 /* EditProfileInteractorTests.swift */, + 19AE48212B29D03D00DD4612 /* EditProfilePresenterTests.swift */, + ); + path = EditProfile; + sourceTree = ""; + }; 19BB8A572B07BEE30070B922 /* UIComponents */ = { isa = PBXGroup; children = ( @@ -926,7 +941,6 @@ FC5BE1162B148D160036366D /* EditProfilePresenter.swift */, FC5BE1192B148D160036366D /* EditProfileModels.swift */, FC5BE1182B148D160036366D /* EditProfileRouter.swift */, - FC5BE1172B148D160036366D /* EditProfileWorker.swift */, FC5BE1222B1490660036366D /* EditProfileConfigurator.swift */, ); path = EditProfile; @@ -1350,7 +1364,6 @@ 1945520D2B0399E500299768 /* MainTabBarViewController.swift in Sources */, FC2511AB2B04EA6B004717BC /* MapConfigurator.swift in Sources */, 1945523B2B05258200299768 /* HomeConfigurator.swift in Sources */, - FC5BE11D2B148D160036366D /* EditProfileWorker.swift in Sources */, 19A1693A2B17BCC400DB34C0 /* MemberDTO.swift in Sources */, 194551F62B037F2D00299768 /* LoginViewController.swift in Sources */, FC767FA52B125F430088CF9B /* UIViewController+.swift in Sources */, @@ -1501,6 +1514,7 @@ 192513A72B278BB3001533FA /* Seeds.swift in Sources */, 194C21C52B1DEE6B00C62645 /* HomeWorkerTests.swift in Sources */, 19AE481C2B28C53800DD4612 /* MockSettingWorker.swift in Sources */, + 19AE48252B29D03D00DD4612 /* EditProfilePresenterTests.swift in Sources */, 192513802B277CD7001533FA /* ProfileViewControllerTests.swift in Sources */, 194C21C62B1DEE6B00C62645 /* HomePresenterTests.swift in Sources */, 1925137A2B273D98001533FA /* StubAuthManager.swift in Sources */, @@ -1509,6 +1523,8 @@ 19AE48172B28C2B700DD4612 /* SettingViewControllerTests.swift in Sources */, 194C21C32B1DEE6B00C62645 /* HomeViewControllerTests.swift in Sources */, 192513692B26F7CE001533FA /* TagPlayListInteractorTests.swift in Sources */, + 19AE48222B29D03D00DD4612 /* EditProfileViewControllerTests.swift in Sources */, + 19AE48232B29D03D00DD4612 /* EditProfileInteractorTests.swift in Sources */, 194C21CC2B1DF39200C62645 /* MockHomeWorker.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/iOS/Layover/Layover/Scenes/EditProfile/EditProfileInteractor.swift b/iOS/Layover/Layover/Scenes/EditProfile/EditProfileInteractor.swift index 9343d1c..12baa56 100644 --- a/iOS/Layover/Layover/Scenes/EditProfile/EditProfileInteractor.swift +++ b/iOS/Layover/Layover/Scenes/EditProfile/EditProfileInteractor.swift @@ -13,6 +13,7 @@ import OSLog protocol EditProfileBusinessLogic { func setProfile(with request: EditProfileModels.SetProfile.Request) func changeProfile(with request: EditProfileModels.ChangeProfile.Request) + @discardableResult func checkDuplication(with request: EditProfileModels.CheckNicknameDuplication.Request) async -> Bool @discardableResult func editProfile(with request: EditProfileModels.EditProfile.Request) async -> Bool @@ -96,6 +97,7 @@ final class EditProfileInteractor: EditProfileBusinessLogic, EditProfileDataStor presenter?.presentProfileState(with: response) } + @discardableResult func checkDuplication(with request: Models.CheckNicknameDuplication.Request) async -> Bool { guard let response = await userWorker?.checkNotDuplication(for: request.nickname) else { os_log(.error, log: .data, "checkDuplication Server Error") diff --git a/iOS/Layover/Layover/Scenes/EditProfile/EditProfileWorker.swift b/iOS/Layover/Layover/Scenes/EditProfile/EditProfileWorker.swift deleted file mode 100644 index 653c75c..0000000 --- a/iOS/Layover/Layover/Scenes/EditProfile/EditProfileWorker.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// EditProfileWorker.swift -// Layover -// -// Created by kong on 2023/11/27. -// Copyright © 2023 CodeBomber. All rights reserved. -// - -import UIKit - -final class EditProfileWorker { - - // MARK: - Properties - - typealias Models = EditProfileModels - - // MARK: - Methods - -} diff --git a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift new file mode 100644 index 0000000..ad65887 --- /dev/null +++ b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift @@ -0,0 +1,302 @@ +// +// EditProfileInteractorTests.swift +// Layover +// +// Created by 김인환 on 12/13/23. +// Copyright (c) 2023 CodeBomber. All rights reserved. +// +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com +// + +@testable import Layover +import XCTest + +final class EditProfileInteractorTests: XCTestCase { + // MARK: Subject under test + + var sut: EditProfileInteractor! + + let stubNickname = "안유진" + let stubIntroduce = "아이브의 리더 안유진" + let stubProfileImageData = Seeds.sampleImageData + + typealias Models = EditProfileModels + + // MARK: - Test lifecycle + + override func setUp() { + super.setUp() + setupEditProfileInteractor() + } + + override func tearDown() { + super.tearDown() + } + + // MARK: - Test setup + + func setupEditProfileInteractor() { + sut = EditProfileInteractor() + sut.userWorker = MockUserWorker() + sut.nickname = stubNickname + sut.introduce = stubIntroduce + sut.profileImageData = stubProfileImageData + } + + // MARK: - Test doubles + + final class EditProfilePresentationLogicSpy: EditProfilePresentationLogic { + var presentSetProfileCalled = false + var presentSetProfileResponse: Models.SetProfile.Response! + var presentEditProfileCalled = false + var presentProfileStateCalled = false + var presentProfileStateResponse: Models.ChangeProfile.Response! + var presentNicknameDuplicationCalled = false + var presentNicknameDuplicationResponse: Models.CheckNicknameDuplication.Response! + + func presentProfile(with response: Models.SetProfile.Response) { + presentSetProfileCalled = true + presentSetProfileResponse = response + } + + func presentProfile(with response: Models.EditProfile.Response) { + presentEditProfileCalled = true + } + + func presentProfileState(with response: Models.ChangeProfile.Response) { + presentProfileStateCalled = true + presentProfileStateResponse = response + } + + func presentNicknameDuplication(with response: Models.CheckNicknameDuplication.Response) { + presentNicknameDuplicationCalled = true + presentNicknameDuplicationResponse = response + } + } + + // MARK: - Tests + + func test_setProfile을_실행하면_presenter의_presentProfile이_호출되고_자신의_데이터를_presenter에게_전달한다() { + // arrange + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.setProfile(with: Models.SetProfile.Request()) + + // assert + XCTAssertTrue(spy.presentSetProfileCalled, "setProfile은 presenter의 presentProfile을 호출하지 못했다.") + XCTAssertEqual(spy.presentSetProfileResponse.nickname, stubNickname, "setProfile은 presenter에게 nickname을 전달하지 못했다.") + XCTAssertEqual(spy.presentSetProfileResponse.introduce, stubIntroduce, "setProfile은 presenter에게 introduce를 전달하지 못했다.") + XCTAssertEqual(spy.presentSetProfileResponse.profileImageData, stubProfileImageData, "setProfile은 presenter에게 profileImageData를 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_nickname이_2자_이상_8자_이하의_한글영숫자로만_이루어진_닉네임이면_presenter에_nicknameState를_valid로_전달하고_canEditProfile을_True로_전달하고_기존_닉네임과_다르면_canCheckNicknameDuplicate를_true로_전달한다() { + // arrange + let changedNickname = "안유진an12" + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .nickname(changedNickname))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile 값을 전달하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "presenter에게 올바른 introduceAlertDescription을 전달하지 못했다.") + XCTAssertTrue(spy.presentProfileStateResponse.canCheckNicknameDuplication!, "changeProfile을 호출해서 presenter에게 anCheckNicknameDuplication을 true로 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_nickname이_2자_이상_8자_이하의_한글영숫자로만_이루어진_닉네임이면_presenter에_nicknameState를_valid로_전달하고_기존_닉네임과_같으면_canEditProfile을_false로_전달하고_canCheckNicknameDuplicate를_false로_전달한다() { + // arrange + let changedNickname = stubNickname + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .nickname(changedNickname))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "presenter에게 올바른 introduceAlertDescription을 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canCheckNicknameDuplication!, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + } + + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_nickname이_2자_이상_8자_이하로_이루어진_한글영숫자로만_이루어지지_않은_다른_닉네임이면_presenter에_nicknameState를_invalidCharacter로_전달한다() { + // arrange + let changedNickname = "유진jin😭" + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .nickname(changedNickname))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .invalidCharacter, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "presenter에게 올바른 introduceAlertDescription을 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canCheckNicknameDuplication!, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_nickname이_2자_미만_으로_이루어진_한글로만_이루어진_닉네임이면_presenter에_nicknameState를_lessThan2GreaterThan8로_전달한다() { + // arrange + let changedNickname = "안" + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .nickname(changedNickname))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .lessThan2GreaterThan8, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "presenter에게 올바른 introduceAlertDescription을 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canCheckNicknameDuplication!, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + } + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_nickname이_2자_미만_으로_이루어진_영어로만_이루어진_닉네임이면_presenter에_nicknameState를_lessThan2GreaterThan8로_전달한다() { + // arrange + let changedNickname = "a" + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .nickname(changedNickname))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .lessThan2GreaterThan8, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + + XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "presenter에게 올바른 introduceAlertDescription을 전달하지 못했다.") + + XCTAssertFalse(spy.presentProfileStateResponse.canCheckNicknameDuplication!, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_nickname이_8자_이상_으로_이루어진_한글영숫자로만_이루어진_닉네임이면_presenter에_nicknameState를_lessThan2GreaterThan8로_전달한다() { + // arrange + let changedNickname = "안유진안댕댕good123" + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .nickname(changedNickname))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .lessThan2GreaterThan8, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 lessThan2GreaterThan8로 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "presenter에게 올바른 introduceAlertDescription을 전달하지 못했다.") + XCTAssertFalse(spy.presentProfileStateResponse.canCheckNicknameDuplication!, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_introduce의_길이가_introduceLengthLimit보다_짧으면_presenter에_introduceAlertDescription이_nil_로_전달된다() { + // arrange + let changedIntroduce = "안녕하세요 아이브의 리더 안유진입니다." + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .introduce(changedIntroduce))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") + + XCTAssertTrue(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + + XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_introduce의_길이가_ChangeProfile_introduceLengthLimit보다_길면_presenter에_introduceAlertDescription이_IntroduceLengthState_overLength의_description_으로_전달된다() { + // arrange + let changedIntroduce = "안녕하세요 아이브의 리더 안유진입니다.안녕하세요 아이브의 리더 안유진입니다.안녕하세요 아이브의 리더 안유진입니다.안녕하세요 아이브의 리더 안유진입니다." + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .introduce(changedIntroduce))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertEqual(spy.presentProfileStateResponse.introduceAlertDescription, Models.ChangeProfile.IntroduceLengthState.overLength.description,"changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") + + + XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + + + XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_introduce가_원래의_introduce와_같으면_presenter에_introduceAlertDescription이_nil로_전달된다() { + // arrange + let changedIntroduce = "안녕하세요 아이브의 리더 안유진입니다." + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .introduce(changedIntroduce))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") + + XCTAssertTrue(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + + XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + } + + func test_changeProfile을_실행했을때_presenter의_presentProfileState가_호출되고_전달된_값이_profileImage라면_이전의_상태값들이_전달된다() { + + // arrange + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + sut.changeProfile(with: Models.ChangeProfile.Request(changedProfileComponent: .profileImage(nil))) + + // assert + XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") + XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") + + XCTAssertTrue(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + + XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") + + XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") + } + + func test_checkDuplication을_실행했을때_중복된_닉네임이_아니라면_presenter의_presentNicknameDuplication을_호출하고_올바른_값을_전달한다() async { + + // arrange + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + + // act + await sut.checkDuplication(with: Models.CheckNicknameDuplication.Request(nickname: "안유진")) + + // assert + XCTAssertTrue(spy.presentNicknameDuplicationCalled, "checkDuplication을 호출해서 presenter의 presentNicknameDuplication을 호출하지 못했다.") + XCTAssertTrue(spy.presentNicknameDuplicationResponse.isValid, + "checkDuplication을 호출해서 presenter에게 올바른 isValid값을 전달하지 못했다.") + + XCTAssertTrue(spy.presentNicknameDuplicationResponse.canEditProfile, + "checkDuplication을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") + } + + // TODO: editProfile 테스트 메서드는 내부 병렬실행 이슈 해결 후 작성 +} diff --git a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift new file mode 100644 index 0000000..ce6b0f4 --- /dev/null +++ b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift @@ -0,0 +1,62 @@ +//// +//// EditProfilePresenterTests.swift +//// Layover +//// +//// Created by 김인환 on 12/13/23. +//// Copyright (c) 2023 CodeBomber. All rights reserved. +//// +//// This file was generated by the Clean Swift Xcode Templates so +//// you can apply clean architecture to your iOS and Mac projects, +//// see http://clean-swift.com +//// +// +//@testable import Layover +//import XCTest +// +//class EditProfilePresenterTests: XCTestCase { +// // MARK: Subject under test +// +// var sut: EditProfilePresenter! +// +// // MARK: - Test lifecycle +// +// override func setUp() { +// super.setUp() +// setupEditProfilePresenter() +// } +// +// override func tearDown() { +// super.tearDown() +// } +// +// // MARK: - Test setup +// +// func setupEditProfilePresenter() { +// sut = EditProfilePresenter() +// } +// +// // MARK: - Test doubles +// +// class EditProfileDisplayLogicSpy: EditProfileDisplayLogic { +// var displaySomethingCalled = false +// +// func displaySomething(viewModel: EditProfile.Something.ViewModel) { +// displaySomethingCalled = true +// } +// } +// +// // MARK: - Tests +// +// func testPresentSomething() { +// // Given +// let spy = EditProfileDisplayLogicSpy() +// sut.viewController = spy +// let response = EditProfile.Something.Response() +// +// // When +// sut.presentSomething(response: response) +// +// // Then +// XCTAssertTrue(spy.displaySomethingCalled, "presentSomething(response:) should ask the view controller to display the result") +// } +//} diff --git a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift new file mode 100644 index 0000000..5e3d3b4 --- /dev/null +++ b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift @@ -0,0 +1,84 @@ +//// +//// EditProfileViewControllerTests.swift +//// Layover +//// +//// Created by 김인환 on 12/13/23. +//// Copyright (c) 2023 CodeBomber. All rights reserved. +//// +//// This file was generated by the Clean Swift Xcode Templates so +//// you can apply clean architecture to your iOS and Mac projects, +//// see http://clean-swift.com +//// +// +//@testable import Layover +//import XCTest +// +//class EditProfileViewControllerTests: XCTestCase { +// // MARK: Subject under test +// +// var sut: EditProfileViewController! +// var window: UIWindow! +// +// // MARK: - Test lifecycle +// +// override func setUp() { +// super.setUp() +// window = UIWindow() +// setupEditProfileViewController() +// } +// +// override func tearDown() { +// window = nil +// super.tearDown() +// } +// +// // MARK: - Test setup +// +// func setupEditProfileViewController() { +// let bundle = Bundle.main +// let storyboard = UIStoryboard(name: "Main", bundle: bundle) +// sut = storyboard.instantiateViewController(withIdentifier: "EditProfileViewController") as! EditProfileViewController +// } +// +// func loadView() { +// window.addSubview(sut.view) +// RunLoop.current.run(until: Date()) +// } +// +// // MARK: - Test doubles +// +// class EditProfileBusinessLogicSpy: EditProfileBusinessLogic { +// var doSomethingCalled = false +// +// func doSomething(request: EditProfile.Something.Request) +// { +// doSomethingCalled = true +// } +// } +// +// // MARK: - Tests +// +// func testShouldDoSomethingWhenViewIsLoaded() { +// // Given +// let spy = EditProfileBusinessLogicSpy() +// sut.interactor = spy +// +// // When +// loadView() +// +// // Then +// XCTAssertTrue(spy.doSomethingCalled, "viewDidLoad() should ask the interactor to do something") +// } +// +// func testDisplaySomething() { +// // Given +// let viewModel = EditProfile.Something.ViewModel() +// +// // When +// loadView() +// sut.displaySomething(viewModel: viewModel) +// +// // Then +// //XCTAssertEqual(sut.nameTextField.text, "", "displaySomething(viewModel:) should update the name text field") +// } +//} From 389328020ff65f43d248e85ae73c7fffb2ae8c0a Mon Sep 17 00:00:00 2001 From: loinsir Date: Wed, 13 Dec 2023 22:37:45 +0900 Subject: [PATCH 2/4] =?UTF-8?q?:white=5Fcheck=5Fmark:=20EditProfilePresent?= =?UTF-8?q?erTests=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditProfilePresenterTests.swift | 216 +++++++++++++----- 1 file changed, 158 insertions(+), 58 deletions(-) diff --git a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift index ce6b0f4..2cdb1b2 100644 --- a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift +++ b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfilePresenterTests.swift @@ -1,62 +1,162 @@ -//// -//// EditProfilePresenterTests.swift -//// Layover -//// -//// Created by 김인환 on 12/13/23. -//// Copyright (c) 2023 CodeBomber. All rights reserved. -//// -//// This file was generated by the Clean Swift Xcode Templates so -//// you can apply clean architecture to your iOS and Mac projects, -//// see http://clean-swift.com -//// // -//@testable import Layover -//import XCTest +// EditProfilePresenterTests.swift +// Layover // -//class EditProfilePresenterTests: XCTestCase { -// // MARK: Subject under test +// Created by 김인환 on 12/13/23. +// Copyright (c) 2023 CodeBomber. All rights reserved. // -// var sut: EditProfilePresenter! +// This file was generated by the Clean Swift Xcode Templates so +// you can apply clean architecture to your iOS and Mac projects, +// see http://clean-swift.com // -// // MARK: - Test lifecycle -// -// override func setUp() { -// super.setUp() -// setupEditProfilePresenter() -// } -// -// override func tearDown() { -// super.tearDown() -// } -// -// // MARK: - Test setup -// -// func setupEditProfilePresenter() { -// sut = EditProfilePresenter() -// } -// -// // MARK: - Test doubles -// -// class EditProfileDisplayLogicSpy: EditProfileDisplayLogic { -// var displaySomethingCalled = false -// -// func displaySomething(viewModel: EditProfile.Something.ViewModel) { -// displaySomethingCalled = true -// } -// } -// -// // MARK: - Tests -// -// func testPresentSomething() { -// // Given -// let spy = EditProfileDisplayLogicSpy() -// sut.viewController = spy -// let response = EditProfile.Something.Response() -// -// // When -// sut.presentSomething(response: response) -// -// // Then -// XCTAssertTrue(spy.displaySomethingCalled, "presentSomething(response:) should ask the view controller to display the result") -// } -//} + +@testable import Layover +import XCTest + +final class EditProfilePresenterTests: XCTestCase { + // MARK: Subject under test + + var sut: EditProfilePresenter! + + typealias Models = EditProfileModels + + // MARK: - Test lifecycle + + override func setUp() { + super.setUp() + setupEditProfilePresenter() + } + + override func tearDown() { + super.tearDown() + } + + // MARK: - Test setup + + func setupEditProfilePresenter() { + sut = EditProfilePresenter() + } + + // MARK: - Test doubles + + final class EditProfileDisplayLogicSpy: EditProfileDisplayLogic { + var displayProfileCalled = false + var displayProfileViewModel: Models.SetProfile.ViewModel! + var displayProfileEditCompletedCalled = false + var displayProfileEditCompletedViewModel: Models.EditProfile.ViewModel! + var displayChangedProfileStateCalled = false + var displayChangedProfileStateViewModel: Models.ChangeProfile.ViewModel! + var displayNicknameDuplicationCalled = false + var displayNicknameDuplicationViewModel: Models.CheckNicknameDuplication.ViewModel! + + func displayProfile(with viewModel: Models.SetProfile.ViewModel) { + displayProfileCalled = true + displayProfileViewModel = viewModel + } + + func displayProfileEditCompleted(with viewModel: Models.EditProfile.ViewModel) { + displayProfileEditCompletedCalled = true + displayProfileEditCompletedViewModel = viewModel + } + + func displayChangedProfileState(with viewModel: Models.ChangeProfile.ViewModel) { + displayChangedProfileStateCalled = true + displayChangedProfileStateViewModel = viewModel + } + + func displayNicknameDuplication(with viewModel: Models.CheckNicknameDuplication.ViewModel) { + displayNicknameDuplicationCalled = true + displayNicknameDuplicationViewModel = viewModel + + } + } + + // MARK: - Tests + + func test_presentProfile을_실행하면_viewController의_displayProfile가_호출되고_올바른_값을_전달한다() { + // arrange + let spy = EditProfileDisplayLogicSpy() + sut.viewController = spy + let nickname = "안유진" + let introduce = "아이브의 리더" + let profileImageData = Seeds.sampleImageData + let response = Models.SetProfile.Response(nickname: nickname, + introduce: introduce, + profileImageData: profileImageData) + + // act + sut.presentProfile(with: response) + + // assert + XCTAssertTrue(spy.displayProfileCalled, "presentProfile을 실행해서 displayProfile이 호출되지 못했다") + XCTAssertEqual(spy.displayProfileViewModel.nickname, nickname, "presentProfile을 실행해서 올바른 nickname이 전달되지 못했다.") + XCTAssertEqual(spy.displayProfileViewModel.introduce, introduce, "presentProfile을 실행해서 올바른 introduce가 전달되지 못했다.") + XCTAssertEqual(spy.displayProfileViewModel.profileImageData, profileImageData, "presentProfile을 실행해서 올바른 profileImageData가 전달되지 못했다.") + } + + func test_presentProfile을_실행하면_viewController의_displayProfileEditCompleted가_호출되고_isSuccess값이_true이면_toastMessage로_프로필이_수정되었습니다_를_전달한다() { + // arrange + let spy = EditProfileDisplayLogicSpy() + sut.viewController = spy + let response = Models.EditProfile.Response(isSuccess: true) + + // act + sut.presentProfile(with: response) + + // assert + XCTAssertTrue(spy.displayProfileEditCompletedCalled, "presentProfileEditCompleted을 실행해서 displayProfileEditCompleted이 호출되지 못했다") + XCTAssertEqual(spy.displayProfileEditCompletedViewModel.toastMessage, "프로필이 수정되었습니다.", "presentProfileEditCompleted을 실행해서 올바른 toastMessage가 전달되지 못했다.") + } + + func test_presentProfile을_실행하면_viewController의_displayProfileEditCompleted가_호출되고_isSuccess값이_false면_toastMessage로_프로필_수정에_실패했습니다_를_전달한다() { + // arrange + let spy = EditProfileDisplayLogicSpy() + sut.viewController = spy + let response = Models.EditProfile.Response(isSuccess: false) + + // act + sut.presentProfile(with: response) + + // assert + XCTAssertTrue(spy.displayProfileEditCompletedCalled, "presentProfileEditCompleted을 실행해서 displayProfileEditCompleted이 호출되지 못했다") + XCTAssertEqual(spy.displayProfileEditCompletedViewModel.toastMessage, "프로필 수정에 실패했습니다.", "presentProfileEditCompleted을 실행해서 올바른 toastMessage가 전달되지 못했다.") + } + + func test_presentProfileState를_실행하면_viewController의_displayChangedProfileState가_호출되고_올바른_값을_전달한다() { + // arrange + let spy = EditProfileDisplayLogicSpy() + sut.viewController = spy + let response = Models.ChangeProfile.Response(nicknameState: .lessThan2GreaterThan8, + nicknameAlertDescription: "닉네임 알림", + introduceAlertDescription: "소개글 알림", + canCheckNicknameDuplication: true, + canEditProfile: true) + + // act + sut.presentProfileState(with: response) + + // assert + XCTAssertTrue(spy.displayChangedProfileStateCalled, "presentProfileState을 실행해서 displayChangedProfileState이 호출되지 못했다") + XCTAssertEqual(spy.displayChangedProfileStateViewModel.nicknameState, .lessThan2GreaterThan8, "presentProfileState을 실행해서 올바른 nicknameState가 전달되지 못했다.") + XCTAssertEqual(spy.displayChangedProfileStateViewModel.nicknameAlertDescription, "닉네임 알림", "presentProfileState을 실행해서 올바른 nicknameAlertDescription가 전달되지 못했다.") + XCTAssertEqual(spy.displayChangedProfileStateViewModel.introduceAlertDescription, "소개글 알림", "presentProfileState을 실행해서 올바른 introduceAlertDescription가 전달되지 못했다.") + XCTAssertEqual(spy.displayChangedProfileStateViewModel.canCheckNicknameDuplication, true, "presentProfileState을 실행해서 올바른 canCheckNicknameDuplication가 전달되지 못했다.") + XCTAssertEqual(spy.displayChangedProfileStateViewModel.canEditProfile, true, "presentProfileState을 실행해서 올바른 canEditProfile이 전달되지 못했다.") + } + + func test_presentNicknameDuplication을_실행하면_viewController의_displayNicknameDuplication이_호출되고_올바른_값을_전달한다() { + // arrange + let spy = EditProfileDisplayLogicSpy() + sut.viewController = spy + let response = Models.CheckNicknameDuplication.Response(isValid: true, + canEditProfile: true) + + // act + sut.presentNicknameDuplication(with: response) + + // assert + XCTAssertTrue(spy.displayNicknameDuplicationCalled, "presentNicknameDuplication을 실행해서 displayNicknameDuplication이 호출되지 못했다") + XCTAssertEqual(spy.displayNicknameDuplicationViewModel.isValidNickname, true, "presentNicknameDuplication을 실행해서 올바른 isValidNickname이 전달되지 못했다.") + XCTAssertEqual(spy.displayNicknameDuplicationViewModel.canEditProfile, true, "presentNicknameDuplication을 실행해서 올바른 canEditProfile이 전달되지 못했다.") + } +} From 859795cde41c62f2ec12335f6cf9fc3061dcdea9 Mon Sep 17 00:00:00 2001 From: loinsir Date: Thu, 14 Dec 2023 00:01:08 +0900 Subject: [PATCH 3/4] =?UTF-8?q?:wrench:=20=EC=BD=94=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C,=20=EC=97=A3=EC=A7=80?= =?UTF-8?q?=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS/Layover/Layover.xcodeproj/project.pbxproj | 4 - .../EditProfileInteractorTests.swift | 25 +++++- .../EditProfileViewControllerTests.swift | 84 ------------------- 3 files changed, 24 insertions(+), 89 deletions(-) delete mode 100644 iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift diff --git a/iOS/Layover/Layover.xcodeproj/project.pbxproj b/iOS/Layover/Layover.xcodeproj/project.pbxproj index 15c92eb..6baf284 100644 --- a/iOS/Layover/Layover.xcodeproj/project.pbxproj +++ b/iOS/Layover/Layover.xcodeproj/project.pbxproj @@ -108,7 +108,6 @@ 19AE48182B28C2B700DD4612 /* SettingInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE48142B28C2B700DD4612 /* SettingInteractorTests.swift */; }; 19AE481A2B28C2B700DD4612 /* SettingPresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE48162B28C2B700DD4612 /* SettingPresenterTests.swift */; }; 19AE481C2B28C53800DD4612 /* MockSettingWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE481B2B28C53800DD4612 /* MockSettingWorker.swift */; }; - 19AE48222B29D03D00DD4612 /* EditProfileViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE481E2B29D03D00DD4612 /* EditProfileViewControllerTests.swift */; }; 19AE48232B29D03D00DD4612 /* EditProfileInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE481F2B29D03D00DD4612 /* EditProfileInteractorTests.swift */; }; 19AE48252B29D03D00DD4612 /* EditProfilePresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19AE48212B29D03D00DD4612 /* EditProfilePresenterTests.swift */; }; 19C7AFCE2B02410F003B35F2 /* AuthManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19C7AFCD2B02410F003B35F2 /* AuthManager.swift */; }; @@ -351,7 +350,6 @@ 19AE48142B28C2B700DD4612 /* SettingInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingInteractorTests.swift; sourceTree = ""; }; 19AE48162B28C2B700DD4612 /* SettingPresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingPresenterTests.swift; sourceTree = ""; }; 19AE481B2B28C53800DD4612 /* MockSettingWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSettingWorker.swift; sourceTree = ""; }; - 19AE481E2B29D03D00DD4612 /* EditProfileViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileViewControllerTests.swift; sourceTree = ""; }; 19AE481F2B29D03D00DD4612 /* EditProfileInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfileInteractorTests.swift; sourceTree = ""; }; 19AE48212B29D03D00DD4612 /* EditProfilePresenterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditProfilePresenterTests.swift; sourceTree = ""; }; 19C7AFCD2B02410F003B35F2 /* AuthManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthManager.swift; sourceTree = ""; }; @@ -750,7 +748,6 @@ 19AE481D2B29D02700DD4612 /* EditProfile */ = { isa = PBXGroup; children = ( - 19AE481E2B29D03D00DD4612 /* EditProfileViewControllerTests.swift */, 19AE481F2B29D03D00DD4612 /* EditProfileInteractorTests.swift */, 19AE48212B29D03D00DD4612 /* EditProfilePresenterTests.swift */, ); @@ -1523,7 +1520,6 @@ 19AE48172B28C2B700DD4612 /* SettingViewControllerTests.swift in Sources */, 194C21C32B1DEE6B00C62645 /* HomeViewControllerTests.swift in Sources */, 192513692B26F7CE001533FA /* TagPlayListInteractorTests.swift in Sources */, - 19AE48222B29D03D00DD4612 /* EditProfileViewControllerTests.swift in Sources */, 19AE48232B29D03D00DD4612 /* EditProfileInteractorTests.swift in Sources */, 194C21CC2B1DF39200C62645 /* MockHomeWorker.swift in Sources */, ); diff --git a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift index ad65887..f409a9f 100644 --- a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift +++ b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift @@ -76,6 +76,12 @@ final class EditProfileInteractorTests: XCTestCase { } } + final class UserWorkerMock: UserWorker { + override func checkNotDuplication(for userName: String) async -> Bool? { + return false + } + } + // MARK: - Tests func test_setProfile을_실행하면_presenter의_presentProfile이_호출되고_자신의_데이터를_presenter에게_전달한다() { @@ -281,7 +287,6 @@ final class EditProfileInteractorTests: XCTestCase { } func test_checkDuplication을_실행했을때_중복된_닉네임이_아니라면_presenter의_presentNicknameDuplication을_호출하고_올바른_값을_전달한다() async { - // arrange let spy = EditProfilePresentationLogicSpy() sut.presenter = spy @@ -298,5 +303,23 @@ final class EditProfileInteractorTests: XCTestCase { "checkDuplication을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") } + func test_checkDuplication을_실행했을때_중복된_닉네임이라면_presenter의_presentNicknameDuplication을_호출하고_올바른_값을_전달한다() async { + + // arrange + let spy = EditProfilePresentationLogicSpy() + sut.presenter = spy + sut.userWorker = UserWorkerMock() + + // act + await sut.checkDuplication(with: Models.CheckNicknameDuplication.Request(nickname: "안유진")) + + // assert + XCTAssertTrue(spy.presentNicknameDuplicationCalled, "checkDuplication을 호출해서 presenter의 presentNicknameDuplication을 호출하지 못했다.") + XCTAssertFalse(spy.presentNicknameDuplicationResponse.isValid, + "checkDuplication을 호출해서 presenter에게 올바른 isValid값을 전달하지 못했다.") + + XCTAssertFalse(spy.presentNicknameDuplicationResponse.canEditProfile, + "checkDuplication을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.")} + // TODO: editProfile 테스트 메서드는 내부 병렬실행 이슈 해결 후 작성 } diff --git a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift deleted file mode 100644 index 5e3d3b4..0000000 --- a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileViewControllerTests.swift +++ /dev/null @@ -1,84 +0,0 @@ -//// -//// EditProfileViewControllerTests.swift -//// Layover -//// -//// Created by 김인환 on 12/13/23. -//// Copyright (c) 2023 CodeBomber. All rights reserved. -//// -//// This file was generated by the Clean Swift Xcode Templates so -//// you can apply clean architecture to your iOS and Mac projects, -//// see http://clean-swift.com -//// -// -//@testable import Layover -//import XCTest -// -//class EditProfileViewControllerTests: XCTestCase { -// // MARK: Subject under test -// -// var sut: EditProfileViewController! -// var window: UIWindow! -// -// // MARK: - Test lifecycle -// -// override func setUp() { -// super.setUp() -// window = UIWindow() -// setupEditProfileViewController() -// } -// -// override func tearDown() { -// window = nil -// super.tearDown() -// } -// -// // MARK: - Test setup -// -// func setupEditProfileViewController() { -// let bundle = Bundle.main -// let storyboard = UIStoryboard(name: "Main", bundle: bundle) -// sut = storyboard.instantiateViewController(withIdentifier: "EditProfileViewController") as! EditProfileViewController -// } -// -// func loadView() { -// window.addSubview(sut.view) -// RunLoop.current.run(until: Date()) -// } -// -// // MARK: - Test doubles -// -// class EditProfileBusinessLogicSpy: EditProfileBusinessLogic { -// var doSomethingCalled = false -// -// func doSomething(request: EditProfile.Something.Request) -// { -// doSomethingCalled = true -// } -// } -// -// // MARK: - Tests -// -// func testShouldDoSomethingWhenViewIsLoaded() { -// // Given -// let spy = EditProfileBusinessLogicSpy() -// sut.interactor = spy -// -// // When -// loadView() -// -// // Then -// XCTAssertTrue(spy.doSomethingCalled, "viewDidLoad() should ask the interactor to do something") -// } -// -// func testDisplaySomething() { -// // Given -// let viewModel = EditProfile.Something.ViewModel() -// -// // When -// loadView() -// sut.displaySomething(viewModel: viewModel) -// -// // Then -// //XCTAssertEqual(sut.nameTextField.text, "", "displaySomething(viewModel:) should update the name text field") -// } -//} From 68c2a41212114bb3f41bd7a5db5139a1f8dc85fb Mon Sep 17 00:00:00 2001 From: loinsir Date: Thu, 14 Dec 2023 00:02:29 +0900 Subject: [PATCH 4/4] =?UTF-8?q?:wrench:=20=EB=B6=88=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=A4=84=EB=B0=94=EA=BF=88=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditProfileInteractorTests.swift | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift index f409a9f..7af3360 100644 --- a/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift +++ b/iOS/Layover/LayoverTests/Scenes/EditProfile/EditProfileInteractorTests.swift @@ -179,11 +179,8 @@ final class EditProfileInteractorTests: XCTestCase { // assert XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .lessThan2GreaterThan8, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") - XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") - XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "presenter에게 올바른 introduceAlertDescription을 전달하지 못했다.") - XCTAssertFalse(spy.presentProfileStateResponse.canCheckNicknameDuplication!, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") } @@ -216,11 +213,8 @@ final class EditProfileInteractorTests: XCTestCase { // assert XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") - XCTAssertTrue(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") - XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") - XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") } @@ -237,12 +231,8 @@ final class EditProfileInteractorTests: XCTestCase { XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") XCTAssertEqual(spy.presentProfileStateResponse.introduceAlertDescription, Models.ChangeProfile.IntroduceLengthState.overLength.description,"changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") - XCTAssertFalse(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") - - XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") - XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") } @@ -260,9 +250,7 @@ final class EditProfileInteractorTests: XCTestCase { XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") XCTAssertTrue(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") - XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") - XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") } @@ -278,11 +266,8 @@ final class EditProfileInteractorTests: XCTestCase { // assert XCTAssertTrue(spy.presentProfileStateCalled, "changeProfile을 호출해서 presenter의 presentProfileState를 호출하지 못했다.") XCTAssertNil(spy.presentProfileStateResponse.introduceAlertDescription, "changeProfile을 호출해서 presenter에게 introduceAlertDescription이 Nil로 전달하지 못했다.") - XCTAssertTrue(spy.presentProfileStateResponse.canEditProfile, "changeProfile을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") - XCTAssertNil(spy.presentProfileStateResponse.canCheckNicknameDuplication, "changeProfile을 호출해서 presenter에게 올바른 canCheckNicknameDuplication을 전달하지 못했다.") - XCTAssertEqual(spy.presentProfileStateResponse.nicknameState, .valid, "changeProfile을 호출해서 presenter에게 올바른 nickname의 nicknameState를 전달하지 못했다.") } @@ -298,7 +283,6 @@ final class EditProfileInteractorTests: XCTestCase { XCTAssertTrue(spy.presentNicknameDuplicationCalled, "checkDuplication을 호출해서 presenter의 presentNicknameDuplication을 호출하지 못했다.") XCTAssertTrue(spy.presentNicknameDuplicationResponse.isValid, "checkDuplication을 호출해서 presenter에게 올바른 isValid값을 전달하지 못했다.") - XCTAssertTrue(spy.presentNicknameDuplicationResponse.canEditProfile, "checkDuplication을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.") } @@ -317,7 +301,6 @@ final class EditProfileInteractorTests: XCTestCase { XCTAssertTrue(spy.presentNicknameDuplicationCalled, "checkDuplication을 호출해서 presenter의 presentNicknameDuplication을 호출하지 못했다.") XCTAssertFalse(spy.presentNicknameDuplicationResponse.isValid, "checkDuplication을 호출해서 presenter에게 올바른 isValid값을 전달하지 못했다.") - XCTAssertFalse(spy.presentNicknameDuplicationResponse.canEditProfile, "checkDuplication을 호출해서 presenter에게 올바른 canEditProfile값을 전달하지 못했다.")}