witch_doctor 0.2.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62a6d2446df132b40062054df4cefaa444b038a2
4
- data.tar.gz: 7a73956f5b7ec02a248628b5d2189297d7637854
3
+ metadata.gz: 650c3ce0616680e392499a923f74f19b8786ce71
4
+ data.tar.gz: 82d4262010013f84a259bf5e985e30e37cee9822
5
5
  SHA512:
6
- metadata.gz: 8bdcbfc8f4ad8ef68d392f243ea1d7a9e58ddd2d938a46ba276cf01fb24507386463860b813206791343fd7f8d1667fc7996d8fb773fe687a91e8bfb93d324c1
7
- data.tar.gz: 06078977ef998a31963d69287397148eea095d5ec014fc8b06c50daffbed48ce23b172a2aa218b129e1d9fdc8a162a502cd7b68d61af0be9ab7abf7f6e8cda3a
6
+ metadata.gz: 3e0bba87c3db83b2f36c1aa1d5e7f4ea33f4d4ac4ff88205575e241a200a21b9bef87e94a90ca66a356354ffb0708ca99ea348d068145df363ab0196df03def6
7
+ data.tar.gz: f3e566771992cb017041faa6c268c153c60d56a79335507a81923e81ce1c255967fd281daffc23cc0549b127b88a36136f96dd45f7fed760f8d01934913dc5b0
data/README.md CHANGED
@@ -13,6 +13,7 @@ Engine was designed to work alongside [virus_scan_service gem](https://github.co
13
13
  to which it provides a list of VirusScans. These are created upon file resource
14
14
  create / update events.
15
15
 
16
+ API is trying to comply with [JSON API standard](http://jsonapi.org/)
16
17
 
17
18
  ## CarrierWave
18
19
 
@@ -24,11 +25,7 @@ details
24
25
 
25
26
  ## working along `ActiveModel::Serializer`
26
27
 
27
- The reason why the gem is not using [ActiveModel::Serializer](https://github.com/rails-api/active_model_serializers)
28
- by default is that I didn't want to introduce extra dependencies.
29
- This engine is trying to be really lightweight.
30
-
31
- If you choose to use it in application using ActiveModel::Serializer you should have no problems.
28
+ please read more in `docs/action_model_serializer.md`
32
29
 
33
30
  # Setup
34
31
 
@@ -175,16 +172,18 @@ RSpec.describe 'VirusScans', :type => :request do
175
172
  expect(response.status).to be 200
176
173
  end
177
174
 
178
- it 'expect the JSON response to be Array' do
179
- expect(JSON.parse response.body).to eq [
180
- {
181
- "id" => virus_scan.id,
182
- "scan_result" => nil,
183
- "scanned_at" => nil,
184
- "file_url" => "/uploads/documents/#{virus_scan.id}/passport.jpg" # don't care about file storage (tests)
185
- # as virus scans are needed only on s3
186
- }
187
- ]
175
+ it 'expect the JSON response to be JSON API hash' do
176
+ expect(JSON.parse response.body).to eq({
177
+ "data" => [
178
+ {
179
+ "id" => virus_scan.id,
180
+ "scan_result" => nil,
181
+ "scanned_at" => nil,
182
+ "file_url" => "/uploads/documents/#{virus_scan.id}/passport.jpg" # don't care about file storage (tests)
183
+ # as virus scans are needed only on s3
184
+ }
185
+ ]
186
+ })
188
187
  end
189
188
  end
190
189
 
@@ -204,13 +203,14 @@ RSpec.describe 'VirusScans', :type => :request do
204
203
 
205
204
  it 'expect to update existing virus_scan' do
206
205
  expect(JSON.parse response.body).to eq({
206
+ "data" => {
207
207
  "id" => virus_scan.id,
208
208
  "scan_result" => 'Clean',
209
209
  "scanned_at" => Time.now.midnight.utc.iso8601,
210
210
  "file_url" => "/uploads/documents/#{virus_scan.id}/passport.jpg"
211
- })
211
+ }
212
+ })
212
213
  end
213
214
  end
214
215
  end
215
216
  ```
216
-
@@ -12,12 +12,16 @@ module WitchDoctor
12
12
  .not_scanned
13
13
  .limit(WitchDoctor.virus_scan_limit)
14
14
 
15
+
15
16
  respond_to do |format|
16
17
  format.json do
17
- render json: @virus_scans
18
+ render WitchDoctor.controller_object_hash_generator.call(@virus_scans)
18
19
  end
19
20
  format.html do
20
- render json: { errors: { request: ['needs to be JSON request'] } }, status: 406
21
+ json_406 = { title: "Not Acceptable",
22
+ detail: 'needs to be JSON request',
23
+ status: '406' }
24
+ render json: { errors: [json_406] }, status: 406
21
25
  end
22
26
  end
23
27
  end
@@ -31,18 +35,30 @@ module WitchDoctor
31
35
  @virus_scan = VirusScan.where(scan_result: nil).find params[:id]
32
36
  @virus_scan.update_attributes virus_scan_params# as: :scan_update
33
37
  if @virus_scan.errors.any?
34
- render json: { errors: @virus_scan.errors }, status: 400
38
+ json_400 = { title: "Bad Request",
39
+ detail: @virus_scan.errors.first.join(' '),
40
+ status: '400' }
41
+ render json: { errors: [json_400] }, status: 400
35
42
  else
36
- render json: @virus_scan.reload
43
+ render WitchDoctor.controller_object_hash_generator.call(@virus_scan.reload)
37
44
  end
38
45
  rescue ActionController::ParameterMissing => e
39
- render json: { errors: { request: [e.to_s] } }, status: 406
46
+ json_406 = { title: "Not Acceptable",
47
+ detail: e.to_s,
48
+ status: '406' }
49
+ render json: { errors: [json_406] }, status: 406
40
50
  rescue ActiveRecord::RecordNotFound => e
41
- render json: { errors: { request: ['Record not found or already scanned'] } }, status: 404
51
+ json_404 = { title: "Not Found",
52
+ detail: 'Record not found or already scanned',
53
+ status:'404' }
54
+ render json: { errors: [json_404] }, status: 404
42
55
  end
43
56
  end
44
57
  format.html do
45
- render json: { errors: { request: ['needs to be JSON request'] } }, status: 406
58
+ err_json = { title: 'Not Acceptable',
59
+ detail: 'needs to be JSON request',
60
+ status: '406' }
61
+ render json: { errors: [err_json] }, status: 406
46
62
  end
47
63
  end
48
64
  end
@@ -52,11 +68,17 @@ module WitchDoctor
52
68
 
53
69
  def authenticate!
54
70
  if provided_token == nil
55
- render json: { errors: { request: ['Not Authenticated'] } }, status: 401
71
+ unauthorized = {title: 'Unauthorized',
72
+ detail: 'Not Authenticated',
73
+ status: '401' }
74
+ render json: { errors: [unauthorized] }, status: 401
56
75
  elsif provided_token.to_s == WitchDoctor.token
57
76
  yield
58
77
  else
59
- render json: { errors: { request: ['Not Authorized'] } }, status: 403
78
+ forbidden = { title: 'Forbidden',
79
+ detail: 'Not Authorized',
80
+ status: '403' }
81
+ render json: { errors: [forbidden] }, status: 403
60
82
  end
61
83
  end
62
84
 
@@ -78,12 +100,10 @@ module WitchDoctor
78
100
  end
79
101
 
80
102
  def incorrect_format
81
- render json: { errors: { request: ["Incorrect format"] } }, status: 406
82
- end
83
-
84
- # when used in app with ActiveModel::Serializer this will prevent it to do root JSON
85
- def default_serializer_options
86
- {root: false}
103
+ json_406 = { title: 'Not Acceptable',
104
+ detail: "Incorrect format",
105
+ status: '406' }
106
+ render json: { errors: [json_406] }, status: 406
87
107
  end
88
108
  end
89
109
  end
@@ -1,3 +1,3 @@
1
1
  module WitchDoctor
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/witch_doctor.rb CHANGED
@@ -6,7 +6,8 @@ module WitchDoctor
6
6
  TokenNotSpecified = Class.new(StandardError)
7
7
 
8
8
  class << self
9
- attr_writer :time_stamper, :virus_scan_limit, :token, :skip_virus_scan_scheduling
9
+ attr_writer :time_stamper, :virus_scan_limit, :token,
10
+ :skip_virus_scan_scheduling, :controller_object_hash_generator
10
11
 
11
12
  def time_stamper
12
13
  @time_stamper ||= -> { Time.now }
@@ -23,5 +24,11 @@ module WitchDoctor
23
24
  def skip_virus_scan_scheduling
24
25
  !!@skip_virus_scan_scheduling
25
26
  end
27
+
28
+ def controller_object_hash_generator
29
+ @controller_object_hash_generator ||= begin
30
+ ->(object) { { json: { data: object.as_json } } }
31
+ end
32
+ end
26
33
  end
27
34
  end
@@ -13,6 +13,14 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
13
13
  before(:all) { WitchDoctor.time_stamper = -> { Time.now.midnight } }
14
14
  after(:all) { WitchDoctor.time_stamper = (reset_stamper_to_default = nil) }
15
15
 
16
+ let(:json_401) do
17
+ %q{{"errors":[{"title":"Unauthorized","detail":"Not Authenticated","status":"401"}]}}
18
+ end
19
+
20
+ let(:json_403) do
21
+ %q{{"errors":[{"title":"Forbidden","detail":"Not Authorized","status":"403"}]}}
22
+ end
23
+
16
24
  describe 'get index' do
17
25
  let!(:scheduled_virus_scan1) { create :virus_scan }
18
26
  let!(:clean_virus_scan) { create :virus_scan, :clean }
@@ -22,7 +30,7 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
22
30
  it 'responds 401 Not Authenticated' do
23
31
  get(:index, format: format)
24
32
  expect(response.status).to eq 401
25
- expect(response.body).to eq %q{{"errors":{"request":["Not Authenticated"]}}}
33
+ expect(response.body).to eq json_401
26
34
  end
27
35
  end
28
36
 
@@ -30,7 +38,7 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
30
38
  it 'responds 403 with Not Authorized errors' do
31
39
  get(:index, token: 999, format: format)
32
40
  expect(response.status).to eq 403
33
- expect(response.body).to eq %q{{"errors":{"request":["Not Authorized"]}}}
41
+ expect(response.body).to eq %q{{"errors":[{"title":"Forbidden","detail":"Not Authorized","status":"403"}]}}
34
42
  end
35
43
  end
36
44
 
@@ -42,7 +50,7 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
42
50
  it 'responds 200 with ASC scheduled virus scans' do
43
51
  trigger
44
52
  expect(response.status).to eq 200
45
- expect(response.body).to eq("[#{scheduled_virus_scan1.to_json},#{scheduled_virus_scan2.to_json}]")
53
+ expect(response.body).to eq("{\"data\":[#{scheduled_virus_scan1.to_json},#{scheduled_virus_scan2.to_json}]}")
46
54
  end
47
55
 
48
56
  context 'using header token' do
@@ -62,7 +70,16 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
62
70
  before { trigger }
63
71
  let(:format) { 'html' }
64
72
  it{ expect(response.status).to eq 406 }
65
- it{ expect(response.body).to eq %q{{"errors":{"request":["needs to be JSON request"]}}} }
73
+ it do
74
+ err_json = {
75
+ "errors"=>[
76
+ { "title"=>"Not Acceptable",
77
+ "detail"=>"needs to be JSON request",
78
+ "status"=>"406"}
79
+ ]
80
+ }
81
+ expect(JSON.parse response.body).to match err_json
82
+ end
66
83
  end
67
84
  end
68
85
  end
@@ -77,7 +94,7 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
77
94
  .not_to change { virus_scan.reload.scan_result }
78
95
 
79
96
  expect(response.status).to eq 401
80
- expect(response.body).to eq %q{{"errors":{"request":["Not Authenticated"]}}}
97
+ expect(response.body).to eq json_401
81
98
  end
82
99
  end
83
100
 
@@ -87,7 +104,7 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
87
104
  .not_to change { virus_scan.reload.scan_result }
88
105
 
89
106
  expect(response.status).to eq 403
90
- expect(response.body).to eq %q{{"errors":{"request":["Not Authorized"]}}}
107
+ expect(response.body).to eq json_403
91
108
  end
92
109
  end
93
110
 
@@ -109,12 +126,14 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
109
126
  .from(nil)
110
127
  .to('Clean')
111
128
 
112
- expect(JSON.parse response.body).to eq({
129
+ expect(JSON.parse response.body).to match({
130
+ "data" => {
113
131
  "id" => virus_scan.id,
114
132
  "scan_result" => 'Clean',
115
133
  "scanned_at" => Time.now.midnight.utc.iso8601,
116
134
  "file_url" => "https://my-s3-bucket.dummy/uploads/documents/blank_pdf.pdf"
117
- })
135
+ }
136
+ })
118
137
  end
119
138
 
120
139
  context 'sending missing params' do
@@ -124,7 +143,14 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
124
143
  .not_to change { virus_scan.reload.mount_point }
125
144
 
126
145
  expect(response.status).to eq 406
127
- expect(response.body).to eq(%q{{"errors":{"request":["param is missing or the value is empty: virus_scan"]}}})
146
+ err_json = {
147
+ "errors" => [
148
+ { "title"=>"Not Acceptable",
149
+ "detail"=>"param is missing or the value is empty: virus_scan",
150
+ "status"=>"406" }
151
+ ]
152
+ }
153
+ expect(JSON.parse(response.body)).to match(err_json)
128
154
  end
129
155
  end
130
156
 
@@ -135,7 +161,15 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
135
161
  .not_to change { virus_scan.reload.mount_point }
136
162
 
137
163
  expect(response.status).to eq 400
138
- expect(response.body).to eq(%q{{"errors":{"scan_result":["is not included in the list"]}}})
164
+
165
+ err_json = {
166
+ "errors" => [
167
+ { 'title' => "Bad Request",
168
+ 'detail' => "scan_result is not included in the list",
169
+ 'status' => '400' }
170
+ ]
171
+ }
172
+ expect(JSON.parse(response.body)).to match(err_json)
139
173
  end
140
174
  end
141
175
 
@@ -146,7 +180,15 @@ RSpec.describe WitchDoctor::VirusScansController, type: :controller do
146
180
  .not_to change { virus_scan.reload.scan_result }
147
181
 
148
182
  expect(response.status).to eq 406
149
- expect(response.body).to eq '{"errors":{"request":["needs to be JSON request"]}}'
183
+
184
+ err_json = {
185
+ "errors"=> [
186
+ { "title"=>"Not Acceptable",
187
+ "detail"=>"needs to be JSON request",
188
+ "status"=>"406" }
189
+ ]
190
+ }
191
+ expect(JSON.parse response.body).to match err_json
150
192
  end
151
193
  end
152
194
  end
@@ -281,3 +281,25 @@ Migrating to CreateWitchDoctorVirusScans (20150209121818)
281
281
  ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
282
282
  ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
283
283
  ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
284
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
285
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
286
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
287
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
288
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
289
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
290
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
291
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
292
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
293
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
294
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
295
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
296
+ ActiveRecord::SchemaMigration Load (0.3ms) SELECT "schema_migrations".* FROM "schema_migrations"
297
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
298
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
299
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
300
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
301
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
302
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
303
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
304
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
305
+ ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"