/**
* Marabou - Audio Tagger
* Copyright (C) 2012 - 2016 Jan-Hendrik Peters
* https://github.com/hennr/marabou
* Marabou is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
*/
package com.github.marabou.audio.store;
import com.github.marabou.audio.AudioFile;
import com.github.marabou.audio.AudioFileFactory;
import com.github.marabou.audio.save.SaveService;
import com.github.marabou.ui.events.FilesSelectedEvent;
import com.github.marabou.ui.events.OpenFileEvent;
import com.github.marabou.ui.events.SaveSelectedFilesEvent;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.mpatric.mp3agic.*;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.io.File;
import java.io.IOException;
import java.util.Set;
import static com.github.marabou.helper.Constants.IGNORE_THIS_WHEN_SAVING;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static testdata.builder.TestAudioFileBuilder.aValidCompleteAudioFile;
import static testdata.builder.TestAudioFileBuilder.anotherValidCompleteAudioFile;
public class AudioFileStoreTest {
private String storedAudioFileFilePath = "/path";
@Test
public void getsTheSameAudioFileByFilePathAfterStoring() throws Exception {
// given
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
AudioFileStore audioFileStore = new AudioFileStore(new EventBus(), fileFactoryMock, new SaveService());
File dummyFile = mock(File.class);
AudioFile audioFile = new AudioFile(storedAudioFileFilePath);
when(fileFactoryMock.createAudioFile(any(File.class))).thenReturn(audioFile);
// when
audioFileStore.addFile(dummyFile);
AudioFile result = audioFileStore.getAudioFileByFilePath(storedAudioFileFilePath);
// then
assertEquals(audioFile, result);
}
@Test
public void getStoredFilesReturnsCorrectResults() {
// given
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
AudioFileStore audioFileStore = new AudioFileStore(new EventBus(), fileFactoryMock, new SaveService());
File dummyFile = mock(File.class);
AudioFile audioFile = new AudioFile(storedAudioFileFilePath);
when(fileFactoryMock.createAudioFile(any(File.class))).thenReturn(audioFile);
// when
audioFileStore.addFile(dummyFile);
// then
assertEquals(1, audioFileStore.getStoredAudioFiles().size());
assertEquals(storedAudioFileFilePath, audioFileStore.getStoredAudioFiles().get(0).getFilePath());
}
@Test
public void canRemoveAudioFile() throws Exception {
// given
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
AudioFileStore audioFileStore = new AudioFileStore(new EventBus(), fileFactoryMock, new SaveService());
File dummyFile = mock(File.class);
AudioFile audioFile = new AudioFile(storedAudioFileFilePath);
when(fileFactoryMock.createAudioFile(any(File.class))).thenReturn(audioFile);
// when
audioFileStore.addFile(dummyFile);
audioFileStore.removeAudioFile(storedAudioFileFilePath);
// then
assertNull(audioFileStore.getAudioFileByFilePath(storedAudioFileFilePath));
assertEquals(0, audioFileStore.audioFiles.size());
}
@Test
public void doesNotStoreTheSameFileMoreThanOnce() {
// given
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
AudioFileStore audioFileStore = new AudioFileStore(new EventBus(), fileFactoryMock, new SaveService());
File dummyFile = mock(File.class);
AudioFile audioFile = new AudioFile("/path");
when(fileFactoryMock.createAudioFile(any(File.class))).thenReturn(audioFile);
// when
audioFileStore.addFile(dummyFile);
audioFileStore.addFile(dummyFile);
// then
assertEquals(1, audioFileStore.audioFiles.size());
}
@Test
public void propagatesANewFileFOnlyOnceOverTheEventBus() throws IOException {
// given
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
EventBus bus = spy(new EventBus());
AudioFileStore audioFileStore = new AudioFileStore(bus, fileFactoryMock, new SaveService());
File dummyFile = mock(File.class);
when(dummyFile.getCanonicalPath()).thenReturn("/path");
AudioFile audioFile = new AudioFile("/path");
when(fileFactoryMock.createAudioFile(any(File.class))).thenReturn(audioFile);
// when
bus.post(new OpenFileEvent(dummyFile));
bus.post(new OpenFileEvent(dummyFile));
// then
assertEquals(1, audioFileStore.audioFiles.size());
verify(bus, atMost(1)).post(isA(AudioFileAddedEvent.class));
}
@Test
public void remembersSelectedFilesOnFilesSelectedEvent() {
// given
EventBus bus = new EventBus();
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
AudioFileStore audioFileStore = new AudioFileStore(bus, fileFactoryMock, new SaveService());
AudioFile audioFile = new AudioFile("/path");
when(fileFactoryMock.createAudioFile(any(File.class))).thenReturn(audioFile);
Set<AudioFile> selectedFiles = Sets.newHashSet(audioFile);
// when
bus.post(new FilesSelectedEvent(selectedFiles));
// then
Set<AudioFile> result = audioFileStore.getSelectedAudioFiles();
assertEquals(1, result.size());
assertTrue(result.contains(audioFile));
}
@Test
public void forgetsAboutPreviouslySelectedFilesOnNewFilesSelectedEvent() {
// given
EventBus bus = new EventBus();
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
AudioFileStore audioFileStore = new AudioFileStore(bus, fileFactoryMock, new SaveService());
AudioFile audioFileOne = new AudioFile("/one");
when(fileFactoryMock.createAudioFile(any(File.class))).thenReturn(audioFileOne);
Set<AudioFile> selectedFiles = Sets.newHashSet(audioFileOne);
// when
bus.post(new FilesSelectedEvent(selectedFiles));
// next event
AudioFile audioFileTwo = new AudioFile("/two");
selectedFiles.clear();
selectedFiles.add(audioFileTwo);
bus.post(new FilesSelectedEvent(selectedFiles));
// then
Set<AudioFile> result = audioFileStore.getSelectedAudioFiles();
assertTrue(result.contains(audioFileTwo));
assertFalse(result.contains(audioFileOne));
}
@Test
public void justStoresAnId3v24TagWhenSavingFile() throws InvalidDataException, IOException, UnsupportedTagException {
// given
EventBus bus = new EventBus();
AudioFileFactory fileFactoryMock = mock(AudioFileFactory.class);
Mp3File mp3FileMock = mock(Mp3File.class);
when(fileFactoryMock.createMp3File(any())).thenReturn(mp3FileMock);
SaveService saveServiceMock = mock(SaveService.class);
AudioFileStore audioFileStore = new AudioFileStore(bus, fileFactoryMock, saveServiceMock);
AudioFile fileToBeSaved = new AudioFile("foo").withAlbum("bar");
audioFileStore.currentlySelectedFiles = Sets.newHashSet(fileToBeSaved);
// when
bus.post(new SaveSelectedFilesEvent());
// then
verify(mp3FileMock).setId3v2Tag(isA(ID3v24Tag.class));
verify(mp3FileMock, times(1)).setId3v2Tag(isA(ID3v2.class));
verify(mp3FileMock, never()).setId3v1Tag(isA(ID3v1.class));
}
@Test
public void aSaveSelectedFilesEventProvokesNewAudioFileSavedEvent() throws Exception {
// given
AudioFile audioFileMock = mock(AudioFile.class);
AudioFileFactory audioFileFactoryMock = mock(AudioFileFactory.class);
when(audioFileFactoryMock.createAudioFile(any(Mp3File.class))).thenReturn(audioFileMock);
when(audioFileFactoryMock.createMp3File(any())).thenReturn(mock(Mp3File.class));
EventBus eventBusMock = mock(EventBus.class);
SaveService saveServiceMock = mock(SaveService.class);
when(saveServiceMock.saveMp3File(any(Mp3File.class))).thenReturn("/newPath");
AudioFileStore audioFileStore = new AudioFileStore(eventBusMock, audioFileFactoryMock, saveServiceMock);
AudioFile audioFile = new AudioFile("/path").withAlbum("album");
audioFileStore.currentlySelectedFiles = Sets.newHashSet(audioFile);
// when
audioFileStore.onSaveSelectedFiles(new SaveSelectedFilesEvent());
// then
ArgumentCaptor<AudioFileSavedEvent> argument = ArgumentCaptor.forClass(AudioFileSavedEvent.class);
verify(eventBusMock).post(argument.capture());
assertEquals("/path", argument.getValue().oldFilePath);
assertEquals("/newPath", argument.getValue().newFilePath);
}
@Test
public void savesSidePanelEntriesToSelectedFiles() {
// given
Mp3File mp3FileMock = mock(Mp3File.class);
AudioFileFactory audioFileFactoryMock = mock(AudioFileFactory.class);
when(audioFileFactoryMock.createAudioFile(any(Mp3File.class))).thenReturn(
new AudioFile("will be used to hold new entries"));
when(audioFileFactoryMock.createMp3File(any())).thenReturn(mp3FileMock);
EventBus bus = new EventBus();
SaveService saveServiceMock = mock(SaveService.class);
AudioFileStore audioFileStore = new AudioFileStore(bus, audioFileFactoryMock, saveServiceMock);
AudioFile sidePanelEntriesAudioFile = aValidCompleteAudioFile();
audioFileStore.sidePanelEntries = sidePanelEntriesAudioFile;
AudioFile audioFile = new AudioFile("we need at least one selected file");
audioFileStore.currentlySelectedFiles = Sets.newHashSet(audioFile);
// when
bus.post(new SaveSelectedFilesEvent());
// then
ArgumentCaptor<ID3v24Tag> tagToBeSavedCaptor = ArgumentCaptor.forClass(ID3v24Tag.class);
verify(mp3FileMock).setId3v2Tag(tagToBeSavedCaptor.capture());
ID3v24Tag tag = tagToBeSavedCaptor.getValue();
assertEquals(sidePanelEntriesAudioFile.getArtist(), tag.getArtist());
assertEquals(sidePanelEntriesAudioFile.getAlbum(), tag.getAlbum());
assertEquals(sidePanelEntriesAudioFile.getComment(), tag.getComment());
assertEquals(sidePanelEntriesAudioFile.getComposer(), tag.getComposer());
assertEquals(sidePanelEntriesAudioFile.getDiscNumber(), tag.getPartOfSet());
assertEquals(sidePanelEntriesAudioFile.getGenre(), tag.getGenreDescription());
assertEquals(sidePanelEntriesAudioFile.getTitle(), tag.getTitle());
assertEquals(sidePanelEntriesAudioFile.getTrack(), tag.getTrack());
assertEquals(sidePanelEntriesAudioFile.getYear(), tag.getYear());
}
@Test
public void doesNotOverwriteValuesIfFieldIsSetToIgnore() {
// given
Mp3File mp3FileMock = mock(Mp3File.class);
AudioFileFactory audioFileFactoryMock = mock(AudioFileFactory.class);
when(audioFileFactoryMock.createAudioFile(any(Mp3File.class))).thenReturn(
new AudioFile("will be used to hold new entries"));
when(audioFileFactoryMock.createMp3File(any())).thenReturn(mp3FileMock);
EventBus bus = new EventBus();
SaveService saveServiceMock = mock(SaveService.class);
AudioFileStore audioFileStore = new AudioFileStore(bus, audioFileFactoryMock, saveServiceMock);
AudioFile sidePanelEntriesAudioFile = aValidCompleteAudioFile()
.withTitle(IGNORE_THIS_WHEN_SAVING)
.withTrack(IGNORE_THIS_WHEN_SAVING)
.withDiscNumber(IGNORE_THIS_WHEN_SAVING);
audioFileStore.sidePanelEntries = sidePanelEntriesAudioFile;
AudioFile selectedAudioFile = anotherValidCompleteAudioFile();
audioFileStore.currentlySelectedFiles = Sets.newHashSet(selectedAudioFile);
// when
bus.post(new SaveSelectedFilesEvent());
// then
ArgumentCaptor<ID3v24Tag> tagToBeSavedCaptor = ArgumentCaptor.forClass(ID3v24Tag.class);
verify(mp3FileMock).setId3v2Tag(tagToBeSavedCaptor.capture());
ID3v24Tag tag = tagToBeSavedCaptor.getValue();
// these should contain the side panel values
assertEquals(sidePanelEntriesAudioFile.getArtist(), tag.getArtist());
assertEquals(sidePanelEntriesAudioFile.getAlbum(), tag.getAlbum());
assertEquals(sidePanelEntriesAudioFile.getComment(), tag.getComment());
assertEquals(sidePanelEntriesAudioFile.getComposer(), tag.getComposer());
assertEquals(sidePanelEntriesAudioFile.getGenre(), tag.getGenreDescription());
assertEquals(sidePanelEntriesAudioFile.getYear(), tag.getYear());
// these should contain the old values
assertEquals(selectedAudioFile.getTitle(), tag.getTitle());
assertEquals(selectedAudioFile.getTrack(), tag.getTrack());
assertEquals(selectedAudioFile.getDiscNumber(), tag.getPartOfSet());
}
}