From d7e93e199a21926782ef026064fa8a82d9081446 Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Mon, 16 Dec 2024 15:36:26 +0200 Subject: [PATCH] Allow filtering availableFounders by slug --- lib/sanbase/clickhouse/founders/founders.ex | 20 ++++++--- .../resolvers/metric/metric_resolver.ex | 6 ++- .../graphql/schema/types/metric_types.ex | 4 ++ .../metric/api_metric_metadata_test.exs | 44 ++++++++++++++++++- 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/lib/sanbase/clickhouse/founders/founders.ex b/lib/sanbase/clickhouse/founders/founders.ex index c54bded73..63481b7c5 100644 --- a/lib/sanbase/clickhouse/founders/founders.ex +++ b/lib/sanbase/clickhouse/founders/founders.ex @@ -1,13 +1,13 @@ defmodule Sanbase.Clickhouse.Founders do - def get_founders() do - query = get_founders_query() + def get_founders(slug \\ nil) do + query = get_founders_query(slug) - Sanbase.ClickhouseRepo.query_transform(query, fn [name, slug] -> - %{name: name, slug: slug} + Sanbase.ClickhouseRepo.query_transform(query, fn [name, project_slug] -> + %{name: name, slug: project_slug} end) end - defp get_founders_query() do + defp get_founders_query(nil) do sql = """ SELECT name, slug FROM founder_metadata @@ -15,4 +15,14 @@ defmodule Sanbase.Clickhouse.Founders do Sanbase.Clickhouse.Query.new(sql, %{}) end + + defp get_founders_query(slug) do + sql = """ + SELECT name, slug + FROM founder_metadata + WHERE slug = {{slug}} + """ + + Sanbase.Clickhouse.Query.new(sql, %{slug: slug}) + end end diff --git a/lib/sanbase_web/graphql/resolvers/metric/metric_resolver.ex b/lib/sanbase_web/graphql/resolvers/metric/metric_resolver.ex index 0cfe9c68f..8adbf4fe9 100644 --- a/lib/sanbase_web/graphql/resolvers/metric/metric_resolver.ex +++ b/lib/sanbase_web/graphql/resolvers/metric/metric_resolver.ex @@ -107,11 +107,13 @@ defmodule SanbaseWeb.Graphql.Resolvers.MetricResolver do end end - def get_available_founders(_root, _args, %{source: %{metric: metric}}) do + def get_available_founders(_root, args, %{source: %{metric: metric}}) do with {:ok, selectors} <- Metric.available_selectors(metric) do case :founders in selectors do true -> - with {:ok, data} <- Sanbase.Clickhouse.Founders.get_founders() do + slug = Map.get(args, :slug, nil) + + with {:ok, data} <- Sanbase.Clickhouse.Founders.get_founders(slug) do slugs = Enum.map(data, & &1.slug) projects = Sanbase.Project.List.by_slugs(slugs) slug_to_project_map = Map.new(projects, &{&1.slug, &1}) diff --git a/lib/sanbase_web/graphql/schema/types/metric_types.ex b/lib/sanbase_web/graphql/schema/types/metric_types.ex index 13f8650a4..4662af129 100644 --- a/lib/sanbase_web/graphql/schema/types/metric_types.ex +++ b/lib/sanbase_web/graphql/schema/types/metric_types.ex @@ -417,6 +417,10 @@ defmodule SanbaseWeb.Graphql.MetricTypes do end field :available_founders, list_of(:founder) do + @desc ~s""" + Filter the founders for which slug should be returned + """ + arg(:slug, :string, default_value: nil) cache_resolve(&MetricResolver.get_available_founders/3) end diff --git a/test/sanbase_web/graphql/metric/api_metric_metadata_test.exs b/test/sanbase_web/graphql/metric/api_metric_metadata_test.exs index a7c67241c..812a9de06 100644 --- a/test/sanbase_web/graphql/metric/api_metric_metadata_test.exs +++ b/test/sanbase_web/graphql/metric/api_metric_metadata_test.exs @@ -44,8 +44,9 @@ defmodule SanbaseWeb.Graphql.ApiMetricMetadataTest do |> json_response(200) |> get_in(["data", "getMetric", "metadata", "availableFounders"]) - assert %{"name" => "Vitalik Buterin", "project" => %{"name" => "Ethereum"}} in result + assert length(result) == 2 assert %{"name" => "Satoshi Nakamoto", "project" => %{"name" => "Bitcoin"}} in result + assert %{"name" => "Vitalik Buterin", "project" => %{"name" => "Ethereum"}} in result end end) @@ -59,6 +60,47 @@ defmodule SanbaseWeb.Graphql.ApiMetricMetadataTest do assert result == [] end + test "returns data for availableFounders with slug filter", %{conn: conn} do + metric_with_founders = + Metric.available_metrics() + |> Enum.filter(fn m -> + {:ok, selectors} = Metric.available_selectors(m) + + :founders in selectors + end) + |> hd() + + insert(:project, %{name: "Ethereum", ticker: "ETH", slug: "ethereum"}) + insert(:project, %{name: "Bitcoin", ticker: "BTC", slug: "bitcoin"}) + + rows = [ + ["Satoshi Nakamoto", "bitcoin"] + ] + + query = + """ + { + getMetric(metric: "#{metric_with_founders}"){ + metadata{ + availableFounders(slug: "bitcoin"){ name project{ name } } + } + } + } + """ + + Sanbase.Mock.prepare_mock2(&Sanbase.ClickhouseRepo.query/2, {:ok, %{rows: rows}}) + |> Sanbase.Mock.run_with_mocks(fn -> + result = + conn + |> post("/graphql", query_skeleton(query)) + |> json_response(200) + |> get_in(["data", "getMetric", "metadata", "availableFounders"]) + + assert length(result) == 1 + assert %{"name" => "Satoshi Nakamoto", "project" => %{"name" => "Bitcoin"}} in result + end) + end + test "returns data for all available metric", %{conn: conn} do metrics = Metric.available_metrics() |> Enum.shuffle()