diff --git a/AutoCat2.xcodeproj/project.pbxproj b/AutoCat2.xcodeproj/project.pbxproj index 39d9fe5..91a9e80 100644 --- a/AutoCat2.xcodeproj/project.pbxproj +++ b/AutoCat2.xcodeproj/project.pbxproj @@ -35,6 +35,9 @@ 7A40D60826998DCF009B0BC4 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D60726998DCF009B0BC4 /* Alert.swift */; }; 7A40D60926998DCF009B0BC4 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D60726998DCF009B0BC4 /* Alert.swift */; }; 7A40D60C2699A070009B0BC4 /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A40D60B2699A070009B0BC4 /* MockURLProtocol.swift */; }; + 7A503C03269F382F002C1A0D /* login_success.json in Resources */ = {isa = PBXBuildFile; fileRef = 7A503C02269F382F002C1A0D /* login_success.json */; }; + 7A503C05269F494C002C1A0D /* login_invalid_params.json in Resources */ = {isa = PBXBuildFile; fileRef = 7A503C04269F494C002C1A0D /* login_invalid_params.json */; }; + 7A503C07269F49F4002C1A0D /* login_wrong_credentials.json in Resources */ = {isa = PBXBuildFile; fileRef = 7A503C06269F49F4002C1A0D /* login_wrong_credentials.json */; }; 7A683999269612EA00B2188A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A683998269612EA00B2188A /* Response.swift */; }; 7A68399A269612EA00B2188A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A683998269612EA00B2188A /* Response.swift */; }; 7ACD05D72695C08A00557667 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD05D62695C08A00557667 /* Constants.swift */; }; @@ -113,6 +116,9 @@ 7A40D6012694FF5D009B0BC4 /* Api.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Api.swift; sourceTree = ""; }; 7A40D60726998DCF009B0BC4 /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = ""; }; 7A40D60B2699A070009B0BC4 /* MockURLProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockURLProtocol.swift; sourceTree = ""; }; + 7A503C02269F382F002C1A0D /* login_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = login_success.json; sourceTree = ""; }; + 7A503C04269F494C002C1A0D /* login_invalid_params.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = login_invalid_params.json; sourceTree = ""; }; + 7A503C06269F49F4002C1A0D /* login_wrong_credentials.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = login_wrong_credentials.json; sourceTree = ""; }; 7A683998269612EA00B2188A /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = ""; }; 7ACD05D62695C08A00557667 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; 7AEFAEEC26985A3400ED2C85 /* ACProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACProgressView.swift; sourceTree = ""; }; @@ -260,6 +266,7 @@ 7A40D5F42693A63A009B0BC4 /* AutoCat2Tests */ = { isa = PBXGroup; children = ( + 7A503C00269F370A002C1A0D /* Responses */, 7A40D60A2699A04F009B0BC4 /* Mocks */, 7A40D5F52693A63A009B0BC4 /* SettingsTests.swift */, 7AF552D82696E5C100578083 /* ApiTests.swift */, @@ -293,6 +300,24 @@ path = Mocks; sourceTree = ""; }; + 7A503C00269F370A002C1A0D /* Responses */ = { + isa = PBXGroup; + children = ( + 7A503C01269F3797002C1A0D /* Login */, + ); + path = Responses; + sourceTree = ""; + }; + 7A503C01269F3797002C1A0D /* Login */ = { + isa = PBXGroup; + children = ( + 7A503C06269F49F4002C1A0D /* login_wrong_credentials.json */, + 7A503C04269F494C002C1A0D /* login_invalid_params.json */, + 7A503C02269F382F002C1A0D /* login_success.json */, + ); + path = Login; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -473,6 +498,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7A503C07269F49F4002C1A0D /* login_wrong_credentials.json in Resources */, + 7A503C03269F382F002C1A0D /* login_success.json in Resources */, + 7A503C05269F494C002C1A0D /* login_invalid_params.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/AutoCat2Tests/ApiTests.swift b/AutoCat2Tests/ApiTests.swift index 762e4b0..bba9cec 100644 --- a/AutoCat2Tests/ApiTests.swift +++ b/AutoCat2Tests/ApiTests.swift @@ -16,8 +16,21 @@ class ApiTests: XCTestCase { // Put teardown code here. This method is called after the invocation of each test method in the class. } - func testLogin() async throws { + func testLoginSuccess() async throws { + MockURLProtocol.responseType = MockResponseType.loginSuccess let user = try await self.api.login(email: "", password: "") + XCTAssertTrue(!user.token.isEmpty) + } + + func testLoginInvalidParams() async throws { + MockURLProtocol.responseType = MockResponseType.loginWrongCredentials + do { + _ = try await self.api.login(email: "", password: "") + } catch { + return + } + + XCTFail("Exception expected") } // func testPerformanceExample() throws { diff --git a/AutoCat2Tests/Mocks/MockURLProtocol.swift b/AutoCat2Tests/Mocks/MockURLProtocol.swift index 264640f..ef804b5 100644 --- a/AutoCat2Tests/Mocks/MockURLProtocol.swift +++ b/AutoCat2Tests/Mocks/MockURLProtocol.swift @@ -1,44 +1,46 @@ import Foundation +enum MockResponseType: String { + case loginSuccess = "login_success" + case loginWrongCredentials = "login_wrong_credentials" + case +} + class MockURLProtocol: URLProtocol { + + static var responseType: MockResponseType? - override class func canInit(with request: URLRequest) -> Bool { - // To check if this protocol can handle the given request. - return true - } + override class func canInit(with request: URLRequest) -> Bool { + // To check if this protocol can handle the given request. + return true + } - override class func canonicalRequest(for request: URLRequest) -> URLRequest { - // Here you return the canonical version of the request but most of the time you pass the orignal one. - return request - } + override class func canonicalRequest(for request: URLRequest) -> URLRequest { + // Here you return the canonical version of the request but most of the time you pass the orignal one. + return request + } - override func startLoading() { - guard let handler = MockURLProtocol.requestHandler else { - fatalError("Handler is unavailable.") - } + override func startLoading() { - do { - // 2. Call handler with received request and capture the tuple of response and data. - let (response, data) = try handler(request) + guard let respType = MockURLProtocol.responseType else { return } + guard let jsonUrl = Bundle(for: type(of: self)).url(forResource: respType.rawValue, withExtension: "json") else { return } + guard let response = HTTPURLResponse(url: jsonUrl, statusCode: 200, httpVersion: "HTTP/2", headerFields: [:]) else { return } + + let data = try? Data(contentsOf: jsonUrl) - // 3. Send received response to the client. client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) - + if let data = data { - // 4. Send received data to the client. client?.urlProtocol(self, didLoad: data) } - - // 5. Notify request has been finished. - client?.urlProtocolDidFinishLoading(self) - } catch { - // 6. Notify received error. - client?.urlProtocol(self, didFailWithError: error) - } - } - override func stopLoading() { + client?.urlProtocolDidFinishLoading(self) + + //client?.urlProtocol(self, didFailWithError: error) + } + + override func stopLoading() { // This is called if the request gets canceled or completed. print("") - } + } } diff --git a/AutoCat2Tests/Responses/Login/login_invalid_params.json b/AutoCat2Tests/Responses/Login/login_invalid_params.json new file mode 100644 index 0000000..fe5461a --- /dev/null +++ b/AutoCat2Tests/Responses/Login/login_invalid_params.json @@ -0,0 +1,4 @@ +{ + "success": false, + "error": "Invalid parameters" +} diff --git a/AutoCat2Tests/Responses/Login/login_success.json b/AutoCat2Tests/Responses/Login/login_success.json new file mode 100644 index 0000000..60c13de --- /dev/null +++ b/AutoCat2Tests/Responses/Login/login_success.json @@ -0,0 +1,8 @@ +{ + "success": true, + "data": { + "_id": "832c1bd4-5caa-4c9d-b24c-4c000cd8a793", + "email": "selim@fastmail.fm", + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InNlbGltQGZhc3RtYWlsLmZtIiwiaWF0IjoxNjI2MjgwNDgxLCJleHAiOjE2NTc4MTY0ODF9.eU6wpacgCSnhM4EiyMY2lUptsfSfHz9guuvOsAw4X90" + } +} diff --git a/AutoCat2Tests/Responses/Login/login_wrong_credentials.json b/AutoCat2Tests/Responses/Login/login_wrong_credentials.json new file mode 100644 index 0000000..01044e5 --- /dev/null +++ b/AutoCat2Tests/Responses/Login/login_wrong_credentials.json @@ -0,0 +1,4 @@ +{ + "success": false, + "error": "Incorrect email or password" +} diff --git a/Shared/Views/AuthView.swift b/Shared/Views/AuthView.swift index 942adbd..5db7bc3 100644 --- a/Shared/Views/AuthView.swift +++ b/Shared/Views/AuthView.swift @@ -26,9 +26,7 @@ struct AuthView: View { } } } - .alert(item: $alert) { id in - Alert(id) - } + .alert(item: $alert, content: Alert.init) Spacer() } .buttonStyle(.bordered)