blob: eb4ca25b0f5c9a0c201ebeb7fd303cf32cb8eb30 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 Christian Pontesegger and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christian Pontesegger - initial API and implementation
*******************************************************************************/
package org.eclipse.skills.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Arrays;
import org.eclipse.skills.model.IUser;
import org.eclipse.skills.model.IUserTask;
import org.eclipse.skills.service.storage.IDataStorage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class UserStorageTest {
// @formatter:off
private static final byte[] DEFAULT_USER = ("<?xml version=\"1.0\" encoding=\"ASCII\"?>\n"
+ "<skills:User xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:skills=\"http://eclipse.org/skills/1.0.0\" name=\"John Doe\">\n"
+ " <usertasks>\n"
+ " <task href=\"platform:/plugin/org.eclipse.skills/resources/UserStorageTest.skills#UserStorageTest_Quest_First_task\"/>\n"
+ " </usertasks>\n"
+ " <experience name=\"Experience\" experience=\"30\">\n"
+ " <progression xsi:type=\"skills:FactorProgression\"/>\n"
+ " </experience>\n"
+ "</skills:User>\n").getBytes();
// @formatter:on
private static byte[] getDamagedProfile() {
final byte[] damagedProfile = Arrays.copyOf(DEFAULT_USER, DEFAULT_USER.length);
damagedProfile[0] = 'x';
return damagedProfile;
}
private UserStorage fUserStorage;
private IDataStorage fStorageMock;
@BeforeEach
public void setup() {
fStorageMock = mock(IDataStorage.class);
fUserStorage = new UserStorage(fStorageMock);
}
@Test
@DisplayName("resetProgress() re-initializes the user")
public void resetProgressReInitializesUser() throws IOException {
final IUser defaultUser = loadDefaultUser();
final String oldName = defaultUser.getName();
final String oldAvatar = defaultUser.getImageLocation();
fUserStorage.resetProgress();
assertEquals(oldName, fUserStorage.getUser().getName());
assertEquals(oldAvatar, fUserStorage.getUser().getImageLocation());
assertEquals(0, fUserStorage.getUser().getExperience().getExperience());
assertTrue(fUserStorage.getUser().getBadges().isEmpty());
}
@Test
@DisplayName("getUser() creates a default user when storage is empty")
public void getUserCreatesDefaultUserOnEmptyStorage() {
final IUser user = fUserStorage.getUser();
assertNotNull(user.getName());
}
@Test
@DisplayName("getUser() loads data from storage")
public void getUserLoadsDataFromStorage() {
final IUser user = loadDefaultUser();
assertEquals("John Doe", user.getName());
}
@Test
@DisplayName("getUser() contains resolved usertask -> task references")
void resolveTaskReferences() {
final IUser user = loadDefaultUser();
assertFalse(user.getUsertasks().isEmpty());
for (final IUserTask usertask : user.getUsertasks())
assertFalse(usertask.getTask().eIsProxy());
}
@Test
@DisplayName("On a damaged profile the old one gets backup'ed")
public void backupOnDamagedProfile() throws IOException {
when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(getDamagedProfile());
when(fStorageMock.hasResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1")).thenReturn(false);
fUserStorage.getUser();
verify(fStorageMock, times(1)).storeResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1", getDamagedProfile());
}
@Test
@DisplayName("On a damaged profile backups do not get overwritten")
public void backupOnDamagedProfileDoesNotOverwrite() throws IOException {
when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
when(fStorageMock.hasResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1")).thenReturn(true);
when(fStorageMock.hasResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "2")).thenReturn(false);
when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(getDamagedProfile());
fUserStorage.getUser();
verify(fStorageMock, times(0)).storeResource(eq(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "1"), any());
verify(fStorageMock, times(1)).storeResource(IDataStorage.USER_PROFILE + UserStorage.BACKUP_SUFFIX + "2", getDamagedProfile());
}
@Test
@DisplayName("On a damaged profile a new user gets created")
public void newUserOnDamagedProfile() throws IOException {
when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(getDamagedProfile());
assertNotNull(fUserStorage.getUser());
}
@Test
@DisplayName("storeUser() saves the user instance")
public void storeUser() throws IOException {
final IUser user = loadDefaultUser();
fUserStorage.storeUser(user);
verify(fStorageMock, times(1)).storeResource(IDataStorage.USER_PROFILE, DEFAULT_USER);
}
private IUser loadDefaultUser() {
try {
when(fStorageMock.hasResource(IDataStorage.USER_PROFILE)).thenReturn(true);
when(fStorageMock.loadResource(IDataStorage.USER_PROFILE)).thenReturn(DEFAULT_USER);
return fUserStorage.getUser();
} catch (final IOException e) {
throw new UncheckedIOException(e);
}
}
}