audio streaming app plyr.fm
at main 100 lines 4.7 kB view raw
1"""tests for OAuth scope validation functions.""" 2 3from backend._internal.auth.scopes import ( 4 check_scope_coverage, 5 get_missing_scopes, 6) 7 8 9class TestCheckScopeCoverage: 10 """tests for check_scope_coverage.""" 11 12 def test_returns_true_when_all_scopes_granted(self): 13 """should return True when granted scope covers all required.""" 14 granted = "atproto repo:fm.plyr.track repo:fm.plyr.like repo:fm.plyr.comment" 15 required = "atproto repo:fm.plyr.track repo:fm.plyr.like repo:fm.plyr.comment" 16 assert check_scope_coverage(granted, required) is True 17 18 def test_returns_true_when_extra_scopes_granted(self): 19 """should return True when granted has more than required.""" 20 granted = "atproto repo:fm.plyr.track repo:fm.plyr.like repo:fm.plyr.comment repo:fm.plyr.extra" 21 required = "atproto repo:fm.plyr.track repo:fm.plyr.like" 22 assert check_scope_coverage(granted, required) is True 23 24 def test_returns_false_when_missing_scope(self): 25 """should return False when granted is missing required scope.""" 26 granted = "atproto repo:fm.plyr.track repo:fm.plyr.like" 27 required = "atproto repo:fm.plyr.track repo:fm.plyr.like repo:fm.plyr.comment" 28 assert check_scope_coverage(granted, required) is False 29 30 def test_returns_false_when_granted_empty(self): 31 """should return False when granted scope is empty.""" 32 granted = "" 33 required = "atproto repo:fm.plyr.track" 34 assert check_scope_coverage(granted, required) is False 35 36 def test_returns_true_when_both_empty(self): 37 """should return True when both are empty.""" 38 assert check_scope_coverage("", "") is True 39 40 def test_wildcard_collection_covers_specific(self): 41 """repo:* should cover any specific collection.""" 42 granted = "atproto repo:*" 43 required = "atproto repo:fm.plyr.track" 44 assert check_scope_coverage(granted, required) is True 45 46 def test_format_equivalence(self): 47 """repo:nsid == repo?collection=nsid.""" 48 granted = "atproto repo?collection=fm.plyr.track" 49 required = "atproto repo:fm.plyr.track" 50 assert check_scope_coverage(granted, required) is True 51 52 def test_blob_scope_coverage(self): 53 """blob scopes should be checked.""" 54 granted = "atproto blob:*/*" 55 required = "atproto blob:*/*" 56 assert check_scope_coverage(granted, required) is True 57 58 def test_include_covered_by_expanded_repo_scopes(self): 59 """PDS expands include: into repo: scopes — should still pass.""" 60 granted = "atproto blob:*/* repo:fm.plyr.stg.track repo:fm.plyr.stg.like repo:fm.plyr.stg.comment" 61 required = "atproto blob:*/* include:fm.plyr.stg.authFullApp" 62 assert check_scope_coverage(granted, required) is True 63 64 def test_include_not_covered_by_wrong_namespace(self): 65 """include: should fail if granted scopes are from a different namespace.""" 66 granted = "atproto blob:*/* repo:fm.other.track" 67 required = "atproto blob:*/* include:fm.plyr.stg.authFullApp" 68 assert check_scope_coverage(granted, required) is False 69 70 def test_include_missing_shows_in_get_missing(self): 71 """get_missing_scopes should report include: as missing when not covered.""" 72 granted = "atproto blob:*/* repo:fm.other.track" 73 required = "atproto blob:*/* include:fm.plyr.stg.authFullApp" 74 result = get_missing_scopes(granted, required) 75 assert result == {"include:fm.plyr.stg.authFullApp"} 76 77 78class TestGetMissingScopes: 79 """tests for get_missing_scopes.""" 80 81 def test_returns_empty_when_all_covered(self): 82 """should return empty set when all scopes are granted.""" 83 granted = "atproto repo:fm.plyr.track repo:fm.plyr.like repo:fm.plyr.comment" 84 required = "atproto repo:fm.plyr.track repo:fm.plyr.like" 85 result = get_missing_scopes(granted, required) 86 assert result == set() 87 88 def test_returns_missing_scope(self): 89 """should return the missing scope.""" 90 granted = "atproto repo:fm.plyr.track repo:fm.plyr.like" 91 required = "atproto repo:fm.plyr.track repo:fm.plyr.like repo:fm.plyr.comment" 92 result = get_missing_scopes(granted, required) 93 assert result == {"repo:fm.plyr.comment"} 94 95 def test_returns_multiple_missing_scopes(self): 96 """should return all missing scopes.""" 97 granted = "atproto repo:fm.plyr.track" 98 required = "atproto repo:fm.plyr.track repo:fm.plyr.like repo:fm.plyr.comment" 99 result = get_missing_scopes(granted, required) 100 assert result == {"repo:fm.plyr.like", "repo:fm.plyr.comment"}