/*
* Copyright (C) 2014 SCVNGR, Inc. d/b/a LevelUp
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.scvngr.levelup.core.model.factory.json;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.test.AndroidTestCase;
import com.scvngr.levelup.core.annotation.model.RequiredField;
import com.scvngr.levelup.core.model.Category;
import com.scvngr.levelup.core.model.CategoryFixture;
import com.scvngr.levelup.core.model.MonetaryValue;
import com.scvngr.levelup.core.model.Order;
import com.scvngr.levelup.core.model.OrderFixture;
import com.scvngr.levelup.core.model.User;
import com.scvngr.levelup.core.model.UserFixture;
import com.scvngr.levelup.core.util.NullUtils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import net.jcip.annotations.Immutable;
/**
* Tests {@link com.scvngr.levelup.core.model.factory.json.GsonModelFactory} with a few of the models. Once these are moved over to individual
* models, this class can be removed.
*/
public final class GsonModelFactoryTest extends AndroidTestCase {
/**
* Tests loading a full {@link com.scvngr.levelup.core.model.Category} from the {@link CategoryFixture}.
*/
public void testGsonModel_category() {
final GsonModelFactory<Category> modelFactory =
new GsonModelFactory<Category>(CategoryJsonFactory.JsonKeys.MODEL_ROOT,
Category.class, false);
final Category model =
modelFactory.from(NullUtils.nonNullContract(CategoryFixture.getFullJsonObject()
.toString()));
assertNotNull(model);
assertEquals(1, model.getId());
assertEquals("category name", model.getName());
assertEquals(CategoryFixture.getFullModel(1), model);
}
/**
* Tests loading a minimal {@link com.scvngr.levelup.core.model.Order} from the {@link OrderFixture}.
*/
public void testGsonModel_orderMinimal() {
final GsonModelFactory<Order> modelFactory =
new GsonModelFactory<Order>(OrderJsonFactory.JsonKeys.MODEL_ROOT, Order.class,
false);
final Order order =
modelFactory.from(NullUtils.nonNullContract(OrderFixture.getMinimalJsonObject()
.toString()));
assertNotNull(order);
assertNull(order.getBundleClosedAt());
assertEquals(OrderFixture.DATE_TIME_FIXTURE_1, order.getCreatedAt());
assertEquals(OrderFixture.UUID_FIXTURE_1, order.getUuid());
assertNull(order.getRefundedAt());
assertNull(order.getTransactedAt());
assertEquals(OrderFixture.getMinimalModel(), order);
}
/**
* Tests loading a minimal {@link com.scvngr.levelup.core.model.User} from the {@link UserFixture}.
*/
public void testGsonModel_userMinimal() {
final GsonModelFactory<User> modelFactory =
new GsonModelFactory<User>(UserJsonFactory.JsonKeys.MODEL_ROOT, User.class, false);
final User model =
modelFactory.from(NullUtils.nonNullContract(UserFixture.getMinimalJsonObject()
.toString()));
assertNotNull(model);
assertEquals(1, model.getId());
assertEquals(UserFixture.getMinimalModel(), model);
}
/**
* Tests using {@link com.scvngr.levelup.core.model.factory.json.GsonModelFactoryTest.Product} with a minimal model.
*/
public void testModel_fromJsonMinimal() {
final GsonModelFactory<Product> factory =
new GsonModelFactory<Product>("product", Product.class, false);
final Product product = factory.from(getMinimalProductFixture());
assertNotNull(product.getCost());
assertEquals(500, product.getCost().getAmount());
assertNull(product.getDescription());
assertEquals(123, product.getId());
assertEquals(50, product.getInventoryCount());
assertEquals("widget", product.getName());
assertEquals("Product", Product.DB_KEY);
}
/**
* Tests using {@link com.scvngr.levelup.core.model.factory.json.GsonModelFactoryTest.Product} with a full model.
*/
public void testModel_fromJsonFull() {
final GsonModelFactory<Product> factory =
new GsonModelFactory<Product>("product", Product.class, false);
final Product product = factory.from(getFullProductFixture());
assertNotNull(product.getCost());
assertEquals(500, product.getCost().getAmount());
assertEquals("This makes widgets", product.getDescription());
assertEquals(123, product.getId());
assertEquals(50, product.getInventoryCount());
assertEquals("widget", product.getName());
assertEquals("Product", Product.DB_KEY);
}
public void testModel_fromWrappedJsonFull() {
final GsonModelFactory<Product> factory =
new GsonModelFactory<Product>("product", Product.class, true);
final JsonObject obj = getFullProductFixture();
final JsonObject container = new JsonObject();
container.add("product", obj);
final Product product = factory.from(container);
assertNotNull(product.getCost());
assertEquals(500, product.getCost().getAmount());
assertEquals("This makes widgets", product.getDescription());
assertEquals(123, product.getId());
assertEquals(50, product.getInventoryCount());
assertEquals("widget", product.getName());
assertEquals("Product", Product.DB_KEY);
}
/**
* Tests using {@link com.scvngr.levelup.core.model.factory.json.GsonModelFactoryTest.Product} with an invalid model.
*/
public void testModel_fromJsonInvalidNoName() {
final GsonModelFactory<Product> factory =
new GsonModelFactory<Product>("product", Product.class, false);
try {
final JsonObject jo = getMinimalProductFixture();
jo.remove("name");
factory.from(jo);
fail("Exception expected to be thrown");
} catch (final JsonParseException e) {
// Expected exception.
}
}
@NonNull
private JsonObject getMinimalProductFixture() {
final JsonObject jo = new JsonObject();
jo.addProperty("cost", 500);
jo.addProperty("id", 123);
jo.addProperty("inventory_count", 50);
jo.addProperty("name", "widget");
return jo;
}
@NonNull
private JsonObject getFullProductFixture() {
final JsonObject jo = getMinimalProductFixture();
jo.addProperty("description", "This makes widgets");
return jo;
}
/**
* A test model.
*/
@Immutable
public static final class Product implements Parcelable {
/**
* A test MonetaryValue.
*/
@NonNull
@RequiredField
private final MonetaryValue cost;
/**
* An optional field.
*/
@Nullable
private final String description;
/**
* Basic long.
*/
private final long id;
/**
* A test item with camelCase.
*/
private final long inventoryCount;
/**
* Basic required String.
*/
@NonNull
@RequiredField
private final String name;
/**
* A static field.
*/
@NonNull
public static final String DB_KEY = "Product";
/**
* A test model that's not part of our core models. This includes some common edge cases.
*/
//CHECKSTYLE:OFF don't warn about field hiding for this sample model constructor.
public Product(@NonNull final MonetaryValue cost, @Nullable final String description,
final long id, final long inventoryCount, @NonNull final String name) {
//CHECKSTYLE:ON
this.cost = cost;
this.description = description;
this.id = id;
this.inventoryCount = inventoryCount;
this.name = name;
}
public static final Creator<Product> CREATOR = null;
@NonNull
public MonetaryValue getCost() {
return cost;
}
@Nullable
public String getDescription() {
return description;
}
public long getId() {
return id;
}
public long getInventoryCount() {
return inventoryCount;
}
@NonNull
public String getName() {
return name;
}
@Override
public int describeContents() {
throw new UnsupportedOperationException();
}
@Override
public void writeToParcel(final Parcel dest, final int flags) {
throw new UnsupportedOperationException();
}
}
}