Skip to content

Commit

Permalink
Add signup API
Browse files Browse the repository at this point in the history
  • Loading branch information
mederic committed Aug 22, 2018
1 parent 381a5ae commit 1321611
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 8 deletions.
8 changes: 8 additions & 0 deletions OmiseGO.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@
0379E81D21184BC900E65D4F /* Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379E7E421184BC800E65D4F /* Codable.swift */; };
0379E82021184CE000E65D4F /* Credential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379E81F21184CE000E65D4F /* Credential.swift */; };
0379E82221184CE900E65D4F /* CredentialEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0379E82121184CE900E65D4F /* CredentialEncoder.swift */; };
0380AAE9212D2D78006B2193 /* SignupParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0380AAE8212D2D78006B2193 /* SignupParams.swift */; };
0380AAEB212D311B006B2193 /* SignupFixtureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0380AAEA212D311B006B2193 /* SignupFixtureTests.swift */; };
03BCCCB31F8B311600F604DB /* OmiseGO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03BCCCA91F8B311600F604DB /* OmiseGO.framework */; };
03E565B3211AC87500BC9124 /* SocketClient+Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E565B2211AC87500BC9124 /* SocketClient+Client.swift */; };
03E565B5211AFBB100BC9124 /* QRScannerViewController+Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E565B4211AFBB100BC9124 /* QRScannerViewController+Client.swift */; };
Expand Down Expand Up @@ -325,6 +327,8 @@
0379E82121184CE900E65D4F /* CredentialEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialEncoder.swift; sourceTree = "<group>"; };
0379E82B2118527C00E65D4F /* OmiseGO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OmiseGO.h; sourceTree = "<group>"; };
0379E82C2118527C00E65D4F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0380AAE8212D2D78006B2193 /* SignupParams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignupParams.swift; sourceTree = "<group>"; };
0380AAEA212D311B006B2193 /* SignupFixtureTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignupFixtureTests.swift; sourceTree = "<group>"; };
03BCCCA91F8B311600F604DB /* OmiseGO.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OmiseGO.framework; sourceTree = BUILT_PRODUCTS_DIR; };
03BCCCB21F8B311600F604DB /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
03E565B2211AC87500BC9124 /* SocketClient+Client.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SocketClient+Client.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -373,6 +377,7 @@
0320EAB72119499B0006685C /* TransactionConsumption+Client.swift */,
0320EAB82119499B0006685C /* Wallet+Client.swift */,
0320EAB92119499B0006685C /* TransactionRequest+Client.swift */,
0380AAE8212D2D78006B2193 /* SignupParams.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -565,6 +570,7 @@
032CEDC1211D3D5300E44445 /* SettingFixtureTests.swift */,
032CEDC2211D3D5300E44445 /* RequestFixtureTest.swift */,
03F2D4FF212436BB00BC65BB /* LoginFixtureTests.swift */,
0380AAEA212D311B006B2193 /* SignupFixtureTests.swift */,
);
path = FixtureTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -1017,6 +1023,7 @@
0379E81D21184BC900E65D4F /* Codable.swift in Sources */,
0379E80A21184BC900E65D4F /* Listenable.swift in Sources */,
0379E81621184BC900E65D4F /* HTTPTask.swift in Sources */,
0380AAE9212D2D78006B2193 /* SignupParams.swift in Sources */,
0379E7EB21184BC900E65D4F /* SocketDispatcher.swift in Sources */,
03E565B7211AFF9A00BC9124 /* HTTPAdminAPI.swift in Sources */,
0379E80921184BC900E65D4F /* Retrievable.swift in Sources */,
Expand Down Expand Up @@ -1147,6 +1154,7 @@
032CEDF6211D3D5300E44445 /* UserTests.swift in Sources */,
032CEDCF211D3D5300E44445 /* QRGeneratorTests.swift in Sources */,
03210BA321267AF400B56295 /* FixtureClientAPI.swift in Sources */,
0380AAEB212D311B006B2193 /* SignupFixtureTests.swift in Sources */,
032CEE27211D3D5300E44445 /* APIClientEndpointTest.swift in Sources */,
032CEDDF211D3D5300E44445 /* CredentialEncoderTests.swift in Sources */,
032CEDCD211D3D5300E44445 /* ToolsTests.swift in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions Source/Client/API/APIClientEndpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum APIClientEndpoint: APIEndpoint {
case transactionRequestConsume(params: TransactionConsumptionParams)
case transactionConsumptionApprove(params: TransactionConsumptionConfirmationParams)
case transactionConsumptionReject(params: TransactionConsumptionConfirmationParams)
case signup(params: SignupParams)
case login(params: LoginParams)
case logout

Expand All @@ -43,6 +44,8 @@ enum APIClientEndpoint: APIEndpoint {
return "/me.approve_transaction_consumption"
case .transactionConsumptionReject:
return "/me.reject_transaction_consumption"
case .signup:
return "user.signup"
case .login:
return "user.login"
case .logout:
Expand All @@ -66,6 +69,8 @@ enum APIClientEndpoint: APIEndpoint {
return .requestParameters(parameters: parameters)
case let .transactionConsumptionReject(parameters):
return .requestParameters(parameters: parameters)
case let .signup(parameters):
return .requestParameters(parameters: parameters)
case let .login(parameters):
return .requestParameters(parameters: parameters)
default: return .requestPlain
Expand Down
28 changes: 26 additions & 2 deletions Source/Client/API/HTTPClientAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@ extension HTTPClientAPI {
/// upgraded with the authentication contained in the response.
/// It can then be used to make other authenticated calls
///
/// - Parameter callback: The closure called when the request is completed
/// - Parameters:
/// - params: The login params to use
/// - callback: The closure called when the request is completed
/// - Returns: An optional cancellable request.
@discardableResult
public func login(withParams params: LoginParams, callback: @escaping Request<AuthenticationToken>.Callback)
public func login(withParams params: LoginParams,
callback: @escaping Request<AuthenticationToken>.Callback)
-> Request<AuthenticationToken>? {
let request: Request<AuthenticationToken>? = self.request(toEndpoint: APIClientEndpoint.login(params: params)) { result in
switch result {
Expand All @@ -56,4 +59,25 @@ extension HTTPClientAPI {
}
return request
}

/// Signup a new user using the provided params.
///
/// - Parameters:
/// - params: The signup params to use
/// - callback: The closure called when the request is completed
/// - Returns: An optional cancellable request.
@discardableResult
public func signup(withParams params: SignupParams,
callback: @escaping Request<EmptyResponse>.Callback)
-> Request<EmptyResponse>? {
let request: Request<EmptyResponse>? = self.request(toEndpoint: APIClientEndpoint.signup(params: params)) { result in
switch result {
case let .success(data: data):
callback(.success(data: data))
case let .fail(error):
callback(.fail(error: error))
}
}
return request
}
}
60 changes: 60 additions & 0 deletions Source/Client/Models/SignupParams.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// SignupParams.swift
// OmiseGO
//
// Created by Mederic Petit on 22/8/18.
// Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
//

/// Represents a structure used to signup a new user
public struct SignupParams {
/// The email to use for signup
public let email: String
/// The password to use for signup
public let password: String
/// The password confirmation that should match the password
public let passwordConfirmation: String
/// An optional redirect URL if you want to use an other page from the default one
public let redirectURL: String?
/// An optional success URL to redirect the user to upon successful verification
public let successURL: String?

/// Initialize the params used to signup a user
///
/// - Parameters:
/// - email: The email of the user
/// - password: The password of the user
/// - passwordConfirmation: The password confirmation that should match the password
/// - redirectURL: An optional redirect URL if you want to use an other page from the default one
/// - successURL: An optional success URL to redirect the user to upon successful verification
public init(email: String,
password: String,
passwordConfirmation: String,
redirectURL: String? = nil,
successURL: String? = nil) {
self.email = email
self.password = password
self.passwordConfirmation = passwordConfirmation
self.redirectURL = redirectURL
self.successURL = successURL
}
}

extension SignupParams: APIParameters {
private enum CodingKeys: String, CodingKey {
case email
case password
case passwordConfirmation = "password_confirmation"
case redirectURL = "redirect_url"
case successURL = "success_url"
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(email, forKey: .email)
try container.encode(password, forKey: .password)
try container.encode(passwordConfirmation, forKey: .passwordConfirmation)
try container.encodeIfPresent(redirectURL, forKey: .redirectURL)
try container.encodeIfPresent(successURL, forKey: .successURL)
}
}
39 changes: 39 additions & 0 deletions Tests/Client/FixtureTests/SignupFixtureTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// SignupFixtureTests.swift
// Tests
//
// Created by Mederic Petit on 22/8/18.
// Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
//

@testable import OmiseGO
import XCTest

class SignupFixtureTests: XCTestCase {
var testClient: FixtureClientAPI {
let bundle = Bundle(for: FixtureClientTestCase.self)
let url = bundle.url(forResource: "client_fixtures", withExtension: nil)!
let credentials = ClientCredential(apiKey: "some_api_key")
let config = ClientConfiguration(baseURL: "http://localhst:4000", credentials: credentials)
return FixtureClientAPI(fixturesDirectoryURL: url, config: config)
}

func testSignupSuccessfully() {
let expectation = self.expectation(description: "Signup a user successfully")
XCTAssertNil(try! self.testClient.config.credentials.authentication())
let client = self.testClient
let params = SignupParams(email: "email@example.com",
password: "password",
passwordConfirmation: "password")
let request = client.signup(withParams: params) { result in
defer { expectation.fulfill() }
switch result {
case let .fail(error: error):
XCTFail(error.message)
case .success(data: _): break
}
}
XCTAssertNotNil(request)
waitForExpectations(timeout: 15.0, handler: nil)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"version": "1",
"success": true,
"data": {}
}
47 changes: 42 additions & 5 deletions Tests/Core/CodingTests/EncodeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class EncodeTests: XCTestCase {
let encodedData = try self.encoder.encode(encodable)
XCTAssertEqual(String(data: encodedData, encoding: .utf8)!,
"""
{"value": 2147483647}
{"value": 2147483647}
""".uglifiedEncodedString())
} catch _ {
XCTFail("Should not raise an error")
Expand All @@ -123,7 +123,7 @@ class EncodeTests: XCTestCase {
let encodedData = try self.encoder.encode(encodable)
XCTAssertEqual(String(data: encodedData, encoding: .utf8)!,
"""
{"value": 922337203685400}
{"value": 922337203685400}
""".uglifiedEncodedString())
} catch _ {
XCTFail("Should not raise an error")
Expand All @@ -136,7 +136,7 @@ class EncodeTests: XCTestCase {
let encodedData = try self.encoder.encode(encodable)
XCTAssertEqual(String(data: encodedData, encoding: .utf8)!,
"""
{"value": 99999999999999999999999999999999999998}
{"value": 99999999999999999999999999999999999998}
""".uglifiedEncodedString())
} catch _ {
XCTFail("Should not raise an error")
Expand Down Expand Up @@ -287,7 +287,7 @@ class EncodeTests: XCTestCase {
XCTAssertEqual(encodedData, encodedPayload)
XCTAssertEqual(String(data: encodedData,
encoding: .utf8)!, """
{"formatted_id":"|0a8a4a98-794b-419e-b92d-514e83657e75"}
{"formatted_id":"|0a8a4a98-794b-419e-b92d-514e83657e75"}
""".uglifiedEncodedString())
} catch let thrownError {
XCTFail(thrownError.localizedDescription)
Expand Down Expand Up @@ -474,7 +474,7 @@ class EncodeTests: XCTestCase {
XCTAssertEqual(encodedData, encodedPayload)
XCTAssertEqual(String(data: encodedData,
encoding: .utf8)!, """
{"id":"0a8a4a98-794b-419e-b92d-514e83657e75"}
{"id":"0a8a4a98-794b-419e-b92d-514e83657e75"}
""".uglifiedEncodedString())
} catch let thrownError {
XCTFail(thrownError.localizedDescription)
Expand Down Expand Up @@ -567,4 +567,41 @@ class EncodeTests: XCTestCase {
XCTFail(thrownError.localizedDescription)
}
}

func testLoginParamsEncoding() {
do {
let loginParams = LoginParams(email: "email@example.com", password: "password")
let encodedData = try self.encoder.encode(loginParams)
XCTAssertEqual(String(data: encodedData, encoding: .utf8)!, """
{
"email":"email@example.com",
"password":"password"
}
""".uglifiedEncodedString())
} catch let thrownError {
XCTFail(thrownError.localizedDescription)
}
}

func testSignupParamsEncoding() {
do {
let signupParams = SignupParams(email: "email@example.com",
password: "password",
passwordConfirmation: "password",
redirectURL: "xxx",
successURL: "yyy")
let encodedData = try self.encoder.encode(signupParams)
XCTAssertEqual(String(data: encodedData, encoding: .utf8)!, """
{
"email":"email@example.com",
"password":"password",
"redirect_url":"xxx",
"success_url":"yyy",
"password_confirmation":"password"
}
""".uglifiedEncodedString())
} catch let thrownError {
XCTFail(thrownError.localizedDescription)
}
}
}
17 changes: 16 additions & 1 deletion documentation/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ let configuration = ClientConfiguration(baseURL: "https://your.base.url",
let client = HTTPClientAPI(config: configuration)
```

- If you are running a standalone version of the eWallet:
- If you are running a standalone version of the eWallet, you can sign up and sign in your users directly from the SDK:

You can retrieve an authentication token using the `HTTPClientAPI.login`.
This call does not require an `authenticationToken` to be set to the `ClientCredential`, so you can do the following:
Expand All @@ -87,6 +87,21 @@ client.login(withParams: params) { (result) in
}
```

You can register a user using the `HTTPClientAPI.signup`.

```swift
let params = SignupParams(email: "some@email.com", password: "password", passwordConfirmation: "password")
client.signup(withParams: params) { (result) in
switch result {
case .success:
// TODO: Handle success
// The user will receive an email asking him to confirm his email address, so you may want to show a page indicating this.
case let .fail(error: error):
// TODO: handle error
}
}
```

### Retrieving resources

Once you have an initialized and authenticated client, you can retrieve different resources.
Expand Down

0 comments on commit 1321611

Please sign in to comment.