Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5d1bd5b

Browse files
committed
add tests
1 parent2036479 commit5d1bd5b

File tree

2 files changed

+274
-1
lines changed

2 files changed

+274
-1
lines changed

‎cli/exp_tasklist_test.go‎

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
package cli_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"database/sql"
7+
"encoding/json"
8+
"io"
9+
"testing"
10+
11+
"cdr.dev/slog"
12+
"cdr.dev/slog/sloggers/sloghuman"
13+
"github.com/google/uuid"
14+
"github.com/stretchr/testify/require"
15+
16+
"github.com/coder/coder/v2/cli/clitest"
17+
"github.com/coder/coder/v2/coderd/coderdtest"
18+
"github.com/coder/coder/v2/coderd/database"
19+
"github.com/coder/coder/v2/coderd/database/dbauthz"
20+
"github.com/coder/coder/v2/coderd/database/dbfake"
21+
"github.com/coder/coder/v2/coderd/database/dbgen"
22+
"github.com/coder/coder/v2/coderd/util/slice"
23+
"github.com/coder/coder/v2/codersdk"
24+
"github.com/coder/coder/v2/pty/ptytest"
25+
"github.com/coder/coder/v2/testutil"
26+
)
27+
28+
// makeAITask creates an AI-task workspace.
29+
funcmakeAITask(t*testing.T,db database.Store,orgID,adminID,ownerID uuid.UUID,transition database.WorkspaceTransition,promptstring) (workspace database.WorkspaceTable) {
30+
t.Helper()
31+
32+
tv:=dbfake.TemplateVersion(t,db).
33+
Seed(database.TemplateVersion{
34+
OrganizationID:orgID,
35+
CreatedBy:adminID,
36+
HasAITask: sql.NullBool{
37+
Bool:true,
38+
Valid:true,
39+
},
40+
}).Do()
41+
42+
ws:= database.WorkspaceTable{
43+
OrganizationID:orgID,
44+
OwnerID:ownerID,
45+
TemplateID:tv.Template.ID,
46+
}
47+
build:=dbfake.WorkspaceBuild(t,db,ws).
48+
Seed(database.WorkspaceBuild{
49+
TemplateVersionID:tv.TemplateVersion.ID,
50+
Transition:transition,
51+
}).WithAgent().Do()
52+
dbgen.WorkspaceBuildParameters(t,db, []database.WorkspaceBuildParameter{
53+
{
54+
WorkspaceBuildID:build.Build.ID,
55+
Name:codersdk.AITaskPromptParameterName,
56+
Value:prompt,
57+
},
58+
})
59+
agents,err:=db.GetWorkspaceAgentsByWorkspaceAndBuildNumber(
60+
dbauthz.AsSystemRestricted(context.Background()),
61+
database.GetWorkspaceAgentsByWorkspaceAndBuildNumberParams{
62+
WorkspaceID:build.Workspace.ID,
63+
BuildNumber:build.Build.BuildNumber,
64+
},
65+
)
66+
require.NoError(t,err)
67+
require.NotEmpty(t,agents)
68+
agentID:=agents[0].ID
69+
70+
// Create a workspace app and set it as the sidebar app.
71+
app:=dbgen.WorkspaceApp(t,db, database.WorkspaceApp{
72+
AgentID:agentID,
73+
Slug:"task-sidebar",
74+
DisplayName:"Task Sidebar",
75+
External:false,
76+
})
77+
78+
// Update build flags to reference the sidebar app and HasAITask=true.
79+
err=db.UpdateWorkspaceBuildFlagsByID(
80+
dbauthz.AsSystemRestricted(context.Background()),
81+
database.UpdateWorkspaceBuildFlagsByIDParams{
82+
ID:build.Build.ID,
83+
HasAITask: sql.NullBool{Bool:true,Valid:true},
84+
HasExternalAgent: sql.NullBool{Bool:false,Valid:false},
85+
SidebarAppID: uuid.NullUUID{UUID:app.ID,Valid:true},
86+
UpdatedAt:build.Build.UpdatedAt,
87+
},
88+
)
89+
require.NoError(t,err)
90+
91+
returnbuild.Workspace
92+
}
93+
94+
funcTestExpTaskList(t*testing.T) {
95+
t.Parallel()
96+
97+
t.Run("NoTasks_Table",func(t*testing.T) {
98+
t.Parallel()
99+
100+
// Quiet logger to reduce noise.
101+
quiet:=slog.Make(sloghuman.Sink(io.Discard))
102+
client,_:=coderdtest.NewWithDatabase(t,&coderdtest.Options{Logger:&quiet})
103+
owner:=coderdtest.CreateFirstUser(t,client)
104+
memberClient,_:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID)
105+
106+
inv,root:=clitest.New(t,"exp","task","list")
107+
clitest.SetupConfig(t,memberClient,root)
108+
109+
pty:=ptytest.New(t).Attach(inv)
110+
ctx:=testutil.Context(t,testutil.WaitShort)
111+
112+
err:=inv.WithContext(ctx).Run()
113+
require.NoError(t,err)
114+
115+
pty.ExpectMatch("No tasks found.")
116+
})
117+
118+
t.Run("Single_Table",func(t*testing.T) {
119+
t.Parallel()
120+
121+
// Quiet logger to reduce noise.
122+
quiet:=slog.Make(sloghuman.Sink(io.Discard))
123+
client,db:=coderdtest.NewWithDatabase(t,&coderdtest.Options{Logger:&quiet})
124+
owner:=coderdtest.CreateFirstUser(t,client)
125+
memberClient,memberUser:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID)
126+
127+
wantPrompt:="build me a web app"
128+
ws:=makeAITask(t,db,owner.OrganizationID,owner.UserID,memberUser.ID,database.WorkspaceTransitionStart,wantPrompt)
129+
130+
inv,root:=clitest.New(t,"exp","task","list","--column","id,name,status,initial prompt")
131+
clitest.SetupConfig(t,memberClient,root)
132+
133+
pty:=ptytest.New(t).Attach(inv)
134+
ctx:=testutil.Context(t,testutil.WaitShort)
135+
136+
err:=inv.WithContext(ctx).Run()
137+
require.NoError(t,err)
138+
139+
// Validate the table includes the task and status.
140+
pty.ExpectMatch(ws.Name)
141+
pty.ExpectMatch("running")
142+
pty.ExpectMatch(wantPrompt)
143+
})
144+
145+
t.Run("StatusFilter_JSON",func(t*testing.T) {
146+
t.Parallel()
147+
148+
// Quiet logger to reduce noise.
149+
quiet:=slog.Make(sloghuman.Sink(io.Discard))
150+
client,db:=coderdtest.NewWithDatabase(t,&coderdtest.Options{Logger:&quiet})
151+
owner:=coderdtest.CreateFirstUser(t,client)
152+
memberClient,memberUser:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID)
153+
154+
// Create two AI tasks: one running, one stopped.
155+
running:=makeAITask(t,db,owner.OrganizationID,owner.UserID,memberUser.ID,database.WorkspaceTransitionStart,"keep me running")
156+
stopped:=makeAITask(t,db,owner.OrganizationID,owner.UserID,memberUser.ID,database.WorkspaceTransitionStop,"stop me please")
157+
158+
// Use JSON output to reliably validate filtering.
159+
inv,root:=clitest.New(t,"exp","task","list","--status=stopped","--output=json")
160+
clitest.SetupConfig(t,memberClient,root)
161+
162+
ctx:=testutil.Context(t,testutil.WaitShort)
163+
varstdout bytes.Buffer
164+
inv.Stdout=&stdout
165+
inv.Stderr=&stdout
166+
167+
err:=inv.WithContext(ctx).Run()
168+
require.NoError(t,err)
169+
170+
vartasks []codersdk.Task
171+
require.NoError(t,json.Unmarshal(stdout.Bytes(),&tasks))
172+
173+
// Only the stopped task is returned.
174+
require.Len(t,tasks,1,"expected one task after filtering")
175+
require.Equal(t,stopped.ID,tasks[0].ID)
176+
require.NotEqual(t,running.ID,tasks[0].ID)
177+
})
178+
179+
t.Run("UserFlag_Me_Table",func(t*testing.T) {
180+
t.Parallel()
181+
182+
quiet:=slog.Make(sloghuman.Sink(io.Discard))
183+
client,db:=coderdtest.NewWithDatabase(t,&coderdtest.Options{Logger:&quiet})
184+
owner:=coderdtest.CreateFirstUser(t,client)
185+
_,memberUser:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID)
186+
187+
_=makeAITask(t,db,owner.OrganizationID,owner.UserID,memberUser.ID,database.WorkspaceTransitionStart,"other-task")
188+
ws:=makeAITask(t,db,owner.OrganizationID,owner.UserID,owner.UserID,database.WorkspaceTransitionStart,"me-task")
189+
190+
inv,root:=clitest.New(t,"exp","task","list","--user","me")
191+
clitest.SetupConfig(t,client,root)
192+
193+
pty:=ptytest.New(t).Attach(inv)
194+
ctx:=testutil.Context(t,testutil.WaitShort)
195+
196+
err:=inv.WithContext(ctx).Run()
197+
require.NoError(t,err)
198+
199+
pty.ExpectMatch(ws.Name)
200+
})
201+
}
202+
203+
funcTestExpTaskList_OwnerCanListOthers(t*testing.T) {
204+
t.Parallel()
205+
206+
// Quiet logger to reduce noise.
207+
quiet:=slog.Make(sloghuman.Sink(io.Discard))
208+
ownerClient,db:=coderdtest.NewWithDatabase(t,&coderdtest.Options{Logger:&quiet})
209+
owner:=coderdtest.CreateFirstUser(t,ownerClient)
210+
211+
// Create two additional members in the owner's organization.
212+
_,memberAUser:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID)
213+
_,memberBUser:=coderdtest.CreateAnotherUser(t,ownerClient,owner.OrganizationID)
214+
215+
// Seed an AI task for member A and B.
216+
_=makeAITask(t,db,owner.OrganizationID,owner.UserID,memberAUser.ID,database.WorkspaceTransitionStart,"member-A-task")
217+
_=makeAITask(t,db,owner.OrganizationID,owner.UserID,memberBUser.ID,database.WorkspaceTransitionStart,"member-B-task")
218+
219+
t.Run("OwnerListsSpecificUserWithUserFlag_JSON",func(t*testing.T) {
220+
t.Parallel()
221+
222+
// As the owner, list only member A tasks.
223+
inv,root:=clitest.New(t,"exp","task","list","--user",memberAUser.Username,"--output=json")
224+
clitest.SetupConfig(t,ownerClient,root)
225+
226+
varstdout bytes.Buffer
227+
inv.Stdout=&stdout
228+
229+
ctx:=testutil.Context(t,testutil.WaitShort)
230+
231+
err:=inv.WithContext(ctx).Run()
232+
require.NoError(t,err)
233+
234+
vartasks []codersdk.Task
235+
require.NoError(t,json.Unmarshal(stdout.Bytes(),&tasks))
236+
237+
// Expect at least one task and all tasks to belong to member A.
238+
require.NotEmpty(t,tasks,"expected at least one task for member A")
239+
for_,task:=rangetasks {
240+
require.Equal(t,memberAUser.ID,task.OwnerID,"expected only member A tasks")
241+
}
242+
})
243+
244+
t.Run("OwnerListsAllWithAllFlag_JSON",func(t*testing.T) {
245+
t.Parallel()
246+
247+
// As the owner, list all tasks to verify both member tasks are present.
248+
// Use JSON output to reliably validate filtering.
249+
inv,root:=clitest.New(t,"exp","task","list","--all","--output=json")
250+
clitest.SetupConfig(t,ownerClient,root)
251+
252+
varstdout bytes.Buffer
253+
inv.Stdout=&stdout
254+
255+
ctx:=testutil.Context(t,testutil.WaitShort)
256+
257+
err:=inv.WithContext(ctx).Run()
258+
require.NoError(t,err)
259+
260+
vartasks []codersdk.Task
261+
require.NoError(t,json.Unmarshal(stdout.Bytes(),&tasks))
262+
263+
// Expect at least two tasks and ensure both owners (member A and member B) are represented.
264+
require.GreaterOrEqual(t,len(tasks),2,"expected two or more tasks in --all listing")
265+
266+
// Use slice.Find for concise existence checks.
267+
_,foundA:=slice.Find(tasks,func(t codersdk.Task)bool {returnt.OwnerID==memberAUser.ID })
268+
_,foundB:=slice.Find(tasks,func(t codersdk.Task)bool {returnt.OwnerID==memberBUser.ID })
269+
270+
require.True(t,foundA,"expected at least one task for member A in --all listing")
271+
require.True(t,foundB,"expected at least one task for member B in --all listing")
272+
})
273+
}

‎coderd/aitasks.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ func (api *API) tasksList(rw http.ResponseWriter, r *http.Request) {
280280
// Ensure that we only include AI task workspaces in the results.
281281
filter.HasAITask= sql.NullBool{Valid:true,Bool:true}
282282

283-
iffilter.OwnerUsername=="me"||filter.OwnerUsername==""{
283+
iffilter.OwnerUsername=="me" {
284284
filter.OwnerID=apiKey.UserID
285285
filter.OwnerUsername=""
286286
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp