Skip to content

Commit

Permalink
test: Add tests for active users update across different API calls (#586
Browse files Browse the repository at this point in the history
)

* test: Add tests for active users update across different API calls

* fix: Suppress usermapping exceptions for active users monitoring (#587)
  • Loading branch information
KShivendu authored Mar 22, 2023
1 parent 4e13470 commit b02a420
Show file tree
Hide file tree
Showing 15 changed files with 281 additions and 28 deletions.
4 changes: 4 additions & 0 deletions src/main/java/io/supertokens/ActiveUsers.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ public static void updateLastActive(Main main, String userId) {
} catch (StorageQueryException ignored) {
}
}

public static int countUsersActiveSince(Main main, long time) throws StorageQueryException {
return StorageLayer.getActiveUsersStorage(main).countUsersActiveSince(time);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@

package io.supertokens.webserver.api.session;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import io.supertokens.ActiveUsers;
import io.supertokens.Main;
Expand Down Expand Up @@ -66,14 +64,18 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
SessionInformationHolder sessionInfo = Session.refreshSession(main, refreshToken, antiCsrfToken,
enableAntiCsrf);

UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(super.main,
sessionInfo.session.userId, UserIdType.ANY);
if (userIdMapping != null) {
ActiveUsers.updateLastActive(main, userIdMapping.superTokensUserId);
} else {
ActiveUsers.updateLastActive(main, sessionInfo.session.userId);
try{
UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(super.main,
sessionInfo.session.userId, UserIdType.ANY);
if (userIdMapping != null) {
ActiveUsers.updateLastActive(main, userIdMapping.superTokensUserId);
} else {
ActiveUsers.updateLastActive(main, sessionInfo.session.userId);
}
} catch (StorageQueryException ignored){
}


JsonObject result = sessionInfo.toJsonObject();
result.addProperty("status", "OK");
super.sendJsonResponse(200, result, resp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,15 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
SessionInformationHolder sessionInfo = Session.createNewSession(main, userId, userDataInJWT,
userDataInDatabase, enableAntiCsrf);

UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(super.main,
sessionInfo.session.userId, UserIdType.ANY);
if (userIdMapping != null) {
ActiveUsers.updateLastActive(main, userIdMapping.superTokensUserId);
} else {
ActiveUsers.updateLastActive(main, sessionInfo.session.userId);
try {
UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(super.main,
sessionInfo.session.userId, UserIdType.ANY);
if (userIdMapping != null) {
ActiveUsers.updateLastActive(main, userIdMapping.superTokensUserId);
} else {
ActiveUsers.updateLastActive(main, sessionInfo.session.userId);
}
} catch (StorageQueryException ignored) {
}

JsonObject result = sessionInfo.toJsonObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,16 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
try {
String[] sessionHandlesRevoked = Session.revokeAllSessionsForUser(main, userId);

UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(super.main,
userId, UserIdType.ANY);
if (userIdMapping != null) {
ActiveUsers.updateLastActive(main, userIdMapping.superTokensUserId);
} else {
ActiveUsers.updateLastActive(main, userId);
try {
UserIdMapping userIdMapping = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping(
super.main,
userId, UserIdType.ANY);
if (userIdMapping != null) {
ActiveUsers.updateLastActive(main, userIdMapping.superTokensUserId);
} else {
ActiveUsers.updateLastActive(main, userId);
}
} catch (StorageQueryException ignored) {
}

JsonObject result = new JsonObject();
Expand Down
61 changes: 61 additions & 0 deletions src/test/java/io/supertokens/test/ActiveUsersTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.supertokens.test;

import static org.junit.Assert.assertNotNull;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;

import io.supertokens.pluginInterface.STORAGE_TYPE;
import io.supertokens.storageLayer.StorageLayer;
import io.supertokens.ActiveUsers;
import io.supertokens.Main;
import io.supertokens.ProcessState;

public class ActiveUsersTest {

@Rule
public TestRule watchman = Utils.getOnFailure();

@AfterClass
public static void afterTesting() {
Utils.afterTesting();
}

@Before
public void beforeEach() {
Utils.reset();
}

@Test
public void updateAndCountUserLastActiveTest() throws Exception {
String[] args = { "../" };

TestingProcessManager.TestingProcess process = TestingProcessManager.start(args);
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED));

if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) {
assert (false);
}

Main main = process.getProcess();
long now = System.currentTimeMillis();

assert ActiveUsers.countUsersActiveSince(main, now) == 0;

ActiveUsers.updateLastActive(main, "user1");
ActiveUsers.updateLastActive(main, "user2");

assert ActiveUsers.countUsersActiveSince(main, now) == 2;

long now2 = System.currentTimeMillis();

ActiveUsers.updateLastActive(main, "user1");

assert ActiveUsers.countUsersActiveSince(main, now) == 2; // user1 just got updated
assert ActiveUsers.countUsersActiveSince(main, now2) == 1; // only user1 is counted
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package io.supertokens.test.emailpassword.api;

import com.google.gson.JsonObject;

import io.supertokens.ActiveUsers;
import io.supertokens.ProcessState;
import io.supertokens.pluginInterface.STORAGE_TYPE;
import io.supertokens.storageLayer.StorageLayer;
Expand Down Expand Up @@ -68,6 +70,8 @@ public void testBadInput() throws Exception {
return;
}

long startTs = System.currentTimeMillis();

{
try {
HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
Expand Down Expand Up @@ -107,6 +111,9 @@ public void testBadInput() throws Exception {
}
}

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 0);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Expand All @@ -133,6 +140,8 @@ public void testGoodInput() throws Exception {
responseBody.addProperty("email", "random@gmail.com");
responseBody.addProperty("password", "validPass123");

long beforeSignIn = System.currentTimeMillis();

JsonObject signInResponse = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
"http://localhost:3567/recipe/signin", responseBody, 1000, 1000, null, Utils.getCdiVersion2_7ForTests(),
"emailpassword");
Expand All @@ -147,11 +156,15 @@ public void testGoodInput() throws Exception {
signInResponse.get("user").getAsJsonObject().get("timeJoined").getAsLong();
assertEquals(signInResponse.get("user").getAsJsonObject().entrySet().size(), 3);

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), beforeSignIn);
assert (activeUsers == 1);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

// Test that sign in with unnormalised email like Test@gmail.com should also work
// Test that sign in with unnormalised email like Test@gmail.com should also
// work
@Test
public void testThatUnnormalisedEmailShouldAlsoWork() throws Exception {
String[] args = { "../" };
Expand Down Expand Up @@ -190,7 +203,8 @@ public void testThatUnnormalisedEmailShouldAlsoWork() throws Exception {
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

// Test that giving an empty password, empty email, invalid email, random email or wrong password throws a wrong
// Test that giving an empty password, empty email, invalid email, random email
// or wrong password throws a wrong
// * credentials error
@Test
public void testInputsToSignInAPI() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package io.supertokens.test.emailpassword.api;

import com.google.gson.JsonObject;

import io.supertokens.ActiveUsers;
import io.supertokens.ProcessState;
import io.supertokens.pluginInterface.STORAGE_TYPE;
import io.supertokens.pluginInterface.emailpassword.UserInfo;
Expand Down Expand Up @@ -68,6 +70,8 @@ public void testBadInput() throws Exception {
return;
}

long beforeTestTs = System.currentTimeMillis();

{
try {
HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
Expand Down Expand Up @@ -107,6 +111,9 @@ public void testBadInput() throws Exception {
}
}

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), beforeTestTs);
assert (activeUsers == 0);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Expand All @@ -123,6 +130,8 @@ public void testGoodInput() throws Exception {
return;
}

long beforeSignUpTs = System.currentTimeMillis();

JsonObject signUpResponse = Utils.signUpRequest_2_5(process, "random@gmail.com", "validPass123");
assertEquals(signUpResponse.get("status").getAsString(), "OK");
assertEquals(signUpResponse.entrySet().size(), 2);
Expand All @@ -131,6 +140,9 @@ public void testGoodInput() throws Exception {
assertEquals(signUpUser.get("email").getAsString(), "random@gmail.com");
assertNotNull(signUpUser.get("id"));

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), beforeSignUpTs);
assert (activeUsers == 0);

UserInfo user = StorageLayer.getEmailPasswordStorage(process.getProcess())
.getUserInfoUsingEmail("random@gmail.com");
assertEquals(user.email, signUpUser.get("email").getAsString());
Expand Down Expand Up @@ -160,7 +172,8 @@ public void testGoodInput() throws Exception {

// Test the normalise email function
// Test that only the normalised email is saved in the db
// Failure condition: If the email retrieved from the data is not normalised the test will fail
// Failure condition: If the email retrieved from the data is not normalised the
// test will fail
@Test
public void testTheNormaliseEmailFunction() throws Exception {
String[] args = { "../" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ public void testConsumeLinkCodeWithExistingUser() throws Exception {
}

/**
* Check device clean up when user input code is generated via email & phone number
* Check device clean up when user input code is generated via email & phone
* number
*
* @throws Exception
*/
Expand Down Expand Up @@ -732,7 +733,8 @@ public void testConsumeWrongLinkCodeExceedingMaxAttempts() throws Exception {
}

/**
* user input code with too many failedAttempts (changed maxCodeInputAttempts configuration between consumes)
* user input code with too many failedAttempts (changed maxCodeInputAttempts
* configuration between consumes)
* TODO: review -> do we need to create code again post restart ?
*
* @throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.junit.Test;
import org.junit.rules.TestRule;

import io.supertokens.ActiveUsers;
import io.supertokens.ProcessState;
import io.supertokens.passwordless.Passwordless;
import io.supertokens.passwordless.Passwordless.CreateCodeResponse;
Expand Down Expand Up @@ -62,6 +63,8 @@ public void testBadInput() throws Exception {
return;
}

long startTs = System.currentTimeMillis();

String email = "test@example.com";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);
{
Expand Down Expand Up @@ -276,6 +279,9 @@ public void testBadInput() throws Exception {
error.getMessage());
}

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 0);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Expand All @@ -291,6 +297,8 @@ public void testLinkCode() throws Exception {
return;
}

long startTs = System.currentTimeMillis();

String email = "test@example.com";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);

Expand All @@ -304,6 +312,9 @@ public void testLinkCode() throws Exception {

checkResponse(response, true, email, null);

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 1);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Expand All @@ -321,6 +332,8 @@ public void testExpiredLinkCode() throws Exception {
return;
}

long startTs = System.currentTimeMillis();

String email = "test@example.com";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);
Thread.sleep(150);
Expand All @@ -334,6 +347,9 @@ public void testExpiredLinkCode() throws Exception {

assertEquals("RESTART_FLOW_ERROR", response.get("status").getAsString());

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 0);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Expand All @@ -349,6 +365,8 @@ public void testUserInputCode() throws Exception {
return;
}

long startTs = System.currentTimeMillis();

String email = "test@example.com";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);

Expand All @@ -363,6 +381,9 @@ public void testUserInputCode() throws Exception {

checkResponse(response, true, email, null);

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 1);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Expand All @@ -379,6 +400,8 @@ public void testExpiredUserInputCode() throws Exception {
return;
}

long startTs = System.currentTimeMillis();

String email = "test@example.com";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);
Thread.sleep(150);
Expand All @@ -394,6 +417,9 @@ public void testExpiredUserInputCode() throws Exception {

assertEquals("EXPIRED_USER_INPUT_CODE_ERROR", response.get("status").getAsString());

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 0);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}
Expand Down
Loading

0 comments on commit b02a420

Please sign in to comment.