Skip to content

Commit

Permalink
Merge pull request #61 from Team-Ampersand/59-current-user-role-use-case
Browse files Browse the repository at this point in the history
🔀 :: 현재 유저의 권한 가져오는 도메인 로직 추가
  • Loading branch information
baekteun authored Jul 4, 2023
2 parents 496ff95 + 9ec6665 commit b78772a
Show file tree
Hide file tree
Showing 22 changed files with 291 additions and 18 deletions.
4 changes: 3 additions & 1 deletion Projects/App/Sources/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import SigninFeature
import SignupFeature
import Swinject
import UIKit
import UserDomain

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand All @@ -37,7 +38,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
SignupAssembly(),
RenewalPasswordAssembly(),
RootAssembly(),
AuthDomainAssembly()
AuthDomainAssembly(),
UserDomainAssembly()
], container: AppDelegate.container)
IQKeyboardManager.shared.enable = true
IQKeyboardManager.shared.enableAutoToolbar = true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

public protocol LocalUserDataSource {
func loadCurrentUserRole() throws -> UserRoleType
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Foundation

public enum UserDomainError: Error {
// MARK: LoadCurrentUserRole
case cannotFindUserRole
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

public protocol UserRepository {
func loadCurrentUserRole() throws -> UserRoleType
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Foundation

public protocol LoadCurrentUserRoleUseCase {
func callAsFunction() throws -> UserRoleType
}
7 changes: 5 additions & 2 deletions Projects/Domain/UserDomain/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ let project = Project.module(
.interface(module: .domain(.UserDomain)),
.implements(module: .domain(.UserDomain), dependencies: [
.domain(target: .UserDomain, type: .interface),
.domain(target: .BaseDomain)
.domain(target: .BaseDomain),
.core(target: .KeyValueStore, type: .interface)
]),
.testing(module: .domain(.UserDomain), dependencies: [
.domain(target: .UserDomain, type: .interface)
]),
.tests(module: .domain(.UserDomain), dependencies: [
.domain(target: .UserDomain)
.domain(target: .UserDomain),
.domain(target: .UserDomain, type: .testing),
.core(target: .KeyValueStore, type: .testing)
])
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import KeyValueStoreInterface
import Swinject
import UserDomainInterface

public final class UserDomainAssembly: Assembly {
public init() {}
public func assemble(container: Container) {
container.register(LocalUserDataSource.self) { resolver in
LocalUserDataSourceImpl(keyValueStore: resolver.resolve(KeyValueStore.self)!)
}
.inObjectScope(.container)

container.register(UserRepository.self) { resolver in
UserRepositoryImpl(localUserDataSource: resolver.resolve(LocalUserDataSource.self)!)
}
.inObjectScope(.container)

container.register(LoadCurrentUserRoleUseCase.self) { resolver in
LoadCurrentUserRoleUseCaseImpl(userRepository: resolver.resolve(UserRepository.self)!)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Foundation
import KeyValueStoreInterface
import UserDomainInterface

final class LocalUserDataSourceImpl: LocalUserDataSource {
private let keyValueStore: any KeyValueStore

init(keyValueStore: any KeyValueStore) {
self.keyValueStore = keyValueStore
}

func loadCurrentUserRole() throws -> UserRoleType {
guard let userRoleString = keyValueStore.load(key: .userRole) as? String,
let userRole = UserRoleType(rawValue: userRoleString)
else {
throw UserDomainError.cannotFindUserRole
}
return userRole
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Foundation
import Localization
import UserDomainInterface

extension UserDomainError: LocalizedError {
public var errorDescription: String? {
switch self {
case .cannotFindUserRole:
return "Cannot find user role"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import UserDomainInterface

final class UserRepositoryImpl: UserRepository {
private let localUserDataSource: any LocalUserDataSource

init(localUserDataSource: any LocalUserDataSource) {
self.localUserDataSource = localUserDataSource
}

func loadCurrentUserRole() throws -> UserRoleType {
try localUserDataSource.loadCurrentUserRole()
}
}
1 change: 0 additions & 1 deletion Projects/Domain/UserDomain/Sources/Source.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Foundation
import UserDomainInterface

struct LoadCurrentUserRoleUseCaseImpl: LoadCurrentUserRoleUseCase {
private let userRepository: any UserRepository

init(userRepository: any UserRepository){
self.userRepository = userRepository
}

func callAsFunction() throws -> UserRoleType {
try userRepository.loadCurrentUserRole()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation
import UserDomainInterface

final class LocalUserDataSourceSpy: LocalUserDataSource {
var loadCurrentUserRoleCallCount = 0
var loadCurrentUserRoleReturn: UserRoleType = .member
func loadCurrentUserRole() throws -> UserRoleType {
loadCurrentUserRoleCallCount += 1
return loadCurrentUserRoleReturn
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation
import UserDomainInterface

final class UserRepositorySpy: UserRepository {
var loadCurrentUserRoleCallCount = 0
var loadCurrentUserRoleReturn: UserRoleType = .member
func loadCurrentUserRole() throws -> UserRoleType {
loadCurrentUserRoleCallCount += 1
return loadCurrentUserRoleReturn
}
}
1 change: 0 additions & 1 deletion Projects/Domain/UserDomain/Testing/Testing.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import UserDomainInterface

final class LoadCurrentUserRoleUseCaseSpy: LoadCurrentUserRoleUseCase {
var loadCurrentUserRoleCallCount = 0
var loadCurrentUserRoleReturn: UserRoleType = .member
func callAsFunction() throws -> UserRoleType {
loadCurrentUserRoleCallCount += 1
return loadCurrentUserRoleReturn
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import XCTest
@testable import UserDomainTesting
@testable import UserDomain

class LoadCurrentUserRoleUseCaseTests: XCTestCase {
var loadCurrentUserRoleUseCase: LoadCurrentUserRoleUseCaseImpl!
var userRepositorySpy: UserRepositorySpy!

override func setUp() {
super.setUp()
userRepositorySpy = UserRepositorySpy()
loadCurrentUserRoleUseCase = LoadCurrentUserRoleUseCaseImpl(userRepository: userRepositorySpy)
}

override func tearDown() {
loadCurrentUserRoleUseCase = nil
userRepositorySpy = nil
super.tearDown()
}

func testCallAsFunction() {
// Given
userRepositorySpy.loadCurrentUserRoleReturn = .member

// When
do {
let currentUserRole = try loadCurrentUserRoleUseCase()

// Then
XCTAssertEqual(
userRepositorySpy.loadCurrentUserRoleCallCount,
1,
"loadCurrentUserRole should be called once"
)
XCTAssertEqual(
currentUserRole,
.member,
"The returned currentUserRole should be .admin"
)
} catch {
XCTFail("Unexpected error thrown: \(error)")
}
}
}
58 changes: 58 additions & 0 deletions Projects/Domain/UserDomain/Tests/LocalUserDataSourceTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import UserDomainInterface
import XCTest
@testable import UserDomainTesting
@testable import UserDomain
@testable import KeyValueStoreTesting

final class LocalUserDataSourceTests: XCTestCase {
var localUserDataSource: LocalUserDataSourceImpl!
var keyValueStoreFake: DictionaryKeyValueStore!

override func setUp() {
super.setUp()
keyValueStoreFake = DictionaryKeyValueStore()
localUserDataSource = LocalUserDataSourceImpl(keyValueStore: keyValueStoreFake)
}

override func tearDown() {
localUserDataSource = nil
keyValueStoreFake = nil
super.tearDown()
}

func testLoadCurrentUserRole_Success() {
// Given
keyValueStoreFake.save(key: .userRole, value: UserRoleType.member.rawValue)

// When
do {
let currentUserRole = try localUserDataSource.loadCurrentUserRole()

// Then
XCTAssertEqual(
currentUserRole,
.member,
"The returned currentUserRole should be .admin"
)
} catch {
XCTFail("Unexpected error thrown: \(error)")
}
}

func testLoadCurrentUserRole_ThrowsError() {
// When
do {
_ = try localUserDataSource.loadCurrentUserRole()

// Then
XCTFail("Expected error UserDomainError.cannotFindUserRole not thrown")
} catch {
// Then
XCTAssertEqual(
error as? UserDomainError,
UserDomainError.cannotFindUserRole,
"Unexpected error type"
)
}
}
}
11 changes: 0 additions & 11 deletions Projects/Domain/UserDomain/Tests/UserDomainTest.swift

This file was deleted.

44 changes: 44 additions & 0 deletions Projects/Domain/UserDomain/Tests/UserRepositoryTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import XCTest
@testable import UserDomainTesting
@testable import UserDomain

final class UserRepositoryTests: XCTestCase {
var userRepository: UserRepositoryImpl!
var localUserDataSourceSpy: LocalUserDataSourceSpy!

override func setUp() {
super.setUp()
localUserDataSourceSpy = LocalUserDataSourceSpy()
userRepository = UserRepositoryImpl(localUserDataSource: localUserDataSourceSpy)
}

override func tearDown() {
userRepository = nil
localUserDataSourceSpy = nil
super.tearDown()
}

func testLoadCurrentUserRole() {
// Given
localUserDataSourceSpy.loadCurrentUserRoleReturn = .member

// When
do {
let currentUserRole = try userRepository.loadCurrentUserRole()

// Then
XCTAssertEqual(
localUserDataSourceSpy.loadCurrentUserRoleCallCount,
1,
"loadCurrentUserRole should be called once"
)
XCTAssertEqual(
currentUserRole,
.member,
"The returned currentUserRole should be .member"
)
} catch {
XCTFail("Unexpected error thrown: \(error)")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ public final class DotoriCheckBox: UIControl {
setup()
}

//MARK: - handle touches
// MARK: - handle touches
public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
sendActions(for: .valueChanged)
isChecked.toggle()
}

//MARK: - Increase hit area
// MARK: - Increase hit area
public override func point(
inside point: CGPoint,
with event: UIEvent?
Expand Down

0 comments on commit b78772a

Please sign in to comment.