diff --git a/app/src/main/java/com/eventyay/organizer/common/di/module/ViewModelModule.java b/app/src/main/java/com/eventyay/organizer/common/di/module/ViewModelModule.java index 941565a68..db2438311 100644 --- a/app/src/main/java/com/eventyay/organizer/common/di/module/ViewModelModule.java +++ b/app/src/main/java/com/eventyay/organizer/common/di/module/ViewModelModule.java @@ -33,6 +33,7 @@ import com.eventyay.organizer.core.organizer.update.UpdateOrganizerInfoViewModel; import com.eventyay.organizer.core.role.list.RoleListViewModel; import com.eventyay.organizer.core.role.invite.RoleInviteViewModel; +import com.eventyay.organizer.core.session.create.CreateSessionViewModel; import com.eventyay.organizer.core.settings.autocheckin.AutoCheckInViewModel; import com.eventyay.organizer.core.settings.restriction.TicketSettingsViewModel; import com.eventyay.organizer.core.share.ShareEventViewModel; @@ -246,6 +247,11 @@ public abstract class ViewModelModule { @ViewModelKey(AttendeesViewModel.class) public abstract ViewModel bindAttendeesViewModel(AttendeesViewModel attendeesViewModel); + @Binds + @IntoMap + @ViewModelKey(CreateSessionViewModel.class) + public abstract ViewModel bindCreateSessionViewModel(CreateSessionViewModel createSessionViewModel); + @Binds public abstract ViewModelProvider.Factory bindViewModelFactory(OrgaViewModelFactory factory); diff --git a/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionFragment.java b/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionFragment.java index 1d2dba362..8c3bc47c0 100644 --- a/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionFragment.java +++ b/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionFragment.java @@ -3,6 +3,9 @@ import androidx.databinding.DataBindingUtil; import android.os.Bundle; import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; +import androidx.lifecycle.ViewModelProviders; + import com.google.android.material.textfield.TextInputLayout; import android.text.Editable; import android.text.TextUtils; @@ -25,14 +28,13 @@ import javax.inject.Inject; import br.com.ilhasoft.support.validation.Validator; -import dagger.Lazy; import static com.eventyay.organizer.ui.ViewUtils.showView; -public class CreateSessionFragment extends BaseFragment implements CreateSessionView { +public class CreateSessionFragment extends BaseFragment implements CreateSessionView { @Inject - Lazy presenterProvider; + ViewModelProvider.Factory viewModelFactory; private SessionCreateLayoutBinding binding; private Validator validator; @@ -40,6 +42,8 @@ public class CreateSessionFragment extends BaseFragment private static final String SESSION_KEY = "session_id"; private ArrayAdapter sessionStateAdapter; + private CreateSessionViewModel createSessionViewModel; + private boolean isSessionUpdating; private long trackId; private long eventId; @@ -84,14 +88,15 @@ public void onCreate(@Nullable Bundle savedInstanceState) { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = DataBindingUtil.inflate(inflater, R.layout.session_create_layout, container, false); + createSessionViewModel = ViewModelProviders.of(this, viewModelFactory).get(CreateSessionViewModel.class); validator = new Validator(binding.form); binding.submit.setOnClickListener(view -> { if (validator.validate()) { if (isSessionUpdating) { - getPresenter().updateSession(trackId, eventId); + createSessionViewModel.updateSession(trackId, eventId); } else { - getPresenter().createSession(trackId, eventId); + createSessionViewModel.createSession(trackId, eventId); } } }); @@ -110,11 +115,15 @@ private void setUpSpinner() { @Override public void onStart() { super.onStart(); - getPresenter().attach(this); - binding.setSession(getPresenter().getSession()); + createSessionViewModel.getProgress().observe(this, this::showProgress); + createSessionViewModel.getDismiss().observe(this, (dismiss) -> dismiss()); + createSessionViewModel.getSuccess().observe(this, this::onSuccess); + createSessionViewModel.getError().observe(this, this::showError); + createSessionViewModel.getSessionLiveData().observe(this, this::setSession); + binding.setSession(createSessionViewModel.getSession()); if (isSessionUpdating) { - getPresenter().loadSession(sessionId); + createSessionViewModel.loadSession(sessionId); } validate(binding.form.slidesUrlLayout, ValidateUtils::validateUrl, getResources().getString(R.string.url_validation_error)); @@ -157,7 +166,7 @@ public void afterTextChanged(Editable editable) { @Override public void setSession(Session session) { binding.setSession(session); - String state = getPresenter().getSession().getState(); + String state = createSessionViewModel.getSession().getState(); int statePosition = sessionStateAdapter.getPosition(state); binding.form.spinner.setSelection(statePosition); } @@ -171,11 +180,6 @@ protected int getTitle() { } } - @Override - public Lazy getPresenterProvider() { - return presenterProvider; - } - @Override public void showProgress(boolean show) { showView(binding.progressBar, show); diff --git a/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionPresenter.java b/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionPresenter.java deleted file mode 100644 index c82476bc5..000000000 --- a/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionPresenter.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.eventyay.organizer.core.session.create; - -import com.eventyay.organizer.common.mvp.presenter.AbstractBasePresenter; -import com.eventyay.organizer.common.rx.Logger; -import com.eventyay.organizer.data.event.Event; -import com.eventyay.organizer.data.session.Session; -import com.eventyay.organizer.data.session.SessionRepository; -import com.eventyay.organizer.data.tracks.Track; -import com.eventyay.organizer.utils.DateUtils; -import com.eventyay.organizer.utils.StringUtils; -import org.threeten.bp.LocalDateTime; -import org.threeten.bp.ZonedDateTime; -import org.threeten.bp.format.DateTimeParseException; - -import javax.inject.Inject; - -import static com.eventyay.organizer.common.rx.ViewTransformers.dispose; -import static com.eventyay.organizer.common.rx.ViewTransformers.progressiveErroneous; - -public class CreateSessionPresenter extends AbstractBasePresenter { - - private final SessionRepository sessionRepository; - private Session session = new Session(); - - @Inject - public CreateSessionPresenter(SessionRepository sessionRepository) { - this.sessionRepository = sessionRepository; - - LocalDateTime current = LocalDateTime.now(); - - String isoDate = DateUtils.formatDateToIso(current); - session.setStartsAt(isoDate); - session.setEndsAt(isoDate); - } - - @Override - public void start() { - // Nothing to do - } - - public Session getSession() { - return session; - } - - private boolean verify() { - try { - ZonedDateTime start = DateUtils.getDate(session.getStartsAt()); - ZonedDateTime end = DateUtils.getDate(session.getEndsAt()); - - if (!end.isAfter(start)) { - getView().showError("End time should be after start time"); - return false; - } - return true; - } catch (DateTimeParseException pe) { - getView().showError("Please enter date in correct format"); - return false; - } - } - - protected void nullifyEmptyFields(Session session) { - session.setSlidesUrl(StringUtils.emptyToNull(session.getSlidesUrl())); - session.setAudioUrl(StringUtils.emptyToNull(session.getAudioUrl())); - session.setVideoUrl(StringUtils.emptyToNull(session.getVideoUrl())); - session.setSignupUrl(StringUtils.emptyToNull(session.getSignupUrl())); - } - - //Used for loading the session information on start - public void loadSession(long sessionId) { - sessionRepository - .getSession(sessionId, false) - .compose(dispose(getDisposable())) - .compose(progressiveErroneous(getView())) - .doFinally(this::showSession) - .subscribe(loadedSession -> this.session = (Session) loadedSession, Logger::logError); - } - - private void showSession() { - getView().setSession(session); - } - - //method called for updating an session - public void updateSession(long trackId, long eventId) { - Track track = new Track(); - Event event = new Event(); - - track.setId(trackId); - event.setId(eventId); - session.setTrack(track); - session.setEvent(event); - nullifyEmptyFields(session); - - sessionRepository - .updateSession(session) - .compose(dispose(getDisposable())) - .compose(progressiveErroneous(getView())) - .subscribe(updatedSession -> { - getView().onSuccess("Session Updated Successfully"); - getView().dismiss(); - }, Logger::logError); - } - - public void createSession(long trackId, long eventId) { - if (!verify()) - return; - - Track track = new Track(); - Event event = new Event(); - - track.setId(trackId); - event.setId(eventId); - session.setTrack(track); - session.setEvent(event); - - nullifyEmptyFields(session); - - sessionRepository - .createSession(session) - .compose(dispose(getDisposable())) - .compose(progressiveErroneous(getView())) - .subscribe(createdSession -> { - getView().onSuccess("Session Created"); - getView().dismiss(); - }, Logger::logError); - } -} diff --git a/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionViewModel.java b/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionViewModel.java new file mode 100644 index 000000000..8825de632 --- /dev/null +++ b/app/src/main/java/com/eventyay/organizer/core/session/create/CreateSessionViewModel.java @@ -0,0 +1,156 @@ +package com.eventyay.organizer.core.session.create; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; + +import com.eventyay.organizer.common.livedata.SingleEventLiveData; +import com.eventyay.organizer.data.event.Event; +import com.eventyay.organizer.data.session.Session; +import com.eventyay.organizer.data.session.SessionRepository; +import com.eventyay.organizer.data.tracks.Track; +import com.eventyay.organizer.utils.DateUtils; +import com.eventyay.organizer.utils.ErrorUtils; +import com.eventyay.organizer.utils.StringUtils; + +import org.threeten.bp.LocalDateTime; +import org.threeten.bp.ZonedDateTime; +import org.threeten.bp.format.DateTimeParseException; + +import javax.inject.Inject; + +import io.reactivex.disposables.CompositeDisposable; + +public class CreateSessionViewModel extends ViewModel { + + private final SessionRepository sessionRepository; + private Session session = new Session(); + + private final CompositeDisposable compositeDisposable = new CompositeDisposable(); + private final SingleEventLiveData progress = new SingleEventLiveData<>(); + private final SingleEventLiveData error = new SingleEventLiveData<>(); + private final SingleEventLiveData success = new SingleEventLiveData<>(); + private final SingleEventLiveData dismiss = new SingleEventLiveData<>(); + private final SingleEventLiveData sessionLiveData = new SingleEventLiveData<>(); + + @Inject + public CreateSessionViewModel(SessionRepository sessionRepository) { + this.sessionRepository = sessionRepository; + + LocalDateTime current = LocalDateTime.now(); + + String isoDate = DateUtils.formatDateToIso(current); + session.setStartsAt(isoDate); + session.setEndsAt(isoDate); + } + + public LiveData getProgress() { + return progress; + } + + public LiveData getSuccess() { + return success; + } + + public LiveData getDismiss() { + return dismiss; + } + + public LiveData getError() { + return error; + } + + public LiveData getSessionLiveData() { + return sessionLiveData; + } + + public Session getSession() { + return session; + } + + private boolean verify() { + try { + ZonedDateTime start = DateUtils.getDate(session.getStartsAt()); + ZonedDateTime end = DateUtils.getDate(session.getEndsAt()); + + if (!end.isAfter(start)) { + error.setValue("End time should be after start time"); + return false; + } + return true; + } catch (DateTimeParseException pe) { + error.setValue("Please enter date in correct format"); + return false; + } + } + + protected void nullifyEmptyFields(Session session) { + session.setSlidesUrl(StringUtils.emptyToNull(session.getSlidesUrl())); + session.setAudioUrl(StringUtils.emptyToNull(session.getAudioUrl())); + session.setVideoUrl(StringUtils.emptyToNull(session.getVideoUrl())); + session.setSignupUrl(StringUtils.emptyToNull(session.getSignupUrl())); + } + + // Used for loading the session information on start + public void loadSession(long sessionId) { + + compositeDisposable.add( + sessionRepository + .getSession(sessionId, false) + .doOnSubscribe(disposable -> progress.setValue(true)) + .doFinally(() -> progress.setValue(false)) + .doFinally(this::showSession) + .subscribe(loadedSession -> this.session = loadedSession, + throwable -> error.setValue(ErrorUtils.getMessage(throwable).toString()))); + } + + private void showSession() { + sessionLiveData.setValue(session); + } + + // Method called for updating an session + public void updateSession(long trackId, long eventId) { + Track track = new Track(); + Event event = new Event(); + + track.setId(trackId); + event.setId(eventId); + session.setTrack(track); + session.setEvent(event); + nullifyEmptyFields(session); + + compositeDisposable.add( + sessionRepository + .updateSession(session) + .doOnSubscribe(disposable -> progress.setValue(true)) + .doFinally(() -> progress.setValue(false)) + .subscribe(updatedSession -> { + success.setValue("Session Updated Successfully"); + dismiss.call(); + }, throwable -> error.setValue(ErrorUtils.getMessage(throwable).toString()))); + } + + public void createSession(long trackId, long eventId) { + if (!verify()) + return; + + Track track = new Track(); + Event event = new Event(); + + track.setId(trackId); + event.setId(eventId); + session.setTrack(track); + session.setEvent(event); + + nullifyEmptyFields(session); + + compositeDisposable.add( + sessionRepository + .createSession(session) + .doOnSubscribe(disposable -> progress.setValue(true)) + .doFinally(() -> progress.setValue(false)) + .subscribe(createdSession -> { + success.setValue("Session Created"); + dismiss.call(); + }, throwable -> error.setValue(ErrorUtils.getMessage(throwable).toString()))); + } +} diff --git a/app/src/test/java/com/eventyay/organizer/core/presenter/CreateSessionPresenterTest.java b/app/src/test/java/com/eventyay/organizer/core/presenter/CreateSessionPresenterTest.java deleted file mode 100644 index fd1e27464..000000000 --- a/app/src/test/java/com/eventyay/organizer/core/presenter/CreateSessionPresenterTest.java +++ /dev/null @@ -1,193 +0,0 @@ -package com.eventyay.organizer.core.presenter; - -import com.eventyay.organizer.core.session.create.CreateSessionPresenter; -import com.eventyay.organizer.core.session.create.CreateSessionView; -import com.eventyay.organizer.data.session.Session; -import com.eventyay.organizer.data.session.SessionRepository; -import com.eventyay.organizer.utils.DateUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.threeten.bp.LocalDateTime; - -import io.reactivex.Observable; -import io.reactivex.android.plugins.RxAndroidPlugins; -import io.reactivex.plugins.RxJavaPlugins; -import io.reactivex.schedulers.Schedulers; - -import static org.junit.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class CreateSessionPresenterTest { - - @Rule - public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock - private CreateSessionView createSessionView; - @Mock - private SessionRepository sessionRepository; - - private CreateSessionPresenter createSessionPresenter; - private static final Session SESSION = Session.builder().id(2L).title("dd").build(); - private static final String ERROR = "Error"; - private static final long EVENT_ID = 5L; - private static final long TRACK_ID = 5L; - - @Before - public void setUp() { - RxJavaPlugins.setIoSchedulerHandler(scheduler -> Schedulers.trampoline()); - RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerCallable -> Schedulers.trampoline()); - - createSessionPresenter = new CreateSessionPresenter(sessionRepository); - createSessionPresenter.attach(createSessionView); - } - - @After - public void tearDown() { - RxJavaPlugins.reset(); - RxAndroidPlugins.reset(); - } - - @Test - public void shouldRejectWrongDates() { - Session session = createSessionPresenter.getSession(); - - String isoDate = DateUtils.formatDateToIso(LocalDateTime.now()); - session.setStartsAt(isoDate); - session.setEndsAt(isoDate); - - createSessionPresenter.createSession(TRACK_ID, EVENT_ID); - - verify(createSessionView).showError(anyString()); - verify(sessionRepository, never()).createSession(any()); - } - - @Test - public void shouldAcceptCorrectDates() { - Session session = createSessionPresenter.getSession(); - - when(sessionRepository.createSession(session)).thenReturn(Observable.empty()); - - String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); - String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); - session.setStartsAt(isoDateNow); - session.setEndsAt(isoDateThen); - - createSessionPresenter.createSession(TRACK_ID, EVENT_ID); - - verify(createSessionView, never()).showError(anyString()); - verify(sessionRepository).createSession(session); - } - - @Test - public void shouldNullifyEmptyFields() { - Session session = createSessionPresenter.getSession(); - when(sessionRepository.createSession(session)).thenReturn(Observable.just(session)); - - session.setSlidesUrl(""); - session.setAudioUrl(""); - session.setVideoUrl(""); - session.setSignupUrl(""); - - String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); - String isoDateMax = DateUtils.formatDateToIso(LocalDateTime.MAX); - session.setStartsAt(isoDateNow); - session.setEndsAt(isoDateMax); - - createSessionPresenter.createSession(TRACK_ID, EVENT_ID); - assertNull(session.getSlidesUrl()); - assertNull(session.getAudioUrl()); - assertNull(session.getVideoUrl()); - assertNull(session.getSignupUrl()); - } - - @Test - public void shouldShowSuccessOnCreated() { - Session session = createSessionPresenter.getSession(); - - String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); - String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); - session.setStartsAt(isoDateNow); - session.setEndsAt(isoDateThen); - - when(sessionRepository.createSession(createSessionPresenter.getSession())).thenReturn(Observable.just(SESSION)); - - createSessionPresenter.createSession(TRACK_ID, EVENT_ID); - - InOrder inOrder = Mockito.inOrder(createSessionView); - - inOrder.verify(createSessionView).showProgress(true); - inOrder.verify(createSessionView).onSuccess(anyString()); - inOrder.verify(createSessionView).showProgress(false); - } - - @Test - public void shouldShowErrorOnFailure() { - Session session = createSessionPresenter.getSession(); - - String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); - String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); - session.setStartsAt(isoDateNow); - session.setEndsAt(isoDateThen); - - when(sessionRepository.createSession(createSessionPresenter.getSession())).thenReturn(Observable.error(new Throwable(ERROR))); - - createSessionPresenter.createSession(TRACK_ID, EVENT_ID); - - InOrder inOrder = Mockito.inOrder(createSessionView); - - inOrder.verify(createSessionView).showProgress(true); - inOrder.verify(createSessionView).showError(ERROR); - inOrder.verify(createSessionView).showProgress(false); - } - - @Test - public void shouldShowSuccessOnUpdated() { - Session session = createSessionPresenter.getSession(); - - String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); - String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); - session.setStartsAt(isoDateNow); - session.setEndsAt(isoDateThen); - - when(sessionRepository.updateSession(createSessionPresenter.getSession())).thenReturn(Observable.just(SESSION)); - - createSessionPresenter.updateSession(TRACK_ID, EVENT_ID); - - InOrder inOrder = Mockito.inOrder(createSessionView); - - inOrder.verify(createSessionView).showProgress(true); - inOrder.verify(createSessionView).onSuccess(anyString()); - inOrder.verify(createSessionView).showProgress(false); - } - - @Test - public void shouldShowErrorOnUpdateFailure() { - Session session = createSessionPresenter.getSession(); - - String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); - String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); - session.setStartsAt(isoDateNow); - session.setEndsAt(isoDateThen); - - when(sessionRepository.updateSession(createSessionPresenter.getSession())).thenReturn(Observable.error(new Throwable(ERROR))); - - createSessionPresenter.updateSession(TRACK_ID, EVENT_ID); - - InOrder inOrder = Mockito.inOrder(createSessionView); - - inOrder.verify(createSessionView).showProgress(true); - inOrder.verify(createSessionView).showError(ERROR); - inOrder.verify(createSessionView).showProgress(false); - } -} diff --git a/app/src/test/java/com/eventyay/organizer/core/session/create/CreateSessionViewModelTest.java b/app/src/test/java/com/eventyay/organizer/core/session/create/CreateSessionViewModelTest.java new file mode 100644 index 000000000..e0a05b56f --- /dev/null +++ b/app/src/test/java/com/eventyay/organizer/core/session/create/CreateSessionViewModelTest.java @@ -0,0 +1,231 @@ +package com.eventyay.organizer.core.session.create; + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule; +import androidx.lifecycle.Observer; + +import com.eventyay.organizer.data.session.Session; +import com.eventyay.organizer.data.session.SessionRepository; +import com.eventyay.organizer.utils.DateUtils; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.threeten.bp.LocalDateTime; + +import io.reactivex.Observable; +import io.reactivex.android.plugins.RxAndroidPlugins; +import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.Schedulers; + +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.when; + +@RunWith(JUnit4.class) +public class CreateSessionViewModelTest { + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + @Rule + public TestRule rule = new InstantTaskExecutorRule(); + + @Mock + private SessionRepository sessionRepository; + + @Mock + Observer error; + @Mock + Observer progress; + @Mock + Observer success; + @Mock + Observer dismiss; + + private CreateSessionViewModel createSessionViewModel; + private static final Session SESSION = Session.builder().id(2L).title("dd").build(); + private static final String ERROR = "Error"; + private static final long EVENT_ID = 5L; + private static final long TRACK_ID = 5L; + + @Before + public void setUp() { + RxJavaPlugins.setIoSchedulerHandler(scheduler -> Schedulers.trampoline()); + RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerCallable -> Schedulers.trampoline()); + + createSessionViewModel = new CreateSessionViewModel(sessionRepository); + } + + @After + public void tearDown() { + RxJavaPlugins.reset(); + RxAndroidPlugins.reset(); + } + + @Test + public void shouldRejectWrongDates() { + Session session = createSessionViewModel.getSession(); + + String isoDate = DateUtils.formatDateToIso(LocalDateTime.now()); + session.setStartsAt(isoDate); + session.setEndsAt(isoDate); + + InOrder inOrder = Mockito.inOrder(sessionRepository, error); + + createSessionViewModel.getError().observeForever(error); + + createSessionViewModel.createSession(TRACK_ID, EVENT_ID); + + inOrder.verify(error).onChanged(anyString()); + inOrder.verify(sessionRepository, never()).createSession(any()); + } + + @Test + public void shouldAcceptCorrectDates() { + Session session = createSessionViewModel.getSession(); + + when(sessionRepository.createSession(session)).thenReturn(Observable.empty()); + + String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); + String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); + session.setStartsAt(isoDateNow); + session.setEndsAt(isoDateThen); + + InOrder inOrder = Mockito.inOrder(sessionRepository, error); + + createSessionViewModel.getError().observeForever(error); + + createSessionViewModel.createSession(TRACK_ID, EVENT_ID); + + inOrder.verify(error, never()).onChanged(anyString()); + inOrder.verify(sessionRepository).createSession(session); + } + + @Test + public void shouldNullifyEmptyFields() { + Session session = createSessionViewModel.getSession(); + when(sessionRepository.createSession(session)).thenReturn(Observable.just(session)); + + session.setSlidesUrl(""); + session.setAudioUrl(""); + session.setVideoUrl(""); + session.setSignupUrl(""); + + String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); + String isoDateMax = DateUtils.formatDateToIso(LocalDateTime.MAX); + session.setStartsAt(isoDateNow); + session.setEndsAt(isoDateMax); + + createSessionViewModel.createSession(TRACK_ID, EVENT_ID); + assertNull(session.getSlidesUrl()); + assertNull(session.getAudioUrl()); + assertNull(session.getVideoUrl()); + assertNull(session.getSignupUrl()); + } + + @Test + public void shouldShowSuccessOnCreated() { + Session session = createSessionViewModel.getSession(); + + String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); + String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); + session.setStartsAt(isoDateNow); + session.setEndsAt(isoDateThen); + + when(sessionRepository.createSession(createSessionViewModel.getSession())).thenReturn(Observable.just(SESSION)); + + InOrder inOrder = Mockito.inOrder(progress, success, dismiss); + + createSessionViewModel.getProgress().observeForever(progress); + createSessionViewModel.getSuccess().observeForever(success); + createSessionViewModel.getDismiss().observeForever(dismiss); + + createSessionViewModel.createSession(TRACK_ID, EVENT_ID); + + inOrder.verify(progress).onChanged(true); + inOrder.verify(success).onChanged(anyString()); + inOrder.verify(dismiss).onChanged(null); + inOrder.verify(progress).onChanged(false); + } + + @Test + public void shouldShowErrorOnFailure() { + Session session = createSessionViewModel.getSession(); + + String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); + String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); + session.setStartsAt(isoDateNow); + session.setEndsAt(isoDateThen); + + when(sessionRepository.createSession(createSessionViewModel.getSession())).thenReturn(Observable.error(new Throwable(ERROR))); + + InOrder inOrder = Mockito.inOrder(progress, error); + + createSessionViewModel.getProgress().observeForever(progress); + createSessionViewModel.getError().observeForever(error); + + createSessionViewModel.createSession(TRACK_ID, EVENT_ID); + + inOrder.verify(progress).onChanged(true); + inOrder.verify(error).onChanged(anyString()); + inOrder.verify(progress).onChanged(false); + } + + @Test + public void shouldShowSuccessOnUpdated() { + Session session = createSessionViewModel.getSession(); + + String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); + String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); + session.setStartsAt(isoDateNow); + session.setEndsAt(isoDateThen); + + when(sessionRepository.updateSession(createSessionViewModel.getSession())).thenReturn(Observable.just(SESSION)); + + InOrder inOrder = Mockito.inOrder(progress, success, dismiss); + + createSessionViewModel.getProgress().observeForever(progress); + createSessionViewModel.getSuccess().observeForever(success); + createSessionViewModel.getDismiss().observeForever(dismiss); + + createSessionViewModel.updateSession(TRACK_ID, EVENT_ID); + + inOrder.verify(progress).onChanged(true); + inOrder.verify(success).onChanged(anyString()); + inOrder.verify(dismiss).onChanged(null); + inOrder.verify(progress).onChanged(false); + } + + @Test + public void shouldShowErrorOnUpdateFailure() { + Session session = createSessionViewModel.getSession(); + + String isoDateNow = DateUtils.formatDateToIso(LocalDateTime.now()); + String isoDateThen = DateUtils.formatDateToIso(LocalDateTime.MAX); + session.setStartsAt(isoDateNow); + session.setEndsAt(isoDateThen); + + when(sessionRepository.updateSession(createSessionViewModel.getSession())).thenReturn(Observable.error(new Throwable(ERROR))); + + InOrder inOrder = Mockito.inOrder(progress, error); + + createSessionViewModel.getProgress().observeForever(progress); + createSessionViewModel.getError().observeForever(error); + + createSessionViewModel.updateSession(TRACK_ID, EVENT_ID); + + inOrder.verify(progress).onChanged(true); + inOrder.verify(error).onChanged(anyString()); + inOrder.verify(progress).onChanged(false); + } +}