Skip to content

Commit 9001f2a

Browse files
Erik Bylundkirre-bylund
authored andcommitted
Revamp of Unity Integration Tests
This is a squashed commit of a long living branch. This commit consists of: 1. Initial workflow that targets stage 2. Added CI specific utils to store created users and games 3. Testing on Guest login 4. Testing on White Label Login 5. Testing on Leaderboard details and rewards 6. Testing on submitting scores to Leaderboards 7. Testing on Leaderboard listing, types, and metadata 8. Testing on Player Info 9. Testing on Pinging LootLocker's server 10. Testing on Player Storage, private, public and update 11. Removed ratelimiting while targeting stage 12. Added retry functionality for CI hitting ratelimiter
1 parent 3c0e477 commit 9001f2a

File tree

48 files changed

+3428
-86
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3428
-86
lines changed

.github/workflows/run-tests-and-package.yml

Lines changed: 119 additions & 66 deletions
Large diffs are not rendered by default.

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,10 @@ sysinfo.txt
5959
crashlytics-build.properties
6060

6161
.DS_Store
62+
63+
#IDE generated files
64+
.idea
65+
.vscode
66+
67+
#Specific meta files to ignore
68+
Tests.meta

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,18 @@ If you have any issues or just wanna chat you can reach us on our [Discord Serve
6363
### Testing the SDK
6464
Status: [![Test SDK with Unity](https://github.com/LootLocker/unity-sdk/actions/workflows/run-tests-and-package.yml/badge.svg?branch=main)](https://github.com/LootLocker/unity-sdk/actions/workflows/run-tests-and-package.yml?query=branch%3Amain)
6565

66-
There is a Test Suite for the SDK, but it is in an [external repo](https://github.com/LootLocker/unity-sdk-tests) to keep the size of this one down. It is run automatically on any pull requests towards or updates to main. You can also run it locally, just follow the steps in the test repo.
66+
To set up the tests, you must add our package to the manifest.json `testables` underneath `dependencies`. Your manifest.json should look something like this:
67+
68+
```json
69+
{
70+
"dependencies": {
71+
"com.lootlocker.lootlockersdk": "https://github.com/lootlocker/unity-sdk.git",
72+
many more dependencies...
73+
},
74+
"testables": ["com.lootlocker.lootlockersdk"]
75+
}
76+
```
77+
78+
Once you have done this, you can go into Unity and go to `Window` -> `General` -> `Test Runner`. This will open a new window which should already include all the tests available, Then all you have to do is press `Run All` and the tests will begin.
79+
80+
If you are running the tests towards the LootLocker production environment you will need to provide a username and password to an existing user either by setting the values directly in LootLockerTestConfigurationUser::GetProductionUser or via command line arguments -adminemail and -adminpassword. Bear in mind that your tests will be rate limited when running towards production (and in general this is a bad idea).

Runtime/Client/LootLockerServerApi.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ IEnumerator coroutine()
102102
yield break;
103103
}
104104

105-
LogResponse(request, webRequest.responseCode, webRequest.downloadHandler.text, startTime);
105+
106+
LogResponse(request, webRequest.responseCode, webRequest.downloadHandler.text, startTime, webRequest.error);
106107

107108
if (WebRequestSucceeded(webRequest))
108109
{
@@ -168,8 +169,17 @@ private static bool ShouldRetryRequest(long statusCode, int timesRetried)
168169
return (statusCode == 401 || statusCode == 403) && LootLockerConfig.current.allowTokenRefresh && CurrentPlatform.Get() != Platforms.Steam && timesRetried < MaxRetries;
169170
}
170171

171-
private static void LogResponse(LootLockerServerRequest request, long statusCode, string responseBody, float startTime)
172+
private static void LogResponse(LootLockerServerRequest request, long statusCode, string responseBody, float startTime, string unityWebRequestError)
172173
{
174+
if (statusCode == 0 && string.IsNullOrEmpty(responseBody) && !string.IsNullOrEmpty(unityWebRequestError))
175+
{
176+
LootLockerLogger.GetForLogLevel(LootLockerLogger.LogLevel.Verbose)("Unity Web request failed, request to " +
177+
request.endpoint + " completed in " +
178+
(Time.time - startTime).ToString("n4") +
179+
" secs.\nWeb Request Error: " + unityWebRequestError);
180+
return;
181+
}
182+
173183
try
174184
{
175185
LootLockerLogger.GetForLogLevel(LootLockerLogger.LogLevel.Verbose)("Server Response: " +
@@ -184,8 +194,7 @@ private static void LogResponse(LootLockerServerRequest request, long statusCode
184194
{
185195
LootLockerLogger.GetForLogLevel(LootLockerLogger.LogLevel.Error)(request.httpMethod.ToString());
186196
LootLockerLogger.GetForLogLevel(LootLockerLogger.LogLevel.Error)(request.endpoint);
187-
LootLockerLogger.GetForLogLevel(LootLockerLogger.LogLevel.Error)(
188-
LootLockerObfuscator.ObfuscateJsonStringForLogging(responseBody));
197+
LootLockerLogger.GetForLogLevel(LootLockerLogger.LogLevel.Error)(LootLockerObfuscator.ObfuscateJsonStringForLogging(responseBody));
189198
}
190199
}
191200

Runtime/Client/LootLockerServerRequest.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,12 @@ private int MoveCurrentBucket(DateTime now)
498498

499499
public virtual bool AddRequestAndCheckIfRateLimitHit()
500500
{
501+
//Disable local ratelimiter when not targeting production
502+
if (!LootLockerConfig.IsTargetingProductionEnvironment())
503+
{
504+
return false;
505+
}
506+
501507
DateTime now = GetTimeNow();
502508
var currentBucket = MoveCurrentBucket(now);
503509

Runtime/Game/Requests/AssetRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public class LootLockerCommonAsset : LootLockerResponse
113113
{
114114
public int id { get; set; }
115115
public string uuid { get; set; }
116+
public string ulid { get; set; }
116117
public string name { get; set; }
117118
public bool active { get; set; }
118119
public bool purchasable { get; set; }

Runtime/Game/Resources/LootLockerConfig.cs

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ public static LootLockerConfig Get()
2222
{
2323
if (settingsInstance != null)
2424
{
25-
settingsInstance.ConstructUrls();
2625
#if LOOTLOCKER_COMMANDLINE_SETTINGS
2726
settingsInstance.CheckForSettingOverrides();
2827
#endif
28+
settingsInstance.ConstructUrls();
2929
return settingsInstance;
3030
}
3131

@@ -62,37 +62,32 @@ public static LootLockerConfig Get()
6262
throw new ArgumentException("LootLocker config does not exist. To fix this, play once in the Unity Editor before making a build.");
6363
}
6464
#endif
65-
settingsInstance.ConstructUrls();
6665
#if LOOTLOCKER_COMMANDLINE_SETTINGS
6766
settingsInstance.CheckForSettingOverrides();
6867
#endif
68+
settingsInstance.ConstructUrls();
6969
return settingsInstance;
7070
}
7171

7272
private void CheckForSettingOverrides()
7373
{
7474
#if LOOTLOCKER_COMMANDLINE_SETTINGS
7575
string[] args = System.Environment.GetCommandLineArgs();
76-
string _apiKey = null;
77-
string _domainKey = null;
7876
for (int i = 0; i < args.Length; i++)
7977
{
8078
if (args[i] == "-apikey")
8179
{
82-
_apiKey = args[i + 1];
80+
apiKey = args[i + 1];
8381
}
8482
else if (args[i] == "-domainkey")
8583
{
86-
_domainKey = args[i + 1];
84+
domainKey = args[i + 1];
85+
}
86+
else if (args[i] == "-lootlockerurl")
87+
{
88+
UrlCoreOverride = args[i + 1];
8789
}
8890
}
89-
90-
if (string.IsNullOrEmpty(_apiKey) || string.IsNullOrEmpty(_domainKey))
91-
{
92-
return;
93-
}
94-
apiKey = _apiKey;
95-
domainKey = _domainKey;
9691
#endif
9792
}
9893

@@ -184,10 +179,37 @@ public static bool CreateNewSettings(string apiKey, string gameVersion, string d
184179
_current.currentDebugLevel = debugLevel;
185180
_current.allowTokenRefresh = allowTokenRefresh;
186181
_current.domainKey = domainKey;
182+
_current.token = null;
183+
#if UNITY_EDITOR
184+
_current.adminToken = null;
185+
#endif //UNITY_EDITOR
186+
_current.refreshToken = null;
187+
_current.gameID = 0;
188+
_current.deviceID = null;
189+
#if LOOTLOCKER_COMMANDLINE_SETTINGS
190+
_current.CheckForSettingOverrides();
191+
#endif
187192
_current.ConstructUrls();
188193
return true;
189194
}
190195

196+
public static bool ClearSettings()
197+
{
198+
_current.apiKey = null;
199+
_current.game_version = null;
200+
_current.currentDebugLevel = DebugLevel.All;
201+
_current.allowTokenRefresh = true;
202+
_current.domainKey = null;
203+
_current.token = null;
204+
#if UNITY_EDITOR
205+
_current.adminToken = null;
206+
#endif //UNITY_EDITOR
207+
_current.refreshToken = null;
208+
_current.gameID = 0;
209+
_current.deviceID = null;
210+
return true;
211+
}
212+
191213
private void ConstructUrls()
192214
{
193215
string startOfUrl = UrlProtocol;
@@ -222,7 +244,7 @@ public static LootLockerConfig current
222244
public string token;
223245
#if UNITY_EDITOR
224246
[HideInInspector]
225-
public string adminToken;
247+
public string adminToken = null;
226248
#endif
227249
[HideInInspector]
228250
public string refreshToken;
@@ -238,13 +260,19 @@ public static LootLockerConfig current
238260

239261
[HideInInspector] private static readonly string UrlProtocol = "https://";
240262
[HideInInspector] private static readonly string UrlCore = "api.lootlocker.io";
241-
[HideInInspector] private static readonly string UrlCoreOverride =
263+
[HideInInspector] private static string UrlCoreOverride =
242264
#if LOOTLOCKER_TARGET_STAGE_ENV
243265
"api.stage.internal.dev.lootlocker.cloud";
244266
#else
245267
null;
246268
#endif
247269
private static string GetUrlCore() { return string.IsNullOrEmpty(UrlCoreOverride) ? UrlCore : UrlCoreOverride; }
270+
271+
public static bool IsTargetingProductionEnvironment()
272+
{
273+
return string.IsNullOrEmpty(UrlCoreOverride) || UrlCoreOverride.Equals(UrlCore);
274+
275+
}
248276
[HideInInspector] private static readonly string UrlAppendage = "/v1";
249277
[HideInInspector] private static readonly string AdminUrlAppendage = "/admin";
250278
[HideInInspector] private static readonly string PlayerUrlAppendage = "/player";

Tests/LootLockerTestUtils.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using LootLocker;
2+
using System;
3+
using System.Collections.Generic;
4+
5+
namespace LootLockerTestConfigurationUtils
6+
{
7+
public class ApiKey
8+
{
9+
public class CreateApiKeyRequest
10+
{
11+
public string name { get; set; }
12+
public string api_type { get; set; } = "game";
13+
}
14+
15+
public class CreateApiKeyResponse : LootLockerResponse
16+
{
17+
public string api_key { get; set; }
18+
}
19+
20+
public static void CreateKey(string keyName, Action<CreateApiKeyResponse> onComplete)
21+
{
22+
if (string.IsNullOrEmpty(LootLockerConfig.current.adminToken))
23+
{
24+
// Not signed in
25+
onComplete?.Invoke(new CreateApiKeyResponse { success = false, errorData = new LootLockerErrorData{message = "Not logged in"}});
26+
return;
27+
}
28+
29+
EndPointClass endPoint = LootLockerTestConfigurationEndpoints.CreateKey;
30+
31+
CreateApiKeyRequest request = new CreateApiKeyRequest { name = keyName };
32+
33+
string json = LootLockerJson.SerializeObject(request);
34+
35+
LootLockerAdminRequest.Send(endPoint.endPoint, endPoint.httpMethod, json,
36+
onComplete: (serverResponse) => LootLockerResponse.Deserialize(onComplete, serverResponse), true);
37+
}
38+
}
39+
}

Tests/LootLockerTestUtils/LootLockerTestConfigurationApiKey.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)