Skip to content

Commit 97b6e55

Browse files
committed
toil(front): add service account controller tests
1 parent e21b1af commit 97b6e55

File tree

3 files changed

+362
-2
lines changed

3 files changed

+362
-2
lines changed

front/lib/front_web/controllers/service_account_controller.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ defmodule FrontWeb.ServiceAccountController do
7474
end
7575
end
7676

77-
def update(conn, %{"id" => id} = params) do
77+
def update(conn, params = %{"id" => id}) do
7878
name = params["name"] || ""
7979
description = params["description"] || ""
8080

Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
defmodule FrontWeb.ServiceAccountControllerTest do
2+
use FrontWeb.ConnCase
3+
import Mox
4+
alias Front.Models.ServiceAccount
5+
alias Support.Stubs.DB
6+
7+
setup :verify_on_exit!
8+
9+
setup %{conn: conn} do
10+
Cacheman.clear(:front)
11+
Support.Stubs.init()
12+
Support.Stubs.build_shared_factories()
13+
14+
user_id = DB.first(:users) |> Map.get(:id)
15+
org_id = DB.first(:organizations) |> Map.get(:id)
16+
17+
Support.Stubs.PermissionPatrol.remove_all_permissions()
18+
19+
# Set up base permissions
20+
Support.Stubs.PermissionPatrol.add_permissions(org_id, user_id, [
21+
"organization.view",
22+
"organization.service_accounts.view"
23+
])
24+
25+
conn =
26+
conn
27+
|> put_req_header("x-semaphore-org-id", org_id)
28+
|> put_req_header("x-semaphore-user-id", user_id)
29+
30+
{:ok, conn: conn, org_id: org_id, user_id: user_id}
31+
end
32+
33+
describe "GET /service_accounts" do
34+
test "lists service accounts successfully", %{conn: conn, org_id: org_id} do
35+
service_account = %ServiceAccount{
36+
id: "sa_123",
37+
name: "Test Service Account",
38+
description: "Test description",
39+
created_at: ~U[2024-01-01 10:00:00Z],
40+
updated_at: ~U[2024-01-01 10:00:00Z],
41+
deactivated: false
42+
}
43+
44+
expect(ServiceAccountMock, :list, fn ^org_id, 20, nil ->
45+
{:ok, {[service_account], "next_page_token"}}
46+
end)
47+
48+
conn = get(conn, "/service_accounts")
49+
50+
assert json_response(conn, 200) == %{
51+
"service_accounts" => [
52+
%{
53+
"id" => "sa_123",
54+
"name" => "Test Service Account",
55+
"description" => "Test description",
56+
"created_at" => "2024-01-01T10:00:00Z",
57+
"updated_at" => "2024-01-01T10:00:00Z",
58+
"deactivated" => false
59+
}
60+
]
61+
}
62+
63+
assert get_resp_header(conn, "x-next-page-token") == ["next_page_token"]
64+
end
65+
66+
test "handles pagination parameters", %{conn: conn, org_id: org_id} do
67+
expect(ServiceAccountMock, :list, fn ^org_id, 10, "page_token_123" ->
68+
{:ok, {[], nil}}
69+
end)
70+
71+
conn =
72+
get(conn, "/service_accounts", %{"page_size" => "10", "page_token" => "page_token_123"})
73+
74+
assert json_response(conn, 200) == %{"service_accounts" => []}
75+
assert get_resp_header(conn, "x-next-page-token") == [""]
76+
end
77+
78+
test "handles backend errors", %{conn: conn, org_id: org_id} do
79+
expect(ServiceAccountMock, :list, fn ^org_id, 20, nil ->
80+
{:error, "Failed to list service accounts"}
81+
end)
82+
83+
conn = get(conn, "/service_accounts")
84+
85+
assert json_response(conn, 422) == %{"error" => "Failed to list service accounts"}
86+
end
87+
88+
test "requires service_accounts.view permission", %{
89+
conn: conn,
90+
org_id: org_id,
91+
user_id: user_id
92+
} do
93+
Support.Stubs.PermissionPatrol.remove_all_permissions()
94+
Support.Stubs.PermissionPatrol.add_permissions(org_id, user_id, ["organization.view"])
95+
96+
conn = get(conn, "/service_accounts")
97+
98+
assert html_response(conn, 404) =~ "Page not found"
99+
end
100+
end
101+
102+
describe "POST /service_accounts" do
103+
setup %{org_id: org_id, user_id: user_id} do
104+
Support.Stubs.PermissionPatrol.add_permissions(org_id, user_id, [
105+
"organization.service_accounts.manage"
106+
])
107+
108+
:ok
109+
end
110+
111+
test "creates service account successfully", %{conn: conn, org_id: org_id, user_id: user_id} do
112+
service_account = %ServiceAccount{
113+
id: "sa_new",
114+
name: "New Service Account",
115+
description: "New description",
116+
created_at: ~U[2024-01-01 10:00:00Z],
117+
updated_at: ~U[2024-01-01 10:00:00Z],
118+
deactivated: false
119+
}
120+
121+
expect(ServiceAccountMock, :create, fn ^org_id,
122+
"New Service Account",
123+
"New description",
124+
^user_id ->
125+
{:ok, {service_account, "api_token_123"}}
126+
end)
127+
128+
conn =
129+
post(conn, "/service_accounts", %{
130+
"name" => "New Service Account",
131+
"description" => "New description"
132+
})
133+
134+
assert json_response(conn, 201) == %{
135+
"id" => "sa_new",
136+
"name" => "New Service Account",
137+
"description" => "New description",
138+
"created_at" => "2024-01-01T10:00:00Z",
139+
"updated_at" => "2024-01-01T10:00:00Z",
140+
"deactivated" => false,
141+
"api_token" => "api_token_123"
142+
}
143+
end
144+
145+
test "handles empty parameters", %{conn: conn, org_id: org_id, user_id: user_id} do
146+
expect(ServiceAccountMock, :create, fn ^org_id, "", "", ^user_id ->
147+
{:error, "Name is required"}
148+
end)
149+
150+
conn = post(conn, "/service_accounts", %{})
151+
152+
assert json_response(conn, 422) == %{"error" => "Name is required"}
153+
end
154+
155+
test "handles backend errors", %{conn: conn, org_id: org_id, user_id: user_id} do
156+
expect(ServiceAccountMock, :create, fn ^org_id, "Test", "Desc", ^user_id ->
157+
{:error, "Failed to create service account"}
158+
end)
159+
160+
conn =
161+
post(conn, "/service_accounts", %{
162+
"name" => "Test",
163+
"description" => "Desc"
164+
})
165+
166+
assert json_response(conn, 422) == %{"error" => "Failed to create service account"}
167+
end
168+
169+
test "requires service_accounts.manage permission", %{
170+
conn: conn,
171+
org_id: org_id,
172+
user_id: user_id
173+
} do
174+
Support.Stubs.PermissionPatrol.remove_all_permissions()
175+
176+
Support.Stubs.PermissionPatrol.add_permissions(org_id, user_id, [
177+
"organization.view",
178+
"organization.service_accounts.view"
179+
])
180+
181+
conn = post(conn, "/service_accounts", %{"name" => "Test"})
182+
183+
assert html_response(conn, 404) =~ "Page not found"
184+
end
185+
end
186+
187+
describe "GET /service_accounts/:id" do
188+
test "retrieves service account successfully", %{conn: conn} do
189+
service_account = %ServiceAccount{
190+
id: "sa_123",
191+
name: "Test Service Account",
192+
description: "Test description",
193+
created_at: ~U[2024-01-01 10:00:00Z],
194+
updated_at: ~U[2024-01-01 10:00:00Z],
195+
deactivated: false
196+
}
197+
198+
expect(ServiceAccountMock, :describe, fn "sa_123" ->
199+
{:ok, service_account}
200+
end)
201+
202+
conn = get(conn, "/service_accounts/sa_123")
203+
204+
assert json_response(conn, 200) == %{
205+
"id" => "sa_123",
206+
"name" => "Test Service Account",
207+
"description" => "Test description",
208+
"created_at" => "2024-01-01T10:00:00Z",
209+
"updated_at" => "2024-01-01T10:00:00Z",
210+
"deactivated" => false
211+
}
212+
end
213+
214+
test "handles not found", %{conn: conn} do
215+
expect(ServiceAccountMock, :describe, fn "sa_nonexistent" ->
216+
{:error, "Service account not found"}
217+
end)
218+
219+
conn = get(conn, "/service_accounts/sa_nonexistent")
220+
221+
assert json_response(conn, 422) == %{"error" => "Service account not found"}
222+
end
223+
end
224+
225+
describe "PUT /service_accounts/:id" do
226+
setup %{org_id: org_id, user_id: user_id} do
227+
Support.Stubs.PermissionPatrol.add_permissions(org_id, user_id, [
228+
"organization.service_accounts.manage"
229+
])
230+
231+
:ok
232+
end
233+
234+
test "updates service account successfully", %{conn: conn} do
235+
updated_account = %ServiceAccount{
236+
id: "sa_123",
237+
name: "Updated Name",
238+
description: "Updated description",
239+
created_at: ~U[2024-01-01 10:00:00Z],
240+
updated_at: ~U[2024-01-02 10:00:00Z],
241+
deactivated: false
242+
}
243+
244+
expect(ServiceAccountMock, :update, fn "sa_123", "Updated Name", "Updated description" ->
245+
{:ok, updated_account}
246+
end)
247+
248+
conn =
249+
put(conn, "/service_accounts/sa_123", %{
250+
"name" => "Updated Name",
251+
"description" => "Updated description"
252+
})
253+
254+
assert json_response(conn, 200) == %{
255+
"id" => "sa_123",
256+
"name" => "Updated Name",
257+
"description" => "Updated description",
258+
"created_at" => "2024-01-01T10:00:00Z",
259+
"updated_at" => "2024-01-02T10:00:00Z",
260+
"deactivated" => false
261+
}
262+
end
263+
264+
test "handles update errors", %{conn: conn} do
265+
expect(ServiceAccountMock, :update, fn "sa_123", "", "" ->
266+
{:error, "Failed to update"}
267+
end)
268+
269+
conn = put(conn, "/service_accounts/sa_123", %{})
270+
271+
assert json_response(conn, 422) == %{"error" => "Failed to update"}
272+
end
273+
end
274+
275+
describe "DELETE /service_accounts/:id" do
276+
setup %{org_id: org_id, user_id: user_id} do
277+
Support.Stubs.PermissionPatrol.add_permissions(org_id, user_id, [
278+
"organization.service_accounts.manage"
279+
])
280+
281+
:ok
282+
end
283+
284+
test "deletes service account successfully", %{conn: conn} do
285+
service_account = %ServiceAccount{
286+
id: "sa_123",
287+
name: "To Delete",
288+
description: "Will be deleted",
289+
created_at: ~U[2024-01-01 10:00:00Z],
290+
updated_at: ~U[2024-01-01 10:00:00Z],
291+
deactivated: false
292+
}
293+
294+
expect(ServiceAccountMock, :describe, fn "sa_123" ->
295+
{:ok, service_account}
296+
end)
297+
298+
expect(ServiceAccountMock, :delete, fn "sa_123" ->
299+
:ok
300+
end)
301+
302+
conn = delete(conn, "/service_accounts/sa_123")
303+
304+
assert response(conn, 204) == ""
305+
end
306+
307+
test "handles delete errors", %{conn: conn} do
308+
expect(ServiceAccountMock, :describe, fn "sa_123" ->
309+
{:error, "Not found"}
310+
end)
311+
312+
conn = delete(conn, "/service_accounts/sa_123")
313+
314+
assert json_response(conn, 422) == %{"error" => "Not found"}
315+
end
316+
end
317+
318+
describe "POST /service_accounts/:id/regenerate_token" do
319+
setup %{org_id: org_id, user_id: user_id} do
320+
Support.Stubs.PermissionPatrol.add_permissions(org_id, user_id, [
321+
"organization.service_accounts.manage"
322+
])
323+
324+
:ok
325+
end
326+
327+
test "regenerates token successfully", %{conn: conn} do
328+
service_account = %ServiceAccount{
329+
id: "sa_123",
330+
name: "Test Account",
331+
description: "Test",
332+
created_at: ~U[2024-01-01 10:00:00Z],
333+
updated_at: ~U[2024-01-01 10:00:00Z],
334+
deactivated: false
335+
}
336+
337+
expect(ServiceAccountMock, :describe, fn "sa_123" ->
338+
{:ok, service_account}
339+
end)
340+
341+
expect(ServiceAccountMock, :regenerate_token, fn "sa_123" ->
342+
{:ok, "new_api_token_456"}
343+
end)
344+
345+
conn = post(conn, "/service_accounts/sa_123/regenerate_token")
346+
347+
assert json_response(conn, 200) == %{"api_token" => "new_api_token_456"}
348+
end
349+
350+
test "handles regenerate errors", %{conn: conn} do
351+
expect(ServiceAccountMock, :describe, fn "sa_123" ->
352+
{:error, "Not found"}
353+
end)
354+
355+
conn = post(conn, "/service_accounts/sa_123/regenerate_token")
356+
357+
assert json_response(conn, 422) == %{"error" => "Not found"}
358+
end
359+
end
360+
end

front/test/test_helper.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Application.put_env(:wallaby, :js_logger, file)
1616
Support.Stubs.init()
1717

1818
Mox.defmock(ServiceAccountMock, for: Front.ServiceAccount.Behaviour)
19-
Application.put_env(:front, :service_account_client, ServiceAccountMock)
19+
Application.put_env(:front, :service_account_client, {ServiceAccountMock, []})
2020

2121
ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter])
2222
ExUnit.start(trace: false, capture_log: true)

0 commit comments

Comments
 (0)