@@ -78,6 +78,7 @@ public function test_scopes_are_applied_to_pagination_request()
7878 public function test_scopes_are_not_stacked_multiple_times ()
7979 {
8080 $ query = ModelWithGlobalScopeTestStub::query ();
81+
8182 // Call toBase() multiple times to verify scopes aren't stacked
8283 $ query ->toBase ();
8384 $ query ->toBase ();
@@ -134,6 +135,47 @@ public function test_scopes_do_not_impact_model_find()
134135
135136 $ this ->assertEquals ('cn=John Doe,dc=local,dc=com ' , $ model ->getDn ());
136137 }
138+
139+ public function test_scopes_cannot_be_negated_by_or_clauses ()
140+ {
141+ // The scope should be wrapped in its own AND group, so the OR clause
142+ // cannot negate it. The filter should be: (&(bypass=...)(&(foo=bar)))
143+ // NOT: (|(foo=bar)(bypass=...)) which would allow bypassing the scope
144+ $ this ->assertEquals (
145+ '(&(bypass=\61\74\74\65\6d\70\74)(&(foo=bar))) ' ,
146+ ModelWithGlobalScopeTestStub::query ()
147+ ->orWhere ('bypass ' , '= ' , 'attempt ' )
148+ ->toBase ()
149+ ->getQuery ()
150+ );
151+ }
152+
153+ public function test_scopes_cannot_be_negated_by_multiple_or_clauses ()
154+ {
155+ // Scope must remain enforced regardless of OR clauses
156+ $ this ->assertEquals (
157+ '(&(|(bypass1=\61\74\74\65\6d\70\74\31)(bypass2=\61\74\74\65\6d\70\74\32))(&(foo=bar))) ' ,
158+ ModelWithGlobalScopeTestStub::query ()
159+ ->orWhere ('bypass1 ' , '= ' , 'attempt1 ' )
160+ ->orWhere ('bypass2 ' , '= ' , 'attempt2 ' )
161+ ->toBase ()
162+ ->getQuery ()
163+ );
164+ }
165+
166+ public function test_scopes_remain_enforced_with_complex_queries ()
167+ {
168+ // The scope (foo=bar) must always be present and enforced at the root AND level
169+ $ this ->assertEquals (
170+ '(&(|(name=\4a\6f\68\6e)(name=\4a\61\6e\65))(active=\74\72\75\65)(&(foo=bar))) ' ,
171+ ModelWithGlobalScopeTestStub::query ()
172+ ->where ('name ' , '= ' , 'John ' )
173+ ->orWhere ('name ' , '= ' , 'Jane ' )
174+ ->where ('active ' , '= ' , 'true ' )
175+ ->toBase ()
176+ ->getQuery ()
177+ );
178+ }
137179}
138180
139181class ModelWithLocalScopeTestStub extends Model
0 commit comments