@@ -2,6 +2,7 @@ package cli_test
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"io"
6
7
"testing"
7
8
@@ -10,8 +11,11 @@ import (
10
11
11
12
"github.com/coder/coder/cli/clitest"
12
13
"github.com/coder/coder/coderd/coderdtest"
14
+ "github.com/coder/coder/coderd/database"
15
+ "github.com/coder/coder/coderd/database/dbauthz"
13
16
"github.com/coder/coder/codersdk"
14
17
"github.com/coder/coder/pty/ptytest"
18
+ "github.com/coder/coder/testutil"
15
19
)
16
20
17
21
func TestDelete (t * testing.T ) {
@@ -68,6 +72,54 @@ func TestDelete(t *testing.T) {
68
72
<- doneChan
69
73
})
70
74
75
+ // Super orphaned, as the workspace doesn't even have a user.
76
+ // This is not a scenario we should ever get into, as we do not allow users
77
+ // to be deleted if they have workspaces. However issue #7872 shows that
78
+ // it is possible to get into this state. An admin should be able to still
79
+ // force a delete action on the workspace.
80
+ t .Run ("OrphanDeletedUser" , func (t * testing.T ) {
81
+ t .Parallel ()
82
+ client , _ , api := coderdtest .NewWithAPI (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
83
+ user := coderdtest .CreateFirstUser (t , client )
84
+ deleteMeClient , deleteMeUser := coderdtest .CreateAnotherUser (t , client , user .OrganizationID )
85
+ version := coderdtest .CreateTemplateVersion (t , client , user .OrganizationID , nil )
86
+ coderdtest .AwaitTemplateVersionJob (t , client , version .ID )
87
+ template := coderdtest .CreateTemplate (t , client , user .OrganizationID , version .ID )
88
+
89
+ workspace := coderdtest .CreateWorkspace (t , deleteMeClient , user .OrganizationID , template .ID )
90
+ coderdtest .AwaitWorkspaceBuildJob (t , deleteMeClient , workspace .LatestBuild .ID )
91
+
92
+ // The API checks if the user has any workspaces, so we cannot delete a user
93
+ // this way.
94
+ ctx := testutil .Context (t , testutil .WaitShort )
95
+ var _ = ctx
96
+ var _ = api
97
+ var _ = deleteMeUser
98
+ // nolint:gocritic // Unit test
99
+ err := api .Database .UpdateUserDeletedByID (dbauthz .AsSystemRestricted (ctx ), database.UpdateUserDeletedByIDParams {
100
+ ID : deleteMeUser .ID ,
101
+ Deleted : true ,
102
+ })
103
+ require .NoError (t , err )
104
+
105
+ inv , root := clitest .New (t , "delete" , fmt .Sprintf ("%s/%s" , deleteMeUser .ID , workspace .ID ), "-y" , "--orphan" )
106
+
107
+ clitest .SetupConfig (t , client , root )
108
+ doneChan := make (chan struct {})
109
+ pty := ptytest .New (t ).Attach (inv )
110
+ inv .Stderr = pty .Output ()
111
+ go func () {
112
+ defer close (doneChan )
113
+ err := inv .Run ()
114
+ // When running with the race detector on, we sometimes get an EOF.
115
+ if err != nil {
116
+ assert .ErrorIs (t , err , io .EOF )
117
+ }
118
+ }()
119
+ pty .ExpectMatch ("workspace has been deleted" )
120
+ <- doneChan
121
+ })
122
+
71
123
t .Run ("DifferentUser" , func (t * testing.T ) {
72
124
t .Parallel ()
73
125
adminClient := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
0 commit comments