package com.braintreepayments.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;

import androidx.test.core.app.ApplicationProvider;

import org.json.JSONException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.concurrent.TimeUnit;

@RunWith(RobolectricTestRunner.class)
public class ConfigurationCacheUnitTest {

    BraintreeSharedPreferences braintreeSharedPreferences;
    Context context;

    @Before
    public void beforeEach() throws GeneralSecurityException, IOException {
        context = ApplicationProvider.getApplicationContext();
        braintreeSharedPreferences = mock(BraintreeSharedPreferences.class);
    }

    @Test
    public void saveConfiguration_savesConfigurationInSharedPrefs() throws JSONException, UnexpectedException {
        Configuration configuration = Configuration.fromJson(Fixtures.CONFIGURATION_WITHOUT_ACCESS_TOKEN);

        ConfigurationCache sut = new ConfigurationCache(braintreeSharedPreferences);
        sut.saveConfiguration(context, configuration, "cacheKey", 123);
        verify(braintreeSharedPreferences).putStringAndLong(context, "cacheKey", configuration.toJson(), "cacheKey_timestamp", 123L);
    }

    @Test
    public void getCacheConfiguration_returnsConfigurationFromSharedPrefs() throws JSONException, UnexpectedException {
        Configuration configuration = Configuration.fromJson(Fixtures.CONFIGURATION_WITHOUT_ACCESS_TOKEN);
        when(braintreeSharedPreferences.containsKey(context, "cacheKey_timestamp")).thenReturn(true);
        when(braintreeSharedPreferences.getLong(context, "cacheKey_timestamp")).thenReturn(0L);
        when(braintreeSharedPreferences.getString(context, "cacheKey", "")).thenReturn(configuration.toJson());

        ConfigurationCache sut = new ConfigurationCache(braintreeSharedPreferences);
        sut.saveConfiguration(context, configuration, "cacheKey", 0);

        assertEquals(configuration.toJson(), sut.getConfiguration(context, "cacheKey", TimeUnit.MINUTES.toMillis(5)-1));
    }

    @Test
    public void getCacheConfiguration_returnsNullIfCacheEntryExpires() throws JSONException, UnexpectedException {
        Configuration configuration = Configuration.fromJson(Fixtures.CONFIGURATION_WITHOUT_ACCESS_TOKEN);
        when(braintreeSharedPreferences.containsKey(context, "cacheKey_timestamp")).thenReturn(true);
        when(braintreeSharedPreferences.getLong(context, "cacheKey_timestamp")).thenReturn(TimeUnit.MINUTES.toMillis(5));
        when(braintreeSharedPreferences.getString(context, "cacheKey","")).thenReturn(configuration.toJson());

        ConfigurationCache sut = new ConfigurationCache(braintreeSharedPreferences);
        sut.saveConfiguration(context, configuration, "cacheKey", 0);

        assertNull(sut.getConfiguration(context, "cacheKey", TimeUnit.MINUTES.toMillis(20)));
    }
}
@@ -1545,37 +1545,32 @@
 public void getC
-acheC
 onfiguration_ret
@@ -1640,32 +1640,32 @@
 ctedException %7B%0A
+
         Configur
@@ -2384,13 +2384,8 @@
 getC
-acheC
 onfi
@@ -2397,21 +2397,12 @@
 ion_
-returnsNullIf
+when
 Cach
@@ -2414,16 +2414,28 @@
 yExpires
+_returnsNull
 () throw
@@ -3064,32 +3064,32 @@
 cacheKey%22, 0);%0A%0A
-
         assertNu
@@ -3171,10 +3171,763 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void getConfiguration_whenEncryptedSharedPrefsFails_returnsNull() throws JSONException, UnexpectedException %7B%0A        UnexpectedException unexpectedException = new UnexpectedException(%22unexpected exception%22);%0A        when(braintreeSharedPreferences.containsKey(context, %22cacheKey_timestamp%22)).thenThrow(unexpectedException);%0A        when(braintreeSharedPreferences.getLong(context, %22cacheKey_timestamp%22)).thenThrow(unexpectedException);%0A        when(braintreeSharedPreferences.getString(context, %22cacheKey%22,%22%22)).thenThrow(unexpectedException);%0A%0A        ConfigurationCache sut = new ConfigurationCache(braintreeSharedPreferences);%0A        assertNull(sut.getConfiguration(context, %22cacheKey%22, TimeUnit.MINUTES.toMillis(5)-1));%0A    %7D
 %0A%7D

Add test for Configuration Cache.