Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions PolyPilot.Tests/QrCodeBlurTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Text.RegularExpressions;

namespace PolyPilot.Tests;

/// <summary>
/// Tests that verify the QR code images in Settings are blurred by default
/// (when showToken is false), matching the token's blur behavior.
/// Since these are Blazor components, we verify the source markup contracts.
/// </summary>
public class QrCodeBlurTests
{
private static string GetSettingsRazorPath()
{
// Navigate from test project to main project
var testDir = AppContext.BaseDirectory;
var repoRoot = Path.GetFullPath(Path.Combine(testDir, "..", "..", "..", ".."));
return Path.Combine(repoRoot, "PolyPilot", "Components", "Pages", "Settings.razor");
}

private static string GetSettingsCssPath()
{
var testDir = AppContext.BaseDirectory;
var repoRoot = Path.GetFullPath(Path.Combine(testDir, "..", "..", "..", ".."));
return Path.Combine(repoRoot, "PolyPilot", "Components", "Pages", "Settings.razor.css");
}

[Fact]
public void QrCodeImages_UseBlurredClassFromShowTokenToggle()
{
var razorContent = File.ReadAllText(GetSettingsRazorPath());

// Both QR code img tags should use the showToken toggle for blurred class
var qrImgPattern = new Regex(@"<img\s+src=""@(qrCodeDataUri|directQrCodeDataUri)""\s+alt=""QR Code""\s+class=""@\(showToken \? """" : ""blurred""\)""");
var matches = qrImgPattern.Matches(razorContent);

Assert.True(matches.Count >= 2,
$"Expected at least 2 QR code <img> tags with showToken-based blur class, found {matches.Count}. " +
"Both tunnel and direct QR codes must be blurred when token is hidden.");
}

[Fact]
public void TokenValue_UsesBlurredClassFromShowTokenToggle()
{
var razorContent = File.ReadAllText(GetSettingsRazorPath());

// Token code element should also use showToken toggle
Assert.Contains(@"@(showToken ? """" : ""blurred"")", razorContent);
}

[Fact]
public void ShowToken_DefaultsFalse()
{
var razorContent = File.ReadAllText(GetSettingsRazorPath());

// showToken should be declared as bool (defaults to false)
Assert.Matches(@"private\s+bool\s+showToken\s*;", razorContent);

// It should NOT be initialized to true
Assert.DoesNotMatch(@"private\s+bool\s+showToken\s*=\s*true", razorContent);
}

[Fact]
public void Css_HasBlurredStyleForQrCodeImages()
{
var cssContent = File.ReadAllText(GetSettingsCssPath());

// CSS must define blur styles for QR code images
Assert.Contains(".qr-code img.blurred", cssContent);
Assert.Contains("filter: blur(", cssContent);
}

[Fact]
public void Css_QrCodeImageHasTransition()
{
var cssContent = File.ReadAllText(GetSettingsCssPath());

// QR code img should have a transition for smooth blur toggle
Assert.Contains("transition: filter", cssContent);
}

[Fact]
public void Css_BlurredQrCodeHasHoverReveal()
{
var cssContent = File.ReadAllText(GetSettingsCssPath());

// Blurred QR should partially reveal on hover (like the token does)
Assert.Contains(".qr-code img.blurred:hover", cssContent);
}
}
47 changes: 47 additions & 0 deletions PolyPilot.Tests/Scenarios/mode-switch-scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,53 @@
"note": "Filter input is visible when expanded"
}
]
},
{
"id": "settings-qr-code-blur",
"name": "QR code is blurred by default alongside token",
"steps": [
{
"action": "note",
"note": "Navigate to /settings page. Requires an active DevTunnel to see QR code."
},
{
"action": "evaluate",
"script": "document.querySelector('.qr-code img')?.classList.contains('blurred')",
"expect": {
"equals": true
},
"note": "QR code image is blurred by default (showToken=false)"
},
{
"action": "evaluate",
"script": "document.querySelector('.token-value')?.classList.contains('blurred')",
"expect": {
"equals": true
},
"note": "Token value is also blurred by default"
},
{
"action": "click",
"selector": ".tunnel-token .copy-btn",
"note": "Click reveal/hide token button"
},
{
"action": "evaluate",
"script": "document.querySelector('.qr-code img')?.classList.contains('blurred')",
"expect": {
"equals": false
},
"note": "QR code is revealed when token is shown"
},
{
"action": "evaluate",
"script": "document.querySelector('.token-value')?.classList.contains('blurred')",
"expect": {
"equals": false
},
"note": "Token is also revealed"
}
]
}
]
}
4 changes: 2 additions & 2 deletions PolyPilot/Components/Pages/Settings.razor
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
@if (!string.IsNullOrEmpty(qrCodeDataUri))
{
<div class="qr-code">
<img src="@qrCodeDataUri" alt="QR Code" />
<img src="@qrCodeDataUri" alt="QR Code" class="@(showToken ? "" : "blurred")" />
<p class="qr-hint">Scan with PolyPilot on iOS/Android to connect</p>
</div>
}
Expand Down Expand Up @@ -244,7 +244,7 @@
@if (!string.IsNullOrEmpty(directQrCodeDataUri))
{
<div class="qr-code">
<img src="@directQrCodeDataUri" alt="QR Code" />
<img src="@directQrCodeDataUri" alt="QR Code" class="@(showToken ? "" : "blurred")" />
<p class="qr-hint">Scan with PolyPilot on iOS/Android to connect</p>
</div>
}
Expand Down
10 changes: 10 additions & 0 deletions PolyPilot/Components/Pages/Settings.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,16 @@
border-radius: 8px;
padding: 12px;
background: #fff;
transition: filter 0.2s ease;
}

.qr-code img.blurred {
filter: blur(8px);
cursor: pointer;
}

.qr-code img.blurred:hover {
filter: blur(4px);
}

.qr-hint {
Expand Down