diff --git a/app/src/test/java/org/sagebionetworks/research/app/InstructionStepTest.java b/app/src/test/java/org/sagebionetworks/research/app/InstructionStepTest.java index ff39b2554..3a8aba6db 100644 --- a/app/src/test/java/org/sagebionetworks/research/app/InstructionStepTest.java +++ b/app/src/test/java/org/sagebionetworks/research/app/InstructionStepTest.java @@ -33,7 +33,7 @@ package org.sagebionetworks.research.app; import org.junit.*; -import org.sagebionetworks.research.domain.step.ActiveUIStep; +import org.sagebionetworks.research.domain.step.ActiveUIStepBase; import org.sagebionetworks.research.domain.step.Step; import static org.junit.Assert.*; @@ -53,7 +53,7 @@ public void testActiveUIStep() { Step step = stepTestComponent.gson().fromJson("{'identifier':'stepId', 'type': 'active'}", Step.class); - assertTrue(step instanceof ActiveUIStep); + assertTrue(step instanceof ActiveUIStepBase); } @Test diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/inject/GsonModule.java b/domain/src/main/java/org/sagebionetworks/research/domain/inject/GsonModule.java index 4ca58bbee..30f556c2c 100644 --- a/domain/src/main/java/org/sagebionetworks/research/domain/inject/GsonModule.java +++ b/domain/src/main/java/org/sagebionetworks/research/domain/inject/GsonModule.java @@ -34,23 +34,111 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import org.sagebionetworks.research.domain.RuntimeTypeAdapterFactory; +import org.sagebionetworks.research.domain.step.ActiveUIStepBase; +import org.sagebionetworks.research.domain.step.StepType; +import org.sagebionetworks.research.domain.step.ui.ActiveUIStep; +import org.threeten.bp.Duration; +import java.lang.reflect.Type; import java.util.Map; import java.util.Set; +import dagger.MapKey; import dagger.Module; import dagger.Provides; +import dagger.multibindings.ClassKey; +import dagger.multibindings.IntoMap; import dagger.multibindings.Multibinds; +import javax.inject.Inject; import javax.inject.Singleton; @Module public abstract class GsonModule { - @Multibinds - abstract Map jsonDeserializerMap(); + @MapKey + public @interface ClassKey{ + Class value(); + } + + /** + * @return The json Deserializer for an active step. + */ + @Provides + @IntoMap + @ClassKey(ActiveUIStepBase.class) + static JsonDeserializer provideActiveUIStep() { + return new JsonDeserializer() { + @Override + public ActiveUIStep deserialize(final JsonElement json, final Type typeOfT, + final JsonDeserializationContext context) + throws JsonParseException { + if (json.isJsonObject()) { + JsonObject object = json.getAsJsonObject(); + String identifier = getStringFieldNonNull(object, "identifier"); + String title = getStringFieldNullable(object, "title"); + String text = getStringFieldNullable(object, "text"); + String detail = getStringFieldNullable(object, "detail"); + String footnote = getStringFieldNullable(object, "footnote"); + Duration duration = null; + JsonElement durationElement = object.get("duration"); + if (durationElement != null) { + if (!durationElement.isJsonPrimitive()) { + throw new JsonParseException("duration " + durationElement.toString() + " should be an integer"); + } + int durationInSeconds = durationElement.getAsInt(); + duration = Duration.ofSeconds(durationInSeconds); + } + + return new ActiveUIStepBase(identifier, title, text, detail, footnote, + duration, false); + } + + throw new JsonParseException("json " + json.toString() + "is not an object"); + } + }; + } + + /** + * Returns the string from the given field or null if the given field has been ommited from the JSON + * @param json the json object to get the field from + * @param key the name of the field to get from the json object + * @return The string that corresponds to key or null if no such String exists + */ + private static String getStringFieldNullable(JsonObject json, String key) { + JsonElement element = json.get(key); + if (element != null) { + return element.getAsString(); + } + + return null; + } + + /** + * Returns the string corresponding to the given key in the given json object, or throws a + * JsonParseExecption if no such String exists. + * @param json The json to get the string field from. + * @param key The field to get as a string from the given json. + * @return The string corresponding to the given key in the given json object. + * @throws JsonParseException if there is no string corresponding to the given key in the json object. + */ + private static String getStringFieldNonNull(JsonObject json, String key) throws JsonParseException { + JsonElement element = json.get(key); + if (element != null) { + String result = element.getAsString(); + if (result != null) { + return result; + } + } + + throw new JsonParseException("NonNull field " + key + "of object " + json.toString() + "couldn't be parsed"); + } @Provides @Singleton diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/inject/StepModule.java b/domain/src/main/java/org/sagebionetworks/research/domain/inject/StepModule.java index 2f1538ffd..e17c7da0c 100644 --- a/domain/src/main/java/org/sagebionetworks/research/domain/inject/StepModule.java +++ b/domain/src/main/java/org/sagebionetworks/research/domain/inject/StepModule.java @@ -33,8 +33,11 @@ package org.sagebionetworks.research.domain.inject; import org.sagebionetworks.research.domain.RuntimeTypeAdapterFactory; -import org.sagebionetworks.research.domain.step.ActiveUIStep; +import org.sagebionetworks.research.domain.step.ActiveUIStepBase; +import org.sagebionetworks.research.domain.step.SectionStep; +import org.sagebionetworks.research.domain.step.SectionStepBase; import org.sagebionetworks.research.domain.step.Step; +import org.sagebionetworks.research.domain.step.UIStepBase; import java.util.Map; import java.util.Map.Entry; @@ -44,6 +47,7 @@ import dagger.Provides; import dagger.multibindings.IntoMap; import dagger.multibindings.IntoSet; +import dagger.multibindings.Multibinds; @Module(includes = {GsonModule.class}) public class StepModule { @@ -57,13 +61,33 @@ public class StepModule { } /** - * @return json type key for ActiveUIStep.class + * @return json type key for ActiveUIStepBase.class */ @Provides @IntoMap - @StepClassKey(ActiveUIStep.class) + @StepClassKey(ActiveUIStepBase.class) static String provideActiveUIStep() { - return ActiveUIStep.TYPE_KEY; + return ActiveUIStepBase.TYPE_KEY; + } + + /** + * @return json type key for UIStepBase.class + */ + @Provides + @IntoMap + @StepClassKey(UIStepBase.class) + static String provideUIStep() { + return UIStepBase.TYPE_KEY; + } + + /** + * @return json type key for SectionStepBase.class + */ + @Provides + @IntoMap + @StepClassKey(SectionStepBase.class) + static String provideSectionStep() { + return SectionStepBase.TYPE_KEY; } /** diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/ActiveUIStepBase.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/ActiveUIStepBase.java new file mode 100644 index 000000000..fcaa1bca9 --- /dev/null +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/ActiveUIStepBase.java @@ -0,0 +1,106 @@ +/* + * BSD 3-Clause License + * + * Copyright 2018 Sage Bionetworks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. No license is granted to the trademarks of + * the copyright holders even if such marks are included in this software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.sagebionetworks.research.domain.step; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.common.base.Objects; + +import org.sagebionetworks.research.domain.step.ui.ActiveUIStep; +import org.threeten.bp.Duration; + + +public class ActiveUIStepBase extends UIStepBase implements ActiveUIStep { + public static final String TYPE_KEY = "active"; + + @Nullable + private final Duration duration; + private final boolean backgroundAudioRequired; + + public ActiveUIStepBase(@NonNull final String identifier, + @Nullable final String title, @Nullable final String text, + @Nullable final String detail, @Nullable final String footnote, + @Nullable final Duration duration, final boolean backgroundAudioRequired) { + super(identifier, title, text, detail, footnote); + this.duration = duration; + this.backgroundAudioRequired = backgroundAudioRequired; + } + @Nullable + @Override + public Duration getDuration() { + return this.duration; + } + + @NonNull + @Override + public String getType() { + return TYPE_KEY; + } + + @Override + public boolean isBackgroundAudioRequired() { + return this.backgroundAudioRequired; + } + + @Override + public int hashCode() { + return super.hashCode() + 3 * Objects.hashCode(this.duration, this.backgroundAudioRequired); + } + + /** + * Override equalsHelepr to also check the equality of Duration and isBackgroundAudioRequired. + * @param o The object to check for equality with this. + * @return True if this is equal to other, false otherwise. + */ + @Override + protected boolean equalsHelper(Object o) { + ActiveUIStepBase activeStep = (ActiveUIStepBase) o; + return super.equalsHelper(o) && + Objects.equal(this.getDuration(), activeStep.getDuration()) && + this.isBackgroundAudioRequired() == activeStep.isBackgroundAudioRequired(); + } + + /** + * Override toStringHelper to add the duration and isBackgroundAudioRequired fields to the + * ToStringHelper. + * @return The ToStringHelper that can create a String representation of this. + */ + @Override + protected ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("duration", this.getDuration()) + .add("isBackgroundAudioRequired", this.isBackgroundAudioRequired()); + } +} diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/FormUIStepBase.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/FormUIStepBase.java new file mode 100644 index 000000000..5eb990ac2 --- /dev/null +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/FormUIStepBase.java @@ -0,0 +1,97 @@ +/* + * BSD 3-Clause License + * + * Copyright 2018 Sage Bionetworks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. No license is granted to the trademarks of + * the copyright holders even if such marks are included in this software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.sagebionetworks.research.domain.step; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.common.base.Objects; + +import org.sagebionetworks.research.domain.form.InputField; +import org.sagebionetworks.research.domain.step.ui.FormUIStep; + +import java.util.List; + +public class FormUIStepBase extends UIStepBase implements FormUIStep { + @NonNull + private final List inputFields; + + public static final String TYPE_KEY = "form"; + + public FormUIStepBase(@NonNull final String identifier, @Nullable final String title, + @Nullable final String text, @Nullable final String detail, @Nullable final String footnote, + @NonNull final List inputFields) { + super(identifier, title, text, detail, footnote); + this.inputFields = inputFields; + } + + @NonNull + @Override + public List getInputFields() { + return this.inputFields; + } + + @NonNull + @Override + public String getType() { + return TYPE_KEY; + } + + @Override + public int hashCode() { + return super.hashCode() + 3 * Objects.hashCode(this.inputFields); + } + + /** + * Override equalsHelper to also compare the input fields. + * @param o The object to check for equality with this. + * @return True if this is equal to o, false otherwise. + */ + @Override + protected boolean equalsHelper(Object o) { + FormUIStepBase formStep = (FormUIStepBase) o; + return super.equalsHelper(o) && + Objects.equal(this.getInputFields(), formStep.getInputFields()); + } + + /** + * Override toStringHelper to also add the input fields. + * @return The ToStringHelper that can produce the toString for this. + */ + @Override + protected ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("inputFields", this.getInputFields()); + } +} diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/SectionStep.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/SectionStep.java index 23f032f4a..360dc115c 100644 --- a/domain/src/main/java/org/sagebionetworks/research/domain/step/SectionStep.java +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/SectionStep.java @@ -32,6 +32,8 @@ package org.sagebionetworks.research.domain.step; +import android.support.annotation.NonNull; + import java.util.List; /** @@ -47,5 +49,6 @@ public interface SectionStep extends Step { * * @return list of the steps in the subgrouping */ + @NonNull List getSteps(); } diff --git a/domain/src/test/java/org/sagebionetworks/research/domain/step/StepGsonTest.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/SectionStepBase.java similarity index 68% rename from domain/src/test/java/org/sagebionetworks/research/domain/step/StepGsonTest.java rename to domain/src/main/java/org/sagebionetworks/research/domain/step/SectionStepBase.java index 8b5fd7cdb..2791851b5 100644 --- a/domain/src/test/java/org/sagebionetworks/research/domain/step/StepGsonTest.java +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/SectionStepBase.java @@ -32,27 +32,42 @@ package org.sagebionetworks.research.domain.step; -import org.junit.*; +import android.support.annotation.NonNull; -import static org.junit.Assert.*; +import java.util.List; -public class StepGsonTest { +public class SectionStepBase implements SectionStep { + public static final String TYPE_KEY = "section"; - StepTestComponent stepTestComponent; + @NonNull + private final String identifier; + @NonNull + private final String type; + @NonNull + private final List steps; - @Before - public void setup() { - stepTestComponent = DaggerStepTestComponent.builder().build(); + public SectionStepBase(@NonNull final String identifier, @NonNull final String type, + @NonNull final List steps) { + this.identifier = identifier; + this.type = type; + this.steps = steps; } + @NonNull + @Override + public String getIdentifier() { + return this.identifier; + } - @Test - public void testActiveUIStep() { - String id = "stepId"; - String type = "active"; - - Step step = stepTestComponent.gson().fromJson("{'identifier':'stepId', 'type': 'active'}", Step.class); + @NonNull + @Override + public String getType() { + return this.type; + } - assertTrue(step instanceof ActiveUIStep); + @NonNull + @Override + public List getSteps() { + return this.steps; } -} \ No newline at end of file +} diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/StepBase.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/StepBase.java index cdf8b0bf5..9dc4c29b1 100644 --- a/domain/src/main/java/org/sagebionetworks/research/domain/step/StepBase.java +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/StepBase.java @@ -72,7 +72,8 @@ public boolean equals(Object o) { return false; } StepBase stepBase = (StepBase) o; - return Objects.equal(identifier, stepBase.identifier); + return Objects.equal(identifier, stepBase.identifier) && + Objects.equal(type, stepBase.type); } @Override diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/UIStepBase.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/UIStepBase.java new file mode 100644 index 000000000..d6ee4e145 --- /dev/null +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/UIStepBase.java @@ -0,0 +1,151 @@ +/* + * BSD 3-Clause License + * + * Copyright 2018 Sage Bionetworks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. No license is granted to the trademarks of + * the copyright holders even if such marks are included in this software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.sagebionetworks.research.domain.step; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.common.base.Objects; + +import org.sagebionetworks.research.domain.step.ui.UIStep; + +public class UIStepBase implements UIStep { + public static final String TYPE_KEY = "ui"; + + @NonNull + private final String identifier; + @Nullable + private final String title; + @Nullable + private final String text; + @Nullable + private final String detail; + @Nullable + private final String footnote; + + public UIStepBase(@NonNull final String identifier, + @Nullable final String title, @Nullable final String text, + @Nullable final String detail, @Nullable final String footnote) { + this.identifier = identifier; + this.title = title; + this.text = text; + this.detail = detail; + this.footnote = footnote; + } + + @NonNull + @Override + public String getIdentifier() { + return this.identifier; + } + + + @NonNull + @Override + public String getType() { + return TYPE_KEY; + } + + @Nullable + @Override + public String getTitle() { + return this.title; + } + + @Nullable + @Override + public String getText() { + return this.text; + } + + @Nullable + @Override + public String getDetail() { + return this.detail; + } + + @Nullable + @Override + public String getFootnote() { + return this.footnote; + } + + @Override + public boolean equals(Object o) { + return this == o || (o != null && this.getClass() == o.getClass() && this.equalsHelper(o)); + } + + @Override + public String toString() { + return this.toStringHelper().toString(); + } + + @Override + public int hashCode() { + return Objects.hashCode(this.identifier, this.title, this.text, this.detail, this.footnote); + } + + /** + * Returns true if all the UIStepBase fields of this object are equal to all the UIStepBase fields of o, + * false otherwise. It is expected that subclasses will override this to add their fields to the comparison. + * Requires: this.getClass() == o.getClass() + * @param o The object to check for equality with this. + * @return True if all the UIStepBase fields of this object are equal to all the UIStepBase fields of o, + * false otherwise. + */ + protected boolean equalsHelper(Object o) { + UIStepBase uiStep = (UIStepBase) o; + return Objects.equal(this.identifier, uiStep.identifier) && + Objects.equal(this.title, uiStep.title) && + Objects.equal(this.text, uiStep.text) && + Objects.equal(this.detail, uiStep.detail) && + Objects.equal(this.footnote, uiStep.footnote); + } + + /** + * Returns the ToStringHelper that can be used to create the toString() representation of this as a UIStepBase + * object. It is expected that subclasses will override this to add their own fields to the toString(). + * @return The toStringHelper for this UIStepBase. + */ + protected ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this) + .add("identifier", this.getIdentifier()) + .add("type", this.getType()) + .add("title", this.getTitle()) + .add("text", this.getText()) + .add("detail", this.getDetail()) + .add("footnote", this.getFootnote()); + } +} diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/ActiveUIStep.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/ActiveUIStep.java index 668e1c898..ba2c51915 100644 --- a/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/ActiveUIStep.java +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/ActiveUIStep.java @@ -34,7 +34,8 @@ import android.support.annotation.Nullable; -import java.time.Duration; +import org.threeten.bp.Duration; + public interface ActiveUIStep extends UIStep { /** diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/FormUIStep.java b/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/FormUIStep.java index fa6a2c2ce..3ac36c592 100644 --- a/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/FormUIStep.java +++ b/domain/src/main/java/org/sagebionetworks/research/domain/step/ui/FormUIStep.java @@ -33,9 +33,11 @@ package org.sagebionetworks.research.domain.step.ui; import android.support.annotation.NonNull; -import java.util.List; + import org.sagebionetworks.research.domain.form.InputField; +import java.util.List; + /** * Properties used in creating a form input. */ diff --git a/domain/src/test/java/org/sagebionetworks/research/domain/step/StepTestComponent.java b/domain/src/test/java/org/sagebionetworks/research/domain/step/StepTestComponent.java index 6fc5c43b3..84f23851e 100644 --- a/domain/src/test/java/org/sagebionetworks/research/domain/step/StepTestComponent.java +++ b/domain/src/test/java/org/sagebionetworks/research/domain/step/StepTestComponent.java @@ -35,11 +35,12 @@ import com.google.gson.Gson; import org.sagebionetworks.research.domain.inject.StepModule; +import org.sagebionetworks.research.domain.inject.GsonModule; import dagger.Component; import javax.inject.Singleton; -@Component(modules = StepModule.class) +@Component(modules = {StepModule.class, GsonModule.class}) @Singleton public interface StepTestComponent { Gson gson(); diff --git a/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/.DS_Store b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/.DS_Store new file mode 100644 index 000000000..a3b0fb3b0 Binary files /dev/null and b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/.DS_Store differ diff --git a/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/ActiveUIStepGsonTests.java b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/ActiveUIStepGsonTests.java new file mode 100644 index 000000000..9bdfb4ee8 --- /dev/null +++ b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/ActiveUIStepGsonTests.java @@ -0,0 +1,75 @@ +/* + * BSD 3-Clause License + * + * Copyright 2018 Sage Bionetworks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. No license is granted to the trademarks of + * the copyright holders even if such marks are included in this software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.sagebionetworks.research.domain.step.gson; + +import org.junit.*; +import org.sagebionetworks.research.domain.step.ActiveUIStepBase; +import org.sagebionetworks.research.domain.step.Step; +import org.sagebionetworks.research.domain.step.StepType; +import org.sagebionetworks.research.domain.step.ui.ActiveUIStep; +import org.threeten.bp.Duration; + + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNull; +import static junit.framework.Assert.assertTrue; + +public class ActiveUIStepGsonTests extends IndividualStepGsonTest { + @Test + public void testExample_1() { + ActiveUIStepBase expected = new ActiveUIStepBase("testActiveUIStep1","title", "text", + null, null, null, false); + commonTest(expected, "ActiveUIStep_1.json"); + } + + @Test + public void testExample_2() { + ActiveUIStepBase expected = new ActiveUIStepBase("testActiveUIStep2", "title","text", + "detail", "footnote", null, false); + commonTest(expected, "ActiveUIStep_2.json"); + } + + @Test + public void testExample_3() { + ActiveUIStepBase expected = new ActiveUIStepBase("testActiveUIStep3", "title","text", + "detail", "footnote", Duration.ofSeconds(5), + false); + commonTest(expected, "ActiveUIStep_3.json"); + } + + private void commonTest(ActiveUIStep expected, String filename) { + Step step = this.readJsonFile(filename); + assertTrue(step instanceof ActiveUIStep); + assertEquals(expected, step); + } +} diff --git a/domain/src/main/java/org/sagebionetworks/research/domain/step/ActiveUIStep.java b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/AllStepGsonTests.java similarity index 82% rename from domain/src/main/java/org/sagebionetworks/research/domain/step/ActiveUIStep.java rename to domain/src/test/java/org/sagebionetworks/research/domain/step/gson/AllStepGsonTests.java index e2509d2ac..3015ae1fe 100644 --- a/domain/src/main/java/org/sagebionetworks/research/domain/step/ActiveUIStep.java +++ b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/AllStepGsonTests.java @@ -30,21 +30,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.sagebionetworks.research.domain.step; +package org.sagebionetworks.research.domain.step.gson; -import android.support.annotation.NonNull; +import org.junit.runner.*; +import org.junit.runners.*; +import org.junit.runners.Suite.*; -public class ActiveUIStep implements Step { - public static final String TYPE_KEY = "active"; - @NonNull - @Override - public String getIdentifier() { - return null; - } +@RunWith(Suite.class) +@SuiteClasses({ActiveUIStepGsonTests.class, SectionStepGsonTests.class, UIStepGsonTests.class }) +public class AllStepGsonTests { - @NonNull - @Override - public String getType() { - return TYPE_KEY; - } } diff --git a/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/IndividualStepGsonTest.java b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/IndividualStepGsonTest.java new file mode 100644 index 000000000..5c09fbc0b --- /dev/null +++ b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/IndividualStepGsonTest.java @@ -0,0 +1,83 @@ +/* + * BSD 3-Clause License + * + * Copyright 2018 Sage Bionetworks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. No license is granted to the trademarks of + * the copyright holders even if such marks are included in this software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.sagebionetworks.research.domain.step.gson; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.google.gson.Gson; + +import org.junit.*; +import org.sagebionetworks.research.domain.inject.GsonModule; +import org.sagebionetworks.research.domain.step.DaggerStepTestComponent; +import org.sagebionetworks.research.domain.step.Step; +import org.sagebionetworks.research.domain.step.StepTestComponent; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.Reader; +import java.net.URL; +import java.net.URLClassLoader; + +import static junit.framework.Assert.assertNotNull; + +public class IndividualStepGsonTest { + private StepTestComponent stepTestComponent; + + @Before + public void setup() { + this.stepTestComponent = DaggerStepTestComponent.builder().build(); + } + + @Nullable + private Step readJsonFileHelper(URL url) { + try { + Reader reader = new FileReader(new File(url.getFile())); + Step step = this.stepTestComponent.gson().fromJson(reader, Step.class); + return step; + } catch (FileNotFoundException e) { + return null; + } + } + + @NonNull + protected Step readJsonFile(String filename) { + ClassLoader loader = this.getClass().getClassLoader(); + URL url = loader.getResource(filename); + Step step = this.readJsonFileHelper(url); + assertNotNull("Failed to read file " + filename, step); + return step; + } + +} diff --git a/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/SectionStepGsonTests.java b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/SectionStepGsonTests.java new file mode 100644 index 000000000..ac0bc0852 --- /dev/null +++ b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/SectionStepGsonTests.java @@ -0,0 +1,72 @@ +/* + * BSD 3-Clause License + * + * Copyright 2018 Sage Bionetworks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. No license is granted to the trademarks of + * the copyright holders even if such marks are included in this software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.sagebionetworks.research.domain.step.gson; + +import org.junit.*; +import org.sagebionetworks.research.domain.step.SectionStep; +import org.sagebionetworks.research.domain.step.Step; +import org.sagebionetworks.research.domain.step.ui.ActiveUIStep; +import org.sagebionetworks.research.domain.step.ui.UIStep; + +import java.util.List; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; + +public class SectionStepGsonTests extends IndividualStepGsonTest { + @Test + public void testEmpty() { + Step step = this.readJsonFile("EmptySectionStep.json"); + assertTrue(step instanceof SectionStep); + SectionStep sectionStep = (SectionStep) step; + assertEquals("emptySectionStep", sectionStep.getIdentifier()); + assertTrue(sectionStep.getSteps().isEmpty()); + } + + @Test + public void testExample_1() { + Step step = this.readJsonFile("SectionStep_1.json"); + assertTrue(step instanceof SectionStep); + SectionStep sectionStep = (SectionStep) step; + assertEquals("testSectionStep1", sectionStep.getIdentifier()); + List steps = sectionStep.getSteps(); + assertNotNull(steps); + assertEquals(2, steps.size()); + Step substep1 = steps.get(0); + assertTrue(substep1 instanceof UIStep); + Step substep2 = steps.get(1); + assertTrue(substep2 instanceof ActiveUIStep); + } + +} diff --git a/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/UIStepGsonTests.java b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/UIStepGsonTests.java new file mode 100644 index 000000000..87a6e7bce --- /dev/null +++ b/domain/src/test/java/org/sagebionetworks/research/domain/step/gson/UIStepGsonTests.java @@ -0,0 +1,62 @@ +/* + * BSD 3-Clause License + * + * Copyright 2018 Sage Bionetworks. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. No license is granted to the trademarks of + * the copyright holders even if such marks are included in this software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.sagebionetworks.research.domain.step.gson; + +import org.junit.*; +import org.sagebionetworks.research.domain.step.Step; +import org.sagebionetworks.research.domain.step.UIStepBase; +import org.sagebionetworks.research.domain.step.ui.UIStep; + +import static org.junit.Assert.*; + +public class UIStepGsonTests extends IndividualStepGsonTest { + @Test + public void testExample_1() { + UIStep expected = new UIStepBase("testUIStep1","title", "text", null, + null); + testCommon(expected, "UIStep_1.json"); + } + + @Test + public void testExample_2() { + UIStep expected = new UIStepBase("testUIStep2", "title", "text", "detail", + "footnote"); + testCommon(expected, "UIStep_2.json"); + } + + private void testCommon(UIStep expected, String filename) { + Step step = this.readJsonFile(filename); + assertTrue(step instanceof UIStep); + assertEquals(expected, step); + } +} \ No newline at end of file diff --git a/domain/src/test/resources/ActiveUIStep_1.json b/domain/src/test/resources/ActiveUIStep_1.json new file mode 100644 index 000000000..f451c149b --- /dev/null +++ b/domain/src/test/resources/ActiveUIStep_1.json @@ -0,0 +1,6 @@ +{ + "identifier" : "testActiveUIStep1", + "type" : "active", + "title" : "title", + "text" : "text" +} \ No newline at end of file diff --git a/domain/src/test/resources/ActiveUIStep_2.json b/domain/src/test/resources/ActiveUIStep_2.json new file mode 100644 index 000000000..d5980dc7d --- /dev/null +++ b/domain/src/test/resources/ActiveUIStep_2.json @@ -0,0 +1,8 @@ +{ + "identifier" : "testActiveUIStep2", + "type" : "active", + "title" : "title", + "text" : "text", + "detail" : "detail", + "footnote" : "footnote" +} \ No newline at end of file diff --git a/domain/src/test/resources/ActiveUIStep_3.json b/domain/src/test/resources/ActiveUIStep_3.json new file mode 100644 index 000000000..f73c8c69a --- /dev/null +++ b/domain/src/test/resources/ActiveUIStep_3.json @@ -0,0 +1,9 @@ +{ + "identifier" : "testActiveUIStep3", + "type" : "active", + "title" : "title", + "text" : "text", + "detail" : "detail", + "footnote" : "footnote", + "duration" : 5 +} \ No newline at end of file diff --git a/domain/src/test/resources/EmptySectionStep.json b/domain/src/test/resources/EmptySectionStep.json new file mode 100644 index 000000000..b0eeaee24 --- /dev/null +++ b/domain/src/test/resources/EmptySectionStep.json @@ -0,0 +1,5 @@ +{ + "identifier" : "emptySectionStep", + "type" : "section", + "steps" : [] +} \ No newline at end of file diff --git a/domain/src/test/resources/SectionStep_1.json b/domain/src/test/resources/SectionStep_1.json new file mode 100644 index 000000000..3ffddb8ef --- /dev/null +++ b/domain/src/test/resources/SectionStep_1.json @@ -0,0 +1,19 @@ +{ + "identifier" : "testSectionStep1", + "type" : "section", + "steps" : [ + { + "identifier" : "substep1", + "type" : "ui", + "title" : "substep1 title", + "text" : "substep1 text" + }, + { + "identifier" : "substep2", + "type" : "active", + "title" : "substep2 title", + "text" : "substep2 text", + "footnote" : "substep2 footnote" + } + ] +} diff --git a/domain/src/test/resources/UIStep_1.json b/domain/src/test/resources/UIStep_1.json new file mode 100644 index 000000000..47e4201ca --- /dev/null +++ b/domain/src/test/resources/UIStep_1.json @@ -0,0 +1,6 @@ +{ + "identifier" : "testUIStep1", + "type" : "ui", + "title" : "title", + "text" : "text" +} \ No newline at end of file diff --git a/domain/src/test/resources/UIStep_2.json b/domain/src/test/resources/UIStep_2.json new file mode 100644 index 000000000..6cceb4718 --- /dev/null +++ b/domain/src/test/resources/UIStep_2.json @@ -0,0 +1,8 @@ +{ + "identifier" : "testUIStep2", + "type" : "ui", + "title" : "title", + "text" : "text", + "detail" : "detail", + "footnote" : "footnote" +} \ No newline at end of file