@@ -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,51 @@ 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
+ // nolint:gocritic // Unit test
96
+ err := api .Database .UpdateUserDeletedByID (dbauthz .AsSystemRestricted (ctx ), database.UpdateUserDeletedByIDParams {
97
+ ID : deleteMeUser .ID ,
98
+ Deleted : true ,
99
+ })
100
+ require .NoError (t , err )
101
+
102
+ inv , root := clitest .New (t , "delete" , fmt .Sprintf ("%s/%s" , deleteMeUser .ID , workspace .Name ), "-y" , "--orphan" )
103
+
104
+ clitest .SetupConfig (t , client , root )
105
+ doneChan := make (chan struct {})
106
+ pty := ptytest .New (t ).Attach (inv )
107
+ inv .Stderr = pty .Output ()
108
+ go func () {
109
+ defer close (doneChan )
110
+ err := inv .Run ()
111
+ // When running with the race detector on, we sometimes get an EOF.
112
+ if err != nil {
113
+ assert .ErrorIs (t , err , io .EOF )
114
+ }
115
+ }()
116
+ pty .ExpectMatch ("workspace has been deleted" )
117
+ <- doneChan
118
+ })
119
+
71
120
t .Run ("DifferentUser" , func (t * testing.T ) {
72
121
t .Parallel ()
73
122
adminClient := coderdtest .New (t , & coderdtest.Options {IncludeProvisionerDaemon : true })
0 commit comments