et_fake_ccd 0.1.30 → 0.1.31

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 461f166cb0d439697c747600c6935205ba39e5fb8ec0eda7c82f8075c3b3a299
4
- data.tar.gz: 9ae42a76d0bb6ede5c89606c05bcc638ee32a82ac91e99de609ee60bcceff437
3
+ metadata.gz: 292d3013013ba2ff63dfcd80c0e8bcc75905c31ce58f5123b71896519ce9511a
4
+ data.tar.gz: 04f5b3d3ddd7c67a813913bc5eb44de2f6c477bfb59dff40806e15581726f45a
5
5
  SHA512:
6
- metadata.gz: 3a3fce9abfc823925017fcbf0f9e1233ac68c668b7bc887f40053c383a27d6f2af599a17dada887c0296200b7a6d7826b65d6224da55cfac9314e3583cb909e6
7
- data.tar.gz: 0137a2a02f6526e92f1f3d2c195c3b3d99982de9d31d27cd6a5ca0e927c380ace269c4325cdda12f3b78ad2fea11c6f771310c594c230d314728c0df3d64d9fe
6
+ metadata.gz: c149b5501179a89fdfddbe5ffbff890689153cba32d521b763554356d7c47adb768e025ba06559f66bd06f36abbc04cca81117e0b705155b9da837de46c03531
7
+ data.tar.gz: 8881ea586996e17eb191f23aa432d3b55ada8cef241e32fb5d0e0bdf4f25aa755eaca8385ae94d7793681e029d5d6f30a3e1ba6684849d44029f90ae0790ebbc
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- et_fake_ccd (0.1.30)
4
+ et_fake_ccd (0.1.31)
5
5
  activemodel (>= 5.2.3)
6
6
  iodine (~> 0.7)
7
7
  roda (~> 3.21)
@@ -27,7 +27,7 @@ GEM
27
27
  i18n (1.6.0)
28
28
  concurrent-ruby (~> 1.0)
29
29
  iodine (0.7.33)
30
- minitest (5.11.3)
30
+ minitest (5.12.2)
31
31
  public_suffix (4.0.1)
32
32
  rack (2.0.7)
33
33
  rake (10.5.0)
@@ -50,7 +50,7 @@ GEM
50
50
  rspec-support (3.8.2)
51
51
  thor (0.20.3)
52
52
  thread_safe (0.3.6)
53
- tilt (2.0.9)
53
+ tilt (2.0.10)
54
54
  tzinfo (1.2.5)
55
55
  thread_safe (~> 0.1)
56
56
  zeitwerk (2.1.10)
data/README.md CHANGED
@@ -25,7 +25,70 @@ Or install it yourself as:
25
25
 
26
26
  ## Usage
27
27
 
28
- TODO: Write usage instructions here
28
+ To run the server, use the command
29
+
30
+ ```
31
+ et_fake_ccd start
32
+ ```
33
+
34
+ ## Testing Using This Fake Server
35
+
36
+ In general, this server will try to act like the normal CCD server but only in terms of accepting
37
+ and storing data.
38
+ So, it stores the data that the application gives it and it allows that data to be read back so
39
+ that a test suite or a manual process can validate that data.
40
+
41
+ It also has some basic validation so that it behaves in a similar way to CCD, but due to the complexity of
42
+ CCD itself, this app can never reflect exactly how it validates.
43
+
44
+ So, for this reason, deliberate errors are added to this server.
45
+
46
+ ### Testing Using Deliberate Errors
47
+
48
+ When you think about it, if there was a way in the application to force an error, the developer
49
+ would fix it ! So, we have to rely on having some deliberate errors where the data will pass through
50
+ all the validation within the app, but this server then knows to respond as if it was an error.
51
+
52
+ This will allow a tester or a test suite to provide the magic values that will trigger certain
53
+ error scenarios and prove that the app behaves as expected under these error conditions.
54
+
55
+ This allows for basic testing and is not intended to be real life - only real life will give you
56
+ real life errors.
57
+
58
+ For example, lets say we chose the name "Fred Bloggs" (sorry, the real fred bloggs - you must get fed
59
+ up with people using your name) to always respond with a 403 error saying "Forbidden".
60
+
61
+ Obviously, you could not force the app to get a real forbidden error, so as a tester or a developer
62
+ writing test code, you would know from this readme that Fred Bloggs always causes a 403 error,
63
+ therefore you would expect the exported case in the admin to be marked with an error as an example.
64
+
65
+ So, here is a list of deliberate errors that Im sure will increase in size :-
66
+
67
+ #### Force a 403 error every time
68
+
69
+ * Use the lead claimant name "Force Error403"
70
+
71
+ #### Force a 403 error for just the first time
72
+
73
+ * Use the lead claimant name "Force Error403-<n>" (replace <n> with a number unique to your test)
74
+
75
+ #### Force a 504 error
76
+ * Use the lead claimant name "Force Error504"
77
+ * Use the lead claimant title of "Mr" to only force the error on the first occurence
78
+ * Use the lead claimant title of "Mrs" to force the error on every occurence
79
+
80
+ #### Force a 502 error
81
+ * Use the lead claimant name "Force Error502"
82
+ * Use the lead claimant title of "Mr" to only force the error on the first occurence
83
+ * Use the lead claimant title of "Mrs" to force the error on every occurence
84
+
85
+ #### Force a 422 error
86
+ * Use the lead claimant name "Force Error422"
87
+ * Use the lead claimant title of "Mr" to only force the error on the first occurence
88
+ * Use the lead claimant title of "Mrs" to force the error on every occurence
89
+
90
+
91
+
29
92
 
30
93
  ## Development
31
94
 
@@ -0,0 +1,58 @@
1
+ require "singleton"
2
+ module EtFakeCcd
3
+ class RequestStoreService
4
+ include Singleton
5
+ def self.store(request_id)
6
+ instance.store(request_id)
7
+ end
8
+
9
+ def self.count(request_id)
10
+ instance.count(request_id)
11
+ end
12
+
13
+ def store(request_id)
14
+ adapter.store(request_id)
15
+ end
16
+
17
+ def count(request_id)
18
+ adapter.count(request_id)
19
+ end
20
+
21
+ def adapter
22
+ @adapter ||= InMemoryAdapter.new
23
+ end
24
+
25
+ class InMemoryAdapter
26
+ TTL = 1800
27
+ def initialize
28
+ self.data = {}
29
+ end
30
+
31
+ def store(request_id)
32
+ expire_old_requests(request_id)
33
+ data[request_id] ||= []
34
+ data[request_id] << Time.now.utc
35
+ end
36
+
37
+ def count(request_id)
38
+ expire_old_requests(request_id)
39
+ return 0 if data[request_id].nil?
40
+
41
+ data[request_id].length
42
+ end
43
+
44
+ private
45
+
46
+ attr_accessor :data
47
+
48
+ def expire_old_requests(request_id)
49
+ return unless data.key?(request_id) && data[request_id].length > 0
50
+
51
+ last_request = data[request_id].max
52
+ if (Time.now - last_request) > TTL
53
+ data[request_id].clear
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -3,6 +3,7 @@ require 'json'
3
3
  require 'et_fake_ccd/commands'
4
4
  require 'et_fake_ccd/auth_service'
5
5
  require 'et_fake_ccd/data_store_service'
6
+ require 'et_fake_ccd/request_store_service'
6
7
  module EtFakeCcd
7
8
  module Service
8
9
  class DataStoreApp < Roda
@@ -64,12 +65,14 @@ module EtFakeCcd
64
65
  break
65
66
  end
66
67
  json = JSON.parse(r.body.read)
68
+ next if force_deliberate_error(json, r)
69
+
67
70
  command = case json.dig('event', 'id')
68
- when 'initiateCase' then ::EtFakeCcd::Command::CreateCaseCommand.from_json json
71
+ when 'initiateCase' then ::EtFakeCcd::Command::CreateCaseCommand.from_json json
69
72
  when 'createBulkAction' then ::EtFakeCcd::Command::CreateBulkActionCaseCommand.from_json json
70
73
  else
71
74
  r.halt 400, unknown_event_error_for(r)
72
- end
75
+ end
73
76
  if command.valid?
74
77
  id = ::EtFakeCcd::DataStoreService.store_case_data(command.data, jid: jid, ctid: ctid)
75
78
  case_created_response(id, uid, jid, ctid)
@@ -94,6 +97,66 @@ module EtFakeCcd
94
97
 
95
98
  private
96
99
 
100
+ def force_deliberate_error(data, r)
101
+ return false unless data.dig('data', 'claimantIndType', 'claimant_first_names').strip.downcase == 'force'
102
+ error, client_id = data.dig('data', 'claimantIndType', 'claimant_last_name').split('-')
103
+ if client_id.nil?
104
+ render_error(error)
105
+ else
106
+ track_request_id("#{error}-#{client_id}")
107
+ return false unless should_error_for_request_id?("#{error}-#{client_id}")
108
+ render_error(error)
109
+ end
110
+ true
111
+ end
112
+
113
+ def render_error(error)
114
+ method_name = "render_#{error.downcase}".to_sym
115
+ return unless respond_to?(method_name, true)
116
+
117
+ send method_name
118
+ end
119
+
120
+ def track_request_id(request_id)
121
+ RequestStoreService.store request_id
122
+ end
123
+
124
+ def should_error_for_request_id?(request_id)
125
+ RequestStoreService.count(request_id) > 0
126
+ end
127
+
128
+ def render_error403
129
+ r.halt 403, forbidden_error_for(r)
130
+ end
131
+
132
+ def render_error504
133
+ j = {"timestamp":"2019-07-01T07:46:35.405+0000","status":504,"error":"Forbidden","message":"Access Denied","path": r.path}
134
+ r.halt 504, JSON.generate(j)
135
+ end
136
+
137
+ def render_error502
138
+ j = {"timestamp":"2019-07-01T07:46:35.405+0000","status":502,"error":"Forbidden","message":"Access Denied","path": r.path}
139
+ r.halt 502, JSON.generate(j)
140
+ end
141
+
142
+ def render_error422
143
+ j = {
144
+ "exception": "uk.gov.hmcts.ccd.endpoint.exceptions.CaseValidationException",
145
+ "timestamp": "2019-07-01T16:02:28.045",
146
+ "status": 422,
147
+ "error": "Unprocessable Entity",
148
+ "message": "Case data validation failed",
149
+ "path": request.path,
150
+ "details": {
151
+ "field_errors": command.errors.details[:data].map {|e| e[:field_error]}
152
+ },
153
+ "callbackErrors": nil,
154
+ "callbackWarnings": nil
155
+ }
156
+
157
+ r.halt 422, JSON.generate(j)
158
+ end
159
+
97
160
  def initiate_case(uid, jid, ctid)
98
161
  j = {
99
162
  "token": "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJvZDRwZ3NhbDQwcTdndHI0Y2F1bmVmZGU5aSIsInN1YiI6IjIyIiwiaWF0IjoxNTYxOTY2NzM1LCJldmVudC1pZCI6ImluaXRpYXRlQ2FzZSIsImNhc2UtdHlwZS1pZCI6IkVtcFRyaWJfTVZQXzEuMF9NYW5jIiwianVyaXNkaWN0aW9uLWlkIjoiRU1QTE9ZTUVOVCIsImNhc2UtdmVyc2lvbiI6ImJmMjFhOWU4ZmJjNWEzODQ2ZmIwNWI0ZmEwODU5ZTA5MTdiMjIwMmYifQ.u-OfexKFu52uvSgTNVHJ5kUQ9KTZGClRIRnGXRPSmGY",
@@ -1,3 +1,3 @@
1
1
  module EtFakeCcd
2
- VERSION = "0.1.30"
2
+ VERSION = "0.1.31"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: et_fake_ccd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.30
4
+ version: 0.1.31
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gary Taylor
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-16 00:00:00.000000000 Z
11
+ date: 2019-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: roda
@@ -177,6 +177,7 @@ files:
177
177
  - lib/et_fake_ccd/data_store_service.rb
178
178
  - lib/et_fake_ccd/document_store_service.rb
179
179
  - lib/et_fake_ccd/iodine.rb
180
+ - lib/et_fake_ccd/request_store_service.rb
180
181
  - lib/et_fake_ccd/root_app.rb
181
182
  - lib/et_fake_ccd/service/api_gateway_web_app.rb
182
183
  - lib/et_fake_ccd/service/auth_app.rb