Skip to content

Commit

Permalink
Remove custom navigation controller (#63)
Browse files Browse the repository at this point in the history
* Remove custom navigation controller
Change navigation controller from custom to system for feature changes and adding possibility to swipe gestures
  • Loading branch information
IvanStepanok authored Aug 21, 2023
1 parent 8d45fc5 commit 5cc6e14
Show file tree
Hide file tree
Showing 45 changed files with 1,720 additions and 1,431 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ public struct SignInView: View {

HStack {
Button(AuthLocalization.SignIn.registerBtn) {
viewModel.analytics.signUpClicked()
viewModel.trackSignUpClicked()
viewModel.router.showRegisterScreen()
}.foregroundColor(Theme.Colors.accentColor)

Spacer()

Button(AuthLocalization.SignIn.forgotPassBtn) {
viewModel.analytics.forgotPasswordClicked()
viewModel.trackForgotPasswordClicked()
viewModel.router.showForgotPasswordScreen()
}.foregroundColor(Theme.Colors.accentColor)
}
Expand Down Expand Up @@ -149,6 +149,9 @@ public struct SignInView: View {
}
}
}
.hideNavigationBar()
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
.background(Theme.Colors.background.ignoresSafeArea(.all))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,24 @@ public class SignInViewModel: ObservableObject {
}
}

private let interactor: AuthInteractorProtocol
let router: AuthorizationRouter
let analytics: AuthorizationAnalytics

private let interactor: AuthInteractorProtocol
private let analytics: AuthorizationAnalytics
private let validator: Validator

public init(interactor: AuthInteractorProtocol,
router: AuthorizationRouter,
analytics: AuthorizationAnalytics,
validator: Validator) {
public init(
interactor: AuthInteractorProtocol,
router: AuthorizationRouter,
analytics: AuthorizationAnalytics,
validator: Validator
) {
self.interactor = interactor
self.router = router
self.analytics = analytics
self.validator = validator
}

@MainActor
func login(username: String, password: String) async {
guard validator.isValidEmail(username) else {
Expand Down Expand Up @@ -76,4 +79,12 @@ public class SignInViewModel: ObservableObject {
}
}
}

func trackSignUpClicked() {
analytics.signUpClicked()
}

func trackForgotPasswordClicked() {
analytics.forgotPasswordClicked()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SignUpView.swift
// Authorization
//
// Created by  Stepanok Ivan on 24.10.2022.
// Created by Stepanok Ivan on 24.10.2022.
//

import SwiftUI
Expand Down Expand Up @@ -48,7 +48,6 @@ public struct SignUpView: View {
}.frame(minWidth: 0,
maxWidth: .infinity,
alignment: .topLeading)
.frameLimit()
}

GeometryReader { proxy in
Expand Down Expand Up @@ -96,9 +95,9 @@ public struct SignUpView: View {
} else {
StyledButton(AuthLocalization.SignUp.createAccountBtn) {
Task {
viewModel.analytics.createAccountClicked()
await viewModel.registerUser()
}
viewModel.trackCreateAccountClicked()
}
.padding(.top, 40)
.padding(.bottom, 80)
Expand Down Expand Up @@ -137,6 +136,7 @@ public struct SignUpView: View {
}
}
.background(Theme.Colors.background.ignoresSafeArea(.all))
.hideNavigationBar()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ public class SignUpViewModel: ObservableObject {
@Published var fields: [FieldConfiguration] = []

let router: AuthorizationRouter
let analytics: AuthorizationAnalytics
let config: Config
let cssInjector: CSSInjector

private let interactor: AuthInteractorProtocol
private let analytics: AuthorizationAnalytics
private let validator: Validator

public init(
Expand Down Expand Up @@ -106,4 +106,8 @@ public class SignUpViewModel: ObservableObject {
}
}
}

func trackCreateAccountClicked() {
analytics.createAccountClicked()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// ResetPasswordView.swift
// Authorization
//
// Created by  Stepanok Ivan on 27.03.2023.
// Created by Stepanok Ivan on 27.03.2023.
//

import SwiftUI
Expand Down Expand Up @@ -150,6 +150,7 @@ public struct ResetPasswordView: View {
}
}
.background(Theme.Colors.background.ignoresSafeArea(.all))
.hideNavigationBar()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,26 @@ import Alamofire
import SwiftUI

final class SignInViewModelTests: XCTestCase {

override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

func testLoginValidationEmailError() async throws {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(interactor: interactor,
router: router,
analytics: analytics,
validator: validator)
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)

await viewModel.login(username: "email", password: "")

Expand All @@ -46,10 +48,12 @@ final class SignInViewModelTests: XCTestCase {
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(interactor: interactor,
router: router,
analytics: analytics,
validator: validator)
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)
await viewModel.login(username: "[email protected]", password: "")

Verify(interactor, 0, .login(username: .any, password: .any))
Expand All @@ -64,10 +68,12 @@ final class SignInViewModelTests: XCTestCase {
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(interactor: interactor,
router: router,
analytics: analytics,
validator: validator)
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)
let user = User(id: 1, username: "username", email: "[email protected]", name: "Name", userAvatar: "")

Given(interactor, .login(username: .any, password: .any, willReturn: user))
Expand All @@ -87,10 +93,12 @@ final class SignInViewModelTests: XCTestCase {
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(interactor: interactor,
router: router,
analytics: analytics,
validator: validator)
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)

let validationErrorMessage = "Some error"
let validationError = CustomValidationError(statusCode: 400, data: ["error_description": validationErrorMessage])
Expand All @@ -112,10 +120,12 @@ final class SignInViewModelTests: XCTestCase {
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(interactor: interactor,
router: router,
analytics: analytics,
validator: validator)
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)

Given(interactor, .login(username: .any, password: .any, willThrow: APIError.invalidGrant))

Expand All @@ -133,18 +143,20 @@ final class SignInViewModelTests: XCTestCase {
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(interactor: interactor,
router: router,
analytics: analytics,
validator: validator)
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)

Given(interactor, .login(username: .any, password: .any, willThrow: NSError()))

await viewModel.login(username: "[email protected]", password: "password123")

Verify(interactor, 1, .login(username: .any, password: .any))
Verify(router, 0, .showMainScreen())

XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.unknownError)
XCTAssertEqual(viewModel.isShowProgress, false)
}
Expand All @@ -154,22 +166,58 @@ final class SignInViewModelTests: XCTestCase {
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(interactor: interactor,
router: router,
analytics: analytics,
validator: validator)
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)

let noInternetError = AFError.sessionInvalidated(error: URLError(.notConnectedToInternet))

Given(interactor, .login(username: .any, password: .any, willThrow: noInternetError))

await viewModel.login(username: "[email protected]", password: "password123")

Verify(interactor, 1, .login(username: .any, password: .any))
Verify(router, 0, .showMainScreen())

XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.slowOrNoInternetConnection)
XCTAssertEqual(viewModel.isShowProgress, false)
}


func testTrackSignUpClicked() {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)

viewModel.trackSignUpClicked()

Verify(analytics, 1, .signUpClicked())
}

func testTrackForgotPasswordClicked() {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let analytics = AuthorizationAnalyticsMock()
let viewModel = SignInViewModel(
interactor: interactor,
router: router,
analytics: analytics,
validator: validator
)

viewModel.trackForgotPasswordClicked()

Verify(analytics, 1, .forgotPasswordClicked())
}

}
Loading

0 comments on commit 5cc6e14

Please sign in to comment.