├── .bundle
└── config
├── .github
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .jazzy.yml
├── .swiftlint-test.yml
├── .swiftlint.yml
├── .travis.yml
├── AUTHORS
├── CHANGELOG.md
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── OmiseGO.podspec
├── OmiseGO.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcshareddata
│ └── xcschemes
│ ├── OmiseGO.xcscheme
│ └── Tests.xcscheme
├── OmiseGO.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── Podfile
├── Podfile.lock
├── README.md
├── Rakefile
├── Source
├── Admin
│ ├── API
│ │ ├── APIAdminEndpoint.swift
│ │ ├── AdminConfiguration.swift
│ │ ├── AdminCredential.swift
│ │ └── HTTPAdminAPI.swift
│ ├── Models
│ │ ├── Account+Admin.swift
│ │ ├── AccountGetParams.swift
│ │ ├── Transaction+Admin.swift
│ │ ├── TransactionConsumption+Admin.swift
│ │ ├── TransactionConsumptionParams+Admin.swift
│ │ ├── TransactionCreateParams+Admin.swift
│ │ ├── TransactionRequest+Admin.swift
│ │ ├── TransactionRequestParams+Admin.swift
│ │ ├── Wallet+Admin.swift
│ │ ├── WalletGetParams.swift
│ │ ├── WalletListForAccountParams.swift
│ │ └── WalletListForUserParams.swift
│ └── Websocket
│ │ └── SocketClient+Admin.swift
├── Client
│ ├── API
│ │ ├── APIClientEndpoint.swift
│ │ ├── ClientConfiguration.swift
│ │ ├── ClientCredential.swift
│ │ └── HTTPClientAPI.swift
│ ├── Models
│ │ ├── Setting+Client.swift
│ │ ├── SignupParams.swift
│ │ ├── Transaction+Client.swift
│ │ ├── TransactionConsumption+Client.swift
│ │ ├── TransactionListParams.swift
│ │ ├── TransactionRequest+Client.swift
│ │ ├── User+Client.swift
│ │ ├── UserResetPasswordParams.swift
│ │ ├── UserUpdatePasswordParams.swift
│ │ └── Wallet+Client.swift
│ ├── QRCode
│ │ ├── QRClientVerifier.swift
│ │ └── QRScannerViewController+Client.swift
│ └── Websocket
│ │ └── SocketClient+Client.swift
├── Core
│ ├── API
│ │ ├── APIEndpoint.swift
│ │ ├── APIError.swift
│ │ ├── Configuration.swift
│ │ ├── Credential.swift
│ │ ├── CredentialEncoder.swift
│ │ ├── HTTPAPI.swift
│ │ ├── HTTPTask.swift
│ │ ├── Request.swift
│ │ └── RequestBuilder.swift
│ ├── Helpers
│ │ ├── Codable.swift
│ │ ├── OMGNumberFormatter.swift
│ │ └── Tool.swift
│ ├── Models
│ │ ├── Account.swift
│ │ ├── AuthenticationToken.swift
│ │ ├── Avatar.swift
│ │ ├── Balance.swift
│ │ ├── CollectionParams
│ │ │ ├── FilterParams.swift
│ │ │ ├── PaginatedListParams.swift
│ │ │ ├── PaginationParams.swift
│ │ │ └── SortParams.swift
│ │ ├── EmptyResponse.swift
│ │ ├── ExchangePair.swift
│ │ ├── JSONListResponse.swift
│ │ ├── JSONResponse.swift
│ │ ├── LoginParams.swift
│ │ ├── OMGError.swift
│ │ ├── Pagination.swift
│ │ ├── Reponse.swift
│ │ ├── Setting.swift
│ │ ├── Token.swift
│ │ ├── Transaction.swift
│ │ ├── TransactionConsumption.swift
│ │ ├── TransactionConsumptionParams.swift
│ │ ├── TransactionExchange.swift
│ │ ├── TransactionParams.swift
│ │ ├── TransactionRequest.swift
│ │ ├── TransactionRequestParams.swift
│ │ ├── TransactionSource.swift
│ │ ├── User.swift
│ │ └── Wallet.swift
│ ├── Operations
│ │ ├── Listable.swift
│ │ ├── Listenable.swift
│ │ ├── QREncodable.swift
│ │ └── Retrievable.swift
│ ├── QRCode
│ │ ├── QRGenerator.swift
│ │ ├── QRReader.swift
│ │ ├── QRScannerLoadingView.swift
│ │ ├── QRScannerOverlayView.swift
│ │ ├── QRScannerView.swift
│ │ ├── QRScannerViewController.swift
│ │ ├── QRScannerViewModel.swift
│ │ └── QRVerifier.swift
│ └── Websocket
│ │ ├── SocketChannel.swift
│ │ ├── SocketClient.swift
│ │ ├── SocketDelegate.swift
│ │ ├── SocketDispatcher.swift
│ │ ├── SocketEvent.swift
│ │ ├── SocketMessage.swift
│ │ ├── SocketObject.swift
│ │ └── SocketPayload.swift
├── Info.plist
└── OmiseGO.h
├── Tests
├── Admin
│ ├── APITests
│ │ ├── APIAdminEndpointTest.swift
│ │ └── AdminCredentialTests.swift
│ ├── CondingTests
│ │ └── AdminEncodeTests.swift
│ └── FixtureTests
│ │ ├── AccountAdminFixtureTests.swift
│ │ ├── FixtureAdminAPI.swift
│ │ ├── FixtureAdminTestCase.swift
│ │ ├── LoginAdminFixtureTests.swift
│ │ ├── LogoutAdminFixtureTests.swift
│ │ ├── RequestAdminFixtureTests.swift
│ │ ├── TransactionAdminFixtureTests.swift
│ │ ├── TransactionConsumptionAdminFixtureTests.swift
│ │ ├── TransactionRequestAdminFixtureTests.swift
│ │ ├── WalletAdminFixtureTests.swift
│ │ └── admin_fixtures
│ │ └── api
│ │ ├── account.all.json
│ │ ├── account.get.json
│ │ ├── account.get_wallets.json
│ │ ├── admin.login.json
│ │ ├── me.logout.json
│ │ ├── transaction.all.json
│ │ ├── transaction.create.json
│ │ ├── transaction_consumption.approve.json
│ │ ├── transaction_consumption.cancel.json
│ │ ├── transaction_consumption.reject.json
│ │ ├── transaction_request.consume.json
│ │ ├── transaction_request.create.json
│ │ ├── transaction_request.get.json
│ │ ├── user.get_wallets.json
│ │ └── wallet.get.json
├── Client
│ ├── APITests
│ │ ├── APIClientEndpointTest.swift
│ │ └── ClientCredentialTests.swift
│ ├── FixtureTests
│ │ ├── FixtureClientAPI.swift
│ │ ├── FixtureClientTestCase.swift
│ │ ├── LoginFixtureTests.swift
│ │ ├── LogoutFixtureTests.swift
│ │ ├── RequestFixtureTest.swift
│ │ ├── SettingFixtureTests.swift
│ │ ├── SignupFixtureTests.swift
│ │ ├── TransactionConsumptionFixtureTests.swift
│ │ ├── TransactionFixtureTests.swift
│ │ ├── TransactionRequestFixtureTests.swift
│ │ ├── UserFixtureTests.swift
│ │ ├── WalletFixtureTests.swift
│ │ └── client_fixtures
│ │ │ └── api
│ │ │ ├── me.approve_transaction_consumption.json
│ │ │ ├── me.cancel_transaction_consumption.json
│ │ │ ├── me.consume_transaction_request.json
│ │ │ ├── me.create_transaction.json
│ │ │ ├── me.create_transaction_request.json
│ │ │ ├── me.get.json
│ │ │ ├── me.get_settings.json
│ │ │ ├── me.get_transaction_request.json
│ │ │ ├── me.get_transactions.json
│ │ │ ├── me.get_wallets.json
│ │ │ ├── me.logout.json
│ │ │ ├── me.reject_transaction_consumption.json
│ │ │ ├── user.login.json
│ │ │ ├── user.reset_password.json
│ │ │ ├── user.signup.json
│ │ │ └── user.update_password.json
│ └── LiveTests
│ │ ├── AuthenticationLiveTests.swift
│ │ ├── LiveClientTestCase.swift
│ │ ├── ResponseLiveTest.swift
│ │ ├── SettingLiveTests.swift
│ │ ├── TransactionLiveTests.swift
│ │ ├── TransactionRequestLiveTests.swift
│ │ ├── UserLiveTests.swift
│ │ └── WalletLiveTests.swift
├── Core
│ ├── APITests
│ │ ├── APIErrorTests.swift
│ │ ├── CredentialEncoderTests.swift
│ │ ├── HTTPClientTests.swift
│ │ ├── RequestBuilderTests.swift
│ │ └── RequestTest.swift
│ ├── CodingTests
│ │ ├── DecodeTests.swift
│ │ └── EncodeTests.swift
│ ├── FixtureTests
│ │ ├── DecodingFixtureTests.swift
│ │ ├── FixtureClient.swift
│ │ ├── FixtureTestCase.swift
│ │ ├── ListableTests.swift
│ │ ├── ResponseFixtureTest.swift
│ │ └── core_fixtures
│ │ │ ├── api
│ │ │ ├── dummy.decoding_error.json
│ │ │ ├── dummy.failure.json
│ │ │ ├── dummy.listable.failure.json
│ │ │ ├── dummy.paginated_listable.failure.json
│ │ │ └── dummy.success.json
│ │ │ └── objects
│ │ │ ├── account.json
│ │ │ ├── api_error.json
│ │ │ ├── authentication_token.json
│ │ │ ├── avatar.json
│ │ │ ├── balance.json
│ │ │ ├── bigint_int32.json
│ │ │ ├── bigint_int64.json
│ │ │ ├── bigint_invalid.json
│ │ │ ├── bigint_over_int64.json
│ │ │ ├── dates.json
│ │ │ ├── dates_invalid.json
│ │ │ ├── exchange_pair.json
│ │ │ ├── json_list_response.json
│ │ │ ├── json_response.json
│ │ │ ├── metadata.json
│ │ │ ├── metadata_null.json
│ │ │ ├── pagination.json
│ │ │ ├── setting.json
│ │ │ ├── socket_response.json
│ │ │ ├── socket_response_failure.json
│ │ │ ├── socket_response_reply.json
│ │ │ ├── socket_response_unknown_object.json
│ │ │ ├── token.json
│ │ │ ├── transaction.json
│ │ │ ├── transaction_consumption.json
│ │ │ ├── transaction_exchange.json
│ │ │ ├── transaction_request.json
│ │ │ ├── transaction_source.json
│ │ │ ├── user.json
│ │ │ └── wallet.json
│ ├── Helpers
│ │ ├── Extension.swift
│ │ └── StubGenerator.swift
│ ├── LiveTests
│ │ └── LiveTestCase.swift
│ ├── ModelTests
│ │ ├── AccountTest.swift
│ │ ├── AuthenticationTokenTests.swift
│ │ ├── BalanceTests.swift
│ │ ├── ExchangePairTest.swift
│ │ ├── OMGErrorTests.swift
│ │ ├── TokenTests.swift
│ │ ├── TransactionConsumptionParamsTest.swift
│ │ ├── TransactionConsumptionTest.swift
│ │ ├── TransactionRequestParamsTest.swift
│ │ ├── TransactionRequestTest.swift
│ │ ├── TransactionTest.swift
│ │ ├── UserTests.swift
│ │ └── WalletTests.swift
│ ├── OMGNumberFormatterTests.swift
│ ├── QRCodeTests
│ │ ├── QRGeneratorTests.swift
│ │ ├── QRReaderTests.swift
│ │ ├── QRScannerViewControllerTests.swift
│ │ ├── QRScannerViewModelTests.swift
│ │ └── QRScannerViewTests.swift
│ ├── SocketsTests
│ │ ├── FixtureSocketClient.swift
│ │ ├── SocketChannelTests.swift
│ │ ├── SocketClientTests.swift
│ │ ├── SocketDispatcherTests.swift
│ │ └── SocketMessageTests.swift
│ ├── TestMocks
│ │ ├── QRScannerViewController+Test.swift
│ │ ├── TestAPIEndpoint.swift
│ │ ├── TestBigUInt.swift
│ │ ├── TestConfiguration.swift
│ │ ├── TestCredential.swift
│ │ ├── TestDate.swift
│ │ ├── TestListable.swift
│ │ ├── TestMetadata.swift
│ │ ├── TestObject.swift
│ │ ├── TestQRHelper.swift
│ │ ├── TestQRReader.swift
│ │ ├── TestSocketEventDelegate.swift
│ │ ├── TestSortable.swift
│ │ └── TestWebSocketDelegate.swift
│ └── ToolsTests.swift
├── Info.plist
└── secret.plist
└── documentation
├── admin.md
├── client.md
└── pagination.md
/.bundle/config:
--------------------------------------------------------------------------------
1 | ---
2 | BUNDLE_PATH: "vendor/bundle"
3 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## How to contribute to the OmiseGO's projects
2 |
3 | Welcome to one of OmiseGO's open source projects! We welcome contributions in all kinds and shapes: code, documentation, bug reports, feedbacks... But before opening your first issue or PR, please read through this document.
4 |
5 | #### **Did you find a bug?**
6 |
7 | * __Do not create issues for security vulnerabilities__. We are currently setting up a bounty program for those. In the meantime, you can get in touch with us via [email](mailto:thibault@omisego.co).
8 | * For other bugs, first, ensure that the bug you found has not been reported yet. To do so, you can [search under issues](https://github.com/omisego/ios-sdk/issues).
9 | * Open a new issue if you didn't find an existing one. Follow the issue template and be as specific as possible.
10 |
11 | #### **Did you write a patch that fixes a bug?**
12 |
13 | * Open a Pull Request.
14 | * Describe the problem and solution. Add link to issue if any.
15 |
16 | #### **Do you intend to add a new feature or change an existing one?**
17 |
18 | * Do not open an issue right away. First, get in touch with us through [Gitter](https://gitter.im/omisego/ios-sdk). Once you get the green light to work on something, create an issue to describe the whole idea.
19 |
20 | #### **Do you have questions about the source code?**
21 |
22 | * You can ask any question about the source code in the [Gitter](https://gitter.im/omisego/ios-sdk) or on [stack overflow](https://stackoverflow.com/).
23 |
24 | Thanks!
25 |
26 | The OmiseGO Team
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Subject of the issue
2 |
3 | Describe your issue here.
4 |
5 | # Your environment
6 |
7 | Tell us where this issue occurred.
8 |
9 | # Steps to reproduce
10 |
11 | Tell us how to reproduce this issue.
12 |
13 | # Expected behavior
14 |
15 | Tell us what should happen.
16 |
17 | # Actual behavior
18 |
19 | Tell us what happens instead.
20 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Issue/Task Number:
2 |
3 | # Overview
4 |
5 | Describe what your Pull Request is about in a few sentences. This is a global description that should tell people what your PR is all about. Don't go too much into details here.
6 |
7 | # Changes
8 |
9 | - Change 1
10 | - Change 2
11 | - ...
12 |
13 | # Implementation Details
14 |
15 | Describe your changes and implementation choices. More details make PRs easier to review.
16 |
17 | # Usage
18 |
19 | Describe how to test your new feature/bug fix. Step by step so we can quickly give it a try.
20 |
21 | # Impact
22 |
23 | How can this change be deployed? Any special requirement?
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 | vendor/
20 |
21 | ## Other
22 | *.moved-aside
23 | *.xccheckout
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 | *.dSYM.zip
30 | *.dSYM
31 |
32 | ## Playgrounds
33 | timeline.xctimeline
34 | playground.xcworkspace
35 |
36 | # Swift Package Manager
37 | #
38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
39 | # Packages/
40 | # Package.pins
41 | # Package.resolved
42 | .build/
43 |
44 | # CocoaPods
45 | #
46 | # We recommend against adding the Pods directory to your .gitignore. However
47 | # you should judge for yourself, the pros and cons are mentioned at:
48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
49 | #
50 | Pods/
51 |
52 | # Carthage
53 | #
54 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
55 | Carthage/Checkouts
56 |
57 | Carthage/Build
58 |
59 | # fastlane
60 | #
61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
62 | # screenshots whenever they are needed.
63 | # For more information about the recommended setup visit:
64 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
65 |
66 | fastlane/report.xml
67 | fastlane/Preview.html
68 | fastlane/screenshots
69 | fastlane/test_output
70 |
71 | ## User settings
72 | xcuserdata/
73 |
74 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
75 | *.xcscmblueprint
76 | *.xccheckout
77 |
78 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
79 | build/
80 | DerivedData/
81 | *.moved-aside
82 | *.pbxuser
83 | !default.pbxuser
84 | *.mode1v3
85 | !default.mode1v3
86 | *.mode2v3
87 | !default.mode2v3
88 | *.perspectivev3
89 | !default.perspectivev3
90 |
91 | ## Jazzy generated doc
92 | docs/
93 |
--------------------------------------------------------------------------------
/.jazzy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | author: OmiseGO
3 | author_url: https://omisego.network/
4 | copyright: Copyright (c) 2017-present, Omise Go Pte. Ltd. All rights reserved.
5 | clean: true
6 | github_url: https://github.com/omisego/ios-sdk
7 | hide_documentation_coverage: true
8 | module: OmiseGO
9 | output: docs
10 | podspec: OmiseGO.podspec
11 | readme: README.md
12 | skip_undocumented: true
13 | theme: fullwidth
14 | source_directory: Source
15 | use_safe_filenames: true
16 |
--------------------------------------------------------------------------------
/.swiftlint-test.yml:
--------------------------------------------------------------------------------
1 | included:
2 | - Tests
3 | line_length: 160
4 | disabled_rules:
5 | - identifier_name
6 | - force_try
7 | - force_cast
8 | - cyclomatic_complexity
9 | - function_body_length
10 | - type_body_length
11 | - weak_delegate
12 | - file_length
13 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | included:
2 | - Source
3 | line_length: 140
4 | disabled_rules:
5 | - identifier_name
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: swift
2 | osx_image: xcode10
3 | cache:
4 | - bundler
5 | - cocoapods
6 | env:
7 | matrix:
8 | - TEST_TYPE=iOS
9 | - TEST_TYPE=Lint
10 | - TEST_TYPE=CocoaPods
11 | install:
12 | - |
13 | if [ "$TEST_TYPE" = Lint ]; then
14 | brew install swiftlint || brew upgrade swiftlint
15 | elif [ "$TEST_TYPE" = CocoaPods ] || [ "$TEST_TYPE" = iOS ]; then
16 | bundle install --path vendor/bundle
17 | bundle exec pod repo update --silent
18 | fi
19 | if [ "$TEST_TYPE" = iOS ]; then
20 | bundle exec pod install
21 | fi
22 | script:
23 | - |
24 | if [ "$TEST_TYPE" = iOS ]; then
25 | set -o pipefail
26 | xcodebuild -workspace OmiseGO.xcworkspace -scheme "OmiseGO" -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone X" test | xcpretty -c
27 | elif [ "$TEST_TYPE" = Lint ]; then
28 | swiftlint lint --config .swiftlint.yml
29 | elif [ "$TEST_TYPE" = CocoaPods ]; then
30 | bundle exec pod lib lint --verbose
31 | fi
32 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Omise Go Pte. Ltd.
2 | Ryo Fukuda yuzushioh@gmail.com
3 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | gem 'jazzy', "0.9.5"
5 | gem 'cocoapods', "~> 1.5.3"
6 | gem 'xcpretty'
7 | gem 'github_changelog_generator'
8 |
--------------------------------------------------------------------------------
/OmiseGO.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'OmiseGO'
3 | s.version = '1.1.2'
4 | s.license = 'Apache'
5 | s.summary = 'The OmiseGO iOS SDK allows developers to easily interact with a node of the OmiseGO eWallet.'
6 | s.homepage = 'https://github.com/omisego/ios-sdk'
7 | s.social_media_url = 'https://twitter.com/omise_go'
8 | s.authors = { 'OmiseGO team' => 'omg@omise.co' }
9 | s.source = { :git => 'https://github.com/omisego/ios-sdk.git', :tag => s.version }
10 |
11 | s.platform = :ios, '10.0'
12 | s.swift_version = '4.2'
13 |
14 | s.subspec 'Core' do |ss|
15 | ss.source_files = "Source/Core/**/*.swift"
16 | ss.dependency 'Starscream', '~> 3.0'
17 | ss.dependency 'BigInt', '~> 3.1'
18 | end
19 |
20 | s.subspec 'Client' do |ss|
21 | ss.source_files = "Source/Client/**/*.swift"
22 | ss.dependency 'OmiseGO/Core'
23 | end
24 |
25 | s.subspec 'Admin' do |ss|
26 | ss.source_files = "Source/Admin/**/*.swift"
27 | ss.dependency 'OmiseGO/Core'
28 | end
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/OmiseGO.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/OmiseGO.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
39 |
40 |
41 |
42 |
48 |
49 |
51 |
52 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/OmiseGO.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/OmiseGO.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | platform :ios, '10.0'
3 |
4 | def shared_pods
5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
6 | use_frameworks!
7 | # websocket library
8 | pod 'Starscream', '~> 3.0'
9 | pod 'BigInt', '~> 3.1'
10 | end
11 |
12 | target 'OmiseGO' do
13 | shared_pods
14 | end
15 |
16 | target 'Tests' do
17 | shared_pods
18 | end
19 |
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - BigInt (3.1.0):
3 | - SipHash (~> 1.2)
4 | - SipHash (1.2.2)
5 | - Starscream (3.0.6)
6 |
7 | DEPENDENCIES:
8 | - BigInt (~> 3.1)
9 | - Starscream (~> 3.0)
10 |
11 | SPEC REPOS:
12 | https://github.com/cocoapods/specs.git:
13 | - BigInt
14 | - SipHash
15 | - Starscream
16 |
17 | SPEC CHECKSUMS:
18 | BigInt: 76b5dfdfa3e2e478d4ffdf161aeede5502e2742f
19 | SipHash: fad90a4683e420c52ef28063063dbbce248ea6d4
20 | Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5
21 |
22 | PODFILE CHECKSUM: de86b509d6be5a0f236452ea05b50b8633136c66
23 |
24 | COCOAPODS: 1.5.3
25 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | JAZZY_CONFIG = '.jazzy.yml'
2 |
3 | desc 'Generate API Reference'
4 | task :docs do
5 | `jazzy --config #{JAZZY_CONFIG}`
6 | end
7 |
8 | task :changelog do
9 | `github_changelog_generator omisego/ios-sdk`
10 | end
11 |
12 | task :prepare_release do
13 | Rake::Task["docs"].invoke
14 | Rake::Task["changelog"].invoke
15 | end
16 |
--------------------------------------------------------------------------------
/Source/Admin/API/AdminConfiguration.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AdminConfiguration.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 8/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a configuration object used to setup an HTTPAPI
10 | public struct AdminConfiguration: Configuration {
11 | /// The current SDK version
12 | let apiVersion: String = "1"
13 |
14 | /// The base URL of the wallet server:
15 | /// When initializing the HTTPAPI, this needs to be an http(s) url
16 | /// When initializing the SocketClient, this needs to be a ws(s) url
17 | let baseURL: String
18 | var credentials: Credential
19 | let debugLog: Bool
20 |
21 | /// Creates the configuration required to initialize the OmiseGO SDK
22 | ///
23 | /// - Parameters:
24 | /// - baseURL: The base URL of the wallet server
25 | /// When initializing the HTTPAPI, this needs to be an http(s) url
26 | /// When initializing the SocketClient, this needs to be a ws(s) url
27 | /// - apiKey: The API key (typically generated on the admin panel)
28 | /// - authenticationToken: The authentication token of the current user
29 | /// - debugLog: Enable or not SDK console logs
30 | public init(baseURL: String, credentials: AdminCredential = AdminCredential(), debugLog: Bool = false) {
31 | self.baseURL = baseURL + "/api/admin"
32 | self.credentials = credentials
33 | self.debugLog = debugLog
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Source/Admin/API/AdminCredential.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AdminCredential.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | public struct AdminCredential: Credential {
10 | public var userId: String?
11 | public var authenticationToken: String?
12 |
13 | /// Initialize an AdminCredential object with the given userId and authentication token
14 | ///
15 | /// - Parameters:
16 | /// - userId: The userId of the admin to use for the authenticated calls. Can be nil if doing request that don't need authentication.
17 | /// - authenticationToken: The authentication token of the admin. Can be nil if doing request that don't need authentication.
18 | public init(userId: String, authenticationToken: String) {
19 | self.userId = userId
20 | self.authenticationToken = authenticationToken
21 | }
22 |
23 | public init() {}
24 |
25 | func isAuthenticated() -> Bool { return self.authenticationToken != nil && self.userId != nil }
26 |
27 | func authentication() throws -> String? {
28 | guard let authenticationToken = self.authenticationToken, let userId = self.userId else {
29 | return nil
30 | }
31 | return try CredentialEncoder.encode(value1: userId, value2: authenticationToken, scheme: "OMGAdmin")
32 | }
33 |
34 | mutating func update(withAuthenticationToken authenticationToken: AuthenticationToken) {
35 | self.userId = authenticationToken.user.id
36 | self.authenticationToken = authenticationToken.token
37 | }
38 |
39 | public mutating func invalidate() {
40 | self.userId = nil
41 | self.authenticationToken = nil
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Source/Admin/Models/Account+Admin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Account+Admin.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 18/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension Account: Filterable {
10 | public enum FilterableFields: String, RawEnumerable {
11 | case id
12 | case name
13 | case description
14 | case createdAt = "created_at"
15 | case updatedAt = "updated_at"
16 | case metadata
17 | }
18 | }
19 |
20 | extension Account: Sortable {
21 | public enum SortableFields: String, RawEnumerable {
22 | case id
23 | case name
24 | case description
25 | case createdAt = "created_at"
26 | case updatedAt = "updated_at"
27 | }
28 | }
29 |
30 | extension Account: PaginatedListable {
31 | @discardableResult
32 | /// Get a paginated list of accounts
33 | ///
34 | /// - Parameters:
35 | /// - client: An API client.
36 | /// This client need to be initialized with a AdminConfiguration struct before being used.
37 | /// - params: The pagination params object to use to scope the results
38 | /// - callback: The closure called when the request is completed
39 | /// - Returns: An optional cancellable request.
40 | public static func list(using client: HTTPAdminAPI,
41 | params: PaginatedListParams,
42 | callback: @escaping Account.PaginatedListRequestCallback) -> Account.PaginatedListRequest? {
43 | return self.list(using: client, endpoint: APIAdminEndpoint.getAccounts(params: params), callback: callback)
44 | }
45 | }
46 |
47 | extension Account: Retrievable {
48 | @discardableResult
49 | /// Get an account from its id
50 | ///
51 | /// - Parameters:
52 | /// - client: An API client.
53 | /// This client need to be initialized with a AdminConfiguration struct before being used.
54 | /// - params: The AccountGetParams params object containing the id of the account to retrieve
55 | /// - callback: The closure called when the request is completed
56 | /// - Returns: An optional cancellable request.
57 | public static func get(using client: HTTPAdminAPI,
58 | params: AccountGetParams,
59 | callback: @escaping Account.RetrieveRequestCallback) -> Account.RetrieveRequest? {
60 | return self.retrieve(using: client, endpoint: APIAdminEndpoint.getAccount(params: params), callback: callback)
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Source/Admin/Models/AccountGetParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AccountGetParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 26/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a structure used to retrieve an account from its id
10 | public struct AccountGetParams: APIParameters {
11 | /// The id of the account to retrieve
12 | public let id: String
13 |
14 | /// Initialize the params used to retrive a account from its id
15 | ///
16 | /// - Parameters:
17 | /// - id: The id of the account to retrieve
18 | public init(id: String) {
19 | self.id = id
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Source/Admin/Models/Transaction+Admin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Transaction+Admin.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 19/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension Transaction {
10 | @discardableResult
11 | /// Create a new transaction
12 | ///
13 | /// - Parameters:
14 | /// - client: An API client.
15 | /// This client need to be initialized with a ClientConfiguration struct before being used.
16 | /// - params: The TransactionSendParams object to customize the transaction
17 | /// - callback: The closure called when the request is completed
18 | /// - Returns: An optional cancellable request.
19 | public static func create(using client: HTTPAdminAPI,
20 | params: TransactionCreateParams,
21 | callback: @escaping Transaction.RetrieveRequestCallback) -> Transaction.RetrieveRequest? {
22 | return self.retrieve(using: client, endpoint: APIAdminEndpoint.createTransaction(params: params), callback: callback)
23 | }
24 |
25 | @discardableResult
26 | /// Get a paginated list of transactions
27 | ///
28 | /// - Parameters:
29 | /// - client: An API client.
30 | /// This client need to be initialized with a ClientConfiguration struct before being used.
31 | /// - params: The PaginatedListParams object to use to scope the results
32 | /// - callback: The closure called when the request is completed
33 | /// - Returns: An optional cancellable request.
34 | public static func list(using client: HTTPAdminAPI,
35 | params: PaginatedListParams,
36 | callback: @escaping Transaction.PaginatedListRequestCallback) -> Transaction.PaginatedListRequest? {
37 | return self.list(using: client, endpoint: APIAdminEndpoint.getTransactions(params: params), callback: callback)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Source/Admin/Models/TransactionCreateParams+Admin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionCreateParams+Admin.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 19/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import BigInt
10 |
11 | extension TransactionCreateParams {
12 | public init(fromAddress: String?,
13 | toAddress: String?,
14 | amount: BigInt?,
15 | fromAmount: BigInt?,
16 | toAmount: BigInt?,
17 | fromTokenId: String?,
18 | toTokenId: String?,
19 | tokenId: String?,
20 | fromAccountId: String?,
21 | toAccountId: String?,
22 | fromProviderUserId: String?,
23 | toProviderUserId: String?,
24 | fromUserId: String?,
25 | toUserId: String?,
26 | idempotencyToken: String,
27 | exchangeAccountId: String?,
28 | exchangeAddress: String?,
29 | metadata: [String: Any],
30 | encryptedMetadata: [String: Any]) {
31 | self.fromAddress = fromAddress
32 | self.toAddress = toAddress
33 | self.amount = amount
34 | self.fromAmount = fromAmount
35 | self.toAmount = toAmount
36 | self.fromTokenId = fromTokenId
37 | self.toTokenId = toTokenId
38 | self.tokenId = tokenId
39 | self.fromAccountId = fromAccountId
40 | self.toAccountId = toAccountId
41 | self.fromProviderUserId = fromProviderUserId
42 | self.toProviderUserId = toProviderUserId
43 | self.fromUserId = fromUserId
44 | self.toUserId = toUserId
45 | self.idempotencyToken = idempotencyToken
46 | self.metadata = metadata
47 | self.encryptedMetadata = encryptedMetadata
48 | self.exchangeAddress = exchangeAddress
49 | self.exchangeAccountId = exchangeAccountId
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Source/Admin/Models/TransactionRequest+Admin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionRequest+Admin.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 8/10/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension TransactionRequest {
10 | @discardableResult
11 | /// Generate a transaction request from the given TransactionRequestParams object
12 | ///
13 | /// - Parameters:
14 | /// - client: An API client.
15 | /// This client need to be initialized with a AdminConfiguration struct before being used.
16 | /// - params: The TransactionRequestCreateParams object describing the transaction request to be made.
17 | /// - callback: The closure called when the request is completed
18 | /// - Returns: An optional cancellable request.
19 | public static func create(using client: HTTPAdminAPI,
20 | params: TransactionRequestCreateParams,
21 | callback: @escaping TransactionRequest.RetrieveRequestCallback)
22 | -> TransactionRequest.RetrieveRequest? {
23 | return self.retrieve(using: client,
24 | endpoint: APIAdminEndpoint.transactionRequestCreate(params: params),
25 | callback: callback)
26 | }
27 |
28 | @discardableResult
29 | /// Retreive a transaction request from its formatted id
30 | ///
31 | /// - Parameters:
32 | /// - client: An API client.
33 | /// This client need to be initialized with a AdminConfiguration struct before being used.
34 | /// - formattedId: The formatted id of the TransactionRequest to be retrived.
35 | /// - callback: The closure called when the request is completed
36 | /// - Returns: An optional cancellable request.
37 | public static func get(using client: HTTPAdminAPI,
38 | formattedId: String,
39 | callback: @escaping TransactionRequest.RetrieveRequestCallback)
40 | -> TransactionRequest.RetrieveRequest? {
41 | let params = TransactionRequestGetParams(formattedId: formattedId)
42 | return self.retrieve(using: client,
43 | endpoint: APIAdminEndpoint.transactionRequestGet(params: params),
44 | callback: callback)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Source/Admin/Models/WalletGetParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WalletGetParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 17/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a structure used to retrieve a wallet from its address
10 | public struct WalletGetParams: APIParameters {
11 | /// The address of the wallet to retrieve
12 | public let address: String
13 |
14 | /// Initialize the params used to retrive a wallet from its address
15 | ///
16 | /// - Parameters:
17 | /// - address: The address of the wallet to retrieve
18 | public init(address: String) {
19 | self.address = address
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Source/Admin/Models/WalletListForAccountParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WalletListForAccountParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 18/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// Represents a structure used to retrieve wallets for a specific user
12 | public struct WalletListForAccountParams {
13 | /// The pagination params
14 | public let paginatedListParams: PaginatedListParams
15 | /// The account id
16 | public let accountId: String
17 | /// Query only wallets belonging to the specified account OR also its children
18 | public let owned: Bool
19 |
20 | /// Initialize the params used to query a paginated list of wallets belonging to an account from its id
21 | ///
22 | /// - Parameters:
23 | /// - paginatedListParams: The params to use for the pagination
24 | /// - accountId: The id of the account
25 | public init(paginatedListParams: PaginatedListParams,
26 | accountId: String,
27 | owned: Bool) {
28 | self.paginatedListParams = paginatedListParams
29 | self.accountId = accountId
30 | self.owned = owned
31 | }
32 | }
33 |
34 | extension WalletListForAccountParams: APIParameters {
35 | private enum CodingKeys: String, CodingKey {
36 | case paginatedListParams
37 | case accountId = "id"
38 | case owned
39 | }
40 |
41 | public func encode(to encoder: Encoder) throws {
42 | var container = encoder.container(keyedBy: CodingKeys.self)
43 | try paginatedListParams.encode(to: encoder)
44 | try container.encode(accountId, forKey: .accountId)
45 | try container.encode(owned, forKey: .owned)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Source/Admin/Models/WalletListForUserParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WalletListForUserParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 17/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a structure used to retrieve wallets for a specific user
10 | public struct WalletListForUserParams {
11 | /// The pagination params
12 | public let paginatedListParams: PaginatedListParams
13 | /// The id of the user
14 | public let userId: String?
15 | /// The provider user id of the user
16 | public let providerUserId: String?
17 |
18 | /// Initialize the params used to query a paginated list of wallets belonging to a user from its userId
19 | ///
20 | /// - Parameters:
21 | /// - paginatedListParams: The params to use for the pagination
22 | /// - userId: The id of the user
23 | public init(paginatedListParams: PaginatedListParams,
24 | userId: String) {
25 | self.paginatedListParams = paginatedListParams
26 | self.userId = userId
27 | self.providerUserId = nil
28 | }
29 |
30 | /// Initialize the params used to query a paginated list of wallets belonging to a user from its providerUserId
31 | ///
32 | /// - Parameters:
33 | /// - paginatedListParams: The params to use for the pagination
34 | /// - providerUserId: The id of the user
35 | public init(paginatedListParams: PaginatedListParams,
36 | providerUserId: String) {
37 | self.paginatedListParams = paginatedListParams
38 | self.providerUserId = providerUserId
39 | self.userId = nil
40 | }
41 | }
42 |
43 | extension WalletListForUserParams: APIParameters {
44 | private enum CodingKeys: String, CodingKey {
45 | case paginatedListParams
46 | case userId = "id"
47 | case providerUserId = "provider_user_id"
48 | }
49 |
50 | public func encode(to encoder: Encoder) throws {
51 | var container = encoder.container(keyedBy: CodingKeys.self)
52 | try paginatedListParams.encode(to: encoder)
53 | try container.encodeIfPresent(userId, forKey: .userId)
54 | try container.encodeIfPresent(providerUserId, forKey: .providerUserId)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Source/Admin/Websocket/SocketClient+Admin.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketClient+Admin.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 10/10/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension SocketClient {
10 | /// Initialize a websocket client using a configuration object
11 | ///
12 | /// - Parameters:
13 | /// - config: The configuration object containing the client configuration
14 | /// - delegate: The delegate that should receive connection events
15 | /// - Note: the baseURL of the Configuration needs to be a socket url (wss://your.domain.com)
16 | public convenience init(config: AdminConfiguration, delegate: SocketConnectionDelegate?) {
17 | self.init()
18 | self.config = config
19 | self.delegate = delegate
20 | self.initWebSocket()
21 | }
22 |
23 | /// Invalidate the current (if any) socket connection and prepare the client for a new one with the updated configuration.
24 | /// Note that the active connection will be droped and any topic currently subscribed will be unsubscribed.
25 | /// You will need to start listening for events again.
26 | ///
27 | /// - Parameter configuration: The updated Configuration
28 | public func updateConfiguration(_ configuration: AdminConfiguration) {
29 | self.config = configuration
30 | self.cleanup()
31 | self.initWebSocket()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Source/Client/API/ClientConfiguration.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ClientConfiguration.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a configuration object used to setup an HTTPAPI
10 | public struct ClientConfiguration: Configuration {
11 | /// The current SDK version
12 | let apiVersion: String = "1"
13 |
14 | /// The base URL of the wallet server:
15 | /// When initializing the HTTPAPI, this needs to be an http(s) url
16 | /// When initializing the SocketClient, this needs to be a ws(s) url
17 | let baseURL: String
18 | var credentials: Credential
19 | let debugLog: Bool
20 |
21 | /// Creates the configuration required to initialize the HTTPAPI in order to perform client API calls
22 | ///
23 | /// - Parameters:
24 | /// - baseURL: The base URL of the wallet server
25 | /// When initializing the HTTPAPI, this needs to be an http(s) url
26 | /// When initializing the SocketClient, this needs to be a ws(s) url
27 | /// - apiKey: The API key (typically generated on the admin panel)
28 | /// - authenticationToken: The authentication token of the current user
29 | /// - debugLog: Enable or not SDK console logs
30 | public init(baseURL: String, credentials: ClientCredential, debugLog: Bool = false) {
31 | self.baseURL = baseURL + "/api/client"
32 | self.credentials = credentials
33 | self.debugLog = debugLog
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Source/Client/API/ClientCredential.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ClientCredential.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents the credentials needed for making client API calls.
10 | /// They consist on an API key and an authentication token.
11 | public struct ClientCredential: Credential {
12 | public let apiKey: String
13 | public var authenticationToken: String?
14 |
15 | /// Initialize a ClientCredential with the given API key and authentication token
16 | ///
17 | /// - Parameters:
18 | /// - apiKey: The API key to use for the authenticated calls
19 | /// - authenticationToken: The authentication token of the user. Can be nil if doing request that don't need authentication.
20 | public init(apiKey: String, authenticationToken: String? = nil) {
21 | self.apiKey = apiKey
22 | self.authenticationToken = authenticationToken
23 | }
24 |
25 | func isAuthenticated() -> Bool {
26 | return self.authenticationToken != nil
27 | }
28 |
29 | func authentication() throws -> String? {
30 | guard let authenticationToken = self.authenticationToken else { return nil }
31 | return try CredentialEncoder.encode(value1: self.apiKey, value2: authenticationToken, scheme: "OMGClient")
32 | }
33 |
34 | mutating func update(withAuthenticationToken authenticationToken: AuthenticationToken) {
35 | self.authenticationToken = authenticationToken.token
36 | }
37 |
38 | public mutating func invalidate() {
39 | self.authenticationToken = nil
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Source/Client/Models/Setting+Client.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Setting+Client.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension Setting: Retrievable {
10 | @discardableResult
11 | /// Get the global settings of the provider
12 | ///
13 | /// - Parameters:
14 | /// - client: An API client.
15 | /// This client need to be initialized with a ClientConfiguration struct before being used.
16 | /// - callback: The closure called when the request is completed
17 | /// - Returns: An optional cancellable request.
18 | public static func get(using client: HTTPClientAPI,
19 | callback: @escaping Setting.RetrieveRequestCallback) -> Setting.RetrieveRequest? {
20 | return self.retrieve(using: client, endpoint: APIClientEndpoint.getSettings, callback: callback)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Source/Client/Models/Transaction+Client.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Transaction+Client.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension Transaction {
10 | @discardableResult
11 | /// Create a new transaction
12 | ///
13 | /// - Parameters:
14 | /// - client: An API client.
15 | /// This client need to be initialized with a ClientConfiguration struct before being used.
16 | /// - params: The TransactionSendParams object to customize the transaction
17 | /// - callback: The closure called when the request is completed
18 | /// - Returns: An optional cancellable request.
19 | public static func create(using client: HTTPClientAPI,
20 | params: TransactionCreateParams,
21 | callback: @escaping Transaction.RetrieveRequestCallback) -> Transaction.RetrieveRequest? {
22 | return self.retrieve(using: client, endpoint: APIClientEndpoint.createTransaction(params: params), callback: callback)
23 | }
24 |
25 | @discardableResult
26 | /// Get a paginated list of transaction for the current user
27 | ///
28 | /// - Parameters:
29 | /// - client: An API client.
30 | /// This client need to be initialized with a ClientConfiguration struct before being used.
31 | /// - params: The TransactionListParams object to use to scope the results
32 | /// - callback: The closure called when the request is completed
33 | /// - Returns: An optional cancellable request.
34 | public static func list(using client: HTTPClientAPI,
35 | params: TransactionListParams,
36 | callback: @escaping Transaction.PaginatedListRequestCallback) -> Transaction.PaginatedListRequest? {
37 | return self.list(using: client, endpoint: APIClientEndpoint.getTransactions(params: params), callback: callback)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Source/Client/Models/TransactionListParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionListParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 23/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // Represents a structure used to query a list of transactions
12 | public struct TransactionListParams {
13 | /// The pagination params to use
14 | public let paginatedListParams: PaginatedListParams
15 | /// An optional wallet address owned by the current user
16 | public let address: String?
17 |
18 | /// Initialize the params used to query a paginated list of transactions
19 | ///
20 | /// - Parameters:
21 | /// - paginatedListParams: The pagination params to use
22 | /// - address: An optional wallet address belonging to the current user
23 | public init(paginatedListParams: PaginatedListParams,
24 | address: String? = nil) {
25 | self.paginatedListParams = paginatedListParams
26 | self.address = address
27 | }
28 | }
29 |
30 | extension TransactionListParams: APIParameters {
31 | private enum CodingKeys: String, CodingKey {
32 | case paginationParams
33 | case address
34 | }
35 |
36 | public func encode(to encoder: Encoder) throws {
37 | var container = encoder.container(keyedBy: CodingKeys.self)
38 | try container.encode(address, forKey: .address)
39 | try paginatedListParams.encode(to: encoder)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Source/Client/Models/TransactionRequest+Client.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionRequest.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension TransactionRequest {
10 | @discardableResult
11 | /// Generate a transaction request from the given TransactionRequestParams object
12 | ///
13 | /// - Parameters:
14 | /// - client: An API client.
15 | /// This client need to be initialized with a ClientConfiguration struct before being used.
16 | /// - params: The TransactionRequestCreateParams object describing the transaction request to be made.
17 | /// - callback: The closure called when the request is completed
18 | /// - Returns: An optional cancellable request.
19 | public static func create(using client: HTTPClientAPI,
20 | params: TransactionRequestCreateParams,
21 | callback: @escaping TransactionRequest.RetrieveRequestCallback)
22 | -> TransactionRequest.RetrieveRequest? {
23 | return self.retrieve(using: client,
24 | endpoint: APIClientEndpoint.transactionRequestCreate(params: params),
25 | callback: callback)
26 | }
27 |
28 | @discardableResult
29 | /// Retreive a transaction request from its formatted id
30 | ///
31 | /// - Parameters:
32 | /// - client: An API client.
33 | /// This client need to be initialized with a ClientConfiguration struct before being used.
34 | /// - formattedId: The formatted id of the TransactionRequest to be retrived.
35 | /// - callback: The closure called when the request is completed
36 | /// - Returns: An optional cancellable request.
37 | public static func get(using client: HTTPClientAPI,
38 | formattedId: String,
39 | callback: @escaping TransactionRequest.RetrieveRequestCallback)
40 | -> TransactionRequest.RetrieveRequest? {
41 | let params = TransactionRequestGetParams(formattedId: formattedId)
42 | return self.retrieve(using: client,
43 | endpoint: APIClientEndpoint.transactionRequestGet(params: params),
44 | callback: callback)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Source/Client/Models/UserResetPasswordParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserResetPasswordParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 14/3/19.
6 | // Copyright © 2019 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a structure used to request a password reset for the user
10 | public struct UserResetPasswordParams {
11 | /// The email of the user
12 | public let email: String
13 | /// The URL where the user will be taken when clicking the link in the email
14 | public let redirectUrl: String
15 |
16 | /// Initialize the params used to request a password reset for the user
17 | ///
18 | /// - Parameters:
19 | /// - email: The email of the user
20 | /// - redirectUrl: The URL where the user will be taken when clicking the link in the email
21 | public init(email: String,
22 | redirectUrl: String) {
23 | self.email = email
24 | self.redirectUrl = redirectUrl
25 | }
26 | }
27 |
28 | extension UserResetPasswordParams: APIParameters {
29 | private enum CodingKeys: String, CodingKey {
30 | case email
31 | case redirectUrl = "redirect_url"
32 | }
33 |
34 | public func encode(to encoder: Encoder) throws {
35 | var container = encoder.container(keyedBy: CodingKeys.self)
36 | try container.encode(email, forKey: .email)
37 | try container.encode(redirectUrl, forKey: .redirectUrl)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Source/Client/Models/UserUpdatePasswordParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserUpdatePasswordParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 14/3/19.
6 | // Copyright © 2019 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a structure used to update the password of a user following a reset
10 | public struct UserUpdatePasswordParams {
11 | /// The email of the user (obtained from the params in the link sent to the email of the user)
12 | public let email: String
13 | /// The unique reset password token obtained from the params in the link sent to the email of the user
14 | public let token: String?
15 | /// The updated password
16 | public let password: String
17 | /// The password confirmation that should match the updated password
18 | public let passwordConfirmation: String
19 |
20 | /// Initialize the params used to signup a user
21 | ///
22 | /// - Parameters:
23 | /// - email: The email of the user (obtained from the params in the link sent to the email of the user)
24 | /// - token: The unique reset password token obtained from the params in the link sent to the email of the user
25 | /// - password: The updated password
26 | /// - passwordConfirmation: The password confirmation that should match the updated password
27 | public init(email: String,
28 | token: String,
29 | password: String,
30 | passwordConfirmation: String) {
31 | self.email = email
32 | self.token = token
33 | self.password = password
34 | self.passwordConfirmation = passwordConfirmation
35 | }
36 | }
37 |
38 | extension UserUpdatePasswordParams: APIParameters {
39 | private enum CodingKeys: String, CodingKey {
40 | case email
41 | case token
42 | case password
43 | case passwordConfirmation = "password_confirmation"
44 | }
45 |
46 | public func encode(to encoder: Encoder) throws {
47 | var container = encoder.container(keyedBy: CodingKeys.self)
48 | try container.encode(email, forKey: .email)
49 | try container.encode(token, forKey: .token)
50 | try container.encode(password, forKey: .password)
51 | try container.encode(passwordConfirmation, forKey: .passwordConfirmation)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Source/Client/Models/Wallet+Client.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Wallet+Client.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension Wallet {
10 | @discardableResult
11 | /// Get all wallets of the current user
12 | ///
13 | /// - Parameters:
14 | /// - client: An API client.
15 | /// This client need to be initialized with a ClientConfiguration struct before being used.
16 | /// - callback: The closure called when the request is completed
17 | /// - Returns: An optional cancellable request.
18 | public static func getAll(using client: HTTPClientAPI,
19 | callback: @escaping Wallet.ListRequestCallback) -> Wallet.ListRequest? {
20 | return self.list(using: client, endpoint: APIClientEndpoint.getWallets, callback: callback)
21 | }
22 |
23 | @discardableResult
24 | /// Get the main wallet for the current user
25 | ///
26 | /// - Parameters:
27 | /// - client: An API client.
28 | /// This client need to be initialized with a ClientConfiguration struct before being used.
29 | /// - callback: The closure called when the request is completed
30 | /// - Returns: An optional cancellable request.
31 | public static func getMain(using client: HTTPClientAPI,
32 | callback: @escaping Wallet.RetrieveRequestCallback) -> Wallet.ListRequest? {
33 | return self.list(using: client, endpoint: APIClientEndpoint.getWallets, callback: { response in
34 | switch response {
35 | case let .success(data: wallets):
36 | if wallets.isEmpty {
37 | callback(Response.fail(error: OMGError.unexpected(message: "No wallet received.")))
38 | } else {
39 | callback(.success(data: wallets.first!))
40 | }
41 | case let .fail(error: error):
42 | callback(.fail(error: error))
43 | }
44 |
45 | })
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Source/Client/QRCode/QRClientVerifier.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRClientVerifier.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | public struct QRClientVerifier: QRVerifier {
10 | let client: HTTPClientAPI
11 |
12 | public init(client: HTTPClientAPI) {
13 | self.client = client
14 | }
15 |
16 | public func onData(data: String, callback: @escaping (Response) -> Void) {
17 | TransactionRequest.get(using: self.client, formattedId: data, callback: callback)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Source/Client/QRCode/QRScannerViewController+Client.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRScannerViewController+Client.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 8/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension QRScannerViewController {
10 | /// Initialize the QR code scanner. You should always use this method to initialize it.
11 | ///
12 | /// - Parameters:
13 | /// - delegate: The delegate that will receive the events from the scanner
14 | /// - verifier: A QRClientVerifier that will take care of processing the scanned data
15 | /// - cancelButtonTitle: The title of the cancel button
16 | /// - Returns: An optional cancellable request.
17 | public convenience init?(delegate: QRScannerViewControllerDelegate, verifier: QRClientVerifier, cancelButtonTitle: String) {
18 | self.init(delegate: delegate,
19 | verifier: verifier,
20 | cancelButtonTitle: cancelButtonTitle,
21 | viewModel: QRScannerViewModel(verifier: verifier))
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Source/Client/Websocket/SocketClient+Client.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketClient+Client.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 8/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | extension SocketClient {
10 | /// Initialize a websocket client using a configuration object
11 | ///
12 | /// - Parameters:
13 | /// - config: The configuration object containing the client configuration
14 | /// - delegate: The delegate that should receive connection events
15 | /// - Note: the baseURL of the Configuration needs to be a socket url (wss://your.domain.com)
16 | public convenience init(config: ClientConfiguration, delegate: SocketConnectionDelegate?) {
17 | self.init()
18 | self.config = config
19 | self.delegate = delegate
20 | self.initWebSocket()
21 | }
22 |
23 | /// Invalidate the current (if any) socket connection and prepare the client for a new one with the updated configuration.
24 | /// Note that the active connection will be droped and any topic currently subscribed will be unsubscribed.
25 | /// You will need to start listening for events again.
26 | ///
27 | /// - Parameter configuration: The updated Configuration
28 | public func updateConfiguration(_ configuration: ClientConfiguration) {
29 | self.config = configuration
30 | self.cleanup()
31 | self.initWebSocket()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Source/Core/API/APIEndpoint.swift:
--------------------------------------------------------------------------------
1 | //
2 | // APIEndpoint.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Protocol with the required variable to build an enpoint
10 | protocol APIEndpoint {
11 | var path: String { get }
12 | var task: HTTPTask { get }
13 | }
14 |
--------------------------------------------------------------------------------
/Source/Core/API/Configuration.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Configuration.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Protocol containing the required variable for the initialization of a Client
10 | protocol Configuration {
11 | /// The current SDK version
12 | var apiVersion: String { get }
13 | /// The base URL of the wallet server:
14 | /// When initializing the HTTPAPI, this needs to be an http(s) url
15 | /// When initializing the SocketClient, this needs to be a ws(s) url
16 | var baseURL: String { get }
17 | /// The credential object containing the authentication info if needed
18 | var credentials: Credential { get set }
19 | /// A boolean indicating if the debug logs should be printed to the console
20 | var debugLog: Bool { get }
21 | }
22 |
--------------------------------------------------------------------------------
/Source/Core/API/Credential.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Credential.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 6/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Contains the required functions that a configuration object would need to authenticate an API call if needed
10 | protocol Credential {
11 | func isAuthenticated() -> Bool
12 | func authentication() throws -> String?
13 | mutating func update(withAuthenticationToken authenticationToken: AuthenticationToken)
14 | mutating func invalidate()
15 | }
16 |
--------------------------------------------------------------------------------
/Source/Core/API/CredentialEncoder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CredentialEncoder.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 6/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | struct CredentialEncoder {
10 | static func encode(value1: String, value2: String, scheme: String) throws -> String {
11 | let keys = "\(value1):\(value2)"
12 | let data = keys.data(using: .utf8, allowLossyConversion: false)
13 |
14 | guard let encodedKey = data?.base64EncodedString() else {
15 | throw OMGError.configuration(message: "Failed to encode authorization header")
16 | }
17 |
18 | return "\(scheme) \(encodedKey)"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Source/Core/API/HTTPAPI.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPAPI.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents an HTTPAPI that should be initialized using a Configuration
10 | public class HTTPAPI {
11 | let operationQueue: OperationQueue = OperationQueue()
12 |
13 | lazy var session: URLSession = {
14 | URLSession(configuration: URLSessionConfiguration.ephemeral,
15 | delegate: nil,
16 | delegateQueue: self.operationQueue)
17 | }()
18 |
19 | var config: Configuration
20 |
21 | init(config: Configuration) {
22 | self.config = config
23 | }
24 |
25 | /// A boolean indicating if the client is authenticated and allowed to make authenticated requests
26 | public var isAuthenticated: Bool { return self.config.credentials.isAuthenticated() }
27 |
28 | @discardableResult
29 | func request(toEndpoint endpoint: APIEndpoint,
30 | callback: Request.Callback?) -> Request? {
31 | do {
32 | let request: Request = Request(client: self,
33 | endpoint: endpoint,
34 | callback: callback)
35 | return try request.start()
36 | } catch let error as OMGError {
37 | performCallback {
38 | callback?(.fail(error: error))
39 | }
40 | } catch let error as EncodingError {
41 | switch error {
42 | case let .invalidValue(_, context):
43 | performCallback {
44 | callback?(.fail(error: OMGError.unexpected(message: context.debugDescription)))
45 | }
46 | }
47 | } catch _ {
48 | self.performCallback {
49 | callback?(.fail(error: OMGError.unexpected(message: "Could not build the request")))
50 | }
51 | }
52 |
53 | return nil
54 | }
55 |
56 | private func performCallback(_ callback: @escaping () -> Void) {
57 | OperationQueue.main.addOperation(callback)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Source/Core/API/HTTPTask.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPTask.swift
3 | // OmiseGO
4 | //
5 | // Created by yuzushioh on2017-2018/05/11.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Protocol for api parameters
10 | public protocol APIParameters: Encodable {}
11 |
12 | extension APIParameters {
13 | public func encodedPayload() throws -> Data {
14 | return try serialize(self)
15 | }
16 | }
17 |
18 | /// Represents an HTTP task.
19 | enum HTTPTask {
20 | /// A request with no additional data.
21 | case requestPlain
22 | /// A requests body set with encoded parameters.
23 | case requestParameters(parameters: APIParameters)
24 |
25 | /// Parameters required for task's request
26 | /// nil if tasks do not require any parameters
27 | public var parameters: APIParameters? {
28 | switch self {
29 | case let .requestParameters(parameters):
30 | return parameters
31 | case .requestPlain:
32 | return nil
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Source/Core/API/RequestBuilder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBuilder.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 16/3/18.
6 | //
7 |
8 | import UIKit
9 |
10 | final class RequestBuilder {
11 | private let configuration: Configuration
12 |
13 | init(configuration: Configuration) {
14 | self.configuration = configuration
15 | }
16 |
17 | func buildHTTPURLRequest(withEndpoint endpoint: APIEndpoint) throws -> URLRequest {
18 | guard let requestURL = URL(string: self.configuration.baseURL)?.appendingPathComponent(endpoint.path) else {
19 | throw OMGError.configuration(message: "Invalid base url")
20 | }
21 |
22 | var request = URLRequest(url: requestURL)
23 | request.httpMethod = "POST"
24 | request.cachePolicy = .useProtocolCachePolicy
25 | request.timeoutInterval = 6.0
26 |
27 | try addRequiredHeaders(toRequest: &request)
28 |
29 | // Add endpoint's task parameters if necessary
30 | if let parameters = endpoint.task.parameters {
31 | let payload = try parameters.encodedPayload()
32 | request.httpBody = payload
33 | request.addValue(String(payload.count), forHTTPHeaderField: "Content-Length")
34 | }
35 |
36 | return request
37 | }
38 |
39 | func buildWebsocketRequest() throws -> URLRequest {
40 | guard let url = URL(string: self.configuration.baseURL + "/socket") else {
41 | throw OMGError.configuration(message: "Invalid base url")
42 | }
43 |
44 | var request = URLRequest(url: url)
45 | request.timeoutInterval = 6.0
46 | try addRequiredHeaders(toRequest: &request)
47 | return request
48 | }
49 |
50 | func contentTypeHeader() -> String {
51 | return "application/vnd.omisego.v\(self.configuration.apiVersion)+json; charset=utf-8"
52 | }
53 |
54 | func acceptHeader() -> String {
55 | return "application/vnd.omisego.v\(self.configuration.apiVersion)+json"
56 | }
57 |
58 | private func addRequiredHeaders(toRequest request: inout URLRequest) throws {
59 | if let auth = try self.configuration.credentials.authentication() {
60 | request.addValue(auth, forHTTPHeaderField: "Authorization")
61 | }
62 | request.addValue(self.acceptHeader(), forHTTPHeaderField: "Accept")
63 | request.addValue(self.contentTypeHeader(), forHTTPHeaderField: "Content-Type")
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Source/Core/Models/AuthenticationToken.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthenticationToken.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 15/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | public struct AuthenticationToken {
10 | /// The unique authentication token corresponding to the provided credentials
11 | public let token: String
12 | /// The user corresponding to the token
13 | public let user: User
14 | }
15 |
16 | extension AuthenticationToken: Decodable {
17 | private enum CodingKeys: String, CodingKey {
18 | case token = "authentication_token"
19 | case user
20 | }
21 |
22 | public init(from decoder: Decoder) throws {
23 | let container = try decoder.container(keyedBy: CodingKeys.self)
24 | token = try container.decode(String.self, forKey: .token)
25 | user = try container.decode(User.self, forKey: .user)
26 | }
27 | }
28 |
29 | extension AuthenticationToken: Hashable {
30 | public var hashValue: Int {
31 | return self.token.hashValue
32 | }
33 |
34 | public static func == (lhs: AuthenticationToken, rhs: AuthenticationToken) -> Bool {
35 | return lhs.token == rhs.token
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Source/Core/Models/Avatar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Avatar.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 18/4/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents an avatar containing urls of different sizes
10 | public struct Avatar: Decodable {
11 | /// The url of the original image
12 | public let original: String?
13 | /// The url of the large image
14 | public let large: String?
15 | /// The url of the small image
16 | public let small: String?
17 | /// The url of the thumbnail image
18 | public let thumb: String?
19 | }
20 |
--------------------------------------------------------------------------------
/Source/Core/Models/Balance.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Balance.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import BigInt
10 |
11 | /// Represents a balance of a token
12 | public struct Balance: Decodable {
13 | /// The token corresponding to the balance
14 | public let token: Token
15 | /// The total amount of token available
16 | public let amount: BigInt
17 | }
18 |
19 | extension Balance {
20 | /// Helper method that returns an easily readable value of the amount
21 | ///
22 | /// - Parameter precision: The decimal precision to give to the formatter
23 | /// for example a number 0.123 with a precision of 1 will be 0.1
24 | /// - Returns: the formatted balance amount
25 | public func displayAmount(withPrecision precision: Int = 1000) -> String {
26 | return OMGNumberFormatter(precision: precision).string(from: self.amount, subunitToUnit: self.token.subUnitToUnit)
27 | }
28 | }
29 |
30 | extension Balance: Hashable {
31 | public var hashValue: Int {
32 | return self.token.hashValue
33 | }
34 |
35 | public static func == (lhs: Balance, rhs: Balance) -> Bool {
36 | return lhs.token == rhs.token
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Source/Core/Models/CollectionParams/PaginatedListParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PaginatedListParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 17/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public protocol RawEnumerable: Hashable, RawRepresentable, Encodable {}
12 |
13 | public struct PaginatedListParams {
14 | let sortParams: SortParams
15 | let filterParams: FilterParams?
16 | let paginationParams: PaginationParams
17 |
18 | /// Initialize the params used to query a paginated collection
19 | ///
20 | /// - Parameters:
21 | /// - page: The page requested (0 and 1 are the same)
22 | /// - perPage: The number of result expected per page
23 | /// - filters: A FilterParams struc used to filter the results
24 | /// - sortBy: The field to sort by
25 | /// - sortDirection: The sort direction (ascending or descending)
26 | public init(page: Int,
27 | perPage: Int,
28 | filters: FilterParams? = nil,
29 | sortBy: T.SortableFields,
30 | sortDirection: SortDirection) {
31 | self.paginationParams = PaginationParams(page: page, perPage: perPage)
32 | self.filterParams = filters
33 | self.sortParams = SortParams(sortBy: sortBy, sortDirection: sortDirection)
34 | }
35 | }
36 |
37 | extension PaginatedListParams: APIParameters {
38 | public func encode(to encoder: Encoder) throws {
39 | try self.sortParams.encode(to: encoder)
40 | try self.filterParams?.encode(to: encoder)
41 | try self.paginationParams.encode(to: encoder)
42 | }
43 | }
44 |
45 | extension PaginatedListable {
46 | public static func paginatedListParams(page: Int,
47 | perPage: Int,
48 | filters: FilterParams? = nil,
49 | sortBy: SortableFields,
50 | sortDirection: SortDirection) -> PaginatedListParams {
51 | return PaginatedListParams(page: page,
52 | perPage: perPage,
53 | filters: filters,
54 | sortBy: sortBy,
55 | sortDirection: sortDirection)
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Source/Core/Models/CollectionParams/PaginationParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PaginationParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 17/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a structure used to query a paginated list
10 | struct PaginationParams {
11 | /// The page requested (0 and 1 are the same)
12 | public let page: Int
13 | /// The number of result expected per page
14 | public let perPage: Int
15 |
16 | /// Initialize the params used to query a paginated collection
17 | ///
18 | /// - Parameters:
19 | /// - page: The page requested (0 and 1 are the same)
20 | /// - perPage: The number of result expected per page
21 | public init(page: Int,
22 | perPage: Int) {
23 | self.page = page
24 | self.perPage = perPage
25 | }
26 | }
27 |
28 | extension PaginationParams: APIParameters {
29 | enum CodingKeys: String, CodingKey {
30 | case page
31 | case perPage = "per_page"
32 | }
33 |
34 | public func encode(to encoder: Encoder) throws {
35 | var container = encoder.container(keyedBy: CodingKeys.self)
36 | try container.encode(page, forKey: .page)
37 | try container.encode(perPage, forKey: .perPage)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Source/Core/Models/CollectionParams/SortParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SortParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 17/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// The desired sort direction
10 | ///
11 | /// - ascending: Ascending
12 | /// - descending: Descending
13 | public enum SortDirection: String, Encodable {
14 | case ascending = "asc"
15 | case descending = "desc"
16 | }
17 |
18 | public protocol Sortable {
19 | associatedtype SortableFields: RawEnumerable where SortableFields.RawValue == String
20 | }
21 |
22 | /// Represents a structure used to query a sortable list
23 | struct SortParams {
24 | /// The field to sort by
25 | public let sortBy: T.SortableFields
26 | /// The sort direction (ascending or descending)
27 | public let sortDirection: SortDirection
28 |
29 | /// Initialize the params used to query a sortable collection
30 | ///
31 | /// - Parameters:
32 | /// - sortBy: The field to sort by
33 | /// - sortDirection: The sort direction (ascending or descending)
34 | public init(sortBy: T.SortableFields,
35 | sortDirection: SortDirection) {
36 | self.sortBy = sortBy
37 | self.sortDirection = sortDirection
38 | }
39 | }
40 |
41 | extension SortParams: APIParameters {
42 | enum CodingKeys: String, CodingKey {
43 | case sortBy = "sort_by"
44 | case sortDirection = "sort_dir"
45 | }
46 |
47 | public func encode(to encoder: Encoder) throws {
48 | var container = encoder.container(keyedBy: CodingKeys.self)
49 | try container.encode(self.sortBy, forKey: .sortBy)
50 | try container.encode(self.sortDirection, forKey: .sortDirection)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Source/Core/Models/EmptyResponse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EmptyResponse.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | // Represents an empty response from the server.
10 | public struct EmptyResponse: Decodable {}
11 |
--------------------------------------------------------------------------------
/Source/Core/Models/ExchangePair.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExchangePair.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 29/6/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | /// An ExchangePair describes 2 tradable tokens with a specific rate
12 | public struct ExchangePair {
13 | /// The unique identifier of the exchange pair
14 | public let id: String
15 | /// The name of the pair (ex: ETH/BTC)
16 | public let name: String
17 | /// The 1st token id of the pair
18 | public let fromTokenId: String
19 | /// The 1st token of the pair
20 | public let fromToken: Token
21 | /// The 2nd token id of the pair
22 | public let toTokenId: String
23 | /// The 2nd token of the pair
24 | public let toToken: Token
25 | /// The rate between both tokens (token2/token1)
26 | public let rate: Double
27 | /// The creation date of the pair
28 | public let createdAt: Date
29 | /// The last update date of the pair
30 | public let updatedAt: Date
31 | }
32 |
33 | extension ExchangePair: Decodable {
34 | private enum CodingKeys: String, CodingKey {
35 | case id
36 | case name
37 | case fromTokenId = "from_token_id"
38 | case fromToken = "from_token"
39 | case toTokenId = "to_token_id"
40 | case toToken = "to_token"
41 | case rate
42 | case createdAt = "created_at"
43 | case updatedAt = "updated_at"
44 | }
45 |
46 | public init(from decoder: Decoder) throws {
47 | let container = try decoder.container(keyedBy: CodingKeys.self)
48 | id = try container.decode(String.self, forKey: .id)
49 | name = try container.decode(String.self, forKey: .name)
50 | fromTokenId = try container.decode(String.self, forKey: .fromTokenId)
51 | fromToken = try container.decode(Token.self, forKey: .fromToken)
52 | toTokenId = try container.decode(String.self, forKey: .toTokenId)
53 | toToken = try container.decode(Token.self, forKey: .toToken)
54 | rate = try container.decode(Double.self, forKey: .rate)
55 | createdAt = try container.decode(Date.self, forKey: .createdAt)
56 | updatedAt = try container.decode(Date.self, forKey: .updatedAt)
57 | }
58 | }
59 |
60 | extension ExchangePair: Hashable {
61 | public var hashValue: Int {
62 | return self.id.hashValue
63 | }
64 |
65 | public static func == (lhs: ExchangePair, rhs: ExchangePair) -> Bool {
66 | return lhs.id == rhs.id
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Source/Core/Models/JSONListResponse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JSONListResponse.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 10/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a list response containing a data array of generic items.
10 | public struct JSONListResponse: Decodable {
11 | let data: [Item]
12 | }
13 |
14 | /// Represents a list response containing a data array of generic items and a pagination object.
15 | public struct JSONPaginatedListResponse: Decodable {
16 | public let data: [Item]
17 | public let pagination: Pagination
18 | }
19 |
--------------------------------------------------------------------------------
/Source/Core/Models/JSONResponse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JSONResponse.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 10/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | struct JSONResponse {
10 | let version: String
11 | let success: Bool
12 | let data: Response
13 | }
14 |
15 | extension JSONResponse: Decodable {
16 | private enum CodingKeys: String, CodingKey {
17 | case version
18 | case success
19 | case data
20 | }
21 |
22 | init(from decoder: Decoder) throws {
23 | let container = try decoder.container(keyedBy: CodingKeys.self)
24 | version = try container.decode(String.self, forKey: .version)
25 | success = try container.decode(Bool.self, forKey: .success)
26 | if self.success {
27 | let result = try container.decode(ObjectType.self, forKey: .data)
28 | data = .success(data: result)
29 | } else {
30 | let error = try container.decode(APIError.self, forKey: .data)
31 | data = .fail(error: .api(apiError: error))
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Source/Core/Models/LoginParams.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoginParams.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 15/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a structure used to login an existing user
10 | public struct LoginParams {
11 | public let email: String
12 | public let password: String
13 |
14 | /// Initialize the params used to login a user
15 | ///
16 | /// - Parameters:
17 | /// - email: The email of the user
18 | /// - password: The password of the user
19 | public init(email: String, password: String) {
20 | self.email = email
21 | self.password = password
22 | }
23 | }
24 |
25 | extension LoginParams: APIParameters {
26 | private enum CodingKeys: String, CodingKey {
27 | case email
28 | case password
29 | }
30 |
31 | public func encode(to encoder: Encoder) throws {
32 | var container = encoder.container(keyedBy: CodingKeys.self)
33 | try container.encode(email, forKey: .email)
34 | try container.encode(password, forKey: .password)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Source/Core/Models/Pagination.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Pagination.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 23/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a pagination object contained in a paginated list response
10 | public struct Pagination: Decodable {
11 | /// The number of result per page
12 | public let perPage: Int
13 | /// The current page requested
14 | public let currentPage: Int
15 | /// Indicates if the page requested is the first one
16 | public let isFirstPage: Bool
17 | /// Indicates if the page requested is the last one
18 | public let isLastPage: Bool
19 |
20 | private enum CodingKeys: String, CodingKey {
21 | case perPage = "per_page"
22 | case currentPage = "current_page"
23 | case isFirstPage = "is_first_page"
24 | case isLastPage = "is_last_page"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Source/Core/Models/Reponse.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Response.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents whether an API request was successfull or encountered an error.
10 | ///
11 | /// - success: The request and post processing operations were successful resulting in the serialization
12 | /// of the provided associated Data
13 | /// - fail: The request encountered an error resulting in a failure
14 | public enum Response {
15 | case success(data: Data)
16 | case fail(error: OMGError)
17 | }
18 |
--------------------------------------------------------------------------------
/Source/Core/Models/Setting.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Setting.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents the global settings of the eWallet
10 | public struct Setting: Decodable {
11 | /// An array of tokens available
12 | public let tokens: [Token]
13 | }
14 |
--------------------------------------------------------------------------------
/Source/Core/Models/Token.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Token.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import BigInt
10 |
11 | /// Represents a token
12 | public struct Token {
13 | /// The id of the token
14 | public let id: String
15 | /// The symbol of the token
16 | public let symbol: String
17 | /// The full name of the token
18 | public let name: String
19 | /// The multiplier representing the value of 1 token. i.e: if I want to give or receive
20 | /// 13 tokens and the subunitToUnit is 1000 then the amount will be 13*1000 = 13000
21 | public let subUnitToUnit: BigInt
22 | /// Any additional metadata that need to be stored as a dictionary
23 | public let metadata: [String: Any]
24 | /// Any additional encrypted metadata that need to be stored as a dictionary
25 | public let encryptedMetadata: [String: Any]
26 | /// The creation date of the token
27 | public let createdAt: Date
28 | /// The last update date of the token
29 | public let updatedAt: Date
30 | }
31 |
32 | extension Token: Decodable {
33 | private enum CodingKeys: String, CodingKey {
34 | case id
35 | case symbol
36 | case name
37 | case subUnitToUnit = "subunit_to_unit"
38 | case metadata
39 | case encryptedMetadata = "encrypted_metadata"
40 | case createdAt = "created_at"
41 | case updatedAt = "updated_at"
42 | }
43 |
44 | public init(from decoder: Decoder) throws {
45 | let container = try decoder.container(keyedBy: CodingKeys.self)
46 | id = try container.decode(String.self, forKey: .id)
47 | symbol = try container.decode(String.self, forKey: .symbol)
48 | name = try container.decode(String.self, forKey: .name)
49 | subUnitToUnit = try container.decode(BigInt.self, forKey: .subUnitToUnit)
50 | metadata = try container.decode([String: Any].self, forKey: .metadata)
51 | encryptedMetadata = try container.decode([String: Any].self, forKey: .encryptedMetadata)
52 | createdAt = try container.decode(Date.self, forKey: .createdAt)
53 | updatedAt = try container.decode(Date.self, forKey: .updatedAt)
54 | }
55 | }
56 |
57 | extension Token: Hashable {
58 | public var hashValue: Int {
59 | return self.id.hashValue
60 | }
61 |
62 | public static func == (lhs: Token, rhs: Token) -> Bool {
63 | return lhs.id == rhs.id
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Source/Core/Models/TransactionExchange.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionExchange.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 27/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents a transaction exchange
10 | public struct TransactionExchange {
11 | /// The exchange rate used in the transaction. This can be nil if there was no exchange involved.
12 | public let rate: Double?
13 | /// The date when the exchange was processed
14 | public let calculatedAt: Date?
15 | /// The id of the exchange pair used
16 | public let exchangePairId: String?
17 | /// The exchange pair used in the exchange (if any)
18 | public let exchangePair: ExchangePair?
19 | /// The id of the account used for exchanging the funds
20 | public let exchangeAccountId: String?
21 | /// The account used for exchanging the funds
22 | public let exchangeAccount: Account?
23 | /// The address of the wallet used for exchanging the funds
24 | public let exchangeWalletAddress: String?
25 | /// The wallet used for exchanging the funds
26 | public let exchangeWallet: Wallet?
27 | }
28 |
29 | extension TransactionExchange: Decodable {
30 | private enum CodingKeys: String, CodingKey {
31 | case rate
32 | case calculatedAt = "calculated_at"
33 | case exchangePairId = "exchange_pair_id"
34 | case exchangePair = "exchange_pair"
35 | case exchangeAccountId = "exchange_account_id"
36 | case exchangeAccount = "exchange_account"
37 | case exchangeWalletAddress = "exchange_wallet_address"
38 | case exchangeWallet = "exchange_wallet"
39 | }
40 |
41 | public init(from decoder: Decoder) throws {
42 | let container = try decoder.container(keyedBy: CodingKeys.self)
43 | rate = try container.decodeIfPresent(Double.self, forKey: .rate)
44 | calculatedAt = try container.decodeIfPresent(Date.self, forKey: .calculatedAt)
45 | exchangePairId = try container.decodeIfPresent(String.self, forKey: .exchangePairId)
46 | exchangePair = try container.decodeIfPresent(ExchangePair.self, forKey: .exchangePair)
47 | exchangeAccountId = try container.decodeIfPresent(String.self, forKey: .exchangeAccountId)
48 | exchangeAccount = try container.decodeIfPresent(Account.self, forKey: .exchangeAccount)
49 | exchangeWalletAddress = try container.decodeIfPresent(String.self, forKey: .exchangeWalletAddress)
50 | exchangeWallet = try container.decodeIfPresent(Wallet.self, forKey: .exchangeWallet)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Source/Core/Models/TransactionSource.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionSource.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 27/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import BigInt
10 |
11 | /// Represents a transaction source contained in a transaction object
12 | public struct TransactionSource {
13 | /// The address of the source
14 | public let address: String
15 | /// The amount of token (down to subunit to unit)
16 | public let amount: BigInt
17 | /// The token of the source
18 | public let token: Token
19 | /// The user corresponding to the source (if any)
20 | public let user: User?
21 | /// The account corresponding to the source (if any)
22 | public let account: Account?
23 | }
24 |
25 | extension TransactionSource: Decodable {
26 | private enum CodingKeys: String, CodingKey {
27 | case address
28 | case amount
29 | case token
30 | case user
31 | case account
32 | }
33 |
34 | public init(from decoder: Decoder) throws {
35 | let container = try decoder.container(keyedBy: CodingKeys.self)
36 | address = try container.decode(String.self, forKey: .address)
37 | amount = try container.decode(BigInt.self, forKey: .amount)
38 | token = try container.decode(Token.self, forKey: .token)
39 | user = try container.decodeIfPresent(User.self, forKey: .user)
40 | account = try container.decodeIfPresent(Account.self, forKey: .account)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Source/Core/Operations/Listable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Listable.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represents an object that can be retrived in a collection
10 | public protocol Listable {}
11 |
12 | public extension Listable where Self: Decodable {
13 | public typealias ListRequest = Request>
14 | public typealias ListRequestCallback = (Response<[Self]>) -> Void
15 |
16 | @discardableResult
17 | internal static func list(using client: HTTPAPI,
18 | endpoint: APIEndpoint,
19 | callback: @escaping ListRequestCallback) -> ListRequest? {
20 | return client.request(toEndpoint: endpoint, callback: { result in
21 | switch result {
22 | case let .success(list):
23 | callback(.success(data: list.data))
24 | case let .fail(error):
25 | callback(.fail(error: error))
26 | }
27 | })
28 | }
29 | }
30 |
31 | /// Represents an object that can be retrieved in a paginated collection
32 | public protocol PaginatedListable: Filterable, Sortable {}
33 |
34 | public extension PaginatedListable where Self: Decodable {
35 | public typealias PaginatedListRequest = Request>
36 | public typealias PaginatedListRequestCallback = (Response>) -> Void
37 |
38 | @discardableResult
39 | internal static func list(using client: HTTPAPI,
40 | endpoint: APIEndpoint,
41 | callback: @escaping PaginatedListRequestCallback) -> PaginatedListRequest? {
42 | return client.request(toEndpoint: endpoint, callback: { result in
43 | switch result {
44 | case let .success(list):
45 | callback(.success(data: list))
46 | case let .fail(error):
47 | callback(.fail(error: error))
48 | }
49 | })
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Source/Core/Operations/QREncodable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QREncodable.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 5/6/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// A protocol that takes care of the encoding and generating QR images of different structs
10 | public protocol QREncodable {
11 | func qrImage(withSize size: CGSize) -> UIImage?
12 | }
13 |
14 | public extension QREncodable where Self == TransactionRequest {
15 | /// Generates a QR image containing the encoded transaction request formattedId
16 | ///
17 | /// - Parameter size: the desired image size
18 | /// - Returns: A QR image if the transaction request was successfuly encoded, nil otherwise.
19 | public func qrImage(withSize size: CGSize = CGSize(width: 200, height: 200)) -> UIImage? {
20 | guard let data = self.formattedId.data(using: .isoLatin1) else { return nil }
21 | return QRGenerator.generateQRCode(fromData: data, outputSize: size)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Source/Core/Operations/Retrievable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Retrievable.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 11/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Represent an Object that can be uniquely retrived
10 | public protocol Retrievable {}
11 |
12 | public extension Retrievable where Self: Decodable {
13 | public typealias RetrieveRequest = Request
14 | public typealias RetrieveRequestCallback = RetrieveRequest.Callback
15 |
16 | @discardableResult
17 | internal static func retrieve(using client: HTTPAPI,
18 | endpoint: T,
19 | callback: @escaping RetrieveRequestCallback) -> RetrieveRequest? {
20 | return client.request(toEndpoint: endpoint, callback: callback)
21 | }
22 |
23 | @discardableResult
24 | internal func retrieve(using client: HTTPAPI,
25 | endpoint: T,
26 | callback: @escaping RetrieveRequestCallback) -> RetrieveRequest? {
27 | return client.request(toEndpoint: endpoint, callback: callback)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Source/Core/QRCode/QRGenerator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRGenerator.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 6/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct QRGenerator {
12 | static func generateQRCode(fromData data: Data, outputSize: CGSize) -> UIImage? {
13 | guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
14 |
15 | qrFilter.setDefaults()
16 | qrFilter.setValue(data, forKey: "inputMessage")
17 |
18 | guard let ciImage = qrFilter.outputImage else { return nil }
19 |
20 | let ciImageSize = ciImage.extent.size
21 | let wRatio = outputSize.width / ciImageSize.width
22 | let hRatio = outputSize.height / ciImageSize.height
23 | let transform = CGAffineTransform(scaleX: wRatio, y: hRatio)
24 | let scaledImage = ciImage.transformed(by: transform)
25 | let ciContext = CIContext()
26 | guard let cgImage = ciContext.createCGImage(scaledImage, from: scaledImage.extent) else { return nil }
27 | return UIImage(cgImage: cgImage)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Source/Core/QRCode/QRScannerLoadingView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRScannerLoadingView.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class QRScannerLoadingView: UIView {
12 | lazy var loadingSpinner: UIActivityIndicatorView = {
13 | let spinner = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.whiteLarge)
14 | spinner.hidesWhenStopped = true
15 | spinner.translatesAutoresizingMaskIntoConstraints = false
16 | self.addSubview(spinner)
17 | [NSLayoutConstraint.Attribute.centerX, NSLayoutConstraint.Attribute.centerY].forEach({ attribute in
18 | self.addConstraint(NSLayoutConstraint(item: spinner,
19 | attribute: attribute,
20 | relatedBy: .equal,
21 | toItem: self,
22 | attribute: attribute,
23 | multiplier: 1,
24 | constant: 0))
25 | })
26 | return spinner
27 | }()
28 |
29 | override init(frame: CGRect) {
30 | super.init(frame: frame)
31 | self.backgroundColor = .clear
32 | }
33 |
34 | required init?(coder aDecoder: NSCoder) {
35 | super.init(coder: aDecoder)
36 | self.backgroundColor = .clear
37 | }
38 |
39 | func showLoading() {
40 | self.loadingSpinner.startAnimating()
41 | }
42 |
43 | func hideLoading() {
44 | self.loadingSpinner.stopAnimating()
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Source/Core/QRCode/QRScannerOverlayView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRScannerOverlayView.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class QRScannerOverlayView: UIView {
12 | private lazy var outlineLayer: CAShapeLayer = {
13 | let outlineLayer = CAShapeLayer()
14 | outlineLayer.backgroundColor = UIColor.clear.cgColor
15 | outlineLayer.fillColor = UIColor.clear.cgColor
16 | outlineLayer.strokeColor = UIColor.white.cgColor
17 | outlineLayer.lineWidth = 2
18 | outlineLayer.lineDashPattern = [5.0, 4.0]
19 | outlineLayer.lineDashPhase = 0
20 | return outlineLayer
21 | }()
22 |
23 | private lazy var maskLayer: CAShapeLayer = {
24 | let maskLayer = CAShapeLayer()
25 | maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
26 | maskLayer.fillColor = UIColor.black.cgColor
27 | maskLayer.opacity = 0.6
28 | return maskLayer
29 | }()
30 |
31 | override func draw(_ rect: CGRect) {
32 | var innerRect = rect.insetBy(dx: 50, dy: 50)
33 | let minSize = min(innerRect.width, innerRect.height)
34 |
35 | if innerRect.width != minSize {
36 | innerRect.origin.x += (innerRect.width - minSize) / 2
37 | innerRect.size.width = minSize
38 | } else if innerRect.height != minSize {
39 | innerRect.origin.y += (innerRect.height - minSize) / 2
40 | innerRect.size.height = minSize
41 | }
42 | let innerPath = UIBezierPath(roundedRect: innerRect, cornerRadius: 3)
43 | let outerPath = UIBezierPath(rect: rect)
44 | outerPath.usesEvenOddFillRule = true
45 | outerPath.append(innerPath)
46 |
47 | self.outlineLayer.path = innerPath.cgPath
48 | self.maskLayer.path = outerPath.cgPath
49 |
50 | self.layer.addSublayer(self.outlineLayer)
51 | self.layer.addSublayer(self.maskLayer)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Source/Core/QRCode/QRVerifier.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRVerifier.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 7/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// Takes care of fetching objects decoded by the QR code scanner.
10 | public protocol QRVerifier {
11 | func onData(data: String, callback: @escaping Request.Callback)
12 | }
13 |
--------------------------------------------------------------------------------
/Source/Core/Websocket/SocketChannel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketChannel.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | protocol SocketSendable: class {
10 | func send(topic: String, event: SocketEventSend) -> SocketMessage
11 | }
12 |
13 | struct SocketChannel {
14 | let topic: String
15 | private let dispatcher: SocketDispatcher?
16 | private weak var socket: SocketSendable?
17 |
18 | init(topic: String, socket: SocketSendable, dispatcher: SocketDispatcher?) {
19 | self.topic = topic
20 | self.socket = socket
21 | self.dispatcher = dispatcher
22 | }
23 |
24 | func join() {
25 | self.socket?.send(topic: self.topic, event: .join).onSuccess({ _ in
26 | self.dispatcher?.dispatchJoin()
27 | })
28 | }
29 |
30 | func leave(onSuccess: @escaping (() -> Void)) {
31 | self.socket?.send(topic: self.topic, event: .leave).onSuccess({ _ in
32 | self.dispatcher?.dispatchLeave()
33 | onSuccess()
34 | })
35 | }
36 |
37 | func dispatchEvents(forMessage message: SocketMessage) {
38 | guard let payload = message.dataReceived else { return }
39 | self.dispatcher?.dispatchPayload(payload)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Source/Core/Websocket/SocketDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketDelegate.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | /// A protocol containing the websocket connection events
10 | public protocol SocketConnectionDelegate: class {
11 | func didConnect()
12 | func didDisconnect(_ error: OMGError?)
13 | }
14 |
15 | /// The root protocol of all events that are available when listening any topic
16 | public protocol EventDelegate: class {
17 | func didStartListening()
18 | func didStopListening()
19 | func onError(_ error: APIError)
20 | }
21 |
22 | /// The protocol containing events that are dispatched when listening to a user topic
23 | public protocol UserEventDelegate: EventDelegate {
24 | func on(_ object: WebsocketObject, error: APIError?, forEvent event: SocketEvent)
25 | }
26 |
27 | /// The protocol containing events that are dispatched when listening to a transaction request topic
28 | public protocol TransactionRequestEventDelegate: EventDelegate {
29 | func onTransactionConsumptionRequest(_ transactionConsumption: TransactionConsumption)
30 | func onSuccessfulTransactionConsumptionFinalized(_ transactionConsumption: TransactionConsumption)
31 | func onFailedTransactionConsumptionFinalized(_ transactionConsumption: TransactionConsumption, error: APIError)
32 | }
33 |
34 | /// The protocol containing events that are dispatched when listening to a transaction consumption topic
35 | public protocol TransactionConsumptionEventDelegate: EventDelegate {
36 | func onSuccessfulTransactionConsumptionFinalized(_ transactionConsumption: TransactionConsumption)
37 | func onFailedTransactionConsumptionFinalized(_ transactionConsumption: TransactionConsumption, error: APIError)
38 | }
39 |
--------------------------------------------------------------------------------
/Source/Core/Websocket/SocketEvent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketEvent.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 20/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | enum SocketEventSend: String, Encodable {
10 | case heartbeat
11 | case join = "phx_join"
12 | case leave = "phx_leave"
13 | }
14 |
15 | /// This enum describes the diferent event that can be received from the websockets.
16 | ///
17 | /// - reply: A reply from a previously sent message
18 | /// - error: An error that occured
19 | /// - close: Closure of a topic
20 | /// - transactionConsumptionRequest: A new consumption request on a transaction request
21 | /// - transactionConsumptionFinalized: A consumption has been finalized
22 | /// - other: Any other unhandled event (as a string)
23 | public enum SocketEvent: Decodable {
24 | case reply
25 | case error
26 | case close
27 | case transactionConsumptionRequest
28 | case transactionConsumptionFinalized
29 | case other(event: String)
30 |
31 | public var eventName: String {
32 | return self.rawValue
33 | }
34 |
35 | public init(from decoder: Decoder) throws {
36 | let container = try decoder.singleValueContainer()
37 | let event = try container.decode(String.self)
38 | self = SocketEvent(rawValue: event)!
39 | }
40 | }
41 |
42 | extension SocketEvent: RawRepresentable {
43 | public typealias RawValue = String
44 |
45 | public init?(rawValue: String) {
46 | switch rawValue {
47 | case "phx_error": self = .error
48 | case "phx_close": self = .close
49 | case "phx_reply": self = .reply
50 | case "transaction_consumption_request": self = .transactionConsumptionRequest
51 | case "transaction_consumption_finalized": self = .transactionConsumptionFinalized
52 | default: self = .other(event: rawValue)
53 | }
54 | }
55 |
56 | public var rawValue: String {
57 | switch self {
58 | case .error: return "phx_error"
59 | case .close: return "phx_close"
60 | case .reply: return "phx_reply"
61 | case .transactionConsumptionRequest: return "transaction_consumption_request"
62 | case .transactionConsumptionFinalized: return "transaction_consumption_finalized"
63 | case let .other(event: event): return event
64 | }
65 | }
66 | }
67 |
68 | extension SocketEvent: Equatable {
69 | public static func == (lhs: SocketEvent, rhs: SocketEvent) -> Bool {
70 | return lhs.rawValue == rhs.rawValue
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Source/Core/Websocket/SocketMessage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketMessage.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | class SocketMessage {
10 | let dataSent: SocketPayloadSend?
11 | var dataReceived: SocketPayloadReceive?
12 | private var errorHandler: ((APIError) -> Void)?
13 | private var successHandler: ((GenericObjectEnum?) -> Void)?
14 |
15 | init(socketPayload: SocketPayloadSend) {
16 | self.dataSent = socketPayload
17 | }
18 |
19 | init(socketPayload: SocketPayloadReceive) {
20 | self.dataSent = nil
21 | self.dataReceived = socketPayload
22 | }
23 |
24 | @discardableResult
25 | func onSuccess(_ handler: @escaping ((GenericObjectEnum?) -> Void)) -> SocketMessage {
26 | self.successHandler = handler
27 | return self
28 | }
29 |
30 | @discardableResult
31 | func onError(_ handler: @escaping ((APIError) -> Void)) -> SocketMessage {
32 | self.errorHandler = handler
33 | return self
34 | }
35 |
36 | func topic() -> String {
37 | return self.dataSent?.topic ?? self.dataReceived?.topic ?? "undefined"
38 | }
39 |
40 | func handleResponse(withPayload payload: SocketPayloadReceive) {
41 | self.dataReceived = payload
42 | self.fireCallbacksAndCleanup()
43 | }
44 |
45 | private func fireCallbacksAndCleanup() {
46 | defer {
47 | self.errorHandler = nil
48 | self.successHandler = nil
49 | }
50 | if let error = self.dataReceived?.error {
51 | self.errorHandler?(error)
52 | } else {
53 | self.successHandler?(self.dataReceived?.data?.object)
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Source/Core/Websocket/SocketObject.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketObject.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | struct GenericObject {
10 | let object: GenericObjectEnum
11 | }
12 |
13 | extension GenericObject: Decodable {
14 | private enum CodingKeys: String, CodingKey {
15 | case objectType = "object"
16 | }
17 |
18 | public init(from decoder: Decoder) throws {
19 | let container = try decoder.container(keyedBy: CodingKeys.self)
20 | let objectType: String? = try container.decodeIfPresent(String.self, forKey: .objectType)
21 | guard let decodedObject = try GenericObjectEnum(objectType: objectType, decoder: decoder) else {
22 | throw OMGError.socketError(message: "Unknown object type")
23 | }
24 | self.object = decodedObject
25 | }
26 | }
27 |
28 | public enum WebsocketObject {
29 | case transactionConsumption(object: TransactionConsumption)
30 | }
31 |
32 | enum GenericObjectEnum {
33 | case transactionConsumption(object: TransactionConsumption)
34 | case error(error: OMGError)
35 | case other(object: [String: Any])
36 | }
37 |
38 | extension GenericObjectEnum {
39 | init?(objectType: String?, decoder: Decoder) throws {
40 | guard let objectType = objectType else {
41 | self = .other(object: [:])
42 | return
43 | }
44 | switch objectType {
45 | case "transaction_consumption":
46 | self = .transactionConsumption(object: try TransactionConsumption(from: decoder))
47 | default: self = .error(error: OMGError.socketError(message: "Invalid payload"))
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Source/Core/Websocket/SocketPayload.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketPayload.swift
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 12/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | struct SocketPayloadSend {
10 | let topic: String
11 | let event: SocketEventSend
12 | let ref: String
13 | let data: [String: Any]
14 |
15 | init(topic: String, event: SocketEventSend, ref: String, data: [String: Any] = [:]) {
16 | self.topic = topic
17 | self.event = event
18 | self.ref = ref
19 | self.data = data
20 | }
21 | }
22 |
23 | extension SocketPayloadSend: APIParameters {
24 | private enum CodingKeys: String, CodingKey {
25 | case topic
26 | case event
27 | case data
28 | case ref
29 | }
30 |
31 | func encode(to encoder: Encoder) throws {
32 | var container = encoder.container(keyedBy: CodingKeys.self)
33 | try container.encode(topic, forKey: .topic)
34 | try container.encode(event, forKey: .event)
35 | try container.encode(data, forKey: .data)
36 | try container.encode(ref, forKey: .ref)
37 | }
38 | }
39 |
40 | struct SocketPayloadReceive: Decodable {
41 | let topic: String
42 | let event: SocketEvent
43 | let ref: String?
44 | let data: GenericObject?
45 | let version: String
46 | let success: Bool
47 | let error: APIError?
48 | }
49 |
--------------------------------------------------------------------------------
/Source/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.1.2
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Source/OmiseGO.h:
--------------------------------------------------------------------------------
1 | //
2 | // OmiseGO.h
3 | // OmiseGO
4 | //
5 | // Created by Mederic Petit on 9/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for OmiseGO.
12 | FOUNDATION_EXPORT double OmiseGOVersionNumber;
13 |
14 | //! Project version string for OmiseGO.
15 | FOUNDATION_EXPORT const unsigned char OmiseGOVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
--------------------------------------------------------------------------------
/Tests/Admin/APITests/AdminCredentialTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AdminCredentialTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 14/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class AdminCredentialTests: XCTestCase {
13 | func testIsAuthenticatedIsFalseWithoutAUserId() {
14 | var credentials = AdminCredential()
15 | credentials.authenticationToken = "123"
16 | XCTAssertFalse(credentials.isAuthenticated())
17 | }
18 |
19 | func testIsAuthenticatedIsFalseWithoutAToken() {
20 | var credentials = AdminCredential()
21 | credentials.userId = "123"
22 | XCTAssertFalse(credentials.isAuthenticated())
23 | }
24 |
25 | func testIsAuthenticatedIsTrueWithAUserIdAndAToken() {
26 | let credentials = AdminCredential(userId: "123", authenticationToken: "123")
27 | XCTAssertTrue(credentials.isAuthenticated())
28 | }
29 |
30 | func testUpdateCredentialSuccessfully() {
31 | var credentials = AdminCredential()
32 | XCTAssertNil(credentials.userId)
33 | XCTAssertNil(credentials.authenticationToken)
34 | let authenticationToken = StubGenerator.authenticationToken(token: "token", user: StubGenerator.user(id: "user_id"))
35 | credentials.update(withAuthenticationToken: authenticationToken)
36 | XCTAssertEqual(credentials.authenticationToken, "token")
37 | XCTAssertEqual(credentials.userId, "user_id")
38 | }
39 |
40 | func testAuthenticationReturnsNilAfterInvalidating() {
41 | var credentials = AdminCredential(userId: "123", authenticationToken: "123")
42 | credentials.invalidate()
43 | XCTAssertNil(try credentials.authentication())
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/AccountAdminFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AccountAdminFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 18/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class AccountAdminFixtureTests: FixtureAdminTestCase {
13 | func testGetListOfAccounts() {
14 | let expectation = self.expectation(description: "List accounts")
15 | let params: PaginatedListParams = PaginatedListParams(page: 1, perPage: 10, sortBy: .name, sortDirection: .ascending)
16 | let request = Account.list(using: self.testClient, params: params) { result in
17 | defer { expectation.fulfill() }
18 | switch result {
19 | case let .success(data: paginatedAccounts):
20 | let accounts = paginatedAccounts.data
21 | XCTAssertEqual(paginatedAccounts.pagination.currentPage, 1)
22 | XCTAssertEqual(paginatedAccounts.pagination.perPage, 10)
23 | XCTAssertTrue(paginatedAccounts.pagination.isFirstPage)
24 | XCTAssertTrue(paginatedAccounts.pagination.isLastPage)
25 | XCTAssertEqual(accounts.count, 2)
26 | XCTAssertEqual(accounts.first!.id, "acc_01cnfz5sh5zmhx4xwd6m1rethy")
27 | XCTAssertEqual(accounts[1].id, "acc_01cnnna53f35n80pnmbf730s29")
28 | case let .fail(error: error):
29 | XCTFail("\(error)")
30 | }
31 | }
32 | XCTAssertNotNil(request)
33 | waitForExpectations(timeout: 15.0, handler: nil)
34 | }
35 |
36 | func testGetAccount() {
37 | let expectation = self.expectation(description: "Get an account from its id")
38 | let params = AccountGetParams(id: "acc_01cnfz5sh5zmhx4xwd6m1rethy")
39 | let request = Account.get(using: self.testClient, params: params) { result in
40 | defer { expectation.fulfill() }
41 | switch result {
42 | case let .success(data: account):
43 | XCTAssertEqual(account.id, "acc_01cnfz5sh5zmhx4xwd6m1rethy")
44 | case let .fail(error: error):
45 | XCTFail("\(error)")
46 | }
47 | }
48 | XCTAssertNotNil(request)
49 | waitForExpectations(timeout: 15.0, handler: nil)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/FixtureAdminAPI.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FixtureAdminAPI.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 14/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 |
11 | class FixtureAdminAPI: HTTPAdminAPI {
12 | let fixturesDirectoryURL: URL
13 |
14 | init(fixturesDirectoryURL: URL, config: AdminConfiguration) {
15 | self.fixturesDirectoryURL = fixturesDirectoryURL
16 | super.init(config: config)
17 | }
18 |
19 | @discardableResult
20 | override func request(toEndpoint endpoint: APIEndpoint,
21 | callback: Request.Callback?) -> Request? {
22 | do {
23 | let request: FixtureRequest = FixtureRequest(fixturesDirectoryURL: self.fixturesDirectoryURL,
24 | client: self,
25 | endpoint: endpoint,
26 | callback: callback)
27 | return try request.start()
28 | } catch let error as NSError {
29 | operationQueue.addOperation { callback?(.fail(error: .other(error: error))) }
30 | } catch let error as OMGError {
31 | operationQueue.addOperation { callback?(.fail(error: error)) }
32 | }
33 |
34 | return nil
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/FixtureAdminTestCase.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FixtureAdminTestCase.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 14/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class FixtureAdminTestCase: XCTestCase {
13 | var testClient: FixtureAdminAPI {
14 | let bundle = Bundle(for: FixtureAdminTestCase.self)
15 | let url = bundle.url(forResource: "admin_fixtures", withExtension: nil)!
16 | let credentials = AdminCredential(userId: "user_id", authenticationToken: "token")
17 | let config = AdminConfiguration(baseURL: "http://localhost:4000", credentials: credentials)
18 | return FixtureAdminAPI(fixturesDirectoryURL: url, config: config)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/LoginAdminFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoginAdminFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 14/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class LoginAdminFixtureTests: XCTestCase {
13 | var testClient: FixtureAdminAPI {
14 | let bundle = Bundle(for: LoginAdminFixtureTests.self)
15 | let url = bundle.url(forResource: "admin_fixtures", withExtension: nil)!
16 | let config = AdminConfiguration(baseURL: "http://localhst:4000")
17 | return FixtureAdminAPI(fixturesDirectoryURL: url, config: config)
18 | }
19 |
20 | func testLoginSuccessfullyAndUpdateToken() {
21 | let expectation = self.expectation(description: "Log an admin in successfully and updates the client authentication")
22 | XCTAssertNil(try! self.testClient.config.credentials.authentication())
23 | let client = self.testClient
24 | let params = LoginParams(email: "email", password: "password")
25 | let request = client.login(withParams: params, callback: { result in
26 | defer { expectation.fulfill() }
27 | switch result {
28 | case let .fail(error: error):
29 | XCTFail(error.message)
30 | case let .success(data: authenticationToken):
31 | XCTAssertEqual(authenticationToken.token, "azJRj09l7jvR8KhTqUs3")
32 | XCTAssertEqual(authenticationToken.user.id, "usr_01cc02x0v98qcctvycfx4vsk8x")
33 | XCTAssertNotNil(try! client.config.credentials.authentication())
34 | }
35 | })
36 | XCTAssertNotNil(request)
37 | waitForExpectations(timeout: 15.0, handler: nil)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/LogoutAdminFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LogoutAdminFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 17/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class LogoutAdminFixtureTests: FixtureAdminTestCase {
13 | func testAuthenticationIsInvalidedAfterLogout() {
14 | let expectation = self.expectation(description: "Authentication should be nil after logout")
15 | XCTAssertNotNil(try! self.testClient.config.credentials.authentication())
16 | let client = self.testClient
17 | let request = client.logout { _ in
18 | defer { expectation.fulfill() }
19 | XCTAssertNil(try! client.config.credentials.authentication())
20 | }
21 | XCTAssertNotNil(request)
22 | waitForExpectations(timeout: 15.0, handler: nil)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/RequestAdminFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RequestAdminFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 17/9/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class RequestAdminFixtureTests: FixtureAdminTestCase {
13 | func testBuildRequest() {
14 | do {
15 | let urlRequest = try RequestBuilder(configuration: testClient.config)
16 | .buildHTTPURLRequest(withEndpoint: TestAPIEndpoint())
17 |
18 | guard let httpHeaders = urlRequest.allHTTPHeaderFields else {
19 | XCTFail("Missing HTTP headers")
20 | return
21 | }
22 |
23 | XCTAssertEqual(httpHeaders["Authorization"], "OMGAdmin dXNlcl9pZDp0b2tlbg==")
24 | XCTAssertEqual(httpHeaders["Accept"],
25 | "application/vnd.omisego.v\(self.testClient.config.apiVersion)+json")
26 | XCTAssertEqual(httpHeaders["Content-Type"],
27 | "application/vnd.omisego.v\(self.testClient.config.apiVersion)+json; charset=utf-8")
28 | XCTAssertNil(urlRequest.httpBody)
29 | XCTAssertEqual(urlRequest.httpMethod, "POST")
30 | XCTAssertEqual(urlRequest.timeoutInterval, 6)
31 | } catch let error {
32 | XCTFail(error.localizedDescription)
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/admin_fixtures/api/account.all.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "pagination": {
6 | "per_page": 10,
7 | "is_last_page": true,
8 | "is_first_page": true,
9 | "current_page": 1
10 | },
11 | "object": "list",
12 | "data": [
13 | {
14 | "updated_at": "2018-08-24T09:47:29.116420Z",
15 | "socket_topic": "account:acc_01cnfz5sh5zmhx4xwd6m1rethy",
16 | "parent_id": null,
17 | "object": "account",
18 | "name": "Account 1",
19 | "metadata": {},
20 | "master": true,
21 | "id": "acc_01cnfz5sh5zmhx4xwd6m1rethy",
22 | "encrypted_metadata": {},
23 | "description": "Master Account",
24 | "created_at": "2018-08-22T04:44:38.823385Z",
25 | "category_ids": [],
26 | "categories": {
27 | "object": "list",
28 | "data": []
29 | },
30 | "avatar": {
31 | "thumb": null,
32 | "small": null,
33 | "original": null,
34 | "large": null
35 | }
36 | },
37 | {
38 | "updated_at": "2018-08-24T09:47:42.575342Z",
39 | "socket_topic": "account:acc_01cnnna53f35n80pnmbf730s29",
40 | "parent_id": "acc_01cnfz5sh5zmhx4xwd6m1rethy",
41 | "object": "account",
42 | "name": "Account 2",
43 | "metadata": {},
44 | "master": false,
45 | "id": "acc_01cnnna53f35n80pnmbf730s29",
46 | "encrypted_metadata": {},
47 | "description": null,
48 | "created_at": "2018-08-24T09:47:42.575319Z",
49 | "category_ids": [],
50 | "categories": {
51 | "object": "list",
52 | "data": []
53 | },
54 | "avatar": {
55 | "thumb": null,
56 | "small": null,
57 | "original": null,
58 | "large": null
59 | }
60 | }
61 | ]
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/admin_fixtures/api/account.get.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "account",
6 | "updated_at": "2018-08-24T09:47:29.116420Z",
7 | "socket_topic": "account:acc_01cnfz5sh5zmhx4xwd6m1rethy",
8 | "parent_id": null,
9 | "object": "account",
10 | "name": "Account 1",
11 | "metadata": {},
12 | "master": true,
13 | "id": "acc_01cnfz5sh5zmhx4xwd6m1rethy",
14 | "encrypted_metadata": {},
15 | "description": "Master Account",
16 | "created_at": "2018-08-22T04:44:38.823385Z",
17 | "category_ids": [],
18 | "categories": {
19 | "object": "list",
20 | "data": []
21 | },
22 | "avatar": {
23 | "thumb": null,
24 | "small": null,
25 | "original": null,
26 | "large": null
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/admin_fixtures/api/admin.login.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "authentication_token",
6 | "authentication_token": "azJRj09l7jvR8KhTqUs3",
7 | "user_id": "usr_01cc02x0v98qcctvycfx4vsk8x",
8 | "user": {
9 | "id": "usr_01cc02x0v98qcctvycfx4vsk8x",
10 | "provider_user_id": null,
11 | "username": null,
12 | "email": "user@example.com",
13 | "socket_topic": "user:usr_01cc02x0v98qcctvycfx4vsk8x",
14 | "metadata": {},
15 | "encrypted_metadata": {},
16 | "created_at": "2018-01-01T00:00:00Z",
17 | "updated_at": "2018-01-01T00:00:00Z"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/admin_fixtures/api/me.logout.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {}
5 | }
6 |
--------------------------------------------------------------------------------
/Tests/Admin/FixtureTests/admin_fixtures/api/wallet.get.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "user_id": null,
6 | "user": null,
7 | "updated_at": "2018-08-22T04:44:38.837395Z",
8 | "socket_topic": "wallet:ixsz977823599563",
9 | "object": "wallet",
10 | "name": "primary",
11 | "metadata": {},
12 | "identifier": "primary",
13 | "encrypted_metadata": {},
14 | "enabled": true,
15 | "created_at": "2018-08-22T04:44:38.837384Z",
16 | "balances": [
17 | {
18 | "token": {
19 | "updated_at": "2018-08-22T07:53:13.800904Z",
20 | "symbol": "TK1",
21 | "subunit_to_unit": 1,
22 | "object": "token",
23 | "name": "Token 1",
24 | "metadata": {},
25 | "id": "tok_TK1_01cng9z3a8yn58ts806vbpefxw",
26 | "encrypted_metadata": {},
27 | "enabled": true,
28 | "created_at": "2018-08-22T07:53:13.800896Z"
29 | },
30 | "object": "balance",
31 | "amount": 37585
32 | },
33 | {
34 | "token": {
35 | "updated_at": "2018-08-23T07:21:03.542632Z",
36 | "symbol": "TK2",
37 | "subunit_to_unit": 1,
38 | "object": "token",
39 | "name": "Token 2",
40 | "metadata": {},
41 | "id": "tok_TK2_01cnjtgx9p89p9g1pa2qjzk9mf",
42 | "encrypted_metadata": {},
43 | "enabled": true,
44 | "created_at": "2018-08-23T07:21:03.542625Z"
45 | },
46 | "object": "balance",
47 | "amount": 9999999469
48 | }
49 | ],
50 | "address": "ixsz977823599563",
51 | "account_id": "acc_01cnfz5sh5zmhx4xwd6m1rethy",
52 | "account": {
53 | "updated_at": "2018-08-24T09:47:29.116420Z",
54 | "socket_topic": "account:acc_01cnfz5sh5zmhx4xwd6m1rethy",
55 | "parent_id": null,
56 | "object": "account",
57 | "name": "Account 1",
58 | "metadata": {},
59 | "master": true,
60 | "id": "acc_01cnfz5sh5zmhx4xwd6m1rethy",
61 | "encrypted_metadata": {},
62 | "description": "Master Account",
63 | "created_at": "2018-08-22T04:44:38.823385Z",
64 | "category_ids": [],
65 | "categories": {
66 | "object": "list",
67 | "data": []
68 | },
69 | "avatar": {
70 | "thumb": null,
71 | "small": null,
72 | "original": null,
73 | "large": null
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Tests/Client/APITests/ClientCredentialTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ClientCredentialTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 9/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class ClientCredentialTests: XCTestCase {
13 | func testIsAuthenticatedIsFalseWhenNoAuthenticationToken() {
14 | let credentials = ClientCredential(apiKey: "api_key")
15 | XCTAssertFalse(credentials.isAuthenticated())
16 | }
17 |
18 | func testIsAuthenticatedIsTrueWithAnAuthenticationToken() {
19 | let credentials = ClientCredential(apiKey: "api_key", authenticationToken: "123")
20 | XCTAssertTrue(credentials.isAuthenticated())
21 | }
22 |
23 | func testUpdateCredentialSuccessfully() {
24 | var credentials = ClientCredential(apiKey: "api_key")
25 | XCTAssertNil(credentials.authenticationToken)
26 | let authenticationToken = StubGenerator.authenticationToken(token: "123")
27 | credentials.update(withAuthenticationToken: authenticationToken)
28 | XCTAssertEqual(credentials.authenticationToken, "123")
29 | }
30 |
31 | func testAuthenticationReturnsNilIfAuthenticationTokenIsNotSpecified() {
32 | var credentials = ClientCredential(apiKey: "api_key", authenticationToken: "auth_token")
33 | credentials.invalidate()
34 | XCTAssertNil(try credentials.authentication())
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/FixtureClientAPI.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FixtureClientAPI.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 17/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 |
11 | class FixtureClientAPI: HTTPClientAPI {
12 | let fixturesDirectoryURL: URL
13 |
14 | init(fixturesDirectoryURL: URL, config: ClientConfiguration) {
15 | self.fixturesDirectoryURL = fixturesDirectoryURL
16 | super.init(config: config)
17 | }
18 |
19 | @discardableResult
20 | override func request(toEndpoint endpoint: APIEndpoint,
21 | callback: Request.Callback?) -> Request? {
22 | do {
23 | let request: FixtureRequest = FixtureRequest(fixturesDirectoryURL: self.fixturesDirectoryURL,
24 | client: self,
25 | endpoint: endpoint,
26 | callback: callback)
27 | return try request.start()
28 | } catch let error as NSError {
29 | operationQueue.addOperation { callback?(.fail(error: .other(error: error))) }
30 | } catch let error as OMGError {
31 | operationQueue.addOperation { callback?(.fail(error: error)) }
32 | }
33 |
34 | return nil
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/FixtureClientTestCase.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FixtureClientTestCase.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 10/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class FixtureClientTestCase: XCTestCase {
13 | var testClient: FixtureClientAPI {
14 | let bundle = Bundle(for: FixtureClientTestCase.self)
15 | let url = bundle.url(forResource: "client_fixtures", withExtension: nil)!
16 | let credentials = ClientCredential(apiKey: "some_api_key", authenticationToken: "some_token")
17 | let config = ClientConfiguration(baseURL: "http://localhost:4000", credentials: credentials)
18 | return FixtureClientAPI(fixturesDirectoryURL: url, config: config)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/LoginFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoginFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 15/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class LoginFixtureTests: XCTestCase {
13 | var testClient: FixtureClientAPI {
14 | let bundle = Bundle(for: FixtureClientTestCase.self)
15 | let url = bundle.url(forResource: "client_fixtures", withExtension: nil)!
16 | let credentials = ClientCredential(apiKey: "some_api_key")
17 | let config = ClientConfiguration(baseURL: "http://localhst:4000", credentials: credentials)
18 | return FixtureClientAPI(fixturesDirectoryURL: url, config: config)
19 | }
20 |
21 | func testLoginSuccessfullyAndUpdateToken() {
22 | let expectation = self.expectation(description: "Log a user in successfully and updates the client authentication")
23 | XCTAssertNil(try! self.testClient.config.credentials.authentication())
24 | let client = self.testClient
25 | let params = LoginParams(email: "email", password: "password")
26 | let request = client.login(withParams: params, callback: { result in
27 | defer { expectation.fulfill() }
28 | switch result {
29 | case let .fail(error: error):
30 | XCTFail(error.message)
31 | case let .success(data: authenticationToken):
32 | XCTAssertEqual(authenticationToken.token, "azJRj09l7jvR8KhTqUs3")
33 | XCTAssertEqual(authenticationToken.user.id, "usr_01cc02x0v98qcctvycfx4vsk8x")
34 | XCTAssertNotNil(try! client.config.credentials.authentication())
35 | }
36 | })
37 | XCTAssertNotNil(request)
38 | waitForExpectations(timeout: 15.0, handler: nil)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/LogoutFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LogoutFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 27/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class LogoutFixtureTests: FixtureClientTestCase {
13 | func testAuthenticationIsInvalidedAfterLogout() {
14 | let expectation = self.expectation(description: "Authentication should be nil after logout")
15 | XCTAssertNotNil(try! self.testClient.config.credentials.authentication())
16 | let client = self.testClient
17 | let request = client.logout { _ in
18 | defer { expectation.fulfill() }
19 | XCTAssertNil(try! client.config.credentials.authentication())
20 | }
21 | XCTAssertNotNil(request)
22 | waitForExpectations(timeout: 15.0, handler: nil)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/RequestFixtureTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RequestFixtureTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 13/11/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class RequestFixtureTest: FixtureClientTestCase {
13 | func testBuildRequest() {
14 | do {
15 | let urlRequest = try RequestBuilder(configuration: testClient.config)
16 | .buildHTTPURLRequest(withEndpoint: TestAPIEndpoint())
17 |
18 | guard let httpHeaders = urlRequest.allHTTPHeaderFields else {
19 | XCTFail("Missing HTTP headers")
20 | return
21 | }
22 |
23 | XCTAssertEqual(httpHeaders["Authorization"], "OMGClient c29tZV9hcGlfa2V5OnNvbWVfdG9rZW4=")
24 | XCTAssertEqual(httpHeaders["Accept"],
25 | "application/vnd.omisego.v\(self.testClient.config.apiVersion)+json")
26 | XCTAssertEqual(httpHeaders["Content-Type"],
27 | "application/vnd.omisego.v\(self.testClient.config.apiVersion)+json; charset=utf-8")
28 | XCTAssertNil(urlRequest.httpBody)
29 | XCTAssertEqual(urlRequest.httpMethod, "POST")
30 | XCTAssertEqual(urlRequest.timeoutInterval, 6)
31 | } catch let error {
32 | XCTFail(error.localizedDescription)
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/SettingFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SettingFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 12/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class SettingFixtureTests: FixtureClientTestCase {
13 | func testGetSettings() {
14 | let expectation = self.expectation(description: "Get settings for current user")
15 | let request = Setting.get(using: self.testClient) { result in
16 | defer { expectation.fulfill() }
17 | switch result {
18 | case let .success(setting):
19 | XCTAssertTrue(setting.tokens.count == 2)
20 | XCTAssertEqual(setting.tokens[0].id, "BTC:123")
21 | XCTAssertEqual(setting.tokens[0].symbol, "BTC")
22 | XCTAssertEqual(setting.tokens[0].name, "Bitcoin")
23 | XCTAssertEqual(setting.tokens[0].subUnitToUnit, 100_000)
24 | XCTAssertTrue(setting.tokens[0].metadata.isEmpty)
25 | XCTAssertTrue(setting.tokens[0].encryptedMetadata.isEmpty)
26 | XCTAssertEqual(setting.tokens[0].createdAt, "2018-01-01T00:00:00Z".toDate())
27 | XCTAssertEqual(setting.tokens[0].updatedAt, "2018-01-01T00:00:00Z".toDate())
28 | XCTAssertEqual(setting.tokens[1].id, "OMG:123")
29 | XCTAssertEqual(setting.tokens[1].symbol, "OMG")
30 | XCTAssertEqual(setting.tokens[1].name, "OmiseGO")
31 | XCTAssertEqual(setting.tokens[1].subUnitToUnit, 100_000_000)
32 | XCTAssertTrue(setting.tokens[1].metadata.isEmpty)
33 | XCTAssertTrue(setting.tokens[1].encryptedMetadata.isEmpty)
34 | XCTAssertEqual(setting.tokens[1].createdAt, "2018-01-01T00:00:00Z".toDate())
35 | XCTAssertEqual(setting.tokens[1].updatedAt, "2018-01-01T00:00:00Z".toDate())
36 | case let .fail(error):
37 | XCTFail("\(error)")
38 | }
39 | }
40 | XCTAssertNotNil(request)
41 | waitForExpectations(timeout: 15.0, handler: nil)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/SignupFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SignupFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 22/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class SignupFixtureTests: XCTestCase {
13 | var testClient: FixtureClientAPI {
14 | let bundle = Bundle(for: FixtureClientTestCase.self)
15 | let url = bundle.url(forResource: "client_fixtures", withExtension: nil)!
16 | let credentials = ClientCredential(apiKey: "some_api_key")
17 | let config = ClientConfiguration(baseURL: "http://localhst:4000", credentials: credentials)
18 | return FixtureClientAPI(fixturesDirectoryURL: url, config: config)
19 | }
20 |
21 | func testSignupSuccessfully() {
22 | let expectation = self.expectation(description: "Signup a user successfully")
23 | XCTAssertNil(try! self.testClient.config.credentials.authentication())
24 | let client = self.testClient
25 | let params = SignupParams(email: "email@example.com",
26 | password: "password",
27 | passwordConfirmation: "password")
28 | let request = client.signup(withParams: params) { result in
29 | defer { expectation.fulfill() }
30 | switch result {
31 | case let .fail(error: error):
32 | XCTFail(error.message)
33 | case .success(data: _): break
34 | }
35 | }
36 | XCTAssertNotNil(request)
37 | waitForExpectations(timeout: 15.0, handler: nil)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.create_transaction.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "transaction",
6 | "id": "ce3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
7 | "from": {
8 | "object": "transaction_source",
9 | "address": "1e3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
10 | "amount": 1000,
11 | "token": {
12 | "object": "token",
13 | "id": "BTC:xe3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
14 | "symbol": "BTC",
15 | "name": "Bitcoin",
16 | "subunit_to_unit": 100,
17 | "metadata": {},
18 | "encrypted_metadata": {},
19 | "created_at": "2018-01-01T00:00:00Z",
20 | "updated_at": "2018-01-01T00:00:00Z"
21 | }
22 | },
23 | "to": {
24 | "object": "transaction_source",
25 | "address": "2e3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
26 | "amount": 1000,
27 | "token": {
28 | "object": "token",
29 | "id": "BTC:xe3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
30 | "symbol": "BTC",
31 | "name": "Bitcoin",
32 | "subunit_to_unit": 100,
33 | "metadata": {},
34 | "encrypted_metadata": {},
35 | "created_at": "2018-01-01T00:00:00Z",
36 | "updated_at": "2018-01-01T00:00:00Z"
37 | }
38 | },
39 | "exchange": {
40 | "object": "exchange",
41 | "rate": 1,
42 | "calculated_at": null,
43 | "exchange_pair_id": null,
44 | "exchange_pair": null,
45 | "exchange_account_id": null,
46 | "exchange_account": null,
47 | "exchange_wallet_address": null,
48 | "exchange_wallet": null
49 | },
50 | "status": "confirmed",
51 | "metadata": {},
52 | "encrypted_metadata": {},
53 | "created_at": "2018-01-01T00:00:00Z"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.create_transaction_request.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "transaction_request",
6 | "type": "receive",
7 | "id": "8eb0160e-1c96-481a-88e1-899399cc84dc",
8 | "consumption_interval_duration": null,
9 | "max_consumptions_per_interval": null,
10 | "max_consumptions_per_interval_per_user": null,
11 | "token": {
12 | "object": "token",
13 | "id": "BTC:861020af-17b6-49ee-a0cb-661a4d2d1f95",
14 | "symbol": "BTC",
15 | "name": "Bitcoin",
16 | "subunit_to_unit": 100000,
17 | "metadata": {},
18 | "encrypted_metadata": {},
19 | "created_at": "2018-01-01T00:00:00Z",
20 | "updated_at": "2018-01-01T00:00:00Z"
21 | },
22 | "amount": 1337,
23 | "address": "3b7f1c68-e3bd-4f8f-9916-4af19be95d00",
24 | "user": {
25 | "object": "user",
26 | "id": "6f56efa1-caf9-4348-8e0f-f5af283f17ee",
27 | "provider_user_id": "a_provider_user_id",
28 | "username": "john.doe@example.com",
29 | "socket_topic": "user:6f56efa1-caf9-4348-8e0f-f5af283f17ee",
30 | "metadata": {},
31 | "encrypted_metadata": {},
32 | "created_at": "2018-01-01T00:00:00Z",
33 | "updated_at": "2018-01-01T00:00:00Z"
34 | },
35 | "accountId": null,
36 | "correlation_id": "31009545-db10-4287-82f4-afb46d9741d8",
37 | "status": "valid",
38 | "socket_topic": "transaction_request:8eb0160e-1c96-481a-88e1-899399cc84dc",
39 | "require_confirmation": true,
40 | "max_consumptions": 1,
41 | "consumption_lifetime": 1000,
42 | "created_at": "2018-01-01T00:00:00Z",
43 | "expiration_date": "2019-01-01T00:00:00Z",
44 | "expiration_reason": "Expired",
45 | "expired_at": "2019-01-01T00:00:00Z",
46 | "allow_amount_override": true,
47 | "max_consumptions_per_user": null,
48 | "formatted_id": "|8eb0160e-1c96-481a-88e1-899399cc84dc",
49 | "metadata": {},
50 | "encrypted_metadata": {},
51 | "exchange_account_id": null,
52 | "exchange_account": null,
53 | "exchange_wallet_address": null,
54 | "exchange_wallet": null
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.get.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "user",
6 | "id": "cec34607-0761-4a59-8357-18963e42a1aa",
7 | "provider_user_id": "wijf-fbancomw-dqwjudb",
8 | "username": "john.doe@example.com",
9 | "socket_topic": "user:cec34607-0761-4a59-8357-18963e42a1aa",
10 | "metadata": {
11 | "first_name": "John",
12 | "last_name": "Doe",
13 | "object": {
14 | "my_key": "my_value",
15 | "my_nested_object": {
16 | "my_nested_key": "my_nested_value"
17 | }
18 | },
19 | "array": [
20 | "value_1", "value_2"
21 | ]
22 | },
23 | "encrypted_metadata": {},
24 | "created_at": "2018-01-01T00:00:00Z",
25 | "updated_at": "2018-01-01T00:00:00Z"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.get_settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "setting",
6 | "tokens": [
7 | {
8 | "object": "token",
9 | "id": "BTC:123",
10 | "symbol": "BTC",
11 | "name": "Bitcoin",
12 | "subunit_to_unit": 100000,
13 | "metadata": {},
14 | "encrypted_metadata": {},
15 | "created_at": "2018-01-01T00:00:00Z",
16 | "updated_at": "2018-01-01T00:00:00Z"
17 | },
18 | {
19 | "object": "token",
20 | "id": "OMG:123",
21 | "symbol": "OMG",
22 | "name": "OmiseGO",
23 | "subunit_to_unit": 100000000,
24 | "metadata": {},
25 | "encrypted_metadata": {},
26 | "created_at": "2018-01-01T00:00:00Z",
27 | "updated_at": "2018-01-01T00:00:00Z"
28 | }
29 | ]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.get_transaction_request.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "transaction_request",
6 | "type": "receive",
7 | "id": "8eb0160e-1c96-481a-88e1-899399cc84dc",
8 | "consumption_interval_duration": 10000,
9 | "max_consumptions_per_interval": 10,
10 | "max_consumptions_per_interval_per_user": 1,
11 | "token": {
12 | "object": "token",
13 | "id": "BTC:861020af-17b6-49ee-a0cb-661a4d2d1f95",
14 | "symbol": "BTC",
15 | "name": "Bitcoin",
16 | "subunit_to_unit": 100000,
17 | "metadata": {},
18 | "encrypted_metadata": {},
19 | "created_at": "2018-01-01T00:00:00Z",
20 | "updated_at": "2018-01-01T00:00:00Z"
21 | },
22 | "amount": 1337,
23 | "address": "3b7f1c68-e3bd-4f8f-9916-4af19be95d00",
24 | "user": {
25 | "object": "user",
26 | "id": "6f56efa1-caf9-4348-8e0f-f5af283f17ee",
27 | "provider_user_id": "a_provider_user_id",
28 | "username": "john.doe@example.com",
29 | "socket_topic": "user:6f56efa1-caf9-4348-8e0f-f5af283f17ee",
30 | "metadata": {},
31 | "encrypted_metadata": {},
32 | "created_at": "2018-01-01T00:00:00Z",
33 | "updated_at": "2018-01-01T00:00:00Z"
34 | },
35 | "accountId": null,
36 | "correlation_id": "31009545-db10-4287-82f4-afb46d9741d8",
37 | "status": "valid",
38 | "socket_topic": "transaction_request:8eb0160e-1c96-481a-88e1-899399cc84dc",
39 | "require_confirmation": true,
40 | "max_consumptions": 1,
41 | "consumption_lifetime": 1000,
42 | "created_at": "2018-01-01T00:00:00Z",
43 | "expiration_date": "2019-01-01T00:00:00Z",
44 | "expiration_reason": "Expired",
45 | "expired_at": "2019-01-01T00:00:00Z",
46 | "allow_amount_override": true,
47 | "max_consumptions_per_user": null,
48 | "formatted_id": "|907056a4-fc2d-47cb-af19-5e73aade7ece",
49 | "metadata": {},
50 | "encrypted_metadata": {},
51 | "exchange_account_id": null,
52 | "exchange_account": null,
53 | "exchange_wallet_address": null,
54 | "exchange_wallet": null
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.get_transactions.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "list",
6 | "data": [
7 | {
8 | "object": "transaction",
9 | "id": "ce3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
10 | "from": {
11 | "object": "transaction_source",
12 | "address": "1e3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
13 | "amount": 1000,
14 | "token": {
15 | "object": "token",
16 | "id": "BTC:xe3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
17 | "symbol": "BTC",
18 | "name": "Bitcoin",
19 | "subunit_to_unit": 100,
20 | "metadata": {},
21 | "encrypted_metadata": {},
22 | "created_at": "2018-01-01T00:00:00Z",
23 | "updated_at": "2018-01-01T00:00:00Z"
24 | }
25 | },
26 | "to": {
27 | "object": "transaction_source",
28 | "address": "2e3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
29 | "amount": 1000,
30 | "token": {
31 | "object": "token",
32 | "id": "BTC:xe3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
33 | "symbol": "BTC",
34 | "name": "Bitcoin",
35 | "subunit_to_unit": 100,
36 | "metadata": {},
37 | "encrypted_metadata": {},
38 | "created_at": "2018-01-01T00:00:00Z",
39 | "updated_at": "2018-01-01T00:00:00Z"
40 | }
41 | },
42 | "exchange": {
43 | "object": "exchange",
44 | "rate": 1,
45 | "calculated_at": null,
46 | "exchange_pair_id": null,
47 | "exchange_pair": null,
48 | "exchange_account_id": null,
49 | "exchange_account": null,
50 | "exchange_wallet_address": null,
51 | "exchange_wallet": null
52 | },
53 | "status": "confirmed",
54 | "metadata": {},
55 | "encrypted_metadata": {},
56 | "created_at": "2018-01-01T00:00:00Z",
57 | "error_code": null,
58 | "error_description": null
59 | }
60 |
61 | ],
62 | "pagination": {
63 | "per_page": 10,
64 | "current_page": 1,
65 | "is_first_page": true,
66 | "is_last_page": true
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.get_wallets.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "list",
6 | "data": [
7 | {
8 | "object": "wallet",
9 | "address": "2c2e0f2e-fa0f-4abe-8516-9e92cf003486",
10 | "balances": [
11 | {
12 | "object": "balance",
13 | "amount": 103100,
14 | "token": {
15 | "id": "OMG:123",
16 | "symbol": "OMG",
17 | "subunit_to_unit": 10000,
18 | "object": "token",
19 | "name": "OmiseGO",
20 | "metadata": {},
21 | "encrypted_metadata": {},
22 | "created_at": "2018-01-01T00:00:00Z",
23 | "updated_at": "2018-01-01T00:00:00Z"
24 | }
25 | },
26 | {
27 | "object": "balance",
28 | "amount": 133700,
29 | "token": {
30 | "id": "KNC:123",
31 | "symbol": "KNC",
32 | "subunit_to_unit": 10000,
33 | "object": "token",
34 | "name": "Kyber",
35 | "metadata": {},
36 | "encrypted_metadata": {},
37 | "created_at": "2018-01-01T00:00:00Z",
38 | "updated_at": "2018-01-01T00:00:00Z"
39 | }
40 | }
41 | ],
42 | "name": "primary",
43 | "identifier": "primary",
44 | "user_id": "cec34607-0761-4a59-8357-18963e42a1aa",
45 | "user": {
46 | "id": "cec34607-0761-4a59-8357-18963e42a1aa",
47 | "provider_user_id": "wijf-fbancomw-dqwjudb",
48 | "username": "john.doe@example.com",
49 | "socket_topic": "user:cec34607-0761-4a59-8357-18963e42a1aa",
50 | "metadata": {},
51 | "encrypted_metadata": {},
52 | "created_at": "2018-01-01T00:00:00Z",
53 | "updated_at": "2018-01-01T00:00:00Z"
54 | },
55 | "account_id": null,
56 | "account": null,
57 | "metadata": {},
58 | "encrypted_metadata": {}
59 | }
60 | ]
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/me.logout.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {}
5 | }
6 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/user.login.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "authentication_token",
6 | "authentication_token": "azJRj09l7jvR8KhTqUs3",
7 | "user_id": "usr_01cc02x0v98qcctvycfx4vsk8x",
8 | "user": {
9 | "id": "usr_01cc02x0v98qcctvycfx4vsk8x",
10 | "provider_user_id": null,
11 | "username": null,
12 | "email": "user@example.com",
13 | "socket_topic": "user:usr_01cc02x0v98qcctvycfx4vsk8x",
14 | "metadata": {},
15 | "encrypted_metadata": {},
16 | "created_at": "2018-01-01T00:00:00Z",
17 | "updated_at": "2018-01-01T00:00:00Z"
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/user.reset_password.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {}
5 | }
6 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/user.signup.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {}
5 | }
6 |
--------------------------------------------------------------------------------
/Tests/Client/FixtureTests/client_fixtures/api/user.update_password.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {}
5 | }
6 |
--------------------------------------------------------------------------------
/Tests/Client/LiveTests/LiveClientTestCase.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LiveClientTestCase.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 18/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class LiveClientTestCase: LiveTestCase {
13 | var testClient: HTTPClientAPI!
14 | var testSocketClient: SocketClient!
15 |
16 | override func setUp() {
17 | super.setUp()
18 | self.testClient = HTTPClientAPI(config: self.validHTTPConfig())
19 | self.testSocketClient = SocketClient(config: self.validSocketConfig(), delegate: nil)
20 | }
21 |
22 | private func validHTTPConfig() -> ClientConfiguration {
23 | let credentials = ClientCredential(apiKey: self.validAPIKey,
24 | authenticationToken: self.validAuthenticationToken)
25 | return ClientConfiguration(baseURL: self.validBaseURL, credentials: credentials)
26 | }
27 |
28 | private func validSocketConfig() -> ClientConfiguration {
29 | let credentials = ClientCredential(apiKey: self.validAPIKey,
30 | authenticationToken: self.validAuthenticationToken)
31 | return ClientConfiguration(baseURL: self.validWebsocketURL, credentials: credentials)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/Client/LiveTests/ResponseLiveTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseLiveTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 18/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class ResponseLiveTest: LiveClientTestCase {
13 | func testWrongEndpoint() {
14 | let expectation = self.expectation(description: "Error response")
15 | let endpoint = TestAPIEndpoint(path: "not_existing")
16 | let request: Request? = self.testClient.request(toEndpoint: endpoint) { result in
17 | defer { expectation.fulfill() }
18 | switch result {
19 | case .success(data: _):
20 | XCTFail("Should not succeed")
21 | case let .fail(error):
22 | switch error {
23 | case let .api(apiError: apiError):
24 | XCTAssertEqual(apiError.code, .endPointNotFound)
25 | default:
26 | XCTFail("Error should be an API error")
27 | }
28 | }
29 | }
30 | XCTAssertNotNil(request)
31 | waitForExpectations(timeout: 15.0, handler: nil)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/Client/LiveTests/SettingLiveTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SettingLiveTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 10/11/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class SettingLiveTests: LiveClientTestCase {
13 | func testGetSettings() {
14 | let expectation = self.expectation(description: "Setting result")
15 | let request = Setting.get(using: self.testClient) { result in
16 | defer { expectation.fulfill() }
17 | switch result {
18 | case let .success(setting):
19 | XCTAssert(!setting.tokens.isEmpty)
20 | case let .fail(error):
21 | XCTFail("\(error)")
22 | }
23 | }
24 | XCTAssertNotNil(request)
25 | waitForExpectations(timeout: 15.0, handler: nil)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Tests/Client/LiveTests/TransactionLiveTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionLiveTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 23/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class TransactionLiveTests: LiveClientTestCase {
13 | func testGetTransactionList() {
14 | let expectation = self.expectation(description: "Get paginated list of transactions")
15 | let paginationParams = PaginatedListParams(
16 | page: 1,
17 | perPage: 10,
18 | sortBy: .createdAt,
19 | sortDirection: .descending)
20 | let params = TransactionListParams(paginatedListParams: paginationParams, address: nil)
21 | let request = Transaction.list(
22 | using: self.testClient,
23 | params: params) { result in
24 | defer { expectation.fulfill() }
25 | switch result {
26 | case let .success(paginatedList):
27 | XCTAssertEqual(paginatedList.pagination.currentPage, 1)
28 | XCTAssertTrue(paginatedList.pagination.isFirstPage)
29 | case let .fail(error):
30 | XCTFail("\(error)")
31 | }
32 | }
33 | XCTAssertNotNil(request)
34 | waitForExpectations(timeout: 15.0, handler: nil)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Tests/Client/LiveTests/UserLiveTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserLiveTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 18/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import OmiseGO
11 | import XCTest
12 |
13 | class UserLiveTests: LiveClientTestCase {
14 | func testCurrentUserRetrieve() {
15 | let expectation = self.expectation(description: "Get current user from authentication token")
16 | let request = User.getCurrent(using: self.testClient) { result in
17 | defer { expectation.fulfill() }
18 | switch result {
19 | case let .success(user):
20 | XCTAssertNotNil(user)
21 | case let .fail(error):
22 | XCTFail("\(error)")
23 | }
24 | }
25 | XCTAssertNotNil(request)
26 | waitForExpectations(timeout: 15.0, handler: nil)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Client/LiveTests/WalletLiveTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WalletLiveTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 10/11/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class WalletLiveTests: LiveClientTestCase {
13 | func testGetAll() {
14 | let expectation = self.expectation(description: "Get the list of wallets")
15 | let request = Wallet.getAll(using: self.testClient) { result in
16 | defer { expectation.fulfill() }
17 | switch result {
18 | case let .success(data: addresses):
19 | XCTAssert(!addresses.isEmpty)
20 | case let .fail(error: error):
21 | XCTFail("\(error)")
22 | }
23 | }
24 | XCTAssertNotNil(request)
25 | waitForExpectations(timeout: 15.0, handler: nil)
26 | }
27 |
28 | func testGetMain() {
29 | let expectation = self.expectation(description: "Get the main wallet")
30 | let request = Wallet.getMain(using: self.testClient) { result in
31 | defer { expectation.fulfill() }
32 | switch result {
33 | case .success(data: _):
34 | XCTAssertTrue(true)
35 | case let .fail(error: error):
36 | XCTFail("\(error)")
37 | }
38 | }
39 | XCTAssertNotNil(request)
40 | waitForExpectations(timeout: 15.0, handler: nil)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Tests/Core/APITests/CredentialEncoderTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CredentialEncoderTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 9/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class CredentialEncoderTests: XCTestCase {
13 | func testEncodeAuthorizationHeaderCorrectly() {
14 | XCTAssertEqual(
15 | try! CredentialEncoder.encode(value1: "123", value2: "123", scheme: "OMGClient"),
16 | "OMGClient \("123:123".data(using: .utf8)!.base64EncodedString())"
17 | )
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Tests/Core/APITests/HTTPClientTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HTTPClientTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 11/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class HTTPClientTests: XCTestCase {
13 | func testIsAuthenticatedIsTrueWhenAuthenticated() {
14 | let config = TestConfiguration(baseURL: "http://localhost:4000", credentials: TestCredential(authenticated: true))
15 | let client = HTTPAPI(config: config)
16 | XCTAssertTrue(client.isAuthenticated)
17 | }
18 |
19 | func testIsAuthenticatedIsFalseWhenNotAuthenticated() {
20 | let config = TestConfiguration(baseURL: "http://localhost:4000", credentials: TestCredential(authenticated: false))
21 | let client = HTTPAPI(config: config)
22 | XCTAssertFalse(client.isAuthenticated)
23 | }
24 |
25 | func testInvalidURL() {
26 | let expectation = self.expectation(description: "Invalid url")
27 | let config = TestConfiguration(baseURL: "invalid url @")
28 | let client = HTTPAPI(config: config)
29 | let dummyEndpoint = TestAPIEndpoint()
30 | let request: Request? = client.request(toEndpoint: dummyEndpoint) { result in
31 | defer {
32 | expectation.fulfill()
33 | }
34 | switch result {
35 | case .success(data: _):
36 | XCTFail("Request should not be executed if base url is not correct")
37 | case let .fail(error):
38 | switch error {
39 | case .configuration(message: _): break
40 | default: XCTFail("Error should be a configuration error")
41 | }
42 | }
43 | }
44 | XCTAssertNil(request, "Request should be nil")
45 | waitForExpectations(timeout: 15.0, handler: nil)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Tests/Core/APITests/RequestTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RequestTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 6/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class RequestTest: XCTestCase {
13 | let client: HTTPAPI = HTTPAPI(config: TestConfiguration())
14 |
15 | func testStartRequest() {
16 | let request: Request =
17 | Request(client: client, endpoint: TestAPIEndpoint()) { _ in }
18 | do {
19 | XCTAssertNil(request.task)
20 | _ = try request.start()
21 | XCTAssertNotNil(request.task)
22 | } catch let error {
23 | XCTFail(error.localizedDescription)
24 | }
25 | }
26 |
27 | func testCancelRequest() {
28 | let expectation = self.expectation(description: "Task is cancelled")
29 | let dummyEndpoint = TestAPIEndpoint()
30 | let request: Request =
31 | Request(client: client,
32 | endpoint: dummyEndpoint) { result in
33 | defer { expectation.fulfill() }
34 | switch result {
35 | case .success: XCTFail("Expected failure")
36 | case let .fail(error: error):
37 | XCTAssertEqual(error.description, "I/O error: cancelled")
38 | }
39 | }
40 | do {
41 | XCTAssertNil(request.task)
42 | _ = try request.start()
43 | XCTAssertNotNil(request.task)
44 | request.cancel()
45 | self.wait(for: [expectation], timeout: 10)
46 | XCTAssertEqual(request.task!.state, .completed)
47 | } catch let error {
48 | XCTFail(error.localizedDescription)
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/DecodingFixtureTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DecodingFixtureTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 25/6/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class DecodingFixtureTests: FixtureTestCase {
13 | func testFailToDecodeANumberWhenExpectingAString() {
14 | let e = self.expectation(description: "Raise a decoding error")
15 | let endpoint = TestAPIEndpoint(path: "dummy.decoding_error")
16 | let request: Request? = self.testClient.request(toEndpoint: endpoint) { result in
17 | switch result {
18 | case .success(data: _): XCTFail("Excpected a decoding error")
19 | case let .fail(error: error):
20 | defer { e.fulfill() }
21 | XCTAssertEqual(error.message, "decoding error: Expected to decode String but found a number instead.")
22 | }
23 | }
24 | self.waitForExpectations(timeout: 5, handler: nil)
25 | XCTAssertNotNil(request)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/FixtureTestCase.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FixtureTestCase.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 10/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class FixtureTestCase: XCTestCase {
13 | var testClient: FixtureCoreAPI {
14 | let bundle = Bundle(for: FixtureTestCase.self)
15 | let url = bundle.url(forResource: "core_fixtures", withExtension: nil)!
16 | let config = TestConfiguration()
17 | return FixtureCoreAPI(fixturesDirectoryURL: url, config: config)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/ListableTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ListableTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 7/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class ListableTests: FixtureTestCase {
13 | func testListableFailure() {
14 | let expectation = self.expectation(description: "Fails to load the response for this dummy object")
15 | TestListable.list(using: self.testClient) { response in
16 | defer { expectation.fulfill() }
17 | switch response {
18 | case .success(data: _): XCTFail("Shouldn't succeed")
19 | case let .fail(error: error):
20 | XCTAssertEqual(error.message, "error_message")
21 | }
22 | }
23 | waitForExpectations(timeout: 15.0, handler: nil)
24 | }
25 |
26 | func testPaginatedListableFailure() {
27 | let expectation = self.expectation(description: "Fails to load the response for this paginated dummy object")
28 | PaginatedTestListable.list(using: self.testClient) { response in
29 | defer { expectation.fulfill() }
30 | switch response {
31 | case .success(data: _): XCTFail("Shouldn't succeed")
32 | case let .fail(error: error):
33 | XCTAssertEqual(error.message, "error_message")
34 | }
35 | }
36 | waitForExpectations(timeout: 15.0, handler: nil)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/ResponseFixtureTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 10/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class ResponseFixtureTest: FixtureTestCase {
13 | func testParseSuccessResponse() {
14 | let expectation = self.expectation(description: "Parse success response")
15 | let endpoint = TestAPIEndpoint(path: "dummy.success")
16 | let request: Request? = self.testClient.request(toEndpoint: endpoint) { result in
17 | defer { expectation.fulfill() }
18 | switch result {
19 | case let .success(object):
20 | XCTAssertEqual(object.object, "success_test_object")
21 | case let .fail(error):
22 | XCTFail("\(error)")
23 | }
24 | }
25 | XCTAssertNotNil(request)
26 | waitForExpectations(timeout: 15.0, handler: nil)
27 | }
28 |
29 | func testParseErrorResponse() {
30 | let expectation = self.expectation(description: "Parse error response")
31 | let endpoint = TestAPIEndpoint(path: "dummy.failure")
32 | let request: Request? = self.testClient.request(toEndpoint: endpoint) { result in
33 | defer { expectation.fulfill() }
34 | switch result {
35 | case .success(data: _):
36 | XCTFail("Should not succeed")
37 | case let .fail(error):
38 | XCTAssertEqual(error.description, "error_message")
39 | }
40 | }
41 | XCTAssertNotNil(request)
42 | waitForExpectations(timeout: 15.0, handler: nil)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/api/dummy.decoding_error.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": 1234
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/api/dummy.failure.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": false,
4 | "data": {
5 | "object": "error",
6 | "code": "error_code",
7 | "description": "error_message"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/api/dummy.listable.failure.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": false,
4 | "data": {
5 | "object": "error",
6 | "code": "error_code",
7 | "description": "error_message"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/api/dummy.paginated_listable.failure.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": false,
4 | "data": {
5 | "object": "error",
6 | "code": "error_code",
7 | "description": "error_message"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/api/dummy.success.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "object": "success_test_object"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/account.json:
--------------------------------------------------------------------------------
1 | {
2 | "object": "account",
3 | "id": "acc_01CA2P8JQANS5ATY5GJ5ETMJCF",
4 | "parent_id": "acc_01CA26PKGE49AABZD6K6MSHN0Y",
5 | "name": "Account Name",
6 | "description": "The account description",
7 | "master": false,
8 | "metadata": {},
9 | "encrypted_metadata": {},
10 | "avatar": {
11 | "original": "original_url",
12 | "large": "large_url",
13 | "small": "small_url",
14 | "thumb": "thumb_url"
15 | },
16 | "created_at": "2018-01-01T00:00:00Z",
17 | "updated_at": "2018-01-01T10:00:00Z"
18 | }
19 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/api_error.json:
--------------------------------------------------------------------------------
1 | {
2 | "code": "client:invalid_parameter",
3 | "description": "Invalid parameters"
4 | }
5 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/authentication_token.json:
--------------------------------------------------------------------------------
1 | {
2 | "authentication_token": "azJRj09l7jvR8KhTqUs3",
3 | "user_id": "usr_01cc02x0v98qcctvycfx4vsk8x",
4 | "user": {
5 | "id": "usr_01cc02x0v98qcctvycfx4vsk8x",
6 | "provider_user_id": "wijf-fbancomw-dqwjudb",
7 | "username": "john.doe@example.com",
8 | "socket_topic": "user:usr_01cc02x0v98qcctvycfx4vsk8x",
9 | "metadata": {},
10 | "encrypted_metadata": {},
11 | "created_at": "2018-01-01T00:00:00Z",
12 | "updated_at": "2018-01-01T00:00:00Z"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/avatar.json:
--------------------------------------------------------------------------------
1 | {
2 | "original": "original_url",
3 | "large": "large_url",
4 | "small": "small_url",
5 | "thumb": "thumb_url"
6 | }
7 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/balance.json:
--------------------------------------------------------------------------------
1 | {
2 | "amount": 103100,
3 | "token": {
4 | "id": "OMG:123",
5 | "symbol": "OMG",
6 | "subunit_to_unit": 10000,
7 | "name": "OmiseGO",
8 | "metadata": {},
9 | "encrypted_metadata": {},
10 | "created_at": "2018-01-01T00:00:00Z",
11 | "updated_at": "2018-01-01T00:00:00Z"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/bigint_int32.json:
--------------------------------------------------------------------------------
1 | {
2 | "value": 2147483647,
3 | }
4 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/bigint_int64.json:
--------------------------------------------------------------------------------
1 | {
2 | "value": 922337203685400,
3 | }
4 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/bigint_invalid.json:
--------------------------------------------------------------------------------
1 | {
2 | "value": 999999999999999999999999999999999999991
3 | }
4 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/bigint_over_int64.json:
--------------------------------------------------------------------------------
1 | {
2 | "value": 99999999999999999999999999999999999998,
3 | }
4 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/dates.json:
--------------------------------------------------------------------------------
1 | {
2 | "date_1": "2018-01-01T01:00:00.000000Z",
3 | "date_2": "2018-01-01T02:00:00.000Z",
4 | "date_3": "2018-01-01T03:00:00Z"
5 | }
6 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/dates_invalid.json:
--------------------------------------------------------------------------------
1 | {
2 | "invalid_date": "an invalid date"
3 | }
4 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/exchange_pair.json:
--------------------------------------------------------------------------------
1 | {
2 | "object": "exchange_pair",
3 | "id": "exg_01cgvppyrz2pprj6s0zmc26p2p",
4 | "name": "ETH/OMG",
5 | "from_token_id": "tok_ETH_01cbfge9qhmsdbjyb7a8e8pxt3",
6 | "from_token": {
7 | "id": "tok_ETH_01cbfge9qhmsdbjyb7a8e8pxt3",
8 | "symbol": "ETH",
9 | "name": "Ethereum",
10 | "subunit_to_unit": 100000,
11 | "metadata": {},
12 | "encrypted_metadata": {},
13 | "created_at": "2018-01-01T00:00:00Z",
14 | "updated_at": "2018-01-01T00:00:00Z"
15 | },
16 | "to_token_id": "tok_OMG_01cgvrqbfpa23ehkmrtqpbsyyp",
17 | "to_token": {
18 | "id": "tok_OMG_01cgvrqbfpa23ehkmrtqpbsyyp",
19 | "symbol": "OMG",
20 | "name": "OmiseGO",
21 | "subunit_to_unit": 10000,
22 | "metadata": {},
23 | "encrypted_metadata": {},
24 | "created_at": "2018-01-01T00:00:00Z",
25 | "updated_at": "2018-01-01T00:00:00Z"
26 | },
27 | "rate": 0.017,
28 | "created_at": "2018-01-01T00:00:00Z",
29 | "updated_at": "2018-01-01T10:00:00Z"
30 | }
31 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/json_list_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "data": ["value_1", "value_2"],
6 | "pagination": {
7 | "per_page": 10,
8 | "current_page": 1,
9 | "is_first_page": true,
10 | "is_last_page": true
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/json_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "data": {
5 | "a_key": "a_value"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata":{
3 | "a_string": "some_string",
4 | "an_integer": 1,
5 | "a_bool": true,
6 | "a_double": 12.34,
7 | "an_object": {
8 | "a_key": "a_value",
9 | "a_nested_object": {
10 | "a_nested_key": "a_nested_value"
11 | }
12 | },
13 | "an_array": [
14 | "value_1", "value_2"
15 | ],
16 | "a_null_key": null
17 | },
18 | "metadata_array":[
19 | "value_1",
20 | 1,
21 | true,
22 | 13.37,
23 | {
24 | "a_key": "a_value"
25 | },
26 | ["a_nested_value"]
27 | ],
28 | "optional_metadata": {
29 | "a_string": "some_string"
30 | },
31 | "optional_metadata_array": ["a_value"]
32 | }
33 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/metadata_null.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": null
3 | }
4 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/pagination.json:
--------------------------------------------------------------------------------
1 | {
2 | "per_page": 10,
3 | "current_page": 1,
4 | "is_first_page": true,
5 | "is_last_page": true
6 | }
7 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/setting.json:
--------------------------------------------------------------------------------
1 | {
2 | "tokens": [
3 | {
4 | "id": "OMG:123",
5 | "symbol": "OMG",
6 | "name": "OmiseGO",
7 | "subunit_to_unit": 100000000,
8 | "metadata": {},
9 | "encrypted_metadata": {},
10 | "created_at": "2018-01-01T00:00:00Z",
11 | "updated_at": "2018-01-01T00:00:00Z"
12 | }
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/socket_response_failure.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": false,
4 | "topic": "a_topic",
5 | "ref": "1",
6 | "event": "an_event",
7 | "error": {
8 | "object": "error",
9 | "code": "client:invalid_parameter",
10 | "description": "Invalid parameters"
11 | },
12 | "data": null,
13 | }
14 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/socket_response_reply.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "topic": "a_topic",
5 | "ref": "2",
6 | "error": null,
7 | "event": "phx_reply",
8 | "data": {}
9 | }
10 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/socket_response_unknown_object.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "success": true,
4 | "topic": "a_topic",
5 | "ref": "1",
6 | "event": "an_event",
7 | "error": null,
8 | "data": {
9 | "object": "an unknown object",
10 | "a_param": "a_value"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/token.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "OMG:123",
3 | "symbol": "OMG",
4 | "name": "OmiseGO",
5 | "subunit_to_unit": 100000000,
6 | "metadata": {},
7 | "encrypted_metadata": {},
8 | "created_at": "2018-01-01T00:00:00Z",
9 | "updated_at": "2018-01-01T00:00:00Z"
10 | }
11 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/transaction.json:
--------------------------------------------------------------------------------
1 | {
2 | "object": "transaction",
3 | "id": "ce3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
4 | "from": {
5 | "object": "transaction_source",
6 | "address": "1e3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
7 | "amount": 1000,
8 | "token": {
9 | "object": "token",
10 | "id": "BTC:xe3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
11 | "symbol": "BTC",
12 | "name": "Bitcoin",
13 | "subunit_to_unit": 100,
14 | "metadata": {},
15 | "encrypted_metadata": {},
16 | "created_at": "2018-01-01T00:00:00Z",
17 | "updated_at": "2018-01-01T00:00:00Z"
18 | }
19 | },
20 | "to": {
21 | "object": "transaction_source",
22 | "address": "2e3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
23 | "amount": 1000,
24 | "token": {
25 | "object": "token",
26 | "id": "BTC:xe3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
27 | "symbol": "BTC",
28 | "name": "Bitcoin",
29 | "subunit_to_unit": 100,
30 | "metadata": {},
31 | "encrypted_metadata": {},
32 | "created_at": "2018-01-01T00:00:00Z",
33 | "updated_at": "2018-01-01T00:00:00Z"
34 | }
35 | },
36 | "exchange": {
37 | "object": "exchange",
38 | "rate": 1,
39 | "calculated_at": null,
40 | "exchange_pair_id": null,
41 | "exchange_pair": null,
42 | "exchange_account_id": null,
43 | "exchange_account": null,
44 | "exchange_wallet_address": null,
45 | "exchange_wallet": null
46 | },
47 | "status": "confirmed",
48 | "metadata": {},
49 | "encrypted_metadata": {},
50 | "created_at": "2018-01-01T00:00:00Z",
51 | "error_code": "transaction:same_address",
52 | "error_description": "Same address"
53 | }
54 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/transaction_source.json:
--------------------------------------------------------------------------------
1 | {
2 | "object": "transaction_source",
3 | "address": "2e3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
4 | "amount": 1000,
5 | "token": {
6 | "object": "token",
7 | "id": "BTC:xe3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
8 | "symbol": "BTC",
9 | "name": "Bitcoin",
10 | "subunit_to_unit": 100,
11 | "metadata": {},
12 | "encrypted_metadata": {},
13 | "created_at": "2018-01-01T00:00:00Z",
14 | "updated_at": "2018-01-01T00:00:00Z"
15 | },
16 | "user": {
17 | "id": "cec34607-0761-4a59-8357-18963e42a1aa",
18 | "provider_user_id": "wijf-fbancomw-dqwjudb",
19 | "username": "john.doe@example.com",
20 | "email": "john.doe@example.com",
21 | "socket_topic": "user:cec34607-0761-4a59-8357-18963e42a1aa",
22 | "metadata": {},
23 | "encrypted_metadata": {},
24 | "created_at": "2018-01-01T00:00:00Z",
25 | "updated_at": "2018-01-01T00:00:00Z"
26 | },
27 | "account": {
28 | "object": "account",
29 | "id": "acc_01CA2P8JQANS5ATY5GJ5ETMJCF",
30 | "parent_id": "acc_01CA26PKGE49AABZD6K6MSHN0Y",
31 | "name": "Account Name",
32 | "description": "The account description",
33 | "master": false,
34 | "metadata": {},
35 | "encrypted_metadata": {},
36 | "avatar": {
37 | "original": "original_url",
38 | "large": "large_url",
39 | "small": "small_url",
40 | "thumb": "thumb_url"
41 | },
42 | "created_at": "2018-01-01T00:00:00Z",
43 | "updated_at": "2018-01-01T10:00:00Z"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/user.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "cec34607-0761-4a59-8357-18963e42a1aa",
3 | "provider_user_id": "wijf-fbancomw-dqwjudb",
4 | "username": "john.doe@example.com",
5 | "email": "john.doe@example.com",
6 | "socket_topic": "user:cec34607-0761-4a59-8357-18963e42a1aa",
7 | "metadata": {},
8 | "encrypted_metadata": {},
9 | "created_at": "2018-01-01T00:00:00Z",
10 | "updated_at": "2018-01-01T00:00:00Z"
11 | }
12 |
--------------------------------------------------------------------------------
/Tests/Core/FixtureTests/core_fixtures/objects/wallet.json:
--------------------------------------------------------------------------------
1 | {
2 | "address": "2c2e0f2e-fa0f-4abe-8516-9e92cf003486",
3 | "balances": [
4 | {
5 | "amount": 103100,
6 | "token": {
7 | "id": "OMG:123",
8 | "symbol": "OMG",
9 | "subunit_to_unit": 10000,
10 | "name": "OmiseGO",
11 | "metadata": {},
12 | "encrypted_metadata": {},
13 | "created_at": "2018-01-01T00:00:00Z",
14 | "updated_at": "2018-01-01T00:00:00Z"
15 | }
16 | }
17 | ],
18 | "name": "primary",
19 | "identifier": "primary",
20 | "user_id": "cec34607-0761-4a59-8357-18963e42a1aa",
21 | "user": {
22 | "id": "cec34607-0761-4a59-8357-18963e42a1aa",
23 | "provider_user_id": "wijf-fbancomw-dqwjudb",
24 | "username": "john.doe@example.com",
25 | "socket_topic": "user:cec34607-0761-4a59-8357-18963e42a1aa",
26 | "metadata": {},
27 | "encrypted_metadata": {},
28 | "created_at": "2018-01-01T00:00:00Z",
29 | "updated_at": "2018-01-01T00:00:00Z"
30 | },
31 | "account_id": null,
32 | "account": null,
33 | "metadata": {},
34 | "encrypted_metadata": {}
35 | }
36 |
--------------------------------------------------------------------------------
/Tests/Core/Helpers/Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extension.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 23/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension String {
12 | func toDate(withFormat format: String? = "yyyy-MM-dd'T'HH:mm:ssZ") -> Date {
13 | let formatter = DateFormatter()
14 | formatter.dateFormat = format
15 | return formatter.date(from: self)!
16 | }
17 | }
18 |
19 | extension String {
20 | func uglifiedEncodedString() -> String {
21 | return replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: " ", with: "")
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/AccountTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AccountTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 20/4/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class AccountTest: XCTestCase {
13 | func testEquatable() {
14 | let account1 = StubGenerator.account(id: "123")
15 | let account2 = StubGenerator.account(id: "123")
16 | let account3 = StubGenerator.account(id: "321")
17 | XCTAssertEqual(account1, account2)
18 | XCTAssertNotEqual(account1, account3)
19 | }
20 |
21 | func testHashable() {
22 | let account1 = StubGenerator.account(id: "123")
23 | let account2 = StubGenerator.account(id: "123")
24 | let set: Set = [account1, account2]
25 | XCTAssertEqual(account1.hashValue, "123".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/AuthenticationTokenTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AuthenticationTokenTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 15/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class AuthenticationTokenTests: XCTestCase {
13 | func testEquatable() {
14 | let token1 = StubGenerator.authenticationToken(token: "123")
15 | let token2 = StubGenerator.authenticationToken(token: "123")
16 | let token3 = StubGenerator.authenticationToken(token: "789")
17 | XCTAssertEqual(token1, token2)
18 | XCTAssertNotEqual(token1, token3)
19 | }
20 |
21 | func testHashable() {
22 | let token1 = StubGenerator.authenticationToken(token: "123")
23 | let token2 = StubGenerator.authenticationToken(token: "123")
24 | let set: Set = [token1, token2]
25 | XCTAssertEqual(token1.hashValue, "123".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/ExchangePairTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExchangePairTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 29/6/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class ExchangePairTest: XCTestCase {
13 | func testEquatable() {
14 | let pair1 = StubGenerator.exchangePair(id: "123")
15 | let pair2 = StubGenerator.exchangePair(id: "123")
16 | let pair3 = StubGenerator.exchangePair(id: "321")
17 | XCTAssertEqual(pair1, pair2)
18 | XCTAssertNotEqual(pair1, pair3)
19 | }
20 |
21 | func testHashable() {
22 | let pair1 = StubGenerator.exchangePair(id: "123")
23 | let pair2 = StubGenerator.exchangePair(id: "123")
24 | let set: Set = [pair1, pair2]
25 | XCTAssertEqual(pair1.hashValue, "123".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/TokenTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TokenTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 20/11/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class TokenTests: XCTestCase {
13 | func testEquatable() {
14 | let token1 = StubGenerator.token(id: "OMG:123")
15 | let token2 = StubGenerator.token(id: "OMG:123")
16 | let token3 = StubGenerator.token(id: "BTC:123")
17 | XCTAssertEqual(token1, token2)
18 | XCTAssertNotEqual(token1, token3)
19 | }
20 |
21 | func testHashable() {
22 | let token1 = StubGenerator.token(id: "OMG:123")
23 | let token2 = StubGenerator.token(id: "OMG:123")
24 | let set: Set = [token1, token2]
25 | XCTAssertEqual(token1.hashValue, "OMG:123".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/TransactionConsumptionTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionConsumptionTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 13/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class TransactionConsumptionTest: XCTestCase {
13 | func testEquatable() {
14 | let transactionConsumption1 = StubGenerator.transactionConsumption(id: "1")
15 | let transactionConsumption2 = StubGenerator.transactionConsumption(id: "1")
16 | let transactionConsumption3 = StubGenerator.transactionConsumption(id: "2")
17 | XCTAssertEqual(transactionConsumption1, transactionConsumption2)
18 | XCTAssertNotEqual(transactionConsumption1, transactionConsumption3)
19 | }
20 |
21 | func testHashable() {
22 | let transactionConsumption1 = StubGenerator.transactionConsumption(id: "1")
23 | let transactionConsumption2 = StubGenerator.transactionConsumption(id: "1")
24 | let set: Set = [transactionConsumption1, transactionConsumption2]
25 | XCTAssertEqual(transactionConsumption1.hashValue, "1".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/TransactionRequestTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionRequestTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 5/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class TransactionRequestTest: XCTestCase {
13 | func testQRCodeImage() {
14 | let transactionRequest = StubGenerator.transactionRequest()
15 | if let qrImage = transactionRequest.qrImage() {
16 | let decodedText = TestQRHelper.readQRCode(fromImage: qrImage)
17 | XCTAssertEqual(decodedText, transactionRequest.formattedId)
18 | } else {
19 | XCTFail("QR image should not be nil")
20 | }
21 | }
22 |
23 | func testEquatable() {
24 | let transactionRequest1 = StubGenerator.transactionRequest(id: "1")
25 | let transactionRequest2 = StubGenerator.transactionRequest(id: "1")
26 | let transactionRequest3 = StubGenerator.transactionRequest(id: "2")
27 | XCTAssertEqual(transactionRequest1, transactionRequest2)
28 | XCTAssertNotEqual(transactionRequest1, transactionRequest3)
29 | }
30 |
31 | func testHashable() {
32 | let transactionRequest1 = StubGenerator.transactionRequest(id: "1")
33 | let transactionRequest2 = StubGenerator.transactionRequest(id: "1")
34 | let set: Set = [transactionRequest1, transactionRequest2]
35 | XCTAssertEqual(transactionRequest1.hashValue, "1".hashValue)
36 | XCTAssertEqual(set.count, 1)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/TransactionTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransactionTest.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 23/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class TransactionTest: XCTestCase {
13 | func testEquatable() {
14 | let transaction1 = StubGenerator.transaction(id: "1")
15 | let transaction2 = StubGenerator.transaction(id: "1")
16 | let transaction3 = StubGenerator.transaction(id: "2")
17 | XCTAssertEqual(transaction1, transaction2)
18 | XCTAssertNotEqual(transaction1, transaction3)
19 | }
20 |
21 | func testHashable() {
22 | let transaction1 = StubGenerator.transaction(id: "1")
23 | let transaction2 = StubGenerator.transaction(id: "1")
24 | let set: Set = [transaction1, transaction2]
25 | XCTAssertEqual(transaction1.hashValue, "1".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/UserTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UserTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 20/11/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class UserTests: XCTestCase {
13 | func testEquatable() {
14 | let user1 = StubGenerator.user(id: "123")
15 | let user2 = StubGenerator.user(id: "123")
16 | let user3 = StubGenerator.user(id: "321")
17 | XCTAssertEqual(user1, user2)
18 | XCTAssertNotEqual(user1, user3)
19 | }
20 |
21 | func testHashable() {
22 | let user1 = StubGenerator.user(id: "123")
23 | let user2 = StubGenerator.user(id: "123")
24 | let set: Set = [user1, user2]
25 | XCTAssertEqual(user1.hashValue, "123".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/ModelTests/WalletTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WalletTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 20/11/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 | import XCTest
11 |
12 | class WalletTests: XCTestCase {
13 | func testEquatable() {
14 | let address1 = StubGenerator.wallet(address: "123")
15 | let address2 = StubGenerator.wallet(address: "123")
16 | let address3 = StubGenerator.wallet(address: "321")
17 | XCTAssertEqual(address1, address2)
18 | XCTAssertNotEqual(address1, address3)
19 | }
20 |
21 | func testHashable() {
22 | let address1 = StubGenerator.wallet(address: "123")
23 | let address2 = StubGenerator.wallet(address: "123")
24 | let set: Set = [address1, address2]
25 | XCTAssertEqual(address1.hashValue, "123".hashValue)
26 | XCTAssertEqual(set.count, 1)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Tests/Core/OMGNumberFormatterTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OMGNumberFormatterTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 18/6/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import BigInt
10 | @testable import OmiseGO
11 | import XCTest
12 |
13 | class OMGNumberFormatterTests: XCTestCase {
14 | let locale = NSLocale.current
15 |
16 | func testStringToBigIntWithSubunitToUnit() {
17 | let sut = OMGNumberFormatter(locale: self.locale, precision: 1)
18 | let result = sut.number(from: "10", subunitToUnit: 1_000_000_000_000_000_000)
19 | XCTAssertEqual(result, BigInt("10000000000000000000"))
20 | }
21 |
22 | func testStringToBigIntWithDecimal() {
23 | let sut = OMGNumberFormatter(locale: self.locale, precision: 1)
24 | let result = sut.number(from: "10", decimals: 18)
25 | XCTAssertEqual(result, BigInt("10000000000000000000"))
26 | }
27 |
28 | func testStringToBigIntWithDecimalAndPrecision() {
29 | let sut = OMGNumberFormatter(locale: self.locale, precision: 10000)
30 | let result = sut.number(from: "10", decimals: 18)
31 | XCTAssertEqual(result, BigInt("10000000000000000000"))
32 | }
33 |
34 | func testStringFromBigIntWithSubunitToUnit() {
35 | let sut = OMGNumberFormatter(locale: self.locale, precision: 1)
36 | let result = sut.string(from: BigInt("10000000000000000000"), subunitToUnit: 1_000_000_000_000_000_000)
37 | XCTAssertEqual(result, "10")
38 | }
39 |
40 | func testStringFromBigIntWithDecimal() {
41 | let sut = OMGNumberFormatter(locale: self.locale, precision: 1)
42 | let result = sut.string(from: BigInt("10000000000000000000"), decimals: 18)
43 | XCTAssertEqual(result, "10")
44 | }
45 |
46 | func testStringFromBigIntWithDecimalAndPrecision() {
47 | let sut = OMGNumberFormatter(locale: self.locale, precision: 2)
48 | let result = sut.string(from: BigInt("1"), decimals: 2)
49 | XCTAssertEqual(result, "0\(self.locale.decimalSeparator ?? ".")01")
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Tests/Core/QRCodeTests/QRGeneratorTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRGeneratorTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 6/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class QRGeneratorTest: XCTestCase {
13 | func testImageSize() {
14 | let data = "Test data".data(using: .isoLatin1)!
15 | if let qrCode = QRGenerator.generateQRCode(fromData: data, outputSize: CGSize(width: 150, height: 150)) {
16 | XCTAssertEqual(qrCode.size.width, 150)
17 | XCTAssertEqual(qrCode.size.height, 150)
18 | } else {
19 | XCTFail("Failed to generate the qrCode")
20 | }
21 | }
22 |
23 | func testGeneratedQRCodeContainsInputText() {
24 | let inputText = "Test data"
25 | let data = inputText.data(using: .isoLatin1)!
26 | if let qrCode = QRGenerator.generateQRCode(fromData: data, outputSize: CGSize(width: 200, height: 200)) {
27 | let decodedText = TestQRHelper.readQRCode(fromImage: qrCode)
28 | XCTAssertEqual(decodedText, inputText)
29 | } else {
30 | XCTFail("Failed to generate the qrCode")
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/Core/QRCodeTests/QRReaderTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRReaderTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 12/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 | @testable import OmiseGO
11 | import XCTest
12 |
13 | class QRReaderTest: XCTestCase {
14 | func testCallbackIsCalled() {
15 | let e = self.expectation(description: "calls delegate when decoding data")
16 | let delegate = DummyQRReaderDelegate(ex: e)
17 | let reader = TestQRReader(delegate: delegate)
18 | reader.mockValueFound(value: "123")
19 | waitForExpectations(timeout: 1, handler: nil)
20 | XCTAssertEqual(delegate.decodedData, "123")
21 | }
22 | }
23 |
24 | class DummyQRReaderDelegate: QRReaderDelegate {
25 | let e: XCTestExpectation
26 | var decodedData: String?
27 |
28 | init(ex: XCTestExpectation) {
29 | self.e = ex
30 | }
31 |
32 | func onDecodedData(decodedData: String) {
33 | self.decodedData = decodedData
34 | self.e.fulfill()
35 | }
36 |
37 | func onUserPermissionChoice(granted _: Bool) {}
38 | }
39 |
--------------------------------------------------------------------------------
/Tests/Core/QRCodeTests/QRScannerViewTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRScannerViewTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 7/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class QRScannerViewTest: XCTestCase {
13 | func testInitWithCoder() {
14 | XCTAssertNil(QRScannerView(coder: NSCoder()))
15 | }
16 |
17 | func testInitWithFrame() {
18 | let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
19 | let layer = CALayer()
20 | let view = QRScannerView(frame: frame, readerPreviewLayer: layer)
21 | XCTAssertEqual(view.frame, frame)
22 | XCTAssertEqual(view.readerPreviewLayer, layer)
23 | }
24 |
25 | func testLayoutSubviews() {
26 | let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
27 | let layer = CALayer()
28 | let view = QRScannerView(frame: frame, readerPreviewLayer: layer)
29 | XCTAssertEqual(layer.frame, CGRect(x: 0, y: 0, width: 0, height: 0))
30 | view.layoutSubviews()
31 | XCTAssertEqual(layer.frame, frame)
32 | }
33 |
34 | func testSetup() {
35 | let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
36 | let layer = CALayer()
37 | let view = QRScannerView(frame: frame, readerPreviewLayer: layer)
38 | view.setup()
39 | XCTAssertTrue(view.subviews.contains(view.cameraView))
40 | XCTAssertTrue(view.subviews.contains(view.overlayView))
41 | XCTAssertTrue(view.subviews.contains(view.cancelButton))
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Tests/Core/SocketsTests/FixtureSocketClient.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FixtureSocketClient.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 23/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import Starscream
10 |
11 | class FixtureWebsocketClient: WebSocketClient {
12 | var sslClientCertificate: SSLClientCertificate?
13 |
14 | var delegate: WebSocketDelegate?
15 | var pongDelegate: WebSocketPongDelegate?
16 | var disableSSLCertValidation: Bool = true
17 | var overrideTrustHostname: Bool = false
18 | var desiredTrustHostname: String?
19 | var security: SSLTrustValidator?
20 | var enabledSSLCipherSuites: [SSLCipherSuite]?
21 | var isConnected: Bool = false
22 |
23 | var didWriteString: String?
24 | var didWriteData: Data?
25 |
26 | var shouldAutoConnect = true
27 |
28 | func connect() {
29 | self.isConnected = self.shouldAutoConnect
30 | }
31 |
32 | func disconnect(forceTimeout _: TimeInterval?, closeCode _: UInt16) {
33 | self.isConnected = false
34 | }
35 |
36 | func write(string: String, completion: (() -> Void)?) {
37 | self.didWriteString = string
38 | completion?()
39 | }
40 |
41 | func write(data: Data, completion: (() -> Void)?) {
42 | self.didWriteData = data
43 | completion?()
44 | (self.delegate as? TestWebSocketDelegate)?.websocketDidSendData(socket: self, data: data)
45 | }
46 |
47 | func write(ping _: Data, completion: (() -> Void)?) {
48 | completion?()
49 | }
50 |
51 | func write(pong _: Data, completion: (() -> Void)?) {
52 | completion?()
53 | }
54 |
55 | func simulateReply() {
56 | let data = StubGenerator.fileContent(forResource: "socket_response_reply")
57 | self.delegate?.websocketDidReceiveMessage(socket: self, text: String(data: data, encoding: .utf8)!)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Tests/Core/SocketsTests/SocketMessageTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketMessageTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 22/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class SocketMessageTests: XCTestCase {
13 | var socketMessage: SocketMessage!
14 |
15 | override func setUp() {
16 | super.setUp()
17 | let payload = SocketPayloadSend(topic: "a_topic", event: .join, ref: "1", data: [:])
18 | self.socketMessage = SocketMessage(socketPayload: payload)
19 | }
20 |
21 | func testCallsSuccessHandlerWhenSucceed() {
22 | let expectation = self.expectation(description: "Calls success handler when succeed")
23 | let payload = StubGenerator.socketPayloadReceive()
24 | let handler: ((GenericObjectEnum?) -> Void) = { response in
25 | switch response {
26 | case let .some(.transactionConsumption(object: tc)): XCTAssertNotNil(tc)
27 | default: XCTFail("Unexpected response")
28 | }
29 | expectation.fulfill()
30 | }
31 | self.socketMessage.onSuccess(handler)
32 | self.socketMessage.handleResponse(withPayload: payload)
33 | self.waitForExpectations(timeout: 1, handler: nil)
34 | }
35 |
36 | func testCallsErrorHandlerWhenFail() {
37 | let expectation = self.expectation(description: "Calls failure handler when fail")
38 | let payload = StubGenerator.socketPayloadReceive(error: APIError(code: .websocketError, description: ""),
39 | success: false)
40 | let handler: ((APIError) -> Void) = { error in
41 | XCTAssertEqual(error.code, .websocketError)
42 | expectation.fulfill()
43 | }
44 | self.socketMessage.onError(handler)
45 | self.socketMessage.handleResponse(withPayload: payload)
46 | self.waitForExpectations(timeout: 1, handler: nil)
47 | }
48 |
49 | func testTopicReturnsCorrectValue() {
50 | let payloadSend = SocketPayloadSend(topic: "topic_a", event: .join, ref: "1", data: [:])
51 | let socketMessageSend = SocketMessage(socketPayload: payloadSend)
52 | XCTAssertEqual(socketMessageSend.topic(), "topic_a")
53 | let payloadReceive = StubGenerator.socketPayloadReceive(topic: "topic_b")
54 | let socketMessageReceive = SocketMessage(socketPayload: payloadReceive)
55 | XCTAssertEqual(socketMessageReceive.topic(), "topic_b")
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/QRScannerViewController+Test.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QRScannerViewController+Test.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 9/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 |
11 | extension QRScannerViewController {
12 | convenience init?(delegate: QRScannerViewControllerDelegate, verifier: TestQRVerifier, cancelButtonTitle: String) {
13 | self.init(delegate: delegate,
14 | verifier: verifier,
15 | cancelButtonTitle: cancelButtonTitle,
16 | viewModel: QRScannerViewModel(verifier: verifier))
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestAPIEndpoint.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestAPIEndpoint.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 9/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 |
11 | struct TestAPIEndpoint: APIEndpoint {
12 | let path: String
13 | let task: HTTPTask
14 |
15 | init(path: String = "/test", task: HTTPTask = .requestPlain) {
16 | self.path = path
17 | self.task = task
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestBigUInt.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestBigUInt.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 18/6/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import BigInt
10 | @testable import OmiseGO
11 |
12 | struct TestBigUInt {
13 | let value: BigInt
14 | }
15 |
16 | extension TestBigUInt: Codable {
17 | private enum CodingKeys: String, CodingKey {
18 | case value
19 | }
20 |
21 | func encode(to encoder: Encoder) throws {
22 | var container = encoder.container(keyedBy: CodingKeys.self)
23 | try container.encode(value, forKey: .value)
24 | }
25 |
26 | init(from decoder: Decoder) throws {
27 | let container = try decoder.container(keyedBy: CodingKeys.self)
28 | value = try container.decode(BigInt.self, forKey: .value)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestConfiguration.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestConfiguration.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 9/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 |
11 | struct TestConfiguration: Configuration {
12 | let apiVersion: String = "1"
13 |
14 | let baseURL: String
15 |
16 | var credentials: Credential
17 |
18 | let debugLog: Bool = false
19 |
20 | init(baseURL: String = "http://localhost:4000", credentials: TestCredential = TestCredential(authenticated: true)) {
21 | self.baseURL = baseURL
22 | self.credentials = credentials
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestCredential.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestCredential.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 9/8/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 |
11 | struct TestCredential: Credential {
12 | var authenticated: Bool
13 |
14 | init(authenticated: Bool) {
15 | self.authenticated = authenticated
16 | }
17 |
18 | func isAuthenticated() -> Bool {
19 | return self.authenticated
20 | }
21 |
22 | mutating func update(withAuthenticationToken _: AuthenticationToken) {
23 | self.authenticated = true
24 | }
25 |
26 | func authentication() throws -> String? {
27 | return self.authenticated ? "OMGClient \("123:123".data(using: .utf8)!.base64EncodedString())" : nil
28 | }
29 |
30 | mutating func invalidate() {
31 | self.authenticated = false
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestDate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestDate.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 23/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct TestDate: Decodable {
12 | let date1: Date
13 | let date2: Date
14 | let date3: Date
15 |
16 | enum CodingKeys: String, CodingKey {
17 | case date1 = "date_1"
18 | case date2 = "date_2"
19 | case date3 = "date_3"
20 | }
21 | }
22 |
23 | struct TestDateInvalid: Decodable {
24 | let invalidDate: Date
25 |
26 | enum CodingKeys: String, CodingKey {
27 | case invalidDate = "invalid_date"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestListable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestListable.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 7/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 |
11 | struct TestListable: Decodable, Listable {
12 | static func list(using client: HTTPAPI,
13 | callback: @escaping ListRequestCallback) {
14 | let endpoint = TestAPIEndpoint(path: "dummy.listable.failure")
15 | self.list(using: client, endpoint: endpoint, callback: callback)
16 | }
17 | }
18 |
19 | struct PaginatedTestListable: Decodable, PaginatedListable {
20 | let dummy: String = "123"
21 |
22 | enum FilterableFields: String, RawEnumerable {
23 | case dummy
24 | }
25 |
26 | enum SortableFields: String, RawEnumerable {
27 | case dummy
28 | }
29 |
30 | static func list(using client: HTTPAPI,
31 | callback: @escaping PaginatedTestListable.PaginatedListRequestCallback) {
32 | let endpoint = TestAPIEndpoint(path: "dummy.listable.failure")
33 | self.list(using: client, endpoint: endpoint, callback: callback)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestObject.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestObject.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 11/10/2017.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import UIKit
11 |
12 | struct TestObject: APIParameters, Decodable {
13 | func encodedPayload() -> Data? {
14 | return try? JSONEncoder().encode(self)
15 | }
16 |
17 | var object: String = ""
18 | }
19 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestQRHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestQRHelper.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 7/2/2018.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct TestQRHelper {
12 | static func readQRCode(fromImage image: UIImage) -> String {
13 | let detector: CIDetector = CIDetector(ofType: CIDetectorTypeQRCode,
14 | context: nil,
15 | options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])!
16 | let features = detector.features(in: CIImage(image: image)!)
17 | var result: String = ""
18 | for feature in features as! [CIQRCodeFeature] {
19 | result += feature.messageString ?? ""
20 | }
21 | return result
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestSortable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestSortable.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 23/2/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import OmiseGO
10 |
11 | struct TestPaginatedListable: PaginatedListable {
12 | let aSortableAttribute: String
13 | let aNonSortableAttribute: String
14 |
15 | let aSearchableAttribute: String
16 | let aNonSearchableAttribute: String
17 |
18 | enum SortableFields: String, RawEnumerable {
19 | case aSortableAttribute = "a_sortable_attribute"
20 | }
21 |
22 | enum FilterableFields: String, RawEnumerable {
23 | case aFilterableAttribute = "a_searchable_attribute"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Tests/Core/TestMocks/TestWebSocketDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestWebSocketDelegate.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 23/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | import Starscream
10 | import XCTest
11 |
12 | class TestWebSocketDelegate: WebSocketDelegate {
13 | var didConnect: Bool = false
14 | var didDisconnect: Bool = false
15 | var didReceiveText: String?
16 | var didReceiveData: Data?
17 | var didSendData: Data?
18 |
19 | let expectation: XCTestExpectation?
20 |
21 | init(expectation: XCTestExpectation? = nil) {
22 | self.expectation = expectation
23 | }
24 |
25 | func websocketDidConnect(socket _: WebSocketClient) {
26 | self.didConnect = true
27 | }
28 |
29 | func websocketDidDisconnect(socket _: WebSocketClient, error _: Error?) {
30 | self.didDisconnect = true
31 | }
32 |
33 | func websocketDidReceiveMessage(socket _: WebSocketClient, text: String) {
34 | self.didReceiveText = text
35 | self.expectation?.fulfill()
36 | }
37 |
38 | func websocketDidReceiveData(socket _: WebSocketClient, data: Data) {
39 | self.didReceiveData = data
40 | self.expectation?.fulfill()
41 | }
42 |
43 | func websocketDidSendData(socket _: WebSocketClient, data: Data) {
44 | self.didSendData = data
45 | self.expectation?.fulfill()
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Tests/Core/ToolsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ToolsTests.swift
3 | // Tests
4 | //
5 | // Created by Mederic Petit on 7/3/18.
6 | // Copyright © 2017-2018 Omise Go Pte. Ltd. All rights reserved.
7 | //
8 |
9 | @testable import OmiseGO
10 | import XCTest
11 |
12 | class ToolsTests: XCTestCase {
13 | func testDateToString() {
14 | let date = Date(timeIntervalSince1970: 0)
15 | let defaultFormat = date.toString(timeZone: TimeZone(secondsFromGMT: 0))
16 | XCTAssertEqual(defaultFormat, "1970-01-01T00:00:00Z")
17 | let customFormat = date.toString(withFormat: "yyyy MM dd HH:mm:ss", timeZone: TimeZone(secondsFromGMT: 0))
18 | XCTAssertEqual(customFormat, "1970 01 01 00:00:00")
19 | }
20 |
21 | func testDecodingContainerProtocol() {
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Tests/secret.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | OMG_BASE_URL
6 |
7 | OMG_WEBSOCKET_URL
8 |
9 | OMG_API_KEY
10 |
11 | OMG_CLIENT_AUTHENTICATION_TOKEN
12 |
13 | OMG_TOKEN_ID
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------