Procuret / procuret-swift

Procuret API Swift library
0 stars 1 forks source link

add various signup-related types with tests #15

Closed hwjeremy closed 2 years ago

hwjeremy commented 3 years ago

@kaythoyet check out the latest version of the JavaScript library, you will find several new types, or updated types: Business, HumanIdentityDocument, HumanIdentity.

Go ahead and add/update these in the Swift library, and add tests for each available method (I believe it's .create for each one).

kaythoyet commented 3 years ago

updates: Business and HumanIdentity created/updated. Create tests written and executed. Both successful.

HumanIdentityDocument is next on the chopping block :)

kaythoyet commented 3 years ago

hey @hwjeremy my mom is heading this way to take me out to dinner but wanted to post here.

I initially had this for the enum :

//
//  IdentityDocumentType.swift
//  
//
//  Created by Kayla Hoyet on 10/28/21.
//

import Foundation

public struct IdentityDocumentType: Codable {

    enum _AU_LIC_IDT {
        case enumerations(Int)
        case AU_DRIVERS_LICENSE(String)
    }
}

I keep getting the error that the type is incorrect, but when I looked at it again, I thought that perhaps _AU_LIC_IDT needed its own case in this instance, so I amended the above to this:

//
//  IdentityDocumentType.swift
//  
//
//  Created by Kayla Hoyet on 10/28/21.
//

import Foundation

public struct IdentityDocumentType: Codable {

    enum _AU_LIC_IDT {
        case enumerations(Int)
        case AU_DRIVERS_LICENSE(String)
        case AU_LIC_IDT(Int, String)
    }
}

I'm still getting the same error, and the create function doesn't seem to recognize any of the cases as variables in this case.

The create function for HumanIdentityDocument currently looks like this. I know it's incorrect, but the compiler doesn't seem to recognize either case if I place it any other way. It's building successfully, but throwing an incorrect type error when I try to test.

HumanIdentityDocument.create(
            humanId: "39885555918766603",
            idDocumentType: IdentityDocumentType(),
            idDocumentIdentifier: "123456",
            session: provideTestSession(),
            callback: generateHumanIdentityDocument
        )

I am wondering if I need to set up the enums as separate entities so that I can declare them as part of the struct and perhaps fix my create function. The chapter on Enumerations didn't really cover using them in that way. I'm probably over-thinking it. I'm going to look over that again and see if I can get it fixed when I get back from dinner.

hwjeremy commented 2 years ago

@kaythoyet the enum can stand on its own, it doesn't need to be part of a struct. public enum IdentityDocumentType {}

hwjeremy commented 2 years ago

@kaythoyet other than that, I can see you are getting a bit mixed up with respect to what an enum case actually is. I suggest re-reading the enum chapter in the Swift handbook. Consider this example of an enumeration in Python:

"""
Procuret Web
Entity Type Module
author: hugh@blinkybeach.com
"""
from enum import Enum

class EntityType(Enum):
    """A legal form of business"""

    # Australia
    COMPANY = 1
    SOLE_TRADER = 2
    STRATA = 3
    TRUST = 4
    PARTNERSHIP = 5
    OTHER_INCORPORATED_ENTITY = 6
    OTHER_UNGROUPED_ENTITY = 7
kaythoyet commented 2 years ago

@hwjeremy

I have the enum standing on its own with two cases, enumerations (Int) and AU_DRIVERS_LICENSE (String). However, when set this way, idDocumentType inside the create function in HumanIdentityDocument no longer conforms to Encodable/Decodable protocols. I added Coding Keys, the thought being that IdentityDocumentType is an enum, and Enumeration uses indexid: Int and name: String, but I'm still running into the non-conformity issue.

The compiler says protocol requires the function encode(to:) with type Encodable.

The chapter on enumerations mentions that enums can be made to conform to protocols to provide standard functionality, so I'm going to go in that direction and see if I can get this to behave properly.

hwjeremy commented 2 years ago

@kaythoyet post code

kaythoyet commented 2 years ago

    func testCreateHumanIdentityDocument() {

        let expectation = XCTestExpectation(description:
            "create Human Identity Document")

        func generateHumanIdentityDocument(error: Error?,
            self: HumanIdentityDocument?) {

            XCTAssertNil(error, "An error occurred.")
            XCTAssertNotNil(self, "Human Identity Document is nil.")

            expectation.fulfill()

            return
        }

        HumanIdentityDocument.create(
            humanId: "39885555918766603",
            idDocumentType: IdentityDocumentType(
                enumerations: 1,
                AU_DRIVERS_LICENSE: "Australian Drivers License"
            ),
            idDocumentIdentifier: "123456",
            session: provideTestSession(),
            callback: generateHumanIdentityDocument
        )

        wait(for: [expectation], timeout: 5.0)

        return
    }
//
//  Document.swift
//  
//
//  Created by Kayla Hoyet on 7/20/21.
//

import Foundation

public struct HumanIdentityDocument: Codable {

    internal static let path = "/human/identity-document"

    let documentTypeId: Int
    let documentName: String
    let documentIdentifier: String
    let stateID: Int
    let stateName: String

    public enum CodingKeys: String, CodingKey {
        case documentTypeId = "document_type_id"
        case documentName = "document_name"
        case documentIdentifier = "document_identifier"
        case stateID = "state_id"
        case stateName = "state_name"
    }

    public static func create(
        humanId: String,
        idDocumentType: IdentityDocumentType,
        idDocumentIdentifier: String,
        session: Session?,
        callback: @escaping (Error?, Self?) -> Void
    ) {
        Request.make(
            path: self.path,
            payload: CreatePayload(
                humanId: humanId,
                idDocumentType: idDocumentType,
                idDocumentIdentifier: idDocumentIdentifier
            ),
            session: session,
            query: nil,
            method: .POST
        ) { error, data in
            Request.decodeResponse(error, data, Self.self, callback)
            return
        }
    }

    private struct CreatePayload: Codable {
        let humanId: String
        let idDocumentType: IdentityDocumentType
        let idDocumentIdentifier: String

        private enum CodingKeys: String, CodingKey {
            case humanId = "human_id"
            case idDocumentType = "id_document_type"
            case idDocumentIdentifier = "id_document_identifier"
        }
    }
}
//
//  IdentityDocumentType.swift
//  
//
//  Created by Kayla Hoyet on 10/28/21.
//

import Foundation

public enum IdentityDocumentType {
    case enumerations(Int)
    case AU_DRIVERS_LICENSE(String)

    private enum CodingKeys: String, CodingKey {
        case enumerations = "indexid"
        case AU_DRIVERS_LICENSE = "name"
    }

}
kaythoyet commented 2 years ago

@hwjeremy code is above. The error compiler states that IdDocumentType must conform to Encode/Decode protocol to be used inside the create function. It suggests implementing an encode(to:) to accomplish this.

hwjeremy commented 2 years ago

@kaythoyet I see there's still some confusion around enumerations... Take heart knowing that they are much simpler than you are anticipating. Your end result code will be dramatically simpler than what you have posted above.

I suggest two things:

  1. Ignore the JavaScript "enumeration" example. JS does not have enumerations and what you see me doing in JS is a giant hack to try and get a type that exhibits "enumeration like" qualities.
  2. Re-read the "Raw Values" section of the Swift handbook chapter on enumerations: https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html

Note that there is a difference between an "associated value" and a "raw value". You are interested in raw values.

kaythoyet commented 2 years ago

@hwjeremy

Test successful. Console print-out here:

Test Suite 'Selected tests' started at 2021-11-11 16:30:00.171
Test Suite 'ProcuretAPITests.xctest' started at 2021-11-11 16:30:00.172
Test Suite 'HumanTests' started at 2021-11-11 16:30:00.172
Test Case '-[ProcuretAPITests.HumanTests testCreateHumanIdentityDocument]' started.
Making request to Procuret API: /human/identity-document|POST
Raw response data (if any) will be printed below.
--- Begin raw data returned by Procuret API ---
{
    "document_identifier": "123456",
    "document_name": "Australian Drivers License",
    "document_type_id": 1,
    "state_id": 1,
    "state_name": "not_verified"
}
--- End raw data returned by Procuret API ---
Test Case '-[ProcuretAPITests.HumanTests testCreateHumanIdentityDocument]' passed (0.881 seconds).
Test Suite 'HumanTests' passed at 2021-11-11 16:30:01.054.
     Executed 1 test, with 0 failures (0 unexpected) in 0.881 (0.882) seconds
Test Suite 'ProcuretAPITests.xctest' passed at 2021-11-11 16:30:01.054.
     Executed 1 test, with 0 failures (0 unexpected) in 0.881 (0.882) seconds
Test Suite 'Selected tests' passed at 2021-11-11 16:30:01.055.
     Executed 1 test, with 0 failures (0 unexpected) in 0.881 (0.883) seconds
Program ended with exit code: 0
kaythoyet commented 2 years ago

@hwjeremy this one should be done. Successful tests for HumanIdentity, HumanIdentityDocument, and Business have officially been completed. :)