content: /*
   * Copyright 2015, The Android Open Source Project
   *
   * 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 com.example.android.testing.unittesting.BasicSample;
  
  import static org.hamcrest.MatcherAssert.assertThat;
  import static org.hamcrest.CoreMatchers.*;
  import static org.mockito.Mockito.*;
  import org.junit.Before;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.Mock;
  import org.mockito.runners.MockitoJUnitRunner;
  
  import android.content.SharedPreferences;
  
  import java.util.Calendar;
  
  
  /**
   * Unit tests for the {@link SharedPreferencesHelper} that mocks {@link SharedPreferences}.
   */
  @RunWith(MockitoJUnitRunner.class)
  public class SharedPreferencesHelperTest {
  
      private static final String TEST_NAME = "Test name";
  
      private static final String TEST_EMAIL = "test@email.com";
  
      private static final Calendar TEST_DATE_OF_BIRTH = Calendar.getInstance();
  
      static {
          TEST_DATE_OF_BIRTH.set(1980, 1, 1);
      }
  
      private SharedPreferenceEntry mSharedPreferenceEntry;
  
      private SharedPreferencesHelper mMockSharedPreferencesHelper;
  
      private SharedPreferencesHelper mMockBrokenSharedPreferencesHelper;
  
      @Mock
      SharedPreferences mMockSharedPreferences;
  
      @Mock
      SharedPreferences mMockBrokenSharedPreferences;
  
      @Mock
      SharedPreferences.Editor mMockEditor;
  
      @Mock
      SharedPreferences.Editor mMockBrokenEditor;
  
      @Before
      public void initMocks() {
          // Create SharedPreferenceEntry to persist.
          mSharedPreferenceEntry = new SharedPreferenceEntry(TEST_NAME, TEST_DATE_OF_BIRTH,
                  TEST_EMAIL);
  
          // Create a mocked SharedPreferences.
          mMockSharedPreferencesHelper = createMockSharedPreference();
  
          // Create a mocked SharedPreferences that fails at saving data.
          mMockBrokenSharedPreferencesHelper = createBrokenMockSharedPreference();
      }
  
      @Test
      public void sharedPreferencesHelper_SaveAndReadPersonalInformation() {
          // Save the personal information to SharedPreferences
          boolean success = mMockSharedPreferencesHelper.savePersonalInfo(mSharedPreferenceEntry);
  
          assertThat("Checking that SharedPreferenceEntry.save... returns true",
                  success, is(true));
  
          // Read personal information from SharedPreferences
          SharedPreferenceEntry savedSharedPreferenceEntry =
                  mMockSharedPreferencesHelper.getPersonalInfo();
  
          // Make sure both written and retrieved personal information are equal.
          assertThat("Checking that SharedPreferenceEntry.name has been persisted and read correctly",
                  mSharedPreferenceEntry.getName(),
                  is(equalTo(savedSharedPreferenceEntry.getName())));
          assertThat("Checking that SharedPreferenceEntry.dateOfBirth has been persisted and read "
                  + "correctly",
                  mSharedPreferenceEntry.getDateOfBirth(),
                  is(equalTo(savedSharedPreferenceEntry.getDateOfBirth())));
          assertThat("Checking that SharedPreferenceEntry.email has been persisted and read "
                  + "correctly",
                  mSharedPreferenceEntry.getEmail(),
                  is(equalTo(savedSharedPreferenceEntry.getEmail())));
      }
  
      @Test
      public void sharedPreferencesHelper_SavePersonalInformationFailed_ReturnsFalse() {
          // Read personal information from a broken SharedPreferencesHelper
          boolean success =
                  mMockBrokenSharedPreferencesHelper.savePersonalInfo(mSharedPreferenceEntry);
          assertThat("Makes sure writing to a broken SharedPreferencesHelper returns false", success,
                  is(false));
      }
  
      /**
       * Creates a mocked SharedPreferences.
       */
      private SharedPreferencesHelper createMockSharedPreference() {
          // Mocking reading the SharedPreferences as if mMockSharedPreferences was previously written
          // correctly.
          when(mMockSharedPreferences.getString(eq(SharedPreferencesHelper.KEY_NAME), anyString()))
                  .thenReturn(mSharedPreferenceEntry.getName());
          when(mMockSharedPreferences.getString(eq(SharedPreferencesHelper.KEY_EMAIL), anyString()))
                  .thenReturn(mSharedPreferenceEntry.getEmail());
          when(mMockSharedPreferences.getLong(eq(SharedPreferencesHelper.KEY_DOB), anyLong()))
                  .thenReturn(mSharedPreferenceEntry.getDateOfBirth().getTimeInMillis());
  
          // Mocking a successful commit.
          when(mMockEditor.commit()).thenReturn(true);
  
          // Return the MockEditor when requesting it.
          when(mMockSharedPreferences.edit()).thenReturn(mMockEditor);
          return new SharedPreferencesHelper(mMockSharedPreferences);
      }
  
      /**
       * Creates a mocked SharedPreferences that fails when writing.
       */
      private SharedPreferencesHelper createBrokenMockSharedPreference() {
          // Mocking a commit that fails.
          when(mMockBrokenEditor.commit()).thenReturn(false);
  
          // Return the broken MockEditor when requesting it.
          when(mMockBrokenSharedPreferences.edit()).thenReturn(mMockBrokenEditor);
          return new SharedPreferencesHelper(mMockBrokenSharedPreferences);
      }
  }
  