defra_ruby_mocks 1.4.1 → 2.2.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.
- checksums.yaml +4 -4
- data/README.md +59 -6
- data/app/controllers/defra_ruby_mocks/company_controller.rb +8 -1
- data/app/controllers/defra_ruby_mocks/worldpay_controller.rb +8 -3
- data/app/services/defra_ruby_mocks/base_service.rb +8 -2
- data/app/services/defra_ruby_mocks/companies_house_service.rb +12 -2
- data/app/services/defra_ruby_mocks/worldpay_response_service.rb +33 -8
- data/app/views/defra_ruby_mocks/company/officers.json.erb +26 -0
- data/app/views/defra_ruby_mocks/company/show.json.erb +10 -1
- data/config/routes.rb +5 -0
- data/lib/defra_ruby_mocks/version.rb +1 -1
- data/spec/dummy/log/test.log +2258 -727
- data/spec/examples.txt +110 -79
- data/spec/requests/company_spec.rb +17 -6
- data/spec/requests/officers_spec.rb +37 -0
- data/spec/requests/worldpay_spec.rb +30 -9
- data/spec/services/companies_house_service_spec.rb +28 -6
- data/spec/services/worldpay_response_service_spec.rb +137 -20
- data/spec/spec_helper.rb +3 -0
- metadata +26 -11
- data/spec/dummy/log/development.log +0 -180
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc69209c2d4b90b3726d7486bb0f4f0f001d80aff649951f4e8eaa5e17e46cec
|
4
|
+
data.tar.gz: 2f8ca2c6731b2d0eae695e7aeae936c20288480bf758c4f16fcdcf3a27f70067
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed7a96c4eb66607adbe341b441181b339b60e28cf1d66e92e1eb6467606d82676110efc587d921a309fec419c472095a82c7b1b1bb8ebbff64740182c38723f4
|
7
|
+
data.tar.gz: f9b8847f14ac049e9b1cef302cfbe8893c6b56797e5f48e6b6548f939c16f923111c2f79be4023ab8c1c5a62aa91db10eebfc73b797de9feb7326798a65af215
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Defra Ruby Mocks
|
2
2
|
|
3
|
-
|
3
|
+

|
4
4
|
[](https://sonarcloud.io/dashboard?id=DEFRA_defra-ruby-mocks)
|
5
5
|
[](https://sonarcloud.io/dashboard?id=DEFRA_defra-ruby-mocks)
|
6
|
-
[](https://hakiri.io/github/DEFRA/defra-ruby-mocks/main)
|
7
7
|
[](http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3)
|
8
8
|
|
9
9
|
A Rails Engine used by the [Ruby services team](https://github.com/DEFRA/ruby-services-team) in their digital services.
|
@@ -21,7 +21,7 @@ Things to note
|
|
21
21
|
|
22
22
|
Make sure you already have:
|
23
23
|
|
24
|
-
- Ruby 2.
|
24
|
+
- Ruby 2.7.1
|
25
25
|
- [Bundler](http://bundler.io/) – for installing Ruby gems
|
26
26
|
|
27
27
|
## Mounting the engine
|
@@ -71,14 +71,38 @@ The project currently mocks the following services.
|
|
71
71
|
|
72
72
|
When mounted into an app you can make requests to `/mocks/company/[company number]` to get a response that matches what our apps expect.
|
73
73
|
|
74
|
-
This is an important distinction to note. When our apps like the [Waste Exemptions front office](https://github.com/DEFRA/waste-exemptions-front-office) make a real request to Companies House, they get a lot more information back in the JSON reponse. However the only
|
74
|
+
This is an important distinction to note. When our apps like the [Waste Exemptions front office](https://github.com/DEFRA/waste-exemptions-front-office) make a real request to Companies House, they get a lot more information back in the JSON reponse. However the only things they are interested in are the value of `"company_name"`, `"company_status"`, `"company_type"` and `"registered_office"`, .
|
75
75
|
|
76
|
-
So rather than maintain a lot of unused JSON data, the mock just returns
|
76
|
+
So rather than maintain a lot of unused JSON data, the mock just returns those bits of the JSON.
|
77
77
|
|
78
78
|
```bash
|
79
79
|
curl http://localhost:3000/mocks/company/SC123456
|
80
80
|
{
|
81
|
-
"
|
81
|
+
"company_name": "Acme Industries",
|
82
|
+
"company_status": "active",
|
83
|
+
"company_type": "ltd",
|
84
|
+
"registered_office_address": {
|
85
|
+
"address_line_1": "10 Downing St",
|
86
|
+
"address_line_2": "Horizon House",
|
87
|
+
"locality": "Bristol",
|
88
|
+
"postal_code": "BS1 5AH"
|
89
|
+
}
|
90
|
+
}
|
91
|
+
```
|
92
|
+
|
93
|
+
Additionally, an Officers endpoint is available at `/mocks/company/[company number]/officers`. This returns a list of partial Officer data, eg:
|
94
|
+
```bash
|
95
|
+
curl http://localhost:3000/mocks/company/SC123456/officers
|
96
|
+
{
|
97
|
+
"items": [
|
98
|
+
{
|
99
|
+
"name": "APPLE, Alice",
|
100
|
+
"officer_role": "director"
|
101
|
+
},
|
102
|
+
{
|
103
|
+
"name": "BANANA, Bob",
|
104
|
+
"officer_role": "director"
|
105
|
+
},...
|
82
106
|
}
|
83
107
|
```
|
84
108
|
|
@@ -99,6 +123,11 @@ The exceptions to this are the 'special' numbers listed below. Use them if you a
|
|
99
123
|
- `33333333` will return `"open"`
|
100
124
|
- `22222222` will return `"closed"`
|
101
125
|
|
126
|
+
Additionally, an `"active"` LLP company can be retrieved by using the following registration numbers:
|
127
|
+
|
128
|
+
- `XX999999`
|
129
|
+
- `YY999999`
|
130
|
+
|
102
131
|
The list of possible statuses was taken from
|
103
132
|
|
104
133
|
- [Companies House API](https://developer.companieshouse.gov.uk/api/docs/company/company_number/companyProfile-resource.html)
|
@@ -122,6 +151,30 @@ This Worldpay mock replicates those 2 interactions with the following urls
|
|
122
151
|
- `../worldpay/payments-service`
|
123
152
|
- `../worldpay/dispatcher`
|
124
153
|
|
154
|
+
##### Cancelled payments
|
155
|
+
|
156
|
+
The engine has the ability to mock a user cancelling a payment when on the Worldpay site. To have the mock return a cancelled payment response just ensure the registration's company name includes the word `cancel` (case doesn't matter).
|
157
|
+
|
158
|
+
If it does the engine will redirect back to the cancelled url instead of the success url provided, plus set the payment status to `CANCELLED`.
|
159
|
+
|
160
|
+
This allows us to test how the application handles Worldpay responding with a cancelled payment response.
|
161
|
+
|
162
|
+
##### Errored payments
|
163
|
+
|
164
|
+
The engine has the ability to Worldpay erroring during a payment. To have the mock return an errored payment response just ensure the registration's company name includes the word `error` (case doesn't matter).
|
165
|
+
|
166
|
+
If it does the engine will redirect back to the error url instead of the success url provided, plus set the payment status to `ERROR`.
|
167
|
+
|
168
|
+
This allows us to test how the application handles Worldpay responding with an errored payment response.
|
169
|
+
|
170
|
+
##### Pending payments
|
171
|
+
|
172
|
+
The engine has the ability to also mock Worldpay marking a payment as pending. To have the mock return a payment pending response just ensure the registration's company name includes the word `pending` (case doesn't matter).
|
173
|
+
|
174
|
+
If it does the engine will redirect back to the pending url instead of the success url provided, plus set the payment status to `SENT_FOR_AUTHORISATION`.
|
175
|
+
|
176
|
+
This allows us to test how the application handles Worldpay responding with a payment pending response.
|
177
|
+
|
125
178
|
##### Refused payments
|
126
179
|
|
127
180
|
The engine has the ability to also mock Worldpay refusing a payment. To have the mock refuse payment just ensure the registration's company name includes the word `reject` (case doesn't matter).
|
@@ -6,13 +6,20 @@ module DefraRubyMocks
|
|
6
6
|
before_action :set_default_response_format
|
7
7
|
|
8
8
|
def show
|
9
|
-
|
9
|
+
service = CompaniesHouseService.run(params[:id])
|
10
|
+
|
11
|
+
@company_status = service.company_status
|
12
|
+
@company_type = service.company_type
|
10
13
|
|
11
14
|
respond_to :json
|
12
15
|
rescue NotFoundError
|
13
16
|
render "not_found", status: 404
|
14
17
|
end
|
15
18
|
|
19
|
+
def officers
|
20
|
+
respond_to :json
|
21
|
+
end
|
22
|
+
|
16
23
|
private
|
17
24
|
|
18
25
|
def set_default_response_format
|
@@ -10,14 +10,18 @@ module DefraRubyMocks
|
|
10
10
|
|
11
11
|
render_payment_response if @values[:request_type] == :payment
|
12
12
|
render_refund_response if @values[:request_type] == :refund
|
13
|
-
rescue StandardError
|
13
|
+
rescue StandardError => e
|
14
|
+
Rails.logger.error("MOCKS: Worldpay payments service error: #{e.message}")
|
14
15
|
head 500
|
15
16
|
end
|
16
17
|
|
17
18
|
def dispatcher
|
18
19
|
@response = WorldpayResponseService.run(
|
19
20
|
success_url: params[:successURL],
|
20
|
-
failure_url: params[:failureURL]
|
21
|
+
failure_url: params[:failureURL],
|
22
|
+
pending_url: params[:pendingURL],
|
23
|
+
cancel_url: params[:cancelURL],
|
24
|
+
error_url: params[:errorURL]
|
21
25
|
)
|
22
26
|
|
23
27
|
if @response.status == :STUCK
|
@@ -25,7 +29,8 @@ module DefraRubyMocks
|
|
25
29
|
else
|
26
30
|
redirect_to @response.url
|
27
31
|
end
|
28
|
-
rescue StandardError
|
32
|
+
rescue StandardError => e
|
33
|
+
Rails.logger.error("MOCKS: Worldpay dispatcher error: #{e.message}")
|
29
34
|
head 500
|
30
35
|
end
|
31
36
|
|
@@ -2,8 +2,14 @@
|
|
2
2
|
|
3
3
|
module DefraRubyMocks
|
4
4
|
class BaseService
|
5
|
-
def self.run(
|
6
|
-
|
5
|
+
def self.run(options = nil)
|
6
|
+
if options && !options.is_a?(Hash)
|
7
|
+
new.run(options)
|
8
|
+
elsif options
|
9
|
+
new.run(**options)
|
10
|
+
else
|
11
|
+
new.run
|
12
|
+
end
|
7
13
|
end
|
8
14
|
end
|
9
15
|
end
|
@@ -31,15 +31,22 @@ module DefraRubyMocks
|
|
31
31
|
}
|
32
32
|
end
|
33
33
|
|
34
|
+
def self.llp_company_numbers
|
35
|
+
%w[XX999999 YY999999]
|
36
|
+
end
|
37
|
+
|
34
38
|
def run(company_number)
|
35
39
|
raise NotFoundError unless valid_company_number?(company_number)
|
36
40
|
raise NotFoundError if company_number == NOT_FOUND
|
37
41
|
|
38
|
-
|
42
|
+
@company_status = specials[company_number] || "active"
|
43
|
+
@company_type = llps.include?(company_number) ? "llp" : "ltd"
|
39
44
|
|
40
|
-
|
45
|
+
self
|
41
46
|
end
|
42
47
|
|
48
|
+
attr_reader :company_status, :company_type
|
49
|
+
|
43
50
|
private
|
44
51
|
|
45
52
|
def valid_company_number?(company_number)
|
@@ -50,5 +57,8 @@ module DefraRubyMocks
|
|
50
57
|
self.class.special_company_numbers
|
51
58
|
end
|
52
59
|
|
60
|
+
def llps
|
61
|
+
self.class.llp_company_numbers
|
62
|
+
end
|
53
63
|
end
|
54
64
|
end
|
@@ -3,11 +3,19 @@
|
|
3
3
|
module DefraRubyMocks
|
4
4
|
class WorldpayResponseService < BaseService
|
5
5
|
|
6
|
-
def run(success_url:, failure_url:)
|
7
|
-
|
6
|
+
def run(success_url:, failure_url:, pending_url:, cancel_url:, error_url:)
|
7
|
+
urls = {
|
8
|
+
success: success_url,
|
9
|
+
failure: failure_url,
|
10
|
+
pending: pending_url,
|
11
|
+
cancel: cancel_url,
|
12
|
+
error: error_url
|
13
|
+
}
|
14
|
+
|
15
|
+
parse_reference(urls[:success])
|
8
16
|
@resource = WorldpayResourceService.run(reference: @reference)
|
9
17
|
|
10
|
-
generate_response(
|
18
|
+
generate_response(urls)
|
11
19
|
end
|
12
20
|
|
13
21
|
private
|
@@ -59,27 +67,44 @@ module DefraRubyMocks
|
|
59
67
|
def payment_status
|
60
68
|
return :REFUSED if @resource.company_name.include?("reject")
|
61
69
|
return :STUCK if @resource.company_name.include?("stuck")
|
70
|
+
return :SENT_FOR_AUTHORISATION if @resource.company_name.include?("pending")
|
71
|
+
return :CANCELLED if @resource.company_name.include?("cancel")
|
72
|
+
return :ERROR if @resource.company_name.include?("error")
|
62
73
|
|
63
74
|
:AUTHORISED
|
64
75
|
end
|
65
76
|
|
77
|
+
def url(payment_status, urls)
|
78
|
+
return urls[:failure] if %i[REFUSED STUCK].include?(payment_status)
|
79
|
+
return urls[:pending] if payment_status == :SENT_FOR_AUTHORISATION
|
80
|
+
return urls[:cancel] if payment_status == :CANCELLED
|
81
|
+
return urls[:error] if payment_status == :ERROR
|
82
|
+
|
83
|
+
urls[:success]
|
84
|
+
end
|
85
|
+
|
86
|
+
# Generate a mac that matches what Worldpay would generate
|
87
|
+
#
|
88
|
+
# For whatever reason, if the payment is cancelled by the user Worldpay does
|
89
|
+
# not include the payment status in the mac it generates. Plus the order of
|
90
|
+
# things in the array is important.
|
66
91
|
def generate_mac(status)
|
67
92
|
data = [
|
68
93
|
order_key,
|
69
94
|
order_value,
|
70
|
-
"GBP"
|
71
|
-
status,
|
72
|
-
DefraRubyMocks.configuration.worldpay_mac_secret
|
95
|
+
"GBP"
|
73
96
|
]
|
97
|
+
data << status unless status == :CANCELLED
|
98
|
+
data << DefraRubyMocks.configuration.worldpay_mac_secret
|
74
99
|
|
75
100
|
Digest::MD5.hexdigest(data.join).to_s
|
76
101
|
end
|
77
102
|
|
78
|
-
def generate_response(
|
103
|
+
def generate_response(urls)
|
79
104
|
status = payment_status
|
80
105
|
|
81
106
|
WorldpayResponse.new(
|
82
|
-
status
|
107
|
+
url(status, urls),
|
83
108
|
@url_format == :new ? "?" : "&",
|
84
109
|
order_key,
|
85
110
|
generate_mac(status),
|
@@ -0,0 +1,26 @@
|
|
1
|
+
// https://developer-specs.company-information.service.gov.uk/companies-house-public-data-api/resources/officerlist
|
2
|
+
{
|
3
|
+
"items": [
|
4
|
+
{
|
5
|
+
"name": "APPLE, Alice",
|
6
|
+
"officer_role": "director"
|
7
|
+
},
|
8
|
+
{
|
9
|
+
"name": "BANANA, Bob",
|
10
|
+
"officer_role": "director"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"name": "CARROT, Charlie",
|
14
|
+
"officer_role": "director",
|
15
|
+
"resigned_on": "2020-01-21"
|
16
|
+
},
|
17
|
+
{
|
18
|
+
"name": "DONUT, Dave Dickie",
|
19
|
+
"officer_role": "llp-member"
|
20
|
+
},
|
21
|
+
{
|
22
|
+
"name": "ENDIVE, Eve Marie",
|
23
|
+
"officer_role": "llp-designated-member"
|
24
|
+
}
|
25
|
+
]
|
26
|
+
}
|
@@ -1,3 +1,12 @@
|
|
1
|
+
// https://developer-specs.company-information.service.gov.uk/companies-house-public-data-api/resources/companyprofile
|
1
2
|
{
|
2
|
-
"
|
3
|
+
"company_name": "Acme Industries",
|
4
|
+
"company_status": "<%= @company_status %>",
|
5
|
+
"type": "<%= @company_type %>",
|
6
|
+
"registered_office_address": {
|
7
|
+
"address_line_1": "10 Downing St",
|
8
|
+
"address_line_2": "Horizon House",
|
9
|
+
"locality": "Bristol",
|
10
|
+
"postal_code": "BS1 5AH"
|
11
|
+
}
|
3
12
|
}
|
data/config/routes.rb
CHANGED
@@ -6,6 +6,11 @@ DefraRubyMocks::Engine.routes.draw do
|
|
6
6
|
as: "company",
|
7
7
|
constraints: ->(_request) { DefraRubyMocks.configuration.enabled? }
|
8
8
|
|
9
|
+
get "/company/:id/officers",
|
10
|
+
to: "company#officers",
|
11
|
+
as: "company_officers",
|
12
|
+
constraints: ->(_request) { DefraRubyMocks.configuration.enabled? }
|
13
|
+
|
9
14
|
get "/worldpay/payments-service",
|
10
15
|
to: "worldpay#payments_service",
|
11
16
|
as: "worldpay_payments_service",
|