@Before
  public void setUp() throws Exception {
    repository = mock(IUnifiedRepository.class);

    session = mock(IPentahoSession.class);
    when(session.getName()).thenReturn("test");
    PentahoSessionHolder.setSession(session);

    userSettings =
        new HashMap<String, Serializable>() {
          {
            put(USER_SETTING_NAME_1, USER_SETTING_VALUE_1);
            put(UserSettingService.SETTING_PREFIX + COMMON_SETTING_NAME, COMMON_USER_SETTING_VALUE);
            put(USER_SETTING_NAME_2, USER_SETTING_VALUE_2);
            put(UserSettingService.SETTING_PREFIX + USER_SETTING_NAME_3, USER_SETTING_VALUE_3);
          }
        };
    globalSettings =
        new HashMap<String, Serializable>() {
          {
            put(GLOBAL_SETTING_NAME_1, GLOBAL_SETTING_VALUE_1);
            put(
                UserSettingService.SETTING_PREFIX + COMMON_SETTING_NAME,
                COMMON_GLOBAL_SETTING_VALUE);
            put(GLOBAL_SETTING_NAME_2, GLOBAL_SETTING_VALUE_2);
            put(UserSettingService.SETTING_PREFIX + GLOBAL_SETTING_NAME_3, GLOBAL_SETTING_VALUE_3);
          }
        };

    when(repository.getFileMetadata(eq(USER_FOLDER_ID))).thenReturn(userSettings);
    when(repository.getFileMetadata(eq(TENANT_FOLDER_ID))).thenReturn(globalSettings);

    final RepositoryFile tenantRepositoryFile = mock(RepositoryFile.class);
    when(tenantRepositoryFile.getId()).thenReturn(TENANT_FOLDER_ID);
    when(repository.getFile(eq(ClientRepositoryPaths.getEtcFolderPath())))
        .thenReturn(tenantRepositoryFile);

    final RepositoryFile userRepositoryFile = mock(RepositoryFile.class);
    when(userRepositoryFile.getId()).thenReturn(USER_FOLDER_ID);
    when(repository.getFile(eq(ClientRepositoryPaths.getUserHomeFolderPath(session.getName()))))
        .thenReturn(userRepositoryFile);

    securityHelper = mock(ISecurityHelper.class);
    when(securityHelper.runAsSystem(any(Callable.class)))
        .thenAnswer(
            new Answer<Object>() {
              @Override
              public Object answer(InvocationOnMock invocation) throws Throwable {
                final Callable callable = (Callable) invocation.getArguments()[0];
                if (callable != null) {
                  return callable.call();
                }
                return null;
              }
            });
    SecurityHelper.setMockInstance(securityHelper);

    userSettingService = new UserSettingService(repository);
    userSettingService.init(session);
  }
  @Test
  public void testDeleteUserSettingsByName() throws Exception {
    IAuthorizationPolicy policy = mock(IAuthorizationPolicy.class);
    when(policy.isAllowed(anyString())).thenReturn(true);
    PentahoSystem.registerObject(policy);

    final RepositoryFile repositoryFile = mock(RepositoryFile.class);
    when(repositoryFile.getId()).thenReturn(USER_FOLDER_ID);
    when(repository.getFile(anyString())).thenReturn(repositoryFile);

    doAnswer(
            new Answer() {
              @Override
              public Object answer(InvocationOnMock invocation) throws Throwable {

                final Map<String, Serializable> settings =
                    (Map<String, Serializable>) invocation.getArguments()[1];

                assertNotNull(settings);
                assertEquals(2, settings.size());

                final Iterator<String> iterator = settings.keySet().iterator();
                assertFalse(iterator.next().startsWith(UserSettingService.SETTING_PREFIX));
                assertFalse(iterator.next().startsWith(UserSettingService.SETTING_PREFIX));

                return null;
              }
            })
        .when(repository)
        .setFileMetadata(eq(USER_FOLDER_ID), anyMap());

    userSettingService.deleteUserSettings("test");
  }
  @Test
  public void testSetGlobalUserSettingNonAdmin() throws Exception {
    final String settingName = "settingName";
    final String settingValue = "settingValue";

    when(securityHelper.isPentahoAdministrator(eq(session))).thenReturn(false);

    assertEquals(4, globalSettings.size());
    userSettingService.setGlobalUserSetting(settingName, settingValue);
    assertEquals(4, globalSettings.size());
  }
  @Test
  public void testGetGlobalUserSetting() throws Exception {
    final String settingName = GLOBAL_SETTING_NAME_3;
    final String defaultValue = "defaultValue";

    final IUserSetting globalUserSetting =
        userSettingService.getGlobalUserSetting(settingName, defaultValue);

    assertEquals(settingName, globalUserSetting.getSettingName());
    assertEquals(GLOBAL_SETTING_VALUE_3, globalUserSetting.getSettingValue());
  }
  @Test
  public void testGetGlobalUserSettingUnset() throws Exception {
    final String settingName = "settings";
    final String defaultValue = "defaultValue";

    final IUserSetting globalUserSetting =
        userSettingService.getGlobalUserSetting(settingName, defaultValue);

    assertEquals(settingName, globalUserSetting.getSettingName());
    assertEquals(defaultValue, globalUserSetting.getSettingValue());
  }
  @Test
  public void testGetUserSettingOnlyGlobalExist() throws Exception {
    final String settingName = GLOBAL_SETTING_NAME_3;
    final String defaultValue = "defaultValue";

    when(session.getAttribute(eq("SPRING_SECURITY_CONTEXT"))).thenReturn(1);

    final IUserSetting userSetting = userSettingService.getUserSetting(settingName, defaultValue);
    assertEquals(settingName, userSetting.getSettingName());
    assertEquals(GLOBAL_SETTING_VALUE_3, userSetting.getSettingValue());
  }
  @Test
  public void testGetUserSettingUnset() throws Exception {
    final String settingName = "settingName";
    final String defaultValue = "defaultValue";

    when(session.getAttribute(eq("SPRING_SECURITY_CONTEXT"))).thenReturn(1);

    final IUserSetting userSetting = userSettingService.getUserSetting(settingName, defaultValue);
    assertEquals(settingName, userSetting.getSettingName());
    assertEquals(defaultValue, userSetting.getSettingValue());
  }
  @Test
  public void testSetGlobalUserSettingAdmin() throws Exception {
    final String settingName = "settingName";
    final String settingValue = "settingValue";

    when(securityHelper.isPentahoAdministrator(eq(session))).thenReturn(true);

    assertEquals(4, globalSettings.size());
    userSettingService.setGlobalUserSetting(settingName, settingValue);
    assertEquals(5, globalSettings.size());

    verify(repository).setFileMetadata(eq(TENANT_FOLDER_ID), anyMap());
  }
  @Test
  public void testSetUserSetting() throws Exception {
    final String settingName = "settingName";
    final String settingValue = "settingValue";

    assertEquals(4, userSettings.size());
    userSettingService.setUserSetting(settingName, settingValue);
    assertEquals(5, userSettings.size());

    final Serializable value = userSettings.get(UserSettingService.SETTING_PREFIX + settingName);
    assertEquals(settingValue, value);

    verify(repository).setFileMetadata(eq(USER_FOLDER_ID), anyMap());
  }
  @Test
  public void testGetUserSettingByName() throws Exception {
    final String settingName = USER_SETTING_NAME_3;
    final String defaultValue = "defaultValue";

    IAuthorizationPolicy policy = mock(IAuthorizationPolicy.class);
    when(policy.isAllowed(anyString())).thenReturn(true);
    PentahoSystem.registerObject(policy);

    // try to get existing setting
    final IUserSetting userSetting =
        userSettingService.getUserSetting("test", settingName, defaultValue);
    assertEquals(settingName, userSetting.getSettingName());
    assertEquals(USER_SETTING_VALUE_3, userSetting.getSettingValue());
  }
  @Test
  public void testGetUserSettings() throws Exception {
    final List<IUserSetting> settings = userSettingService.getUserSettings();

    assertNotNull(settings);
    assertEquals(3, settings.size());
    for (IUserSetting setting : settings) {
      if (COMMON_SETTING_NAME.equals(setting.getSettingName())) {
        assertEquals(COMMON_USER_SETTING_VALUE, setting.getSettingValue());
      } else if (USER_SETTING_NAME_3.equals(setting.getSettingName())) {
        assertEquals(USER_SETTING_VALUE_3, setting.getSettingValue());
      } else if (GLOBAL_SETTING_NAME_3.equals(setting.getSettingName())) {
        assertEquals(GLOBAL_SETTING_VALUE_3, setting.getSettingValue());
      }
    }
  }
  @Test
  public void testSetUserSettingByName() throws Exception {
    final String settingName = "settingName";
    final String settingValue = "settingValue";

    IAuthorizationPolicy policy = mock(IAuthorizationPolicy.class);
    when(policy.isAllowed(anyString())).thenReturn(true);
    PentahoSystem.registerObject(policy);

    assertEquals(4, userSettings.size());
    userSettingService.setUserSetting("test", settingName, settingValue);
    assertEquals(5, userSettings.size());

    final Serializable value = userSettings.get(UserSettingService.SETTING_PREFIX + settingName);
    assertEquals(settingValue, value);

    verify(repository).setFileMetadata(eq(USER_FOLDER_ID), anyMap());
  }
  @Test
  public void testGetGlobalUserSettings() throws Exception {
    final List<IUserSetting> globalUserSettings = userSettingService.getGlobalUserSettings();

    assertNotNull(globalUserSettings);
    assertEquals(2, globalUserSettings.size());
    label:
    for (IUserSetting setting : globalUserSettings) {
      for (String key : globalSettings.keySet()) {
        if (key.startsWith(UserSettingService.SETTING_PREFIX)
            && key.substring(UserSettingService.SETTING_PREFIX.length())
                .equals(setting.getSettingName())) {
          assertEquals(globalSettings.get(key), setting.getSettingValue());
          continue label;
        }
      }
      fail("wrong setting");
    }
  }
  @Test
  public void testGetUserSettingsByName() throws Exception {
    final List<IUserSetting> settings = userSettingService.getUserSettings("test");

    IAuthorizationPolicy policy = mock(IAuthorizationPolicy.class);
    when(policy.isAllowed(anyString())).thenReturn(true);
    PentahoSystem.registerObject(policy);

    assertNotNull(settings);
    assertEquals(2, settings.size());
    for (IUserSetting setting : settings) {
      if (COMMON_SETTING_NAME.equals(setting.getSettingName())) {
        assertEquals(COMMON_USER_SETTING_VALUE, setting.getSettingValue());
      } else if (USER_SETTING_NAME_3.equals(setting.getSettingName())) {
        assertEquals(USER_SETTING_VALUE_3, setting.getSettingValue());
      } else if (GLOBAL_SETTING_NAME_3.equals(setting.getSettingName())) {
        assertEquals(GLOBAL_SETTING_VALUE_3, setting.getSettingValue());
      }
    }
  }