Minigame Leaderboard Testing - UQcsse3200/2024-studio-2 GitHub Wiki

1. Overview

The PlayFab class handles user registration, login, and leaderboard management via PlayFab's client API. It allows for initializing the PlayFab client with a Title ID, and provides methods for user registration, login, updating leaderboards, andsubmitting scores.

2. Test Cases

2.1 Initial Set Up

As almost the functions in PlayFab are using APIs, it could cause throttling when users call these functions multiple times within a short period. Therefore, the leaderboard tests will mainly use mockito to test. Firstly, we need to initialize 3 different leadboards and assign some values to them. Then we need to mock that when the PlayFabClientAPI.GetLeaderboard() is called, it will return one of the leaderboards that we defined before based on the given leaderboardName.

mockedAPI = mockStatic(PlayFabClientAPI.class);
mockedAPI.when(() -> PlayFabClientAPI.GetLeaderboard(any(GetLeaderboardRequest.class)))
      .thenAnswer(invocation -> {
             String leaderboardName = ((GetLeaderboardRequest) invocation.getArgument(0)).StatisticName;
             switch (leaderboardName) {
                   case "Snake":
                       return mockSnakeLeaderboardResult;
                   case "Bird":
                       return mockBirdLeaderboardResult;
                   case "Fish":
                       return mockFishLeaderboardResult;
                   default:
                       throw new IllegalArgumentException("Unknown leaderboard: " + leaderboardName);
              }
       });

Besides, we also need to mock the PlayFabClientAPI.UpdatePlayerStatistics, which used for submitting player' scores to ensure that the score is added to the leaderboard.

mockedAPI.when(() -> PlayFabClientAPI.UpdatePlayerStatistics(any(UpdatePlayerStatisticsRequest.class)))
      .thenAnswer(invocation -> {
          UpdatePlayerStatisticsRequest request = invocation.getArgument(0);
          int score = request.Statistics.get(0).Value;
          String leaderboardName = request.Statistics.get(0).StatisticName; // Get the leaderboard type from the request

          GetLeaderboardResult result;
          switch (leaderboardName) {
              case "Snake":
                   result = mockSnakeLeaderboardResult.Result;
                   break;
              case "Bird":
                   result = mockBirdLeaderboardResult.Result;
                   break;
              case "Fish":
                   result = mockFishLeaderboardResult.Result;
                   break;
              default:
                   throw new IllegalArgumentException("Unknown leaderboard: " + leaderboardName);
           }
           // Check if the new user already exists in the leaderboard
           PlayerLeaderboardEntry existingEntry = null;
           for (PlayerLeaderboardEntry entry : result.Leaderboard) {
               if (newUser.equals(entry.DisplayName)) {
                   existingEntry = entry;
                   break;
               }
           }

           // If the user does not exist, then add them to the leaderboard
           if (existingEntry == null) {
               PlayerLeaderboardEntry newEntry = new PlayerLeaderboardEntry();
               newEntry.DisplayName = newUser;
               newEntry.StatValue = score;
               result.Leaderboard.add(newEntry);
           }
           return mockSuccessResult;
       });

Finally, we need to close the mockAPI after running each test. Thus, we need to use @AfterEach method.

@AfterEach
public void closeMockedAPI() {
    if (mockedAPI != null) {
       mockedAPI.close();
    }
}

2.2 Update Snake Leaderboard

  • Purpose: This test verifies that the snake leaderboard is updated when the user give a "Snake" String into the update function.

  • What it does: Mocks the PlayFabClientAPI.GetLeaderboard() and returns the leaderboard based on the given string.

  • Why This Test: Ensures that the correct leaderboard is returned.

  • Code:

@Test
    public void testUpdateSnakeLeaderboard() {
        // Act
        PlayFab.updateLeaderboard("Snake");
        // Assert
        assertEquals(3, playFab.getUsernames().size());
        assertEquals(3, playFab.getHighscores().size());
        assertEquals("User0", playFab.getUsernames().get(0));
        assertEquals("10", playFab.getHighscores().get(0));
        assertEquals("User1", playFab.getUsernames().get(1));
        assertEquals("9", playFab.getHighscores().get(1));
        assertEquals("User2", playFab.getUsernames().get(2));
        assertEquals("8", playFab.getHighscores().get(2));
    }

2.3 Update Bird Leaderboard

  • Purpose: This test verifies that the bird leaderboard is updated when the user give a "Bird" String into the update function.

  • What it does: Mocks the PlayFabClientAPI.GetLeaderboard() and returns the leaderboard based on the given string.

  • Why This Test: Ensures that the correct leaderboard is returned.

  • Code:

@Test
    public void testUpdateBirdLeaderboard() {
        // Act
        PlayFab.updateLeaderboard("Bird");
        // Assert
        assertEquals(3, playFab.getUsernames().size());
        assertEquals(3, playFab.getHighscores().size());
        assertEquals("User3", playFab.getUsernames().get(0));
        assertEquals("7", playFab.getHighscores().get(0));
        assertEquals("User4", playFab.getUsernames().get(1));
        assertEquals("6", playFab.getHighscores().get(1));
        assertEquals("User5", playFab.getUsernames().get(2));
        assertEquals("5", playFab.getHighscores().get(2));
    }

2.4 Update Fish Leaderboard

  • Purpose: This test verifies that the fish leaderboard is updated when the user give a "Fish" String into the update function.

  • What it does: Mocks the PlayFabClientAPI.GetLeaderboard() and returns the leaderboard based on the given string.

  • Why This Test: Ensures that the correct leaderboard is returned.

  • Code:

@Test
    public void testUpdateFishLeaderboard() {
        // Act
        PlayFab.updateLeaderboard("Fish");
        // Assert
        assertEquals(2, playFab.getUsernames().size());
        assertEquals(2, playFab.getHighscores().size());
        assertEquals("User6", playFab.getUsernames().get(0));
        assertEquals("4", playFab.getHighscores().get(0));
        assertEquals("User7", playFab.getUsernames().get(1));
        assertEquals("3", playFab.getHighscores().get(1));
    }

2.5 New User Submit Score To Snake Leaderboard

  • Purpose: This test verifies that the snake leaderboard is added one more entry when logged user submits new score

  • What it does: Mocks the PlayFabClientAPI.UpdatePlayerStatistics() to send the request to PlayFab, which submits score for the logged user.

  • Why This Test: Ensures that a new value is added to the right leaderboard.

  • Code:

@Test
    public void testSubmitSnakeScoreNewUser() {
        PlayFab.isLogin = true;
        // Act
        PlayFab.submitScore("Snake", 20);
        PlayFab.updateLeaderboard("Snake");
        // Assert
        assertEquals(4, mockSnakeLeaderboardResult.Result.Leaderboard.size()); // New user added
        assertEquals(newUser, playFab.getUsernames().get(3));
        assertEquals("20", playFab.getHighscores().get(3));
    }

2.6 New User Submit Score To Bird Leaderboard

  • Purpose: This test verifies that the bird leaderboard is added one more entry when logged user submits new score

  • What it does: Mocks the PlayFabClientAPI.UpdatePlayerStatistics() to send the request to PlayFab, which submits score for the logged user.

  • Why This Test: Ensures that a new value is added to the right leaderboard.

  • Code:

@Test
    public void testSubmitBirdScoreNewUser() {
        PlayFab.isLogin = true;
        // Act
        PlayFab.submitScore("Bird", 20);
        PlayFab.updateLeaderboard("Bird");
        // Assert
        assertEquals(4, mockBirdLeaderboardResult.Result.Leaderboard.size()); // New user added
        assertEquals(newUser, playFab.getUsernames().get(3));
        assertEquals("20", playFab.getHighscores().get(3));
    }

2.7 New User Submit Score To Fish Leaderboard

  • Purpose: This test verifies that the fish leaderboard is added one more entry when logged user submits new score

  • What it does: Mocks the PlayFabClientAPI.UpdatePlayerStatistics() to send the request to PlayFab, which submits score for the logged user.

  • Why This Test: Ensures that a new value is added to the right leaderboard.

  • Code:

@Test
    public void testSubmitFishScoreNewUser() {
        PlayFab.isLogin = true;
        // Act
        PlayFab.submitScore("Fish", 20);
        PlayFab.updateLeaderboard("Fish");
        // Assert
        assertEquals(3, mockFishLeaderboardResult.Result.Leaderboard.size()); // New user added
        assertEquals(newUser, playFab.getUsernames().get(2));
        assertEquals("20", playFab.getHighscores().get(2));
    }