Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into td/ffs-2110-update-fl…
Browse files Browse the repository at this point in the history
…ow-use-new-database

* origin/main:
  FFS-2336: First sketch of multi-provider search (#442)
  • Loading branch information
tdooner committed Feb 12, 2025
2 parents 8d7b98f + a5bf186 commit fefe2b7
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 19 deletions.
1 change: 1 addition & 0 deletions app/.env
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ [email protected]
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=primary
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=deterministic
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=derivationsalt
SUPPORTED_PROVIDERS=pinwheel
15 changes: 5 additions & 10 deletions app/app/controllers/cbv/employer_searches_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class Cbv::EmployerSearchesController < Cbv::BaseController

def show
@query = search_params[:query]
@employers = @query.blank? ? [] : fetch_employers(@query)
@employers = @query.blank? ? [] : provider_search(@query)
@has_pinwheel_account = @cbv_flow.pinwheel_accounts.any?
@selected_tab = search_params[:type] || "payroll"

Expand All @@ -20,17 +20,12 @@ def show

private

def search_params
params.slice(:query, :type)
def provider_search(query = "")
ProviderSearchService.new(@cbv_flow.client_agency_id).search(query)
end

def fetch_employers(query = "")
request_params = {
q: query,
supported_jobs: [ "paystubs" ]
}

pinwheel.fetch_items(request_params)["data"]
def search_params
params.slice(:query, :type)
end

def track_clicked_popular_payroll_providers_event
Expand Down
27 changes: 27 additions & 0 deletions app/app/models/response_objects/search_result.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module ResponseObjects
SearchResult = Struct.new(:provider_name, :provider_options, :name, :logo_url, keyword_init: true) do
def self.from_pinwheel(response_body)
new(
provider_name: :pinwheel,
provider_options: {
response_type: response_body["response_type"],
provider_id: response_body["id"]
},
name: response_body["name"],
logo_url: response_body["logo_url"]
)
end

def self.from_argyle(response_body)
new(
provider_name: :argyle,
provider_options: {
response_type: response_body["kind"],
provider_id: response_body["id"]
},
name: response_body["name"],
logo_url: response_body["logo_url"]
)
end
end
end
43 changes: 43 additions & 0 deletions app/app/services/argyle_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require "faraday"

class ArgyleService
ENVIRONMENTS = {
sandbox: {
base_url: "https://api-sandbox.argyle.com/v2",
api_key_id: ENV["ARGYLE_API_TOKEN_SANDBOX_ID"],
api_key_secret: ENV["ARGYLE_API_TOKEN_SANDBOX_SECRET"]
}
}

def initialize(environment, api_key_id = nil, api_key_secret = nil)
@api_key_id = api_key_id || ENVIRONMENTS.fetch(environment.to_sym)[:api_key_id]
@api_key_secret = api_key_secret || ENVIRONMENTS.fetch(environment.to_sym)[:api_key_secret]
@environment = ENVIRONMENTS.fetch(environment.to_sym) { |env| raise KeyError.new("ArgyleService unknown environment: #{env}") }

client_options = {
request: {
open_timeout: 5,
timeout: 5,
params_encoder: Faraday::FlatParamsEncoder
},
url: @environment[:base_url]
}
@http = Faraday.new(client_options) do |conn|
conn.set_basic_auth @api_key_id, @api_key_secret
conn.response :raise_error
conn.response :json, content_type: "application/json"
conn.response :logger,
Rails.logger,
headers: true,
bodies: true,
log_level: :debug
end
end

# Fetch all Argyle items
def items(query = nil)
@http.get("items", { q: query }).body
end
end
28 changes: 28 additions & 0 deletions app/app/services/provider_search_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class ProviderSearchService
SUPPORTED_PROVIDERS = (ENV["SUPPORTED_PROVIDERS"] || "pinwheel")&.split(",")&.map(&:to_sym)

def initialize(client_agency_id)
@client_agency_config = site_config[client_agency_id]
end

def search(query = "")
SUPPORTED_PROVIDERS.map do |provider|
case provider
when :pinwheel
PinwheelService.new(@client_agency_config.pinwheel_environment).fetch_items(q: query)["data"].map do |result|
ResponseObjects::SearchResult.from_pinwheel(result)
end
when :argyle
ArgyleService.new(@client_agency_config.argyle_environment).items(query)["results"].map do |result|
ResponseObjects::SearchResult.from_argyle(result)
end
end
end.flatten
end

private

def site_config
Rails.application.config.client_agencies
end
end
12 changes: 6 additions & 6 deletions app/app/views/cbv/employer_searches/_employer.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
<div class="usa-card usa-card--flag usa-card--media-right flex-1">
<div class="usa-card__container">
<div class="usa-card__header">
<h3 class="usa-card__heading"><%= employer["name"] %></h3>
<h3 class="usa-card__heading"><%= employer.name %></h3>
</div>
<div class="display-none usa-card__media usa-card__media--inset">
<% if employer['logo_url'] %>
<% if employer.logo_url %>
<div class="usa-card__img">
<img
src="<%= employer["logo_url"] %>"
src="<%= employer.logo_url %>"
alt="A placeholder image"
>
</div>
Expand All @@ -24,10 +24,10 @@
<div class="usa-card__footer">
<button
data-action="click->cbv-employer-search#select"
data-id="<%= employer["id"] %>"
data-response-type="<%= employer["response_type"] %>"
data-id="<%= employer.provider_options[:provider_id] %>"
data-response-type="<%= employer.provider_options[:response_type] %>"
data-is-default-option="false"
data-name="<%= employer["name"] %>"
data-name="<%= employer.name %>"
data-cbv-employer-search-target="employerButton"
class="usa-button usa-button--outline"
type="button"
Expand Down
6 changes: 6 additions & 0 deletions app/config/client-agency-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
logo_square_path: hra_logo_square.png
pinwheel:
environment: <%= ENV["NYC_PINWHEEL_ENVIRONMENT"] %>
argyle:
environment: <%= ENV["SANDBOX_ARGYLE_ENVIRONMENT"] %>
transmission_method: shared_email
transmission_method_configuration:
email: <%= ENV['NYC_HRA_EMAIL'] %>
Expand All @@ -28,6 +30,8 @@
caseworker_feedback_form: https://forms.office.com/r/rfV04qjG9A
pinwheel:
environment: <%= ENV["MA_PINWHEEL_ENVIRONMENT"] %>
argyle:
environment: <%= ENV["SANDBOX_ARGYLE_ENVIRONMENT"] %>
transmission_method: s3
transmission_method_configuration:
bucket: <%= ENV['MA_DTA_S3_BUCKET'] %>
Expand All @@ -53,6 +57,8 @@
caseworker_feedback_form: https://docs.google.com/forms/d/e/1FAIpQLSfrUiz0oWE5jbXjPfl-idQQGPgxKplqFtcKq08UOhTaEa2k6A/viewform
pinwheel:
environment: <%= ENV["SANDBOX_PINWHEEL_ENVIRONMENT"] %>
argyle:
environment: <%= ENV["SANDBOX_ARGYLE_ENVIRONMENT"] %>
transmission_method: shared_email
transmission_method_configuration:
email: <%= ENV['SLACK_TEST_EMAIL'] %>
Expand Down
2 changes: 2 additions & 0 deletions app/lib/client_agency_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class ClientAgency
pay_income_days
pinwheel_api_token
pinwheel_environment
argyle_environment
staff_portal_enabled
sso
transmission_method
Expand All @@ -50,6 +51,7 @@ def initialize(yaml)
@logo_square_path = yaml["logo_square_path"]
@pay_income_days = yaml["pay_income_days"]
@pinwheel_environment = yaml["pinwheel"]["environment"] || "sandbox"
@argyle_environment = yaml["argyle"]["environment"] || "sandbox"
@transmission_method = yaml["transmission_method"]
@transmission_method_configuration = yaml["transmission_method_configuration"]
@staff_portal_enabled = yaml["staff_portal_enabled"]
Expand Down
6 changes: 4 additions & 2 deletions app/spec/lib/site_config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
- id: foo
agency_name: Foo Agency Name
pinwheel:
api_token: foo
environment: foo
argyle:
environment: foo
- id: bar
agency_name: Bar Agency Name
pinwheel:
api_token: bar
environment: bar
argyle:
environment: foo
YAML

before do
Expand Down
33 changes: 33 additions & 0 deletions app/spec/services/provider_search_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'rails_helper'

RSpec.describe ProviderSearchService, type: :service do
include PinwheelApiHelper
let(:service) { ProviderSearchService.new("sandbox") }

describe "#search" do
around do |ex|
stub_environment_variable("SUPPORTED_PROVIDERS", "pinwheel", &ex)
end

before do
stub_request_items_response
end

it "returns results from all enabled providers" do
results = service.search("test")
expect(results.length).to eq(1)
end

it "returns results with correct structure" do
results = service.search("test")
result = results.first

expect(result).to have_attributes(
provider_name: :pinwheel,
provider_options: a_hash_including(:response_type, :provider_id),
name: a_kind_of(String),
logo_url: a_kind_of(String)
)
end
end
end
23 changes: 22 additions & 1 deletion infra/app/app-config/env-config/environment-variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,13 @@ locals {
MA_DTA_S3_PUBLIC_KEY = {
manage_method = "manual"
secret_store_name = "/service/${var.app_name}-${var.environment}/ma-dta-s3-public-key"
}
},

# Feature Flags:
SUPPORTED_PROVIDERS = {
manage_method = "manual"
secret_store_name = "/service/${var.app_name}-${var.environment}/supported-providers"
},

# Pinwheel Configuration:
PINWHEEL_API_TOKEN_PRODUCTION = {
Expand Down Expand Up @@ -113,6 +119,21 @@ locals {
secret_store_name = "/service/${var.app_name}-${var.environment}/sandbox-pinwheel-environment"
},


# Argyle Configuration:
SANDBOX_ARGYLE_ENVIRONMENT = {
manage_method = "manual"
secret_store_name = "/service/${var.app_name}-${var.environment}/sandbox-argyle-environment"
},
ARGYLE_API_TOKEN_SANDBOX_ID = {
manage_method = "manual"
secret_store_name = "/service/${var.app_name}-${var.environment}/argyle-api-token-sandbox-id"
},
ARGYLE_API_TOKEN_SANDBOX_SECRET = {
manage_method = "manual"
secret_store_name = "/service/${var.app_name}-${var.environment}/argyle-api-token-sandbox-secret"
},

# SSO Configuration:
AZURE_NYC_DSS_CLIENT_ID = {
manage_method = "manual"
Expand Down

0 comments on commit fefe2b7

Please sign in to comment.