passfort 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +17 -17
  3. data/.rubocop.yml +5 -5
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +33 -28
  6. data/Gemfile +5 -5
  7. data/Gemfile.lock +91 -89
  8. data/LICENCE.txt +22 -22
  9. data/README.md +6 -6
  10. data/lib/passfort.rb +35 -35
  11. data/lib/passfort/client.rb +23 -23
  12. data/lib/passfort/endpoint.rb +10 -10
  13. data/lib/passfort/endpoint/checks.rb +19 -19
  14. data/lib/passfort/endpoint/profiles.rb +46 -46
  15. data/lib/passfort/endpoint/tasks.rb +16 -16
  16. data/lib/passfort/errors.rb +15 -15
  17. data/lib/passfort/errors/api_error.rb +16 -16
  18. data/lib/passfort/errors/chargeable_limit_reached_error.rb +12 -12
  19. data/lib/passfort/errors/invalid_api_key_error.rb +12 -12
  20. data/lib/passfort/errors/invalid_input_data_error.rb +12 -12
  21. data/lib/passfort/errors/request_error.rb +12 -12
  22. data/lib/passfort/errors/timeout_error.rb +12 -12
  23. data/lib/passfort/errors/unknown_api_error.rb +12 -12
  24. data/lib/passfort/errors/unparseable_response_error.rb +11 -11
  25. data/lib/passfort/http.rb +89 -65
  26. data/lib/passfort/resource.rb +12 -12
  27. data/lib/passfort/resource/base.rb +21 -21
  28. data/lib/passfort/resource/check.rb +10 -10
  29. data/lib/passfort/resource/company_data.rb +11 -11
  30. data/lib/passfort/resource/individual_data.rb +11 -11
  31. data/lib/passfort/resource/profile.rb +15 -15
  32. data/lib/passfort/resource/task.rb +9 -9
  33. data/lib/passfort/version.rb +5 -5
  34. data/passfort.gemspec +30 -29
  35. data/spec/fixtures/check.json +67 -67
  36. data/spec/fixtures/collected_data.json +7 -7
  37. data/spec/fixtures/company_ownership_check/check.json +78 -78
  38. data/spec/fixtures/company_ownership_check/collected_data.json +7 -7
  39. data/spec/fixtures/company_ownership_check/collected_data_update_request.json +63 -63
  40. data/spec/fixtures/company_ownership_check/profile.json +128 -128
  41. data/spec/fixtures/profile.json +128 -128
  42. data/spec/fixtures/task.json +6 -6
  43. data/spec/integration/company_ownership_check_spec.rb +74 -74
  44. data/spec/passfort/endpoint/checks_spec.rb +22 -22
  45. data/spec/passfort/endpoint/profiles_spec.rb +79 -79
  46. data/spec/passfort/endpoint/tasks_spec.rb +21 -21
  47. data/spec/passfort/http_spec.rb +130 -95
  48. data/spec/spec_helper.rb +9 -9
  49. metadata +16 -2
@@ -1,79 +1,79 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- RSpec.describe Passfort::Endpoint::Profiles do
6
- let(:profiles) { described_class.new(client) }
7
-
8
- let(:client) { instance_double(Passfort::Http) }
9
-
10
- let(:profile_fixture) { JSON.parse(load_fixture("profile.json")) }
11
- let(:collected_data_fixture) { JSON.parse(load_fixture("collected_data.json")) }
12
-
13
- describe "#create" do
14
- subject { profiles.create(role: role, collected_data: collected_data) }
15
-
16
- let(:role) { Passfort::Role::COMPANY_CUSTOMER }
17
- let(:collected_data) { {} }
18
-
19
- before do
20
- allow(client).
21
- to receive(:post).
22
- with("/profiles", body: { role: role, collected_data: collected_data }).
23
- and_return(profile_fixture)
24
- end
25
-
26
- it { is_expected.to have_attributes(id: profile_fixture["id"]) }
27
- end
28
-
29
- describe "#find" do
30
- subject { profiles.find(id) }
31
-
32
- let(:id) { profile_fixture["id"] }
33
-
34
- before do
35
- allow(client).to receive(:get).with("/profiles/#{id}").and_return(profile_fixture)
36
- end
37
-
38
- it { is_expected.to have_attributes(id: id) }
39
- end
40
-
41
- describe "#collected_data" do
42
- subject { profiles.collected_data(id) }
43
-
44
- let(:id) { profile_fixture["id"] }
45
-
46
- before do
47
- allow(client).
48
- to receive(:get).
49
- with("/profiles/#{id}/collected_data").
50
- and_return(collected_data_fixture)
51
- end
52
-
53
- it { is_expected.to have_attributes(entity_type: Passfort::EntityType::COMPANY) }
54
- it { is_expected.to be_a(Passfort::Resource::CompanyData) }
55
- end
56
-
57
- describe "#update_collected_data" do
58
- subject { profiles.update_collected_data(id, data) }
59
-
60
- let(:id) { profile_fixture["id"] }
61
- let(:data) do
62
- collected_data_fixture.merge(metadata: { country_of_incorporation: "FR" })
63
- end
64
-
65
- before do
66
- allow(client).
67
- to receive(:post).
68
- with("/profiles/#{id}/collected_data", body: data).
69
- and_return(data)
70
- end
71
-
72
- it do
73
- is_expected.to have_attributes(
74
- entity_type: Passfort::EntityType::COMPANY,
75
- metadata: { country_of_incorporation: "FR" },
76
- )
77
- end
78
- end
79
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Passfort::Endpoint::Profiles do
6
+ let(:profiles) { described_class.new(client) }
7
+
8
+ let(:client) { instance_double(Passfort::Http) }
9
+
10
+ let(:profile_fixture) { JSON.parse(load_fixture("profile.json")) }
11
+ let(:collected_data_fixture) { JSON.parse(load_fixture("collected_data.json")) }
12
+
13
+ describe "#create" do
14
+ subject { profiles.create(role: role, collected_data: collected_data) }
15
+
16
+ let(:role) { Passfort::Role::COMPANY_CUSTOMER }
17
+ let(:collected_data) { {} }
18
+
19
+ before do
20
+ allow(client).
21
+ to receive(:post).
22
+ with("/profiles", body: { role: role, collected_data: collected_data }).
23
+ and_return(profile_fixture)
24
+ end
25
+
26
+ it { is_expected.to have_attributes(id: profile_fixture["id"]) }
27
+ end
28
+
29
+ describe "#find" do
30
+ subject { profiles.find(id) }
31
+
32
+ let(:id) { profile_fixture["id"] }
33
+
34
+ before do
35
+ allow(client).to receive(:get).with("/profiles/#{id}").and_return(profile_fixture)
36
+ end
37
+
38
+ it { is_expected.to have_attributes(id: id) }
39
+ end
40
+
41
+ describe "#collected_data" do
42
+ subject { profiles.collected_data(id) }
43
+
44
+ let(:id) { profile_fixture["id"] }
45
+
46
+ before do
47
+ allow(client).
48
+ to receive(:get).
49
+ with("/profiles/#{id}/collected_data").
50
+ and_return(collected_data_fixture)
51
+ end
52
+
53
+ it { is_expected.to have_attributes(entity_type: Passfort::EntityType::COMPANY) }
54
+ it { is_expected.to be_a(Passfort::Resource::CompanyData) }
55
+ end
56
+
57
+ describe "#update_collected_data" do
58
+ subject { profiles.update_collected_data(id, data) }
59
+
60
+ let(:id) { profile_fixture["id"] }
61
+ let(:data) do
62
+ collected_data_fixture.merge(metadata: { country_of_incorporation: "FR" })
63
+ end
64
+
65
+ before do
66
+ allow(client).
67
+ to receive(:post).
68
+ with("/profiles/#{id}/collected_data", body: data).
69
+ and_return(data)
70
+ end
71
+
72
+ it do
73
+ is_expected.to have_attributes(
74
+ entity_type: Passfort::EntityType::COMPANY,
75
+ metadata: { country_of_incorporation: "FR" },
76
+ )
77
+ end
78
+ end
79
+ end
@@ -1,21 +1,21 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- RSpec.describe Passfort::Endpoint::Tasks do
6
- let(:endpoint) { described_class.new(Passfort::Http.new("api_key")) }
7
-
8
- describe "#find" do
9
- subject { endpoint.find(profile_id: profile_id, task_id: task_id) }
10
-
11
- let(:profile_id) { "a_profile_id" }
12
- let(:task_id) { "a_task_id" }
13
-
14
- before do
15
- stub_request(:get, %r{/profiles/#{profile_id}/tasks/#{task_id}\z}).
16
- to_return(status: 200, body: load_fixture("task.json"))
17
- end
18
-
19
- it { is_expected.to have_attributes(id: "33cdc540-61e0-11e7-b07b-acbc32b67d7b") }
20
- end
21
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Passfort::Endpoint::Tasks do
6
+ let(:endpoint) { described_class.new(Passfort::Http.new("api_key")) }
7
+
8
+ describe "#find" do
9
+ subject { endpoint.find(profile_id: profile_id, task_id: task_id) }
10
+
11
+ let(:profile_id) { "a_profile_id" }
12
+ let(:task_id) { "a_task_id" }
13
+
14
+ before do
15
+ stub_request(:get, %r{/profiles/#{profile_id}/tasks/#{task_id}\z}).
16
+ to_return(status: 200, body: load_fixture("task.json"))
17
+ end
18
+
19
+ it { is_expected.to have_attributes(id: "33cdc540-61e0-11e7-b07b-acbc32b67d7b") }
20
+ end
21
+ end
@@ -1,95 +1,130 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- RSpec.describe Passfort::Http do
6
- let(:http) { described_class.new("api_key") }
7
- let(:path) { "a/path" }
8
-
9
- shared_examples "an API call that handles all errors" do
10
- let(:api_path) { Passfort::Http::DOMAIN + Passfort::Http::ROOT_PATH + path }
11
- let(:status) { 200 }
12
- let(:error_code) { 0 }
13
- let(:body) { { errors: { code: error_code } }.to_json }
14
-
15
- before { stub_request(method, api_path).to_return(status: status, body: body) }
16
-
17
- context "when returning a request error" do
18
- let(:status) { 404 }
19
- let(:error_class) { Passfort::Errors::RequestError }
20
-
21
- it { is_expected.to raise_error(error_class) }
22
- end
23
-
24
- context "when returning an invalid API Key error" do
25
- let(:error_code) { 204 }
26
- let(:error_class) { Passfort::Errors::InvalidAPIKeyError }
27
-
28
- it { is_expected.to raise_error(error_class) }
29
- end
30
-
31
- context "when returning an invalid input data error" do
32
- let(:error_code) { 201 }
33
- let(:error_class) { Passfort::Errors::InvalidInputDataError }
34
-
35
- it { is_expected.to raise_error(error_class) }
36
- end
37
-
38
- context "when returning a chargeable limit reached error" do
39
- let(:error_code) { 104 }
40
- let(:error_class) { Passfort::Errors::ChargeableLimitReachedError }
41
-
42
- it { is_expected.to raise_error(error_class) }
43
- end
44
-
45
- context "when returning an unknown API error" do
46
- let(:error_code) { 203 }
47
- let(:error_class) { Passfort::Errors::UnknownApiError }
48
-
49
- it { is_expected.to raise_error(error_class) }
50
- end
51
-
52
- context "when returning a response that can't be parsed as JSON" do
53
- let(:body) { "<html><body><h1>something that isn't json</h1></body></html>" }
54
- let(:error_class) { Passfort::Errors::UnparseableResponseError }
55
-
56
- it { is_expected.to raise_error(error_class) }
57
- end
58
-
59
- context "when returning a successful result" do
60
- let(:result) { subject.call }
61
-
62
- before do
63
- stub_request(method, api_path).
64
- to_return(status: status, body: load_fixture("check.json"))
65
- end
66
-
67
- it "includes the id response" do
68
- expect(result).to include("id" => "6c1d594a-496e-11e7-911e-acbc32b67d7b")
69
- end
70
- end
71
-
72
- context "when the request times out" do
73
- before { stub_request(method, api_path).to_raise(Excon::Errors::Timeout) }
74
- let(:error_class) { Passfort::Errors::TimeoutError }
75
-
76
- it { is_expected.to raise_error(error_class) }
77
- end
78
- end
79
-
80
- describe "#get" do
81
- subject { -> { http.get(path) } }
82
-
83
- let(:method) { :get }
84
-
85
- it_behaves_like "an API call that handles all errors"
86
- end
87
-
88
- describe "#post" do
89
- subject { -> { http.post(path, body: {}) } }
90
-
91
- let(:method) { :post }
92
-
93
- it_behaves_like "an API call that handles all errors"
94
- end
95
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "timecop"
5
+
6
+ RSpec.describe Passfort::Http do
7
+ let(:http) { described_class.new("api_key") }
8
+ let(:path) { "a/path" }
9
+
10
+ shared_examples "an API call that handles all errors" do
11
+ let(:api_path) { Passfort::Http::DOMAIN + Passfort::Http::ROOT_PATH + path }
12
+ let(:status) { 200 }
13
+ let(:error_code) { 0 }
14
+ let(:body) { { errors: { code: error_code } }.to_json }
15
+
16
+ before { stub_request(method, api_path).to_return(status: status, body: body) }
17
+
18
+ context "when returning a request error" do
19
+ let(:status) { 404 }
20
+ let(:error_class) { Passfort::Errors::RequestError }
21
+
22
+ it { is_expected.to raise_error(error_class) }
23
+ end
24
+
25
+ context "when returning an invalid API Key error" do
26
+ let(:error_code) { 204 }
27
+ let(:error_class) { Passfort::Errors::InvalidAPIKeyError }
28
+
29
+ it { is_expected.to raise_error(error_class) }
30
+ end
31
+
32
+ context "when returning an invalid input data error" do
33
+ let(:error_code) { 201 }
34
+ let(:error_class) { Passfort::Errors::InvalidInputDataError }
35
+
36
+ it { is_expected.to raise_error(error_class) }
37
+ end
38
+
39
+ context "when returning a chargeable limit reached error" do
40
+ let(:error_code) { 104 }
41
+ let(:error_class) { Passfort::Errors::ChargeableLimitReachedError }
42
+
43
+ it { is_expected.to raise_error(error_class) }
44
+ end
45
+
46
+ context "when returning an unknown API error" do
47
+ let(:error_code) { 203 }
48
+ let(:error_class) { Passfort::Errors::UnknownApiError }
49
+
50
+ it { is_expected.to raise_error(error_class) }
51
+ end
52
+
53
+ context "when returning a response that can't be parsed as JSON" do
54
+ let(:body) { "<html><body><h1>something that isn't json</h1></body></html>" }
55
+ let(:error_class) { Passfort::Errors::UnparseableResponseError }
56
+
57
+ it { is_expected.to raise_error(error_class) }
58
+ end
59
+
60
+ context "when returning a successful result" do
61
+ let(:result) { subject.call }
62
+
63
+ before do
64
+ stub_request(method, api_path).
65
+ to_return(status: status, body: load_fixture("check.json"))
66
+ end
67
+
68
+ it "includes the id response" do
69
+ expect(result).to include("id" => "6c1d594a-496e-11e7-911e-acbc32b67d7b")
70
+ end
71
+ end
72
+
73
+ context "when the request times out" do
74
+ before { stub_request(method, api_path).to_raise(Excon::Errors::Timeout) }
75
+ let(:error_class) { Passfort::Errors::TimeoutError }
76
+
77
+ it { is_expected.to raise_error(error_class) }
78
+ end
79
+ end
80
+
81
+ shared_examples_for "an API call that sends notifications" do
82
+ let(:api_path) { Passfort::Http::DOMAIN + Passfort::Http::ROOT_PATH + path }
83
+ let(:notifications) { [] }
84
+ let(:time) { Time.local(1990) }
85
+ let(:payload) { { path: path, response: be_truthy } }
86
+ let(:expected_notification) do
87
+ have_attributes(
88
+ name: "passfort.#{method}",
89
+ transaction_id: match(/\A.{20}\Z/),
90
+ time: time,
91
+ end: time,
92
+ payload: payload,
93
+ )
94
+ end
95
+ let(:result) { subject.call }
96
+
97
+ before do
98
+ ActiveSupport::Notifications.subscribe do |*args|
99
+ notifications << ActiveSupport::Notifications::Event.new(*args)
100
+ end
101
+ stub_request(method, api_path).to_return(body: {}.to_json)
102
+ payload[:body] = be_truthy if method == :post
103
+ end
104
+
105
+ it "records a notification" do
106
+ Timecop.freeze(time) do
107
+ result
108
+ end
109
+ expect(notifications).to match([expected_notification])
110
+ end
111
+ end
112
+
113
+ describe "#get" do
114
+ subject { -> { http.get(path) } }
115
+
116
+ let(:method) { :get }
117
+
118
+ it_behaves_like "an API call that handles all errors"
119
+ it_behaves_like "an API call that sends notifications"
120
+ end
121
+
122
+ describe "#post" do
123
+ subject { -> { http.post(path, body: {}) } }
124
+
125
+ let(:method) { :post }
126
+
127
+ it_behaves_like "an API call that handles all errors"
128
+ it_behaves_like "an API call that sends notifications"
129
+ end
130
+ end
@@ -1,9 +1,9 @@
1
- # frozen_string_literal: true
2
-
3
- require "passfort"
4
- require "pry"
5
- require "webmock/rspec"
6
-
7
- def load_fixture(path)
8
- File.read(File.join(__dir__, "fixtures", path))
9
- end
1
+ # frozen_string_literal: true
2
+
3
+ require "passfort"
4
+ require "pry"
5
+ require "webmock/rspec"
6
+
7
+ def load_fixture(path)
8
+ File.read(File.join(__dir__, "fixtures", path))
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passfort
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GoCardless
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-29 00:00:00.000000000 Z
11
+ date: 2018-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.8'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.8'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: webmock
99
113
  requirement: !ruby/object:Gem::Requirement