Skip to content

Commit

Permalink
186-Add actor that fetchs external api data (#204)
Browse files Browse the repository at this point in the history
* 186-Add actor that fetchs external api data

* 186-add location to fetch_schools

---------

Co-authored-by: Edimo <[email protected]>
  • Loading branch information
edimossilva and Edimo authored Jul 19, 2024
1 parent 38a3c80 commit 3eb1386
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 2 deletions.
1 change: 1 addition & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=database
ELASTICSEARCH_HOST=http://elasticsearch:9200
COLLEGE_SCORE_CARD_API_KEY=
3 changes: 3 additions & 0 deletions backend/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ RSpec/MultipleExpectations:
RSpec/NestedGroups:
Max: 5

RSpec/AnyInstance:
Enabled: false

RSpec/ImplicitSubject:
EnforcedStyle: single_statement_only

Expand Down
6 changes: 6 additions & 0 deletions backend/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ gem "acts_as_paranoid"
# Validation library with type-safe schemas and rules
gem "dry-validation"

# An HTTP client library abstraction layer
gem "faraday"

# Library for stubbing and setting expectations on HTTP requests in Ruby.
gem "webmock"

group :development, :test do
gem "bullet"

Expand Down
10 changes: 10 additions & 0 deletions backend/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ GEM
concurrent-ruby (1.2.3)
connection_pool (2.4.1)
constant_resolver (0.2.0)
crack (1.0.0)
bigdecimal
rexml
crass (1.0.6)
date (3.3.4)
debug (1.9.2)
Expand Down Expand Up @@ -229,6 +232,7 @@ GEM
railties
graphql (2.3.4)
base64
hashdiff (1.1.0)
hashie (5.0.0)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
Expand Down Expand Up @@ -564,6 +568,10 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webmock (3.23.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
websocket (1.2.10)
websocket-driver (0.7.6)
Expand Down Expand Up @@ -594,6 +602,7 @@ DEPENDENCIES
dotenv-rails
dry-validation
factory_bot_rails
faraday
graphiql-rails
graphql
importmap-rails
Expand Down Expand Up @@ -633,6 +642,7 @@ DEPENDENCIES
turbo-rails
tzinfo-data
web-console
webmock

RUBY VERSION
ruby 3.3.1p55
Expand Down
5 changes: 3 additions & 2 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
- cd backend
- create a .env file based on .env.example and copy the content of .env.example to .env (`$ cp .env.example .env`)
- docker compose build
- docker compose run web bundle install
- docker compose run web bin/rails db:setup
- docker compose up
- docker compose exec web bundle install
- docker compose exec web bin/rails db:setup
- bin/dev
- visit http://localhost:3000/

Expand Down
36 changes: 36 additions & 0 deletions backend/app/actors/fetch_schools.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

class FetchSchools < Actor
FETCH_SCHOOLS_URL = "https://api.data.gov/ed/collegescorecard/v1/schools"

input :school_name_like

output :data

def call
fail!(error: :missing_college_score_card_api_key) if api_key.blank?

self.data = fetch_schools
end

private

def fetch_schools
response = Faraday.get(FETCH_SCHOOLS_URL, params)
json_response = JSON.parse(response.body)
json_response["results"]
end

def params
{
api_key:,
fields: "id,school.name,location",
page: 0,
"school.name" => school_name_like
}
end

def api_key
ENV.fetch("COLLEGE_SCORE_CARD_API_KEY", nil)
end
end
11 changes: 11 additions & 0 deletions backend/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ services:
interval: 1s
timeout: 3s
retries: 30
redis_cache:
image: docker.io/redis:latest
hostname: redis
command: redis-server
ports:
- "6380:6379"
healthcheck:
test: redis-cli ping
interval: 1s
timeout: 3s
retries: 30

volumes:
backend_data:
Expand Down
68 changes: 68 additions & 0 deletions backend/spec/actors/fetch_schools_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe FetchSchools, type: :actor do
describe ".call" do
let(:school_name) { "The best school" }

context "when setup is valid" do
let(:valid_params) do
{
api_key:,
fields: "id,school.name,location",
page: 0,
"school.name" => school_name
}
end

let(:success_response) { { results: schools }.to_json }

let(:schools) do
[
{ "id" => "1",
"school.name" => school_name,
"location.lat" => 42.374471,
"location.lon" => -71.118313 }
]
end

let(:api_key) { "secret_api_key" }

before do
allow_any_instance_of(described_class).to receive(:api_key).and_return(api_key)
stub_request(:get, described_class::FETCH_SCHOOLS_URL)
.with(query: valid_params)
.to_return(status: 200, body: success_response, headers: { "Content-Type" => "application/json" })
end

it "is successful" do
result = described_class.result(school_name_like: school_name)
expect(result.success?).to be true
end

it "returns schools list" do
result = described_class.result(school_name_like: school_name)
expect(result.data).to eq(schools)
end
end

context "when setup is not valid" do
context "when api_key is nil" do
before do
allow_any_instance_of(described_class).to receive(:api_key).and_return("")
end

it "is failure" do
result = described_class.result(school_name_like: school_name)
expect(result.failure?).to be true
end
end

it "returns error object" do
result = described_class.result(school_name_like: school_name)
expect(result.error).to eq(:missing_college_score_card_api_key)
end
end
end
end
4 changes: 4 additions & 0 deletions backend/spec/support/webmock.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

require "webmock/rspec"
WebMock.disable_net_connect!(allow_localhost: true)

0 comments on commit 3eb1386

Please sign in to comment.