Skip to content

Commit

Permalink
Document background job result bodies
Browse files Browse the repository at this point in the history
Part of this work includes ensuring the output field of background job results is serialized as JSON (and deserialized as a hash with indifferent access because we are used to dealing with hashes with indifferent access in the Rails context).
  • Loading branch information
mjgiarlo committed Sep 19, 2019
1 parent 4fe5626 commit 69f8915
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 25 deletions.
2 changes: 1 addition & 1 deletion app/jobs/create_virtual_objects_job.rb
Expand Up @@ -20,7 +20,7 @@ def perform(virtual_objects:, background_job_result:)
end

if errors.any?
background_job_result.output = { errors: errors }.to_json
background_job_result.output = { errors: errors }
background_job_result.code = 422
else
background_job_result.code = 200
Expand Down
5 changes: 5 additions & 0 deletions app/models/background_job_result.rb
Expand Up @@ -7,4 +7,9 @@ class BackgroundJobResult < ApplicationRecord
processing: 'processing',
complete: 'complete'
}

# Deserialize JSON output field as a Hash with indifferent access
def output
@output ||= super.with_indifferent_access
end
end
2 changes: 1 addition & 1 deletion db/migrate/20190917215521_create_background_job_results.rb
Expand Up @@ -9,7 +9,7 @@ def up
SQL

create_table :background_job_results do |t|
t.text :output
t.json :output, default: {}
t.integer :code, default: 202
t.column :status, :background_job_result_status, default: 'pending'

Expand Down
2 changes: 1 addition & 1 deletion db/structure.sql
Expand Up @@ -56,7 +56,7 @@ CREATE TABLE public.ar_internal_metadata (

CREATE TABLE public.background_job_results (
id bigint NOT NULL,
output text,
output json DEFAULT '{}'::json,
code integer DEFAULT 202,
status public.background_job_result_status DEFAULT 'pending'::public.background_job_result_status,
created_at timestamp without time zone NOT NULL,
Expand Down
35 changes: 32 additions & 3 deletions openapi.json
Expand Up @@ -263,17 +263,31 @@
"operationId": "background_job_results#show",
"responses": {
"200": {
"description": "The background job has completed successfully"
"description": "The background job has completed successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BackgroundJobResultResponse"
}
}
}
},
"202": {
"description": "The background job is pending or processing"
"description": "The background job is pending or processing",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BackgroundJobResultResponse"
}
}
}
},
"422": {
"description": "One or more errors occurred running the background job",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
"$ref": "#/components/schemas/BackgroundJobResultResponse"
}
}
}
Expand Down Expand Up @@ -892,6 +906,21 @@
},
"required": ["externalIdentifier", "label", "type"]
},
"BackgroundJobResultResponse": {
"type": "object",
"properties": {
"output": {
"type": "object",
"description": "output from the job",
"$ref": "#/components/schemas/ErrorResponse"
},
"status": {
"type": "string",
"description": "the status of the background job",
"enum": ["pending", "processing", "complete"]
}
}
},
"ErrorResponse": {
"type": "object",
"properties": {
Expand Down
2 changes: 1 addition & 1 deletion spec/factories/background_job_results.rb
Expand Up @@ -2,7 +2,7 @@

FactoryBot.define do
factory :background_job_result do
output { '' }
output { {} }
status { 'pending' }
code { 202 }
end
Expand Down
4 changes: 2 additions & 2 deletions spec/jobs/create_virtual_objects_job_spec.rb
Expand Up @@ -66,8 +66,8 @@
expect(result.code).to eq(422)
end

it 'has no output' do
expect(result.output).to eq('{"errors":[{"druid:mk420bs7601":["One thing was not combinable","And another"]}]}')
it 'has output with errors' do
expect(result.output[:errors].first[parent_id]).to match_array(['One thing was not combinable', 'And another'])
end
end
end
29 changes: 13 additions & 16 deletions spec/requests/background_job_results_spec.rb
Expand Up @@ -4,18 +4,15 @@

RSpec.describe 'background job result' do
let(:background_job_result) { create(:background_job_result) }
let(:body) { JSON.parse(response.body) }
let(:body) { JSON.parse(response.body).with_indifferent_access }

context 'when it does not exist' do
it 'renders 404' do
get '/v1/background_job_results/0',
headers: { 'Authorization' => "Bearer #{jwt}" }
expect(response).to have_http_status(:not_found)
expect(body).to eq(
'errors' => [
{ 'title' => 'not found', 'detail' => 'Couldn\'t find BackgroundJobResult with \'id\'=0' }
]
)
expect(body[:errors].first[:title]).to eq('not found')
expect(body[:errors].first[:detail]).to eq('Couldn\'t find BackgroundJobResult with \'id\'=0')
end
end

Expand All @@ -30,11 +27,11 @@
end

it 'states the job is pending' do
expect(body['status']).to eq('pending')
expect(body[:status]).to eq('pending')
end

it 'has no output' do
expect(body['output']).to be_empty
expect(body[:output]).to be_empty
end
end

Expand All @@ -50,11 +47,11 @@
end

it 'states the job is processing' do
expect(body['status']).to eq('processing')
expect(body[:status]).to eq('processing')
end

it 'has no output' do
expect(body['output']).to be_empty
expect(body[:output]).to be_empty
end
end

Expand All @@ -69,35 +66,35 @@

context 'without errors' do
let(:code) { 200 }
let(:output) { '{"result":"succeeded!"}' }
let(:output) { { result: 'succeeded!' } }

it 'renders an HTTP 200 status code' do
expect(response).to have_http_status(:ok)
end

it 'states the job is complete' do
expect(body['status']).to eq('complete')
expect(body[:status]).to eq('complete')
end

it 'has output from the job' do
expect(body['output']).to eq(output)
expect(body[:output][:result]).to eq('succeeded!')
end
end

context 'with errors' do
let(:code) { 422 }
let(:output) { '{"errors":[{"detail":"failed!"}]}' }
let(:output) { { errors: [{ detail: 'failed!' }] } }

it 'renders an HTTP 422 status code' do
expect(response).to have_http_status(:unprocessable_entity)
end

it 'states the job is complete' do
expect(body['status']).to eq('complete')
expect(body[:status]).to eq('complete')
end

it 'has output from the job' do
expect(body['output']).to eq(output)
expect(body[:output][:errors].first[:detail]).to eq('failed!')
end
end
end
Expand Down

0 comments on commit 69f8915

Please sign in to comment.