Skip to content

Commit

Permalink
Port existingDeviceTags query to Ash
Browse files Browse the repository at this point in the history
Return the list of tag names currently assigned to a device

Signed-off-by: Riccardo Binetti <[email protected]>
  • Loading branch information
rbino committed Apr 3, 2024
1 parent cee2778 commit 39181b5
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 106 deletions.
11 changes: 11 additions & 0 deletions backend/lib/edgehog/labeling/tag.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@ defmodule Edgehog.Labeling.Tag do

graphql do
type :tag

queries do
list :existing_device_tags, :assigned_to_devices
end
end

require Ash.Query

actions do
defaults [:read, :destroy]

Expand All @@ -43,6 +49,11 @@ defmodule Edgehog.Labeling.Tag do
upsert? true
upsert_identity :name_tenant_id
end

read :assigned_to_devices do
description "Returns Tags currently assigned to some device."
prepare build(filter: expr(exists(device_tags, true)))
end
end

attributes do
Expand Down
28 changes: 0 additions & 28 deletions backend/lib/edgehog_web/resolvers/labeling.ex

This file was deleted.

4 changes: 1 addition & 3 deletions backend/lib/edgehog_web/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,14 @@ defmodule EdgehogWeb.Schema do
import_types EdgehogWeb.Schema.BaseImagesTypes
import_types EdgehogWeb.Schema.GeolocationTypes
import_types EdgehogWeb.Schema.GroupsTypes
import_types EdgehogWeb.Schema.LabelingTypes
import_types EdgehogWeb.Schema.LocalizationTypes
import_types EdgehogWeb.Schema.OSManagementTypes
import_types EdgehogWeb.Schema.UpdateCampaignsTypes
import_types EdgehogWeb.Schema.VariantTypes
import_types Absinthe.Plug.Types
import_types Absinthe.Type.Custom

@apis [Edgehog.Devices, Edgehog.Tenants]
@apis [Edgehog.Devices, Edgehog.Labeling, Edgehog.Tenants]

# TODO: remove define_relay_types?: false once we convert everything to Ash
use AshGraphql,
Expand Down Expand Up @@ -112,7 +111,6 @@ defmodule EdgehogWeb.Schema do

import_fields :base_images_queries
import_fields :groups_queries
import_fields :labeling_queries
import_fields :update_campaigns_queries
end

Expand Down
33 changes: 0 additions & 33 deletions backend/lib/edgehog_web/schema/labeling_types.ex

This file was deleted.

98 changes: 56 additions & 42 deletions backend/test/edgehog_web/schema/query/existing_device_tags_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -19,66 +19,80 @@
#

defmodule EdgehogWeb.Schema.Query.ExistingDeviceTagsTest do
use EdgehogWeb.ConnCase, async: true
use EdgehogWeb.GraphqlCase, async: true

import Edgehog.AstarteFixtures
import Edgehog.DevicesFixtures

alias Edgehog.Devices

describe "existingDeviceTags field" do
@query """
{
existingDeviceTags
}
"""

test "returns empty tags", %{conn: conn, api_path: api_path} do
conn = get(conn, api_path, query: @query)
@moduletag :ported_to_ash

assert json_response(conn, 200) == %{
"data" => %{
"existingDeviceTags" => []
}
}
describe "existingDeviceTags query" do
test "returns empty tags", %{tenant: tenant} do
assert [] == existing_device_tags_query(tenant: tenant) |> extract_result!()
end

test "returns tags if they're present", %{conn: conn, api_path: api_path} do
cluster = cluster_fixture()
realm = realm_fixture(cluster)
test "returns tags if they're present", %{tenant: tenant} do
device_fixture(tenant: tenant)
|> Ash.Changeset.for_update(:add_tags, tags: ["foo", "bar"])
|> Ash.update!()

tags = ["foo", "bar"]
assert tags = existing_device_tags_query(tenant: tenant) |> extract_result!()
assert length(tags) == 2
tag_names = Enum.map(tags, &Map.fetch!(&1, "name"))
assert "foo" in tag_names
assert "bar" in tag_names
end

{:ok, _device} =
device_fixture(realm)
|> Devices.update_device(%{tags: tags})
test "returns only tags currently assigned to some device", %{tenant: tenant} do
device_fixture(tenant: tenant)
|> Ash.Changeset.for_update(:add_tags, tags: ["foo", "bar"])
|> Ash.update!()
|> Ash.Changeset.for_update(:remove_tags, tags: ["foo"])
|> Ash.update!()

conn = get(conn, api_path, query: @query)
assert [%{"name" => "bar"}] ==
existing_device_tags_query(tenant: tenant) |> extract_result!()
end

assert %{
"data" => %{
"existingDeviceTags" => tags
}
} == json_response(conn, 200)
test "does not return duplicates if a tag is assigned multiple times", %{tenant: tenant} do
device_fixture(tenant: tenant)
|> Ash.Changeset.for_update(:add_tags, tags: ["foo", "bar"])
|> Ash.update!()

device_fixture(tenant: tenant)
|> Ash.Changeset.for_update(:add_tags, tags: ["foo", "baz"])
|> Ash.update!()

assert tags = existing_device_tags_query(tenant: tenant) |> extract_result!()
assert length(tags) == 3
tag_names = Enum.map(tags, &Map.fetch!(&1, "name"))
assert "foo" in tag_names
assert "bar" in tag_names
assert "baz" in tag_names
end
end

test "return tags only if there're assigned to devices", %{conn: conn, api_path: api_path} do
cluster = cluster_fixture()
realm = realm_fixture(cluster)
defp existing_device_tags_query(opts) do
document = """
query {
existingDeviceTags {
name
}
}
"""

{:ok, device} =
device_fixture(realm)
|> Devices.update_device(%{tags: ["foo", "bar"]})
tenant = Keyword.fetch!(opts, :tenant)

Devices.update_device(device, %{tags: ["bar"]})
Absinthe.run!(document, EdgehogWeb.Schema, context: %{tenant: tenant})
end

conn = get(conn, api_path, query: @query)
defp extract_result!(result) do
refute :errors in Map.keys(result)
assert %{data: %{"existingDeviceTags" => tags}} = result
assert tags != nil

assert %{
"data" => %{
"existingDeviceTags" => ["bar"]
}
} == json_response(conn, 200)
end
tags
end
end

0 comments on commit 39181b5

Please sign in to comment.