diff --git a/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs b/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs index 26e30425..7ebd273d 100644 --- a/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs +++ b/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs @@ -160,9 +160,6 @@ private void OnSendCatalogueEvent(EventSpec spec, Dictionary RunAndLog("track()", () => { GuardConsentForTrack(); @@ -205,10 +202,10 @@ private void OnIdentify() => RunAndLog("identify()", () => var f = CaptureIdentifyForm(); var traits = ParseTraits(f.RawTraits); ImmutableAudience.Identify(f.Id, ParseIdentityType(f.Type), traits); - // SDK drops via Log.Warn when id is empty or consent < Full. Mirror - // only when accepted; otherwise the panel would show stale state. - var accepted = !string.IsNullOrEmpty(f.Id) - && string.Equals(ImmutableAudience.UserId, f.Id, StringComparison.Ordinal); + // Empty ids and malformed passport ids throw, caught by RunAndLog + // before this line runs. The one silent no-op left is consent + // below Full, which the UserId check below still catches. + var accepted = string.Equals(ImmutableAudience.UserId, f.Id, StringComparison.Ordinal); if (accepted) { _mirrorIdentityType = f.Type; _mirrorTraits = traits; } OnSdkStateChanged(); var payload = new Dictionary @@ -237,20 +234,16 @@ private void OnAlias() => RunAndLog("alias()", () => { var f = CaptureAliasForm(); ImmutableAudience.Alias(f.FromId, ParseIdentityType(f.FromType), f.ToId, ParseIdentityType(f.ToType)); - // SDK drops via Log.Warn when fromId/toId is empty or consent < Full. - // The IsAliasReady gate keeps empty endpoints unreachable from the - // UI; this post-call check is defense-in-depth. - var accepted = !string.IsNullOrEmpty(f.FromId) && !string.IsNullOrEmpty(f.ToId); - if (accepted) - { - _mirrorAliases.Add($"{f.FromType}:{f.FromId} → {f.ToType}:{f.ToId}"); - OnSdkStateChanged(); - } + // Empty/identical/malformed ids throw, caught by RunAndLog before this + // line runs. Consent below Full still drops silently inside the SDK, + // with no readable property here to detect it (unlike Identify's UserId). + _mirrorAliases.Add($"{f.FromType}:{f.FromId} → {f.ToType}:{f.ToId}"); + OnSdkStateChanged(); return Json.Serialize(new Dictionary { ["from"] = new Dictionary { ["id"] = f.FromId, ["identityType"] = f.FromType }, ["to"] = new Dictionary { ["id"] = f.ToId, ["identityType"] = f.ToType }, - ["accepted"] = accepted, + ["accepted"] = true, }, 2); }); @@ -292,6 +285,18 @@ private void RouteSdkLogToPane(string msg) { UnityEngine.Debug.Log($"[Audience] {body}"); } + + if (body.StartsWith("flush ok", StringComparison.Ordinal)) + { + AppendLog(body, null, LogLevel.Ok, LogSource.Sdk); + return; + } + if (body.StartsWith("flush failed", StringComparison.Ordinal)) + { + AppendLog(body, null, LogLevel.Err, LogSource.Sdk); + return; + } + AppendLog("sdk", body, level, LogSource.Sdk); } diff --git a/examples/audience/Assets/SampleApp/Tests/Runtime/SampleAppLiveFireTests.cs b/examples/audience/Assets/SampleApp/Tests/Runtime/SampleAppLiveFireTests.cs index aeb763f0..d949d28b 100644 --- a/examples/audience/Assets/SampleApp/Tests/Runtime/SampleAppLiveFireTests.cs +++ b/examples/audience/Assets/SampleApp/Tests/Runtime/SampleAppLiveFireTests.cs @@ -253,14 +253,16 @@ public IEnumerator Identify_AndFlush_FlushReportsOk() } [UnityTest] - public IEnumerator Identify_PassportWithInvalidIdFormat_WarnsAndDropsCall() + public IEnumerator Identify_PassportWithInvalidIdFormat_Throws() { // Identity type dropdown defaults to Passport; "12345" isn't Passport-shaped. + // ImmutableAudience.Identify throws on this; RunAndLog catches it and + // renders an identify()@Err row. yield return LoadAndInit(initialConsent: SampleAppUi.Consent.Full); _root!.Q(SampleAppUi.IdentityFields.Id).value = "12345"; _root.Q