From 1c28fa109fe7584dc6a7912e09e4057e7121decb Mon Sep 17 00:00:00 2001 From: jazairi <16103405+jazairi@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:25:59 -0400 Subject: [PATCH] Refactor detector GraphQL and implement journal detection type Why these changes are being introduced: We've implemented a journal detection model but not the corresponding GraphQL. As this will be the second of many detectors, it also makes sense to reconsider how the detector GraphQL is modeled. Relevant ticket(s): * [TCO-50](https://mitlibraries.atlassian.net/browse/TCO-50) How this addresses that need: This makes `journals` and `standard_identifiers` fields within a new `DetectorsType`. Much like the `Detector` module, this new type is not to any ActiveRecord models and acts more as a namespace to contain the various detectors. Side effects of this change: * The graphql-ruby docs [advise against overusing JSON](https://graphql-ruby.org/api-doc/2.3.14/GraphQL/Types/JSON.html) as a GraphQL type, but this feels like a good use case for it. * I'm not certain whether my solution to the `detectors` field is idiomatic. It feels particularly odd given that, in the SearchEventType, there is a method for the `phrase` field that returns the same thing. * The gitignore file has been updated to ignore Lando config. This ended up being unrelated to this changeset, but it might be useful during cassette regeneration. --- .gitignore | 1 + app/graphql/types/detectors_type.rb | 20 ++++++ app/graphql/types/journals_type.rb | 8 +++ app/graphql/types/search_event_type.rb | 8 +-- app/graphql/types/term_type.rb | 8 +-- app/models/detector/standard_identifiers.rb | 5 +- test/controllers/graphql_controller_test.rb | 69 ++++++++++++++------- 7 files changed, 83 insertions(+), 36 deletions(-) create mode 100644 app/graphql/types/detectors_type.rb create mode 100644 app/graphql/types/journals_type.rb diff --git a/.gitignore b/.gitignore index b046838..a2e6fc1 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,4 @@ .DS_Store .vscode/ .yardoc +.lando.yml diff --git a/app/graphql/types/detectors_type.rb b/app/graphql/types/detectors_type.rb new file mode 100644 index 0000000..cb9632e --- /dev/null +++ b/app/graphql/types/detectors_type.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Types + class DetectorsType < Types::BaseObject + field :journals, [Types::JournalsType] + field :standard_identifiers, [Types::StandardIdentifiersType] + + def standard_identifiers + Detector::StandardIdentifiers.new(@object).identifiers.map do |identifier| + { kind: identifier.first, value: identifier.last } + end + end + + def journals + Detector::Journal.full_term_match(@object).map do |journal| + { title: journal.name, additional_info: journal.additional_info } + end + end + end +end diff --git a/app/graphql/types/journals_type.rb b/app/graphql/types/journals_type.rb new file mode 100644 index 0000000..94c1d48 --- /dev/null +++ b/app/graphql/types/journals_type.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Types + class JournalsType < Types::BaseObject + field :additional_info, GraphQL::Types::JSON + field :title, String, null: false + end +end diff --git a/app/graphql/types/search_event_type.rb b/app/graphql/types/search_event_type.rb index 9c0b246..38f0e14 100644 --- a/app/graphql/types/search_event_type.rb +++ b/app/graphql/types/search_event_type.rb @@ -3,10 +3,10 @@ module Types class SearchEventType < Types::BaseObject field :created_at, GraphQL::Types::ISO8601DateTime, null: false + field :detectors, Types::DetectorsType field :id, ID, null: false field :phrase, String field :source, String - field :standard_identifiers, [StandardIdentifiersType] field :term_id, Integer field :updated_at, GraphQL::Types::ISO8601DateTime, null: false @@ -14,10 +14,8 @@ def phrase @object.term.phrase end - def standard_identifiers - Detector::StandardIdentifiers.new(@object.term.phrase).identifiers.map do |identifier| - { kind: identifier.first, value: identifier.last } - end + def detectors + @object.term.phrase end end end diff --git a/app/graphql/types/term_type.rb b/app/graphql/types/term_type.rb index 28b5243..409d940 100644 --- a/app/graphql/types/term_type.rb +++ b/app/graphql/types/term_type.rb @@ -3,21 +3,19 @@ module Types class TermType < Types::BaseObject field :created_at, GraphQL::Types::ISO8601DateTime, null: false + field :detectors, Types::DetectorsType field :id, ID, null: false field :occurence_count, Integer field :phrase, String, null: false field :search_events, [SearchEventType], null: false - field :standard_identifiers, [StandardIdentifiersType] field :updated_at, GraphQL::Types::ISO8601DateTime, null: false def occurence_count @object.search_events.count end - def standard_identifiers - StandardIdentifiers.new(@object.phrase).identifiers.map do |identifier| - { kind: identifier.first, value: identifier.last } - end + def detectors + @object.phrase end end end diff --git a/app/models/detector/standard_identifiers.rb b/app/models/detector/standard_identifiers.rb index e869a98..2a7f644 100644 --- a/app/models/detector/standard_identifiers.rb +++ b/app/models/detector/standard_identifiers.rb @@ -1,9 +1,8 @@ # frozen_string_literal: true -# StandardIdentifiers is a PatternDectector implementation that detects the identifiers DOI, ISBN, ISSN, PMID. -# See /docs/reference/pattern_detection_and_enhancement.md for details. - module Detector + # Detector::StandardIdentifiers detects the identifiers DOI, ISBN, ISSN, PMID. + # See /docs/reference/pattern_detection_and_enhancement.md for details. class StandardIdentifiers attr_reader :identifiers diff --git a/test/controllers/graphql_controller_test.rb b/test/controllers/graphql_controller_test.rb index 2647775..fd0f6c3 100644 --- a/test/controllers/graphql_controller_test.rb +++ b/test/controllers/graphql_controller_test.rb @@ -57,17 +57,38 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest test 'search event query can return detected standard identifiers' do post '/graphql', params: { query: '{ logSearchEvent(sourceSystem: "timdex", searchTerm: "10.1038/nphys1170") { - standardIdentifiers { - kind - value - } + detectors { + standardIdentifiers { + kind + value + } + } } }' } json = response.parsed_body - assert_equal('doi', json['data']['logSearchEvent']['standardIdentifiers'].first['kind']) - assert_equal('10.1038/nphys1170', json['data']['logSearchEvent']['standardIdentifiers'].first['value']) + assert_equal('doi', json['data']['logSearchEvent']['detectors']['standardIdentifiers'].first['kind']) + assert_equal('10.1038/nphys1170', json['data']['logSearchEvent']['detectors']['standardIdentifiers'].first['value']) + end + + test 'search event query can return detected journals' do + post '/graphql', params: { query: '{ + logSearchEvent(sourceSystem: "timdex", searchTerm: "nature") { + detectors { + journals { + title + additionalInfo + } + } + } + }' } + + json = response.parsed_body + + assert_equal('nature', json['data']['logSearchEvent']['detectors']['journals'].first['title']) + assert_equal({"issns"=>["0028-0836", "1476-4687"]}, + json['data']['logSearchEvent']['detectors']['journals'].first['additionalInfo']) end test 'search event query can return phrase from logged term' do @@ -85,29 +106,31 @@ class GraphqlControllerTest < ActionDispatch::IntegrationTest test 'search event query can return details for detected standard identifiers' do VCR.use_cassette('searchevent 10.1038/nphys1170') do post '/graphql', params: { query: '{ - logSearchEvent(sourceSystem: "timdex", searchTerm: "10.1038/nphys1170") { - standardIdentifiers { - kind - value - details { - title - linkResolverUrl - issns - authors - } - } - } - }' } + logSearchEvent(sourceSystem: "timdex", searchTerm: "10.1038/nphys1170") { + detectors { + standardIdentifiers { + kind + value + details { + title + linkResolverUrl + issns + authors + } + } + } + } + }' } json = response.parsed_body assert_equal('Measured measurement', - json['data']['logSearchEvent']['standardIdentifiers'].first['details']['title']) + json['data']['logSearchEvent']['detectors']['standardIdentifiers'].first['details']['title']) assert_equal('https://mit.primo.exlibrisgroup.com/discovery/openurl?institution=01MIT_INST&rfr_id=info:sid/mit.tacos.api&vid=01MIT_INST:MIT&rft.atitle=Measured measurement&rft.date=&rft.genre=journal-article&rft.jtitle=Nature Physics&rft_id=info:doi/10.1038/nphys1170', - json['data']['logSearchEvent']['standardIdentifiers'].first['details']['linkResolverUrl']) + json['data']['logSearchEvent']['detectors']['standardIdentifiers'].first['details']['linkResolverUrl']) assert_equal(%w[1745-2473 1745-2481], - json['data']['logSearchEvent']['standardIdentifiers'].first['details']['issns']) - assert_nil(json['data']['logSearchEvent']['standardIdentifiers'].first['details']['authors']) + json['data']['logSearchEvent']['detectors']['standardIdentifiers'].first['details']['issns']) + assert_nil(json['data']['logSearchEvent']['detectors']['standardIdentifiers'].first['details']['authors']) end end end