defra_ruby_mocks 2.0.0 → 2.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.
data/spec/examples.txt ADDED
@@ -0,0 +1,114 @@
1
+ example_id | status | run_time |
2
+ ------------------------------------------------------------------- | ------ | --------------- |
3
+ ./spec/defra_ruby_mocks_spec.rb[1:1:1] | passed | 0.00215 seconds |
4
+ ./spec/defra_ruby_mocks_spec.rb[1:2:1:1] | passed | 0.00018 seconds |
5
+ ./spec/defra_ruby_mocks_spec.rb[1:2:2:1] | passed | 0.00014 seconds |
6
+ ./spec/lib/configuration_spec.rb[1:1:1:1] | passed | 0.00011 seconds |
7
+ ./spec/lib/configuration_spec.rb[1:1:2:1] | passed | 0.00019 seconds |
8
+ ./spec/lib/configuration_spec.rb[1:1:3:1] | passed | 0.00017 seconds |
9
+ ./spec/lib/configuration_spec.rb[1:1:4:1] | passed | 0.00012 seconds |
10
+ ./spec/lib/configuration_spec.rb[1:2:1:1] | passed | 0.00018 seconds |
11
+ ./spec/lib/configuration_spec.rb[1:2:2:1] | passed | 0.00011 seconds |
12
+ ./spec/lib/configuration_spec.rb[1:2:3:1] | passed | 0.00016 seconds |
13
+ ./spec/lib/configuration_spec.rb[1:2:4:1] | passed | 0.00095 seconds |
14
+ ./spec/requests/company_spec.rb[1:1:1:1] | passed | 0.0082 seconds |
15
+ ./spec/requests/company_spec.rb[1:1:2:1] | passed | 0.00528 seconds |
16
+ ./spec/requests/company_spec.rb[1:1:3:1:1] | passed | 0.0048 seconds |
17
+ ./spec/requests/company_spec.rb[1:1:3:2:1] | passed | 0.00472 seconds |
18
+ ./spec/requests/company_spec.rb[1:2:1] | passed | 0.00226 seconds |
19
+ ./spec/requests/officers_spec.rb[1:1:1] | passed | 0.00903 seconds |
20
+ ./spec/requests/officers_spec.rb[1:2:1] | passed | 0.00429 seconds |
21
+ ./spec/requests/worldpay_spec.rb[1:1:1:1:1:1] | passed | 0.00703 seconds |
22
+ ./spec/requests/worldpay_spec.rb[1:1:1:1:2:1] | passed | 0.00379 seconds |
23
+ ./spec/requests/worldpay_spec.rb[1:1:1:2:1:1] | passed | 0.03276 seconds |
24
+ ./spec/requests/worldpay_spec.rb[1:1:2:1:1:1] | passed | 0.00538 seconds |
25
+ ./spec/requests/worldpay_spec.rb[1:1:2:1:2:1] | passed | 0.0063 seconds |
26
+ ./spec/requests/worldpay_spec.rb[1:1:2:2:1:1] | passed | 0.00462 seconds |
27
+ ./spec/requests/worldpay_spec.rb[1:2:1:1] | passed | 0.01268 seconds |
28
+ ./spec/requests/worldpay_spec.rb[1:2:2:1] | passed | 0.0063 seconds |
29
+ ./spec/services/companies_house_service_spec.rb[1:1:1:1] | passed | 0.00181 seconds |
30
+ ./spec/services/companies_house_service_spec.rb[1:1:2:1:1] | passed | 0.0002 seconds |
31
+ ./spec/services/companies_house_service_spec.rb[1:1:2:1:2] | passed | 0.0001 seconds |
32
+ ./spec/services/companies_house_service_spec.rb[1:1:2:2:1] | passed | 0.00009 seconds |
33
+ ./spec/services/companies_house_service_spec.rb[1:1:2:2:2] | passed | 0.00009 seconds |
34
+ ./spec/services/companies_house_service_spec.rb[1:1:2:3:1] | passed | 0.0001 seconds |
35
+ ./spec/services/companies_house_service_spec.rb[1:1:2:3:2] | passed | 0.00009 seconds |
36
+ ./spec/services/companies_house_service_spec.rb[1:1:2:4:1] | passed | 0.00014 seconds |
37
+ ./spec/services/companies_house_service_spec.rb[1:1:2:4:2] | passed | 0.00009 seconds |
38
+ ./spec/services/companies_house_service_spec.rb[1:1:2:5:1] | passed | 0.00009 seconds |
39
+ ./spec/services/companies_house_service_spec.rb[1:1:2:5:2] | passed | 0.00012 seconds |
40
+ ./spec/services/companies_house_service_spec.rb[1:1:2:6:1] | passed | 0.00009 seconds |
41
+ ./spec/services/companies_house_service_spec.rb[1:1:2:6:2] | passed | 0.00014 seconds |
42
+ ./spec/services/companies_house_service_spec.rb[1:1:2:7:1] | passed | 0.00009 seconds |
43
+ ./spec/services/companies_house_service_spec.rb[1:1:2:7:2] | passed | 0.0001 seconds |
44
+ ./spec/services/companies_house_service_spec.rb[1:1:2:8:1] | passed | 0.0001 seconds |
45
+ ./spec/services/companies_house_service_spec.rb[1:1:2:8:2] | passed | 0.00009 seconds |
46
+ ./spec/services/companies_house_service_spec.rb[1:1:2:9:1] | passed | 0.00012 seconds |
47
+ ./spec/services/companies_house_service_spec.rb[1:1:2:9:2] | passed | 0.00017 seconds |
48
+ ./spec/services/companies_house_service_spec.rb[1:1:3:1] | passed | 0.1475 seconds |
49
+ ./spec/services/companies_house_service_spec.rb[1:1:3:2] | passed | 0.00015 seconds |
50
+ ./spec/services/companies_house_service_spec.rb[1:1:3:3] | passed | 0.00014 seconds |
51
+ ./spec/services/companies_house_service_spec.rb[1:1:3:4] | passed | 0.00009 seconds |
52
+ ./spec/services/companies_house_service_spec.rb[1:1:4:1:1] | passed | 0.00017 seconds |
53
+ ./spec/services/companies_house_service_spec.rb[1:1:4:2:1] | passed | 0.00015 seconds |
54
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:1:1] | passed | 0.00017 seconds |
55
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:1] | passed | 0.00108 seconds |
56
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:2] | passed | 0.00032 seconds |
57
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:3] | passed | 0.00032 seconds |
58
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:4] | passed | 0.00038 seconds |
59
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:5:1] | passed | 0.00038 seconds |
60
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:5:2] | passed | 0.00035 seconds |
61
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:5:3] | passed | 0.00044 seconds |
62
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:2:1:6:1] | passed | 0.00031 seconds |
63
+ ./spec/services/worldpay_payment_service_spec.rb[1:1:3:1] | passed | 0.00042 seconds |
64
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:1:1:1] | passed | 0.00033 seconds |
65
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:1:1:2] | passed | 0.00042 seconds |
66
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:1:1:3] | passed | 0.00041 seconds |
67
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:1:1:4] | passed | 0.0006 seconds |
68
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:1:1:5] | passed | 0.00052 seconds |
69
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:1:1:6] | passed | 0.00038 seconds |
70
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:1:1:7] | passed | 0.0004 seconds |
71
+ ./spec/services/worldpay_refund_service_spec.rb[1:1:2:1] | passed | 0.00045 seconds |
72
+ ./spec/services/worldpay_request_handler_service_spec.rb[1:1:1:1:1] | passed | 0.00111 seconds |
73
+ ./spec/services/worldpay_request_handler_service_spec.rb[1:1:1:1:2] | passed | 0.00087 seconds |
74
+ ./spec/services/worldpay_request_handler_service_spec.rb[1:1:1:2:1] | passed | 0.00057 seconds |
75
+ ./spec/services/worldpay_request_handler_service_spec.rb[1:1:1:2:2] | passed | 0.00058 seconds |
76
+ ./spec/services/worldpay_request_handler_service_spec.rb[1:1:1:3:1] | passed | 0.00036 seconds |
77
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:1:1] | passed | 0.00218 seconds |
78
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:1:2] | passed | 0.00074 seconds |
79
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:1:3] | passed | 0.00864 seconds |
80
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:1:4] | passed | 0.00076 seconds |
81
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:2:1] | passed | 0.00095 seconds |
82
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:2:2] | passed | 0.0008 seconds |
83
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:2:3] | passed | 0.001 seconds |
84
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:2:4] | passed | 0.0007 seconds |
85
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:3:1] | passed | 0.00136 seconds |
86
+ ./spec/services/worldpay_resource_service_spec.rb[1:1:4:1] | passed | 0.00066 seconds |
87
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:1] | passed | 0.00063 seconds |
88
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:2] | passed | 0.00064 seconds |
89
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:3:1] | passed | 0.00072 seconds |
90
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:3:2] | passed | 0.00069 seconds |
91
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:4:1] | passed | 0.0006 seconds |
92
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:4:2] | passed | 0.00066 seconds |
93
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:5:1] | passed | 0.00074 seconds |
94
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:5:2] | passed | 0.0006 seconds |
95
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:6:1] | passed | 0.00136 seconds |
96
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:6:2] | passed | 0.00105 seconds |
97
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:7:1] | passed | 0.00063 seconds |
98
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:7:2] | passed | 0.00067 seconds |
99
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:8:1] | passed | 0.00066 seconds |
100
+ ./spec/services/worldpay_response_service_spec.rb[1:1:1:1:8:2] | passed | 0.00069 seconds |
101
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:1] | passed | 0.0007 seconds |
102
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:2] | passed | 0.00087 seconds |
103
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:3:1] | passed | 0.00795 seconds |
104
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:3:2] | passed | 0.00075 seconds |
105
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:4:1] | passed | 0.00078 seconds |
106
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:4:2] | passed | 0.00076 seconds |
107
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:5:1] | passed | 0.00093 seconds |
108
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:5:2] | passed | 0.00095 seconds |
109
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:6:1] | passed | 0.00073 seconds |
110
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:6:2] | passed | 0.00084 seconds |
111
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:7:1] | passed | 0.00063 seconds |
112
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:7:2] | passed | 0.0007 seconds |
113
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:8:1] | passed | 0.00104 seconds |
114
+ ./spec/services/worldpay_response_service_spec.rb[1:1:2:1:8:2] | passed | 0.00113 seconds |
@@ -29,11 +29,20 @@ module DefraRubyMocks
29
29
 
30
30
  it "returns a JSON response with a 200 code and a status that isn't 'active'" do
31
31
  get "#{path}/#{company_number}"
32
- company_status = JSON.parse(response.body)["company_status"]
33
32
 
34
33
  expect(response.media_type).to eq("application/json")
35
34
  expect(response.code).to eq("200")
36
- expect(company_status).not_to eq("active")
35
+ expect(JSON.parse(response.body).deep_symbolize_keys).to eq(
36
+ company_name: "Acme Industries",
37
+ company_status: "dissolved",
38
+ type: "ltd",
39
+ registered_office_address: {
40
+ address_line_1: "10 Downing St",
41
+ address_line_2: "Horizon House",
42
+ locality: "Bristol",
43
+ postal_code: "BS1 5AH"
44
+ }
45
+ )
37
46
  end
38
47
  end
39
48
 
@@ -44,10 +53,12 @@ module DefraRubyMocks
44
53
  it "returns a JSON response with a 200 code and a status of 'active'" do
45
54
  get "#{path}/#{company_number}"
46
55
  company_status = JSON.parse(response.body)["company_status"]
56
+ company_type = JSON.parse(response.body)["type"]
47
57
 
48
58
  expect(response.media_type).to eq("application/json")
49
59
  expect(response.code).to eq("200")
50
60
  expect(company_status).to eq("active")
61
+ expect(company_type).to eq("ltd")
51
62
  end
52
63
  end
53
64
 
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ module DefraRubyMocks
6
+ RSpec.describe "Officers", type: :request do
7
+ after(:all) { Helpers::Configuration.reset_for_tests }
8
+
9
+ let(:path) { "/defra_ruby_mocks/company/company-no/officers" }
10
+
11
+ context "when mocks are enabled" do
12
+ before(:each) { Helpers::Configuration.prep_for_tests }
13
+
14
+ it "returns a JSON response" do
15
+ get path
16
+
17
+ expect(response.media_type).to eq("application/json")
18
+ expect(response.code).to eq("200")
19
+
20
+ expect(JSON.parse(response.body).deep_symbolize_keys[:items][0]).to eq(
21
+ {
22
+ name: "APPLE, Alice",
23
+ officer_role: "director"
24
+ }
25
+ )
26
+ end
27
+ end
28
+
29
+ context "when mocks are disabled" do
30
+ before(:all) { DefraRubyMocks.configuration.enable = false }
31
+
32
+ it "cannot load the page" do
33
+ expect { get path }.to raise_error(ActionController::RoutingError)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -24,7 +24,7 @@ module DefraRubyMocks
24
24
  let(:data) { File.read("spec/fixtures/payment_request_valid.xml") }
25
25
 
26
26
  it "returns an XML response with a 200 code" do
27
- get path, headers: { "RAW_POST_DATA" => data }
27
+ post path, headers: { "RAW_POST_DATA" => data }
28
28
 
29
29
  expect(response.media_type).to eq("application/xml")
30
30
  expect(response.code).to eq("200")
@@ -36,7 +36,7 @@ module DefraRubyMocks
36
36
  let(:data) { File.read("spec/fixtures/payment_request_invalid.xml") }
37
37
 
38
38
  it "returns a response with a 500 code" do
39
- get path, headers: { "RAW_POST_DATA" => data }
39
+ post path, headers: { "RAW_POST_DATA" => data }
40
40
 
41
41
  expect(response.code).to eq("500")
42
42
  end
@@ -48,7 +48,7 @@ module DefraRubyMocks
48
48
  let(:data) { File.read("spec/fixtures/refund_request_valid.xml") }
49
49
 
50
50
  it "returns an XML response with a 200 code" do
51
- get path, headers: { "RAW_POST_DATA" => data }
51
+ post path, headers: { "RAW_POST_DATA" => data }
52
52
 
53
53
  expect(response.media_type).to eq("application/xml")
54
54
  expect(response.code).to eq("200")
@@ -5,11 +5,13 @@ require "rails_helper"
5
5
  module DefraRubyMocks
6
6
  RSpec.describe CompaniesHouseService do
7
7
  describe ".run" do
8
+ subject { described_class.run(company_number) }
9
+
8
10
  context "when the company number is 99999999 for not found" do
9
11
  let(:company_number) { "99999999" }
10
12
 
11
13
  it "raises a NotFoundError" do
12
- expect { described_class.run(company_number) }.to raise_error(NotFoundError)
14
+ expect { subject }.to raise_error(NotFoundError)
13
15
  end
14
16
  end
15
17
 
@@ -18,19 +20,39 @@ module DefraRubyMocks
18
20
 
19
21
  specials.each do |company_number, status|
20
22
  context "and the number is #{company_number}" do
21
- it "returns a status of '#{status}'" do
22
- expect(described_class.run(company_number)).to eq(status)
23
+ let(:company_number) { company_number }
24
+
25
+ it "returns a company_status of '#{status}'" do
26
+ expect(subject.company_status).to eq(status)
27
+ end
28
+
29
+ it "returns a company_type of 'ltd'" do
30
+ expect(subject.company_type).to eq("ltd")
23
31
  end
24
32
  end
25
33
  end
26
34
  end
27
35
 
36
+ context "when the company is an LLP" do
37
+ CompaniesHouseService.llp_company_numbers.each do |company_number|
38
+ let(:company_number) { company_number }
39
+
40
+ it "returns a company_status of 'active'" do
41
+ expect(subject.company_status).to eq("active")
42
+ end
43
+
44
+ it "returns a company_type of 'llp'" do
45
+ expect(subject.company_type).to eq("llp")
46
+ end
47
+ end
48
+ end
49
+
28
50
  context "when the company number is not from the 'specials' list" do
29
51
  context "and it is valid" do
30
52
  let(:company_number) { "SC247974" }
31
53
 
32
- it "returns a status of 'active'" do
33
- expect(described_class.run(company_number)).to eq("active")
54
+ it "returns a company_status of 'active'" do
55
+ expect(subject.company_status).to eq("active")
34
56
  end
35
57
  end
36
58
 
@@ -38,7 +60,7 @@ module DefraRubyMocks
38
60
  let(:company_number) { "foo" }
39
61
 
40
62
  it "raises a NotFoundError" do
41
- expect { described_class.run(company_number) }.to raise_error(NotFoundError)
63
+ expect { subject }.to raise_error(NotFoundError)
42
64
  end
43
65
  end
44
66
  end
@@ -75,7 +75,6 @@ module DefraRubyMocks
75
75
 
76
76
  context "and is for a successful payment" do
77
77
  it "can generate a valid mac" do
78
- puts "Test data #{mac_data.join}"
79
78
  expect(described_class.run(args).mac).to eq(mac)
80
79
  end
81
80
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: defra_ruby_mocks
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Defra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-26 00:00:00.000000000 Z
11
+ date: 2022-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.3.1
19
+ version: '6.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.3.1
26
+ version: '6.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sprockets
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -158,6 +158,7 @@ files:
158
158
  - app/services/defra_ruby_mocks/worldpay_resource_service.rb
159
159
  - app/services/defra_ruby_mocks/worldpay_response_service.rb
160
160
  - app/views/defra_ruby_mocks/company/not_found.json.erb
161
+ - app/views/defra_ruby_mocks/company/officers.json.erb
161
162
  - app/views/defra_ruby_mocks/company/show.json.erb
162
163
  - app/views/defra_ruby_mocks/worldpay/payment_request.xml.erb
163
164
  - app/views/defra_ruby_mocks/worldpay/refund_request.xml.erb
@@ -203,10 +204,12 @@ files:
203
204
  - spec/dummy/config/locales/en.yml
204
205
  - spec/dummy/config/routes.rb
205
206
  - spec/dummy/config/secrets.yml
207
+ - spec/dummy/log/test.log
206
208
  - spec/dummy/public/404.html
207
209
  - spec/dummy/public/422.html
208
210
  - spec/dummy/public/500.html
209
211
  - spec/dummy/public/favicon.ico
212
+ - spec/examples.txt
210
213
  - spec/fixtures/payment_request_invalid.xml
211
214
  - spec/fixtures/payment_request_valid.xml
212
215
  - spec/fixtures/refund_request_invalid.xml
@@ -215,6 +218,7 @@ files:
215
218
  - spec/lib/configuration_spec.rb
216
219
  - spec/rails_helper.rb
217
220
  - spec/requests/company_spec.rb
221
+ - spec/requests/officers_spec.rb
218
222
  - spec/requests/worldpay_spec.rb
219
223
  - spec/services/companies_house_service_spec.rb
220
224
  - spec/services/worldpay_payment_service_spec.rb
@@ -241,7 +245,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
241
245
  requirements:
242
246
  - - ">="
243
247
  - !ruby/object:Gem::Version
244
- version: '0'
248
+ version: '2.4'
245
249
  required_rubygems_version: !ruby/object:Gem::Requirement
246
250
  requirements:
247
251
  - - ">="
@@ -287,10 +291,13 @@ test_files:
287
291
  - spec/dummy/public/422.html
288
292
  - spec/dummy/public/500.html
289
293
  - spec/dummy/public/404.html
294
+ - spec/dummy/log/test.log
290
295
  - spec/dummy/README.rdoc
296
+ - spec/examples.txt
291
297
  - spec/defra_ruby_mocks_spec.rb
292
298
  - spec/requests/company_spec.rb
293
299
  - spec/requests/worldpay_spec.rb
300
+ - spec/requests/officers_spec.rb
294
301
  - spec/support/simplecov.rb
295
302
  - spec/support/pry.rb
296
303
  - spec/support/helpers/helpers.rb