diff --git a/Gemfile b/Gemfile index bd71b63ad..fde95c2d6 100644 --- a/Gemfile +++ b/Gemfile @@ -31,7 +31,6 @@ gem "bcrypt", "~> 3.1.7" gem "pwqgen.rb", "~> 0.1.0" gem "string_pattern" gem "simple_command" -gem "kaminari", "~> 1.0", ">= 1.0.1" gem "cancancan", "~> 2.0" gem "country_select", "~> 3.1" gem "countries", "~> 2.1", ">= 2.1.2" diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql index 963008a6c..3bcc48018 100644 --- a/app/graphql/schema.graphql +++ b/app/graphql/schema.graphql @@ -204,6 +204,11 @@ type Client { """ alternateName: String + """ + The number of citations. + """ + citationCount: Int + """ Datasets managed by the client """ @@ -218,19 +223,28 @@ type Client { """ before: String first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int """ Returns the last _n_ elements from the list. """ last: Int query: String - ): ClientDatasetConnectionWithMeta! + userId: String + ): DatasetConnectionWithMeta """ Description of the client """ description: String + """ + The number of downloads according to the Counter Code of Practice. + """ + downloadCount: Int + """ Unique identifier for each client """ @@ -261,8 +275,9 @@ type Client { """ last: Int query: String + state: String year: String - ): PrefixConnectionWithMeta! + ): ClientPrefixConnectionWithMeta """ Publications managed by the client @@ -278,13 +293,17 @@ type Client { """ before: String first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int """ Returns the last _n_ elements from the list. """ last: Int query: String - ): ClientPublicationConnectionWithMeta! + userId: String + ): PublicationConnectionWithMeta """ The re3data identifier for the client @@ -299,7 +318,7 @@ type Client { """ Software managed by the client """ - softwareSourceCodes( + softwares( """ Returns the elements in the list that come after the specified cursor. """ @@ -310,13 +329,17 @@ type Client { """ before: String first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int """ Returns the last _n_ elements from the list. """ last: Int query: String - ): ClientSoftwareConnectionWithMeta! + userId: String + ): SoftwareConnectionWithMeta """ Client system email @@ -332,48 +355,60 @@ type Client { The homepage of the client """ url: String -} -""" -The connection type for Client. -""" -type ClientConnectionWithMeta { """ - A list of edges. + The number of views according to the Counter Code of Practice. """ - edges: [ClientEdge] + viewCount: Int """ - A list of nodes. + Works managed by the client """ - nodes: [Client] + works( + """ + Returns the elements in the list that come after the specified cursor. + """ + after: String - """ - Information to aid in pagination. - """ - pageInfo: PageInfo! - totalCount: Int! + """ + Returns the elements in the list that come before the specified cursor. + """ + before: String + first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int + + """ + Returns the last _n_ elements from the list. + """ + last: Int + query: String + userId: String + ): WorkConnectionWithMeta } """ -The connection type for Dataset. +The connection type for Client. """ -type ClientDatasetConnectionWithMeta { +type ClientConnectionWithMeta { """ A list of edges. """ - edges: [DatasetEdge] + edges: [ClientEdge] """ A list of nodes. """ - nodes: [Dataset] + nodes: [Client] """ Information to aid in pagination. """ pageInfo: PageInfo! - totalCount: Int! + software: [Facet!] + totalCount: Int + years: [Facet!] } """ @@ -392,45 +427,60 @@ type ClientEdge { } """ -The connection type for Dataset. +Information about client prefixes """ -type ClientPublicationConnectionWithMeta { +type ClientPrefix { """ - A list of edges. + Unique identifier for each client prefix """ - edges: [DatasetEdge] + id: ID! """ - A list of nodes. + Client prefix name """ - nodes: [Dataset] + name: String! """ - Information to aid in pagination. + The type of the item. """ - pageInfo: PageInfo! - totalCount: Int! + type: String! } """ -The connection type for Dataset. +The connection type for ClientPrefix. """ -type ClientSoftwareConnectionWithMeta { +type ClientPrefixConnectionWithMeta { """ A list of edges. """ - edges: [DatasetEdge] + edges: [ClientPrefixEdge] """ A list of nodes. """ - nodes: [Dataset] + nodes: [ClientPrefix] """ Information to aid in pagination. """ pageInfo: PageInfo! totalCount: Int! + years: [Facet!]! +} + +""" +An edge in a connection. +""" +type ClientPrefixEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of the edge. + """ + node: ClientPrefix } type Collection implements DoiItem { @@ -1313,6 +1363,7 @@ type DatasetConnectionWithMeta { publicationConnectionCount: Int! softwareConnectionCount: Int! totalCount: Int! + years: [Facet!] } """ @@ -3185,11 +3236,6 @@ type Person { query: String ): DatasetConnectionWithMeta - """ - The number of works per year. - """ - doiCount: [Facet!] - """ The number of downloads according to the Counter Code of Practice. """ @@ -3242,11 +3288,6 @@ type Person { query: String ): PublicationConnectionWithMeta - """ - The work types. - """ - resourceTypeCount: [Facet!] - """ Authored software """ @@ -3302,7 +3343,6 @@ type Person { hasCitations: Int hasDownloads: Int hasViews: Int - ids: String """ Returns the last _n_ elements from the list. @@ -3310,7 +3350,7 @@ type Person { last: Int providerId: String query: String - ): WorkConnectionWithMeta! + ): WorkConnectionWithMeta } """ @@ -3526,44 +3566,6 @@ type Prefix { id: ID! } -""" -The connection type for Prefix. -""" -type PrefixConnectionWithMeta { - """ - A list of edges. - """ - edges: [PrefixEdge] - - """ - A list of nodes. - """ - nodes: [Prefix] - - """ - Information to aid in pagination. - """ - pageInfo: PageInfo! - states: [Facet!]! - totalCount: Int! - years: [Facet!]! -} - -""" -An edge in a connection. -""" -type PrefixEdge { - """ - A cursor for use in pagination. - """ - cursor: String! - - """ - The item at the end of the edge. - """ - node: Prefix -} - """ Information about providers """ @@ -3590,13 +3592,40 @@ type Provider { query: String software: String year: String - ): ProviderClientConnectionWithMeta! + ): ClientConnectionWithMeta """ Country where the provider is located """ country: Country + """ + Authored datasets + """ + datasets( + """ + Returns the elements in the list that come after the specified cursor. + """ + after: String + + """ + Returns the elements in the list that come before the specified cursor. + """ + before: String + clientId: String + first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int + + """ + Returns the last _n_ elements from the list. + """ + last: Int + query: String + userId: String + ): DatasetConnectionWithMeta + """ Description of the provider """ @@ -3664,7 +3693,34 @@ type Provider { query: String state: String year: String - ): PrefixConnectionWithMeta! + ): ProviderPrefixConnectionWithMeta + + """ + Authored publications + """ + publications( + """ + Returns the elements in the list that come after the specified cursor. + """ + after: String + + """ + Returns the elements in the list that come before the specified cursor. + """ + before: String + clientId: String + first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int + + """ + Returns the last _n_ elements from the list. + """ + last: Int + query: String + userId: String + ): PublicationConnectionWithMeta """ Geographic region where the provider is located @@ -3676,6 +3732,33 @@ type Provider { """ rorId: String! + """ + Authored software + """ + softwares( + """ + Returns the elements in the list that come after the specified cursor. + """ + after: String + + """ + Returns the elements in the list that come before the specified cursor. + """ + before: String + clientId: String + first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int + + """ + Returns the last _n_ elements from the list. + """ + last: Int + query: String + userId: String + ): SoftwareConnectionWithMeta + """ The type of the item. """ @@ -3685,21 +3768,48 @@ type Provider { Website of the provider """ website: String + + """ + Authored works + """ + works( + """ + Returns the elements in the list that come after the specified cursor. + """ + after: String + + """ + Returns the elements in the list that come before the specified cursor. + """ + before: String + clientId: String + first: Int = 25 + hasCitations: Int + hasDownloads: Int + hasViews: Int + + """ + Returns the last _n_ elements from the list. + """ + last: Int + query: String + userId: String + ): WorkConnectionWithMeta } """ -The connection type for Client. +The connection type for Provider. """ -type ProviderClientConnectionWithMeta { +type ProviderConnectionWithMeta { """ A list of edges. """ - edges: [ClientEdge] + edges: [ProviderEdge] """ A list of nodes. """ - nodes: [Client] + nodes: [Provider] """ Information to aid in pagination. @@ -3709,30 +3819,67 @@ type ProviderClientConnectionWithMeta { } """ -The connection type for Provider. +An edge in a connection. """ -type ProviderConnectionWithMeta { +type ProviderEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of the edge. + """ + node: Provider +} + +""" +Information about provider prefixes +""" +type ProviderPrefix { + """ + Unique identifier for each provider prefix + """ + id: ID! + + """ + Provider prefix name + """ + name: String! + + """ + The type of the item. + """ + type: String! +} + +""" +The connection type for ProviderPrefix. +""" +type ProviderPrefixConnectionWithMeta { """ A list of edges. """ - edges: [ProviderEdge] + edges: [ProviderPrefixEdge] """ A list of nodes. """ - nodes: [Provider] + nodes: [ProviderPrefix] """ Information to aid in pagination. """ pageInfo: PageInfo! + states: [Facet!]! totalCount: Int! + years: [Facet!]! } """ An edge in a connection. """ -type ProviderEdge { +type ProviderPrefixEdge { """ A cursor for use in pagination. """ @@ -3741,7 +3888,7 @@ type ProviderEdge { """ The item at the end of the edge. """ - node: Provider + node: ProviderPrefix } type Publication implements DoiItem { @@ -3971,7 +4118,7 @@ type Publication implements DoiItem { } """ -The connection type for Dataset. +The connection type for Publication. """ type PublicationConnectionWithMeta { datasetConnectionCount: Int! @@ -3979,13 +4126,13 @@ type PublicationConnectionWithMeta { """ A list of edges. """ - edges: [DatasetEdge] + edges: [PublicationEdge] funderConnectionCount: Int! """ A list of nodes. """ - nodes: [Dataset] + nodes: [Publication] organizationConnectionCount: Int! """ @@ -3996,6 +4143,7 @@ type PublicationConnectionWithMeta { publicationConnectionCount: Int! softwareConnectionCount: Int! totalCount: Int! + years: [Facet!] } """ @@ -4019,6 +4167,21 @@ type PublicationDatasetConnectionWithMeta { totalCount: Int! } +""" +An edge in a connection. +""" +type PublicationEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of the edge. + """ + node: Publication +} + """ The connection type for EventData. """ @@ -4132,6 +4295,7 @@ type Query { last: Int providerId: String query: String + userId: String ): DatasetConnectionWithMeta! event(id: ID!): Event! events(first: Int = 25, query: String): [Event!]! @@ -4201,7 +4365,7 @@ type Query { ): PersonConnectionWithMeta! person(id: ID!): Person physicalObject(id: ID!): PhysicalObject! - physicalObjects(first: Int = 25, hasCitations: Int, hasDownloads: Int, hasViews: Int, query: String): [PhysicalObject!]! + physicalObjects(clientId: String, first: Int = 25, hasCitations: Int, hasDownloads: Int, hasViews: Int, providerId: String, query: String, userId: String): [PhysicalObject!]! prefix(id: ID!): Prefix! prefixes(first: Int = 25, query: String): [Prefix!]! provider(id: ID!): Provider! @@ -4246,6 +4410,7 @@ type Query { last: Int providerId: String query: String + userId: String ): PublicationConnectionWithMeta! service(id: ID!): Service! services( @@ -4291,6 +4456,7 @@ type Query { last: Int providerId: String query: String + userId: String ): SoftwareConnectionWithMeta! sound(id: ID!): Sound! sounds(first: Int = 25, query: String): [Sound!]! @@ -4335,6 +4501,7 @@ type Query { last: Int providerId: String query: String + userId: String ): WorkConnectionWithMeta! } @@ -4611,18 +4778,18 @@ type Service implements DoiItem { } """ -The connection type for Dataset. +The connection type for Service. """ type ServiceConnectionWithMeta { """ A list of edges. """ - edges: [DatasetEdge] + edges: [ServiceEdge] """ A list of nodes. """ - nodes: [Dataset] + nodes: [Service] """ Information to aid in pagination. @@ -4631,6 +4798,21 @@ type ServiceConnectionWithMeta { totalCount: Int! } +""" +An edge in a connection. +""" +type ServiceEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of the edge. + """ + node: Service +} + type Software implements DoiItem { """ Total number of citations. @@ -4883,7 +5065,7 @@ type SoftwareApplication { } """ -The connection type for Dataset. +The connection type for Software. """ type SoftwareConnectionWithMeta { datasetConnectionCount: Int! @@ -4891,13 +5073,13 @@ type SoftwareConnectionWithMeta { """ A list of edges. """ - edges: [DatasetEdge] + edges: [SoftwareEdge] funderConnectionCount: Int! """ A list of nodes. """ - nodes: [Dataset] + nodes: [Software] organizationConnectionCount: Int! """ @@ -4908,6 +5090,7 @@ type SoftwareConnectionWithMeta { publicationConnectionCount: Int! softwareConnectionCount: Int! totalCount: Int! + years: [Facet!] } """ @@ -4931,6 +5114,21 @@ type SoftwareDatasetConnectionWithMeta { totalCount: Int! } +""" +An edge in a connection. +""" +type SoftwareEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + The item at the end of the edge. + """ + node: Software +} + """ The connection type for EventData. """ @@ -5468,7 +5666,9 @@ type WorkConnectionWithMeta { Information to aid in pagination. """ pageInfo: PageInfo! + resourceTypes: [Facet!] totalCount: Int! + years: [Facet!] } """ diff --git a/app/graphql/types/base_connection.rb b/app/graphql/types/base_connection.rb index 751dd8193..9715aea22 100644 --- a/app/graphql/types/base_connection.rb +++ b/app/graphql/types/base_connection.rb @@ -7,4 +7,51 @@ def doi_from_url(url) uri.path.gsub(/^\//, "").downcase end end + + def orcid_from_url(url) + if /\A(?:(http|https):\/\/(orcid.org)\/)(.+)\z/.match?(url) + uri = Addressable::URI.parse(url) + uri.path.gsub(/^\//, "").downcase + end + end + + def prepare_args(args) + args[:user_id] ||= object.parent.try(:orcid).present? ? object.parent.orcid : nil + args[:user_id] = orcid_from_url(args[:user_id]) if args[:user_id].present? + args[:client_id] ||= object.parent.try(:client_type).present? ? object.parent.symbol.downcase : nil + args[:provider_id] ||= object.parent.try(:region).present? ? object.parent.symbol.downcase : nil + args.compact + end + + def facet_by_year(arr) + arr.map do |hsh| + { "id" => hsh["key_as_string"][0..3], + "title" => hsh["key_as_string"][0..3], + "count" => hsh["doc_count"] } + end + end + + def facet_by_key(arr) + arr.map do |hsh| + { "id" => hsh["key"], + "title" => hsh["key"].titleize, + "count" => hsh["doc_count"] } + end + end + + def facet_by_resource_type(arr) + arr.map do |hsh| + { "id" => hsh["key"].underscore.dasherize, + "title" => hsh["key"], + "count" => hsh["doc_count"] } + end + end + + def facet_by_software(arr) + arr.map do |hsh| + { "id" => hsh["key"].downcase, + "title" => hsh["key"], + "count" => hsh["doc_count"] } + end + end end diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb index 44be8abc5..4f7779306 100644 --- a/app/graphql/types/base_object.rb +++ b/app/graphql/types/base_object.rb @@ -18,4 +18,27 @@ def orcid_from_url(url) uri.path.gsub(/^\//, "").downcase end end + + def facet_by_year(arr) + arr.map do |hsh| + { "id" => hsh["key_as_string"][0..3], + "title" => hsh["key_as_string"][0..3], + "count" => hsh["doc_count"] } + end + end + + def facet_by_resource_type(arr) + arr.map do |hsh| + { "id" => hsh["key"].underscore.dasherize, + "title" => hsh["key"], + "count" => hsh["doc_count"] } + end + end + + def aggregate_count(arr) + arr.reduce(0) do |sum, hsh| + sum + hsh.dig("metric_count", "value").to_i + sum + end + end end diff --git a/app/graphql/types/client_connection_with_meta_type.rb b/app/graphql/types/client_connection_with_meta_type.rb index 16ebabc4d..eeafa1220 100644 --- a/app/graphql/types/client_connection_with_meta_type.rb +++ b/app/graphql/types/client_connection_with_meta_type.rb @@ -4,11 +4,31 @@ class ClientConnectionWithMetaType < BaseConnection edge_type(ClientEdgeType) field_class GraphQL::Cache::Field - field :total_count, Integer, null: false, cache: true + field :total_count, Integer, null: true, cache: true + field :years, [FacetType], null: true, cache: true + field :software, [FacetType], null: true, cache: true def total_count - args = object.arguments + args = prepare_args(object.arguments) - Client.query(args[:query], year: args[:year], software: args[:software], page: { number: 1, size: 0 }).results.total + response(**args).results.total + end + + def years + args = prepare_args(object.arguments) + + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end + + def software + args = prepare_args(object.arguments) + + res = response(**args) + res.results.total.positive? ? facet_by_software(res.response.aggregations.software.buckets) : nil + end + + def response(**args) + @response ||= Client.query(args[:query], provider_id: args[:provider_id], year: args[:year], software: args[:software], page: { number: 1, size: 0 }) end end diff --git a/app/graphql/types/client_dataset_connection_with_meta_type.rb b/app/graphql/types/client_dataset_connection_with_meta_type.rb deleted file mode 100644 index 91053e9e3..000000000 --- a/app/graphql/types/client_dataset_connection_with_meta_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -class ClientDatasetConnectionWithMetaType < BaseConnection - edge_type(DatasetEdgeType) - field_class GraphQL::Cache::Field - - field :total_count, Integer, null: false, cache: true - - def total_count - args = object.arguments - - Doi.query(args[:query], client_id: object.parent.uid, resource_type_id: "Dataset", state: "findable", page: { number: 1, size: 0 }).results.total - end -end diff --git a/app/graphql/types/client_prefix_connection_with_meta_type.rb b/app/graphql/types/client_prefix_connection_with_meta_type.rb new file mode 100644 index 000000000..d2e9935e7 --- /dev/null +++ b/app/graphql/types/client_prefix_connection_with_meta_type.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class ClientPrefixConnectionWithMetaType < BaseConnection + edge_type(ClientPrefixEdgeType) + field_class GraphQL::Cache::Field + + field :total_count, Integer, null: false, cache: true + field :years, [FacetType], null: false, cache: true + + def total_count + args = prepare_args(object.arguments) + + response(**args).results.total + end + + def years + args = prepare_args(object.arguments) + + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end + + def response(**args) + @response ||= ClientPrefix.query(args[:query], client_id: args[:client_id], provider_id: args[:provider_id], state: args[:state], year: args[:year], page: { number: 1, size: 0 }) + end +end diff --git a/app/graphql/types/client_prefix_edge_type.rb b/app/graphql/types/client_prefix_edge_type.rb new file mode 100644 index 000000000..89a024e03 --- /dev/null +++ b/app/graphql/types/client_prefix_edge_type.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ClientPrefixEdgeType < GraphQL::Types::Relay::BaseEdge + node_type(ClientPrefixType) +end diff --git a/app/graphql/types/client_prefix_type.rb b/app/graphql/types/client_prefix_type.rb new file mode 100644 index 000000000..88854fd07 --- /dev/null +++ b/app/graphql/types/client_prefix_type.rb @@ -0,0 +1,11 @@ +class ClientPrefixType < BaseObject + description "Information about client prefixes" + + field :id, ID, null: false, hash_key: "uid", description: "Unique identifier for each client prefix" + field :type, String, null: false, description: "The type of the item." + field :name, String, null: false, hash_key: "prefix_id", description: "Client prefix name" + + def type + "ClientPrefix" + end +end diff --git a/app/graphql/types/client_publication_connection_with_meta_type.rb b/app/graphql/types/client_publication_connection_with_meta_type.rb deleted file mode 100644 index 51ddfb514..000000000 --- a/app/graphql/types/client_publication_connection_with_meta_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -class ClientPublicationConnectionWithMetaType < BaseConnection - edge_type(DatasetEdgeType) - field_class GraphQL::Cache::Field - - field :total_count, Integer, null: false, cache: true - - def total_count - args = object.arguments - - Doi.query(args[:query], client_id: object.parent.uid, resource_type_id: "Text", state: "findable", page: { number: 1, size: 0 }).results.total - end -end diff --git a/app/graphql/types/client_software_connection_with_meta_type.rb b/app/graphql/types/client_software_connection_with_meta_type.rb deleted file mode 100644 index 78af43db2..000000000 --- a/app/graphql/types/client_software_connection_with_meta_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -class ClientSoftwareConnectionWithMetaType < BaseConnection - edge_type(DatasetEdgeType) - field_class GraphQL::Cache::Field - - field :total_count, Integer, null: false, cache: true - - def total_count - args = object.arguments - - Doi.query(args[:query], client_id: object.parent.uid, resource_type_id: "Software", state: "findable", page: { number: 1, size: 0 }).results.total - end -end diff --git a/app/graphql/types/client_type.rb b/app/graphql/types/client_type.rb index 7d125db9a..6aadff72e 100644 --- a/app/graphql/types/client_type.rb +++ b/app/graphql/types/client_type.rb @@ -12,24 +12,56 @@ class ClientType < BaseObject field :url, String, null: true, description: "The homepage of the client" field :system_email, String, null: true, description: "Client system email" field :software, String, null: true, description: "The name of the software that is used to run the repository" - field :prefixes, PrefixConnectionWithMetaType, null: false, description: "Prefixes managed by the client", connection: true do + field :view_count, Integer, null: true, description: "The number of views according to the Counter Code of Practice." + field :download_count, Integer, null: true, description: "The number of downloads according to the Counter Code of Practice." + field :citation_count, Integer, null: true, description: "The number of citations." + + field :prefixes, PrefixConnectionWithMetaType, null: true, description: "Prefixes managed by the client", connection: true do argument :query, String, required: false argument :year, String, required: false argument :first, Int, required: false, default_value: 25 end - field :datasets, ClientDatasetConnectionWithMetaType, null: false, connection: true, description: "Datasets managed by the client" do + field :datasets, DatasetConnectionWithMetaType, null: true, connection: true, description: "Datasets managed by the client" do argument :query, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false argument :first, Int, required: false, default_value: 25 end - field :publications, ClientPublicationConnectionWithMetaType, null: false, connection: true, description: "Publications managed by the client" do + field :publications, PublicationConnectionWithMetaType, null: true, connection: true, description: "Publications managed by the client" do argument :query, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false argument :first, Int, required: false, default_value: 25 end - field :software_source_codes, ClientSoftwareConnectionWithMetaType, null: false, connection: true, description: "Software managed by the client" do + field :softwares, SoftwareConnectionWithMetaType, null: true, connection: true, description: "Software managed by the client" do argument :query, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false + argument :first, Int, required: false, default_value: 25 + end + + field :works, WorkConnectionWithMetaType, null: true, connection: true, description: "Works managed by the client" do + argument :query, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false + argument :first, Int, required: false, default_value: 25 + end + + field :prefixes, ClientPrefixConnectionWithMetaType, null: true, description: "Prefixes managed by the client", connection: true do + argument :query, String, required: false + argument :state, String, required: false + argument :year, String, required: false argument :first, Int, required: false, default_value: 25 end @@ -37,22 +69,39 @@ def type "Client" end + def datasets(**args) + Doi.query(args[:query], user_id: args[:user_id].present? ? orcid_from_url(args[:user_id]) : nil, client_id: object.uid, resource_type_id: "Dataset", page: { number: 1, size: args[:first] }).results.to_a + end + + def publications(**args) + Doi.query(args[:query], user_id: args[:user_id].present? ? orcid_from_url(args[:user_id]) : nil, client_id: object.uid, resource_type_id: "Text", page: { number: 1, size: args[:first] }).results.to_a + end + + def softwares(**args) + Doi.query(args[:query], user_id: args[:user_id].present? ? orcid_from_url(args[:user_id]) : nil, client_id: object.uid, resource_type_id: "Software", page: { number: 1, size: args[:first] }).results.to_a + end + + def works(**args) + Doi.query(args[:query], user_id: args[:user_id].present? ? orcid_from_url(args[:user_id]) : nil, client_id: object.uid, page: { number: 1, size: args[:first] }).results.to_a + end + def prefixes(**args) - collection = ClientPrefix.joins(:client, :prefix).where('datacentre.symbol = ?', object.uid) - collection = collection.query(args[:query]) if args[:query].present? - collection = collection.where('YEAR(datacentre_prefixes.created_at) = ?', args[:year]) if args[:year].present? - collection + ClientPrefix.query(args[:query], client_id: object.uid, state: args[:state], year: args[:year], page: { number: 1, size: args[:first] }).results.to_a end - def datasets(**args) - Doi.query(args[:query], client_id: object.uid, resource_type_id: "Dataset", page: { number: 1, size: args[:first] }).results.to_a + def view_count + response.results.total.positive? ? aggregate_count(response.response.aggregations.views.buckets) : [] end - def publications(**args) - Doi.query(args[:query], client_id: object.uid, resource_type_id: "Text", page: { number: 1, size: args[:first] }).results.to_a + def download_count + response.results.total.positive? ? aggregate_count(response.response.aggregations.downloads.buckets) : [] + end + + def citation_count + response.results.total.positive? ? aggregate_count(response.response.aggregations.citations.buckets) : [] end - def software_source_codes(**args) - Doi.query(args[:query], client_id: object.uid, resource_type_id: "Software", page: { number: 1, size: args[:first] }).results.to_a + def response + @response ||= Doi.query(nil, client_id: object.uid, state: "findable", page: { number: 1, size: 0 }) end end diff --git a/app/graphql/types/dataset_connection_with_meta_type.rb b/app/graphql/types/dataset_connection_with_meta_type.rb index 9185bdda4..6f03929b3 100644 --- a/app/graphql/types/dataset_connection_with_meta_type.rb +++ b/app/graphql/types/dataset_connection_with_meta_type.rb @@ -5,6 +5,7 @@ class DatasetConnectionWithMetaType < BaseConnection field_class GraphQL::Cache::Field field :total_count, Integer, null: false, cache: true + field :years, [FacetType], null: true, cache: true field :dataset_connection_count, Integer, null: false, cache: true field :publication_connection_count, Integer, null: false, cache: true field :software_connection_count, Integer, null: false, cache: true @@ -13,32 +14,43 @@ class DatasetConnectionWithMetaType < BaseConnection field :organization_connection_count, Integer, null: false, cache: true def total_count - args = object.arguments + args = prepare_args(object.arguments) - Doi.query(args[:query], client_id: args[:client_id], provider_id: args[:provider_id], resource_type_id: "Dataset", state: "findable", page: { number: 1, size: 0 }).results.total + response(**args).results.total + end + + def years + args = prepare_args(object.arguments) + + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end + + def response(**args) + @response ||= Doi.query(args[:query], user_id: args[:user_id], client_id: args[:client_id], provider_id: args[:provider_id], year: args[:year], resource_type_id: "Dataset", has_citations: args[:has_citations], has_views: args[:has_views], has_downloads: args[:has_downloads], page: { number: 1, size: 0 }) end def dataset_connection_count - Event.query(nil, citation_type: "Dataset-Dataset").results.total + @dataset_connection_count ||= Event.query(nil, citation_type: "Dataset-Dataset", page: { number: 1, size: 0 }).results.total end def publication_connection_count - Event.query(nil, citation_type: "Dataset-ScholarlyArticle").results.total + @publication_connection_count ||= Event.query(nil, citation_type: "Dataset-ScholarlyArticle", page: { number: 1, size: 0 }).results.total end def software_connection_count - Event.query(nil, citation_type: "Dataset-SoftwareSourceCode").results.total + @software_connection_count ||= Event.query(nil, citation_type: "Dataset-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def person_connection_count - Event.query(nil, citation_type: "Dataset-Person").results.total + @person_connection_count ||= Event.query(nil, citation_type: "Dataset-Person", page: { number: 1, size: 0 }).results.total end def funder_connection_count - Event.query(nil, citation_type: "Dataset-Funder").results.total + @funder_connection_count ||= Event.query(nil, citation_type: "Dataset-Funder", page: { number: 1, size: 0 }).results.total end def organization_connection_count - Event.query(nil, citation_type: "Dataset-Organization").results.total + Event.query(nil, citation_type: "Dataset-Organization", page: { number: 1, size: 0 }).results.total end end diff --git a/app/graphql/types/person_connection_with_meta_type.rb b/app/graphql/types/person_connection_with_meta_type.rb index ed60b7c9f..c75291e42 100644 --- a/app/graphql/types/person_connection_with_meta_type.rb +++ b/app/graphql/types/person_connection_with_meta_type.rb @@ -17,18 +17,18 @@ def total_count end def publication_connection_count - Event.query(nil, citation_type: "Person-ScholarlyArticle").results.total + Event.query(nil, citation_type: "Person-ScholarlyArticle", page: { number: 1, size: 0 }).results.total end def dataset_connection_count - Event.query(nil, citation_type: "Dataset-Person").results.total + Event.query(nil, citation_type: "Dataset-Person", page: { number: 1, size: 0 }).results.total end def software_connection_count - Event.query(nil, citation_type: "Person-SoftwareSourceCode").results.total + Event.query(nil, citation_type: "Person-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def organization_connection_count - Event.query(nil, citation_type: "Organization-Person").results.total + Event.query(nil, citation_type: "Organization-Person", page: { number: 1, size: 0 }).results.total end end \ No newline at end of file diff --git a/app/graphql/types/person_type.rb b/app/graphql/types/person_type.rb index 8fa4b0682..04b68b1b2 100644 --- a/app/graphql/types/person_type.rb +++ b/app/graphql/types/person_type.rb @@ -8,8 +8,6 @@ class PersonType < BaseObject field :name, String, null: true, description: "The name of the person." field :given_name, String, null: true, description: "Given name. In the U.S., the first name of a Person." field :family_name, String, null: true, description: "Family name. In the U.S., the last name of an Person." - field :doi_count, [FacetType], null: true, description: "The number of works per year." - field :resource_type_count, [FacetType], null: true, description: "The work types." field :view_count, Integer, null: true, description: "The number of views according to the Counter Code of Practice." field :download_count, Integer, null: true, description: "The number of downloads according to the Counter Code of Practice." field :citation_count, Integer, null: true, description: "The number of citations." @@ -44,9 +42,8 @@ class PersonType < BaseObject argument :first, Int, required: false, default_value: 25 end - field :works, WorkConnectionWithMetaType, null: false, connection: true, max_page_size: 1000, description: "Authored works" do + field :works, WorkConnectionWithMetaType, null: true, connection: true, max_page_size: 1000, description: "Authored works" do argument :query, String, required: false - argument :ids, String, required: false argument :client_id, String, required: false argument :provider_id, String, required: false argument :has_citations, Int, required: false @@ -71,21 +68,8 @@ def softwares(query: nil, client_id: nil, provider_id: nil, has_citations: nil, Doi.query(query, user_id: orcid_from_url(object[:id]), client_id: client_id, provider_id: provider_id, has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, resource_type_id: "Software", state: "findable", page: { number: 1, size: first }).results.to_a end - def works(query: nil, ids: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) - if ids.present? - dois = ids.split(",").map { |i| doi_from_url(i) } - ElasticsearchLoader.for(Doi).load_many(dois) - else - Doi.query(query, user_id: orcid_from_url(object[:id]), client_id: client_id, provider_id: provider_id, resource_type_id: "Dataset", state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a - end - end - - def doi_count - response.results.total.positive? ? facet_by_year(response.aggregations.years.buckets) : [] - end - - def resource_type_count - response.results.total.positive? ? facet_by_resource_type(response.response.aggregations.resource_types.buckets) : [] + def works(query: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: orcid_from_url(object[:id]), client_id: client_id, provider_id: provider_id, resource_type_id: "Dataset", state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a end def view_count @@ -103,27 +87,4 @@ def citation_count def response @response ||= Doi.query(nil, user_id: orcid_from_url(object[:id]), state: "findable", page: { number: 1, size: 0 }) end - - def facet_by_year(arr) - arr.map do |hsh| - { "id" => hsh["key_as_string"][0..3], - "title" => hsh["key_as_string"][0..3], - "count" => hsh["doc_count"] } - end - end - - def facet_by_resource_type(arr) - arr.map do |hsh| - { "id" => hsh["key"].underscore.dasherize, - "title" => hsh["key"], - "count" => hsh["doc_count"] } - end - end - - def aggregate_count(arr) - arr.reduce(0) do |sum, hsh| - sum << hsh.dig("metric_count", "value").to_i - sum - end - end end diff --git a/app/graphql/types/prefix_connection_with_meta_type.rb b/app/graphql/types/prefix_connection_with_meta_type.rb index 814be7bdf..ffafb13d9 100644 --- a/app/graphql/types/prefix_connection_with_meta_type.rb +++ b/app/graphql/types/prefix_connection_with_meta_type.rb @@ -9,65 +9,26 @@ class PrefixConnectionWithMetaType < BaseConnection field :years, [FacetType], null: false, cache: true def total_count - object.nodes.size + args = prepare_args(object.arguments) + + response(**args).results.total end def states - args = self.object.arguments + args = prepare_args(object.arguments) - if object.parent._index == "providers" - collection = ProviderPrefix.joins(:provider, :prefix).where('allocator.symbol = ?', object.parent.symbol) - collection = collection.where('YEAR(allocator_prefixes.created_at) = ?', args[:year]) if args[:year].present? - collection = collection.state(args[:state].underscore.dasherize) if args[:state].present? - collection = collection.query(args[:query]) if args[:query].present? - - if args[:state].present? - [{ id: args[:state], - title: args[:state].underscore.humanize, - count: collection.state(args[:state].underscore.dasherize).count }] - else - [{ id: "withoutRepository", - title: "Without repository", - count: collection.state("without-client").count }, - { id: "withRepository", - title: "With repository", - count: collection.state("with-client").count }] - end - else - [] - end + res = response(**args) + res.results.total.positive? ? facet_by_key(res.response.aggregations.states.buckets) : nil end def years - args = self.object.arguments + args = prepare_args(object.arguments) - if object.parent._index == "providers" - collection = ProviderPrefix.joins(:provider, :prefix).where('allocator.symbol = ?', object.parent.symbol) - collection = collection.state(args[:state].underscore.dasherize) if args[:state].present? - collection = collection.query(args[:query]) if args[:query].present? + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end - if args[:year].present? - [{ id: args[:year], - title: args[:year], - count: collection.where('YEAR(allocator_prefixes.created_at) = ?', args[:year]).count }] - else - years = collection.where.not(prefixes: nil).order("YEAR(allocator_prefixes.created_at) DESC").group("YEAR(allocator_prefixes.created_at)").count - years.map { |k,v| { id: k.to_s, title: k.to_s, count: v } } - end - elsif object.parent._index == "clients" - collection = ClientPrefix.joins(:client, :prefix).where('datacentre.symbol = ?', object.parent.symbol) - collection = collection.query(args[:query]) if args[:query].present? - - if args[:year].present? - [{ id: args[:year], - title: args[:year], - count: collection.where('YEAR(datacentre_prefixes.created_at) = ?', args[:year]).count }] - else - years = collection.where.not(prefixes: nil).order("YEAR(datacentre_prefixes.created_at) DESC").group("YEAR(datacentre_prefixes.created_at)").count - years.map { |k,v| { id: k.to_s, title: k.to_s, count: v } } - end - else - {} - end + def response(**args) + @response ||= Prefix.query(args[:query], provider_id: args[:provider_id], state: args[:state], year: args[:year], page: { number: 1, size: 0 }) end end diff --git a/app/graphql/types/prefix_type.rb b/app/graphql/types/prefix_type.rb index 6932a0dea..221f48c78 100644 --- a/app/graphql/types/prefix_type.rb +++ b/app/graphql/types/prefix_type.rb @@ -3,30 +3,9 @@ class PrefixType < BaseObject description "Information about prefixes" - field :id, ID, null: false, hash_key: "prefix.id", description: "Unique identifier for each prefix" - # field :providers, [ProviderType], null: false do - # argument :query, String, required: false - # argument :first, Int, required: false, default_value: 25 - # end + field :id, ID, null: false, hash_key: "uid", description: "Unique identifier for each prefix" - # field :clients, [ClientType], null: false do - # argument :query, String, required: false - # argument :first, Int, required: false, default_value: 25 - # end - - def id - object.class.name == "Prefix" ? object.prefix : object.prefix.uid - end - - def providers(**args) - collection = object.providers - collection = collection.query(args[:query]) if args[:query].present? - collection.page(1).per(args[:first]) - end - - def clients(**args) - collection = object.clients - collection = collection.query(args[:query]) if args[:query].present? - collection.page(1).per(args[:first]) + def type + "Prefix" end end diff --git a/app/graphql/types/provider_client_connection_with_meta_type.rb b/app/graphql/types/provider_client_connection_with_meta_type.rb deleted file mode 100644 index fd8ebb1db..000000000 --- a/app/graphql/types/provider_client_connection_with_meta_type.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -class ProviderClientConnectionWithMetaType < BaseConnection - edge_type(ClientEdgeType) - field_class GraphQL::Cache::Field - - field :total_count, Integer, null: false, cache: true - - def total_count - args = object.arguments - - Client.query(args[:query], provider_id: object.parent.uid, year: args[:year], software: args[:software], page: { number: 1, size: 0 }).results.total - end -end diff --git a/app/graphql/types/provider_prefix_connection_with_meta_type.rb b/app/graphql/types/provider_prefix_connection_with_meta_type.rb new file mode 100644 index 000000000..acc200ffa --- /dev/null +++ b/app/graphql/types/provider_prefix_connection_with_meta_type.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class ProviderPrefixConnectionWithMetaType < BaseConnection + edge_type(ProviderPrefixEdgeType) + field_class GraphQL::Cache::Field + + field :total_count, Integer, null: false, cache: true + field :states, [FacetType], null: false, cache: true + field :years, [FacetType], null: false, cache: true + + def total_count + args = object.arguments + args[:provider_id] ||= object.parent.try(:role_name).present? ? object.parent.symbol.downcase : nil + + response(**args).results.total + end + + def states + args = object.arguments + args[:provider_id] ||= object.parent.try(:role_name).present? ? object.parent.symbol.downcase : nil + + res = response(**args) + res.results.total.positive? ? facet_by_key(res.response.aggregations.states.buckets) : nil + end + + def years + args = object.arguments + args[:provider_id] ||= object.parent.try(:role_name).present? ? object.parent.symbol.downcase : nil + + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end + + def response(**args) + @response ||= ProviderPrefix.query(args[:query], provider_id: args[:provider_id], state: args[:state], year: args[:year], page: { number: 1, size: 0 }) + end +end diff --git a/app/graphql/types/provider_prefix_edge_type.rb b/app/graphql/types/provider_prefix_edge_type.rb new file mode 100644 index 000000000..10ed431ed --- /dev/null +++ b/app/graphql/types/provider_prefix_edge_type.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ProviderPrefixEdgeType < GraphQL::Types::Relay::BaseEdge + node_type(ProviderPrefixType) +end diff --git a/app/graphql/types/provider_prefix_type.rb b/app/graphql/types/provider_prefix_type.rb new file mode 100644 index 000000000..ef79dd890 --- /dev/null +++ b/app/graphql/types/provider_prefix_type.rb @@ -0,0 +1,11 @@ +class ProviderPrefixType < BaseObject + description "Information about provider prefixes" + + field :id, ID, null: false, hash_key: "uid", description: "Unique identifier for each provider prefix" + field :type, String, null: false, description: "The type of the item." + field :name, String, null: false, hash_key: "prefix_id", description: "Provider prefix name" + + def type + "ProviderPrefix" + end +end diff --git a/app/graphql/types/provider_type.rb b/app/graphql/types/provider_type.rb index eba303fb7..cb24dbbe6 100644 --- a/app/graphql/types/provider_type.rb +++ b/app/graphql/types/provider_type.rb @@ -17,14 +17,54 @@ class ProviderType < BaseObject field :organization_type, String, null: true, description: "Type of organization" field :focus_area, String, null: true, description: "Field of science covered by provider" field :joined, String, null: true, description: "Date provider joined DataCite" - field :prefixes, PrefixConnectionWithMetaType, null: false, description: "Prefixes managed by the provider", connection: true do + field :datasets, DatasetConnectionWithMetaType, null: true, connection: true, max_page_size: 1000, description: "Authored datasets" do + argument :query, String, required: false + argument :client_id, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false + argument :first, Int, required: false, default_value: 25 + end + + field :publications, PublicationConnectionWithMetaType, null: true, connection: true, max_page_size: 1000, description: "Authored publications" do + argument :query, String, required: false + argument :client_id, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false + argument :first, Int, required: false, default_value: 25 + end + + field :softwares, SoftwareConnectionWithMetaType, null: true, connection: true, max_page_size: 1000, description: "Authored software" do + argument :query, String, required: false + argument :client_id, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false + argument :first, Int, required: false, default_value: 25 + end + + field :works, WorkConnectionWithMetaType, null: true, connection: true, max_page_size: 1000, description: "Authored works" do + argument :query, String, required: false + argument :client_id, String, required: false + argument :user_id, String, required: false + argument :has_citations, Int, required: false + argument :has_views, Int, required: false + argument :has_downloads, Int, required: false + argument :first, Int, required: false, default_value: 25 + end + + field :prefixes, ProviderPrefixConnectionWithMetaType, null: true, description: "Prefixes managed by the provider", connection: true do argument :query, String, required: false argument :state, String, required: false argument :year, String, required: false argument :first, Int, required: false, default_value: 25 end - field :clients, ProviderClientConnectionWithMetaType, null: false, description: "Clients associated with the provider", connection: true do + field :clients, ClientConnectionWithMetaType, null: true, description: "Clients associated with the provider", connection: true do argument :query, String, required: false argument :year, String, required: false argument :software, String, required: false @@ -43,12 +83,24 @@ def country }.compact end + def publications(query: nil, client_id: nil, user_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: object.uid, has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, resource_type_id: "Text", state: "findable", page: { number: 1, size: first }).results.to_a + end + + def datasets(query: nil, client_id: nil, user_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: object.uid, resource_type_id: "Dataset", state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a + end + + def softwares(query: nil, client_id: nil, user_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: object.uid, has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, resource_type_id: "Software", state: "findable", page: { number: 1, size: first }).results.to_a + end + + def works(query: nil, client_id: nil, user_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: object.uid, state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a + end + def prefixes(**args) - collection = ProviderPrefix.joins(:provider, :prefix).where('allocator.symbol = ?', object.uid) - collection = collection.state(args[:state].underscore.dasherize) if args[:state].present? - collection = collection.query(args[:query]) if args[:query].present? - collection = collection.where('YEAR(allocator_prefixes.created_at) = ?', args[:year]) if args[:year].present? - collection + ProviderPrefix.query(args[:query], provider_id: object.uid, state: args[:state], year: args[:year], page: { number: 1, size: args[:first] }).results.to_a end def clients(**args) diff --git a/app/graphql/types/publication_connection_with_meta_type.rb b/app/graphql/types/publication_connection_with_meta_type.rb index 639411104..ebcaf39d6 100644 --- a/app/graphql/types/publication_connection_with_meta_type.rb +++ b/app/graphql/types/publication_connection_with_meta_type.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true class PublicationConnectionWithMetaType < BaseConnection - edge_type(DatasetEdgeType) + edge_type(PublicationEdgeType) field_class GraphQL::Cache::Field field :total_count, Integer, null: false, cache: true + field :years, [FacetType], null: true, cache: true field :publication_connection_count, Integer, null: false, cache: true field :dataset_connection_count, Integer, null: false, cache: true field :software_connection_count, Integer, null: false, cache: true @@ -13,32 +14,43 @@ class PublicationConnectionWithMetaType < BaseConnection field :organization_connection_count, Integer, null: false, cache: true def total_count - args = object.arguments + args = prepare_args(object.arguments) + + response(**args).results.total + end + + def years + args = prepare_args(object.arguments) + + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end - Doi.query(args[:query], client_id: args[:client_id], provider_id: args[:provider_id], resource_type_id: "Text", state: "findable", page: { number: 1, size: 0 }).results.total + def response(**args) + @response ||= Doi.query(args[:query], user_id: args[:user_id], client_id: args[:client_id], provider_id: args[:provider_id], year: args[:year], resource_type_id: "Text", has_citations: args[:has_citations], has_views: args[:has_views], has_downloads: args[:has_downloads], page: { number: 1, size: 0 }) end def publication_connection_count - Event.query(nil, citation_type: "ScholarlyArticle-ScholarlyArticle").results.total + @publication_connection_count ||= Event.query(nil, citation_type: "ScholarlyArticle-ScholarlyArticle", page: { number: 1, size: 0 }).results.total end def dataset_connection_count - Event.query(nil, citation_type: "Dataset-ScholarlyArticle").results.total + @dataset_connection_count ||= Event.query(nil, citation_type: "Dataset-ScholarlyArticle", page: { number: 1, size: 0 }).results.total end def software_connection_count - Event.query(nil, citation_type: "ScholarlyArticle-SoftwareSourceCode").results.total + @software_connection_count ||= Event.query(nil, citation_type: "ScholarlyArticle-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def person_connection_count - Event.query(nil, citation_type: "Person-ScholarlyArticle").results.total + @person_connection_count ||= Event.query(nil, citation_type: "Person-ScholarlyArticle", page: { number: 1, size: 0 }).results.total end def funder_connection_count - Event.query(nil, citation_type: "Funder-ScholarlyArticle").results.total + @funder_connection_count ||= Event.query(nil, citation_type: "Funder-ScholarlyArticle", page: { number: 1, size: 0 }).results.total end def organization_connection_count - Event.query(nil, citation_type: "Organization-ScholarlyArticle").results.total + @organization_connection_count ||= Event.query(nil, citation_type: "Organization-ScholarlyArticle", page: { number: 1, size: 0 }).results.total end end diff --git a/app/graphql/types/publication_edge_type.rb b/app/graphql/types/publication_edge_type.rb new file mode 100644 index 000000000..07fe63ee6 --- /dev/null +++ b/app/graphql/types/publication_edge_type.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class PublicationEdgeType < GraphQL::Types::Relay::BaseEdge + node_type(PublicationType) +end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 36247a93d..282d30700 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -17,7 +17,7 @@ def providers(query: nil, year: nil, first: nil) end def provider(id:) - ElasticsearchLoader.for(Provider).load(id) + Provider.unscoped.where("allocator.role_name IN ('ROLE_FOR_PROFIT_PROVIDER', 'ROLE_CONTRACTUAL_PROVIDER', 'ROLE_CONSORTIUM' , 'ROLE_CONSORTIUM_ORGANIZATION', 'ROLE_ALLOCATOR', 'ROLE_ADMIN', 'ROLE_MEMBER', 'ROLE_REGISTRATION_AGENCY')").where(deleted_at: nil).where(symbol: id).first end field :clients, ClientConnectionWithMetaType, null: false, connection: true, max_page_size: 1000 do @@ -36,7 +36,7 @@ def clients(query: nil, year: nil, software: nil, first: nil) end def client(id:) - ElasticsearchLoader.for(Client).load(id) + Client.where(symbol: id).where(deleted_at: nil).first end field :prefixes, [PrefixType], null: false do @@ -146,17 +146,18 @@ def people(query: nil, first: nil) field :works, WorkConnectionWithMetaType, null: false, connection: true, max_page_size: 1000 do argument :query, String, required: false argument :ids, String, required: false + argument :user_id, String, required: false argument :client_id, String, required: false argument :provider_id, String, required: false argument :first, Int, required: false, default_value: 25 end - def works(query: nil, ids: nil, client_id: nil, provider_id: nil, first: nil) + def works(query: nil, ids: nil, user_id: nil, client_id: nil, provider_id: nil, first: nil) if ids.present? dois = ids.split(",").map { |i| doi_from_url(i) } ElasticsearchLoader.for(Doi).load_many(dois) else - Doi.query(query, client_id: client_id, provider_id: provider_id, state: "findable", page: { number: 1, size: first }).results.to_a + Doi.query(query, user_id: user_id, client_id: client_id, provider_id: provider_id, state: "findable", page: { number: 1, size: first }).results.to_a end end @@ -170,6 +171,7 @@ def work(id:) field :datasets, DatasetConnectionWithMetaType, null: false, connection: true, max_page_size: 1000 do argument :query, String, required: false + argument :user_id, String, required: false argument :client_id, String, required: false argument :provider_id, String, required: false argument :has_citations, Int, required: false @@ -178,8 +180,8 @@ def work(id:) argument :first, Int, required: false, default_value: 25 end - def datasets(query: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) - Doi.query(query, client_id: client_id, provider_id: provider_id, resource_type_id: "Dataset", state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a + def datasets(query: nil, user_id: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: provider_id, resource_type_id: "Dataset", state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a end field :dataset, DatasetType, null: false do @@ -192,6 +194,7 @@ def dataset(id:) field :publications, PublicationConnectionWithMetaType, null: false, connection: true, max_page_size: 1000 do argument :query, String, required: false + argument :user_id, String, required: false argument :client_id, String, required: false argument :provider_id, String, required: false argument :has_citations, Int, required: false @@ -200,8 +203,8 @@ def dataset(id:) argument :first, Int, required: false, default_value: 25 end - def publications(query: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) - Doi.query(query, client_id: client_id, provider_id: provider_id, has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, resource_type_id: "Text", state: "findable", page: { number: 1, size: first }).results.to_a + def publications(query: nil, user_id: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: provider_id, has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, resource_type_id: "Text", state: "findable", page: { number: 1, size: first }).results.to_a end field :publication, PublicationType, null: false do @@ -339,14 +342,17 @@ def model(id:) field :physical_objects, [PhysicalObjectType], null: false do argument :query, String, required: false + argument :user_id, String, required: false + argument :client_id, String, required: false + argument :provider_id, String, required: false argument :has_citations, Int, required: false argument :has_views, Int, required: false argument :has_downloads, Int, required: false argument :first, Int, required: false, default_value: 25 end - def physical_objects(query: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) - Doi.query(query, resource_type_id: "PhysicalObject", state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a + def physical_objects(query: nil, user_id: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: provider_id, resource_type_id: "PhysicalObject", state: "findable", has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, page: { number: 1, size: first }).results.to_a end field :physical_object, PhysicalObjectType, null: false do @@ -378,6 +384,7 @@ def service(id:) field :softwares, SoftwareConnectionWithMetaType, null: false, connection: true, max_page_size: 1000 do argument :query, String, required: false + argument :user_id, String, required: false argument :client_id, String, required: false argument :provider_id, String, required: false argument :has_citations, Int, required: false @@ -386,8 +393,8 @@ def service(id:) argument :first, Int, required: false, default_value: 25 end - def softwares(query: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) - Doi.query(query, client_id: client_id, provider_id: provider_id, has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, resource_type_id: "Software", state: "findable", page: { number: 1, size: first }).results.to_a + def softwares(query: nil, user_id: nil, client_id: nil, provider_id: nil, has_citations: nil, has_views: nil, has_downloads: nil, first: nil) + Doi.query(query, user_id: user_id.present? ? orcid_from_url(user_id) : nil, client_id: client_id, provider_id: provider_id, has_citations: has_citations, has_views: has_views, has_downloads: has_downloads, resource_type_id: "Software", state: "findable", page: { number: 1, size: first }).results.to_a end field :software, SoftwareType, null: false do diff --git a/app/graphql/types/service_connection_with_meta_type.rb b/app/graphql/types/service_connection_with_meta_type.rb index f50587af9..51ab5cf8b 100644 --- a/app/graphql/types/service_connection_with_meta_type.rb +++ b/app/graphql/types/service_connection_with_meta_type.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class ServiceConnectionWithMetaType < BaseConnection - edge_type(DatasetEdgeType) + edge_type(ServiceEdgeType) field_class GraphQL::Cache::Field field :total_count, Integer, null: false, cache: true diff --git a/app/graphql/types/service_edge_type.rb b/app/graphql/types/service_edge_type.rb new file mode 100644 index 000000000..6b3e826b0 --- /dev/null +++ b/app/graphql/types/service_edge_type.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ServiceEdgeType < GraphQL::Types::Relay::BaseEdge + node_type(ServiceType) +end diff --git a/app/graphql/types/software_connection_with_meta_type.rb b/app/graphql/types/software_connection_with_meta_type.rb index ac5025128..670b57b20 100644 --- a/app/graphql/types/software_connection_with_meta_type.rb +++ b/app/graphql/types/software_connection_with_meta_type.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true class SoftwareConnectionWithMetaType < BaseConnection - edge_type(DatasetEdgeType) + edge_type(SoftwareEdgeType) field_class GraphQL::Cache::Field field :total_count, Integer, null: false, cache: true + field :years, [FacetType], null: true, cache: true field :software_connection_count, Integer, null: false, cache: true field :publication_connection_count, Integer, null: false, cache: true field :dataset_connection_count, Integer, null: false, cache: true @@ -14,31 +15,46 @@ class SoftwareConnectionWithMetaType < BaseConnection def total_count args = object.arguments + args[:user_id] ||= object.parent.try(:orcid).present? ? orcid_from_url(object.parent.orcid) : nil + args[:client_id] ||= object.parent.try(:client_type).present? ? object.parent.symbol.downcase : nil + args[:provider_id] ||= object.parent.try(:role_name).present? ? object.parent.symbol.downcase : nil - Doi.query(args[:query], client_id: args[:client_id], provider_id: args[:provider_id], resource_type_id: "Software", state: "findable", page: { number: 1, size: 0 }).results.total + response(**args).results.total + end + + def years + args = object.arguments + args[:provider_id] ||= object.parent.try(:role_name).present? ? object.parent.symbol.downcase : nil + + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end + + def response(**args) + @response ||= Doi.query(args[:query], user_id: args[:user_id], client_id: args[:client_id], provider_id: args[:provider_id], year: args[:year], resource_type_id: "Software", has_citations: args[:has_citations], has_views: args[:has_views], has_downloads: args[:has_downloads], page: { number: 1, size: 0 }) end def software_connection_count - Event.query(nil, citation_type: "SoftwareSourceCode-SoftwareSourceCode").results.total + Event.query(nil, citation_type: "SoftwareSourceCode-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def publication_connection_count - Event.query(nil, citation_type: "ScholarlyArticle-SoftwareSourceCode").results.total + Event.query(nil, citation_type: "ScholarlyArticle-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def dataset_connection_count - Event.query(nil, citation_type: "Dataset-SoftwareSourceCode").results.total + Event.query(nil, citation_type: "Dataset-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def person_connection_count - Event.query(nil, citation_type: "Person-SoftwareSourceCode").results.total + Event.query(nil, citation_type: "Person-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def funder_connection_count - Event.query(nil, citation_type: "Funder-SoftwareSourceCode").results.total + Event.query(nil, citation_type: "Funder-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end def organization_connection_count - Event.query(nil, citation_type: "Organization-SoftwareSourceCode").results.total + Event.query(nil, citation_type: "Organization-SoftwareSourceCode", page: { number: 1, size: 0 }).results.total end end diff --git a/app/graphql/types/software_edge_type.rb b/app/graphql/types/software_edge_type.rb new file mode 100644 index 000000000..9c41c4da0 --- /dev/null +++ b/app/graphql/types/software_edge_type.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class SoftwareEdgeType < GraphQL::Types::Relay::BaseEdge + node_type(SoftwareType) +end diff --git a/app/graphql/types/work_connection_with_meta_type.rb b/app/graphql/types/work_connection_with_meta_type.rb index be6fa027b..bdae52b96 100644 --- a/app/graphql/types/work_connection_with_meta_type.rb +++ b/app/graphql/types/work_connection_with_meta_type.rb @@ -5,10 +5,30 @@ class WorkConnectionWithMetaType < BaseConnection field_class GraphQL::Cache::Field field :total_count, Integer, null: false, cache: true + field :years, [FacetType], null: true, cache: true + field :resource_types, [FacetType], null: true, cache: true def total_count - args = object.arguments + args = prepare_args(object.arguments) - Doi.query(args[:query], client_id: args[:client_id], provider_id: args[:provider_id], state: "findable", page: { number: 1, size: 0 }).results.total + response(**args).results.total + end + + def years + args = prepare_args(object.arguments) + + res = response(**args) + res.results.total.positive? ? facet_by_year(res.response.aggregations.years.buckets) : nil + end + + def resource_types + args = prepare_args(object.arguments) + + res = response(**args) + res.results.total.positive? ? facet_by_resource_type(res.response.aggregations.resource_types.buckets) : nil + end + + def response(**args) + @response ||= Doi.query(args[:query], user_id: args[:user_id], client_id: args[:client_id], provider_id: args[:provider_id], year: args[:year], resource_type_id: args[:resource_type_id], has_citations: args[:has_citations], has_views: args[:has_views], has_downloads: args[:has_downloads], page: { number: 1, size: 0 }) end end diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb deleted file mode 100644 index 3b17fbf16..000000000 --- a/config/initializers/kaminari_config.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -Kaminari.configure do |config| - config.default_per_page = 25 - config.max_per_page = 1000 -end - -Kaminari::Hooks.init if defined?(Kaminari::Hooks) -Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari diff --git a/spec/factories/default.rb b/spec/factories/default.rb index 0826595ef..94ae9b95b 100644 --- a/spec/factories/default.rb +++ b/spec/factories/default.rb @@ -248,6 +248,7 @@ factory :provider do system_email { "josiah@example.org" } sequence(:symbol, 'A') { |n| "TEST#{n}" } + role_name { "ROLE_ALLOCATOR" } globus_uuid { "53d8d984-450d-4b1d-970b-67faff28db1c" } name { "My provider" } display_name { "My provider" } diff --git a/spec/fixtures/vcr_cassettes/QueryType/query_person/returns_person_information.yml b/spec/fixtures/vcr_cassettes/QueryType/query_person/returns_person_information.yml index cdd808bc4..b31ef6395 100644 --- a/spec/fixtures/vcr_cassettes/QueryType/query_person/returns_person_information.yml +++ b/spec/fixtures/vcr_cassettes/QueryType/query_person/returns_person_information.yml @@ -2,7 +2,7 @@ http_interactions: - request: method: get - uri: https://api.datacite.org/users/0000-0003-1419-2405 + uri: https://api.datacite.org/users/0000-0003-3484-6875 body: encoding: US-ASCII string: '' @@ -19,7 +19,7 @@ http_interactions: message: OK headers: Date: - - Sat, 28 Mar 2020 06:54:58 GMT + - Sat, 28 Mar 2020 13:27:17 GMT Content-Type: - application/json; charset=utf-8 Connection: @@ -41,15 +41,15 @@ http_interactions: X-Xss-Protection: - 1; mode=block X-Request-Id: - - 2b166c3f-08ed-4afe-8656-b20333ef9505 + - f6a741d8-222d-4114-91ce-b7ec28d74da5 X-Download-Options: - noopen Etag: - - W/"94b43ec3d1b2409c091752e20a5e1599" + - W/"87c6397c4485081a1b68ed8b10f5fd7a" X-Frame-Options: - SAMEORIGIN X-Runtime: - - '0.771127' + - '2.396820' X-Content-Type-Options: - nosniff X-Powered-By: @@ -59,7 +59,7 @@ http_interactions: body: encoding: ASCII-8BIT string: !binary |- - H4sIAML0fl4AA6yUTYvbMBCG/0rROU4s+SvxbemysIf20pxaSlFsORHYlpFGSZfF/71S7DgS24AKNRg8r5/RjF6P9Y5qChSV74jXqESxuSJzJxFO8S4iaZyhFYK3gZmXWjGpTEgBJD9oYMrmHfmZ9V9pZ4kvVALvDdLQjrdvs/rC+p5Jo/Yu9WmRhayuxU8Agyo3m2u8FvK4+Xs7Rw4nfXASJmFdiW7TNbdVpWjZq11WAW2aX7Turp1x9VSBaRmVIDVboUoyCsxyJMZ5hHFEij0hZZyUab42tb+bJD3UC0RMR6af7Z7gMtuVCZ6g0VRkLQUuenXig7VmNFrHJndrwY30Y7bZlCLWVw4tu4eV0D2gkoyrO5b4WPIAS30sfYBlPpY9wHIfy+9YunW5wucKZ7nE5bY+t71zSepyO5/bOXVjhyOxx13DmcPx+HOFBn1ouTrZDxbkeBrmePF/HS/CLCdpoOU40HIcZnlS/IvlkimhZcX25qhwBh3Yb3Ay91N4y3S2RnXNxZkrTVuHf/LUW1q+ZNmzSzG3wvOi3OhsoZVo4EIlc/Bvd+nDLFSibVllf2gn4bMrfvjgvKNHd/nXOV5A49SZs4t1yDzW4tK3gtZzWHGYzg9vbB9PEA4boCxsfkLHJ2x6zFbH8Q8AAAD//wMANKWCol0GAAA= + H4sIALVQf14AA6yTb2vbMBDGv0rRa9ux5fxx9G6sMNrB3iyvNsZQ5EuiTraMdGrWFX/3SbGJZdpCYTMYdI9/9+juZD2TmiMn7JnImjCS+yf1b5mWy2qZrqvNiiQEnzrwH50FY33IEY3cOwQb8o7yEdovvPFE65RKyIE3Uj3FSntZk8/ZzX1284mbP9y7aCMuW54QO8sWi0ucaXNcvF7EUeLJ7aOEQciEbha/Ho6jq9EK7oKtRX44/OR1I1svS/tBoC+UMDQOEiIMcITA0bxYp3mV5sWuWDO6YmWV+b2/+STX1VeI+orKtMh3tGC0YmU+QL3fERRHqVt7kl0YSO+1BoaZ1lp66fs43LBVmKZEBVMotGuRsGWfTNhmjm0mrIyxao5Vb7ht59h2wmiE0XyGXcIRK/ofCencXkl7CvOIGlrNvVdvVPrPfdP39U3/f98GrHZGwM5fgugwEX5jlLgbwjFxe/UXWikQ4f+I4I+x+KKkcCEtxOa3V+UFbPUBz9xARH+dpLiPRwnnUL9f1vrcKs3rMRQShz/4nSfr7fr+LwAAAP//AwDCYjxKOQQAAA== http_version: null - recorded_at: Sat, 28 Mar 2020 06:54:58 GMT + recorded_at: Sat, 28 Mar 2020 13:27:17 GMT recorded_with: VCR 5.1.0 diff --git a/spec/graphql/types/client_type_spec.rb b/spec/graphql/types/client_type_spec.rb index 679b8b7bd..69b20bf39 100644 --- a/spec/graphql/types/client_type_spec.rb +++ b/spec/graphql/types/client_type_spec.rb @@ -9,6 +9,9 @@ it { is_expected.to have_field(:name).of_type("String!") } it { is_expected.to have_field(:alternateName).of_type("String") } it { is_expected.to have_field(:description).of_type("String") } - it { is_expected.to have_field(:datasets).of_type("ClientDatasetConnectionWithMeta!") } + it { is_expected.to have_field(:datasets).of_type("DatasetConnectionWithMeta") } + it { is_expected.to have_field(:publications).of_type("PublicationConnectionWithMeta") } + it { is_expected.to have_field(:softwares).of_type("SoftwareConnectionWithMeta") } + it { is_expected.to have_field(:works).of_type("WorkConnectionWithMeta") } end end diff --git a/spec/graphql/types/person_type_spec.rb b/spec/graphql/types/person_type_spec.rb index 36feaccb4..6a3df94e8 100644 --- a/spec/graphql/types/person_type_spec.rb +++ b/spec/graphql/types/person_type_spec.rb @@ -9,13 +9,12 @@ it { is_expected.to have_field(:name).of_type("String") } it { is_expected.to have_field(:givenName).of_type("String") } it { is_expected.to have_field(:familyName).of_type("String") } - it { is_expected.to have_field(:doiCount).of_type("[Facet!]") } - it { is_expected.to have_field(:resourceTypeCount).of_type("[Facet!]") } it { is_expected.to have_field(:citationCount).of_type("Int") } it { is_expected.to have_field(:viewCount).of_type("Int") } it { is_expected.to have_field(:downloadCount).of_type("Int") } it { is_expected.to have_field(:datasets).of_type("DatasetConnectionWithMeta") } it { is_expected.to have_field(:publications).of_type("PublicationConnectionWithMeta") } it { is_expected.to have_field(:softwares).of_type("SoftwareConnectionWithMeta") } + it { is_expected.to have_field(:works).of_type("WorkConnectionWithMeta") } end end diff --git a/spec/graphql/types/provider_type_spec.rb b/spec/graphql/types/provider_type_spec.rb index dcc7c5fe1..2322cf816 100644 --- a/spec/graphql/types/provider_type_spec.rb +++ b/spec/graphql/types/provider_type_spec.rb @@ -9,6 +9,11 @@ it { is_expected.to have_field(:name).of_type("String!") } it { is_expected.to have_field(:displayName).of_type("String") } it { is_expected.to have_field(:description).of_type("String") } - it { is_expected.to have_field(:clients).of_type("ProviderClientConnectionWithMeta!") } + it { is_expected.to have_field(:clients).of_type("ClientConnectionWithMeta") } + it { is_expected.to have_field(:prefixes).of_type("ProviderPrefixConnectionWithMeta") } + it { is_expected.to have_field(:datasets).of_type("DatasetConnectionWithMeta") } + it { is_expected.to have_field(:publications).of_type("PublicationConnectionWithMeta") } + it { is_expected.to have_field(:softwares).of_type("SoftwareConnectionWithMeta") } + it { is_expected.to have_field(:works).of_type("WorkConnectionWithMeta") } end end diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb index 2ffcdb003..e6417f7be 100644 --- a/spec/graphql/types/query_type_spec.rb +++ b/spec/graphql/types/query_type_spec.rb @@ -12,6 +12,277 @@ it { is_expected.to have_field(:services).of_type("ServiceConnectionWithMeta!") } end + describe "query providers", elasticsearch: true do + let!(:providers) { create_list(:provider, 3) } + + before do + Provider.import + sleep 1 + end + + let(:query) do + %(query { + providers { + totalCount + nodes { + id + name + } + } + }) + end + + it "returns all providers" do + response = LupoSchema.execute(query).as_json + + expect(response.dig("data", "providers", "totalCount")).to eq(3) + expect(response.dig("data", "providers", "nodes").length).to eq(3) + expect(response.dig("data", "providers", "nodes", 0, "id")).to eq(providers.first.uid) + end + end + + describe "find provider", elasticsearch: true do + let(:provider) { create(:provider, symbol: "TESTC") } + let(:client) { create(:client, provider: provider, software: "dataverse") } + let!(:doi) { create(:doi, client: client, aasm_state: "findable") } + let(:prefix) { create(:prefix) } + let!(:provider_prefixes) { create_list(:provider_prefix, 3, provider: provider) } + + before do + Provider.import + Client.import + Doi.import + Prefix.import + ProviderPrefix.import + sleep 2 + end + + let(:query) do + %(query { + provider(id: "testc") { + id + name + country { + name + } + clients { + totalCount + years { + id + count + } + software { + id + count + } + nodes { + id + name + software + datasets { + totalCount + } + } + } + prefixes { + totalCount + years { + id + count + } + nodes { + name + } + } + } + }) + end + + it "returns provider" do + response = LupoSchema.execute(query).as_json + + expect(response.dig("data", "provider", "id")).to eq(provider.uid) + expect(response.dig("data", "provider", "name")).to eq("My provider") + expect(response.dig("data", "provider", "country")).to eq("name"=>"Germany") + + expect(response.dig("data", "provider", "clients", "totalCount")).to eq(1) + expect(response.dig("data", "provider", "clients", "years")).to eq([{"count"=>1, "id"=>"2020"}]) + expect(response.dig("data", "provider", "clients", "software")).to eq([{"count"=>1, "id"=>"dataverse"}]) + expect(response.dig("data", "provider", "clients", "nodes").length).to eq(1) + client1 = response.dig("data", "provider", "clients", "nodes", 0) + expect(client1.fetch("id")).to eq(client.uid) + expect(client1.fetch("name")).to eq(client.name) + expect(client1.fetch("software")).to eq("dataverse") + expect(client1.dig("datasets", "totalCount")).to eq(1) + + expect(response.dig("data", "provider", "prefixes", "totalCount")).to eq(3) + expect(response.dig("data", "provider", "prefixes", "years")).to eq([{"count"=>3, "id"=>"2020"}]) + expect(response.dig("data", "provider", "prefixes", "nodes").length).to eq(3) + prefix1 = response.dig("data", "provider", "prefixes", "nodes", 0) + expect(prefix1.fetch("name")).to eq(provider_prefixes.first.prefix_id) + end + end + + describe "query clients", elasticsearch: true do + let!(:clients) { create_list(:client, 3) } + + before do + Client.import + sleep 1 + end + + let(:query) do + %(query { + clients { + totalCount + nodes { + id + name + alternateName + } + } + }) + end + + it "returns all clients" do + response = LupoSchema.execute(query).as_json + + expect(response.dig("data", "clients", "totalCount")).to eq(3) + expect(response.dig("data", "clients", "nodes").length).to eq(3) + + client1 = response.dig("data", "clients", "nodes", 0) + expect(client1.fetch("id")).to eq(clients.first.uid) + expect(client1.fetch("name")).to eq(clients.first.name) + expect(client1.fetch("alternateName")).to eq(clients.first.alternate_name) + end + end + + describe "find client", elasticsearch: true do + let(:provider) { create(:provider, symbol: "TESTC") } + let(:client) { create(:client, symbol: "TESTC.TESTC", alternate_name: "ABC", provider: provider) } + let!(:doi) { create(:doi, client: client, aasm_state: "findable") } + let(:prefix) { create(:prefix) } + let!(:client_prefixes) { create_list(:client_prefix, 3, client: client) } + + before do + Provider.import + Client.import + Doi.import + Prefix.import + ClientPrefix.import + sleep 2 + end + + let(:query) do + %(query { + client(id: "testc.testc") { + id + name + alternateName + datasets { + totalCount + } + prefixes { + totalCount + years { + id + count + } + nodes { + name + } + } + } + }) + end + + it "returns client" do + response = LupoSchema.execute(query).as_json + + expect(response.dig("data", "client", "id")).to eq(client.uid) + expect(response.dig("data", "client", "name")).to eq("My data center") + expect(response.dig("data", "client", "alternateName")).to eq("ABC") + + expect(response.dig("data", "client", "datasets", "totalCount")).to eq(1) + + expect(response.dig("data", "client", "prefixes", "totalCount")).to eq(3) + expect(response.dig("data", "client", "prefixes", "years")).to eq([{"count"=>3, "id"=>"2020"}]) + expect(response.dig("data", "client", "prefixes", "nodes").length).to eq(3) + prefix1 = response.dig("data", "client", "prefixes", "nodes", 0) + expect(prefix1.fetch("name")).to eq(client_prefixes.first.prefix_id) + end + end + + describe "find client with citations", elasticsearch: true do + let(:provider) { create(:provider, symbol: "TESTR") } + let(:client) { create(:client, symbol: "TESTR.TESTR", provider: provider) } + let(:doi) { create(:doi, client: client, aasm_state: "findable", creators: + [{ + "familyName" => "Garza", + "givenName" => "Kristian", + "name" => "Garza, Kristian", + "nameIdentifiers" => [{"nameIdentifier"=>"https://orcid.org/0000-0003-3484-6875", "nameIdentifierScheme"=>"ORCID", "schemeUri"=>"https://orcid.org"}], + "nameType" => "Personal", + }]) + } + let(:source_doi) { create(:doi, client: client, aasm_state: "findable") } + let(:source_doi2) { create(:doi, client: client, aasm_state: "findable") } + let!(:citation_event) { create(:event_for_datacite_crossref, subj_id: "https://doi.org/#{doi.doi}", obj_id: "https://doi.org/#{source_doi.doi}", relation_type_id: "is-referenced-by", occurred_at: "2015-06-13T16:14:19Z") } + let!(:citation_event2) { create(:event_for_datacite_crossref, subj_id: "https://doi.org/#{doi.doi}", obj_id: "https://doi.org/#{source_doi2.doi}", relation_type_id: "is-referenced-by", occurred_at: "2016-06-13T16:14:19Z") } + + before do + Provider.import + Client.import + Event.import + Doi.import + sleep 2 + end + + let(:query) do + %(query { + client(id: "testr.testr") { + id + name + citationCount + works { + totalCount + years { + title + count + } + resourceTypes { + title + count + } + nodes { + id + titles { + title + } + citationCount + } + } + } + }) + end + + it "returns client information" do + response = LupoSchema.execute(query).as_json + + expect(response.dig("data", "client", "id")).to eq("testr.testr") + expect(response.dig("data", "client", "name")).to eq("My data center") + expect(response.dig("data", "client", "citationCount")).to eq(0) + expect(response.dig("data", "client", "works", "totalCount")).to eq(3) + expect(response.dig("data", "client", "works", "years")).to eq([{"count"=>3, "title"=>"2011"}]) + expect(response.dig("data", "client", "works", "resourceTypes")).to eq([{"count"=>3, "title"=>"Dataset"}]) + expect(response.dig("data", "client", "works", "nodes").length).to eq(3) + + work = response.dig("data", "client", "works", "nodes", 0) + expect(work.dig("titles", 0, "title")).to eq("Data from: A new malaria agent in African hominids.") + expect(work.dig("citationCount")).to eq(0) + end + end + describe "query datasets", elasticsearch: true do let!(:datasets) { create_list(:doi, 3, aasm_state: "findable") } @@ -40,47 +311,96 @@ end end + describe "query datasets by person", elasticsearch: true do + let!(:datasets) { create_list(:doi, 3, aasm_state: "findable") } + let!(:dataset) { create(:doi, aasm_state: "findable", creators: + [{ + "familyName" => "Garza", + "givenName" => "Kristian", + "name" => "Garza, Kristian", + "nameIdentifiers" => [{"nameIdentifier"=>"https://orcid.org/0000-0003-3484-6875", "nameIdentifierScheme"=>"ORCID", "schemeUri"=>"https://orcid.org"}], + "nameType" => "Personal", + }]) + } + before do + Doi.import + sleep 2 + end + + let(:query) do + %(query { + datasets(userId: "https://orcid.org/0000-0003-1419-2405") { + totalCount + years { + id + count + } + nodes { + id + } + } + }) + end + + it "returns all datasets" do + response = LupoSchema.execute(query).as_json + + expect(response.dig("data", "datasets", "totalCount")).to eq(3) + expect(response.dig("data", "datasets", "years")).to eq([{"count"=>3, "id"=>"2011"}]) + expect(response.dig("data", "datasets", "nodes").length).to eq(3) + expect(response.dig("data", "datasets", "nodes", 0, "id")).to eq(datasets.first.identifier) + end + end + describe "query person", elasticsearch: true, vcr: true do - let!(:datasets) { create_list(:doi, 3, aasm_state: "findable", creators: + let(:client) { create(:client) } + let(:doi) { create(:doi, client: client, aasm_state: "findable", creators: [{ - "familyName" => "Fenner", - "givenName" => "Martin", - "name" => "Fenner, Martin", - "nameIdentifiers" => [{"nameIdentifier"=>"https://orcid.org/0000-0003-1419-2405", "nameIdentifierScheme"=>"ORCID", "schemeUri"=>"https://orcid.org"}], + "familyName" => "Garza", + "givenName" => "Kristian", + "name" => "Garza, Kristian", + "nameIdentifiers" => [{"nameIdentifier"=>"https://orcid.org/0000-0003-3484-6875", "nameIdentifierScheme"=>"ORCID", "schemeUri"=>"https://orcid.org"}], "nameType" => "Personal", }]) } + let(:source_doi) { create(:doi, client: client, aasm_state: "findable") } + let(:source_doi2) { create(:doi, client: client, aasm_state: "findable") } + let!(:citation_event) { create(:event_for_datacite_crossref, subj_id: "https://doi.org/#{doi.doi}", obj_id: "https://doi.org/#{source_doi.doi}", relation_type_id: "is-referenced-by", occurred_at: "2015-06-13T16:14:19Z") } + let!(:citation_event2) { create(:event_for_datacite_crossref, subj_id: "https://doi.org/#{doi.doi}", obj_id: "https://doi.org/#{source_doi2.doi}", relation_type_id: "is-referenced-by", occurred_at: "2016-06-13T16:14:19Z") } before do + Client.import + Event.import Doi.import sleep 2 end let(:query) do %(query { - person(id: "https://orcid.org/0000-0003-1419-2405") { + person(id: "https://orcid.org/0000-0003-3484-6875") { id name givenName familyName - doiCount { - title - count - } - resourceTypeCount { - title - count - } citationCount viewCount downloadCount works { totalCount + years { + title + count + } + resourceTypes { + title + count + } nodes { id titles { title } + citationCount } } } @@ -90,15 +410,17 @@ it "returns person information" do response = LupoSchema.execute(query).as_json - expect(response.dig("data", "person", "id")).to eq("https://orcid.org/0000-0003-1419-2405") - expect(response.dig("data", "person", "name")).to eq("Martin Fenner") - expect(response.dig("data", "person", "givenName")).to eq("Martin") - expect(response.dig("data", "person", "doiCount")).to eq([{"count"=>3, "title"=>"2011"}]) - expect(response.dig("data", "person", "resourceTypeCount")).to eq([{"count"=>3, "title"=>"Dataset"}]) - expect(response.dig("data", "person", "works", "totalCount")).to eq(3) + expect(response.dig("data", "person", "id")).to eq("https://orcid.org/0000-0003-3484-6875") + expect(response.dig("data", "person", "name")).to eq("K. J. Garza") + expect(response.dig("data", "person", "citationCount")).to eq(0) + expect(response.dig("data", "person", "works", "totalCount")).to eq(1) + expect(response.dig("data", "person", "works", "years")).to eq([{"count"=>1, "title"=>"2011"}]) + expect(response.dig("data", "person", "works", "resourceTypes")).to eq([{"count"=>1, "title"=>"Dataset"}]) + expect(response.dig("data", "person", "works", "nodes").length).to eq(1) work = response.dig("data", "person", "works", "nodes", 0) expect(work.dig("titles", 0, "title")).to eq("Data from: A new malaria agent in African hominids.") + expect(work.dig("citationCount")).to eq(0) end end @@ -112,9 +434,12 @@ name givenName familyName - doiCount { - title - count + works { + totalCount + years { + title + count + } } } }