Skip to content

Commit 13a4d1d

Browse files
Write and test describe endpoint
1 parent 9837661 commit 13a4d1d

File tree

3 files changed

+102
-18
lines changed

3 files changed

+102
-18
lines changed

ee/ephemeral_environments/lib/ephemeral_environments/grpc/ephemeral_environments_server.ex

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,21 @@ defmodule EphemeralEnvironments.Grpc.EphemeralEnvironmentsServer do
2626
end
2727
end
2828

29-
def describe(_request, _stream) do
30-
%DescribeResponse{}
29+
def describe(request, _stream) do
30+
case EphemeralEnvironments.Service.EphemeralEnvironmentType.describe(
31+
request.id,
32+
request.org_id
33+
) do
34+
{:ok, environment_type} ->
35+
# Note: instances field will be added once we implement instance management
36+
%{environment_type: environment_type, instances: []}
37+
38+
{:error, :not_found} ->
39+
raise GRPC.RPCError, status: :not_found, message: "Environment type not found"
40+
41+
{:error, error_message} ->
42+
raise GRPC.RPCError, status: :unknown, message: error_message
43+
end
3144
end
3245

3346
def create(request, _stream) do

ee/ephemeral_environments/lib/ephemeral_environments/service/ephemeral_environment_type.ex

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@ defmodule EphemeralEnvironments.Service.EphemeralEnvironmentType do
2222
{:ok, environment_types}
2323
end
2424

25+
@doc """
26+
Describes a specific ephemeral environment type by ID and org_id.
27+
28+
## Parameters
29+
- id: String UUID of the environment type
30+
- org_id: String UUID of the organization
31+
32+
## Returns
33+
- {:ok, map} on success
34+
- {:error, :not_found} if the environment type doesn't exist
35+
"""
36+
def describe(id, org_id) when is_binary(id) and is_binary(org_id) do
37+
Schema
38+
|> where([e], e.id == ^id and e.org_id == ^org_id)
39+
|> Repo.one()
40+
|> case do
41+
nil -> {:error, :not_found}
42+
record -> {:ok, struct_to_map(record)}
43+
end
44+
end
45+
2546
@doc """
2647
Creates a new ephemeral environment type.
2748
@@ -58,6 +79,14 @@ defmodule EphemeralEnvironments.Service.EphemeralEnvironmentType do
5879
struct
5980
|> Map.from_struct()
6081
|> Map.drop([:__meta__])
82+
|> rename_timestamp_fields()
83+
end
84+
85+
# Rename Ecto's inserted_at to created_at to match proto definition
86+
defp rename_timestamp_fields(map) do
87+
map
88+
|> Map.put(:created_at, map[:inserted_at])
89+
|> Map.delete(:inserted_at)
6190
end
6291

6392
defp format_errors(changeset) do

ee/ephemeral_environments/test/grpc/ephemeral_environments_server_test.exs

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ defmodule EphemeralEnvironments.Grpc.EphemeralEnvironmentsServerTest do
33

44
alias EphemeralEnvironments.Repo
55
alias EphemeralEnvironments.Repo.EphemeralEnvironmentType, as: Schema
6+
alias Support.Factories
67

78
alias InternalApi.EphemeralEnvironments.{
89
CreateRequest,
910
EphemeralEnvironmentType,
1011
EphemeralEnvironments,
11-
ListRequest
12+
ListRequest,
13+
DescribeRequest
1214
}
1315

1416
@org_id Ecto.UUID.generate()
@@ -35,14 +37,11 @@ defmodule EphemeralEnvironments.Grpc.EphemeralEnvironmentsServerTest do
3537

3638
test "returns all environment types for a specific org", %{channel: channel} do
3739
# Create environment types for the test org
38-
{:ok, env1} =
39-
Support.Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Development")
40-
41-
{:ok, env1} =
42-
Support.Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Staging")
40+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Development")
41+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Staging")
4342

4443
# Create environment type for a different org (should not be returned)
45-
{:ok, _} = Support.Factories.EphemeralEnvironmentsType.insert(org_id: Ecto.UUID.generate())
44+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: Ecto.UUID.generate())
4645

4746
request = %ListRequest{org_id: @org_id}
4847
{:ok, response} = EphemeralEnvironments.Stub.list(channel, request)
@@ -61,11 +60,11 @@ defmodule EphemeralEnvironments.Grpc.EphemeralEnvironmentsServerTest do
6160
test "handles multiple orgs correctly", %{channel: channel} do
6261
org2_id = Ecto.UUID.generate()
6362

64-
{:ok, _} = Support.Factories.EphemeralEnvironmentsType.insert(org_id: @org_id)
65-
{:ok, _} = Support.Factories.EphemeralEnvironmentsType.insert(org_id: @org_id)
63+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: @org_id)
64+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: @org_id)
6665

6766
# Create environment types for org2
68-
{:ok, _} = Support.Factories.EphemeralEnvironmentsType.insert(org_id: org2_id)
67+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: org2_id)
6968

7069
# Request for org1
7170
request1 = %ListRequest{org_id: @org_id}
@@ -82,6 +81,50 @@ defmodule EphemeralEnvironments.Grpc.EphemeralEnvironmentsServerTest do
8281
end
8382

8483
describe "describe/2" do
84+
test "returns environment type when it exists", %{channel: channel} do
85+
{:ok, env_type} =
86+
Factories.EphemeralEnvironmentsType.insert(
87+
org_id: @org_id,
88+
name: "Production",
89+
description: "Production environment",
90+
created_by: @user_id,
91+
state: :ready,
92+
max_number_of_instances: 20
93+
)
94+
95+
request = %DescribeRequest{id: env_type.id, org_id: @org_id}
96+
97+
{:ok, response} = EphemeralEnvironments.Stub.describe(channel, request)
98+
99+
assert response.environment_type.id == env_type.id
100+
assert response.environment_type.org_id == @org_id
101+
assert response.environment_type.name == "Production"
102+
assert response.environment_type.description == "Production environment"
103+
assert response.environment_type.created_by == @user_id
104+
assert response.environment_type.last_updated_by == @user_id
105+
assert response.environment_type.state == :TYPE_STATE_READY
106+
assert response.environment_type.max_number_of_instances == 20
107+
assert_recent_timestamp(DateTime.from_unix!(response.environment_type.created_at.seconds))
108+
assert_recent_timestamp(DateTime.from_unix!(response.environment_type.updated_at.seconds))
109+
assert response.instances == []
110+
end
111+
112+
test "returns not_found error when environment type doesn't exist", %{channel: channel} do
113+
request = %DescribeRequest{id: Ecto.UUID.generate(), org_id: @org_id}
114+
{:error, %GRPC.RPCError{} = error} = EphemeralEnvironments.Stub.describe(channel, request)
115+
116+
assert error.status == 5
117+
assert error.message == "Environment type not found"
118+
end
119+
120+
test "returns not_found when querying with wrong org_id", %{channel: channel} do
121+
{:ok, env_type} = Factories.EphemeralEnvironmentsType.insert(org_id: @org_id)
122+
request = %DescribeRequest{id: env_type.id, org_id: Ecto.UUID.generate()}
123+
{:error, %GRPC.RPCError{} = error} = EphemeralEnvironments.Stub.describe(channel, request)
124+
125+
assert error.status == 5
126+
assert error.message == "Environment type not found"
127+
end
85128
end
86129

87130
describe "create/2" do
@@ -117,20 +160,20 @@ defmodule EphemeralEnvironments.Grpc.EphemeralEnvironmentsServerTest do
117160
assert env_type.state == :TYPE_STATE_DRAFT
118161
assert env_type.max_number_of_instances == 5
119162
assert_recent_timestamp(DateTime.from_unix!(env_type.updated_at.seconds))
163+
assert_recent_timestamp(DateTime.from_unix!(env_type.created_at.seconds))
120164

121165
# Validate database record exists
122166
assert Repo.get(Schema, env_type.id)
123167
end
124168

125169
test "fails to create environment type with duplicate name in same org", %{channel: channel} do
126-
{:ok, _} = Support.Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Test")
170+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Test")
127171

128172
duplicate_request = %CreateRequest{
129173
environment_type: %EphemeralEnvironmentType{
130174
org_id: @org_id,
131175
name: "Test",
132-
max_number_of_instances: 1,
133-
created_by: @user_id
176+
max_number_of_instances: 1
134177
}
135178
}
136179

@@ -141,14 +184,13 @@ defmodule EphemeralEnvironments.Grpc.EphemeralEnvironmentsServerTest do
141184
end
142185

143186
test "allows same name in different orgs", %{channel: channel} do
144-
{:ok, _} = Support.Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Test")
187+
{:ok, _} = Factories.EphemeralEnvironmentsType.insert(org_id: @org_id, name: "Test")
145188

146189
request = %CreateRequest{
147190
environment_type: %EphemeralEnvironmentType{
148191
org_id: Ecto.UUID.generate(),
149192
name: "Test",
150-
max_number_of_instances: 1,
151-
created_by: @user_id
193+
max_number_of_instances: 1
152194
}
153195
}
154196

0 commit comments

Comments
 (0)