package net.threescale.service;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import java.util.Map;
import java.util.Properties;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

import threescale.v3.api.AuthorizeResponse;
import threescale.v3.api.ServerError;
import threescale.v3.api.ServiceApi;


public class PluginServiceTest{
    private final String SUCCESSFUL_RESP = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><status><authorized>true</authorized><plan>Application Plan</plan></status>";
    private final String FAILED_RESP = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><status code=\"409\"><authorized>false</authorized><reason>usage limits are exceeded</reason><plan>Application Plan</plan></status>";
    
    private PluginServiceImpl pluginServiceUnderTest; 
    private ServiceApi mockServiceApi;
    private Properties mockProps;
    private Map <String, Boolean> mockAuthorizations;
    
    @Before 
    public void before() throws Exception {
        
        mockServiceApi = Mockito.mock(ServiceApi.class);
        mockProps = new Properties();
        mockAuthorizations = Mockito.mock(Map.class);
       
        pluginServiceUnderTest = new PluginServiceImpl();
        pluginServiceUnderTest.setAuthorizations(mockAuthorizations);
        pluginServiceUnderTest.setProps(mockProps);
        pluginServiceUnderTest.setServiceApi(mockServiceApi);
    }

    
    @Test (expected = ServerError.class) 
    public void testServerErrorNoServiceId() throws ServerError  {    	
    	mockProps.setProperty("method-token", "servicetoken");
    	pluginServiceUnderTest.setProps(mockProps);     
        pluginServiceUnderTest.authRep("userKey", "method");
    }
    
    @Test (expected = ServerError.class) 
    public void testServerErrorNoServiceToken() throws ServerError  {
        mockProps.setProperty("method-serviceid", "serviceId");      
        pluginServiceUnderTest.setProps(mockProps);
        pluginServiceUnderTest.authRep("userKey", "method");
    }

    
    @Test 
    public void testSuccessfulAuthEmptyCache() throws ServerError  {
    	mockProps.setProperty("method-token", "servicetoken"); 
    	mockProps.setProperty("method-serviceid", "serviceId");        
        
        AuthorizeResponse successfulResponse = new AuthorizeResponse(200, SUCCESSFUL_RESP);
        when(mockServiceApi.authrep(any(), any(), any())).thenReturn(successfulResponse);
        
        AuthorizeResponse response = pluginServiceUnderTest.authRep("userKey", "method");
        //A non-null response  is what we expect from a synchronous call - made when <key>+<method or metric> not found in the cache
        assertNotNull(response);
        assertEquals(response.success(), true);
    }

    @Test 
    public void testFailedAuthEmptyCache() throws ServerError  {
    	mockProps.setProperty("method-token", "servicetoken"); 
    	mockProps.setProperty("method-serviceid", "serviceId");        
        
        AuthorizeResponse failResponse = new AuthorizeResponse(403, FAILED_RESP);
        when(mockServiceApi.authrep(any(), any(), any())).thenReturn(failResponse);
        
        AuthorizeResponse response = pluginServiceUnderTest.authRep("userKey", "method");
        //A non-null response  is what we expect from a synchronous call - made when <key>+<method or metric> not found in the cache
        assertNotNull(response);
        assertEquals(response.success(), false);
    }

    
    @Test 
    public void testValueInCacheAsynchAuth() throws ServerError  {
    	mockProps.setProperty("method-token", "servicetoken"); 
    	mockProps.setProperty("method-serviceid", "serviceId");        
        
    	when(mockAuthorizations.get("userKeymethod")).thenReturn(true);
                
        AuthorizeResponse response = pluginServiceUnderTest.authRep("userKey", "method");
        //A null response  is what we expect from an asynchronous call - made when <key>+<method or metric> is found in the cache. 
        //Return null as we don't wait for the response
        assertNull(response);
     }

 
    
}
@@ -1,8 +1,759 @@
+/*%0A%09The code in this repo is not supported by Red Hat/3scale. %0A    Rather it's example code of how you can and we did achieve %0A    very low latency API Management. %0A/*%0A/*%0A *   Licensed under the Apache License, Version 2.0 (the %22License%22);%0A *   you may not use this file except in compliance with the License.%0A *   You may obtain a copy of the License at%0A *%0A *        http://www.apache.org/licenses/LICENSE-2.0%0A *%0A *   Unless required by applicable law or agreed to in writing, software%0A *   distributed under the License is distributed on an %22AS IS%22 BASIS,%0A *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A *   See the License for the specific language governing permissions and%0A *   limitations under the License.%0A */%0A%0A%0A
 package 
@@ -4993,8 +4993,9 @@
  %0A    %0A%7D
+%0A

Update PluginServiceTest.java