/*
 * Copyright 2018 Arne Limburg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 */
package org.jpasecurity.security.rules;

import static java.util.Collections.singleton;

import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;

import java.util.Collection;
import java.util.Set;

import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.Metamodel;

import org.jpasecurity.SecurityContext;
import org.jpasecurity.security.AccessRule;
import org.jpasecurity.security.Permit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class AccessRulesParserTest {

  @Mock
  private Metamodel metamodel;
  @Mock
  private ManagedType<?> managedType;
  @Mock
  private SecurityContext securityContext;
  @Mock
  private AccessRulesProvider accessRulesProvider;

  private AccessRulesParser parser;

  @Before
  public void createAccessRulesParser() {
    when(metamodel.getManagedTypes()).thenReturn((Set)singleton(managedType));
    parser = new AccessRulesParser("test", metamodel, securityContext, accessRulesProvider);
  }

  @Test
  public void subselectWithWithClause() {
    when(managedType.getJavaType()).thenReturn((Class)RuleWithSubselectAndWith.class);
    Collection<AccessRule> accessRules = parser.parseAccessRules();
    assertThat(accessRules, hasSize(1));
    assertThat(accessRules.iterator().next().getStatement().toString(),
        is(" GRANT  CREATE  READ  UPDATE  DELETE ACCESS TO"
            + " org.jpasecurity.security.rules.AccessRulesParserTest$RuleWithSubselectAndWith"
            + " ruleWithSubselectAndWith"
            + " WHERE  EXISTS ( SELECT b FROM RuleWithSubselectAndWith b"
            + " LEFT OUTER JOIN b.parent p  WITH p IS NOT NULL  ) "));
  }

  @Permit(where = "EXISTS (SELECT b FROM RuleWithSubselectAndWith b LEFT JOIN b.parent p WITH p IS NOT NULL)")
  public static class RuleWithSubselectAndWith {

  }
}

@@ -1343,24 +1343,26 @@
 Test %7B%0A%0A
+  
   @Mock%0A
   privat
@@ -1345,32 +1345,34 @@
 st %7B%0A%0A    @Mock%0A
+  
   private Metamo
@@ -1384,30 +1384,34 @@
 etamodel;%0A  
+ 
+ 
 @Mock%0A
+  
   private Ma
@@ -1436,24 +1436,26 @@
 edType;%0A
+  
   @Mock%0A
   privat
@@ -1438,32 +1438,34 @@
 Type;%0A    @Mock%0A
+  
   private Securi
@@ -1491,16 +1491,18 @@
 ontext;%0A
+  
   @Mock%0A
@@ -1503,16 +1503,18 @@
 @Mock%0A  
+ 
+ 
 private 
@@ -1555,16 +1555,18 @@
 vider;%0A%0A
+  
   privat
@@ -1594,16 +1594,18 @@
 arser;%0A%0A
+  
   @Befor
@@ -1606,16 +1606,18 @@
 @Before%0A
+  
   public
@@ -1646,24 +1646,28 @@
 sParser() %7B%0A
+    
     when(met
@@ -1729,24 +1729,28 @@
 agedType));%0A
+    
     parser =
@@ -1834,21 +1834,27 @@
 r);%0A
+  
   %7D%0A%0A  
+ 
+ 
 @Test%0A
+  
   pu
@@ -1887,24 +1887,28 @@
 hClause() %7B%0A
+    
     when(man
@@ -1982,16 +1982,20 @@
 class);%0A
+    
     Coll
@@ -2054,16 +2054,20 @@
 ules();%0A
+    
     asse
@@ -2099,24 +2099,28 @@
 ze(1));%0A    
+  
+  
 assertThat(a
@@ -2183,16 +2183,20 @@
         
+    
 is(%22 GRA
@@ -2239,16 +2239,20 @@
 ESS TO%22%0A
+    
         
@@ -2346,24 +2346,28 @@
             
+    
 + %22 ruleWith
@@ -2376,32 +2376,36 @@
 bselectAndWith%22%0A
+    
             + %22 
@@ -2470,24 +2470,28 @@
             
+  
+  
 + %22 LEFT OUT
@@ -2537,23 +2537,27 @@
  ) %22));%0A
+  
   %7D%0A%0A  
+ 
+ 
 @Permit(
@@ -2657,16 +2657,18 @@
 NULL)%22)%0A
+  
   public
@@ -2709,14 +2709,16 @@
 With %7B%0A%0A
+  
   %7D%0A%7D%0A

Fix indentation level