Skip to content

Commit 2e58aaf

Browse files
committed
Add Test coverage for scoped attribute persistence in Windows NativeClient
- Verifies duplicate keys are not added repeatedly - Confirms PlayerPrefs writes are skipped when value unchanged - Retains backward compatibility with legacy attribute reads
1 parent dd0e25c commit 2e58aaf

File tree

1 file changed

+64
-2
lines changed

1 file changed

+64
-2
lines changed

Tests/Runtime/Native/Windows/ScopedNativeAttributesTests.cs

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,27 @@ namespace Backtrace.Unity.Tests.Runtime.Native.Windows
1010
{
1111
public sealed class ScopedNativeAttributesTests
1212
{
13+
// PlayerPrefs key used by the Windows NativeClient to store the scoped list
14+
private const string ScopedKeyList = "backtrace-scoped-attributes";
15+
private const string ScopedValuePattern = "bt-{0}";
16+
1317
[TearDown]
1418
public void Setup()
1519
{
1620
CleanLegacyAttributes();
1721
NativeClient.CleanScopedAttributes();
22+
PlayerPrefs.DeleteAll();
1823
}
1924

25+
[Test]
2026
public void FreshStartup_ShouldntIncludeAnyAttributeFromPlayerPrefs_AttributesAreEmpty()
2127
{
2228
var attributes = NativeClient.GetScopedAttributes();
2329

2430
Assert.IsEmpty(attributes);
2531
}
2632

33+
[Test]
2734
public void LegacyAttributesSupport_ShouldIncludeLegacyAttributesWhenScopedAttributesAreNotAvailable_AllLegacyAttributesArePresent()
2835
{
2936
string testVersion = "0.1.0";
@@ -82,7 +89,6 @@ public void NativeCrashUploadAttributesSetting_ShouldReadPlayerPrefsWithLegacyAt
8289
[Test]
8390
public void NativeCrashUploadAttributes_ShouldSetScopedAttributeViaNativeClientApi_AttributePresentsInScopedAttributes()
8491
{
85-
8692
var configuration = ScriptableObject.CreateInstance<BacktraceConfiguration>();
8793
configuration.SendUnhandledGameCrashesOnGameStartup = true;
8894
const string testAttributeKey = "foo-key-bar-baz";
@@ -93,7 +99,6 @@ public void NativeCrashUploadAttributes_ShouldSetScopedAttributeViaNativeClientA
9399
var scopedAttributes = NativeClient.GetScopedAttributes();
94100

95101
Assert.AreEqual(scopedAttributes[testAttributeKey], testAttributeValue);
96-
97102
}
98103

99104
[Test]
@@ -119,6 +124,63 @@ public void NativeCrashAttributesCleanMethod_ShouldCleanAllScopedAttribtues_Scop
119124
Assert.IsNotEmpty(attributesBeforeCleanup);
120125
}
121126

127+
[Test]
128+
public void ScopedAttributes_ShouldNotDuplicateKeys_OnRepeatedAdds()
129+
{
130+
var configuration = ScriptableObject.CreateInstance<BacktraceConfiguration>();
131+
configuration.SendUnhandledGameCrashesOnGameStartup = true;
132+
133+
const string k = "dup-key";
134+
const string v = "v1";
135+
136+
var client = new NativeClient(configuration, null, new Dictionary<string, string>(), new List<string>());
137+
138+
// Add the same key/value multiple times
139+
client.SetAttribute(k, v);
140+
client.SetAttribute(k, v);
141+
client.SetAttribute(k, v);
142+
143+
// Verify the stored list
144+
var scoped = NativeClient.GetScopedAttributes();
145+
Assert.IsTrue(scoped.ContainsKey(k));
146+
Assert.AreEqual(v, scoped[k]);
147+
148+
// Inspect the JSON list to ensure one occurrence of the key
149+
var json = PlayerPrefs.GetString(ScopedKeyList);
150+
var occurrences = json.Split('"');
151+
int count = 0;
152+
foreach (var s in occurrences)
153+
{
154+
if (s == k) count++;
155+
}
156+
Assert.AreEqual(1, count, "Key should be stored once in the scoped key list.");
157+
}
158+
159+
[Test]
160+
public void ScopedAttributes_ShouldSkipWrites_WhenValueUnchanged()
161+
{
162+
var configuration = ScriptableObject.CreateInstance<BacktraceConfiguration>();
163+
configuration.SendUnhandledGameCrashesOnGameStartup = true;
164+
165+
const string k = "stable-key";
166+
const string v = "same-value";
167+
168+
var client = new NativeClient(configuration, null, new Dictionary<string, string>(), new List<string>());
169+
170+
// First write
171+
client.SetAttribute(k, v);
172+
var json1 = PlayerPrefs.GetString(ScopedKeyList);
173+
var val1 = PlayerPrefs.GetString(string.Format(ScopedValuePattern, k));
174+
175+
// Second write with same value should be a no-op
176+
client.SetAttribute(k, v);
177+
var json2 = PlayerPrefs.GetString(ScopedKeyList);
178+
var val2 = PlayerPrefs.GetString(string.Format(ScopedValuePattern, k));
179+
180+
Assert.AreEqual(json1, json2, "Scoped key list JSON should not change when value is unchanged.");
181+
Assert.AreEqual(val1, val2, "Stored value should remain the same.");
182+
}
183+
122184
private void CleanLegacyAttributes()
123185
{
124186
PlayerPrefs.DeleteKey(NativeClient.VersionKey);

0 commit comments

Comments
 (0)