Skip to content

Commit

Permalink
feat: Add quietLogout method
Browse files Browse the repository at this point in the history
`quietLogout` skips firing interception events and logs out the currently logged in user.  This is useful in testing scenarios where your "logged in" user may no longer exist in your database.
  • Loading branch information
elpete authored Mar 4, 2021
2 parents c43353a + bae8be0 commit ffe62b2
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 7 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,19 @@ This method returns the passed in `user` object.

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| No arguments |
| quiet | boolean | false | false | Skips firing interception events if `true` |

Logs a user out of system. This method can be called regardless of if there is currently a logged in user.
This method fires two interception events: `preLogout` and `postLogout`. The `preLogout` event recieves the currently logged-in user, if there is one.

### `quietLogout`

| name | type | required | default | description |
| --- | --- | --- | --- | --- |
| No arguments |

Logs a user out of system without firing interception events.
Useful in testing situations where the "logged in" user may no longer exist in your database.

### `authenticate`

Expand Down
25 changes: 19 additions & 6 deletions models/AuthenticationService.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,32 @@ component singleton {
/**
* Logout a user
*/
public void function logout() {
public void function logout( boolean quiet = false ) {
// Annouce pre logout with or without user
variables.interceptorService.processState(
"preLogout",
{ user: isLoggedIn() ? getUser() : javacast( "null", "" ) }
);
if ( !arguments.quiet ) {
variables.interceptorService.processState(
"preLogout",
{ user: isLoggedIn() ? getUser() : javacast( "null", "" ) }
);
}

// cleanup
variables.sessionStorage.delete( variables.USER_ID_KEY );
variables.requestStorage.delete( variables.USER_KEY );

// Announce post logout
variables.interceptorService.processState( "postLogout", {} );
if ( !arguments.quiet ) {
variables.interceptorService.processState( "postLogout", {} );
}
}

/**
* Logout a user without raising interceptor events.
* Useful when testing "logged in" user no longer exists.
*/
public void function quietLogout() {
arguments.quiet = true;
logout( argumentCollection = arguments );
}

/**
Expand Down
48 changes: 48 additions & 0 deletions tests/specs/AuthenticationSpec.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,54 @@ component extends="testbox.system.BaseSpec" {
"[postLogin] should have been announced."
);
} );

it( "announces a preLogout and postLogout interception point", function() {
sessionStorageMock.$( "delete", true ).$( "exists", false );
requestStorageMock.$( "delete", true );

auth.logout();

var processStateCallLog = interceptorServiceMock.$callLog().processState;

expect( processStateCallLog ).toHaveLength( 2, "Two events should have been announced" );
expect( processStateCallLog[ 1 ][ 1 ] ).toBe(
"preLogout",
"[preLogout] should have been announced."
);
expect( processStateCallLog[ 2 ][ 1 ] ).toBe(
"postLogout",
"[postLogout] should have been announced."
);
} );

it( "the current user is provided to the preLogout interception point", function() {
sessionStorageMock.$( "delete", true ).$( "exists", true );
requestStorageMock.$( "delete", true );
auth.$( "getUser", userMock );

auth.logout();

var processStateCallLog = interceptorServiceMock.$callLog().processState;

expect( processStateCallLog ).toHaveLength( 2, "Two events should have been announced" );
expect( processStateCallLog[ 1 ][ 1 ] ).toBe(
"preLogout",
"[preLogout] should have been announced."
);
expect( processStateCallLog[ 1 ][ 2 ].user ).toBe( userMock );
} );

it( "skips interceptor events when using quietLogout", function() {
sessionStorageMock.$( "delete", true ).$( "exists", false );
requestStorageMock.$( "delete", true );
auth.$( "getUser", userMock );

auth.quietLogout();

var processStateCallLog = interceptorServiceMock.$callLog().processState;

expect( processStateCallLog ).toHaveLength( 0, "No events should have been announced" );
} );
} );

it( "returns the user if the user was successfully authenticated", function() {
Expand Down

0 comments on commit ffe62b2

Please sign in to comment.