Skip to content

Commit

Permalink
Add missing endpoints and test
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwr18 committed Oct 13, 2023
1 parent c366a56 commit 1f69750
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 8 deletions.
59 changes: 51 additions & 8 deletions app/controllers/api_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,17 @@

class ApiController < ApplicationController
skip_before_action :require_login
before_action :authorize_api_access
before_action :authorize_api_access, :contributor

def show
contributor = Contributor.find_by(external_id: external_id)

unless contributor
if contributor
render json: { status: 'ok', data: { first_name: contributor.first_name, external_id: contributor.external_id } }, status: :ok
else
render json: { status: 'error', message: 'Not found' }, status: :not_found
return
end

render json: { status: 'ok', data: { first_name: contributor.first_name, external_id: contributor.external_id } }, status: :ok
end

def create
contributor = Contributor.find_by(external_id: external_id)
if contributor
render json: {
status: 'ok',
Expand All @@ -41,8 +37,51 @@ def create
end
end

def current_request
if contributor
current_personalized_request = contributor.received_messages.first
render json: {
status: 'ok',
data: {
id: current_personalized_request.id,
personalized_text: current_personalized_request.text,
contributor_replies_count: contributor.replies.where(request_id: current_personalized_request.request.id).count
}
}, status: :ok
else
render json: { status: 'error', message: 'Not found' }, status: :not_found
end
end

def messages
if contributor
message = Message.new(
request: contributor.active_request,
text: messages_params[:text],
sender: contributor
)
message.raw_data.attach(
io: StringIO.new(JSON.generate(messages_params)),
filename: 'api.json',
content_type: 'application/json'
)

if message.save!
render json: { status: 'ok', data: { id: message.id, text: message.text } }, status: :created
else
render json: { status: 'error', message: 'Record could not be created' }, status: :unprocessable_entity
end
else
render json: { status: 'error', message: 'Not found' }, status: :not_found
end
end

private

def contributor
@contributor ||= Contributor.find_by(external_id: external_id)
end

def authorize_api_access
authenticate_or_request_with_http_token do |token, _options|
ActiveSupport::SecurityUtils.secure_compare(token, Setting.api_token)
Expand All @@ -56,4 +95,8 @@ def external_id
def onboard_params
params.permit(:first_name)
end

def messages_params
params.permit(:text)
end
end
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,6 @@

get '/v1/contributors/me', to: 'api#show'
post '/v1/contributors', to: 'api#create'
get '/v1/contributors/me/requests/current', to: 'api#current_request'
post '/v1/contributors/me/messages', to: 'api#messages'
end
135 changes: 135 additions & 0 deletions spec/requests/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,139 @@
end
end
end

describe 'GET /contributors/me/requests/current' do
subject { -> { get '/v1/contributors/me/requests/current', headers: headers } }

describe 'not authorized' do
context 'missing auth headers' do
it 'returns not authorized' do
subject.call

expect(response).to have_http_status(:unauthorized)
expect(response.code.to_i).to eq(401)
end
end

context 'invalid token' do
let(:headers) { { 'Authorization' => "Bearer #{SecureRandom.urlsafe_base64(128)}" } }

it 'returns not authorized' do
subject.call

expect(response).to have_http_status(:unauthorized)
expect(response.code.to_i).to eq(401)
end
end
end

describe 'authorized' do
before { allow(Setting).to receive(:api_token).and_return(token) }
let(:headers) { valid_headers }

context 'unknown contributor' do
it 'returns not found' do
subject.call

expect(response).to have_http_status(:not_found)
expect(response.code.to_i).to eq(404)
end

it 'returns error status with message Not found' do
subject.call

expect(response.body).to eq({ status: 'error', message: 'Not found' }.to_json)
end
end

context 'known contributor' do
let(:contributor) { create(:contributor, external_id: external_id) }
let!(:message) { create(:message, :outbound, recipient_id: contributor.id) }
let(:expected_response) do
{
status: 'ok',
data:
{
id: message.id,
personalized_text: message.text,
contributor_replies_count: contributor.replies.where(request_id: message.request.id).count
}
}.to_json
end

it 'returns resource data' do
subject.call

expect(response.body).to eq(expected_response)
expect(response.code.to_i).to eq(200)
end
end
end

describe 'POST /v1/contributors/me/messages' do
subject { -> { post v1_contributors_me_messages_path, params: { text: 'Create this message' }, headers: headers } }

describe 'not authorized' do
context 'missing auth headers' do
it 'returns not authorized' do
subject.call

expect(response).to have_http_status(:unauthorized)
expect(response.code.to_i).to eq(401)
end
end

context 'invalid token' do
let(:headers) { { 'Authorization' => "Bearer #{SecureRandom.urlsafe_base64(128)}" } }

it 'returns not authorized' do
subject.call

expect(response).to have_http_status(:unauthorized)
expect(response.code.to_i).to eq(401)
end
end
end

describe 'authorized' do
before { allow(Setting).to receive(:api_token).and_return(token) }

let(:headers) { valid_headers }
let(:expected_response) do
{
status: 'ok',
data: {
id: Message.first.id,
text: Message.first.text
}
}
end

context 'unknown contributor' do
it 'returns not found' do
subject.call

expect(response).to have_http_status(:not_found)
expect(response.code.to_i).to eq(404)
end
end

context 'known contributor' do
let!(:contributor) { create(:contributor, external_id: external_id) }
let!(:request) { create(:request) }

it 'creates a message' do
expect { subject.call }.to change(Message, :count).by(1)
end

it 'returns resource data' do
subject.call

expect(response.body).to eq(expected_response.to_json)
expect(response.code.to_i).to eq(201)
end
end
end
end
end
end

0 comments on commit 1f69750

Please sign in to comment.