Skip to content

Commit

Permalink
Review market tests documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
cabaluniovi committed Sep 3, 2024
1 parent 3346b4d commit 2f44242
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,23 @@
import giis.tdrules.store.loader.oa.OaPathResolver;
import test4giis.tdrules.tdg.st.test.BaseAll;

/**
* Common configuration and customization for all Market tests that use entities in its OpenApi model.
*/
public class BaseMarket extends BaseAll {
protected static final String MARKET_SCHEMA_LOCAL = "../sut-market/src/main/resources/marketWithoutArrays.json";
private static final String MARKET_URL_LIVE = "http://localhost:8083";


// attributes that can be filtered during comparisons of assertions
private static final String[] FILTERED_ATTRS = {"password", "dateCreated","number"};

public static String queryCartByUser = "tds CartDTO where user='lucia@email.com'";
public static String queryCartByUserProductQuantity = "tds CartDTO,CartItemDTORes,ProductDTORes where CartDTO.user='pepe@email.com' and CartItemDTORes.productId=1 and CartItemDTORes.quantity=5 and ProductDTORes.available=1";
public static String queryOrderByUser = "tds OrderDTO where userAccount='pepe@email.com' ";
public static String queryProductByAge = "tds ProductDTORes where age=10";
public static String queryUserByName = "tds UserDTORes where name='Pepe'";
public static String queryUserByEmail = "tds UserDTORes where email ='pepe@email.com'";
public static String queryCartByUserProductQuantity = "tds CartDTO,CartItemDTORes,ProductDTORes where CartDTO.user='pepe@email.com' and CartItemDTORes.productId=1 and CartItemDTORes.quantity=5 and ProductDTORes.available=1";


@Override
protected String getSutName() {
return "market";
Expand All @@ -54,9 +60,9 @@ protected String getDeleteAllDataLiveEndpoint() {
@Override
protected TdSchema getSchema() {
// Configure:
// filter entities Link* and attributes _link*, and
// the schema id resolver to use id attributes as uid and
// not to use productId as product.id in entities CartItem and ProductDTO
// - filter entities Link* and attributes _link*
// - the schema id resolver to use id attributes as uid
// except in entities CartItemDTO (pk are user + productId) and ProductDTO (pk is productId)
OaSchemaApi api = new OaSchemaApi(MARKET_SCHEMA_LOCAL)
.setFilter(new OaSchemaFilter()
.add("*", "_link*")
Expand All @@ -69,15 +75,16 @@ protected TdSchema getSchema() {
;
return api.getSchema();
}

/**
* Instancia un generador utilizando un Adaptador para Openapi que genera los datos directamente a traves del api
* El path resolver se configura con la url donde extraer los paths de los endpoints de LiveBackId.
* La generación de las claves se realiza en el backend (UidGen), las columnas (AttrGen) se generan de forma determinista.
* Se utliza diccionario para la generación de columnas (getDictionaryAttrGen)
*/

@Override
protected DataLoader getLiveDataLoader() {
// Generator with a custom path resolver injected:
// * Get uids from the backend
// * Include an authenticator:
// - The provider is the entity userDTOReq storing credential in email and password attributes
// - Consumers are entities CartItemDTO and ContactsDTO (username is user attribute) and
// OrderDTO (username is userAccount attribute)
// * Use a dictionary
TdSchema model = getSchema();
IPathResolver pathResolver=new CustomPathResolver().setServerUrl(MARKET_URL_LIVE);
OaBasicAuthStore authenticator = new OaBasicAuthStore()
Expand All @@ -91,12 +98,12 @@ protected DataLoader getLiveDataLoader() {
.setAttrGen(getDictionaryAttrGen());
}

/**
* Instancia un generador de datos configurado con un diccionario para que los datos
* generados no sean solo numeros, sino valores procedentes de un diccionario o mascaras
* Para tarjetas de crédito: https://dev.na.bambora.com/docs/references/payment_APIs/test_cards/
*/
protected IAttrGen getDictionaryAttrGen() {
// Dictionary configured for:
// - UserDTO (attributes email, name, password, phone)
// - DistilleryDTO (attribute title)
// - RegionDTO (attribute name)
// - CreditCardDTO (attribute ccNumber, source https://dev.na.bambora.com/docs/references/payment_APIs/test_cards/)
return new DictionaryAttrGen()
.with("UserDTORes", "email").padLeft('0', 2).mask("us{}@email.com")
.with("UserDTOReq", "email").padLeft('0', 2).mask("us{}@email.com")
Expand All @@ -119,7 +126,7 @@ protected IAttrGen getDictionaryAttrGen() {
protected void assertLiveData(String fileName, DataLoader dg) {
String dataLive = getAllLiveData();
log.info("Actual data stored in the backend\n{}", reserializeStoredData(dataLive));
// antes de comparar, se deben filtrar los atributos que no se quieren comparar
// before comparing, filter attributes
super.assertModel(fileName, filterAttributes(dataLive,FILTERED_ATTRS));
}

Expand All @@ -140,7 +147,7 @@ private String filterAttributes(String strJson, String... ignoreAttributes) {
return reserializeStoredData(sb.toString());
}

// actualiza json eliminando attributeName y su valor en todas las apariciones
// update json deleting attributeName and its value
private void removeAttribute(JsonNode node, String attributeName) {
if (node.isObject()) {
ObjectNode objectNode = (ObjectNode) node;
Expand All @@ -151,11 +158,11 @@ private void removeAttribute(JsonNode node, String attributeName) {
}
}

//los endpoints estan bajo el path backid
// Use the appropiate endpoint depending on the entity
public class CustomPathResolver extends OaPathResolver {
@Override
public String getEndpointPath(String tableName) {
//Eliminacion de Req o Res en las llamadas a los endpoints
//Removing Req or Res from the endpoints
String table = tableName.split("Re(s|q)")[0];
if ("CartDTO".equals(table))
return null;
Expand All @@ -173,6 +180,7 @@ else if ("OrderDTO".equals(table))
return super.getEndpointPath(table);
}

// Endpoint using PUT instead of POST for entity CartItemDTO
@Override public boolean usePut(String tableName) {
String table = tableName.split("Re(s|q)")[0];
return "CartItemDTO".equals(table);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import giis.tdrules.store.loader.IAttrGen;

/**
* Tests de funcionalidad de Carts
* Generación: QAGrow y claves se realiza en el backend
* Carts Functionality Tests.
* - Use the live SUT where the uids of each generated object are generated by the backend.
* - Use the dictionary
* - Include Users, Carts and Orders
*/
public class TestMarketFuncCarts extends BaseMarket {

Expand All @@ -18,51 +20,42 @@ protected boolean isLiveBackend() {

@Test
public void testDictUserDTOResByName() {
// users
String query = queryUserByName;
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-UsersByName.txt", dg);
}

/*
* Inserta carts pero no items ni productos. Para cubrir las reglas de cobertura no son necesarios
* Son carts vacíos.
*/
@Test
public void testDictCartDTOByUser() {
String query = "tds CartDTO where user='lucia@email.com'";
// empty carts
String query = queryCartByUser;
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-CartsByUser.txt", dg);
}

/* Inserta carts y sus items.
* Para que se inserte un producto en un carrito, debe estar disponible, necesario incluirlo en la query.
* Si no se indica en la query, se genera por DataGenerator y es no disponible (available = false),
* entonces al intentar añadirlo via api, no se inserta en la tabla (lo que es correcto)
* Hay otra regla de cobertura que no se cubre con una única base de datos:
* - user='lucia...' and productId=1 and quantity != 5
* En este caso, desde QAGrow ya no se generan los datos.
*/
@Test
public void testDictCartDTOByUserProductQuantity() {
// carts and items
// products must be available
String query = queryCartByUserProductQuantity;
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-CartsByUserProductQuantity.txt", dg);
}

/* Inserta order a un usuario.
* Para que cree una order, el carrito no puede estar vacio.
* Por tanto, habrá una query1 para generar carritos con productos y query2 para generar la orden del carrito
*/
@Test
public void testOrderDTOByUser() {
// order (cart must not be empty)
// query 1 generates a non-empty cart,
// query 2 generates the order
String query1= queryCartByUserProductQuantity;
String query2 = "tds OrderDTO where userAccount='pepe@email.com' ";
String query2 = queryOrderByUser;
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, new String[] {query1, query2}, dict);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import giis.tdrules.store.loader.IAttrGen;

/**
* Tests de funcionalidad de Products
* Generación: QAGrow y claves se realiza en el backend
* Products Functionality Tests
* - Use the live SUT where the uids of each generated object are generated by the backend.
* - Use the dictionary
* - Include Products, Distilleries and Regions
*/
public class TestMarketFuncProducts extends BaseMarket {

Expand All @@ -15,60 +17,49 @@ protected boolean isLiveBackend() {
return true;
}

/**
* Todos los productos de una destileria
*/
@Test
public void testProductsByDistillery() {
// products of a distillery
String query = "tds ProductDTOReq where distillery ='Ardbeg'";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-ProductsByDistillery.txt", dg);
}


/**
* Productos de una destileria disponibles
*/
@Test
public void testProductsByDistilleryAvaliable() {
// available products of a distillery
String query = "tds ProductDTOReq where distillery ='Ardbeg' and available = 1";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-ProductsByDistilleryAvailable.txt", dg);
}

/**
* Todos los productos de una destileria no disponibles
*/
@Test
public void testProductsByDistilleryNotAvailable() {
// non-available products of a distillery
String query = "tds ProductDTOReq where distillery ='Ardbeg' and available = 0";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-ProductsByDistilleryNotAvailable.txt", dg);
}

/**
* Productos de una destileria disponibles entre dos precios
*/
@Test
public void testProductsByDistilleryPrice() {
// available products of a distillery, price between two values
String query = "tds ProductDTOReq where distillery ='Ardbeg' and price < 100 and price > 5";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-ProductsByDistilleryPrice.txt", dg);
}

/**
* Productos de una destileria disponibles entre dos precios
*/
@Test
public void testProductsByDistilleryPriceAge() {
// available products of a distillery and an age, price between two values
String query = "tds ProductDTOReq where distillery ='Ardbeg' and price < 100 and price > 5 and age = 12";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
Expand All @@ -77,28 +68,34 @@ public void testProductsByDistilleryPriceAge() {
}


/**
* Prueba de generacion de distillery y region con claves en el backend, fijando distillery.title
*/
@Test
public void testDistilleryByTitle() {
// distillery
String query = "tds DistilleryDTOReq where title ='Ardbeg'";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-DistilleryByTitle.txt", dg);
}

/**
* Prueba de generacion de distillery y region con claves en el backend, fijando distillery.region (region es maestro de distillery)
*/
@Test
public void testDistilleryByRegion() {
// distillery of a region
String query = "tds DistilleryDTOReq where region ='Islay'";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-DistilleryByRegion.txt", dg);
}

@Test
public void testRegionByName() {
// region
String query = "tds RegionDTOReq where name ='Campbeltown'";
IAttrGen dict=getDictionaryAttrGen();
DataLoader dg = getLiveDataLoader().setAttrGen(dict);
generateAndLoad(dg, query, dict);
assertData("func-RegionByName.txt", dg);
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import giis.tdrules.store.loader.DataLoader;

/**
* Generacion de datos para Market utilizando QAGrow.
* Utiliza un un esquema y un DataAdapter local, que no requiere una conexion activa a un servidor.
* Generates test data for a given query using QAGrow and loads
* the data as indicated by the local specified data loader
*/

public class TestMarketQagrowLocal extends BaseMarket {

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
import giis.tdrules.openapi.model.TdSchema;

/**
* Genera el esquema a partir de la especificacion (leida de archivo) y lo comprueba en formato json y xml
* Checks the transformation of the OpenApi specification into the TdSchema model
* (json, xml and Mermaid graph)
*/
public class TestMarketSchemaLocal extends BaseMarket {

Expand Down

This file was deleted.

Loading

0 comments on commit 2f44242

Please sign in to comment.