fix: keep mobile review handoff popup-safe (#143)
This commit is contained in:
1 parent
54638d2686
commit
b51542363c
3 files changed
+99
-34
No files matched your search
+49
-15
@@ -534,25 +534,29 @@ process.stdout.write(markdown);
|
||||
)
|
||||
|
||||
|
||||
def test_review_handoff_opens_gitea_only_after_copy_and_preserves_failed_copy():
|
||||
def test_review_handoff_reserves_window_before_copy_and_reports_blocked_popup():
|
||||
script = f"""
|
||||
const reviewSheet = require({json.dumps(str(REVIEW_SHEET))});
|
||||
const events = [];
|
||||
let finishCopy;
|
||||
const reserved = {{ location: {{ href: '' }}, close: () => events.push('close') }};
|
||||
const success = reviewSheet.copyAndContinue({{
|
||||
text: 'feedback', url: 'https://forge.example/pulls/7',
|
||||
copy: async text => events.push('copy:' + text),
|
||||
open: url => events.push('open:' + url),
|
||||
copy: text => new Promise(resolve => {{ events.push('copy:' + text); finishCopy = resolve; }}),
|
||||
open: () => {{ events.push('reserve'); return reserved; }},
|
||||
fallback: text => events.push('fallback:' + text),
|
||||
}});
|
||||
const failedEvents = [];
|
||||
const failure = reviewSheet.copyAndContinue({{
|
||||
text: 'keep me', url: 'https://forge.example/pulls/8',
|
||||
copy: async () => {{ throw new Error('denied'); }},
|
||||
open: url => failedEvents.push('open:' + url),
|
||||
fallback: text => failedEvents.push('fallback:' + text),
|
||||
const beforeCopySettles = events.slice();
|
||||
finishCopy();
|
||||
const blockedEvents = [];
|
||||
const blocked = reviewSheet.copyAndContinue({{
|
||||
text: 'copied', url: 'https://forge.example/pulls/8',
|
||||
copy: async () => blockedEvents.push('copy'),
|
||||
open: () => {{ blockedEvents.push('reserve'); return null; }},
|
||||
fallback: text => blockedEvents.push('fallback:' + text),
|
||||
}});
|
||||
Promise.all([success, failure]).then(results => process.stdout.write(JSON.stringify({{
|
||||
events, failedEvents, results
|
||||
Promise.all([success, blocked]).then(results => process.stdout.write(JSON.stringify({{
|
||||
beforeCopySettles, events, blockedEvents, destination: reserved.location.href, results
|
||||
}})));
|
||||
"""
|
||||
result = subprocess.run(
|
||||
@@ -560,9 +564,35 @@ Promise.all([success, failure]).then(results => process.stdout.write(JSON.string
|
||||
)
|
||||
|
||||
assert json.loads(result.stdout) == {
|
||||
"events": ["copy:feedback", "open:https://forge.example/pulls/7"],
|
||||
"failedEvents": ["fallback:keep me"],
|
||||
"results": [True, False],
|
||||
"beforeCopySettles": ["reserve", "copy:feedback"],
|
||||
"events": ["reserve", "copy:feedback"],
|
||||
"blockedEvents": ["reserve", "copy", "fallback:copied"],
|
||||
"destination": "https://forge.example/pulls/7",
|
||||
"results": [
|
||||
{"copied": True, "opened": True},
|
||||
{"copied": True, "opened": False},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def test_review_handoff_closes_reserved_window_when_copy_fails():
|
||||
script = f"""
|
||||
const reviewSheet = require({json.dumps(str(REVIEW_SHEET))});
|
||||
const events = [];
|
||||
reviewSheet.copyAndContinue({{
|
||||
text: 'keep me', url: 'https://forge.example/pulls/8',
|
||||
copy: async () => {{ throw new Error('denied'); }},
|
||||
open: () => ({{ close: () => events.push('close') }}),
|
||||
fallback: text => events.push('fallback:' + text),
|
||||
}}).then(result => process.stdout.write(JSON.stringify({{ events, result }})));
|
||||
"""
|
||||
result = subprocess.run(
|
||||
["node", "-e", script], check=True, capture_output=True, text=True
|
||||
)
|
||||
|
||||
assert json.loads(result.stdout) == {
|
||||
"events": ["close", "fallback:keep me"],
|
||||
"result": {"copied": False, "opened": False},
|
||||
}
|
||||
|
||||
|
||||
@@ -611,6 +641,9 @@ async def test_mobile_review_sheet_captures_and_safely_hands_off_feedback():
|
||||
assert 'id="review-summary"' in html
|
||||
assert 'id="copy-review-feedback"' in html
|
||||
assert 'id="review-copy-fallback"' in html
|
||||
assert 'id="review-handoff-link"' in html
|
||||
assert '.review-handoff-link' in html and 'min-height:44px' in html
|
||||
assert '.review-handoff-link[hidden]' in html and 'display:none' in html
|
||||
assert '.review-note' in html and 'min-height:88px' in html
|
||||
assert '.review-handoff' in html and 'position:sticky' in html
|
||||
assert "createReviewController.createDraft" in html
|
||||
@@ -620,7 +653,8 @@ async def test_mobile_review_sheet_captures_and_safely_hands_off_feedback():
|
||||
assert "createReviewController.formatFeedback" in html
|
||||
assert "createReviewController.copyAndContinue" in html
|
||||
assert "navigator.clipboard.writeText" in html
|
||||
assert "window.open(url, '_blank', 'noopener,noreferrer')" in html
|
||||
assert "window.open('about:blank', '_blank')" in html
|
||||
assert "handoffWindow.opener = null" in html
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
|
||||
Reference in new issue
Block a user