Skip to content

Commit 6a14fb5

Browse files
Connect UI application to TACOS
** Why are these changes being introduced: The search UI needs to be connected with TACOS, in order to get insight about interventions and allow term categorization to continue. ** Relevant ticket(s): * https://mitlibraries.atlassian.net/browse/use-66 ** How does this address that need: This adds a route, controller, and model for the integration with TACOS, along with defining some new environment variables. The approach is similar, but not identical, to the integration present in the Bento app. ** Document any side effects to this change: One oddity I can't explain is why the "tacos" cassette doesn't have any record of a call to TACOS - only the call to TIMDEX for the requested search is present. The related test passes, so everything worked and the UI element is present - but no interaction is present in the cassette (and thus made by the application when tested).
1 parent 0c0ae54 commit 6a14fb5

File tree

16 files changed

+345
-7
lines changed

16 files changed

+345
-7
lines changed

.env.test

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
TIMDEX_HOST=FAKE_TIMDEX_HOST
2-
TIMDEX_GRAPHQL=https://FAKE_TIMDEX_HOST/graphql
1+
TACOS_HOST=FAKE_TACOS_HOST
2+
TACOS_URL=http://FAKE_TACOS_HOST/graphql
3+
TACOS_SOURCE=FAKE_TACOS_SOURCE
4+
TIMDEX_HOST=FAKE_TACOS_HOST
5+
TIMDEX_GRAPHQL=https://FAKE_TACOS_HOST/graphql
36
TIMDEX_INDEX=FAKE_TIMDEX_INDEX
47
GDT=false

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,29 @@ mode (e.g., `GDT=false` will still enable GDT features). Note that this is curre
120120
may have unexpected consequences if applied to other TIMDEX UI apps.
121121
- `GLOBAL_ALERT`: The main functionality for this comes from our theme gem, but when set the value will be rendered as
122122
safe html above the main header of the site.
123+
- `ORIGINS`: sets origins for CORS (currently used only for TACOS API calls).
123124
- `PLATFORM_NAME`: The value set is added to the header after the MIT Libraries logo. The logic and CSS for this comes from our theme gem.
124125
- `REQUESTS_PER_PERIOD` - number of requests that can be made for general throttles per `REQUEST_PERIOD`
125126
- `REQUEST_PERIOD` - time in minutes used along with `REQUESTS_PER_PERIOD`
126127
- `REDIRECT_REQUESTS_PER_PERIOD`- number of requests that can be made that the query string starts with our legacy redirect parameter to throttle per `REQUEST_PERIOD`
127128
- `REDIRECT_REQUEST_PERIOD`- time in minutes used along with `REDIRECT_REQUEST_PERIOD`
128129
- `SENTRY_DSN`: Client key for Sentry exception logging.
129130
- `SENTRY_ENV`: Sentry environment for the application. Defaults to 'unknown' if unset.
131+
- `TACOS_SOURCE`: If set, this value is sent to TACOS (as the `sourceSystem` value) to distinguish which application
132+
instance is sending what search traffic. Defaults to "unset" if not defined.
133+
- `TACOS_URL`: The GraphQL endpoint for the [TACOS API](https://github.com/mitlibraries/tacos/). When set, the
134+
application will log search terms to TACOS (and eventually return suggested resources that TACOS detects).
130135
- `TIMDEX_INDEX`: Name of the index, or alias, to provide to the GraphQL endpoint. Defaults to `nil` which will let TIMDEX determine the best index to use. Wildcard values can be set, for example `rdi*` would search any indexes that begin with `rdi` in the underlying OpenSearch instance behind TIMDEX.
131136
- `TIMDEX_SOURCES`: Comma-separated list of sources to display in the advanced-search source selection element. This
132137
overrides the default which is set in ApplicationHelper.
133138

134139
#### Test Environment-only Variables
135140

136141
- `SPEC_REPORTER`: Optional variable. If set, enables spec reporter style output from tests rather than minimal output.
142+
- `TACOS_HOST`: Test Env only. Used to ensure the VCR cassettes can properly scrub specific host data to make sure we
143+
get the same cassettes regardless of which host was used to generate the cassettes. This should be set to the hostname
144+
that matches `TACOS_URL`. Ex: If `TACOS_URL` is `http://localhost:3001/graphql` then `TACOS_HOST` should be
145+
`localhost:3001`.
137146
- `TIMDEX_HOST`: Test Env only. Used to ensure the VCR cassettes can properly scrub specific host data to make sure we get the same cassettes regardless of which host was used to generate the cassettes. This should be set to the host name that matches `TIMDEX_GRAPHQL`. Ex: If `TIMDEX_GRAPHQL` is `https://www.example.com/graphql` then `TIMDEX_HOST` should be `www.example.com`.
138147

139148
### Generating VCR Cassettes
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class TacosController < ApplicationController
2+
layout false
3+
4+
def analyze
5+
return unless ApplicationHelper.tacos_enabled?
6+
7+
Tacos.call(params[:q])
8+
end
9+
end

app/helpers/application_helper.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
module ApplicationHelper
2+
def tacos_enabled?
3+
ENV.fetch('TACOS_URL', '').length > 0
4+
end
5+
module_function :tacos_enabled?
6+
27
def timdex_sources
38
ENV.fetch('TIMDEX_SOURCES', timdex_source_defaults).split(',')
49
end

app/models/tacos.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Tacos
2+
def self.call(term)
3+
tacos_http = HTTP.persistent(tacos_url)
4+
.headers(accept: 'application/json',
5+
'Content-Type': 'application/json',
6+
origin: origins)
7+
query = '{ "query": "{ logSearchEvent(searchTerm: \"' + clean_term(term) + '\", sourceSystem: \"' + tacos_source + '\" ) { phrase source detectors { suggestedResources { title url } } } }" }'
8+
raw_response = tacos_http.timeout(http_timeout).post(tacos_url, body: query)
9+
JSON.parse(raw_response.to_s)
10+
end
11+
12+
private
13+
14+
def self.clean_term(term)
15+
term.gsub('"', '\'')
16+
end
17+
18+
def self.http_timeout
19+
ENV.fetch('TIMDEX_TIMEOUT', 6).to_f
20+
end
21+
22+
def self.origins
23+
ENV.fetch('ORIGINS', nil)
24+
end
25+
26+
def self.tacos_source
27+
ENV.fetch('TACOS_SOURCE', 'unset')
28+
end
29+
30+
def self.tacos_url
31+
ENV.fetch('TACOS_URL', nil)
32+
end
33+
end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<% return unless (tacos_enabled? and @enhanced_query[:q].present?) %>
2+
3+
<% data_url = "/analyze?q=#{URI.encode_www_form_component(@enhanced_query[:q])}" %>
4+
5+
<div class="tacos-container"
6+
data-controller="content-loader"
7+
data-content-loader-url-value=<%= data_url %>>
8+
</div>

app/views/search/results.html.erb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,6 @@
6868
<% end %>
6969
</div>
7070

71+
<%= render(partial: 'trigger_tacos') if tacos_enabled? %>
72+
7173
<%= javascript_include_tag "filters" %>

app/views/tacos/analyze.html.erb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!-- Result of TACOS analysis would go here -->

config/routes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
get 'issn', to: 'fact#issn'
99
get 'pmid', to: 'fact#pmid'
1010

11+
get 'analyze', to: 'tacos#analyze'
12+
1113
get 'record/(:id)',
1214
to: 'record#view',
1315
as: 'record',

test/controllers/search_controller_test.rb

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ def setup
275275
end
276276
assert_response :success
277277

278-
assert_select('div[data-content-loader-url-value]', 0)
278+
assert_select('div[data-content-loader-url-value].fact-container', 0)
279279
end
280280
end
281281

@@ -305,7 +305,7 @@ def setup
305305

306306
assert_response :success
307307

308-
assert_select('div[data-content-loader-url-value]', 0)
308+
assert_select('div[data-content-loader-url-value].fact-container', 0)
309309
end
310310
end
311311

@@ -333,7 +333,7 @@ def setup
333333
end
334334
assert_response :success
335335

336-
assert_select('div[data-content-loader-url-value]', 0)
336+
assert_select('div[data-content-loader-url-value].fact-container', 0)
337337
end
338338
end
339339

@@ -361,7 +361,31 @@ def setup
361361
end
362362
assert_response :success
363363

364-
assert_select('div[data-content-loader-url-value]', 0)
364+
assert_select('div[data-content-loader-url-value].fact-container', 0)
365+
end
366+
end
367+
368+
test 'TACOS intervention is inserted when TACOS enabled' do
369+
VCR.use_cassette('tacos',
370+
allow_playback_repeats: true) do
371+
get '/results?q=tacos'
372+
373+
assert_response :success
374+
375+
tacos_div = assert_select('div[data-content-loader-url-value].tacos-container')
376+
assert_equal '/analyze?q=tacos', tacos_div.attribute('data-content-loader-url-value').value
377+
end
378+
end
379+
380+
test 'TACOS intervention not inserted when TACOS not enabled' do
381+
VCR.use_cassette('tacos',
382+
allow_playback_repeats: true) do
383+
ClimateControl.modify(TACOS_URL: '') do
384+
get '/results?q=tacos'
385+
end
386+
assert_response :success
387+
388+
assert_select('div[data-content-loader-url-value].tacos-container', 0)
365389
end
366390
end
367391

0 commit comments

Comments
 (0)