Skip to content

Feature/ios 23 api improvments #4

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

Merged
merged 11 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Authorization/Authorization.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
022D04962976DA6500E0059B /* AuthorizationMock.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022D04952976DA6500E0059B /* AuthorizationMock.generated.swift */; };
025F40E029D1E2FC0064C183 /* ResetPasswordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 025F40DF29D1E2FC0064C183 /* ResetPasswordView.swift */; };
025F40E229D360E20064C183 /* ResetPasswordViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 025F40E129D360E20064C183 /* ResetPasswordViewModel.swift */; };
02E0618429DC2373006E9024 /* ResetPasswordViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02E0618329DC2373006E9024 /* ResetPasswordViewModelTests.swift */; };
02F3BFE5292533720051930C /* AuthorizationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02F3BFE4292533720051930C /* AuthorizationRouter.swift */; };
071009C728D1DA4F00344290 /* SignInViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 071009C628D1DA4F00344290 /* SignInViewModel.swift */; };
07169458296D913400E3DED6 /* Authorization.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0770DE3B28D0A319006D8A5D /* Authorization.framework */; platformFilter = ios; };
Expand Down Expand Up @@ -45,6 +46,7 @@
022D04952976DA6500E0059B /* AuthorizationMock.generated.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthorizationMock.generated.swift; sourceTree = "<group>"; };
025F40DF29D1E2FC0064C183 /* ResetPasswordView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetPasswordView.swift; sourceTree = "<group>"; };
025F40E129D360E20064C183 /* ResetPasswordViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetPasswordViewModel.swift; sourceTree = "<group>"; };
02E0618329DC2373006E9024 /* ResetPasswordViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetPasswordViewModelTests.swift; sourceTree = "<group>"; };
02ED50CC29A64B90008341CD /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
02F3BFE4292533720051930C /* AuthorizationRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthorizationRouter.swift; sourceTree = "<group>"; };
071009C628D1DA4F00344290 /* SignInViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignInViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -170,6 +172,7 @@
07169484296EC3D700E3DED6 /* Login */ = {
isa = PBXGroup;
children = (
02E0618329DC2373006E9024 /* ResetPasswordViewModelTests.swift */,
07169463296D96DD00E3DED6 /* SignInViewModelTests.swift */,
);
path = Login;
Expand Down Expand Up @@ -445,6 +448,7 @@
022D04962976DA6500E0059B /* AuthorizationMock.generated.swift in Sources */,
022D0482297442BA00E0059B /* SignUpViewModelTests.swift in Sources */,
07169464296D96DD00E3DED6 /* SignInViewModelTests.swift in Sources */,
02E0618429DC2373006E9024 /* ResetPasswordViewModelTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
50 changes: 40 additions & 10 deletions Authorization/AuthorizationTests/AuthorizationMock.generated.swift

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
//
// ResetPasswordViewModelTests.swift
// AuthorizationTests
//
// Created by  Stepanok Ivan on 04.04.2023.
//

import SwiftyMocky
import XCTest
@testable import Core
@testable import Authorization
import Alamofire
import SwiftUI

final class ResetPasswordViewModelTests: XCTestCase {

func testResetPasswordValidationEmailError() async throws {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let viewModel = ResetPasswordViewModel(interactor: interactor, router: router, validator: validator)

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "e", isRecovered: binding)

Verify(interactor, 0, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, AuthLocalization.Error.invalidEmailAddress)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

func testResetPasswordSuccess() async throws {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let viewModel = ResetPasswordViewModel(interactor: interactor, router: router, validator: validator)

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

let data = ResetPassword(success: true, responseText: "Success")
Given(interactor, .resetPassword(email: .any, willReturn: data))

await viewModel.resetPassword(email: "[email protected]", isRecovered: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertFalse(isRecoveryPassword)
XCTAssertEqual(viewModel.errorMessage, nil)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, false)
}

func testResetPasswordErrorValidation() async throws {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let viewModel = ResetPasswordViewModel(interactor: interactor, router: router, validator: validator)

let validationErrorMessage = "Some error"
let validationError = CustomValidationError(statusCode: 400, data: ["value": validationErrorMessage])
let error = AFError.responseValidationFailed(reason: AFError.ResponseValidationFailureReason.customValidationFailed(error: validationError))

Given(interactor, .resetPassword(email: .any, willThrow: error))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecovered: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, validationErrorMessage)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

func testResetPasswordErrorInvalidGrant() async throws {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let viewModel = ResetPasswordViewModel(interactor: interactor, router: router, validator: validator)

Given(interactor, .resetPassword(email: .any, willThrow: APIError.invalidGrant))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecovered: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.invalidCredentials)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

func testResetPasswordErrorUnknown() async throws {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let viewModel = ResetPasswordViewModel(interactor: interactor, router: router, validator: validator)

Given(interactor, .resetPassword(email: .any, willThrow: NSError()))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecovered: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.unknownError)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

func testResetPasswordNoInternetError() async throws {
let interactor = AuthInteractorProtocolMock()
let router = AuthorizationRouterMock()
let validator = Validator()
let viewModel = ResetPasswordViewModel(interactor: interactor, router: router, validator: validator)

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

Given(interactor, .resetPassword(email: .any, willThrow: noInternetError))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecovered: binding)

Verify(interactor, 1, .resetPassword(email: .any))

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -143,155 +143,5 @@ final class SignInViewModelTests: XCTestCase {
XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.slowOrNoInternetConnection)
XCTAssertEqual(viewModel.isShowProgress, false)
}

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

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "e", isRecoveryPassord: binding)

Verify(interactor, 0, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, AuthLocalization.Error.invalidEmailAddress)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

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

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

let data = ResetPassword(success: true, responseText: "Success")
Given(interactor, .resetPassword(email: .any, willReturn: data))

await viewModel.resetPassword(email: "[email protected]", isRecoveryPassord: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertEqual(viewModel.alertMessage, data.responseText)
XCTAssertEqual(viewModel.errorMessage, nil)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, false)
}

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

let validationErrorMessage = "Some error"
let validationError = CustomValidationError(statusCode: 400, data: ["value": validationErrorMessage])
let error = AFError.responseValidationFailed(reason: AFError.ResponseValidationFailureReason.customValidationFailed(error: validationError))

Given(interactor, .resetPassword(email: .any, willThrow: error))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecoveryPassord: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, validationErrorMessage)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

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

Given(interactor, .resetPassword(email: .any, willThrow: APIError.invalidGrant))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecoveryPassord: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.invalidCredentials)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

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

Given(interactor, .resetPassword(email: .any, willThrow: NSError()))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecoveryPassord: binding)

Verify(interactor, 1, .resetPassword(email: .any))

XCTAssertEqual(viewModel.errorMessage, CoreLocalization.Error.unknownError)
XCTAssertEqual(viewModel.isShowProgress, false)
XCTAssertEqual(isRecoveryPassword, true)
}

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

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

Given(interactor, .resetPassword(email: .any, willThrow: noInternetError))

var isRecoveryPassword = true
let binding = Binding(get: {
return isRecoveryPassword
}, set: { value in
isRecoveryPassword = value
})

await viewModel.resetPassword(email: "[email protected]", isRecoveryPassord: binding)

Verify(interactor, 1, .resetPassword(email: .any))

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

}
4 changes: 4 additions & 0 deletions Core/Core.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
02B2B594295C5C7A00914876 /* Thread.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B2B593295C5C7A00914876 /* Thread.swift */; };
02B3E3B32930198600A50475 /* AVPlayerViewControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B3E3B22930198600A50475 /* AVPlayerViewControllerExtension.swift */; };
02C2DC0829B63D6200F4445D /* WebViewHTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C2DC0729B63D6200F4445D /* WebViewHTML.swift */; };
02C917F029CDA99E00DBB8BD /* Data_Dashboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C917EF29CDA99E00DBB8BD /* Data_Dashboard.swift */; };
02CF46C829546AA200A698EE /* NoCachedDataError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02CF46C729546AA200A698EE /* NoCachedDataError.swift */; };
02D800CC29348F460099CF16 /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02D800CB29348F460099CF16 /* ImagePicker.swift */; };
02E225B0291D29EB0067769A /* UrlExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02E225AF291D29EB0067769A /* UrlExtension.swift */; };
Expand Down Expand Up @@ -187,6 +188,7 @@
02B2B593295C5C7A00914876 /* Thread.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Thread.swift; sourceTree = "<group>"; };
02B3E3B22930198600A50475 /* AVPlayerViewControllerExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerViewControllerExtension.swift; sourceTree = "<group>"; };
02C2DC0729B63D6200F4445D /* WebViewHTML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewHTML.swift; sourceTree = "<group>"; };
02C917EF29CDA99E00DBB8BD /* Data_Dashboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Data_Dashboard.swift; sourceTree = "<group>"; };
02CF46C729546AA200A698EE /* NoCachedDataError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoCachedDataError.swift; sourceTree = "<group>"; };
02D800CB29348F460099CF16 /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = "<group>"; };
02E225AF291D29EB0067769A /* UrlExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UrlExtension.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -388,6 +390,7 @@
0727877628D23847002E9142 /* DataLayer.swift */,
0727878428D31657002E9142 /* Data_User.swift */,
0283347C28D4D3DE00C828FC /* Data_Discovery.swift */,
02C917EF29CDA99E00DBB8BD /* Data_Dashboard.swift */,
027DB33428D8C8FE002B6862 /* Data_MyCourse.swift */,
021D924728DC860C00ACC565 /* Data_UserProfile.swift */,
0259104929C4A5B6004B5A55 /* UserSettings.swift */,
Expand Down Expand Up @@ -773,6 +776,7 @@
027BD3BE2909478B00392132 /* UIResponder+CurrentResponder.swift in Sources */,
070019AE28F701B200D5FC78 /* Certificate.swift in Sources */,
0770DE5F28D0B22C006D8A5D /* Strings.swift in Sources */,
02C917F029CDA99E00DBB8BD /* Data_Dashboard.swift in Sources */,
024FCD0028EF1CD300232339 /* WebBrowser.swift in Sources */,
027BD3B52909475900392132 /* KeyboardStateObserver.swift in Sources */,
0283347D28D4D3DE00C828FC /* Data_Discovery.swift in Sources */,
Expand Down
Loading