@@ -45,7 +45,7 @@ class RoleReconcilerTest {
4545
4646 @ Test
4747 @ DisplayName ("When a Role (LOGIN) is created, it should be reconciled to READY and present in pg_authid" )
48- void createRole_withLogin_andStatusReady () {
48+ void createRole_withLogin_andStatusReady () throws SQLException {
4949 // given
5050 var clusterConnection = given .one ()
5151 .clusterConnection ()
@@ -79,20 +79,15 @@ void createRole_withLogin_andStatusReady() {
7979 now
8080 );
8181
82- DSLContext dsl ;
83- try {
84- dsl = postgreSQLContextFactory .getDSLContext (clusterConnection );
85- } catch (Exception e ) {
86- throw new AssertionError ("Failed to obtain DSLContext" , e );
87- }
82+ var dsl = postgreSQLContextFactory .getDSLContext (clusterConnection );
8883
8984 assertThat (RoleUtil .roleExists (dsl , reconciled .getSpec ())).isTrue ();
9085 assertThat (RoleUtil .roleLoginMatches (dsl , reconciled .getSpec ())).isTrue ();
9186 }
9287
9388 @ Test
9489 @ DisplayName ("When a Role (NOLOGIN) is created, it should be reconciled to READY and present with NOLOGIN" )
95- void createRole_withoutLogin_andStatusReady () {
90+ void createRole_withoutLogin_andStatusReady () throws SQLException {
9691 // given
9792 var clusterConnection = given .one ()
9893 .clusterConnection ()
@@ -122,17 +117,79 @@ void createRole_withoutLogin_andStatusReady() {
122117 now
123118 );
124119
125- DSLContext dsl ;
126- try {
127- dsl = postgreSQLContextFactory .getDSLContext (clusterConnection );
128- } catch (Exception e ) {
129- throw new AssertionError ("Failed to obtain DSLContext" , e );
130- }
120+ var dsl = postgreSQLContextFactory .getDSLContext (clusterConnection );
131121
132122 assertThat (RoleUtil .roleExists (dsl , reconciled .getSpec ())).isTrue ();
133123 assertThat (RoleUtil .roleLoginMatches (dsl , reconciled .getSpec ())).isTrue ();
134124 }
135125
126+ @ Test
127+ @ DisplayName ("When a Role login state is changed, it should be updated correctly in pg_authid" )
128+ void toggleRoleLogin_updatesCorrectly () throws SQLException {
129+ // given
130+ var clusterConnection = given .one ()
131+ .clusterConnection ()
132+ .withName ("test-connection-role-toggle-login" )
133+ .returnFirst ();
134+
135+ var now = OffsetDateTime .now (ZoneOffset .UTC );
136+ var roleName = "test-role-toggle-login" ;
137+
138+ // 1. Create a Role without a login (no passwordSecretRef)
139+ var role = buildRole (
140+ roleName ,
141+ clusterConnection .getMetadata ().getName (),
142+ /*login*/ false
143+ );
144+
145+ // when
146+ var reconciled = applyRole (role );
147+
148+ // then
149+ assertThatRoleHasExpectedStatus (
150+ reconciled ,
151+ new CRStatus ()
152+ .setName (roleName )
153+ .setPhase (CRPhase .READY )
154+ .setObservedGeneration (1L ),
155+ now
156+ );
157+
158+ var dsl = postgreSQLContextFactory .getDSLContext (clusterConnection );
159+
160+ assertThat (
161+ RoleUtil .roleExists (dsl , reconciled .getSpec ())
162+ ).isTrue ();
163+
164+ assertThat (
165+ getRoleFlagValue (dsl , roleName , PG_AUTHID .ROLCANLOGIN )
166+ ).isFalse ();
167+
168+ // 2. Add a passwordSecretRef to make it a login role
169+ role .getSpec ().setPasswordSecretRef (clusterConnection .getSpec ().getAdminSecretRef ());
170+
171+ // when
172+ applyRole (
173+ role ,
174+ r -> r .getStatus ().getObservedGeneration () == 2L
175+ );
176+
177+ // then
178+ assertThat (getRoleFlagValue (dsl , roleName , PG_AUTHID .ROLCANLOGIN )).isTrue ();
179+
180+ // 3. Remove passwordSecretRef again
181+ role .getSpec ().setPasswordSecretRef (null );
182+
183+ // when
184+ applyRole (
185+ role ,
186+ r -> r .getStatus ().getObservedGeneration () == 3L
187+ );
188+
189+ // then
190+ assertThat (getRoleFlagValue (dsl , roleName , PG_AUTHID .ROLCANLOGIN )).isFalse ();
191+ }
192+
136193 @ Test
137194 @ DisplayName ("When a Role references a missing ClusterConnection, status should be PENDING with a helpful message" )
138195 void createRole_withMissingClusterConnection_setsPending () {
0 commit comments